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:
- Crush Resistance – CBRNGs pass rigorous and extensive statistical tests while Mersenne Twister and XORWOW are not as accurate.
- 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
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:
- General discussion forums on the ArrayFire Google Group
- Live discussion chat on the ArrayFire Gitter
- Issue reports on the ArrayFire GitHub
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.