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