VS assumes that at any moment during the program execution you may simultaneously use several random number subsequences generated by one or more BRNGs. Consider the following scenarios:
The simulation system has several independent structural blocks of random number generation. For example, one block generates random numbers of normal distribution, another block generates uniformly distributed numbers, and so on. Each of the blocks should generate an independent random number sequence, that is, each block is assigned an individual stream that generates random numbers of a given distribution.
You need to study correlation properties of the simulation output with different distribution parameters. In this case, it looks natural to assign an individual random number stream (subsequence) to each set of the parameters. For example, see [Mikh2000
Each parallel process (computational node) requires an independent random number subsequence of a given distribution, that is, a random number stream.
A random stream means a certain abstract source of random numbers. By linking such a stream to a specific BRNG and assigning specific initial values, you can predetermine the random number sequence produced by this particular stream. In VS, a universal
stream state descriptor
identifies every random number stream (in C language this is just a pointer to the structure). The descriptor specifies the dynamically allocated memory space that contains information on the respective BRNG and its current state, as well as some additional data necessary for the leapfrog and/or skip-ahead method.
VS has two stream creation and initialization functions:
vslNewStream( stream, brng, seed )
vslNewStreamEx( stream, brng, n, params )
Each of these subroutines allocates memory space to store information on the basic generator
, its current state, etc., and then calls the initialization function of the basic generator
that fills the fields of the generator current state with relevant initial values. The initial values are defined either by a single 32-bit value
) or an array of n 32-bit initial values
). The output of
is a pointer to
, that is, the stream state descriptor.
To initialize a non-deterministic random number generator, use the same NewStream-based mechanism as shown below:
errstatus = vslNewStream( stream, VSL_BRNG_NONDETERM, VSL_BRNG_RDRAND );
nretries = 5;
params = VSL_BRNG_RDRAND;
params = nretries;
errstatus = vslNewStreamEx( stream, VSL_BRNG_NONDETERM, 2, params );
If the underlying hardware does not support this non-deterministic generator, creation and initialization function returns the corresponding error code.
You can create any number of streams through multiple calls of
functions. For example, you can generate several thread-safe streams that are linked to the same BRNG.
The generated streams are further identified by their stream state descriptors. Although a random number stream is a source of random numbers produced by a BRNG, that is, a generator of uniform distribution, you can generate random numbers of non-uniform distribution using streams. To do this, the stream state descriptor is passed to the transformation function that generates random numbers of a given distribution. Each function uses the stream state descriptor to produce random numbers of a uniform distribution, which are further transformed into sequences of the required distribution. See section Generating Methods for Random Numbers of Non-Uniform Distribution
When a given random number stream is no longer needed, delete it by calling
vslDeleteStream( stream )
This function frees the memory space related to the stream state descriptor
. After that, you can no longer use the descriptor.
You can use non-deterministic random number generators only if the underlying hardware provides the respective support. For example, see Chapter 8 in [AVX
] or Chapter 4 in [BMT
] for instructions on how to determine whether an Intel® processor supports a non-deterministic random number generator.