1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>Random123-1.09: Examples, Tests and Benchmarks</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javaScript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body onload='searchBox.OnSelectItem(0);'>
<div class="tabs"><ul class="tablist"><li style="padding-left: 1.5em; font-weight: bold">Random123-1.09 Documentation</li></ul></div>
<!-- Generated by Doxygen 1.7.1 -->
<script type="text/javascript"><!--
var searchBox = new SearchBox("searchBox", "search",false,'Search');
--></script>
<div class="navigation" id="top">
<div class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
<li id="searchli">
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
</div>
<div class="header">
<div class="headertitle">
<h1>Examples, Tests and Benchmarks </h1> </div>
</div>
<div class="contents">
<p>The examples/ directory contains tests, examples and timing harnesses for the components of the Random123 library.</p>
<h2><a class="anchor" id="building"></a>
Compiling and Running the code</h2>
<p>Installing and using Random123 requires only the use of the header files, and has no prerequisites other than a reasonable C99 or C++98 compiler.</p>
<p>With a modern GNU make (3.80 or newer), building and running the core tests and examples can be as easy as running gmake with no arguments. Note, though, that the provided examples/GNUmakefile intentionally avoids setting any of the standard make variables: CC, CXX, CPPFLAGS, CFLAGS, CXXFLAGS, TARGET_ARCH, LDFLAGS, LOADLIBES, LDLIBS. GNU make will inherit settings for these variables from the environment, or they may be set on the command line. If none are set, compilation will proceed using system-wide default flags, generally without advanced optimization, architectural tuning, warnings, or other common options.</p>
<p>Before putting the Random123 library to use in an application, it is important to test it using the same compiler flags and features that the application will use. In other words, the conventional make variables should be set the same way when testing the library as they will be set when the library is actually compiled into your application. Something like: </p>
<div class="fragment"><pre class="fragment">gmake CFLAGS=<span class="stringliteral">"-std=c99"</span> CXXFLAGS=<span class="stringliteral">"-std=c++0x"</span> CPPFLAGS=<span class="stringliteral">"/alternate/location/include -O3 -Wall -Wstrict-aliasing=2"</span> TARGET_ARCH=<span class="stringliteral">"-march=native"</span>
</pre></div><p> would confirm that all is well with optimization on, and output targeted at an architecture with the same capabilities as the machine running the compilation.</p>
<p>Very old versions of GNU make (pre-2002) or non-GNU make will not work with examples/GNUmakefile.. Lacking a suitably modern GNU make, our advice is to invoke the C or C++ compiler directly on the source files in the examples/ directory. The <a href="file:">file:</a> examples/BUILD.LOG contains a list of sample build commands. They will almost certainly need to be adapted to the target system. For Windows users, BUILDVC.BAT invokes the Microsoft Visual Studio compiler. Edit it as needed for your platform.</p>
<h2><a class="anchor" id="tests"></a>
Tests</h2>
<p>It is recommended that Random123 be tested <b> on the target system, with the target compiler, intended optimization levels, options, target architectures, etc.</b> before relying it. The library uses architecture- and compiler-specific intrinsics, features and assembly language. We have seen cases where one compiler (open64 version 4.2.4) masquerades as another compiler (it defines __GNUC__) accepts extensions specific to the other compiler (__uint128_t) without error or warning, and then silently produces incorrect code. The only way to guard against this kind of misbehavior is to compile and run the tests with the compiler and options that you intend to use and the platform that you intend to run on.</p>
<h3><a class="anchor" id="kat"></a>
Known Answer Tests</h3>
<p>Testing that your compiled code computes the same "Known Answers" as the reference implementation which has been subjected to the Crush batteries of statistical tests is critically important.</p>
<p>The file <code>examples/kat_vectors</code> contains a few thousand "Known Answer
Test" vectors, i.e., tuples of (method, counter, key, answer). The source file katc.c is incorporated into kat_c.c (C), kat_cpp.cpp (C++), kat_cuda.cu (CUDA) and kat_opencl.c (OpenCL), which are compiled into kat_c, kat_cpp, kat_cuda and kat_opencl, respectively. Each of these will read kat_vectors and verify that the compiled code obtains the same "known answers".</p>
<p>The kat vectors are not language-specific. Implementations of CBRNGs in other languages could also be validated against <code>kat_vectors</code>. The kat vectors are also byte-order independent. In other words, the CBRNGs in the library should produce the same numerical results on little-endian and big-endian hardware, but this behavior is largely untested.</p>
<h3><a class="anchor" id="ut"></a>
Unit Tests</h3>
<p>examples/ also contains tests of specific components of the library. While not exhaustive, these tests verify that a variety of invariants are satisfied by the public methods (e.g., that incr(N) is the same as incr() N times). They also serve to verify some of the compile-time feature-test logic which, if incorrect can lead to mysterious errors (e.g., is it necessary to <code>include <smmintrin.h></code>). Unit tests include:</p>
<ul>
<li>
ut_features - verifies compile-time feature-test logic. </li>
<li>
ut_carray - verifies the capabilities of the <a class="el" href="group__arrayNxW.html">r123arrayNxW</a> types. </li>
<li>
ut_M128 - verifies the capabilities of the <a class="el" href="structr123m128i.html">r123m128i</a> type (only when SSE2 is available). </li>
<li>
ut_ReinterpretCtr - verifies the <a class="el" href="structr123_1_1ReinterpretCtr.html">r123::ReinterpretCtr</a> wrapper template. </li>
<li>
ut_Engine - verifies the capabilities of the <a class="el" href="structr123_1_1Engine.html">r123::Engine</a> wrapper template. </li>
<li>
ut_aes - verifies that the <a class="el" href="group__AESNI.html">AESNI</a> cbrngs match known answers from FIPS-197. </li>
<li>
ut_gsl - tests the <a class="el" href="gsl__cbrng_8h.html#af561a004eef8e93cdfd6b255a8a1eb75">GSL_CBRNG</a> adapter <b>Requires the GNU Scientific Library</b>. </li>
</ul>
<h2><a class="anchor" id="examples"></a>
Examples</h2>
<h3><a class="anchor" id="simple"></a>
Simple examples in C and C++</h3>
<p>There are two extremely short examples that show all the code necessary to obtain and print a few random numbers in C and C++: </p>
<ul>
<li>
simple.c </li>
<li>
simplepp.cpp </li>
</ul>
<h3><a class="anchor" id="generation"></a>
Generation of uniformly distributed real values.</h3>
<p>The uniformly distributed integers that the CBRNGs produce are rarely what is required by applications. Sampling other distributions is beyond the scope of Random123. Many distributions can be sampled with GSL (using <<a class="el" href="gsl__cbrng_8h.html">Random123/conventional/gsl_cbrng.h</a>> or with C++11's <random> (using <<a class="el" href="MicroURNG_8hpp.html">Random123/MicroURNG.hpp</a>> or <<a class="el" href="Engine_8hpp.html">Random123/conventional/Engine.hpp</a>>. Nevertheless, some distributions are so simple that the machinery of <random> or GSL seems like overkill. We provide code to generate uniformly distributed real numbers in the range (0, 1) and (-1, 1) in two header files: </p>
<ul>
<li>
uniform.hpp </li>
<li>
u01fixedpt.h </li>
</ul>
<p>We encourage you to copy these header files and use them (or modify them) to suit your needs. They are not as thoroughly tested or as portable as the headers in the library itself, but they should be safe to use on any platform with IEEE-754 floating point support. They are documented in comments in the files themselves.</p>
<h3><a class="anchor" id="pi"></a>
Estimating pi using different APIs</h3>
<p>Using random numbers to estimate pi is a classic example. The idea is to choose points at random in a square and to count how many of them lie within the inscribed circle. Since the area of the square is 4*r^2 and the area of the circle is pi*r^2, the ratio of the number of points in the circle to the total number of points should approach pi/4 as the number of points grows.</p>
<p>We give several examples of pi estimation, each of which illustrates a slightly different API</p>
<ul>
<li>
pi_capi - using only the basic C API </li>
<li>
pi_cppapi - using only the basic C++ API </li>
<li>
pi_u01 - using the C++ API and uniform.hpp </li>
<li>
pi_gsl - using a Random123 generator, but a gsl distribution to obtain real-valued random numbers. <b>Requires the GNU Scientific Library</b> </li>
<li>
pi_microurng - using a Random123 generator, but a C++0x <random> distribution to obtain real-valued random numbers </li>
<li>
pi_cuda - using the Random123 library with CUDA, runnable on an NVIDIA GPU </li>
<li>
pi_cudapp - using the C++ API with CUDA, runnable on an NVIDIA GPU </li>
<li>
pi_opencl - using the Random123 library with OpenCL, runnable on any OpenCL platform: e.g. NVIDIA or ATI GPUs or Intel or AMD CPUs. The actual compute kernel lives in the <code>pi_opencl_kernel.ocl</code> file and is transformed by <code>gencl.sh</code> into strings that get included in <code>pi_opencl.c</code>, since the OpenCL kernels get compiled for the target OpenCL platform at run-time </li>
<li>
pi_aes - uses the AESNI4x32 Random123 generator </li>
</ul>
<h2><a class="anchor" id="timers"></a>
Measuring performance</h2>
<p>We include some timing harnesses that can be used to measure the performance of these CBRNGs on various platforms. These timing harnesses report a cycles-per-byte (cpB) metric, which should be independent of clock-rate or number of cores, but depends on compilers and the architecture of the processor being run on. They also report aggregate throughput in GB/sec: a more direct measure of performance, but one that depends on clock speed and number of cores being used. The timing harnesses are obscured by tricks required for portability across platforms and CBRNG type. As a result, they are not recommended as examples of the use of library and its APIs.</p>
<ul>
<li>
time_serial - uses the C API and reports performance for a single core. </li>
<li>
timers - uses the C++ API, and is the only tool that reports AESNI1xm128i and ARS1xm128i performance (if your CPU supports the AES-NI instruction extensions). </li>
<li>
time_thread - uses the C API and pthreads to report multithreaded performance, uses all cores available on the platform. </li>
<li>
time_cuda - uses the C API within NVIDIA CUDA to run on NVIDIA GPUs. </li>
<li>
time_opencl - uses the C API within OpenCL to run on GPUs or CPUs. </li>
</ul>
<p>time_serial, time_thread, time_cuda, time_opencl all use a common kernel defined in time_random123.h. They all use various util_* header files for utility functions and platform-related boilerplate (also used by the pi_* examples). </p>
</div>
<!--- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Defines</a></div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<hr class="footer"/><address class="footer"><small>Generated on Mon Mar 7 2016 18:34:00 for Random123-1.09 by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
</body>
</html>
|