init#

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

Initialize the RNG state.

The arguments depend upon the selected bit generator (see the overloads of curand_init in cuRAND docs).

Example

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

We will be working on a grid of 64 blocks, with 64 threads in each.

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

Let us show how to use init with nvmath.device.random.StatesPhilox4_32_10 states. The same applies to nvmath.device.random.StatesMRG32k3a and nvmath.device.random.StatesXORWOW.

First, create an array of states (one per thread) using nvmath.device.random.StatesPhilox4_32_10 constructor.

>>> states = random.StatesPhilox4_32_10(nthreads)

Define a kernel to initialize the states. Each thread will initialize one element of states. For the Philox4_32_10 generator, the init arguments are: seed, subsequence, offset.

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

Run the kernel to initialize the states:

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

Now, you can use the states array to generate random numbers using the random samplers available.

For Sobol’ family of quasirandom number generators, initialization is a bit more complex as it requires preparing a set of direction vectors and scramble constants. In this example, we will setup nvmath.device.random.StatesScrambledSobol64 states.

Direction vectors can be obtained with 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)

To get scramble constants, use nvmath.device.random_helpers.get_scramble_constants64():

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

As init expects a pointer to direction vectors, we will use cffi to obtain it.

>>> 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])