Bridge++  Ver. 2.0.2
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
186  unique_ptr<FieldIO> fio;
187  if (Communicator::size() > 1) {
189  } else {
190  fio.reset(new FieldIO_Binary(IO_Format::Trivial));
191  }
192 #else
193  unique_ptr<FieldIO> fio(new FieldIO_Binary(IO_Format::Trivial));
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", params_fft));
253 
254  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
255  } else {
256  vout.general(vl, "FFT_xyz_1dim is not available.\n");
257  }
258 
259  // test FFT_xyz_3dim
260  if (
261  (NPEt == 1) && (NPEx == 1) && (NPEy == 1)
262  ) {
263  vout.general(vl, "test FFT_xyz_3dim.\n");
264 
265  unique_ptr<FFT> fft(FFT::New("FFT_xyz_3dim", params_fft));
266 
267  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
268  } else {
269  vout.general(vl, "FFT_xyz_3dim is not available.\n");
270  }
271 
272  // test FFT_3d_local
273  if (NPEx * NPEy * NPEz == 1)
274  {
275  vout.general(vl, "test FFT_3d_local.\n");
276 
277  unique_ptr<FFT> fft(FFT::New("FFT_3d_local", params_fft));
278 
279  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
280  } else {
281  vout.general(vl, "FFT_3d_local is not available.\n");
282  }
283 
284  // test FFT_3d_parallel1d
285 #ifdef USE_MPI
286  if (NPEx * NPEy == 1)
287  {
288  vout.general(vl, "test FFT_3d_parallel_1dim.\n");
289 
290  unique_ptr<FFT> fft(FFT::New("FFT_3d_parallel_1dim", 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", params_fft));
305 
306  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
307  } else {
308  vout.general(vl, "FFT_3d_parallel_3dim is not available.\n");
309  }
310 #endif
311 
312  // test FFT_3d auto
313  if (true)
314  {
315  vout.general(vl, "test FFT auto.\n");
316 
317  unique_ptr<FFT> fft(FFT::New("auto", params_fft));
318 
319  err += run_task(fft, src, ref, res1, res2, check_precision, vl);
320  } else {
321  vout.general(vl, "FFT auto is not available.\n");
322  }
323 
324 
325  if (do_check) {
326  return Test::verify(err, 0);
327  } else {
328  vout.detailed(vl, "check skipped: expected_result not set.\n\n");
329  return EXIT_SKIP;
330  }
331  }
332 } // namespace Test_FFT
333 #endif
CommonParameters::Ny
static int Ny()
Definition: commonParameters.h:106
Test::verify
int verify(const double result, const double expected, double eps)
Definition: test.cpp:27
CommonParameters::Nz
static int Nz()
Definition: commonParameters.h:107
Test_Eigensolver::test_name
const std::string test_name
Definition: test_Eigensolver.cpp:40
field_F.h
fieldIO_Binary_Parallel.h
RandomNumbers_MT19937
Definition: randomNumbers_MT19937.h:43
Field::set
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:175
Parameters
Class for parameters.
Definition: parameters.h:46
fft_3d_parallel3d.h
Parameters::get_int
int get_int(const string &key) const
Definition: parameters.cpp:192
Bridge::BridgeIO::detailed
void detailed(const char *format,...)
Definition: bridgeIO.cpp:219
Communicator::size
static int size()
size of small world.
Definition: communicator.cpp:81
CommonParameters::Ly
static int Ly()
Definition: commonParameters.h:92
CommonParameters::Nvol
static int Nvol()
Definition: commonParameters.h:109
axpy
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:380
Timer
Definition: timer.h:31
IO_Format::Trivial
const Format * Trivial
Definition: io_format.cpp:27
Field::norm2
double norm2() const
Definition: field.cpp:113
CommonParameters::Nx
static int Nx()
Definition: commonParameters.h:105
CommonParameters::Lt
static int Lt()
Definition: commonParameters.h:94
CommonParameters::Lx
static int Lx()
Definition: commonParameters.h:91
fieldIO_Binary.h
CommonParameters::Lz
static int Lz()
Definition: commonParameters.h:93
ParameterCheck::vl
Bridge::VerboseLevel vl
Definition: parameterCheck.cpp:18
CommonParameters::Nt
static int Nt()
Definition: commonParameters.h:108
Field::norm
double norm() const
Definition: field.h:226
CommonParameters::NPEz
static int NPEz()
Definition: commonParameters.h:99
fft_3d.h
file_utils.h
test.h
ParameterManager::read
static void read(const std::string &params_file, Parameters &params)
Definition: parameterManager.cpp:33
FieldIO_Binary
FieldIO_Binary class for file I/O of Field data in binary format.
Definition: fieldIO_Binary.h:47
io_format.h
fft_xyz_1dim.h
Parameters::get_double
double get_double(const string &key) const
Definition: parameters.cpp:175
randomNumbers_MT19937.h
CommonParameters::NPEy
static int NPEy()
Definition: commonParameters.h:98
EXIT_SKIP
#define EXIT_SKIP
Definition: test.h:17
FileUtils::generate_filename
std::string generate_filename(const char *fmt,...)
Definition: file_utils.cpp:17
Bridge::BridgeIO::set_verbose_level
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:133
Parameters::is_set
bool is_set(const string &key) const
Definition: parameters.cpp:525
CommonParameters::NPEx
static int NPEx()
Definition: commonParameters.h:97
fft.h
Field_F
Wilson-type fermion field.
Definition: field_F.h:37
CommonParameters::NPEt
static int NPEt()
Definition: commonParameters.h:100
commonParameters.h
Parameters::get_string
string get_string(const string &key) const
Definition: parameters.cpp:221
Field
Container of Field-type object.
Definition: field.h:46
communicator.h
Bridge::VerboseLevel
VerboseLevel
Definition: bridgeIO.h:42
fft_xyz_3dim.h
fft_3d_parallel1d.h
Bridge::BridgeIO::general
void general(const char *format,...)
Definition: bridgeIO.cpp:200
fft_3d_local.h
Parameters::lookup
Parameters lookup(const string &key) const
Definition: parameters.h:79
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:512
TestManager::RegisterTest
static bool RegisterTest(const std::string &key, const Test_function func)
Definition: testManager.h:69
FieldIO_Binary_Parallel
FieldIO_Binary_Parallel class for file I/O of Field data in binary format using MPI parallel I/O.
Definition: fieldIO_Binary_Parallel.h:80