random123

Counter-based Random Number Generators
git clone git://git.meso-star.com/random123.git
Log | Files | Refs | README | LICENSE

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&nbsp;--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&nbsp;(Linaro&nbsp;GCC&nbsp;4.8-2014.04)&nbsp;4.8.3&nbsp;20140401&nbsp;(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