rngtest namespace

RNGTest declarations and definitions.

Everything that contributes to the rngtest executable.

Namespaces

namespace cmd
RNGTest command line grammar definition.
namespace ctr
RNGTest control facilitating user input to internal data transfer.
namespace deck
RNGTest input deck facilitating user input for testing RNGs.

Classes

class CmdLineParser
Command-line parser for RNGTest.
class InputDeckParser
Control file parser for RNGTest.
class RNGTestDriver
Random number generator test suite driver used polymorphically with tk::Driver.
class RNGTestPrint
RNGTestPrint : tk::RNGPrint.
class Battery
Battery.
class BigCrush
Class registering the TestU01 library's BigCrush battery.
class Crush
Class registering the TestU01 library's Crush battery.
class SmallCrush
Class registering the TestU01 library's SmallCrush battery.
class StatTest
Random number generator statistical test.
struct TestStack
Stack collecting all types of random RNG statistical tests.
template<class TestU01Props>
class TestU01
TestU01 statistical test used polymorphically with rngtest::StatTest.
template<class Test, class Proxy, class Result, Result*(*)(void) Creator, void(*)(Result*) Deleter, typename... Ts>
class TestU01Props
TestU01 properties used to initialize TestU01 tests.
class TestU01Stack
Stack of TestU01 RNG statistical tests.
class TestU01Suite
TestU01 random number generator test suite used polymorphically with Battery.
template<typename RawPtr, void(*)(RawPtr*) Deleter>
struct Eraser
Custom deleter binding a raw TestU01 pointer to its TestU01 deleter.

Typedefs

using BatteryFactory = std::map<ctr::BatteryType, std::function<Battery()>>
Battery factory type.
template<class Ptr, void(*)(Ptr*) Deleter>
using TestU01Ptr = std::unique_ptr<Ptr, Eraser<Ptr, Deleter>>
TestU01 pointer type with a custom deleter.
using Gen01Ptr = TestU01Ptr<unif01_Gen, unif01_DeleteExternGen01>
TestU01 external generator type with a custom deleter by TestU01.

Functions

void operator|(PUP::er& p, std::map<tk::ctr::RawRNGType, tk::RNG>& rng)
void operator|(PUP::er& p, TestStack& stack)
template<tk::ctr::RawRNGType id>
static auto uniform(void*, void*) -> double
template<tk::ctr::RawRNGType id>
static auto uniform_bits(void*, void*) -> unsigned long
template<tk::ctr::RawRNGType id>
static auto createTestU01Gen(const std::string& name) -> unif01_Gen*

Variables

ctr::InputDeck g_inputdeck
ctr::InputDeck g_inputdeck_defaults
std::map<tk::ctr::RawRNGType, tk::RNG> g_rng
TestStack g_testStack

Function documentation

void rngtest::operator|(PUP::er& p, std::map<tk::ctr::RawRNGType, tk::RNG>& rng)

Pack/Unpack selected RNGs. This Pack/Unpack method (re-)creates the full RNG stack since it needs to (re-)bind function pointers on different processing elements. Therefore we circumvent Charm's usual pack/unpack for this type, and thus sizing does not make sense: sizing is a no-op. We could initialize the stack in RNGTestDriver's constructor and let this function re-create the stack only when unpacking, but that leads to repeating the same code twice: once in RNGTestDriver's constructor, once here. Another option is to use this pack/unpack routine to both initially create (when packing) and to re-create (when unpacking) the stack, which eliminates the need for pre-creating the object in RNGTestDriver's constructor and therefore eliminates the repeated code. This explains the guard for sizing: the code below is called for packing only (in serial) and packing and unpacking (in parallel).

void rngtest::operator|(PUP::er& p, TestStack& stack)

Pack/Unpack test stack. This Pack/Unpack method (re-)creates the full test stack since it needs to (re-)bind function pointers on different processing elements. Therefore we circumvent Charm's usual pack/unpack for this type, and thus sizing does not make sense: sizing is a no-op. We could initialize the stack in RNGTestDriver's constructor and let this function re-create the stack only when unpacking, but that leads to repeating the same code twice: once in RNGTestDriver's constructor, once here. Another option is to use this pack/unpack routine to both initially create (when packing) and to re-create (when unpacking) the stack, which eliminates the need for pre-creating the object in RNGTestDriver's constructor and therefore eliminates the repeated code. This explains the guard for sizing: the code below is called for packing only (in serial) and packing and unpacking (in parallel).

template<tk::ctr::RawRNGType id>
static double rngtest::uniform(void*, void*)

Returns Random number generated as a double-precision floating point value

This functions is used as an external uniform random number generator (i.e., external to TestU01) that is called by the TestU01 library, hence the required signature and hence the global scope. It is templated on a unique integer corresponding to the RNG type enum defined by tk::ctr::RNGType. Templating on the id enables the compiler to generate a different wrapper for a different RNG facilitating simultaneous calls to any or all wrappers as they are unique functions.

template<tk::ctr::RawRNGType id>
static unsigned long rngtest::uniform_bits(void*, void*)

Returns Random number generated as a unsigned long integer value

This functions is used as an external uniform random number generator (i.e., external to TestU01) that is called by the TestU01 library, hence the required signature and hence the global scope. It is templated on a unique integer corresponding to the RNG type enum defined by tk::ctr::RNGType. Templating on the id enables the compiler to generate a different wrapper for a different RNG facilitating simultaneous calls to any or all wrappers as they are unique functions.

template<tk::ctr::RawRNGType id>
static unif01_Gen* rngtest::createTestU01Gen(const std::string& name)

Parameters
name in Random number generator name

This is the function that contains the TestU01 library call to register a TestU01-external random number generator that later can be subjected to the TestU01 batteries. It ties the unique global-scope wrappers templated on the unique RNG id, thus TestU01 will see them as different external generators.

Variable documentation

ctr::InputDeck rngtest::g_inputdeck

Input deck filled by parser, containing all input data

This object is in global scope, it contains all of user input, and thus it is made available to all PEs for convenience reasons. The runtime system distributes it to all PEs during initialization. Once distributed, the object does not change.

ctr::InputDeck rngtest::g_inputdeck_defaults

Global-scope data. Initialized by the main chare and distibuted to all PEs by the Charm++ runtime system. Though semantically not const, all these global data should be considered read-only. See also http://charm.cs.illinois.edu/ manuals/html/charm++/manual.html. The data below is global-scope because they must be available to all PEs which could be on different machines. In a previous non-Charm++ design, most of this data was held at class-level, but since the generators in g_rng must be possible to be called from global-scope, as external generators to TestU01, it is easier to make g_rng global-scope, as well the additional data required to initialize it, contained in g_inputdeck (storing all parsed user input). This is required for serializing during migration of g_rng across the network.

Note that the container (std::map) holding tk::RNG objects uses value semantics which is safer and generally less error-prone than reference semantics. At the same time tk::RNG is used in a polymorphic fashion with various classes that adhere to the concepts required by Concept defined inside tk::RNG. tk::RNG does not define a default, i.e., non-templated constructor, since then the "derived" class object could not be initialized rendering the class tk::RNG empty-constructed, which invites abuse and ill-defined behavior. As such, the "derived" class type comes through the constructors and thus would not be available for a pack/unpack migrator required by Charm++ from within. Templating the class tk::RNG is not an option since then we could not hold tk::RNG objects in a simple std::vector. As a result of the above requirements, the tk::RNG objects in g_rng are migrated (here in global-scope) by reinstantiating RNGStack, which reinstatiates the RNG factory, from which the RNGs selected by the user are instantiated.

Note also that RNGFactory associates tk::ctr::RNG ids (enum class values) to function pointers (std::function objects pointing to tk::RNG constructors bound with their arguments). Since function pointers cannot simply be serialized and migrated via the network, they must also be recreated on remote machines. This initial migration of global-scope data is done by the Charm++ runtime once the main chare constructor is finished – see the RNGTestDriver constructor, which initializes the data required for the migration). Defaults of input deck, facilitates detection what is set by user

This object is in global scope, it contains the default of all possible user input, and thus it is made available to all PEs for convenience reasons. The runtime system distributes it to all PEs during initialization. Once distributed, the object does not change.

std::map<tk::ctr::RawRNGType, tk::RNG> rngtest::g_rng

Random number generators selected by user

This map is in global scope, because it holds polymorphic objects, and thus must be distributed to all PEs during initialization. Once distributed by the runtime system, the objects do not change and available to all PEs.

TestStack rngtest::g_testStack

Statistical test wrappers, grouped by test libraries

This object is in global scope, because it holds function pointers to test runners, and thus must be distributed to all PEs during initialization. Once distributed by the runtime system, the objects do not change.