Simple Interface
In this section, we give detailed descriptions of each SPRNG function call with the simple interface. It is invoked by defining the macro SIMPLE_SPRNG before including a SPRNG header file. This interface is used when only one random number stream is required on each process at any given time. In this case, it is not necessary to use stream ID to distinguish between different streams. Hence a simpler interface is possible in which SPRNG maintains a single random number stream. Functions that require a stream ID in other interfaces make use of this stream instead.
Pointers for FORTRAN users
Different random number streams available on a process, in other interfaces, are distinguished by unique ID's, which are implemented as pointers to memory locations where states of the respective streams are stored. Though stream ID's are not used in the simple interface, some functions return pointers for the sake of consistency with the other interfaces. Since standard FORTRAN 77 does not have a pointer type, we can store a pointer as an integer of the same size as a C pointer. We have defined a macro called POINTER in the file sprng_f.h that automatically defines an integer of the correct size on platforms on which SPRNG is supported. A FORTRAN programmer can then use the type POINTER just as if it were a FORTRAN data type. However, this applies only if the FORTRAN program is compiled with the same flags as given in the make file that comes with SPRNG.
Terminology
In the following description, an argument marked as IN indicates that the argument, or array elements pointed to by that argument, are read by the function, but not modified. OUT indicates that the argument, or array elements pointed to by that argument, are written into by the function, but that its values are not used by the function. Arguments that are both read and modified are denoted by INOUT.SPRNG Functions
We describe below SPRNG function calls available in the simple interface. For each function, the C call is given first, followed by the FORTRAN call. The data type preceding the function name is the type returned by the function. The data types preceding the arguments to the functions are the data types of the corresponding function arguments.
- 1. init_sprng
- int *init_sprng(int seed, int param)
- SPRNG_POINTER init_sprng(integer seed, integer param)
IN seed, IN param.
- init_sprng initializes random number streams. This function call can be omitted if the user wishes to use default values of the arguments.
seed is the seed to the random number generator. It is not the starting state of the sequence; rather, it is an encoding of the starting state. It is acceptable (and recommended) to use the same seed for all the streams. Distinct streams are returned based on their seed and the stream number. Only the 31 least significant bits of seed are used in determining the initial starting state of the stream. Higher order bits that are set will be ignored. No warning message is printed if the higher order bits are set.
The argument param selects appropriate parameters (for example, multiplier for a Linear Congruential Generator or lag for a Lagged Fibonacci Generator). The macro SPRNG_DEFAULT, defined in SPRNG header files, can be used to choose default parameters. If an invalid parameter is passed to this function, then a warning message is sent to stderr and the default parameter is used.
init_sprng returns a NULL pointer if it fails, normally due to an inability to allocate memory. Otherwise it returns a non-NULL value.
If the MPI version of SPRNG has been installed and the macro USE_MPI has been defined before including a SPRNG header file, then this routine makes some MPI calls to determine the number of processes. This value is used to ensure that different streams are produced on different processes. If the MPI version of SPRNG has been installed but the macro USE_MPI has not been defined, then the same stream is returned on all processes (provided the same seed and param value have been passed to this function on all processes). If the MPI version of SPRNG has not been installed but the macro USE_MPI has been defined, then a warning message is sent to stderr and the initialization is performed as if the macro USE_MPI has not been defined.In case the user calls init_sprng while another stream has already been initialized by calling init_sprng, unpack_sprng, isprng or sprng, then the new stream replaces the previous one. If a call to this function fails, then the previous stream is still available.
Note: If the user has installed the MPI version of the library and defined the macro USE_MPI, then the user must have called MPI_Init before making calls to init_sprng. The user should also call MPI_Finalize later. SPRNG does not make either of these calls.
Example
- 2. sprng
- double sprng()
- real*8 sprng()
- The next random number in [0,1) is returned by this function.
If FORTRAN programmers wish to obtain real*4 numbers, or C programmers float numbers, instead of the double precision default, then they should define the macro FLOAT_GEN before including a SPRNG header file.
If no stream has been initialized before, by calling init_sprng, unpack_sprng, isprng or sprng, then a new stream is initialized using the default parameters. If this initialization fails due to an inability to allocate sufficient memory, then this function returns -1. Please see init_sprng for further details on the initialization.
Example
- 3. isprng
- int isprng()
- integer isprng()
- The next random number in [0,231) is returned by this function.
Callingisprng
is equivalent to multiplying the result ofsprng
by 231 and truncating to an integer. Calls tosprng
andisprng
can be interleaved.
If no stream has been initialized before, by calling init_sprng, unpack_sprng, isprng or sprng, then a new stream is initialized using the default parameters. If this initialization fails due to an inability to allocate sufficient memory, then this function returns -1. Please see init_sprng for further details on the initialization.
Example
- 4. print_sprng
- int print_sprng()
- integer print_sprng()
- The user may wish to print information about streams without printing the entire state, for example after initialization. This is typically done when the user wishes to record information which can later be used to identify the random number stream used in the computations. This information can be obtained by a call to print_sprng.
Example
- 5. make_sprng_seed
- int make_sprng_seed()
- integer make_sprng_seed()
- This function produces a new seed using system date and time information. It will typically be used when the programmer wishes to initialize with a different seed every time the program is run. User should note that both the Lagged Fibonacci Generators requires the use of the same seed for each stream in order to guarantee their independence. In order to ensure this on a parallel computer, they should install the MPI version of SPRNG and define the macro USE_MPI before including a SPRNG header file. This function will then involves some inter-processor communication.
If the user has installed the MPI version of the library but has not defined the macro USE_MPI, then the seed could be different on the different processes. No warning message is printed. If the user has not installed the MPI version of the library but includes the macro USE_MPI, then link time errors will be reported by the compiler.
Note: If users have installed the MPI version of the library and defined the macro USE_MPI, then they must call MPI_Init before making calls to make_sprng_seed. The user should also call MPI_Finalize later. SPRNG does not make either of these calls. If any process calls make_sprng_seed, then users should ensure that all their processes call this function, since collective MPI operations are performed here.
Example
- 6. pack_sprng
- int pack_sprng(char **buffer)
- integer pack_sprng(character fbuffer)
OUT buffer, OUT fbuffer.
- This function packs the state of the random number stream into an array and returns the number of bytes actually required for the storage.
fbuffer should be the first element of an array of size MAX_PACKED_LENGTH bytes, where MAX_PACKED_LENGTH is a macro defined in "sprng_f.h" and "sprng.h". If the memory in the array is insufficient, undetected errors could occur. It might also lead to segmentation faults. In the C interface, the programmer need not allocate memory. SPRNG allocates memory for the array and has the result stored in *buffer.
Calls to this function in C or FORTRAN involve memory allocation within this function. In case of insufficient memory, an error message is sent to stderr and the value 0 is returned.
This function can be used for check-pointing, where the programmer packs the state of the stream into an array and then saves it to a file. This state can later be retrieved by calling unpack_sprng, which is explained below. pack_sprng can also be used to pass a stream to another process. That process will unpack the packed array to obtain the stream.
Example
- 7. unpack_sprng
- int *unpack_sprng(char *buffer)
- SPRNG_POINTER unpack_sprng(character fbuffer)
IN buffer, IN fbuffer.
- This function recreates a stream given the array buffer or fbuffer, which was used to store the stream's state through a call to the function pack_sprng. The return value should be ignored unless it is NULL. A NULL pointer is returned only if this function failed due to an inability to allocate memory.
Calls to this function involve memory allocation. In case sufficient memory was not obtained, an error message is sent to stderr and the NULL pointer is returned. The packed string must be the state of a valid stream. If it is not, the error may not necessarily be detected by SPRNG. If an error is detected, then an error message is sent to stderr and a NULL pointer is returned.
In case a random number stream has already been initialized, by calling init_sprng, unpack_sprng, isprng or sprng, then the unpacked stream replaces the previous stream. If a call to this function fails, then the previous stream is still available.
Example