Belle II Software light-2406-ragdoll
RandomGenerator Class Reference

Fast Random number Generator using on xorshift1024* [arXiv:1402.6246]. More...

#include <RandomGenerator.h>

Inheritance diagram for RandomGenerator:
Collaboration diagram for RandomGenerator:

Public Types

enum  EGeneratorMode {
  c_independent ,
  c_runDependent ,
  c_eventDependent
}
 Generator mode: determines which information is used to generate the internal state. More...
 

Public Member Functions

 RandomGenerator (const std::string &name="Belle2 Random Generator")
 Default constructor, does not initialize the generator.
 
virtual ~RandomGenerator ()
 Destructor to free the seed information.
 
void setSeed (const unsigned char *seed, unsigned int n)
 Set the seed information.
 
void setMode (EGeneratorMode mode)
 Set the generator mode.
 
EGeneratorMode getMode () const
 Get the generator mode.
 
const std::vector< unsigned char > & getSeed () const
 return the seed object
 
void initialize ()
 set the State from event meta information like experiment, run, and event number.
 
void barrier ()
 increase the barrier index.
 
void setBarrier (int barrierIndex)
 manually set the barrier index to a fixed value
 
int getBarrier () const
 obtain the currently active barrier id
 
uint64_t random64 ()
 Generate one 64bit unsigned integer between 0 and UINT64_MAX (both inclusive).
 
uint32_t random32 ()
 Generate one 32bit unsigned integer between 0 and UINT32_MAX (both inclusive)
 
double random01 ()
 Generate a random double value between 0 and 1, both limits excluded.
 
Double_t Rndm ()
 Generate a random value in (0,1), both limits excluded.
 
Double_t Rndm (Int_t)
 Generate a random value in (0,1), both limits excluded (backward compatibility with root < 6.08).
 
void RndmArray (Int_t n, Float_t *array)
 Fill an array of floats with random values in (0,1), both limits excluded.
 
void RndmArray (Int_t n, Double_t *array)
 Fill an array of doubles with random values in (0,1), both limits excluded.
 
void RndmArray (Int_t n, ULong64_t *array)
 Fill an array of unsigned 64bit integers with random values in [0, UINT64_MAX], both limits included.
 
void RndmArray (Int_t n, UInt_t *array)
 Fill an array of unsigned integers with random values in [0, UINT32_MAX], both limits included.
 
void RndmArray (Int_t n, Int_t *array)
 Fill an array of 32bit integers with random values in [INT32_MIN, INT32_MAX], both limits included.
 
void RndmArray (Int_t n, Long64_t *array)
 Fill an array of 64bit integers with random values in [INT64_MIN, INT64_MAX], both limits included.
 
void RndmArray (Int_t n, unsigned char *array)
 Fill an array with random data.
 

Private Member Functions

void SetSeed (UInt_t)
 override base class SetSeed to do nothing, we don't need it but it gets called by parent constructor
 
void SetSeed (ULong_t)
 argument type was changed in root 6.08.
 
void setState (int barrier)
 Set the state of the random number generator.
 
 ClassDef (RandomGenerator, 2)
 and the root dictionary macro needs to be documented as well :) Version 2: merge m_eventDependent and m_useEventData into a general generator mode m_mode
 

Private Attributes

uint64_t m_state [16]
 Internal state of the random number generator.
 
unsigned int m_index
 currently active index in the internal state
 
int m_barrier
 current barrier index.
 
std::vector< unsigned char > m_seed
 seed information
 
EGeneratorMode m_mode
 Current generator mode.
 

Detailed Description

Fast Random number Generator using on xorshift1024* [arXiv:1402.6246].

It has a period of 2^{1024-1} and passes the Big Crush test while being very small and fast with an internal state of just 1024bit. We seed the generator at the beginning of each event with a combination of a seed value and the experiment/run/event number information of that event to ensure maximum reproducibility even in multiprocessing environments.

The seeding is done using the Keccak secure hash algorithm (SHA-3, FIPS 202 Draft) with arbitrary hash length (set to 1024bit). This ensures evenly distributed generator states even with only small changes in the event information and large numbers of zeros in the seed information. We generate the hash from the (optional) arbitrary seed information followed by the event meta data in big endian representation.

See BELLE2-NOTE-TE-2015-031: Belle II UNICORN – UNIfied Calculation Of Random Numbers for details. Available at: https://docs.belle2.org/record/292?ln=en

Definition at line 37 of file RandomGenerator.h.

Member Enumeration Documentation

◆ EGeneratorMode

Generator mode: determines which information is used to generate the internal state.

Enumerator
c_independent 

Don't use event info to generate state.

c_runDependent 

Use experiment and run number to generate state.

c_eventDependent 

Use experiment, run and event number to generate state.

Definition at line 41 of file RandomGenerator.h.

41 {
48 };
@ c_runDependent
Use experiment and run number to generate state.
@ c_eventDependent
Use experiment, run and event number to generate state.
@ c_independent
Don't use event info to generate state.

Constructor & Destructor Documentation

◆ RandomGenerator()

RandomGenerator ( const std::string &  name = "Belle2 Random Generator")
explicit

Default constructor, does not initialize the generator.

Definition at line 35 of file RandomGenerator.cc.

35 : TRandom(), m_state{0}, m_index(0), m_barrier(0),
37{
38 SetName(name.c_str());
39 SetTitle("Belle2 Random Generator");
40}
uint64_t m_state[16]
Internal state of the random number generator.
unsigned int m_index
currently active index in the internal state
int m_barrier
current barrier index.
EGeneratorMode m_mode
Current generator mode.

◆ ~RandomGenerator()

virtual ~RandomGenerator ( )
inlinevirtual

Destructor to free the seed information.

Definition at line 54 of file RandomGenerator.h.

54{}

Member Function Documentation

◆ barrier()

void barrier ( )
inline

increase the barrier index.

This will reseed the generator with the current event information and and a new barrier index to make random number state independent between different parts of the steering file.

Definition at line 86 of file RandomGenerator.h.

86{ setState(m_barrier + 1); }
void setState(int barrier)
Set the state of the random number generator.

◆ getBarrier()

int getBarrier ( ) const
inline

obtain the currently active barrier id

Definition at line 92 of file RandomGenerator.h.

92{ return m_barrier; }

◆ getMode()

EGeneratorMode getMode ( ) const
inline

Get the generator mode.

Definition at line 71 of file RandomGenerator.h.

71{ return m_mode; }

◆ getSeed()

const std::vector< unsigned char > & getSeed ( ) const
inline

return the seed object

Definition at line 74 of file RandomGenerator.h.

74{ return m_seed; }
std::vector< unsigned char > m_seed
seed information

◆ initialize()

void initialize ( )
inline

set the State from event meta information like experiment, run, and event number.

The event number is only used if the generator is set to event dependent on construction.

Definition at line 80 of file RandomGenerator.h.

80{ setState(0); }

◆ random32()

uint32_t random32 ( )
inline

Generate one 32bit unsigned integer between 0 and UINT32_MAX (both inclusive)

Returns
random value in [0, UINT32_MAX]

Definition at line 104 of file RandomGenerator.h.

104{ return random64() >> 32; }
uint64_t random64()
Generate one 64bit unsigned integer between 0 and UINT64_MAX (both inclusive).

◆ Rndm() [1/2]

Double_t Rndm ( )
inline

Generate a random value in (0,1), both limits excluded.

Definition at line 112 of file RandomGenerator.h.

112{ return random01(); }
double random01()
Generate a random double value between 0 and 1, both limits excluded.

◆ Rndm() [2/2]

Double_t Rndm ( Int_t  )
inline

Generate a random value in (0,1), both limits excluded (backward compatibility with root < 6.08).

Definition at line 114 of file RandomGenerator.h.

114{ return Rndm(); }
Double_t Rndm()
Generate a random value in (0,1), both limits excluded.

◆ RndmArray() [1/3]

void RndmArray ( Int_t  n,
Int_t *  array 
)
inline

Fill an array of 32bit integers with random values in [INT32_MIN, INT32_MAX], both limits included.

Parameters
nnumber of ints to generate
arraypointer to an array where the numbers should be stored

Definition at line 144 of file RandomGenerator.h.

144{ RndmArray(n, (UInt_t*) array); }
void RndmArray(Int_t n, Float_t *array)
Fill an array of floats with random values in (0,1), both limits excluded.

◆ RndmArray() [2/3]

void RndmArray ( Int_t  n,
Long64_t *  array 
)
inline

Fill an array of 64bit integers with random values in [INT64_MIN, INT64_MAX], both limits included.

Parameters
nnumber of ints to generate
arraypointer to an array where the numbers should be stored

Definition at line 151 of file RandomGenerator.h.

151{ RndmArray(n, (ULong64_t*) array); }

◆ RndmArray() [3/3]

void RndmArray ( Int_t  n,
unsigned char *  array 
)

Fill an array with random data.

Parameters
nnumber of bytes to generate
arraypointer to an array where the data should be stored

Definition at line 120 of file RandomGenerator.cc.

121{
122 //First we fill the array using 64bit blocks
123 RndmArray(n / sizeof(ULong64_t), (ULong64_t*)array);
124 const Int_t remainder = n % sizeof(ULong64_t);
125 //If the size is not divisible by 8 we fill the remainder from one additional
126 //random value
127 if (remainder) {
128 const ULong64_t r = random64();
129 std::copy_n((unsigned char*)&r, remainder, array + (n - remainder - 1));
130 }
131}

◆ setBarrier()

void setBarrier ( int  barrierIndex)
inline

manually set the barrier index to a fixed value

Definition at line 89 of file RandomGenerator.h.

89{ setState(barrierIndex); }

◆ setMode()

void setMode ( EGeneratorMode  mode)
inline

Set the generator mode.

Definition at line 68 of file RandomGenerator.h.

68{ m_mode = mode; }

◆ setSeed()

void setSeed ( const unsigned char *  seed,
unsigned int  n 
)

Set the seed information.

This can be an arbitrary sequence of bytes: strings, values, etc. It should be less or equal to 128 bytes as this is the size of the random generator state but it can be longer. The seed is copied when calling this function so the original buffer can be freed afterwards

Parameters
seedpointer to seed data
nof the seed data in bytes

Definition at line 42 of file RandomGenerator.cc.

43{
44 //Copy the seed information and set the seed length
45 m_seed.resize(n);
46 std::copy_n(seed, n, m_seed.data());
47 //reinit the state but ignore missing EventMetaInfo
48 setState(0);
49}

◆ SetSeed() [1/2]

void SetSeed ( UInt_t  )
inlineprivate

override base class SetSeed to do nothing, we don't need it but it gets called by parent constructor

Definition at line 161 of file RandomGenerator.h.

161{}

◆ SetSeed() [2/2]

void SetSeed ( ULong_t  )
inlineprivate

argument type was changed in root 6.08.

Definition at line 163 of file RandomGenerator.h.

163{}

◆ setState()

void setState ( int  barrier)
private

Set the state of the random number generator.

To achieve maximum reproducibility the generator is reset at the begin of every event using a combination of the seed data and the experiment/run/event number and possible some extra information.

To achieve a good separation of the state for similar event information we use the Keccak hash algorithm (SHAKE, FIPS202 draft) where we select the hashsize to be equal to the generator state. This generates evenly distributed generator states even for input data which contains many zeros.

Parameters
barrierindex to use when setting the state. m_barrier will be set to his value

Definition at line 51 of file RandomGenerator.cc.

52{
53 //Reset the internal state position
54 m_index = 0;
55 //Set the barrier to the requested value
57 //Create a SHA-3 hash structrure
58 ShakeHash hash(ShakeHash::c_SHAKE256);
59 //If we have a seed info, add it to the hash
60 if (m_seed.size() > 0) hash.update(m_seed.size(), m_seed.data());
61 //Create a byte buffer to store event dependent data to feed to the hash
62 std::vector<unsigned char> buffer;
63 //estimated size of event dependent info in bytes. vector will make sure it
64 //works even if this changes but we like to avoid unnecessary relocations
65 buffer.reserve(28);
66 //add the barrier to the buffer
67 addValueToBuffer(buffer, m_barrier);
68 //do we want to use EventMetaData at all?
69 if (m_mode != c_independent) {
70 //check if we have event data
72 if (!evt) {
73 //no event data, this should not be
74 B2ERROR("No EventMetaData, cannot set state of RandomGenerator from event data");
75 } else {
76 //ok, add event data to buffer
77 addValueToBuffer(buffer, evt->getExperiment());
78 addValueToBuffer(buffer, evt->getRun());
79 // and if we are in run dependent mode add also event number to the hash
80 if (m_mode == c_eventDependent) {
81 addValueToBuffer(buffer, evt->getEvent());
82 }
83 }
84 }
85
86 hash.update(buffer.size(), buffer.data());
87 //Extract 1024bit hash from the hash structure and write it into the
88 //internal state
89 hash.getHash(sizeof(m_state), (unsigned char*) m_state);
90
91 //Only prepare debugoutput if we actually want to show it. This is almost
92 //equivalent to B2DEBUG(200, ...); but we need to loop over states for
93 //printing so we could not put it in a normal B2DEBUG statement easily.
94#ifndef LOG_NO_B2DEBUG
95 if (Belle2::LogSystem::Instance().isLevelEnabled(Belle2::LogConfig::c_Debug, 200, PACKAGENAME())) {
96 std::stringstream info;
97 info << "Random Generator '" << GetName() << "' State info:\n";
98 info << " seed (" << std::dec << m_seed.size() << "):\n ";
99 for (auto c : m_seed) { info << std::setw(2) << std::setfill('0') << std::hex << (int)c << " "; }
100 info << "\n event info (mode=" << m_mode << "): \n";
101 info << " barrier:" << std::dec << m_barrier;
102 if (m_mode != c_independent) {
104 info << " EXP:" << evt->getExperiment() << " RUN:" << evt->getRun();
105 if (m_mode == c_eventDependent) {
106 info << " EVT:" << evt->getEvent();
107 }
108 }
109 info << "\n event bytes (" << std::dec << buffer.size() << "):\n ";
110 for (auto c : buffer) { info << std::setw(2) << std::setfill('0') << std::hex << (int)c << " "; }
111 info << "\n state (index=" << m_index << "): ";
112 for (int i = 0; i < 16; ++i) {
113 info << ((i % 4 == 0) ? "\n " : " ") << std::setw(16) << std::setfill('0') << std::hex << m_state[i];
114 }
115 _B2LOGMESSAGE(Belle2::LogConfig::c_Debug, 200, info.str(), PACKAGENAME(), FUNCTIONNAME(), __FILE__, __LINE__);
116 }
117#endif
118}
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:26
static LogSystem & Instance()
Static method to get a reference to the LogSystem instance.
Definition: LogSystem.cc:31
void barrier()
increase the barrier index.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96

Member Data Documentation

◆ m_barrier

int m_barrier
private

current barrier index.

This is used to separate random numbers in different modules by resetting the state between modules using a different barrier index.

Definition at line 188 of file RandomGenerator.h.

◆ m_index

unsigned int m_index
private

currently active index in the internal state

Definition at line 184 of file RandomGenerator.h.

◆ m_mode

EGeneratorMode m_mode
private

Current generator mode.

Definition at line 192 of file RandomGenerator.h.

◆ m_seed

std::vector<unsigned char> m_seed
private

seed information

Definition at line 190 of file RandomGenerator.h.

◆ m_state

uint64_t m_state[16]
private

Internal state of the random number generator.

Definition at line 182 of file RandomGenerator.h.


The documentation for this class was generated from the following files: