Bridge++  Ver. 1.2.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test_RandomNumbers_Mseries_Global.cpp
Go to the documentation of this file.
1 
14 #include "test.h"
15 #include "randomNumbers_Mseries.h"
16 #include "field_G.h"
17 #include "fieldIO_Text.h" // for gather field
18 #include "io_format_gauge.h"
19 
20 //====================================================================
22 
23 namespace Test_RandomNumbers_Mseries {
24  const std::string test_name = "RandomNumbers.Mseries.Global";
25 
26  //- test-private parameters
27  namespace {
28  const std::string filename_input = "test_RandomNumbers_Mseries_Global.yaml";
29  const std::string filename_output = "stdout";
30 
31  class Parameters_Test_RandomNumbers : public Parameters {
32  public:
33  Parameters_Test_RandomNumbers()
34  {
35  Register_int("seed", 0);
36 
37  Register_string("verbose_level", "NULL");
38 
39  Register_double("expected_result", 0.0);
40  }
41  };
42  }
43 
44  //- prototype declaration
45  int test_global(void);
46 
47 #ifdef USE_TESTMANAGER_AUTOREGISTER
48  namespace {
49  static const bool is_registered = TestManager::RegisterTest(
50  test_name,
52  );
53  }
54 #endif
55 
56  //====================================================================
57  int test_global(void)
58  {
59  // #### parameter setup ####
60  Parameters *params_test = new Parameters_Test_RandomNumbers;
61  Parameters *params_all = new Parameters;
62 
63  params_all->Register_Parameters("Test_RandomNumbers", params_test);
64 
65  ParameterManager_YAML params_manager;
66  params_manager.read_params(filename_input, params_all);
67 
68  int seed = params_test->get_int("seed");
69  const string str_vlevel = params_test->get_string("verbose_level");
70 
71  const bool do_check = params_test->is_set("expected_result");
72  const double expected_result = do_check ? params_test->get_double("expected_result") : 0.0;
73 
75 
76  //- print input parameters
77  vout.general(vl, " seed = %d\n", seed);
78  vout.general(vl, " vlevel = %s\n", str_vlevel.c_str());
79  vout.general(vl, "\n");
80 
81 
82  // #### object setup #####
83  Timer *timer = new Timer(test_name);
84 
85 
86  // #### Execution main part ####
87  timer->start();
88 
89  vout.general(vl, "\n");
90  vout.general(vl, "Serial and Node-parallel test of Random Number Generator:\n");
91 
92  // sample field size
93  int nin = 8;
94  int nex = 4;
95 
96  int nvol = CommonParameters::Nvol();
97 
98  int lvol = CommonParameters::Lvol();
99 
100  vout.general(vl, "field size: nin = %d, nex = %d, nvol = %d, lvol = %d\n", nin, nex, nvol, lvol);
101 
102  // buffer for checks
103  const size_t nsample = 1024;
104  double data[nsample];
105  for (size_t i = 0; i < nsample; ++i) {
106  data[i] = 0.0;
107  }
108 
109 
110  // 1. generate field in parallel
111  Field field1(nin, nvol, nex);
112 
113  if (true) {
114  RandomNumbers *rand = new RandomNumbers_Mseries(seed);
116 
117  // fill field with uniform random numbers
118  rand->uniform_lex_global(field1);
119 
120  // generate additional random numbers to check rng state.
121  for (size_t i = 0; i < nsample; ++i) {
122  data[i] = rand->get();
123  }
124 
125  delete rand;
126  }
127 
128  // 2. generate field at rank 0 with the same seed
129  Field field2(0, 0, 0);
130 
131  if (Communicator::is_primary()) {
132  RandomNumbers *rand = new RandomNumbers_Mseries(seed);
133 
134  field2.reset(nin, lvol, nex);
135 
136  double *p = field2.ptr(0);
137 
138  for (size_t i = 0, n = field2.size(); i < n; ++i) {
139  *p++ = rand->get();
140  }
141 
142  delete rand;
143  }
144 
145  // 3. gather parallel field to rank 0
146  Field field1b(0, 0, 0);
147 
148  if (Communicator::is_primary()) {
149  field1b.reset(nin, lvol, nex);
150  }
151 
153 
154  fieldio.gather(&field1b, &field1);
155 
156  // 4. compare
157  int err1 = 0;
158 
159  if (Communicator::is_primary()) {
160  if (field1b.size() != field2.size()) {
161  vout.crucial(vl, "%s: field size mismatch.\n", test_name.c_str());
162  abort();
163  }
164 
165  double *p1 = field1b.ptr(0);
166  double *p2 = field2.ptr(0);
167 
168  for (size_t i = 0, n = field2.size(); i < n; ++i) {
169  if (*p1++ != *p2++) ++err1;
170  }
171  }
172 
173  Communicator::broadcast(1, &err1, 0);
174  vout.general(vl, "%s: serial and parallel: err = %d\n", test_name.c_str(), err1);
175 
176  // 5. check rng state
177  int err2 = 0;
178  double buf[nsample];
179 
180  for (int ipe = 1, npe = Communicator::size(); ipe < npe; ++ipe) {
181  Communicator::send_1to1(nsample, buf, data, 0, ipe, ipe);
182 
183  if (Communicator::is_primary()) {
184  for (size_t i = 0; i < nsample; ++i) {
185  if (data[i] != buf[i]) ++err2;
186  }
187  }
188 
189  Communicator::broadcast(1, &err2, 0);
190  vout.general(vl, "%s: check local state at rank %d, err = %d\n", test_name.c_str(), ipe, err2);
191  }
192 
193  // 6. check save and restore
194 
195  int err3 = 0;
196 
197  if (true) {
200 
201  // save current state to file
202  rand->writefile("RNG_Mseries.state");
203 
204  vout.detailed("%s: number of samples = %lu\n", test_name.c_str(), nsample);
205 
206  for (size_t i = 0; i < nsample; ++i) {
207  data[i] = rand->get();
208  }
209 
210  // restore state from file
211  rand->readfile("RNG_Mseries.state");
212 
213  // check if same series are generated.
214  int err3_part = 0;
215 
216  for (size_t i = 0; i < nsample; ++i) {
217  if (data[i] != rand->get()) ++err3_part;
218  }
219 
220  Communicator::reduce_sum(1, &err3, &err3_part);
221 
222  vout.general(vl, "%s: save/restore test: err = %d\n", test_name.c_str(), err3);
223 
224  delete rand;
225  }
226 
227  // 7. check gaussian field
228 
229  field1.reset(nin, nvol, nex);
230 
231  if (true) {
232  RandomNumbers *rand = new RandomNumbers_Mseries(seed);
234 
235  // fill field with gaussian random numbers
236  rand->gauss_lex_global(field1);
237 
238  delete rand;
239  }
240 
241  if (Communicator::is_primary()) {
242  RandomNumbers *rand = new RandomNumbers_Mseries(seed);
243 
244  field2.reset(nin, lvol, nex);
245 
246  double *p = field2.ptr(0);
247 
248  if (field2.nin() % 2 == 0) {
249  double r1, r2;
250 
251  for (int j = 0, Nex = field2.nex(); j < Nex; ++j) {
252  for (int isite = 0, Nvol = field2.nvol(); isite < Nvol; ++isite) {
253  for (int i = 0, Nin = field2.nin(); i < Nin; i += 2) {
254  rand->gauss(r1, r2);
255  *p++ = r1;
256  *p++ = r2;
257  }
258  }
259  }
260  } else {
261  double r1, r2;
262 
263  for (int j = 0, Nex = field2.nex(); j < Nex; ++j) {
264  for (int isite = 0, Nvol = field2.nvol(); isite < Nvol; ++isite) {
265  for (int i = 0, Nin = field2.nin(); i < Nin; ++i) {
266  rand->gauss(r1, r2);
267  *p++ = r1;
268  }
269  }
270  }
271  }
272 
273  delete rand;
274  }
275 
276  if (Communicator::is_primary()) {
277  field1b.reset(nin, lvol, nex);
278  }
279 
280  fieldio.gather(&field1b, &field1);
281 
282  int err4 = 0;
283 
284  if (Communicator::is_primary()) {
285  if (field1b.size() != field2.size()) {
286  vout.crucial(vl, "%s: field size mismatch.\n", test_name.c_str());
287  abort();
288  }
289 
290  double *p1 = field1b.ptr(0);
291  double *p2 = field2.ptr(0);
292 
293  for (size_t i = 0, n = field2.size(); i < n; ++i) {
294  if (*p1++ != *p2++) ++err4;
295  }
296  }
297 
298  Communicator::broadcast(1, &err4, 0);
299  vout.general(vl, "%s: serial and parallel for gaussian: err = %d\n", test_name.c_str(), err4);
300 
301 
302  // 8. summary
303 
304  double result = err1 + err2 + err3 + err4;
305 
306  timer->report();
307 
308 
309  // #### tidy up ####
310  delete params_test;
311  delete params_all;
312 
313  delete timer;
314 
315 
316  if (do_check) {
317  return Test::verify(expected_result, result);
318  } else {
319  vout.detailed(vl, "check skipped: expected_result not set.\n\n");
320  return EXIT_SKIP;
321  }
322  }
323 } // namespace Test_RandomNumbers
#define EXIT_SKIP
Definition: test.h:17
void readfile(const std::string &)
Random number generator base on M-series.
BridgeIO vout
Definition: bridgeIO.cpp:207
void read_params(const std::string &params_file, Parameters *params)
read parameters from file.
void detailed(const char *format,...)
Definition: bridgeIO.cpp:50
virtual double get()=0
void set_parameter_verboselevel(const Bridge::VerboseLevel vl)
Definition: randomNumbers.h:55
virtual void uniform_lex_global(Field &)
uniform random number defined on global lattice.
void general(const char *format,...)
Definition: bridgeIO.cpp:38
double * ptr(const int jin, const int site, const int jex)
Definition: field.h:118
Container of Field-type object.
Definition: field.h:37
int nvol() const
Definition: field.h:101
FieldIO_Text class for file I/O of Field data in plain text format.
Definition: fieldIO_Text.h:33
const Format * ILDG
Definition: io_format.cpp:28
int get_int(const string &key) const
Definition: parameters.cpp:40
Class for parameters.
Definition: parameters.h:40
static int Lvol()
virtual void gauss_lex_global(Field &)
gaussian random number defined on global lattice.
static int send_1to1(int count, double *recv_buf, double *send_buf, int p_to, int p_from, int tag)
send array of double from rank p_from to rank p_to. communication distinguished by tag...
int nin() const
Definition: field.h:100
static bool RegisterTest(const std::string &key, const Test_function func)
Definition: testManager.h:79
bool is_set(const string &) const
Definition: parameters.cpp:366
double get_double(const string &key) const
Definition: parameters.cpp:25
void reset(const int Nin, const int Nvol, const int Nex, const element_type cmpl=COMPLEX)
Definition: field.h:82
int nex() const
Definition: field.h:102
void start()
Definition: timer.cpp:44
void crucial(const char *format,...)
Definition: bridgeIO.cpp:26
void Register_Parameters(const string &, Parameters *const)
Definition: parameters.cpp:359
static int size()
size of small world.
Base class of random number generators.
Definition: randomNumbers.h:40
Bridge::VerboseLevel vl
Definition: checker.cpp:18
VerboseLevel
Definition: bridgeIO.h:25
static int reduce_sum(int count, double *recv_buf, double *send_buf, int pattern=0)
make a global sum of an array of double over the communicator. pattern specifies the dimensions to be...
static int broadcast(int count, double *data, int sender)
broadcast array of double from sender.
Parameter manager with YAML parser.
Definition: timer.h:31
static bool is_primary()
check if the present node is primary in small communicator.
int verify(const double expected, const double result)
Definition: test.cpp:27
string get_string(const string &key) const
Definition: parameters.cpp:85
void writefile(const std::string &)
void gather(Field *vglobal, Field *vlocal)
gather data on parallel nodes to primary node.
Definition: fieldIO.cpp:115
void report(const Bridge::VerboseLevel vl=Bridge::GENERAL)
Definition: timer.cpp:128
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:191
int size() const
Definition: field.h:106
void gauss(double &rn1, double &rn2)