Developer Reference

Contents

Formats for User-Designed Generators

To register a user-designed basic generator using
vslRegisterBrng
function, you need to pass the pointer
iBrng
to the integer-value implementation of the generator; the pointers
sBrng
and
dBrng
to the generator implementations for single and double precision values, respectively; and pass the pointer
InitStream
to the stream initialization routine. See recommendations below on defining such functions with input and output arguments. An example of the registration procedure for a user-designed generator can be found in the respective directory of VS examples.
The respective pointers are defined as follows:
typedef int(*InitStreamPtr)( int method, VSLStreamStatePtr stream, int n, const unsigned int params[] );
typedef int(*sBRngPtr)( VSLStreamStatePtr stream, int n, float r[], float a, float b );
typedef int(*dBRngPtr)( VSLStreamStatePtr stream, int n, double r[], double a, double b );
typedef int(*iBRngPtr)( VSLStreamStatePtr stream, int n, unsigned int r[] );

InitStream

int MyBrngInitStream( int
method
, VSLStreamStatePtr
stream
, int
n
, const unsigned int
params
[] ) { /* Initialize the stream */ ... } /* MyBrngInitStream */

Description

The initialization routine of a user-designed generator must initialize
stream
according to the specified initialization
method
, initial conditions
params
and the argument
n
. The value of
method
determines the initialization method to be used.
  • If
    method
    is equal to
    1
    , the initialization is by the standard generation method, which must be supported by all basic generators. In this case the function assumes that the
    stream
    structure was not previously initialized. The value of
    n
    is used as the actual number of 32-bit values passed as initial conditions through
    params
    . Note, that the situation when the actual number of initial conditions passed to the function is not sufficient to initialize the generator is not an error. Whenever it occurs, the basic generator must initialize the missing conditions using default settings.
  • If
    method
    is equal to
    2
    , the generation is by the leapfrog method, where
    n
    specifies the number of computational nodes (independent streams). Here the function assumes that the
    stream
    was previously initialized by the standard generation method. In this case
    params
    contains only one element, which identifies the computational node. If the generator does not support the leapfrog method, the function must return the error code
    VSL_RNG_ERROR_LEAPFROG_UNSUPPORTED
    .
  • If
    method
    is equal to
    3
    , the generation is by the block-splitting method. Same as above, the
    stream
    is assumed to be previously initialized by the standard generation method;
    params
    is not used,
    n
    identifies the number of skipped elements. If the generator does not support the block-splitting method, the function must return the error code
    VSL_RNG_ERROR_SKIPAHEAD_UNSUPPORTED
    .
  • If
    method
    is equal to
    4
    , the generation is by the advanced block-splitting method. The stream is assumed to be previously initialized by the standard generation method;
    params
    is converted to
    MKL_UINT64[]
    and
    n
    is used as actual number of 64-bit values in
    params
    . If the generator does not support the advanced block-splitting method, the function must return the error code
    VSL_RNG_ERROR_SKIPAHEADEX_UNSUPPORTED
    .
For a more detailed description of the leapfrog and the block-splitting methods, refer to the description of
vslLeapfrogStream
,
vslSkipAheadStream
, and
vslSkipAheadStreamEx
, respectively.
Stream state structure is individual for every generator. However, each structure has a number of fields that are the same for all the generators:
typedef struct { unsigned int
Reserved1
[2]; unsigned int
Reserved2
[2]; [fields specific for the given generator] } MyStreamState;
The fields
Reserved1
and
Reserved2
are reserved for private needs only, and must not be modified by the user. When including specific fields into the structure, follow the rules below:
  • The fields must fully describe the current state of the generator. For example, the state of a linear congruential generator can be identified by only one initial condition;
  • If the generator can use both the leapfrog and the block-splitting methods, additional fields should be introduced to identify the independent streams. For example, in
    LCG
    (
    a
    ,
    c
    ,
    m
    )
    , apart from the initial conditions, two more fields should be specified: the value of the multiplier
    a
    k
    and the value of the increment (
    a
    k
    -1)
    c
    /(
    a
    -1
    ).
For a more detailed discussion, refer to [ Knuth81 ], and [ Gentle98 ]. An example of the registration procedure can be found in the respective directory of VS examples.

iBRng

int iMyBrng( VSLStreamStatePtr
stream
, int
n
, unsigned int
r
[] ) { int
i
; /* Loop variable */ /* Generating integer random numbers */ /* Pay attention to word size needed to store only random number */ for(
i
= 0;
i
<
n
;
i
++) {
r
[
i
] = ...; } /* Update stream state */ ... return errcode; } /* iMyBrng */
When using 64 and 128-bit generators, consider digit capacity to store the numbers to the random vector
r
correctly. For example, storing one 64-bit value requires two elements of
r
, the first to store the lower 32 bits and the second to store the higher 32 bits. Similarly, use 4 elements of
r
to store a 128-bit value.

sBRng

int sMyBrng( VSLStreamStatePtr
stream
, int
n
, float
r
[], float
a
, float
b
) { int
i
; /* Loop variable */ /* Generating float (a,b) random numbers */ for (
i
= 0;
i
<
n
;
i
++ ) {
r
[
i
] = ...; } /* Update stream state */ ... return errcode; } /* sMyBrng */

dBRng

int dMyBrng( VSLStreamStatePtr
stream
, int
n
, double
r
[], double
a
, double
b
) { int
i
; /* Loop variable */ /* Generating double (a,b) random numbers */ for (
i
= 0;
i
<
n
;
i
++ ) {
r
[
i
] = ...; } /* Update stream state */ ... return errcode; } /* dMyBrng */

Product and Performance Information

1

Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice.

Notice revision #20110804