lcg64
The Scalable Parallel Pseuo Random Number Generators Library (SPRNG) is a C-library that was designed to solve this challenge. As explained in detail in the SPRNG paper, there are several methods of creating independent parallel random number streams, using parametrization of the generator, or cycle division techniques.
Since the method to create independent streams depends on the choice of generator, no generic seeding can be implemented, but the seeding mechanism is specific to the generator. However, a common interface is possible, and we follow the design of the SPRNG library by requiring the following two parameters next to a global seed
stream_number: the number of the current streamtotal_streams: the total number of streams requiredtotal_streams, global_seed
but different values for stream_number produce independent
non-overlapping sequences of random numbers. In a parallel application, typically
the node number is chosen as stream_number and the total number
of nodes as total_streams.
UniformRandomNumberGenerator concept to a
ParallelUniformRandomNumberGenerator
In the following table,
X denotes a model of the concept
ParallelUniformRandomNumberGenerator.
v is
an object of type X.
num and total
are unsigned integral values saitsfying num < total.
first and last
input iterators with a value type convertible to unsigned int.
first is required to be non-const.
num, total must produce independent
non-overlapping sequences of random numbers, if all other arguments besides
v are equivalent, including where
applicable, the
values of the range [first,last).
ParallelUniformRandomNumberGenerator
requirements | ||
|---|---|---|
| Expression | Return type | Note |
seed(v,num,total) | void |
default parallel seeding of v |
seed(v,num,total,first,last) | void |
parallel seeding of v from two iterators. The semantics is
identical to that of the seeding of a UniformRandomNumberGenerator from
a pair of iterators, with the only distinction that for identical elements in the range
[first,last) and identical values of total
but different values of num, independent
non-overlapping sequences of random numbers will be produced by the generator.
|
ParallelUniformRandomNumberGenerator
requirements | ||
|---|---|---|
| Expression | Return type | Note |
X::max_streams | int |
the maximum number of independent streams provided by X. |
X(named parameters) | X |
creates an object of type X with the named parameter arguments given in
the table below. |
v.seed(optional named parameters) | void |
seeds v with the named parameter arguments given in
the table below. |
v.seed(first,last,optional named parameters) | void |
seeds v with the range of values given by [first,last), and the named parameter arguments given in
the table below. |
Parallel uniform random number generators created
with the same values of total_streams, global_seed
but different values for stream_number will produce independent
non-overlapping sequences of random numbers.
<boost/random/parallel/keyword.hpp>
#include <boost/parameter/keyword.hpp>
namespace boost { namespace random { namespace parallel {
BOOST_PARAMETER_KEYWORD(tag,stream_number)
BOOST_PARAMETER_KEYWORD(tag,total_streams)
BOOST_PARAMETER_KEYWORD(tag,global_seed)
} } }
defines the named parameters for seeding for parallel random
number generators according to the above table.
<boost/parallel/seed.hpp> and
<boost/parallel/mpi.hpp> provide default implementations
of the parallel seeding functions required by the
ParallelUniformRandomNumberGenerator concept, and additional
convencience functions.
<boost/random/parallel/seed.hpp>
namespace boost { namespace random { namespace parallel {
template <class PRNG>
void seed(PRNG& prng, unsigned int num, unsigned int total);
template <class PRNG, class Iterator>
void seed(PRNG& prng, unsigned int num, unsigned int total, Iterator& first, Iterator const& last);
template <class PRNG, class SeedType>
void seed(PRNG& prng, unsigned int num, unsigned int total, SeedType const& s);
} } }
template <class PRNG> void seed(PRNG& prng, unsigned int num, unsigned int total);provides a default implementation of the default parallel seeding function by asssuming a named parameter seeding interface. It is implemented as
prng.seed(stream_number=num, total_streams=total);.
template <class PRNG, class Iterator> void seed(PRNG& prng, unsigned int num, unsigned int total, Iterator& first, Iterator const& last);provides a default implementation of the parallel seeding from a pair iterators by asssuming a named parameter seeding interface. It is implemented as
prng.seed(first,last,stream_number=num, total_streams=total);.
template <class PRNG, class SeedType> void seed(PRNG& prng, unsigned int num, unsigned int total, SeedType const& s);provides a convenience function for parallel seeding from a single global seed by asssuming a named parameter seeding interface. It is implemented as
prng.seed(global_seed=s, stream_number=num, total_streams=total);.
<boost/random/parallel/mpi.hpp>num
and total parameters are obtained from a
boost::parallel::mpi::communicator.
MPI communicator.
namespace boost { namespace random { namespace parallel {
template <class PRNG>
void seed(PRNG& prng, boost::parallel::mpi::communicator const& c)
template <class PRNG, class SeedType>
void seed(PRNG& prng, boost::parallel::mpi::communicator const& c, SeedType const& s)
template <class PRNG, class Iterator>
void seed(PRNG& prng, boost::parallel::mpi::communicator const& c, Iterator& first, Iterator const& last)
template <class PRNG, class SeedType>
void broadcast_seed( PRNG& prng, boost::parallel::mpi::communicator const& c, int root, SeedType s)
} } }
template <class PRNG> void seed(PRNG& prng, boost::parallel::mpi::communicator const& c) template <class PRNG, class SeedType> void seed(PRNG& prng, boost::parallel::mpi::communicator const& c, SeedType const& s) template <class PRNG, class Iterator> void seed(PRNG& prng, boost::parallel::mpi::communicator const& c, Iterator& first, Iterator const& last)call the corresponding
seed functions from the <boost/parallel/seed.hpp>,
using the communicator rank c.rank() and size c.size()
as num and total arguments.
template <class PRNG, class SeedType> void broadcast_seed( PRNG& prng, boost::parallel::mpi::communicator const& c, int root, SeedType s)broadcasts the global seed
s from the root rank given by the root argument and then
calls the seed function with the same arguments.
lcg64<boost/random/parallel/lcg64.hpp>
namespace boost {
namespace random {
template<uint64_t a, uint64_t val>
class lcg64
{
typedef uint64_t result_type;
static const bool has_fixed_range = true;
static const result_type min_value;
static const result_type max_value;
static const result_type max_streams = 146138719;
lcg64(optional named parameters);
template<class It> lcg64(It& first, It last,optional named parameters);
void seed(optional named parameters);
template<class It> void seed(It& first, It last,optional named parameters);
result_type operator()();
static bool validation(result_type);
};
}
typedef random::lcg64< /* ... */> lcg64a;
typedef random::lcg64< /* ... */> lcg64b;
typedef random::lcg64< /* ... */> lcg64c;
}
a,
which is given as template parameter is different for the three generators . The prime additive constant c is chosen depending
on the stream number, thus giving independent sequences for each stream.
<boost/random/parallel/well.hpp>
namespace boost {
namespace random {
template<class UIntType, int statesize, UIntType val, class F1, class F2
, class F3, class F4, class F5, class F6, class F7, class F8
, int p1, int p2, int p3, UIntType mask=statesize-1, class RNG=mt19937>
class well
{
typedef UIntType result_type;
static const bool has_fixed_range = true;
static const result_type min_value;
static const result_type max_value;
well(optional named parameters);
template<class It> well(It& first, It last,optional named parameters);
void seed(optional named parameters);
template<class It> void seed(It& first, It last,optional named parameters);
result_type operator()();
static bool validation(result_type);
};
typedef well< /* ... */> well512a;
typedef well< /* ... */> well1024a;
}
}
well model a pseudo-random number
generator, whose algorithm is described in
"Improved Long-Period Generators Based on Linear Recurrences Modulo 2" , F. Panneton, P. L'Ecuyer and M. Matsumoto, submitted to ACM TOMSTwo well-tested and validated generators
well512a and well1024a are provided as specializations.
The parallel seeding is based on cycle division:
mt19937), which provides the random seeds for total_streams WELL generators.total_streams WELL generators is filled by a buffer.