init#

nvmath.device.random.init(..., state)#

初始化 RNG 状态。

参数取决于所选的位生成器(请参阅 cuRAND 文档curand_init 的重载)。

示例

>>> from numba import cuda
>>> from nvmath.device import random
>>> compiled_apis = random.Compile(cc=None)

我们将在一个 64 块的网格上工作,每个块有 64 个线程。

>>> threads = 64
>>> blocks = 64
>>> nthreads = blocks * threads

让我们展示如何将 initnvmath.device.random.StatesPhilox4_32_10 状态一起使用。 这同样适用于 nvmath.device.random.StatesMRG32k3anvmath.device.random.StatesXORWOW

首先,使用 nvmath.device.random.StatesPhilox4_32_10 构造函数创建一个状态数组(每个线程一个)。

>>> states = random.StatesPhilox4_32_10(nthreads)

定义一个内核来初始化状态。 每个线程将初始化 states 的一个元素。 对于 Philox4_32_10 生成器,init 参数为:seedsubsequenceoffset

>>> @cuda.jit(link=compiled_apis.files, extensions=compiled_apis.extension)
... def setup(states):
...     i = cuda.grid(1)
...     random.init(1234, i, 0, states[i])

运行内核以初始化状态

>>> setup[blocks, threads](states)

现在,您可以使用 states 数组,使用可用的随机采样器生成随机数。

对于 Sobol’ 准随机数生成器系列,初始化稍微复杂一些,因为它需要准备一组方向向量扰码常数。 在此示例中,我们将设置 nvmath.device.random.StatesScrambledSobol64 状态。

方向向量可以使用 nvmath.device.random_helpers.get_direction_vectors64() 获取

>>> from nvmath.device import random_helpers
>>> hostVectors = random_helpers.get_direction_vectors64(
...     random.random_helpers.DirectionVectorSet.SCRAMBLED_DIRECTION_VECTORS_64_JOEKUO6, nthreads)
>>> sobolDirectionVectors = cuda.to_device(hostVectors)

要获取扰码常数,请使用 nvmath.device.random_helpers.get_scramble_constants64()

>>> hostScrambleConstants = random_helpers.get_scramble_constants64(nthreads)
>>> sobolScrambleConstants = cuda.to_device(hostScrambleConstants)

由于 init 需要一个指向方向向量的指针,我们将使用 cffi 来获取它。

>>> states = random.StatesScrambledSobol64(nthreads)
>>>
>>> import cffi
>>> ffi = cffi.FFI()
>>>
>>> @cuda.jit(link=compiled_apis.files, extensions=compiled_apis.extension)
... def setup(sobolDirectionVectors, sobolScrambleConstants, states):
...     id = cuda.grid(1)
...     dirptr = ffi.from_buffer(sobolDirectionVectors[id:])
...     random.init(dirptr, sobolScrambleConstants[id], 1234, states[id])