README.md (19819B)
1 # Random123: a Library of Counter-Based Random Number Generators 2 3 <!-- Note that this file is both README.md and the doxygen mainpage. 4 It is minimally processed to uncomment the @ref directives 5 before doxygen is run on it. --> 6 7 The Random123 library is a collection of counter-based random 8 number generators (<!-- @ref CBRNG--> "CBRNGs") for CPUs (C and C++) and GPUs (CUDA and OpenCL), as described in 9 <a href="http://dl.acm.org/citation.cfm?doid=2063405"><i>Parallel Random Numbers: As Easy 10 as 1, 2, 3</i>, Salmon, Moraes, Dror & Shaw, SC11, Seattle, Washington, USA, 2011, ACM </a>. 11 They are intended for use in statistical 12 applications and Monte Carlo simulation 13 and have passed all of the rigorous 14 SmallCrush, Crush and BigCrush tests in the 15 <a href="http://www.iro.umontreal.ca/~simardr/testu01/tu01.html"> 16 extensive TestU01 suite</a> of statistical tests for random number generators. 17 They are **not** suitable for use in cryptography or security 18 even though they are constructed using principles drawn from cryptography. 19 20 The Random123 library is implemented entirely in header files. 21 See [below](#installation-and-testing), for how to 22 install and use the library, and how to generate documentation 23 with doxygen. 24 25 CBRNGs are as fast as, or faster than conventional RNGs, much 26 easier to parallelize, use minimal memory/cache resources, and 27 require very little code. On modern architectures, the 28 Random123 CBRNGs require a few cycles per byte of random data 29 returned and return random data in convenient sizes (arrays of 30 two or four elements, each of which is an unsigned integer of 32 31 or 64 bits). The range of random numbers is the full 32 representable range of the 32 or 64 bit unsigned integer) 33 The `<Random123/uniform.h>` header contains utility functions 34 to convert 32- and 64-bit unsigned integers to open or closed 35 ranges of single or double precision floating point numbers. 36 37 The Random123 library was written by John Salmon and Mark Moraes. 38 It is available at <a href="https://github.com/DEShawResearch/random123"> 39 https://github.com/DEShawResearch/random123</a> with documentation at 40 <a href="https://deshawresearch.github.io/random123"> 41 https://deshawresearch.github.io/random123</a>. 42 Archived releases are also 43 available from 44 <a href="http://deshawresearch.com/resources_random123.html"> 45 http://deshawresearch.com/resources_random123.html.</a> Please see 46 the <!-- @ref LICENSE--> "LICENSE" for terms and conditions. 47 48 ## Overview 49 50 Unlike conventional RNGs, counter-based RNGs are 51 *stateless* functions (or function classes i.e. functors) whose 52 arguments are a *counter*, and a *key* 53 that return a result of the same type as the counter. 54 55 result = CBRNGname(counter, key) 56 57 The returned result is a deterministic function of the key and counter, 58 i.e. a unique (counter, key) tuple will always produce the same 59 result. The result is highly sensitive to small changes in the inputs, 60 so that the sequence of values produced by simply 61 incrementing the counter (or key) is effectively indistinguishable from a 62 sequence of samples of a uniformly distributed random variable. 63 64 For all the CBRNGs in the Random123 library, the result and 65 counter are the same type, specifically an array of *N* words, 66 where words have a width of *W* bits, encapsulated in 67 <!-- @ref arrayNxW--> "r123arrayNxW" structs, or equivalently, for C++, in 68 the <!-- @ref r123::Array1x32--> "ArrayNxW" typedefs in the r123 69 namespace. Keys are usually also arrayMxW types, but sometimes M is 70 a different size than the counter N (e.g. Philox keys have half the 71 number of elements as the counter, Threefry and ARS have the same number, 72 AES uses an opaque key type rather than an array) The N random 73 numbers returned in `result.v[]` are unsigned integers of 74 width W (32 or 64), and the range of the random numbers is the full 75 range of the unsigned integer of that width (i.e. 0 to 2^W-1) 76 77 In C++, all public names (classes, structs, typedefs, etc) are in the 78 `r123` namespace. In C, the public names (functions, enums, structs, 79 typedefs) begin either with `r123` or with one of the RNG family names, e.g., 80 `threefry`, `philox`, `ars`, `aesni`. The RNG functions themselves have names like 81 `philox4x32`. C++ class names are capitalized, e.g., `Threefry4x32`. 82 83 <!-- @anchor families--> 84 ## The different families of Random123 generators 85 86 Several families of CBRNGs are available in this version of the library: 87 <ul> 88 <li> <!-- @ref ThreefryNxW--> "Threefry" is a **non-cryptographic** 89 adaptation of the Threefish block cipher from the <a href="http://www.skein-hash.info/"> Skein Hash Function</a>. 90 See <!-- @ref--> r123::Threefry2x32, <!-- @ref--> r123::Threefry4x32, <!-- @ref--> r123::Threefry2x64, <!-- @ref--> r123::Threefry4x64. 91 <li> <!-- @ref PhiloxNxW--> "Philox" uses a Feistel network and integer multiplication. 92 See <!-- @ref--> r123::Philox2x32, <!-- @ref--> r123::Philox4x32, <!-- @ref--> r123::Philox2x64, <!-- @ref--> r123::Philox4x64. 93 The Nx64 forms are only available on hardware 94 that supports 64-bit multiplication producing a 128-bit result. 95 <li> <!-- @ref AESNI--> "AESNI" uses the Advanced Encryption Standard (AES) New Instruction, 96 available on certain modern x86 processors (some models of Intel Westmere and Sandy Bridge, 97 and AMD Interlagos, as of 2011). AESNI CBRNGs can operate on four 32bit words (internally converting 98 them to the 128bit SSE type needed by the AES-NI instructions, or on a single m128i "word", 99 which holds the SSE type. 100 See <!-- @ref--> r123::AESNI4x32, <!-- @ref--> r123::AESNI1xm128i. 101 <li> <!-- @ref AESNI--> "ARS" (Advanced Randomization System) is a **non-cryptographic** simplification of <!-- @ref AESNI--> "AESNI". 102 See <!-- @ref--> r123::ARS4x32_R, <!-- @ref--> r123::ARS1xm128i_R. 103 </ul> 104 105 ## Installation and Testing 106 107 The Random123 library is implemented entirely in header files. Thus, 108 there is nothing to compile before using it and nothing to link after 109 you `#include` it in your source files. Simply direct your C or 110 C++ compiler to find the header files in the `include/` directory 111 of the cloned repo and use the Random123 112 header files, types, and functions in your application. 113 114 Users and packagers are **STRONGLY ADVISED** run `make check` to 115 compile and run the tests in `tests/` before using Random123 in an 116 application (see <!-- @ref TestsREADME--> "tests/README"). Do not use 117 the library if any tests fail. (It is not a failure for a test to 118 report that it cannot run because of missing hardware capabilities 119 like 64bit multiply, SSE, AES-NI or compiler capabilities) 120 121 The top-level GNUmakefile also has "install", "html", and 122 "install-html" targets. The former will copy header files to 123 \$(DESTDIR)\$(includedir) (default: /usr/local/include). The second 124 will run doxygen, replacing anything in docs/html. The last will 125 install the documentation in \$(DESTDIR)\$(docdir)/html (default: 126 /usr/local/doc/Random123/html). 127 128 ## Usage 129 130 ### C++ API 131 132 A typical C++ use case might look like: 133 134 135 #include <Random123/philox.h> 136 137 typedef r123::Philox4x32 RNG; 138 RNG rng; 139 RNG::ctr_type c={{}}; 140 RNG::ukey_type uk={{}}; 141 uk[0] = ???; // some user_supplied_seed 142 RNG::key_type k=uk; 143 144 for(...){ 145 c[0] = ???; // some loop-dependent application variable 146 c[1] = ???; // another loop-dependent application variable 147 RNG::ctr_type r = rng(c, k); 148 // use the random values in r for some operation related to 149 // this iteration on objectid 150 } 151 152 On each iteration, `r` contains an array of 4 32-bit random values that 153 will not be repeated by any other call to `rng` as long as `c` and `k` 154 are not reused. 155 156 In the example above, we use the <!-- @ref--> r123::Philox4x32, but any of the 157 other <!-- @ref CBRNG--> "CBRNGs" would serve equally well. Also note that 158 for most CBRNGs, the `ukey_type` and the `key_type` are identical; the code 159 could just as well ignore the `ukey_type` and directly construct the 160 `key_type`. However, for the <!-- @ref AESNI--> "AESNI" CBRNGs, the `key_type` is opaque, and 161 must be constructed from a `ukey_type`, as shown. 162 163 ### The C API 164 165 In C, the example above could be written as: 166 167 #include <Random123/philox.h> 168 169 philox4x32_ctr_t c={{}}; 170 philox4x32_ukey_t uk={{}}; 171 172 uk.v[0] = user_supplied_seed; 173 philox4x32_key_t k = philox4x32keyinit(uk); 174 175 for(...){ 176 c.v[0] = ???; /* some loop-dependent application variable */ 177 c.v[1] = ???; /* another loop-dependent application variable */ 178 philox4x32_ctr_t r = philox4x32(c, k); 179 } 180 181 182 In C, access to the contents of the counter and key is through 183 the fixed-size array member `v`. 184 185 ## The CUDA platform 186 187 All relevant functions in the C and C++ APIs for Random123 are declared 188 as CUDA device functions if they are included in a CUDA kernel source file 189 and compiled with a CUDA compiler (nvcc). They can be used exactly 190 as described/documented for regular C or C++ programs. It is now 191 possible to use Random123 functions in 192 both the host portion and the device portion of the same .cu source file. 193 The Nx32 forms were faster than the Nx64 variants on 194 32-bit GPU architectures in 2011, but we haven't measured this recently. 195 196 It has been reported that Random123 uses 16 bytes of 197 static memory per thread. This is undesirable and not intentional, 198 but we do not have a workaround other than to suggest adjusting memory 199 allocation accordingly. 200 201 The 202 pi_cuda.cu and pi_cudapp.cu examples illustrate the use of CUDA. 203 204 In a machine with different GPUs, the 205 R123EXAMPLE_ENVCONF_CUDA_DEVICE environment variable can be set 206 to a unique substring of the CUDA GPU device name to select a 207 specific GPU (else examples try to choose the GPU with the most 208 cores) 209 210 ## The OpenCL platform 211 212 The functions in the Random123 C API can all be used in 213 OpenCL kernels, just as in regular C functions. 214 As with CUDA, the Nx32 forms are faster than the Nx64 variants on current (2011) 215 32-bit GPU architectures. 216 217 The `pi_opencl.c` and `pi_opencl_kernel.ocl` examples illustrate the use 218 of OpenCL. 219 220 In a machine with different OpenCL devices, the 221 R123EXAMPLE_ENVCONF_OPENCL_DEVICE environment variable can be 222 set to a unique substring of the OpenCL device name to select a 223 specific OpenCL device (else examples try to choose the device 224 with the most cores) 225 226 ## C++11 \<random\> interface 227 228 In addition to the stateless ("pure/functional") C++ API above, 229 the Random123 package includes two C++ classes 230 that leverage the C++11 \<random\> API. 231 232 <ul> 233 <li>r123::MicroURNG provides an adapter class that provides a 234 more conventional interface compatible with the C++11 URNG 235 (uniform random number generator) API; the MicroURNG adapter can 236 be used with C++11 random number distributions and is 237 fast/lightweight enough that a new MicroURNG can be instantiated 238 with a unique key,counter tuple and used for each call to a 239 distribution, there is little or no overhead to creating 240 billions of unique MicroURNGs. This adapter retains one of the 241 key advantages of CBRNGs -- complete application control over 242 the RNG state. 243 <li>r123::Engine provides the C++11 Random Engine API. This can 244 also be used with any of the C++11 random distributions, but 245 sacrifices the application control over RNG state that is a 246 defining characteristic of CBRNGs. 247 </ul> 248 249 ## The GNU Scientific Library (GSL) interface 250 251 In addition to the stateless ("pure/functional") C API above, 252 the Random123 package includes two C adapter interfaces 253 to the <a href="http://www.gnu.org/s/gsl/">GNU Scientific Library (GSL).</a> 254 255 <ul> 256 <li>The <!-- @ref--> GSL_MICRORNG macro allows the application to 257 define a GSL random number generator. It 258 can be used with GSL random distributions but still provides the 259 application with complete control over the RNG state (it is 260 analogous to the MicroURNG class, in that it uses shorter 261 periods, and is intended to be instantiated in large numbers for 262 a few calls to the random distribution). 263 <li>The <!-- @ref--> GSL_CBRNG macro allows the application to create a GSL 264 RNG with a completely conventional interface, sacrificing 265 application control over the internal RNG state. 266 </ul> 267 268 ## Generating uniformly distributed and Gaussian distributed floats and doubles 269 270 The Random123 library provides generators for uniformly distributed 271 random **integers**. Often, applications want random **real** values or 272 samples from other distributions. The general problem of generating 273 samples from arbitrary distributions is beyond the scope of the Random123 274 library. One can, of course, use GSL or MicroURNG and the 275 distributions in the C++11 \<random\> library, but a few simple cases 276 are common enough that all that extra machinery seems like overkill. 277 We have included a few generic conversion utilities which developers may 278 find useful. 279 280 <ul> 281 <li> uniform.hpp - C++ functions that convert random integers to 282 random, uniformly distributed floating point values. 283 <li> u01fixedpt.h - C functions that convert random integers to 284 random, uniformly distributed, equi-spaced, i.e., fixed point, 285 values. 286 <li> boxmuller.hpp - C++ functions that take two 287 uniformly distributed integers (32 or 64 bit) and 288 return a pair of Gaussian distributed floats or doubles. 289 </ul> 290 291 The Box-Muller method of generating Gaussian random variables is 292 particularly well suited to Random123 because it deterministically 293 consumes exactly two uniform randoms to generate exactly two gaussian 294 randoms. It uses math library functions: sincos, log and sqrt which 295 may be slow on some platforms, but which are surprisingly fast on 296 others. Notably, on GPUs, the lack of branching in the Box-Muller 297 method and hardware support for math functions overcomes the 298 transcendental function overhead, making it the fastest generator of 299 Gaussians that we are aware of. 300 301 ## Examples 302 303 The <!-- @ref ExamplesREADME--> "examples/" directory, contains example code 304 intended to illustrate use of the library. 305 306 Complete, short programs estimate pi by counting the number of random 307 points that fall inside a circle inscribed in a square, demonstrating 308 the C, C++, AES, GSL, OpenCL, CUDA and C++11 APIs. The environment 309 variable R123EXAMPLE_ENVCONF_SEED can be set to any unsigned integer value to run 310 the example with a different seed. Many of the pi_* examples run different 311 numbers of iterations if that number is specified as the first argument 312 on the command line. 313 314 ### Tests and Benchmarks 315 316 The <!-- @ref TestsREADME--> "tests/" directory contains tests and benchmarks. 317 This code is complicated due to the fact that it is 318 largely "single source" for CUDA, OpenCL and CPU implmentations. 319 Developers are strongly discouraged from emulating its style. 320 It contains: 321 <ul> 322 <li> Unit tests for individual components and "known-answer-tests", which 323 should be run to ensure that these RNGs build correctly on desired platforms. 324 These help to provide assurance that the code is being compiled correctly. 325 <li> A variety of timing harnesses are provided 326 which measure performance of a variety of generators in different 327 programming environments. 328 </ul> 329 330 ## Portability 331 332 Although we have done our best to make Random123 portable and standards conforming, 333 it is an unfortunate fact that there is no portable code. There is only 334 code that has been ported. 335 336 Prior to release, we test Random123 on a variety of systems and with a 337 variety of toolchains that are readily available to us. Our 338 current test environment includes: 339 340 <ul> 341 <li> Linux, gcc-5.2.0, 6.3.0, 8.1.0, 10.1.0 using -march=native on Xeon hardware with 342 AES and SSE4_2 and AVX2 support. 343 <li> Linux, gcc-5.2.0 using -m32. 344 <li> Linux, clang-8.0.0 with libc++ (8.0.0) on Xeon hardware. 345 <li> Linux, CentOS7 using the vendor supplied gcc toolchain (4.8.5-16). 346 <li> Linux, Ubuntu 16.04(LTS) using the vendor supplied gcc toolchain (5.4.0-6ubuntu1-16.04.11). 347 <li> Linux, Ubuntu 16.04(LTS) using OpenCL beignet 1.1.1-2 and https://github.com/intel/compute-runtime/releases/tag/19.07.12410 348 <li> Linux, Ubuntu 18.04(LTS) with clang-11.0.1 and both libc++ and libstdc++. 349 <li> Linux, icc-18.0.3 and 19.1.2.254 on Xeon hardware with AES, SSE4 and AVX2 support. 350 <li> Linux, NVIDIA CUDA 10.0.130 with GTX 980 and 1080, and Titan RTX (aka Turing) hardware. 351 <li> MacOS, with Xcode-10.1 and Metal on a 2018 Mac mini. 352 </ul> 353 354 In the past, we have tested Random123 with additional toolchains and 355 hardware. Although we no longer test on these platforms, we know of 356 no reason that they should not work. 357 358 <ul> 359 <li>Linux, gcc (multiple versions from 3.4.3 through 6.3.0), on x86_64. 360 <li>Linux, gcc-4.1.2 and 4.4.1 on i686. 361 <li>Linux, gcc-4.8 on ARMv7 (32bit) Freescale/NXP LS1021A & ARM A53 (64bit) Freescale/NXP 1043A. 362 <li>Linux, clang-2.9, 3.0, 3.1, 3.3 and 3.6 on x86_64. 363 <li>Linux, clang-3.0 and 3.1 with lib++ (2012-04-19 svn checkout) on x86_64. 364 <li>Linux, clang-8.0.0 with libc++ on x86_64 365 <li>Linux, open64-4.2.4 on x86_64. 366 <li>Linux, Intel icc and icpc 12.0.2 on x86_64. 367 <li>Linux, NVIDIA CUDA 4.1.15, 4.2.6, 5.5.22 and 7.5.1. (NOTE: We recommend against the use of CUDA before 4.1) 368 <li>Linux, OpenCL (NVIDIA SDK 4.0.17) on GTX480, M2090, GTX580 and GTX680 GPUs. 369 <li>Linux, OpenCL (AMD APP SDK 2.4 or 2.5), on x86_64 CPUs and Radeon HD6970 GPUs. 370 <li>Linux, OpenCL (Intel OpenCL 1.5), on x86_64 CPUs. 371 <li>Solaris, both gcc-3.4.3 and Sun C/C++ 5.8, on x86_64. 372 <li>FreeBSD 8.2, gcc-4.2.1, on x86_64. 373 <li>MacOS X 5.8, gcc-4.0.1, on i686. 374 <li>MacOS X 5.8, llvm-2.9.1 on i686 (problems with catching C++ exceptions). 375 <li>Windows 7, Microsoft Visual Studio, version 10.0, Microsoft C/C++ compiler 16.00. 376 </ul> 377 378 Others have reported success on 379 <ul> 380 <li>MacOS, OpenCL on x86_64 CPUs 381 <li>Linux, gcc-4.7.2 on Powerpc64 (BlueGene/Q) 382 <li>Linux, Portland Group Compiler on Powerpc64 (BlueGene/Q) 383 <li>Linux, IBM xlc on Powerpc64 (BlueGene/Q) 384 <li>MacOS, Metal on x86_64 CPUs and AMD Radeon R9 M380 GPU 385 <li>MacOS Sierra and Scientific Linux with Nvidia GPU and CUDA 8 386 <li>Linux, on s390x 387 </ul> 388 389 ## Warnings 390 391 With some compilation options, the CUDA nvcc compiler warns about 392 unreachable code in array.h. The compiler doesn't recognize that the 393 code that is unreachable for some values of some macro parameters, is 394 actually reachable for other values of the parameters. It is possible 395 to disable that particular warning for a specific compilation unit by 396 adding -Wcudafe --diag_suppress=111 to the compilation command 397 line. 398 399 On our ARMv7 test platform, we suspect a compiler bug with -O3, 400 which does not seem to affect Random123 code itself, but 401 produces nondeterministic results from time_serial. The 402 offending compiler version was 403 "aarch64-fsl-linux-gcc (Linaro GCC 4.8-2014.04) 4.8.3 20140401 (prerelease)". 404 We slightly reordered a couple of innocuous statements (a 405 timer() and dprintf() call) in time_serial to avoid the bug, but 406 we would avoid -O3 on ARMv7 with that particular version of the 407 compiler at least. 408 409 ## Contributors 410 411 We welcome bug reports, bug fixes, ports, 412 general feedback and other enhancements to the 413 [issues](https://github.com/DEShawResearch/random123/issues) and 414 [pull requests](https://github.com/DEShawResearch/random123/pulls) pages of 415 our [github repo](https://github.com/DEShawResearch/random123/). 416 417 We are grateful for contributed bug-fixes and portability enhancements from the following users: 418 <ul> 419 <li> Geoffrey Irving and Gabriel Rockefeller - BlueGene/Q and powerpc ports 420 <li> Yan Zhou - MacOS and clang ports 421 <li> David Lawrie - allowing 64-bit philox to compile for both host and device with CUDA 422 <li> Bogdan Opanchuk - pointing out the inconsistent rotation constants in the implementation of threefry2xW in version 1.07 and earlier. 423 <li> Tom Schoonjans - Support for Metal (Apple's successor to OpenCL) 424 <li> Karl Magdsick - documentation in uniform.hpp 425 <li> KT Thompson - Visual Studio 2015 and ibm xlc compiler ports 426 </ul> 427 428