oneMKL RNG Usage Model#
A typical algorithm for random number generators is as follows:
Create and initialize the object for basic random number generator.
Use the
skip_ahead
orleapfrog
function if it is required (used in parallel with random number generation for CPU devices).
Create and initialize the object for distribution generator.
Call the generate routine to get random numbers with appropriate statistical distribution.
The following example demonstrates generation of random numbers that is output from basic generator (engine) PHILOX4X32X10. The seed is equal to 777. The generator is used to generate 10,000 normally distributed random numbers with parameters \(a = 5\) and \(\sigma = 2\). The purpose of the example is to calculate the sample mean for normal distribution with the given parameters.
Example of RNG Usage#
Buffer API
1#include <iostream>
2#include <vector>
3
4
5#include <sycl/sycl.hpp>
6#include "oneapi/mkl/rng.hpp"
7#define SEED 777
8
9
10int main() {
11 sycl::queue queue;
12
13
14 const size_t n = 10000;
15 std::vector<double> r(n);
16
17
18 // create basic random number generator object
19 oneapi::mkl::rng::philox4x32x10 engine(queue, SEED);
20 // create distribution object
21 oneapi::mkl::rng::gaussian<double, oneapi::mkl::rng::gaussian_method::icdf> distr(5.0, 2.0);
22
23
24 {
25 // buffer for random numbers
26 sycl::buffer<double, 1> r_buf(r.data(), r.size());
27 // perform generation
28 oneapi::mkl::rng::generate(distr, engine, n, r_buf);
29
30
31 }
32
33
34 double s = 0.0;
35 for(int i = 0; i < n; i++) {
36 s += r[i];
37 }
38 s /= n;
39
40
41 std::cout << "Average = " << s << std::endl;
42
43
44 return 0;
45}
USM API
1#include <iostream>
2#include <vector>
3#include <sycl/sycl.hpp>
4#include "oneapi/mkl/rng.hpp"
5#define SEED 777
6
7
8int main() {
9 sycl::queue queue;
10
11
12 const size_t n = 10000;
13
14
15 // create USM allocator
16 sycl::usm_allocator<double, sycl::usm::alloc::shared> allocator(queue);
17
18
19 // create vector with USM allocator
20 std::vector<double, decltype(allocator)> r(n, allocator);
21
22
23 // create basic random number generator object
24 oneapi::mkl::rng::philox4x32x10 engine(queue, SEED);
25 // create distribution object
26 oneapi::mkl::rng::gaussian<double, oneapi::mkl::rng::gaussian_method::icdf> distr(5.0, 2.0);
27
28
29 // perform generation
30 auto event = oneapi::mkl::rng::generate(distr, engine, n, r.data());
31
32
33 // sycl::event object is returned by generate function for synchronization
34 event.wait(); // synchronization can be also done by queue.wait()
35
36
37 double s = 0.0;
38 for(int i = 0; i < n; i++) {
39 s += r[i];
40 }
41 s /= n;
42
43
44 std::cout << "Average = " << s << std::endl;
45
46
47 return 0;
48 }
Additionally, examples that demonstrate usage of random number generators functionality are available in:
${MKL}/share/doc/mkl/examples/sycl/rng/source