A typical algorithm for random number generators is as follows:
Create and initialize the object for basic random number generator.
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 of 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.
Buffer API
#include <iostream> #include <vector> #include “CL/sycl.hpp” #include “mkl_rng_sycl.hpp” int main() { cl::sycl::queue queue; const size_t n = 10000; std::vector<double> r(n); // create basic random number generator object mkl::rng::philox4x32x10 engine(queue, SEED); // create distribution object mkl::rng::gaussian<double, mkl::rng::gaussian_method::icdf> distr(5.0, 2.0); { // buffer for random numbers cl::sycl::buffer<double, 1> r_buf(r.data(), r.size()); // perform generation mkl::rng::generate(distr, engine, n, r_buf); } double s = 0.0; for(int i = 0; i < n; i++) { s += r[i]; } s /= n; std::cout << “Average = ” << s << std::endl; return 0; }
USM API
#include <iostream> #include <vector> #include “CL/sycl.hpp” #include “mkl_rng_sycl.hpp” int main() { cl::sycl::queue queue; const size_t n = 10000; // create USM allocator cl::sycl::usm_allocator<double, cl::sycl::usm::alloc::shared> allocator(queue); // create vector with USM allocator std::vector<double, decltype(allocator)> r(n, allocator); // create basic random number generator object mkl::rng::philox4x32x10 engine(queue, SEED); // create distribution object mkl::rng::gaussian<double, mkl::rng::gaussian_method::icdf> distr(5.0, 2.0); // perform generation auto event = mkl::rng::generate(distr, engine, n, r.data()); // cl::sycl::event object is returned by generate function for synchronization event.wait(); // synchronization can be also done by queue.wait() double s = 0.0; for(int i = 0; i < n; i++) { s += r[i]; } s /= n; std::cout << “Average = ” << s << std::endl; return 0; }
You can also use USM with raw pointers by using the cl::sycl::malloc_shared function.
Additionally, examples that demonstrate usage of random number generators functionality are available in:
${MKL}/examples/sycl/rng