主要内容

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

GPU 上的随机数流

默认情况下,随机数生成函数 randrandirandn 在 GPU 上进行计算时使用与 CPU 上不同的生成器设置。您可以改变随机数生成器的行为,以在 GPU 和 CPU 上生成可重现的随机数序列。

下表总结了客户端和工作单元 MATLAB® 会话中 GPU 和 CPU 的默认设置:

 生成器种子正态变换
客户端 CPU

梅森扭转算法

0

金字塔

工作单元 CPU

执行 20 轮的 Threefry 4x64 生成器

0

反转

GPU(在客户端或工作单元上)

执行 20 轮的 Threefry 4x64 生成器

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.9134
Rg = rand(1,4,"gpuArray")
Rg =
    0.3640    0.5421    0.6543    0.7436

如果您需要在 GPU 和 CPU 上生成相同的随机数序列,则可以将生成器的设置调整为一致。

GPU 上有三种随机数生成器算法:"Threefry""Philox""CombRecursive"。这三项功能在 CPU 上也都得到了支持。下表列出了这些生成器的算法及其属性。

发电机名称生成器关键字多流和子流支持高精度近似周期
"Threefry"执行 20 轮的 Threefry 4x64 生成器

threefry4x64_20

2514(2256 个长度为 2258 的流)
"Philox"执行 10 轮的 Philox 4x32 生成器

philox4x32_10

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 参量控制。您可以在 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

另请参阅

| | | |

主题