インテル® oneAPI DPC++ ライブラリー (インテル® oneDPL) は、以下を含む乱数の生成をサポートしています。
乱数エンジン。符号なし整数の乱数シーケンスを生成します。
乱数分布 (例: uniform_real_distribution)。乱数エンジンの出力をさまざまな統計分布に変換します。
乱数エンジンは、シードデータをエントロピー源として使用して疑似乱数を生成します。インテル® oneDPL は、カスタマイズされたエンジン向けにいくつかのクラス・テンプレートを提供しており、これらは <oneapi/dpl/random> ヘッダーで定義されています。
エンジン |
説明 |
---|---|
linear_congruential_engine |
線形合同アルゴリズムを実装します。 |
subtract_with_carry_engine |
キャリー付き減算アルゴリズムを実装します。 |
discard_block_engine |
破棄ブロックアダプターを実装します。 |
事前定義済みの乱数エンジンは、乱数エンジン・クラス・テンプレートをインスタンス化したものです。以下の型は、<oneapi/dpl/random> ヘッダーの oneapi::dpl:: 名前空間で定義されています。
種類 |
説明 |
---|---|
minstd_rand0 |
oneapi::dpl::linear_congruential_engine<std::uint32_t, 16807, 0, 2147483647> |
minstd_rand |
oneapi::dpl::linear_congruential_engine<std::uint32_t, 48271, 0, 2147483647> |
ranlux24_base |
oneapi::dpl::subtract_with_carry_engine<std::uint32_t, 24, 10, 24> |
ranlux48_base |
oneapi::dpl::subtract_with_carry_engine<std::uint64_t, 48, 5, 12> |
ranlux24 |
oneapi::dpl::discard_block_engine<ranlux24_base, 223, 23> |
ranlux48 |
oneapi::dpl::discard_block_engine<ranlux48_base, 389, 11> |
以下に示すエンジンは、乱数ベクトルを効率良く生成することができます。これらの型は、<oneapi/dpl/random> ヘッダーの oneapi::dpl:: 名前空間で定義されています。
種類 |
説明 |
---|---|
template<std::int32_t N> minstd_rand0_vec<N> |
oneapi::dpl::linear_congruential_engine<sycl::vec<std::uint32_t, N>, 16807, 0, 2147483647> minstd_rand0 (ベクトル生成の場合) |
template<std::int32_t N> minstd_rand_vec<N> |
oneapi::dpl::linear_congruential_engine<sycl::vec<std::uint32_t, N>, 48271, 0, 2147483647> minstd_rand (ベクトル生成の場合) |
template<std::int32_t N> ranlux24_base_vec<N> |
oneapi::dpl::subtract_with_carry_engine<sycl::vec<std::uint32_t, N>, 24, 10, 24> ranlux24_base (ベクトル生成の場合) |
template<std::int32_t N> ranlux48_base_vec<N> |
oneapi::dpl::subtract_with_carry_engine<sycl::vec<std::uint64_t, N>, 48, 5, 12> ranlux48_base (ベクトル生成の場合) |
template<std::int32_t N> ranlux24_vec<N> |
oneapi::dpl::discard_block_engine<ranlux24_base_vec<N>, 223, 23> ranlux24 (ベクトル生成の場合) |
template<std::int32_t N> ranlux48_vec<N> |
oneapi::dpl::discard_block_engine<ranlux48_base_vec<N>, 389, 11> ranlux48 (ベクトル生成の場合) |
乱数分布は、乱数エンジンの出力が定義された統計的確率密度関数に従って分布するように処理します。これらの型は、<oneapi/dpl/random> ヘッダーの oneapi::dpl:: 名前空間で定義されています。
分布 |
説明 |
---|---|
uniform_int_distribution |
範囲内に均等に分布された整数値を生成します。 |
uniform_real_distribution |
範囲内に均等に分布された実数値を生成します。 |
normal_distribution |
正規分布 (ガウス分布) に従って実数値を生成します。 |
exponential_distribution |
指数分布に従って実数値を生成します。 |
bernoulli_distribution |
ベルヌーイ分布に従って実数値を生成します。 |
geometric_distribution |
幾何分布に従って実数値を生成します。 |
weibull_distribution |
ワイブル分布に従って実数値を生成します。 |
lognormal_distribution |
対数正規分布に従って実数値を生成します。 |
extreme_value_distribution |
極値 (ガンベル) 分布に従って実数値を生成します。 |
cauchy_distribution |
コーシー分布に従って実数値を生成します。 |
乱数生成は、データ並列 C++ (DPC++) のデバイスコードとホストコードの両方で利用できます。次に例を示します。
#include <iostream>
#include <vector>
#include <CL/sycl.hpp>
#include <oneapi/dpl/random>
int main() {
sycl::queue queue(sycl::default_selector{});
std::int64_t nsamples = 100;
std::uint32_t seed = 777;
std::vector<float> x(nsamples);
{
sycl::buffer<float, 1> x_buf(x.data(), sycl::range<1>(x.size()));
queue.submit([&] (sycl::handler &cgh) {
auto x_acc =
x_buf.template get_access<sycl::access::mode::write>(cgh);
cgh.parallel_for<class count_kernel>(sycl::range<1>(nsamples),
[=](sycl::item<1> idx) {
std::uint64_t offset = idx.get_linear_id();
// minstd_rand エンジンを作成
oneapi::dpl::minstd_rand engine(seed, offset);
// float 型の uniform_real_distribution 分布を作成
oneapi::dpl::uniform_real_distribution<float> distr;
// float 型の乱数を生成
auto res = distr(engine);
// 結果を x_acc にストア
x_acc[idx] = res;
});
});
}
std::cout << "\nFirst 5 samples of minstd_rand with scalar generation" << std::endl;
for(int i = 0; i < 5; i++) {
std::cout << x.begin()[i] << std::endl;
}
std::cout << "\nLast 5 samples of minstd_rand with scalar generation" << std::endl;
for(int i = 0; i < 5; i++) {
std::cout << x.rbegin()[i] << std::endl;
}
return 0;
}