Block-Structured AMR Software Framework
Dfft.H
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017, UChicago Argonne, LLC
3  * All Rights Reserved
4  *
5  * Hardware/Hybrid Cosmology Code (HACC), Version 1.0
6  *
7  * Salman Habib, Adrian Pope, Hal Finkel, Nicholas Frontiere, Katrin Heitmann,
8  * Vitali Morozov, Jeffrey Emberson, Thomas Uram, Esteban Rangel
9  * (Argonne National Laboratory)
10  *
11  * David Daniel, Patricia Fasel, Chung-Hsing Hsu, Zarija Lukic, James Ahrens
12  * (Los Alamos National Laboratory)
13  *
14  * George Zagaris
15  * (Kitware)
16  *
17  * OPEN SOURCE LICENSE
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions are met:
21  *
22  * 1. Redistributions of source code must retain the above copyright notice,
23  * this list of conditions and the following disclaimer. Software changes,
24  * modifications, or derivative works, should be noted with comments and
25  * the author and organization's name.
26  *
27  * 2. Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  *
31  * 3. Neither the names of UChicago Argonne, LLC or the Department of Energy
32  * nor the names of its contributors may be used to endorse or promote
33  * products derived from this software without specific prior written
34  * permission.
35  *
36  * 4. The software and the end-user documentation included with the
37  * redistribution, if any, must include the following acknowledgment:
38  *
39  * "This product includes software produced by UChicago Argonne, LLC under
40  * Contract No. DE-AC02-06CH11357 with the Department of Energy."
41  *
42  * *****************************************************************************
43  * DISCLAIMER
44  * THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY OF ANY KIND. NEITHER THE
45  * UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT OF ENERGY, NOR
46  * UCHICAGO ARGONNE, LLC, NOR ANY OF THEIR EMPLOYEES, MAKES ANY WARRANTY,
47  * EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE
48  * ACCURARY, COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, DATA, APPARATUS,
49  * PRODUCT, OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE
50  * PRIVATELY OWNED RIGHTS.
51  *
52  * *****************************************************************************
53  */
54 
55 // I think this should work for global {ngx, ngy, ngz}
56 
57 #ifndef HACC_DFFT_HPP
58 #define HACC_DFFT_HPP
59 #include <AMReX_Config.H>
60 
61 #ifdef ESSL_FFTW
62 #include <fftw3_essl.h>
63 #else
64 #include <fftw3.h>
65 #endif
66 
67 #include "complex-type.h"
68 #include "Distribution.H"
69 #include "Error.h"
70 
71 // DFFT_TIMING
72 // 0 = no info
73 // 1 = summary info
74 // 2 = fine grain info
75 #ifndef DFFT_TIMING
76 #define DFFT_TIMING 0
77 #endif
78 
79 #if DFFT_TIMING
80 #include "TimingStats.h"
81 #endif
82 
83 #define FFTW_ADDR(X) reinterpret_cast<fftw_complex*>(&(X)[0])
84 
85 namespace hacc {
86 
87 class Dfft {
88 
89 public:
90 
91  //
92  int global_ng(int i) const { return d.global_ng(i); }
93  int const (& global_ng() const)[3] { return d.global_ng(); }
94  size_t global_size() const { return d.global_size(); }
95  MPI_Comm parent_comm() const { return d.parent_comm(); }
96 
97 
98 
99  //
100  size_t local_size() const { return d.local_size(); }
101 
102 
103 
104  // rank location in r-space
105  int self_rspace(int i) const { return d.self_3d(i);}
106  int const (& self_rspace() const)[3] { return d.self_3d();}
107 
108  // number of ranks in r-space
109  int nproc_rspace(int i) const { return d.nproc_3d(i);}
110  int const (& nproc_rspace() const)[3] { return d.nproc_3d();}
111 
112  // local grid dimensions in r-space
113  int local_ng_rspace(int i) const { return d.local_ng_3d(i);}
114  int const (& local_ng_rspace() const)[3] { return d.local_ng_3d();}
115 
116  // 3D cartesian communicator in r-space
117  MPI_Comm cartcomm_rspace() const { return d.cart_3d(); }
118 
119 
120 
121  // rank location in k-space
122  int self_kspace(int i) const { return d.self_2d_z(i);}
123  int const (& self_kspace() const)[3] { return d.self_2d_z();}
124 
125  // number of ranks in r-space
126  int nproc_kspace(int i) const { return d.nproc_2d_z(i);}
127  int const (& nproc_kspace() const)[3] { return d.nproc_2d_z();}
128 
129  // local grid dimensions in k-space
130  int local_ng_kspace(int i) const { return d.local_ng_2d_z(i);}
131  int const (& local_ng_kspace() const)[3] { return d.local_ng_2d_z();}
132 
133  // 3D cartesian communicator in k-space
134  MPI_Comm cartcomm_kspace() const { return d.cart_2d_z(); }
135 
136 
137 
138  void forward(complex_t const *in) {
139 
140  if (PlansMade != true) Error() << "Dfft buffers not set";
141 
142 #if DFFT_TIMING
143  double start, stop;
144  double tdist=0.0, tdfft=0.0;
145  start = MPI_Wtime();
146 #endif
147 
148  distribution_3_to_2(&in[0], &m_fs[0], &d.m_d, 0); // in --> fs
149 
150 #if DFFT_TIMING
151  stop = MPI_Wtime();
152  tdist += stop-start;
153 #if DFFT_TIMING > 1
154  printTimingStats(d.parent_comm(), "DFFT fd32", stop-start);
155 #endif
156  MPI_Barrier(d.parent_comm());
157  start = MPI_Wtime();
158 #endif
159 
160  fftw_execute(m_plan_f_x); // fs --> fo
161 
162 #if DFFT_TIMING
163  stop = MPI_Wtime();
164  tdfft += stop-start;
165 #if DFFT_TIMING > 1
166  printTimingStats(d.parent_comm(), "DFFT f1dx", stop-start);
167 #endif
168  MPI_Barrier(d.parent_comm());
169  start = MPI_Wtime();
170 #endif
171 
172  distribution_2_to_3(&m_fo[0], &m_fs[0], &d.m_d, 0); // fo --> fs
173 
174 #if DFFT_TIMING
175  stop = MPI_Wtime();
176  tdist += stop-start;
177 #if DFFT_TIMING > 1
178  printTimingStats(d.parent_comm(), "DFFT fd23", stop-start);
179 #endif
180  MPI_Barrier(d.parent_comm());
181  start = MPI_Wtime();
182 #endif
183 
184  distribution_3_to_2(&m_fs[0], &m_fo[0], &d.m_d, 1); // fs --> fo
185 
186 #if DFFT_TIMING
187  stop = MPI_Wtime();
188  tdist += stop-start;
189 #if DFFT_TIMING > 1
190  printTimingStats(d.parent_comm(), "DFFT fd32", stop-start);
191 #endif
192  MPI_Barrier(d.parent_comm());
193  start = MPI_Wtime();
194 #endif
195 
196  fftw_execute(m_plan_f_y); // fo --> fs
197 
198 #if DFFT_TIMING
199  stop = MPI_Wtime();
200  tdfft += stop-start;
201 #if DFFT_TIMING > 1
202  printTimingStats(d.parent_comm(), "DFFT f1dy", stop-start);
203 #endif
204  MPI_Barrier(d.parent_comm());
205  start = MPI_Wtime();
206 #endif
207 
208  distribution_2_to_3(&m_fs[0], &m_fo[0], &d.m_d, 1); // fs --> fo
209 
210 #if DFFT_TIMING
211  stop = MPI_Wtime();
212  tdist += stop-start;
213 #if DFFT_TIMING > 1
214  printTimingStats(d.parent_comm(), "DFFT fd23", stop-start);
215 #endif
216  MPI_Barrier(d.parent_comm());
217  start = MPI_Wtime();
218 #endif
219 
220  distribution_3_to_2(&m_fo[0], &m_fs[0], &d.m_d, 2); // fo --> fs
221 
222 #if DFFT_TIMING
223  stop = MPI_Wtime();
224  tdist += stop-start;
225 #if DFFT_TIMING > 1
226  printTimingStats(d.parent_comm(), "DFFT fd32", stop-start);
227 #endif
228  MPI_Barrier(d.parent_comm());
229  start = MPI_Wtime();
230 #endif
231 
232  fftw_execute(m_plan_f_z); // fs --> fo
233 
234 #if DFFT_TIMING
235  stop = MPI_Wtime();
236  tdfft += stop-start;
237 #if DFFT_TIMING > 1
238  printTimingStats(d.parent_comm(), "DFFT f1dz", stop-start);
239 #endif
240  printTimingStats(d.parent_comm(), "DFFT fdist", tdist);
241  printTimingStats(d.parent_comm(), "DFFT fdfft", tdfft);
242 #endif
243 
244  }
245 
246 
247 
248  void forward(float const *in, size_t ghost0, size_t ghost1) {
249 
250  if (PlansMade != true) Error() << "Dfft buffers not set";
251 
252 #if DFFT_TIMING
253  double start = MPI_Wtime();
254 #endif
255 
256  // copy from overloaded in to m_fo
257  const int *local_dim_r = local_ng_rspace();
258  int indexc = 0;
259  int indexf = ghost0*(ghost0 + local_dim_r[2] + ghost1)*(ghost0 + local_dim_r[1] + ghost1);
260  for(int local_r0=0; local_r0 < local_dim_r[0]; ++local_r0) {
261  indexf += ghost0*(ghost0 + local_dim_r[2] + ghost1);
262  for(int local_r1=0; local_r1 < local_dim_r[1]; ++local_r1) {
263  indexf += ghost0;
264  for(int local_r2=0; local_r2 < local_dim_r[2]; ++local_r2) {
265  m_fo[indexc] = in[indexf];
266  indexf++;
267  indexc++;
268  } // 2
269  indexf += ghost1;
270  } // 1
271  indexf += ghost1*(ghost0 + local_dim_r[2] + ghost1);
272  } // 0
273 
274 #if DFFT_TIMING
275  double stop = MPI_Wtime();
276  printTimingStats(d.parent_comm(), "DFFT fcopy", stop-start);
277 #endif
278 
279  // forward FFT from m_fo into m_fo
280  forward(&m_fo[0]);
281  }
282 
283 
284 
285  void forward(float const *in, size_t ghost) {
286  return forward(in, ghost, ghost+1);
287  }
288 
289 
290 
291  void backward(complex_t *out) {
292 
293  if (PlansMade != true) Error() << "Dfft buffers not set";
294 
295 #if DFFT_TIMING
296  double start, stop;
297  double tdist=0.0, tdfft=0.0;
298  start = MPI_Wtime();
299 #endif
300 
301  fftw_execute(m_plan_b_z); // bi --> bs
302 
303 #if DFFT_TIMING
304  stop = MPI_Wtime();
305  tdfft += stop-start;
306 #if DFFT_TIMING > 1
307  printTimingStats(d.parent_comm(), "DFFT b1dz", stop-start);
308 #endif
309  MPI_Barrier(d.parent_comm());
310  start = MPI_Wtime();
311 #endif
312 
313  distribution_2_to_3(&m_bs[0], &m_bi[0], &d.m_d, 2); // bs --> bi
314 
315 #if DFFT_TIMING
316  stop = MPI_Wtime();
317  tdist += stop-start;
318 #if DFFT_TIMING > 1
319  printTimingStats(d.parent_comm(), "DFFT bd23", stop-start);
320 #endif
321  MPI_Barrier(d.parent_comm());
322  start = MPI_Wtime();
323 #endif
324 
325  distribution_3_to_2(&m_bi[0], &m_bs[0], &d.m_d, 1); // bi --> bs
326 
327 #if DFFT_TIMING
328  stop = MPI_Wtime();
329  tdist += stop-start;
330 #if DFFT_TIMING > 1
331  printTimingStats(d.parent_comm(), "DFFT bd32", stop-start);
332 #endif
333  MPI_Barrier(d.parent_comm());
334  start = MPI_Wtime();
335 #endif
336 
337  fftw_execute(m_plan_b_y); // bs --> bi
338 
339 #if DFFT_TIMING
340  stop = MPI_Wtime();
341  tdfft += stop-start;
342 #if DFFT_TIMING > 1
343  printTimingStats(d.parent_comm(), "DFFT b1dy", stop-start);
344 #endif
345  MPI_Barrier(d.parent_comm());
346  start = MPI_Wtime();
347 #endif
348 
349  distribution_2_to_3(&m_bi[0], &m_bs[0], &d.m_d, 1); // bi --> bs
350 
351 #if DFFT_TIMING
352  stop = MPI_Wtime();
353  tdist += stop-start;
354 #if DFFT_TIMING > 1
355  printTimingStats(d.parent_comm(), "DFFT bd23", stop-start);
356 #endif
357  MPI_Barrier(d.parent_comm());
358  start = MPI_Wtime();
359 #endif
360 
361  distribution_3_to_2(&m_bs[0], &m_bi[0], &d.m_d, 0); // bs --> bi
362 
363 #if DFFT_TIMING
364  stop = MPI_Wtime();
365  tdist += stop-start;
366 #if DFFT_TIMING > 1
367  printTimingStats(d.parent_comm(), "DFFT bd32", stop-start);
368 #endif
369  MPI_Barrier(d.parent_comm());
370  start = MPI_Wtime();
371 #endif
372 
373  fftw_execute(m_plan_b_x); // bi --> bs
374 
375 #if DFFT_TIMING
376  stop = MPI_Wtime();
377  tdfft += stop-start;
378 #if DFFT_TIMING > 1
379  printTimingStats(d.parent_comm(), "DFFT b1dx", stop-start);
380 #endif
381  MPI_Barrier(d.parent_comm());
382  start = MPI_Wtime();
383 #endif
384 
385  distribution_2_to_3(&m_bs[0], &out[0], &d.m_d, 0); // bs --> out
386 
387 #if DFFT_TIMING
388  stop = MPI_Wtime();
389  tdist += stop-start;
390 #if DFFT_TIMING > 1
391  printTimingStats(d.parent_comm(), "DFFT bd23", stop-start);
392 #endif
393  printTimingStats(d.parent_comm(), "DFFT bdist", tdist);
394  printTimingStats(d.parent_comm(), "DFFT bdfft", tdfft);
395 #endif
396 
397  }
398 
399 
400 
401  void backward(float *out, size_t ghost0, size_t ghost1) {
402 
403  // backward FFT from m_bi into m_bi
404  backward(&m_bi[0]);
405 
406 #if DFFT_TIMING
407  double start = MPI_Wtime();
408 #endif
409 
410  // copy from m_bi to overloaded out
411  const int *local_dim_r = local_ng_rspace();
412  int indexc = 0;
413  int indexf = ghost0*(ghost0 + local_dim_r[2] + ghost1)*(ghost0 + local_dim_r[1] + ghost1);
414  for(int local_r0=0; local_r0 < local_dim_r[0]; ++local_r0) {
415  indexf += ghost0*(ghost0 + local_dim_r[2] + ghost1);
416  for(int local_r1=0; local_r1 < local_dim_r[1]; ++local_r1) {
417  indexf += ghost0;
418  for(int local_r2=0; local_r2 < local_dim_r[2]; ++local_r2) {
419  out[indexf] = std::real(m_bi[indexc]);
420  indexf++;
421  indexc++;
422  } // 2
423  indexf += ghost1;
424  } // 1
425  indexf += ghost1*(ghost0 + local_dim_r[2] + ghost1);
426  } // 0
427 
428 #if DFFT_TIMING
429  double stop = MPI_Wtime();
430  printTimingStats(d.parent_comm(), "DFFT bcopy", stop-start);
431 #endif
432 
433  }
434 
435 
436 
437  void backward(float *out, size_t ghost) {
438  return backward(out, ghost, ghost+1);
439  }
440 
441 
442 
444  : d(dist), PlansMade(false)
445  {}
446 
447 
448 
449  // arrays given at class initialization are hard-wired to the fft plans
451  complex_t *forward_output,
452  complex_t *forward_scratch,
453  complex_t *backward_input,
454  complex_t *backward_scratch,
455  unsigned int flags = FFTW_MEASURE)
456  : d(dist), PlansMade(false)
457  {
458  makePlans(forward_output,
459  forward_scratch,
460  backward_input,
461  backward_scratch,
462  flags);
463  }
464 
465 
466 
467  // array rules:
468  // forward/backward method calls over-write these arrays
469  // forward method has separate input array argument
470  // backward method has separate output array argument
471  // forward_scratch != forward_output && backward_scratch != backward_input
472  // no required relationship between forward and backward arrays
473 
474  // actually, can these transforms be done in-place?
475  // for now leave as-is, but test later
476 
477  // FFTW_MEASURE = 0
478  void makePlans(complex_t *forward_output,
479  complex_t *forward_scratch,
480  complex_t *backward_input,
481  complex_t *backward_scratch,
482  unsigned int flags = FFTW_MEASURE)
483  {
484  if(forward_output == forward_scratch)
485  Error() << "Dfft::setBuffers() forward_output == forward_scratch";
486  if(backward_input == backward_scratch)
487  Error() << "Dfft::setBuffers() backward_input == backward_scratch";
488 
489  m_fo = forward_output;
490  m_fs = forward_scratch;
491  m_bi = backward_input;
492  m_bs = backward_scratch;
493 
494 #if DFFT_TIMING
495  double start = MPI_Wtime();
496 #endif
497 
498  // fs --> fo
499  m_plan_f_x = fftw_plan_many_dft(1, // rank
500  &(d.m_d.process_topology_2_x.n[0]), // const int *n,
501  d.m_d.process_topology_2_x.n[1] * d.m_d.process_topology_2_x.n[2], // howmany
502  FFTW_ADDR(m_fs),
503  NULL, // const int *inembed,
504  1, // int istride,
505  d.m_d.process_topology_2_x.n[0], // int idist,
506  FFTW_ADDR(m_fo),
507  NULL, // const int *onembed,
508  1, // int ostride,
509  d.m_d.process_topology_2_x.n[0], // int odist,
510  FFTW_FORWARD, // int sign,
511  flags); // unsigned flags
512 
513  // fo --> fs
514  m_plan_f_y = fftw_plan_many_dft(1, // rank
515  &(d.m_d.process_topology_2_y.n[1]), // const int *n,
516  d.m_d.process_topology_2_y.n[0] * d.m_d.process_topology_2_y.n[2], // howmany
517  FFTW_ADDR(m_fo),
518  NULL, // const int *inembed,
519  1, // int istride,
520  d.m_d.process_topology_2_y.n[1], // int idist,
521  FFTW_ADDR(m_fs),
522  NULL, // const int *onembed,
523  1, // int ostride,
524  d.m_d.process_topology_2_y.n[1], // int odist,
525  FFTW_FORWARD, // int sign,
526  flags); // unsigned flags
527 
528  // fs --> fo
529  m_plan_f_z = fftw_plan_many_dft(1, // rank
530  &(d.m_d.process_topology_2_z.n[2]), // const int *n,
531  d.m_d.process_topology_2_z.n[1] * d.m_d.process_topology_2_z.n[0], // howmany
532  FFTW_ADDR(m_fs),
533  NULL, // const int *inembed,
534  1, // int istride,
535  d.m_d.process_topology_2_z.n[2], // int idist,
536  FFTW_ADDR(m_fo),
537  NULL, // const int *onembed,
538  1, // int ostride,
539  d.m_d.process_topology_2_z.n[2], // int odist,
540  FFTW_FORWARD, // int sign,
541  flags); // unsigned flags
542 
543  // bi --> bs
544  m_plan_b_z = fftw_plan_many_dft(1, // rank
545  &(d.m_d.process_topology_2_z.n[2]), // const int *n,
546  d.m_d.process_topology_2_z.n[1] * d.m_d.process_topology_2_z.n[0], // howmany
547  FFTW_ADDR(m_bi),
548  NULL, // const int *inembed,
549  1, // int istride,
550  d.m_d.process_topology_2_z.n[2], // int idist,
551  FFTW_ADDR(m_bs),
552  NULL, // const int *onembed,
553  1, // int ostride,
554  d.m_d.process_topology_2_z.n[2], // int odist,
555  FFTW_BACKWARD, // int sign,
556  flags); // unsigned flags
557 
558  // bs --> bi
559  m_plan_b_y = fftw_plan_many_dft(1, // rank
560  &(d.m_d.process_topology_2_y.n[1]), // const int *n,
561  d.m_d.process_topology_2_y.n[0] * d.m_d.process_topology_2_y.n[2], // howmany
562  FFTW_ADDR(m_bs),
563  NULL, // const int *inembed,
564  1, // int istride,
565  d.m_d.process_topology_2_y.n[1], // int idist,
566  FFTW_ADDR(m_bi),
567  NULL, // const int *onembed,
568  1, // int ostride,
569  d.m_d.process_topology_2_y.n[1], // int odist,
570  FFTW_BACKWARD, // int sign,
571  flags); // unsigned flags
572 
573  // bi --> bs
574  m_plan_b_x = fftw_plan_many_dft(1, // rank
575  &(d.m_d.process_topology_2_x.n[0]), // const int *n,
576  d.m_d.process_topology_2_x.n[1] * d.m_d.process_topology_2_x.n[2], // howmany
577  FFTW_ADDR(m_bi),
578  NULL, // const int *inembed,
579  1, // int istride,
580  d.m_d.process_topology_2_x.n[0], // int idist,
581  FFTW_ADDR(m_bs),
582  NULL, // const int *onembed,
583  1, // int ostride,
584  d.m_d.process_topology_2_x.n[0], // int odist,
585  FFTW_BACKWARD, // int sign,
586  flags); // unsigned flags
587 
588 #if DFFT_TIMING
589  double stop = MPI_Wtime();
590  printTimingStats(d.parent_comm(), "DFFT init", stop-start);
591 #endif
592 
593  PlansMade = true;
594  }
595 
596 
597 
598  ~Dfft() {
599  if(PlansMade == true) {
600  fftw_destroy_plan(m_plan_f_x);
601  fftw_destroy_plan(m_plan_f_y);
602  fftw_destroy_plan(m_plan_f_z);
603  fftw_destroy_plan(m_plan_b_z);
604  fftw_destroy_plan(m_plan_b_y);
605  fftw_destroy_plan(m_plan_b_x);
606  }
607  }
608 
609 
610 
611  Distribution & get_d() {return d;}
612 
613 protected:
614 
616  bool PlansMade;
621  fftw_plan m_plan_f_x;
622  fftw_plan m_plan_f_y;
623  fftw_plan m_plan_f_z;
624  fftw_plan m_plan_b_z;
625  fftw_plan m_plan_b_y;
626  fftw_plan m_plan_b_x;
627 };
628 
629 } // namespace hacc
630 
631 #endif // HACC_DFFT_HPP
int MPI_Comm
Definition: AMReX_ccse-mpi.H:47
#define FFTW_ADDR(X)
Definition: Dfft.H:83
void printTimingStats(MPI_Comm comm, const char *preamble, double dt)
Definition: TimingStats.h:73
Definition: Dfft.H:87
int global_ng(int i) const
Definition: Dfft.H:92
size_t local_size() const
Definition: Dfft.H:100
MPI_Comm parent_comm() const
Definition: Dfft.H:95
int const (& local_ng_kspace() const)[3]
Definition: Dfft.H:131
MPI_Comm cartcomm_rspace() const
Definition: Dfft.H:117
complex_t * m_fo
Definition: Dfft.H:617
int const (& global_ng() const)[3]
Definition: Dfft.H:93
complex_t * m_bs
Definition: Dfft.H:620
complex_t * m_fs
Definition: Dfft.H:618
int const (& nproc_rspace() const)[3]
Definition: Dfft.H:110
Distribution & d
Definition: Dfft.H:615
fftw_plan m_plan_b_x
Definition: Dfft.H:626
void forward(complex_t const *in)
Definition: Dfft.H:138
fftw_plan m_plan_f_z
Definition: Dfft.H:623
void backward(complex_t *out)
Definition: Dfft.H:291
Dfft(Distribution &dist)
Definition: Dfft.H:443
int nproc_kspace(int i) const
Definition: Dfft.H:126
int local_ng_rspace(int i) const
Definition: Dfft.H:113
void backward(float *out, size_t ghost)
Definition: Dfft.H:437
void forward(float const *in, size_t ghost0, size_t ghost1)
Definition: Dfft.H:248
int local_ng_kspace(int i) const
Definition: Dfft.H:130
void makePlans(complex_t *forward_output, complex_t *forward_scratch, complex_t *backward_input, complex_t *backward_scratch, unsigned int flags=FFTW_MEASURE)
Definition: Dfft.H:478
fftw_plan m_plan_f_x
Definition: Dfft.H:621
fftw_plan m_plan_f_y
Definition: Dfft.H:622
~Dfft()
Definition: Dfft.H:598
void backward(float *out, size_t ghost0, size_t ghost1)
Definition: Dfft.H:401
complex_t * m_bi
Definition: Dfft.H:619
fftw_plan m_plan_b_y
Definition: Dfft.H:625
int const (& self_kspace() const)[3]
Definition: Dfft.H:123
size_t global_size() const
Definition: Dfft.H:94
int const (& self_rspace() const)[3]
Definition: Dfft.H:106
Dfft(Distribution &dist, complex_t *forward_output, complex_t *forward_scratch, complex_t *backward_input, complex_t *backward_scratch, unsigned int flags=FFTW_MEASURE)
Definition: Dfft.H:450
int const (& nproc_kspace() const)[3]
Definition: Dfft.H:127
int nproc_rspace(int i) const
Definition: Dfft.H:109
fftw_plan m_plan_b_z
Definition: Dfft.H:624
int self_kspace(int i) const
Definition: Dfft.H:122
int self_rspace(int i) const
Definition: Dfft.H:105
int const (& local_ng_rspace() const)[3]
Definition: Dfft.H:114
bool PlansMade
Definition: Dfft.H:616
void forward(float const *in, size_t ghost)
Definition: Dfft.H:285
Distribution & get_d()
Definition: Dfft.H:611
MPI_Comm cartcomm_kspace() const
Definition: Dfft.H:134
Definition: Distribution.H:73
size_t global_size() const
Definition: Distribution.H:178
MPI_Comm parent_comm() const
Definition: Distribution.H:243
MPI_Comm cart_3d() const
Definition: Distribution.H:241
int local_ng_3d(int i) const
Definition: Distribution.H:191
int global_ng(int i) const
Definition: Distribution.H:186
int self_2d_z(int i) const
Definition: Distribution.H:225
MPI_Comm cart_2d_z() const
Definition: Distribution.H:240
int self_3d(int i) const
Definition: Distribution.H:226
distribution_t m_d
Definition: Distribution.H:277
int nproc_2d_z(int i) const
Definition: Distribution.H:208
int local_ng_2d_z(int i) const
Definition: Distribution.H:190
size_t local_size() const
Definition: Distribution.H:170
int nproc_3d(int i) const
Definition: Distribution.H:209
double complex complex_t
Definition: complex-type.h:79
#define real(x)
Definition: complex-type.h:83
void distribution_3_to_2(const complex_t *a, complex_t *b, distribution_t *d, int z_dim)
Definition: distribution.c:1509
void distribution_2_to_3(const complex_t *a, complex_t *b, distribution_t *d, int z_dim)
Definition: distribution.c:1495
void Error(const std::string &msg)
Print out message to cerr and exit via amrex::Abort().
Definition: AMReX.cpp:215
Definition: AlignedAllocator.h:63
process_topology_t process_topology_2_y
Definition: distribution_c.h:98
process_topology_t process_topology_2_z
Definition: distribution_c.h:97
process_topology_t process_topology_2_x
Definition: distribution_c.h:99
int n[3]
Definition: distribution_c.h:81