QMCPACK
RandomNumberControl Class Reference

class RandomNumberControl More...

+ Inheritance diagram for RandomNumberControl:
+ Collaboration diagram for RandomNumberControl:

Public Types

using FullPrecRealType = QMCTraits::FullPrecRealType
 
using uint_type = RandomBase< FullPrecRealType >::uint_type
 
- Public Types inherited from OhmmsElementBase
enum  { useLIBXML = 0, useLIBXMLPP, usePLAIN }
 enumeration to choose the xml parser More...
 

Public Member Functions

 RandomNumberControl (const char *aname="random")
 constructors and destructors More...
 
bool get (std::ostream &os) const override
 generic output More...
 
bool put (std::istream &is) override
 generic input More...
 
bool put (xmlNodePtr cur) override
 read from an xmlNode More...
 
void reset () override
 reset the generator More...
 
xmlNodePtr initialize (xmlXPathContextPtr)
 
- Public Member Functions inherited from OhmmsElementBase
 OhmmsElementBase (const char *aname="none")
 constructor with a name More...
 
virtual ~OhmmsElementBase ()
 destructor More...
 
const std::string & getName () const
 return the name More...
 
void setName (const std::string &aname)
 set name More...
 
void setIOMode (int imode)
 set iomode More...
 
virtual bool add (xmlNodePtr parent)
 add a xmlNode to the children list of parent More...
 
void put (const std::string &s)
 read from string More...
 
virtual void begin_node (std::ostream &os) const
 write the start of a node More...
 
virtual void end_node (std::ostream &os) const
 write the end of a node More...
 

Static Public Member Functions

static void test ()
 
static void make_seeds ()
 reset the generator More...
 
static void make_children ()
 
static void read (const std::string &fname, Communicate *comm)
 read in parallel or serial More...
 
static void write (const std::string &fname, Communicate *comm)
 write in parallel or serial More...
 
static void write (const RefVector< RandomBase< FullPrecRealType >> &rng, const std::string &fname, Communicate *comm)
 write in parallel or serial More...
 
static void read_parallel (hdf_archive &hin, Communicate *comm)
 read random state from a hdf file in parallel More...
 
static void write_parallel (const RefVector< RandomBase< FullPrecRealType >> &rng, hdf_archive &hout, Communicate *comm)
 write random state to a hdf file in parallel More...
 
static void read_rank_0 (hdf_archive &hin, Communicate *comm)
 rank 0 reads random states from a hdf file and distributes them to all the other ranks More...
 
static void write_rank_0 (const RefVector< RandomBase< FullPrecRealType >> &rng, hdf_archive &hout, Communicate *comm)
 rank 0 gathers the random states from all the other ranks and write them to a hdf file More...
 

Static Public Attributes

static PrimeNumberSet< uint_typePrimeNumbers
 initialize the static data members More...
 
static UPtrVector< RandomBase< FullPrecRealType > > Children
 

Private Attributes

bool NeverBeenInitialized
 
xmlNodePtr myCur
 

Static Private Attributes

static uint_type Offset = 11u
 

Additional Inherited Members

- Protected Attributes inherited from OhmmsElementBase
int myIOMode
 the type of IO mode: default is useLIBXML More...
 
std::string myName
 the name of the node, corresponds to the xml tag More...
 

Detailed Description

class RandomNumberControl

Encapsulate data to initialize and save the status of the random number generator

Default: myName = "random" 2007-12-01 Use PrimeNumbers to generate random seeds.

Definition at line 39 of file RandomNumberControl.h.

Member Typedef Documentation

◆ FullPrecRealType

◆ uint_type

Definition at line 43 of file RandomNumberControl.h.

Constructor & Destructor Documentation

◆ RandomNumberControl()

RandomNumberControl ( const char *  aname = "random")

constructors and destructors

Definition at line 36 of file RandomNumberControl.cpp.

37  : OhmmsElementBase(aname), NeverBeenInitialized(true), myCur(NULL) //, Offset(5)
38 {}
OhmmsElementBase(const char *aname="none")
constructor with a name

Member Function Documentation

◆ get()

bool get ( std::ostream &  os) const
overridevirtual

generic output

Implements OhmmsElementBase.

Definition at line 41 of file RandomNumberControl.cpp.

References RandomNumberControl::Children, omp_get_max_threads(), and Random.

42 {
43  if (omp_get_max_threads() > 1)
44  {
45  for (int ip = 0; ip < omp_get_max_threads(); ip++)
46  {
47  Children[ip]->write(os);
48  os << std::endl;
49  }
50  }
51  else
52  {
53  Random.write(os);
54  }
55  return true;
56 }
#define Random
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
static UPtrVector< RandomBase< FullPrecRealType > > Children

◆ initialize()

xmlNodePtr initialize ( xmlXPathContextPtr  acontext)

Definition at line 98 of file RandomNumberControl.cpp.

References RandomNumberControl::myCur, and RandomNumberControl::put().

Referenced by QMCMain::execute(), qmcplusplus::TEST_CASE(), and QMCMain::validateXML().

99 {
100  OhmmsXPathObject rg_request("//random", acontext);
101  put(rg_request[0]);
102  return myCur;
103 }
class to handle xmlXPathObject
Definition: Libxml2Doc.h:26
bool put(std::istream &is) override
generic input

◆ make_children()

void make_children ( )
static

Definition at line 80 of file RandomNumberControl.cpp.

References RandomNumberControl::Children, OHMMS::Controller, PrimeNumberSet< UIntType >::get(), qmcplusplus::n, RandomNumberControl::Offset, omp_get_max_threads(), RandomNumberControl::PrimeNumbers, qmcplusplus::rank, Communicate::rank(), and Communicate::size().

Referenced by RandomNumberControl::make_seeds(), and RandomNumberControl::put().

81 {
82  int nthreads = omp_get_max_threads();
83  int n = nthreads - Children.size();
84  while (n)
85  {
86  Children.push_back(std::make_unique<RandomGenerator>());
87  n--;
88  }
89  int rank = OHMMS::Controller->rank();
90  int nprocs = OHMMS::Controller->size();
91  int baseoffset = Offset + nprocs + nthreads * rank;
92  std::vector<uint_type> myprimes;
93  PrimeNumbers.get(baseoffset, nthreads, myprimes);
94  for (int ip = 0; ip < nthreads; ip++)
95  Children[ip]->init(myprimes[ip]);
96 }
int rank() const
return the rank
Definition: Communicate.h:116
static PrimeNumberSet< uint_type > PrimeNumbers
initialize the static data members
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
int size() const
return the number of tasks
Definition: Communicate.h:118
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
static UPtrVector< RandomBase< FullPrecRealType > > Children
bool get(UIntType offset, int n, std::vector< UIntType > &primes_add)
add n new primes starting with an offset

◆ make_seeds()

void make_seeds ( )
static

reset the generator

Definition at line 65 of file RandomNumberControl.cpp.

References qmcplusplus::bcast(), OHMMS::Controller, PrimeNumberSet< UIntType >::get(), RandomNumberControl::make_children(), RandomNumberControl::Offset, omp_get_max_threads(), RandomNumberControl::PrimeNumbers, Random, Communicate::rank(), and Communicate::size().

Referenced by QMCDriverNew::createRngsStepContexts(), QMCDriver::process(), RandomNumberControl::reset(), and qmcplusplus::TEST_CASE().

66 {
67  int pid = OHMMS::Controller->rank();
68  int nprocs = OHMMS::Controller->size();
69  uint_type iseed = static_cast<uint_type>(std::time(0)) % 1024;
71  //OHMMS::Controller->bcast(iseed);//broadcast the seed
72  Offset = iseed;
73  std::vector<uint_type> mySeeds;
75  Random.init(mySeeds[pid]);
76  //change children as well
77  make_children();
78 }
int rank() const
return the rank
Definition: Communicate.h:116
static PrimeNumberSet< uint_type > PrimeNumbers
initialize the static data members
#define Random
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
int size() const
return the number of tasks
Definition: Communicate.h:118
void bcast(T &a, Communicate *comm)
Definition: CommUtilities.h:78
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
RandomBase< FullPrecRealType >::uint_type uint_type
bool get(UIntType offset, int n, std::vector< UIntType > &primes_add)
add n new primes starting with an offset

◆ put() [1/2]

bool put ( std::istream &  is)
overridevirtual

generic input

Implements OhmmsElementBase.

Definition at line 59 of file RandomNumberControl.cpp.

Referenced by RandomNumberControl::initialize().

59 { return true; }

◆ put() [2/2]

bool put ( xmlNodePtr  cur)
overridevirtual

read from an xmlNode

Implements OhmmsElementBase.

Definition at line 148 of file RandomNumberControl.cpp.

References OhmmsAttributeSet::add(), qmcplusplus::app_log(), qmcplusplus::app_summary(), qmcplusplus::bcast(), OHMMS::Controller, PrimeNumberSet< UIntType >::get(), RandomNumberControl::make_children(), RandomNumberControl::NeverBeenInitialized, RandomNumberControl::Offset, omp_get_max_threads(), RandomNumberControl::PrimeNumbers, OhmmsAttributeSet::put(), Random, Communicate::rank(), RandomNumberControl::reset(), and Communicate::size().

149 {
151  {
152  bool init_mpi = true;
153  int offset_in = -1; // default is to generate by Wall-clock
154  if (cur != NULL)
155  {
156  std::string pname("yes");
157  OhmmsAttributeSet oAttrib;
158  oAttrib.add(pname, "parallel");
159  oAttrib.add(offset_in, "seed");
160  oAttrib.put(cur);
161  if (pname == "0" || pname == "false" || pname == "no")
162  init_mpi = false;
163  }
164  int nprocs = 1;
165  int pid = 0;
166  if (init_mpi)
167  {
168  pid = OHMMS::Controller->rank();
169  nprocs = OHMMS::Controller->size();
170  }
171 
172  app_summary() << std::endl;
173  app_summary() << " Random Number" << std::endl;
174  app_summary() << " -------------" << std::endl;
175  if (offset_in < 0)
176  {
177  offset_in = static_cast<int>(static_cast<uint_type>(std::time(0)) % 1024);
178  app_summary() << " Offset for the random number seeds based on time: " << offset_in << std::endl;
179  mpi::bcast(*OHMMS::Controller, offset_in);
180  }
181  else
182  {
183  offset_in %= 1024;
184  app_summary() << " Offset for the random number seeds from input file (mod 1024): " << offset_in << std::endl;
185  }
186  app_summary() << std::endl;
187  Offset = offset_in;
188  std::vector<uint_type> mySeeds;
189  //allocate twice of what is required
190  PrimeNumbers.get(Offset, nprocs * (omp_get_max_threads() + 2), mySeeds);
191  Random.init(mySeeds[pid]);
192  app_log() << " Range of prime numbers to use as seeds over processors and threads = " << mySeeds[0] << "-"
193  << mySeeds[nprocs * omp_get_max_threads()] << std::endl;
194  app_log() << std::endl;
195 
196  make_children();
197  NeverBeenInitialized = false;
198  }
199  else
200  reset();
201  return true;
202 }
int rank() const
return the rank
Definition: Communicate.h:116
std::ostream & app_log()
Definition: OutputManager.h:65
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
static PrimeNumberSet< uint_type > PrimeNumbers
initialize the static data members
#define Random
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
int size() const
return the number of tasks
Definition: Communicate.h:118
void bcast(T &a, Communicate *comm)
Definition: CommUtilities.h:78
void reset() override
reset the generator
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
RandomBase< FullPrecRealType >::uint_type uint_type
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
bool get(UIntType offset, int n, std::vector< UIntType > &primes_add)
add n new primes starting with an offset

◆ read()

void read ( const std::string &  fname,
Communicate comm 
)
static

read in parallel or serial

Parameters
fnamefile name
commcommunicator

Definition at line 206 of file RandomNumberControl.cpp.

References qmcplusplus::comm, hdf_archive::is_parallel(), hdf_archive::open(), RandomNumberControl::read_parallel(), and RandomNumberControl::read_rank_0().

Referenced by QMCMain::setMCWalkers(), and qmcplusplus::TEST_CASE().

207 {
208  std::string h5name = fname + ".random.h5";
209  hdf_archive hin(comm, true); //attempt to read in parallel
210  hin.open(h5name, H5F_ACC_RDONLY);
211  if (hin.is_parallel())
212  read_parallel(hin, comm);
213  else
214  read_rank_0(hin, comm);
215 }
static void read_parallel(hdf_archive &hin, Communicate *comm)
read random state from a hdf file in parallel
static void read_rank_0(hdf_archive &hin, Communicate *comm)
rank 0 reads random states from a hdf file and distributes them to all the other ranks ...

◆ read_parallel()

void read_parallel ( hdf_archive hin,
Communicate comm 
)
static

read random state from a hdf file in parallel

Parameters
hinhdf_archive set to parallel
commcommunicator

Definition at line 237 of file RandomNumberControl.cpp.

References qmcplusplus::app_log(), RandomNumberControl::Children, hdf_archive::close(), qmcplusplus::comm, qmcplusplus::hdf::main_state, omp_get_max_threads(), hdf_archive::pop(), hdf_archive::push(), Random, Communicate::rank(), hdf_archive::read(), and Communicate::size().

Referenced by RandomNumberControl::read().

238 {
239  // cast integer to size_t
240  const size_t nthreads = static_cast<size_t>(omp_get_max_threads());
241  const size_t comm_size = static_cast<size_t>(comm->size());
242  const size_t comm_rank = static_cast<size_t>(comm->rank());
243 
244  std::vector<uint_type> vt, mt;
245  TinyVector<int, 3> shape_now(comm->size(), nthreads, Random.state_size()); //cur configuration
246  TinyVector<int, 3> shape_hdf5(3, 0); //configuration when file was written
247 
248  //grab shape and Random.state_size() used to create hdf5 file
249  hin.push(hdf::main_state);
250  hin.read(shape_hdf5, "nprocs_nthreads_statesize");
251 
252  //if hdf5 file's shape and the current shape don't match, abort read
253  if (shape_hdf5[0] != shape_now[0] || shape_hdf5[1] != shape_now[1] || shape_hdf5[2] != shape_now[2])
254  {
255  app_log() << "Mismatched random number generators."
256  << "\n Number of procs in streams : old=" << shape_hdf5[0] << " new= " << shape_now[0]
257  << "\n Number of threads in streams : old=" << shape_hdf5[1] << " new= " << shape_now[1]
258  << "\n State size per stream : old=" << shape_hdf5[2] << " new= " << shape_now[2]
259  << "\n Using the random streams generated at the initialization.\n";
260  return;
261  }
262  app_log() << " Restart from the random number streams from the previous configuration.\n";
263 
264  vt.resize(nthreads * Random.state_size()); //buffer for children[ip]
265  mt.resize(Random.state_size()); //buffer for single thread Random object of random nums
266 
267  std::array<size_t, 2> shape{comm_size * nthreads, Random.state_size()}; //global dims of children dataset
268  std::array<size_t, 2> counts{nthreads, Random.state_size()}; //local dimensions of dataset
269  std::array<size_t, 2> offsets{comm_rank * nthreads, 0}; //offsets for each process to read in
270 
271  hin.push("random"); //group that holds children[ip] random nums
272  hyperslab_proxy<std::vector<uint_type>, 2> slab(vt, shape, counts, offsets);
273  hin.read(slab, Random.EngineName);
274 
275  hin.pop();
276  hin.push("random_master"); //group that holds Random_th random nums
277  shape[0] = comm->size(); //reset shape, counts and offset for non-multiple threads
278  counts[0] = 1;
279  offsets[0] = comm->rank();
280  hyperslab_proxy<std::vector<uint_type>, 2> slab2(mt, shape, counts, offsets);
281  hin.read(slab2, Random.EngineName);
282  hin.close();
283 
284  std::vector<uint_type>::iterator vt_it(vt.begin());
285  for (int ip = 0; ip < nthreads; ip++, vt_it += shape[1])
286  {
287  std::vector<uint_type> c(vt_it, vt_it + shape[1]);
288  Children[ip]->load(c); //load random nums back to program from buffer
289  }
290  Random.load(mt); //load random nums back to prog from buffer
291 }
int rank() const
return the rank
Definition: Communicate.h:116
std::ostream & app_log()
Definition: OutputManager.h:65
#define Random
int size() const
return the number of tasks
Definition: Communicate.h:118
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
const char main_state[]
Definition: HDFVersion.h:31
static UPtrVector< RandomBase< FullPrecRealType > > Children

◆ read_rank_0()

void read_rank_0 ( hdf_archive hin,
Communicate comm 
)
static

rank 0 reads random states from a hdf file and distributes them to all the other ranks

Parameters
hinhdf_archive set to serial
commcommunicator

Definition at line 338 of file RandomNumberControl.cpp.

References qmcplusplus::app_log(), qmcplusplus::bcast(), RandomNumberControl::Children, hdf_archive::close(), qmcplusplus::comm, copy(), qmcplusplus::hdf::main_state, omp_get_max_threads(), hdf_archive::pop(), hdf_archive::push(), Random, Communicate::rank(), hdf_archive::read(), hdf_archive::readSlabReshaped(), and Communicate::size().

Referenced by RandomNumberControl::read().

339 {
340  // cast integer to size_t
341  const size_t nthreads = static_cast<size_t>(omp_get_max_threads());
342  const size_t comm_size = static_cast<size_t>(comm->size());
343  const size_t comm_rank = static_cast<size_t>(comm->rank());
344 
345  std::vector<uint_type> vt, vt_tot, mt, mt_tot;
346  TinyVector<size_t, 3> shape_now(comm_size, nthreads, Random.state_size()); //current configuration
347  TinyVector<size_t, 3> shape_hdf5; //configuration when hdf5 file was written
348  std::array<size_t, 2> shape{comm_size * nthreads, Random.state_size()}; //dimensions of children dataset
349 
350  //grab configuration of threads/procs and Random.state_size() in hdf5 file
351  if (comm->rank() == 0)
352  {
353  hin.push(hdf::main_state);
354  hin.read(shape_hdf5, "nprocs_nthreads_statesize");
355  }
356 
357  mpi::bcast(*comm, shape_hdf5);
358 
359  //if hdf5 file's configuration and current configuration don't match, abort read
360  if (shape_hdf5[0] != shape_now[0] || shape_hdf5[1] != shape_now[1] || shape_hdf5[2] != shape_now[2])
361  {
362  app_log() << "Mismatched random number generators."
363  << "\n Number of procs in streams : old=" << shape_hdf5[0] << " new= " << shape_now[0]
364  << "\n Number of threads in streams : old=" << shape_hdf5[1] << " new= " << shape_now[1]
365  << "\n State size per stream : old=" << shape_hdf5[2] << " new= " << shape_now[2]
366  << "\n Using the random streams generated at the initialization.\n";
367  return;
368  }
369  app_log() << " Restart from the random number streams from the previous configuration.\n";
370 
371  vt.resize(nthreads * Random.state_size()); //buffer for random nums in children of each thread
372  mt.resize(Random.state_size()); //buffer for random numbers from single Random object
373 
374  if (comm->rank() == 0)
375  {
376  hin.push("random"); //group for children[ip] (Random.object for each thread)
377  vt_tot.resize(nthreads * Random.state_size() * comm->size());
378  hin.readSlabReshaped(vt_tot, shape, Random.EngineName);
379  hin.pop();
380 
381  shape[0] = comm->size(); //reset shape to one thread per process
382  mt_tot.resize(Random.state_size() * comm->size());
383  hin.push("random_master"); //group for single Random object
384  hin.readSlabReshaped(mt_tot, shape, Random.EngineName);
385  hin.close();
386  }
387 
388  if (comm->size() > 1)
389  {
390  mpi::scatter(*comm, vt_tot, vt); //divide big buffer into on for each proc
391  mpi::scatter(*comm, mt_tot, mt);
392  }
393  else
394  {
395  copy(vt_tot.begin(), vt_tot.end(), vt.begin());
396  copy(mt_tot.begin(), mt_tot.end(), mt.begin());
397  }
398 
399  std::vector<uint_type>::iterator vt_it(vt.begin());
400  for (int i = 0; i < nthreads; i++, vt_it += shape[1])
401  {
402  std::vector<uint_type> c(vt_it, vt_it + shape[1]);
403  Children[i]->load(c); //read seeds for each thread from buffer back into object
404  }
405  Random.load(mt); //read seeds back into object
406 }
int rank() const
return the rank
Definition: Communicate.h:116
std::ostream & app_log()
Definition: OutputManager.h:65
#define Random
int size() const
return the number of tasks
Definition: Communicate.h:118
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
Definition: Blitz.h:639
void bcast(T &a, Communicate *comm)
Definition: CommUtilities.h:78
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
const char main_state[]
Definition: HDFVersion.h:31
static UPtrVector< RandomBase< FullPrecRealType > > Children

◆ reset()

void reset ( )
overridevirtual

reset the generator

Implements OhmmsElementBase.

Definition at line 62 of file RandomNumberControl.cpp.

References RandomNumberControl::make_seeds().

Referenced by RandomNumberControl::put().

62 { make_seeds(); }
static void make_seeds()
reset the generator

◆ test()

void test ( )
static

Definition at line 105 of file RandomNumberControl.cpp.

References qmcplusplus::app_log(), RandomNumberControl::Children, OHMMS::Controller, qmcplusplus::n, omp_get_max_threads(), and Communicate::size().

Referenced by QMCMain::executeQMCSection().

106 {
107  /* Add random number generator tester
108  */
109  int nthreads = omp_get_max_threads();
110  std::vector<double> avg(nthreads), avg2(nthreads);
111 #pragma omp parallel for
112  for (int ip = 0; ip < nthreads; ++ip)
113  {
114  const int n = 1000000;
115  double sum = 0.0, sum2 = 0.0;
116  auto& myrand(*Children[ip]);
117  for (int i = 0; i < n; ++i)
118  {
119  double r = myrand();
120  sum += r;
121  sum2 += r * r;
122  }
123  avg[ip] = sum / static_cast<double>(n);
124  avg2[ip] = sum2 / static_cast<double>(n);
125  }
126  std::vector<double> avg_tot(nthreads * OHMMS::Controller->size()), avg2_tot(nthreads * OHMMS::Controller->size());
127  mpi::gather(*OHMMS::Controller, avg, avg_tot);
128  mpi::gather(*OHMMS::Controller, avg2, avg2_tot);
129  double avg_g = 0.0;
130  double avg2_g = 0.0;
131  for (int i = 0, ii = 0; i < OHMMS::Controller->size(); ++i)
132  {
133  for (int ip = 0; ip < nthreads; ++ip, ++ii)
134  {
135  app_log() << "RNGTest " << std::setw(4) << i << std::setw(4) << ip << std::setw(20) << avg_tot[ii]
136  << std::setw(20) << avg2_tot[ii] - avg_tot[ii] * avg_tot[ii] << std::endl;
137  avg_g += avg_tot[ii];
138  avg2_g += avg2_tot[ii];
139  }
140  }
141  avg_g /= static_cast<double>(nthreads * OHMMS::Controller->size());
142  avg2_g /= static_cast<double>(nthreads * OHMMS::Controller->size());
143  app_log() << "RNGTest " << std::setw(4) << OHMMS::Controller->size() << std::setw(4) << nthreads << std::setw(20)
144  << avg_g << std::setw(20) << avg2_g - avg_g * avg_g << std::endl;
145  app_log().flush();
146 }
std::ostream & app_log()
Definition: OutputManager.h:65
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
int size() const
return the number of tasks
Definition: Communicate.h:118
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
static UPtrVector< RandomBase< FullPrecRealType > > Children

◆ write() [1/2]

void write ( const std::string &  fname,
Communicate comm 
)
static

write in parallel or serial

Parameters
fnamefile name
commcommunicator

Definition at line 217 of file RandomNumberControl.cpp.

References RandomNumberControl::Children, qmcplusplus::comm, and qmcplusplus::convertUPtrToRefVector().

Referenced by QMCDriverNew::finalize(), QMCDriver::finalize(), QMCDriverNew::recordBlock(), QMCDriver::recordBlock(), and qmcplusplus::TEST_CASE().

218 {
220 }
static void write(const std::string &fname, Communicate *comm)
write in parallel or serial
static RefVector< T > convertUPtrToRefVector(const UPtrVector< T > &ptr_list)
convert a vector of std::unique_ptrs<T> to a refvector<T>
static UPtrVector< RandomBase< FullPrecRealType > > Children

◆ write() [2/2]

void write ( const RefVector< RandomBase< FullPrecRealType >> &  rng,
const std::string &  fname,
Communicate comm 
)
static

write in parallel or serial

Parameters
rngrandom number generators
fnamefile name
commcommunicator

Definition at line 223 of file RandomNumberControl.cpp.

References qmcplusplus::comm, hdf_archive::create(), hdf_archive::is_parallel(), RandomNumberControl::write_parallel(), and RandomNumberControl::write_rank_0().

226 {
227  std::string h5name = fname + ".random.h5";
228  hdf_archive hout(comm, true); //attempt to write in parallel
229  hout.create(h5name);
230  if (hout.is_parallel())
231  write_parallel(rng, hout, comm);
232  else
233  write_rank_0(rng, hout, comm);
234 }
static void write_parallel(const RefVector< RandomBase< FullPrecRealType >> &rng, hdf_archive &hout, Communicate *comm)
write random state to a hdf file in parallel
static void write_rank_0(const RefVector< RandomBase< FullPrecRealType >> &rng, hdf_archive &hout, Communicate *comm)
rank 0 gathers the random states from all the other ranks and write them to a hdf file ...

◆ write_parallel()

void write_parallel ( const RefVector< RandomBase< FullPrecRealType >> &  rng,
hdf_archive hout,
Communicate comm 
)
static

write random state to a hdf file in parallel

Parameters
hdf_archiveset to parallel
commcommunicator

Definition at line 294 of file RandomNumberControl.cpp.

References hdf_archive::close(), qmcplusplus::comm, qmcplusplus::hdf::main_state, omp_get_max_threads(), hdf_archive::pop(), hdf_archive::push(), Random, Communicate::rank(), Communicate::size(), and hdf_archive::write().

Referenced by RandomNumberControl::write().

297 {
298  // cast integer to size_t
299  const size_t nthreads = static_cast<size_t>(omp_get_max_threads());
300  const size_t comm_size = static_cast<size_t>(comm->size());
301  const size_t comm_rank = static_cast<size_t>(comm->rank());
302 
303  std::vector<uint_type> vt, mt;
304  TinyVector<int, 3> shape_hdf5(comm->size(), nthreads, Random.state_size()); //configuration at write time
305  vt.reserve(nthreads * Random.state_size()); //buffer for random numbers from children[ip] of each thread
306  mt.reserve(Random.state_size()); //buffer for random numbers from single Random object
307 
308  std::vector<uint_type> c;
309  for (int ip = 0; ip < nthreads; ++ip)
310  {
311  rng[ip].get().save(c);
312  vt.insert(vt.end(), c.begin(), c.end()); //get nums from each thread into buffer
313  }
314  Random.save(mt); //get nums for single random object (no threads)
315 
316  std::array<size_t, 2> shape{comm_size * nthreads, Random.state_size()}; //global dimensions
317  std::array<size_t, 2> counts{nthreads, Random.state_size()}; //local dimensions
318  std::array<size_t, 2> offsets{comm_rank * nthreads, 0}; //offset for the file write
319 
320  hout.push(hdf::main_state);
321  hout.write(shape_hdf5, "nprocs_nthreads_statesize"); //save the shape of the data at write
322 
323  hout.push("random"); //group for children[ip]
324  hyperslab_proxy<std::vector<uint_type>, 2> slab(vt, shape, counts, offsets);
325  hout.write(slab, Random.EngineName); //write to hdf5file
326  hout.pop();
327 
328  shape[0] = comm->size(); //adjust shape, counts, offset for just one thread
329  counts[0] = 1;
330  offsets[0] = comm->rank();
331  hout.push("random_master"); //group for random object without threads
332  hyperslab_proxy<std::vector<uint_type>, 2> slab2(mt, shape, counts, offsets);
333  hout.write(slab2, Random.EngineName); //write data to hdf5 file
334  hout.close();
335 }
int rank() const
return the rank
Definition: Communicate.h:116
#define Random
int size() const
return the number of tasks
Definition: Communicate.h:118
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
const char main_state[]
Definition: HDFVersion.h:31

◆ write_rank_0()

void write_rank_0 ( const RefVector< RandomBase< FullPrecRealType >> &  rng,
hdf_archive hout,
Communicate comm 
)
static

rank 0 gathers the random states from all the other ranks and write them to a hdf file

Parameters
hinhdf_archive object set to serial
commcommunicator

Definition at line 409 of file RandomNumberControl.cpp.

References hdf_archive::close(), qmcplusplus::comm, qmcplusplus::hdf::main_state, omp_get_max_threads(), hdf_archive::pop(), hdf_archive::push(), Random, Communicate::rank(), Communicate::size(), hdf_archive::write(), and hdf_archive::writeSlabReshaped().

Referenced by RandomNumberControl::write().

412 {
413  // cast integer to size_t
414  const size_t nthreads = static_cast<size_t>(omp_get_max_threads());
415  const size_t comm_size = static_cast<size_t>(comm->size());
416  const size_t comm_rank = static_cast<size_t>(comm->rank());
417 
418  std::vector<uint_type> vt, vt_tot, mt, mt_tot;
419  std::array<size_t, 2> shape{comm_size * nthreads, Random.state_size()}; //dimensions of children dataset
420  TinyVector<size_t, 3> shape_hdf5(comm_size, nthreads, Random.state_size()); //configuration at write time
421  vt.reserve(nthreads * Random.state_size()); //buffer for children[ip] (Random object of seeds for each thread)
422  mt.reserve(Random.state_size()); //buffer for single Random object of seeds, one per proc regardless of thread num
423 
424  for (int i = 0; i < nthreads; ++i)
425  {
426  std::vector<uint_type> c;
427  rng[i].get().save(c);
428  vt.insert(vt.end(), c.begin(), c.end()); //copy children[nthreads] seeds to buffer
429  }
430  Random.save(mt); //copy random_th seeds to buffer
431 
432  if (comm->size() > 1)
433  {
434  vt_tot.resize(vt.size() * comm->size());
435  mt_tot.resize(mt.size() * comm->size());
436  mpi::gather(*comm, vt, vt_tot); //gather into one big buffer for master write
437  mpi::gather(*comm, mt, mt_tot);
438  }
439  else
440  {
441  vt_tot = vt;
442  mt_tot = mt;
443  }
444 
445  if (comm->rank() == 0)
446  {
447  hout.push(hdf::main_state);
448  hout.write(shape_hdf5, "nprocs_nthreads_statesize"); //configuration at write time to file
449 
450  hout.push("random"); //group for children[ip]
451  hout.writeSlabReshaped(vt_tot, shape, Random.EngineName);
452  hout.pop();
453 
454  shape[0] = comm->size(); //reset dims for single thread use
455  hout.push("random_master"); //group for random_th object
456  hout.writeSlabReshaped(mt_tot, shape, Random.EngineName);
457  hout.close();
458  }
459 }
int rank() const
return the rank
Definition: Communicate.h:116
#define Random
int size() const
return the number of tasks
Definition: Communicate.h:118
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
const char main_state[]
Definition: HDFVersion.h:31

Member Data Documentation

◆ Children

◆ myCur

xmlNodePtr myCur
private

Definition at line 103 of file RandomNumberControl.h.

Referenced by RandomNumberControl::initialize().

◆ NeverBeenInitialized

bool NeverBeenInitialized
private

Definition at line 102 of file RandomNumberControl.h.

Referenced by RandomNumberControl::put().

◆ Offset

◆ PrimeNumbers

initialize the static data members

Definition at line 44 of file RandomNumberControl.h.

Referenced by RandomNumberControl::make_children(), RandomNumberControl::make_seeds(), and RandomNumberControl::put().


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