oneMKL RNG 使用モデル

目次

oneMKL RNG 使用モデル#

乱数生成器の一般的なアルゴリズムは次のとおりです:

  1. 基本的な乱数生成器のオブジェクトを作成して初期化します。

    • 必要に応じて skip_ahead または leapfrog 関数を使用します (CPU デバイスの乱数生成と並行して使用されます)。

  2. 配布生成器のオブジェクトを作成して初期化します。

  3. 適切な統計分布を持つ乱数を取得するには、生成ルーチンを呼び出します。

次の例は、基本生成器 (エンジン) 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