CASToR  1.1
Tomographic Reconstruction (PET/SPECT)
 All Classes Files Functions Variables Typedefs Macros Groups Pages
sRandomNumberGenerator.cc
Go to the documentation of this file.
1 
2 /*
3  Implementation of class sRandomNumberGenerator
4 
5  - separators: X
6  - doxygen: X
7  - default initialization: X
8  - CASTOR_DEBUG: none
9  - CASTOR_VERBOSE: X
10 */
11 
21 
23 
24 
25 // =====================================================================
26 // ---------------------------------------------------------------------
27 // ---------------------------------------------------------------------
28 // =====================================================================
33 {
34  mp_Instance = NULL;
35  m_verbose = 5;
36  mp_Engines.clear();
37  mp_NonThreadedEngine = NULL;
38 }
39 
40 
41 
42 // =====================================================================
43 // ---------------------------------------------------------------------
44 // ---------------------------------------------------------------------
45 // =====================================================================
46 /*
47  \brief Destructor of sRandomNumberGenerator. Do nothing by default
48 */
50 {
52 }
53 
54 
55 
56 // =====================================================================
57 // ---------------------------------------------------------------------
58 // ---------------------------------------------------------------------
59 // =====================================================================
60 /*
61  \fn Initialize
62  \param a_nbThreads
63  \brief Instanciate a number of RNG according to the number of threads used in openMP
64  \details It uses a std::random_device as initial seed for each thread
65  \return 0 if success, positive value otherwise
66 */
68 {
69  if(m_verbose >=3) if(m_verbose>=3) Cout("sRandomNumberGenerator::Initialize ..."<< endl);
70 
71  for(int th=0; th<a_nbThreads; th++)
72  {
73  std::random_device rd;
74  mp_Engines.push_back(Engine(rd()));
75  }
76 
77  std::random_device rd_single;
78  mp_NonThreadedEngine = new Engine(rd_single());
79 
80  return 0;
81 }
82 
83 
84 
85 // =====================================================================
86 // ---------------------------------------------------------------------
87 // ---------------------------------------------------------------------
88 // =====================================================================
98 int sRandomNumberGenerator::Initialize(int64_t a_seed, int a_nbThreads)
99 {
100  if(m_verbose >=3) Cout("sRandomNumberGenerator::Initialize with provided seed..."<< endl);
101 
102  if (a_seed<0)
103  {
104  Cout("***** sRandomNumberGenerator::Initialize()-> Error : seed for RNG should be >=0 !" << endl);
105  return 1;
106  }
107 
108  for(int th=0; th<a_nbThreads; th++)
109  {
110  mp_Engines.push_back(Engine(a_seed));
111  if(m_verbose>=3) Cout("sRandomNumberGenerator::Initialize()->Seed for thread "<< th << " : " << a_seed << endl);
112  a_seed++;
113  }
114 
115  mp_NonThreadedEngine = new Engine(a_seed);
116 
117  return 0;
118 }
119 
120 
121 
122 // =====================================================================
123 // ---------------------------------------------------------------------
124 // ---------------------------------------------------------------------
125 // =====================================================================
126 /*
127  \fn GenerateRdmNber
128  \brief Generate a random number for the thread whose index is recovered from the ompenMP function
129  \todo Perhaps getting the thread index from argument rather than directly from the function.
130  \todo But this implementation allows the RNG to be used anywhere in the code
131  \todo Perhaps create a random distribution on the fly, and offer the possibility to select lower/upper bounds via argument parameters
132  \return a random generated number in [0. ; 1.)
133 */
135 {
136  #ifdef CASTOR_VERBOSE
137  if(m_verbose >=4) Cout("sRandomNumberGenerator::GenerateRdmNber..."<< endl);
138  #endif
139 
140  int id=0;
141  #ifdef CASTOR_OMP
142  id = omp_get_thread_num();
143  #endif
144  return mp_Distribution(mp_Engines[id]);
145 }
146 
147 
148 
149 // =====================================================================
150 // ---------------------------------------------------------------------
151 // ---------------------------------------------------------------------
152 // =====================================================================
153 /*
154  \fn GenerateNonThreadedRdmNber
155  \brief Generate a random number using the not thread safe random generator, for use in sequential
156  parts of an otherwise multithreaded code
157  \return double random number
158 */
160 {
161  #ifdef CASTOR_VERBOSE
162  if(m_verbose >=4) Cout("sRandomNumberGenerator::GenerateNonThreadedRdmNber..."<< endl);
163  #endif
164 
166 }
167 
168 
169 
170 // =====================================================================
171 // ---------------------------------------------------------------------
172 // ---------------------------------------------------------------------
173 // =====================================================================
174 /*
175  \fn GetNonThreadedGenerator
176  \brief Get the not thread safe random generator, for use in sequential
177  parts of an otherwise multithreaded code
178  \return double random number
179 */
181 {
182  #ifdef CASTOR_VERBOSE
183  if(m_verbose >=4) Cout("sRandomNumberGenerator::GetNonThreadedGenerator..."<< endl);
184  #endif
185 
186  return mp_NonThreadedEngine;
187 }
double GenerateRdmNber()
Generate a random number for the thread whose index is recovered from the ompenMP function...
double GenerateNonThreadedRdmNber()
Generate a random number using the not thread safe random generator, for use in sequential parts of a...
int Initialize(int a_nbThreads)
Instanciate a number of RNG according to the number of threads used in openMP.
sRandomNumberGenerator()
Constructor of sRandomNumberGenerator. Do nothing by default as it is a singleton clasee...
Singleton class that generate a thread-safe random generator number for openMP As singleton...
Declaration of class sRandomNumberGenerator.
#define Cout(MESSAGE)
static sRandomNumberGenerator * mp_Instance
~sRandomNumberGenerator()
Destructor of sRandomNumberGenerator. Do nothing by default.
Engine * GetNonThreadedGenerator()
Get the not thread safe random generator, for use in sequential parts of an otherwise multithreaded c...