Bridge++  Version 1.6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test_FFT_check.cpp
Go to the documentation of this file.
1 
14 #include "test.h"
15 
16 #include "Tools/fft.h"
17 #include "Tools/fft_xyz_1dim.h"
18 #include "Tools/fft_xyz_3dim.h"
19 #include "Tools/fft_3d.h"
20 #include "Tools/fft_3d_local.h"
23 
24 #include "Field/field_F.h"
25 
26 #include "IO/fieldIO_Binary.h"
28 #include "IO/io_format.h"
30 #include "Tools/file_utils.h"
31 
34 
35 //====================================================================
37 
50 #ifdef USE_FFTWLIB
51 namespace Test_FFT {
52  const std::string test_name = "FFT.fft_check";
53 
54  //- test-private parameters
55  namespace {
56  const std::string filename_input = "test_FFT_check.yaml";
57  }
58 
59  //- prototype declaration
60  int fft_check(void);
61 
62 #ifdef USE_TESTMANAGER_AUTOREGISTER
63  namespace {
64  static const bool is_registered = TestManager::RegisterTest(
65  test_name,
66  fft_check
67  );
68  }
69 #endif
70 
71  //====================================================================
72  int run_task(unique_ptr<FFT>& fft,
73  const Field& src,
74  const Field& ref,
75  Field& res1,
76  Field& res2,
77  double check_precision,
79  {
80  int err = 0;
81 
82  res1.set(0.0);
83  res2.set(0.0);
84 
85  // #### Execution main part ####
86 
87  Timer time_fft_fw("FFT_Forward");
88 
89  time_fft_fw.start();
90  fft->fft(res1, src, FFT::FORWARD);
91  time_fft_fw.stop();
92 
93  Timer time_fft_bw("FFT_Backward");
94 
95  time_fft_bw.start();
96  fft->fft(res2, res1, FFT::BACKWARD);
97  time_fft_bw.stop();
98 
99  vout.general(vl, "source norm2 = %24.20e\n", src.norm2());
100  vout.general(vl, "result norm2 = %24.20e\n", res1.norm2());
101  vout.general(vl, "reverse norm2 = %24.20e\n", res2.norm2());
102 
103  double diff = 0.0;
104 
105  // forward check
106  axpy(res1, -1.0, ref);
107 
108  diff = res1.norm();
109 
110  vout.general(vl, "diff (result - ref) = %24.20e\n", diff);
111 
112  if (!(diff < check_precision)) ++err;
113 
114  // forward-backward reverse check
115  axpy(res2, -1.0, src);
116 
117  diff = res2.norm();
118  vout.general(vl, "diff (reverse - src) = %24.20e\n", diff);
119 
120  if (!(diff < check_precision)) ++err;
121 
122  time_fft_fw.report();
123  time_fft_bw.report();
124 
125  return err;
126  }
127 
128 
129  //====================================================================
130  int fft_check(void)
131  {
132  // #### parameter setup ####
133  //- global lattice size
134  const int Lx = CommonParameters::Lx();
135  const int Ly = CommonParameters::Ly();
136  const int Lz = CommonParameters::Lz();
137  const int Lt = CommonParameters::Lt();
138 
139  //- local size
140  const int Nx = CommonParameters::Nx();
141  const int Ny = CommonParameters::Ny();
142  const int Nz = CommonParameters::Nz();
143  const int Nt = CommonParameters::Nt();
144 
145  const int Nvol = CommonParameters::Nvol();
146 
147  //- grid size
148  const int NPEx = CommonParameters::NPEx();
149  const int NPEy = CommonParameters::NPEy();
150  const int NPEz = CommonParameters::NPEz();
151  const int NPEt = CommonParameters::NPEt();
152 
153 
154  Parameters params_all = ParameterManager::read(filename_input);
155 
156  // Parameters: Test section
157  Parameters params_test = params_all.lookup("Test_FFT");
158 
159  int nex = params_test.get_int("external_dof");
160 
161  string str_vlevel = params_test.get_string("verbose_level");
162  bool do_check = params_test.is_set("expected_result");
163  double expected_result = do_check ? params_test.get_double("expected_result") : 0.0;
164  double check_precision = params_test.is_set("check_precision") ? params_test.get_double("check_precision") : 1.0e-8;
165 
166  // Parameters: FFT section
167  Parameters params_fft = params_all.lookup("FFT");
168  // string str_fft_type = params_fft.get_string("FFT_type");
169 
171 
172  // #### object setup #####
173 
174  std::string filename_source = FileUtils::generate_filename("fft_src_%02dx%02dx%02dx%02d_%02d.dat", Lx, Ly, Lz, Lt, nex);
175 
176  std::string filename_reference = FileUtils::generate_filename("fft_ref_%02dx%02dx%02dx%02d_%02d.dat", Lx, Ly, Lz, Lt, nex);
177 
178  // vout.general(vl, "fft mode = %s\n", str_fft_type.c_str());
179  vout.general(vl, "external dof = %d\n", nex);
180  vout.general(vl, "source data file = %s\n", filename_source.c_str());
181  vout.general(vl, "reference data file = %s\n", filename_reference.c_str());
182  vout.general(vl, "check precision = %8.6e\n", check_precision);
183 
184 
185 #if 0
187  if (Communicator::size() > 1) {
189  } else {
191  }
192 #else
194 #endif
195 
196 
197  // Field_F src, ref, res1, res2;
198  int Nex = nex;
199 
200  Field_F src(Nvol, Nex);
201  Field_F ref(Nvol, Nex);
202  Field_F res1(Nvol, Nex);
203  Field_F res2(Nvol, Nex);
204 
205 
206  // find source or generate one randomly.
207 
208  std::ifstream fsrc(filename_source.c_str());
209  if (fsrc) {
210  vout.general(vl, "%s: source file exists.\n", test_name.c_str());
211 
212  fsrc.close();
213 
214  fio->read_file(&src, filename_source);
215  } else {
216  vout.general(vl, "%s: source file not exist. generate one.\n", test_name.c_str());
217 
218  RandomNumbers_MT19937 rng(0xdeadbeefUL);
219  rng.gauss_lex_global(src);
220 
221  fio->write_file(&src, filename_source);
222  }
223 
224  // find reference or calculate from source.
225 
226  std::ifstream fref(filename_reference.c_str());
227  if (fref) {
228  vout.general(vl, "%s: reference file exists.\n", test_name.c_str(), filename_reference.c_str());
229 
230  fref.close();
231 
232  fio->read_file(&ref, filename_reference);
233  } else {
234  vout.general(vl, "%s: reference data not yet exported.\n", test_name.c_str());
235 
236  unique_ptr<FFT> fft(FFT::New("auto"));
237  fft->fft(ref, src, FFT::FORWARD);
238 
239  fio->write_file(&ref, filename_reference);
240  }
241 
242 
243  int err = 0;
244 
245  // test FFT_xyz_1dim
246  if (
247  (NPEt == 1) &&
248  ((NPEx * NPEy == 1) || (NPEx * NPEz == 1) || (NPEy * NPEz == 1))
249  ) {
250  vout.general(vl, "test FFT_xyz_1dim.\n");
251 
252  unique_ptr<FFT> fft(FFT::New("FFT_xyz_1dim"));
253  fft->set_parameters(params_fft);
254 
255  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
256  } else {
257  vout.general(vl, "FFT_xyz_1dim is not available.\n");
258  }
259 
260  // test FFT_xyz_3dim
261  if (
262  (NPEt == 1) && (NPEx == 1) && (NPEy == 1)
263  ) {
264  vout.general(vl, "test FFT_xyz_3dim.\n");
265 
266  unique_ptr<FFT> fft(FFT::New("FFT_xyz_3dim"));
267  fft->set_parameters(params_fft);
268 
269  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
270  } else {
271  vout.general(vl, "FFT_xyz_3dim is not available.\n");
272  }
273 
274  // test FFT_3d_local
275  if (NPEx * NPEy * NPEz == 1)
276  {
277  vout.general(vl, "test FFT_3d_local.\n");
278 
279  unique_ptr<FFT> fft(FFT::New("FFT_3d_local"));
280  fft->set_parameters(params_fft);
281 
282  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
283  } else {
284  vout.general(vl, "FFT_3d_local is not available.\n");
285  }
286 
287  // test FFT_3d_parallel1d
288 #ifdef USE_MPI
289  if (NPEx * NPEy == 1)
290  {
291  vout.general(vl, "test FFT_3d_parallel_1dim.\n");
292 
293  unique_ptr<FFT> fft(FFT::New("FFT_3d_parallel_1dim"));
294  fft->set_parameters(params_fft);
295 
296  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
297  } else {
298  vout.general(vl, "FFT_3d_parallel_1dim is not available.\n");
299  }
300 #endif
301 
302  // test FFT_3d_parallel3d
303 #ifdef USE_MPI
304  if (true)
305  {
306  vout.general(vl, "test FFT_3d_parallel_3dim.\n");
307 
308  unique_ptr<FFT> fft(FFT::New("FFT_3d_parallel_3dim"));
309  fft->set_parameters(params_fft);
310 
311  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
312  } else {
313  vout.general(vl, "FFT_3d_parallel_3dim is not available.\n");
314  }
315 #endif
316 
317  // test FFT_3d auto
318  if (true)
319  {
320  vout.general(vl, "test FFT auto.\n");
321 
322  unique_ptr<FFT> fft(FFT::New("auto"));
323  fft->set_parameters(params_fft);
324 
325  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
326  } else {
327  vout.general(vl, "FFT auto is not available.\n");
328  }
329 
330 
331  if (do_check) {
332  return Test::verify(err, 0);
333  } else {
334  vout.detailed(vl, "check skipped: expected_result not set.\n\n");
335  return EXIT_SKIP;
336  }
337  }
338 } // namespace Test_FFT
339 #endif
#define EXIT_SKIP
Definition: test.h:17
BridgeIO vout
Definition: bridgeIO.cpp:503
void detailed(const char *format,...)
Definition: bridgeIO.cpp:216
static int NPEy()
double norm2() const
Definition: field.cpp:637
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:176
virtual void read_file(Field *v, const std::string)=0
read data from file. (`const' is added [18 Mar 2021])
void general(const char *format,...)
Definition: bridgeIO.cpp:197
const std::string test_name
Container of Field-type object.
Definition: field.h:46
void reset(pointer p=pointer())
int get_int(const string &key) const
Definition: parameters.cpp:192
Class for parameters.
Definition: parameters.h:46
Wilson-type fermion field.
Definition: field_F.h:37
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
FieldIO_Binary_Parallel class for file I/O of Field data in binary format using MPI parallel I/O...
double get_double(const string &key) const
Definition: parameters.cpp:175
std::string generate_filename(const char *fmt,...)
Definition: file_utils.cpp:17
double norm() const
Definition: field.h:227
bool is_set(const string &key) const
Definition: parameters.cpp:528
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:320
static int NPEx()
static void read(const std::string &params_file, Parameters &params)
const Format * Trivial
Definition: io_format.cpp:27
static int NPEz()
int verify(const double result, const double expected, double eps)
Definition: test.cpp:27
FieldIO_Binary class for file I/O of Field data in binary format.
static int size()
size of small world.
Bridge::VerboseLevel vl
VerboseLevel
Definition: bridgeIO.h:42
virtual void write_file(Field *v, const std::string)=0
write data to file. (`const' is added [18 Mar 2021])
Definition: timer.h:31
string get_string(const string &key) const
Definition: parameters.cpp:221
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:131