Random Number Generators in ArrayFire v3.4

Kumar AatishArrayFire Leave a Comment

Pseudorandom number generators (PRNGs) are an integral part of many applications in statistics, modeling, and simulations. In ArrayFire v3.4, we introduce random number generation enhancements that improve speed, accuracy, storage, and unity among the ArrayFire backends.

Previously in ArrayFire v3.3, each ArrayFire backend used a different PRNG. In ArrayFire v3.4, each ArrayFire backend is able to select from among 3 different random number generators.

ArrayFire v3.3 (platform specific) ArrayFire v3.4 (all generators on all platforms)
CUDA XORWOW CUDA,
OpenCL,
CPU
Philox (CBRNG),
Threefry (CBRNG),
Mersenne Twister
OpenCL Threefry (CBRNG)
CPU Mersenne Twister

As seen above, the XORWOW generator (which was only available for CUDA devices previously) has been replaced by the Philox generator which is available along with Threefry and Mersenne Twister on all ArrayFire supported devices. Philox and Threefry are Counter Based Random Number Generators (CBRNGs). CBRNGs have two major advantages over traditional PRNGs:

  1. Crush Resistance – CBRNGs pass rigorous and extensive statistical tests while Mersenne Twister and XORWOW are not as accurate.
  2. Smaller Storage Space – The amount of storage space required to maintain the state of CBRNGs is minimal compared to Mersenne Twister.

For these reasons, ArrayFire v3.4 now includes both the Philox and Threefry CBRNGs. Mersenne Twister will continue to be maintained due to its ubiquity in technical computing.

Usage

Users create a random engine object that contains the state of the engine. These objects are initialized by specifying the random engine type and seed. Then the objects are passed into the randu and randn functions which generate the sequence of random numbers.

unsigned seed;
unsigned elem;
af::randomEngine rp(AF_RANDOM_ENGINE_PHILOX, seed);
af::array R = af::randu(elem, f32, rp);

Another method to select a random engine algorithm is to set the default random engine type. If needed the desired seed can be specified as well. Subsequent calls to randu  and randn  will utilize the default random engine. These default random engines contain the state of the engine and can be reset or changed by the user.

unsigned seed;
setSeed(seed);
setDefaultRandomEngine(AF_RANDOM_ENGINE_THREEFRY);
//Or AF_RANDOM_ENGINE_DEFAULT, AF_RANDOM_ENGINE_PHILOX, AF_RANDOM_ENGINE_MERSENNE
af::array R = af::randu(elem, f32);//Utilizes threefry PRNG algorithm initialized with 'seed'

The default random engine type is AF_RANDOM_ENGINE_PHILOX because it has the best statistical properties among the available generators. For further details on usage, please refer to the documentation.

Performance Results

OpenCL Backend Performance

OpenCL Backend Performance

CUDA Backend Performance

CUDA Backend Performance

Future Plans

Future releases of ArrayFire will include the XORWOW and MRG32K3a generators for all platforms.

Download

ArrayFire v3.4 can be downloaded from these locations:

Community

ArrayFire is continually improving through the addition of new random number generators and statistical functions. We welcome your feedback:

Finally, as you find success with ArrayFire, we invite you to contribute a post to this blog to share with the broader community. Email scott@arrayfire.com to contribute to this blog.

Leave a Reply

Your email address will not be published. Required fields are marked *