Bridge++  Version 1.4.4
 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 "Tests/test.h"
16 #include "Field/field_G.h"
17 #include "IO/fieldIO_Text.h" // for gather field
18 #include "IO/io_format_gauge.h"
19 
20 //====================================================================
22 
31 namespace Test_RandomNumbers_Mseries {
32  const std::string test_name = "RandomNumbers.Mseries.Global";
33 
34  //- test-private parameters
35  namespace {
36  const std::string filename_input = "test_RandomNumbers_Mseries_Global.yaml";
37  }
38 
39  //- prototype declaration
40  int test_global(void);
41 
42 #ifdef USE_TESTMANAGER_AUTOREGISTER
43  namespace {
44  static const bool is_registered = TestManager::RegisterTest(
45  test_name,
47  );
48  }
49 #endif
50 
51  //====================================================================
52  int test_global(void)
53  {
54  // #### parameter setup ####
55 
56  Parameters params_all = ParameterManager::read(filename_input);
57 
58  Parameters params_test = params_all.lookup("Test_RandomNumbers");
59 
60  int iseed = params_test.get_int("int_seed");
61  const string str_vlevel = params_test.get_string("verbose_level");
62 
63  const bool do_check = params_test.is_set("expected_result");
64  const double expected_result = do_check ? params_test.get_double("expected_result") : 0.0;
65 
67 
68  //- print input parameters
69  vout.general(vl, " iseed = %d\n", iseed);
70  vout.general(vl, " vlevel = %s\n", str_vlevel.c_str());
71  vout.general(vl, "\n");
72 
73 
74  // #### object setup #####
75  unique_ptr<Timer> timer(new Timer(test_name));
76 
77 
78  // #### Execution main part ####
79  timer->start();
80 
81  vout.general(vl, "\n");
82  vout.general(vl, "Serial and Node-parallel test of Random Number Generator:\n");
83 
84  // sample field size
85  int nin = 8;
86  int nex = 4;
87 
88  int nvol = CommonParameters::Nvol();
89  int lvol = CommonParameters::Lvol();
90 
91  vout.general(vl, "field size: nin = %d, nex = %d, nvol = %d, lvol = %d\n", nin, nex, nvol, lvol);
92 
93  // buffer for checks
94  const size_t nsample = 1024;
95  double data[nsample];
96  for (size_t i = 0; i < nsample; ++i) {
97  data[i] = 0.0;
98  }
99 
100 
101  // 1. generate field in parallel
102  Field field1(nin, nvol, nex);
103 
104  if (true) {
107 
108  // fill field with uniform random numbers
109  rand->uniform_lex_global(field1);
110 
111  // generate additional random numbers to check rng state.
112  for (size_t i = 0; i < nsample; ++i) {
113  data[i] = rand->get();
114  }
115  }
116 
117  // 2. generate field at rank 0 with the same seed
118  Field field2(0, 0, 0);
119 
120  if (Communicator::is_primary()) {
122 
123  field2.reset(nin, lvol, nex);
124 
125  double *p = field2.ptr(0);
126 
127  for (size_t i = 0, n = field2.size(); i < n; ++i) {
128  *p++ = rand->get();
129  }
130  }
131 
132  // 3. gather parallel field to rank 0
133  Field field1b(0, 0, 0);
134 
135  if (Communicator::is_primary()) {
136  field1b.reset(nin, lvol, nex);
137  }
138 
140 
141  fieldio.gather(&field1b, &field1);
142 
143  // 4. compare
144  int err1 = 0;
145 
146  if (Communicator::is_primary()) {
147  if (field1b.size() != field2.size()) {
148  vout.crucial(vl, "Error at %s: field size mismatch.\n", test_name.c_str());
149  exit(EXIT_FAILURE);
150  }
151 
152  double *p1 = field1b.ptr(0);
153  double *p2 = field2.ptr(0);
154 
155  for (size_t i = 0, n = field2.size(); i < n; ++i) {
156  if (*p1++ != *p2++) ++err1;
157  }
158  }
159 
160  Communicator::broadcast(1, &err1, 0);
161  vout.general(vl, "%s: serial and parallel: err = %d\n", test_name.c_str(), err1);
162 
163  // 5. check rng state
164  int err2 = 0;
165  double buf[nsample];
166 
167  for (int ipe = 1, npe = Communicator::size(); ipe < npe; ++ipe) {
168  Communicator::send_1to1(nsample, buf, data, 0, ipe, ipe);
169 
170  if (Communicator::is_primary()) {
171  for (size_t i = 0; i < nsample; ++i) {
172  if (data[i] != buf[i]) ++err2;
173  }
174  }
175 
176  Communicator::broadcast(1, &err2, 0);
177  vout.general(vl, "%s: check local state at rank %d, err = %d\n", test_name.c_str(), ipe, err2);
178  }
179 
180  // 6. check save and restore
181  int err3 = 0;
182 
183  if (true) {
186 
187  // save current state to file
188  rand->write_file("RNG_Mseries.state");
189 
190  vout.detailed("%s: number of samples = %lu\n", test_name.c_str(), nsample);
191 
192  for (size_t i = 0; i < nsample; ++i) {
193  data[i] = rand->get();
194  }
195 
196  // restore state from file
197  rand->read_file("RNG_Mseries.state");
198 
199  // check if same series are generated.
200  int err3_part = 0;
201 
202  for (size_t i = 0; i < nsample; ++i) {
203  if (data[i] != rand->get()) ++err3_part;
204  }
205 
206  Communicator::reduce_sum(1, &err3, &err3_part);
207 
208  vout.general(vl, "%s: save/restore test: err = %d\n", test_name.c_str(), err3);
209  }
210 
211  // 7. check gaussian field
212  field1.reset(nin, nvol, nex);
213 
214  if (true) {
217 
218  // fill field with gaussian random numbers
219  rand->gauss_lex_global(field1);
220  }
221 
222  if (Communicator::is_primary()) {
224 
225  field2.reset(nin, lvol, nex);
226 
227  double *p = field2.ptr(0);
228 
229  if (field2.nin() % 2 == 0) {
230  double r1, r2;
231 
232  for (int j = 0, Nex = field2.nex(); j < Nex; ++j) {
233  for (int isite = 0, Nvol = field2.nvol(); isite < Nvol; ++isite) {
234  for (int i = 0, Nin = field2.nin(); i < Nin; i += 2) {
235  rand->gauss(r1, r2);
236  *p++ = r1;
237  *p++ = r2;
238  }
239  }
240  }
241  } else {
242  double r1, r2;
243 
244  for (int j = 0, Nex = field2.nex(); j < Nex; ++j) {
245  for (int isite = 0, Nvol = field2.nvol(); isite < Nvol; ++isite) {
246  for (int i = 0, Nin = field2.nin(); i < Nin; ++i) {
247  rand->gauss(r1, r2);
248  *p++ = r1;
249  }
250  }
251  }
252  }
253  }
254 
255  if (Communicator::is_primary()) {
256  field1b.reset(nin, lvol, nex);
257  }
258 
259  fieldio.gather(&field1b, &field1);
260 
261  int err4 = 0;
262 
263  if (Communicator::is_primary()) {
264  if (field1b.size() != field2.size()) {
265  vout.crucial(vl, "Error at %s: field size mismatch.\n", test_name.c_str());
266  exit(EXIT_FAILURE);
267  }
268 
269  double *p1 = field1b.ptr(0);
270  double *p2 = field2.ptr(0);
271 
272  for (size_t i = 0, n = field2.size(); i < n; ++i) {
273  if (*p1++ != *p2++) ++err4;
274  }
275  }
276 
277  Communicator::broadcast(1, &err4, 0);
278  vout.general(vl, "%s: serial and parallel for gaussian: err = %d\n", test_name.c_str(), err4);
279 
280 
281  // 8. summary
282  double result = err1 + err2 + err3 + err4;
283 
284  timer->report();
285 
286 
287  if (do_check) {
288  return Test::verify(result, expected_result);
289  } else {
290  vout.detailed(vl, "check skipped: expected_result not set.\n\n");
291  return EXIT_SKIP;
292  }
293  }
294 } // namespace Test_RandomNumbers
#define EXIT_SKIP
Definition: test.h:17
Random number generator base on M-series.
BridgeIO vout
Definition: bridgeIO.cpp:495
void detailed(const char *format,...)
Definition: bridgeIO.cpp:212
virtual double get()=0
const double * ptr(const int jin, const int site, const int jex) const
Definition: field.h:142
void read_file(const std::string &)
save and load random number status.
void set_parameter_verboselevel(const Bridge::VerboseLevel vl)
Definition: randomNumbers.h:58
virtual void uniform_lex_global(Field &)
uniform random number defined on global lattice.
void general(const char *format,...)
Definition: bridgeIO.cpp:195
Container of Field-type object.
Definition: field.h:39
int nvol() const
Definition: field.h:116
FieldIO_Text class for file I/O of Field data in plain text format.
Definition: fieldIO_Text.h:37
const Format * ILDG
Definition: io_format.cpp:28
int get_int(const string &key) const
Definition: parameters.cpp:87
Class for parameters.
Definition: parameters.h:46
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:115
Parameters lookup(const string &key) const
Definition: parameters.h:78
static bool RegisterTest(const std::string &key, const Test_function func)
Definition: testManager.h:69
double get_double(const string &key) const
Definition: parameters.cpp:70
void reset(const int Nin, const int Nvol, const int Nex, const element_type cmpl=COMPLEX)
Definition: field.h:84
int nex() const
Definition: field.h:117
void write_file(const std::string &)
bool is_set(const string &key) const
Definition: parameters.cpp:396
void start()
Definition: timer.cpp:44
void crucial(const char *format,...)
Definition: bridgeIO.cpp:178
static void read(const std::string &params_file, Parameters &params)
int verify(const double result, const double expected, double eps)
Definition: test.cpp:27
static int size()
size of small world.
Bridge::VerboseLevel vl
Definition: checker.cpp:18
VerboseLevel
Definition: bridgeIO.h:42
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.
Definition: timer.h:31
static bool is_primary()
check if the present node is primary in small communicator.
string get_string(const string &key) const
Definition: parameters.cpp:116
void gather(Field *vglobal, Field *vlocal)
gather data on parallel nodes to primary node.
Definition: fieldIO.cpp:116
void report(const Bridge::VerboseLevel vl=Bridge::GENERAL)
Definition: timer.cpp:128
void gauss(double &rand1, double &rand2)
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:131
int size() const
Definition: field.h:121