Intel® oneAPI Math Kernel Library Developer Reference - C

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.

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:

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 */

Note

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 */