oneMKL RNG 使用モデル#
乱数生成器の一般的なアルゴリズムは次のとおりです:
基本的な乱数生成器のオブジェクトを作成して初期化します。
必要に応じて
skip_aheadまたはleapfrog関数を使用します (CPU デバイスの乱数生成と並行して使用されます)。
配布生成器のオブジェクトを作成して初期化します。
適切な統計分布を持つ乱数を取得するには、生成ルーチンを呼び出します。
次の例は、基本生成器 (エンジン) PHILOX4X32X10 から出力される乱数生成を示しています。シードは 777 に等しくなります。この生成器は、パラメーター \(a = 5\) および \(\sigma = 2\) を持つ 10,000 個の正規分布乱数を生成するのに使用されます。この例の目的は、指定されたパラメーターを使用して正規分布のサンプル平均を計算することです。
RNG 使用例#
バッファー 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
10 int main() {
11 sycl::queue queue;
12
13
14 const size_t n = 10000;
15 std::vector<double> r(n);
16
17
18 // 基本的な乱数生成器オブジェクトを作成
19 oneapi::mkl::rng::philox4x32x10 engine(queue, SEED);
20 // 分布オブジェクトを作成
21 oneapi::mkl::rng::gaussian<double, oneapi::mkl::rng::gaussian_method::icdf> distr(5.0, 2.0);
22
23
24 {
25 // 乱数用バッファー
26 sycl::buffer<double, 1> r_buf(r.data(), r.size());
27 // 生成を実行
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
8 int main() {
9 sycl::queue queue;
10
11
12 const size_t n = 10000;
13
14
15 // USMアロケーターを作成
16 sycl::usm_allocator<double, sycl::usm::alloc::shared> allocator(queue);
17
18
19 // USMアロケーターでベクトルを作成
20 std::vector<double, decltype(allocator)> r(n, allocator);
21
22
23 // 基本的な乱数生成器オブジェクトを作成
24 oneapi::mkl::rng::philox4x32x10 engine(queue, SEED);
25 // 分布オブジェクトを作成
26 oneapi::mkl::rng::gaussian<double, oneapi::mkl::rng::gaussian_method::icdf> distr(5.0, 2.0);
27
28
29 // 生成を実行
30 auto event = oneapi::mkl::rng::generate(distr, engine, n, r.data());
31
32
33 // sycl::eventオブジェクトは同期のための生成関数によって返される
34 event.wait(); // 同期は 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 }さらに、乱数生成器機能の使用方法を示す例が以下で提供されています。
${MKL}/share/doc/mkl/examples/sycl/rng/source