GPU 上の乱数ストリーム
乱数発生関数 rand、randi および randn が GPU 上での計算に使用する発生器の既定の設定は、CPU 上での計算に使用する設定とは異なります。GPU と CPU で再現可能な乱数列を生成するように、乱数発生器の動作を変更できます。
次の表は、クライアントおよびワーカーの MATLAB® セッションにおける GPU および CPU の既定の設定をまとめています。
| 発生器 | シード | 正規変換 | |
|---|---|---|---|
| クライアント CPU | メルセンヌ・ツイスター | 0 | Ziggurat |
| ワーカー CPU | Threefry 4x64 発生器、20 ラウンド | 0 | Inversion |
| GPU (クライアントまたはワーカー) | Threefry 4x64 発生器、20 ラウンド | 0 | Box–Muller |
ほとんどの場合、GPU 上の既定の乱数発生器が、クライアントまたはワーカーの CPU 上の既定の発生器と異なっていても問題はありません。しかし、GPU と CPU の両方で同じ結果を再現する必要がある場合は、発生器を適切に設定できます。
クライアント CPU および GPU
新しい MATLAB セッションで、MATLAB は CPU と GPU で異なる乱数列を生成します。
Rc = rand(1,4)
Rc =
0.8147 0.9058 0.1270 0.9134Rg = rand(1,4,"gpuArray")
Rg =
0.3640 0.5421 0.6543 0.7436GPU と CPU の両方で同じ乱数列を生成する必要がある場合、発生器の設定を一致させることができます。
GPU 上で使用できる乱数発生器アルゴリズムには "Threefry"、"Philox" および "CombRecursive" の 3 つがあります。3 つすべてが CPU でもサポートされています。次の表は、これらの発生器とそのプロパティのアルゴリズムの一覧です。
| 値 | 発生器の名前 | 発生器のキーワード | 複数のストリームとサブストリームのサポート | 完全精度での近似周期 |
|---|---|---|---|---|
"Threefry" | Threefry 4x64 発生器、20 ラウンド | threefry4x64_20 | あり | 2514 (長さが 2258 の 2256 個のストリーム) |
"Philox" | Philox 4x32 発生器、10 ラウンド | philox4x32_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 に同じ発生器と変換を設定して、同じ正規分布乱数列を得ることができます。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
参考
gpurng | parallel.gpu.RandStream | RandStream | rng | gpuArray