Next:Interface with Checkpointing
Previous:Simple Interface
Default Interface
In this section, we give detailed descriptions of each SPRNG
function call with the default interface. This interface would typically be used if
more than one random number stream is needed on any
process.
Pointers for FORTRAN users
The different random number streams available on a
process are distinguished by unique ID's, which are implemented as pointers
to the memory locations where the states of the
respective streams are stored. 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 SPRNG_POINTER in the file sprng_f.h that
automatically defines an integer of the correct size on the
platforms on which SPRNG is supported. A FORTRAN programmer can then
use the type SPRNG_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 the SPRNG function calls available in the default
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
streamnum, int nstreams, int seed, int param)
- SPRNG_POINTER init_sprng(integer
streamnum, integer nstreams, integer seed, integer param)
IN streamnum, IN nstreams, IN seed, IN param.
- init_sprng initializes random number streams.
nstreams is the number of
distinct streams that will be initialized across all
the processes and must be greater than 0. Otherwise it is reset to 1 and a
warning message is sent to stderr stating that the
number of streams has been reset.
streamnum is the stream
number, typically the processor number, and must be in
[0,nstreams-1]. If it is not in the acceptable range,
then an error message is sent to stderr and the function
returns a NULL
pointer. Note that the number of independent streams for each
type of generator is limited (but at least 105). If streamnum is larger
than this number, then a warning message is sent to stderr
stating that the independence of streams cannot be guaranteed.
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 the
appropriate parameters (for example, the multiplier for a Linear
Congruential Generator or the lag for a Lagged Fibonacci
Generator). The macro
SPRNG_DEFAULT, defined in the
SPRNG header files, can be used to choose the
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 the ID of the stream when it completes successfully. If
it fails due to incorrect arguments or inability to allocate
memory, then an error message is sent to stderr and a
NULL pointer is returned.
Example
- 2. sprng
- double sprng(int *stream)
- real*8 sprng(SPRNG_POINTER
stream)
INOUT stream.
- stream is the ID of
the stream from which
the next random number
in [0,1) is returned by this function. This argument must have been
obtained by a prior call to init_sprng, spawn_sprng or
unpack_sprng. In the default interface, SPRNG does not check for
the validity of the ID. Incorrect answers or segmentation faults
could occur due to invalid ID's. In case the user wishes SPRNG to check
for the validity of the ID, then the interface with pointer checking must be
used.
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.
Example
- 3. isprng
- int isprng(int *stream)
- integer isprng(SPRNG_POINTER
stream)
INOUT stream.
- stream is the ID of
the stream from which the next random integer
in [0,231) is returned by this function. This argument must have been
obtained by a prior call to init_sprng, spawn_sprng or
unpack_sprng. In this interface, SPRNG does not check for
the validity of the ID. Incorrect answers or segmentation faults
could occur due to invalid ID's. In case the user wishes SPRNG to check
for the validity of the ID, then the interface with pointer checking must be
used.
Calling
isprng is equivalent to multiplying the result of
sprng by 231 and truncating to an integer. Calls to
sprng and isprng can be interleaved.
Example
- 4. print_sprng
- int print_sprng(int *stream)
- integer print_sprng(SPRNG_POINTER
stream)
IN stream .
- 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 with
the ID of
the stream as argument. stream must have been
obtained by a prior call to init_sprng, spawn_sprng or
unpack_sprng. In this interface, SPRNG does not check for
the validity of the ID. Incorrect answers or segmentation faults
could occur due to invalid ID's. In case the user wishes SPRNG to check
for the validity of the ID, then the interface with pointer checking must be
used.
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(int *stream, char **buffer)
- integer pack_sprng(SPRNG_POINTER stream, character fbuffer)
IN stream, OUT buffer, OUT fbuffer.
- This function packs the state of the stream with ID stream into an array and
returns the number of bytes actually required for the storage. stream must have been
obtained by a prior call to init_sprng, spawn_sprng or
unpack_sprng. In this interface, SPRNG does not check for
the validity of the ID. Incorrect answers or segmentation faults
could occur due to invalid ID's. In case the user wishes SPRNG to check
for the validity of the ID, then the interface with pointer checking must be
used.
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.
Note: SPRNG does not free the memory associated with
a stream when it packs it. If users do not plan to use
the stream that has been packed, then they can explicitly call
free_sprng in order to free the memory.
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. An
ID for the recreated stream is returned. Note that this ID is
unrelated to the previous
ID of the stream before it was packed, though the states are
the same.
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.
Example
- 8. free_sprng
- int free_sprng(int *stream)
- integer free_sprng(SPRNG_POINTER
stream)
INOUT stream.
- This function frees the memory used to store information
concerning the random number stream identified by the
stream ID
stream. The stream's
ID is then no longer valid. stream must have been
obtained by a prior call to init_sprng, spawn_sprng or
unpack_sprng. In this interface, SPRNG does not check for
the validity of the ID. Incorrect answers or segmentation faults
could occur due to invalid ID's. In case the user wishes SPRNG to check
for the validity of the ID, then the interface with pointer checking must be
used.
free_sprng returns the current
number of streams available on the process.
Example
- 9. spawn_sprng
- int spawn_sprng(int
*stream, int nspawned, int ***newstreams)
- integer spawn_sprng(SPRNG_POINTER stream,
integer nspawned, SPRNG_POINTER fnewstreams)
INOUT stream, IN nspawned, OUT newstreams, OUT fnewstreams .
- Some times, for example in branching processes, it is necessary
to spawn new streams from an old one. This function creates new
random number streams when given a
stream ID stream and the number of new streams
nspawned to be spawned.
stream must have been
obtained by a prior call to init_sprng, spawn_sprng or
unpack_sprng. In this interface, SPRNG does not check for
the validity of the ID. Incorrect answers or segmentation faults
could occur due to invalid ID's. In case the user wishes SPRNG to check
for the validity of the ID, then the interface with pointer checking must be
used.
nspawned is the number of
streams that will be spawned and must be greater than
0. Otherwise it is reset to 1 and a
warning message is sent to stderr stating that the
number of streams has been reset. In the unlikely event of an
extremely large number of streams being spawned, SPRNG cannot
guarantee the independence
of the different streams. In this case, a warning message is sent
to stderr. We may also change the seed of the new streams spawned in this case to make it less likely that different streams will overlap.
fnewstreams is the first element of an array of length
at least nspawned in which the ID's of the new streams will
be stored. In the C interface, SPRNG allocates memory for the array
and makes *newstreams point to this
array.
spawn_sprng returns the number of streams successfully
spawned. If the function fails due to an inability to allocate memory, then the value returned is less than nspawned.
Note: If users spawn too often, then the
available set independent streams can get exhausted, depending on the
random number generator used. Therefore some
caution must be used in spawning streams.
Example