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