Main Content

本页采用了机器翻译。点击此处可查看英文原文。

GPU 上的随机数流

默认情况下,随机数生成函数 randrandirandn 在 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'。所有这些都受 CPU 支持。下表列出了这些生成器的算法及其属性。

关键词生成器多流和子流支持高精度近似周期
"Threefry""Threefry4x64_20"执行 20 轮的 Threefry 4x64 生成器2514(2256 个长度为 2258 的流)
"Philox""Philox4x32_10"执行 10 轮的 Philox 4x32 生成器2193(264 条长度为 2129 的流)
"CombRecursive""mrg32k3a"组合多重递归生成器2191(263 条长度为 2127 的流)

您可以使用 rnggpurng 分别在 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

randrandi 现在在客户端 CPU 和 GPU 上生成相同的随机数序列。

您还可以使用 rnggpurng 将生成器算法和种子分别重置为 CPU 和 GPU 上的默认值。

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

工作进程 CPU 和 GPU

如果有的话,并行工作进程 CPU 使用与客户端 GPU 和工作进程 GPU 相同的默认随机数生成器类型和种子。GPU 和 CPU 不共享同一个流。默认情况下,randrandi 在 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 设置控制。您可以使用 parallel.gpu.RandStream 在 GPU 上控制它。

在客户端 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

另请参阅

| | | |

相关主题