Main Content

GPU 上の乱数ストリーム

乱数発生関数 randrandi および randn が GPU 上での計算に使用する発生器の既定の設定は、CPU 上での計算に使用する設定とは異なります。GPU と CPU で再現可能な乱数列を生成するように、乱数発生器の動作を変更できます。

次の表は、クライアントおよびワーカーの MATLAB® セッションにおける GPU および CPU の既定の設定をまとめています。

 発生器シード正規変換
クライアント CPU'Twister' または 'mt19937ar'0'Ziggurat'
ワーカー CPU'Threefry' または 'Threefry4x64_20'0'Inversion'
GPU (クライアントまたはワーカー)'Threefry' または 'Threefry4x64_20'0'BoxMuller'

ほとんどの場合、GPU 上の既定の乱数発生器が、クライアントまたはワーカーの CPU 上の既定の発生器と異なっていても問題はありません。しかし、GPU と CPU の両方で同じ結果を再現する必要がある場合は、発生器を適切に設定できます。

クライアント CPU および GPU

新しい MATLAB セッションで、MATLAB は CPU と GPU で異なる乱数列を生成します。

Rc = rand(1,4)
Rc =
    0.8147    0.9058    0.1270    0.9134
Rg = rand(1,4,'gpuArray')
Rg =
    0.3640    0.5421    0.6543    0.7436

GPU と CPU の両方で同じ乱数列を生成する必要がある場合、発生器の設定を一致させることができます。

GPU 上で使用できる乱数発生器アルゴリズムには 'Threefry''Philox' および 'CombRecursive' の 3 つがあります。すべてが CPU でサポートされています。次の表は、これらの発生器とそのプロパティのアルゴリズムの一覧です。

キーワード発生器複数のストリームとサブストリームのサポート完全精度での近似周期
"Threefry" または "Threefry4x64_20"Threefry 4x64 発生器、20 ラウンドあり2514 (長さが 2258 の 2256 個のストリーム)
"Philox" または "Philox4x32_10"Philox 4x32 発生器、10 ラウンドあり2193 (長さが 2129 の 264 個のストリーム)
"CombRecursive" または "mrg32k3a"結合多重再帰発生器あり2191 (長さが 2127 の 263 個のストリーム)

rng および gpurng を使用して、CPU および GPU 上の発生器アルゴリズムとシードをそれぞれ設定できます。GPU 乱数発生器とそのパフォーマンスの詳細については、GPU での乱数の生成を参照してください。

sc = rng(1,'Threefry');
Rc = rand(1,4)
Rc =
   0.1404    0.8197    0.1073    0.4131
sg = gpurng(1,'Threefry');
Rg = rand(1,4,'gpuArray')
Rg =
    0.1404    0.8197    0.1073    0.4131

これで、rand および randi は、クライアントの CPU 上および GPU 上で同じ乱数列を生成します。

また、rng および gpurng を使用して、CPU および GPU で発生器アルゴリズムとシードをそれぞれ既定値にリセットできます。

rsc = rng('default')
rsg = gpurng('default')

ワーカー CPU および GPU

並列ワーカーの CPU は、クライアント GPU およびワーカー GPU (存在する場合) と同じ既定の乱数発生器のタイプおよびシードを使用します。GPU と CPU は同じストリームを共有しません。既定で、rand および randi は、GPU 上とワーカー CPU 上で同じ数列を生成します。

それらの設定は、クライアント CPU の設定と異なります。詳細については、ワーカー上の乱数ストリームの制御を参照してください。

各ワーカーで異なる乱数を生成する必要がある場合は、発生器の設定を変更できます。次の例で、各ワーカーはその GPU 上および CPU 上で同じ数列を作成しますが、ワーカーごとに異なる数列が生成されます。

p = parpool(2);
spmd
    rng(spmdIndex,'Threefry');
    Rc = rand(1,4)

    gpurng(spmdIndex,'Threefry');
    Rg = rand(1,4,'gpuArray')
end
delete(p)

正規分布乱数

関数 randn を使用して正規分布乱数を作成する場合、MATLAB は、クライアント CPU、ワーカー CPU、および GPU で異なる結果を生成します。一様な乱数から正規分布乱数への変換は、NormalTransform の設定によって制御されます。GPU 上では、parallel.gpu.RandStream を使用してこれを制御できます。

クライアント CPU 上での 'NormalTransform' の既定の設定は 'Ziggurat' です。ワーカー CPU 上での既定の設定は 'Inversion' です。

特に指定のない限り、GPU コードは、'Threefry' 発生器および 'Philox' 発生器に 'BoxMuller' 変換を使用し、'CombRecursive' 発生器に 'Inversion' 変換を使用します。

CPU と GPU に同じ発生器と変換を設定して、同じ randn 数列を得ることができます。CPU と GPU の両方でサポートされている唯一の変換は 'Inversion' 変換です。

sc = RandStream('Threefry','NormalTransform','Inversion','Seed',1);
RandStream.setGlobalStream(sc)

sg = parallel.gpu.RandStream('Threefry','NormalTransform','Inversion','Seed',1);
parallel.gpu.RandStream.setGlobalStream(sg);

Rc = randn(1,4)
Rc =
   -1.0783    0.9144   -1.2412   -0.2196
Rg = randn(1,4,'gpuArray')
Rg =
   -1.0783    0.9144   -1.2412   -0.2196

参考

| | | |

関連するトピック