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