Block-Structured AMR Software Framework
AMReX_FFT_R2C.H
Go to the documentation of this file.
1 #ifndef AMREX_FFT_R2C_H_
2 #define AMREX_FFT_R2C_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_MultiFab.H>
6 #include <AMReX_FFT_Helper.H>
7 #include <algorithm>
8 #include <numeric>
9 #include <tuple>
10 
11 namespace amrex::FFT
12 {
13 
14 template <typename T> class OpenBCSolver;
15 
30 template <typename T = Real, FFT::Direction D = FFT::Direction::both,
32  // Don't change the default. Otherwise OpenBCSolver might break.
33 class R2C
34 {
35 public:
36  using MF = std::conditional_t<std::is_same_v<T,Real>,
39 
40  template <typename U> friend class OpenBCSolver;
41 
48  explicit R2C (Box const& domain, Info const& info = Info{});
49 
50  ~R2C ();
51 
52  R2C (R2C const&) = delete;
53  R2C (R2C &&) = delete;
54  R2C& operator= (R2C const&) = delete;
55  R2C& operator= (R2C &&) = delete;
56 
76  template <typename F, Direction DIR=D,
77  std::enable_if_t<DIR == Direction::both, int> = 0>
78  void forwardThenBackward (MF const& inmf, MF& outmf, F const& post_forward)
79  {
80  BL_PROFILE("FFT::R2C::forwardbackward");
81  this->forward(inmf);
82  this->post_forward_doit(post_forward);
83  this->backward(outmf);
84  }
85 
95  template <Direction DIR=D, std::enable_if_t<DIR == Direction::forward ||
96  DIR == Direction::both, int> = 0>
97  void forward (MF const& inmf);
98 
108  template <Direction DIR=D, std::enable_if_t<DIR == Direction::forward ||
109  DIR == Direction::both, int> = 0>
110  void forward (MF const& inmf, cMF& outmf);
111 
120  template <Direction DIR=D, std::enable_if_t<DIR == Direction::both, int> = 0>
121  void backward (MF& outmf);
122 
132  template <Direction DIR=D, std::enable_if_t<DIR == Direction::backward ||
133  DIR == Direction::both, int> = 0>
134  void backward (cMF const& inmf, MF& outmf);
135 
139  [[nodiscard]] T scalingFactor () const;
140 
150  template <Direction DIR=D, std::enable_if_t<DIR == Direction::forward ||
151  DIR == Direction::both, int> = 0>
152  std::pair<cMF*,IntVect> getSpectralData ();
153 
161  [[nodiscard]] std::pair<BoxArray,DistributionMapping> getSpectralDataLayout () const;
162 
163  // public for cuda
164  template <typename F>
165  void post_forward_doit (F const& post_forward);
166 
167 private:
168 
169  static std::pair<Plan<T>,Plan<T>> make_c2c_plans (cMF& inout);
170 
171  void backward_doit (MF& outmf, IntVect const& ngout = IntVect(0));
172 
179 
180  // Comm meta-data. In the forward phase, we start with (x,y,z),
181  // transpose to (y,x,z) and then (z,x,y). In the backward phase, we
182  // perform inverse transpose.
183  std::unique_ptr<MultiBlockCommMetaData> m_cmd_x2y; // (x,y,z) -> (y,x,z)
184  std::unique_ptr<MultiBlockCommMetaData> m_cmd_y2x; // (y,x,z) -> (x,y,z)
185  std::unique_ptr<MultiBlockCommMetaData> m_cmd_y2z; // (y,x,z) -> (z,x,y)
186  std::unique_ptr<MultiBlockCommMetaData> m_cmd_z2y; // (z,x,y) -> (y,x,z)
187  std::unique_ptr<MultiBlockCommMetaData> m_cmd_x2z; // (x,y,z) -> (z,x,y)
188  std::unique_ptr<MultiBlockCommMetaData> m_cmd_z2x; // (z,x,y) -> (x,y,z)
189  std::unique_ptr<MultiBlockCommMetaData> m_cmd_x2z_half; // for openbc
190  std::unique_ptr<MultiBlockCommMetaData> m_cmd_z2x_half; // for openbc
197 
202 
203  std::unique_ptr<char,DataDeleter> m_data_1;
204  std::unique_ptr<char,DataDeleter> m_data_2;
205 
210 
212 
213  bool m_slab_decomp = false;
214  bool m_openbc_half = false;
215 };
216 
217 template <typename T, Direction D, DomainStrategy S>
218 R2C<T,D,S>::R2C (Box const& domain, Info const& info)
219  : m_real_domain(domain),
220  m_spectral_domain_x(IntVect(0), IntVect(AMREX_D_DECL(domain.length(0)/2,
221  domain.length(1)-1,
222  domain.length(2)-1)),
223  domain.ixType()),
224 #if (AMREX_SPACEDIM >= 2)
225  m_spectral_domain_y(IntVect(0), IntVect(AMREX_D_DECL(domain.length(1)-1,
226  domain.length(0)/2,
227  domain.length(2)-1)),
228  domain.ixType()),
229 #if (AMREX_SPACEDIM == 3)
230  m_spectral_domain_z(IntVect(0), IntVect(AMREX_D_DECL(domain.length(2)-1,
231  domain.length(0)/2,
232  domain.length(1)-1)),
233  domain.ixType()),
234 #endif
235 #endif
236  m_info(info)
237 {
238  BL_PROFILE("FFT::R2C");
239 
240  static_assert(std::is_same_v<float,T> || std::is_same_v<double,T>);
242 #if (AMREX_SPACEDIM == 3)
245 #else
247 #endif
248 
249  int myproc = ParallelContext::MyProcSub();
251 
252 #if (AMREX_SPACEDIM == 3)
253  if (S == DomainStrategy::slab && (m_real_domain.length(1) > 1)) {
254  m_slab_decomp = true;
255  }
256 #endif
257 
258  //
259  // make data containers
260  //
261 
262  auto bax = amrex::decompose(m_real_domain, nprocs,
263  {AMREX_D_DECL(false,!m_slab_decomp,true)}, true);
265  m_rx.define(bax, dmx, 1, 0, MFInfo().SetAlloc(false));
266 
267  {
268  BoxList bl = bax.boxList();
269  for (auto & b : bl) {
270  b.shift(-m_real_domain.smallEnd());
271  b.setBig(0, m_spectral_domain_x.bigEnd(0));
272  }
273  BoxArray cbax(std::move(bl));
274  m_cx.define(cbax, dmx, 1, 0, MFInfo().SetAlloc(false));
275  }
276 
277 #if (AMREX_SPACEDIM >= 2)
278  DistributionMapping cdmy;
279  if ((m_real_domain.length(1) > 1) && !m_slab_decomp) {
280  auto cbay = amrex::decompose(m_spectral_domain_y, nprocs,
281  {AMREX_D_DECL(false,true,true)}, true);
282  if (cbay.size() == dmx.size()) {
283  cdmy = dmx;
284  } else {
285  cdmy = detail::make_iota_distromap(cbay.size());
286  }
287  m_cy.define(cbay, cdmy, 1, 0, MFInfo().SetAlloc(false));
288  }
289 #endif
290 
291 #if (AMREX_SPACEDIM == 3)
292  if (m_real_domain.length(1) > 1 &&
293  (! m_info.batch_mode && m_real_domain.length(2) > 1))
294  {
295  auto cbaz = amrex::decompose(m_spectral_domain_z, nprocs,
296  {false,true,true}, true);
297  DistributionMapping cdmz;
298  if (cbaz.size() == dmx.size()) {
299  cdmz = dmx;
300  } else if (cbaz.size() == cdmy.size()) {
301  cdmz = cdmy;
302  } else {
303  cdmz = detail::make_iota_distromap(cbaz.size());
304  }
305  m_cz.define(cbaz, cdmz, 1, 0, MFInfo().SetAlloc(false));
306  }
307 #endif
308 
309  if (m_slab_decomp) {
312  } else {
315  }
316 
317  //
318  // make copiers
319  //
320 
321 #if (AMREX_SPACEDIM >= 2)
322  if (! m_cy.empty()) {
323  // comm meta-data between x and y phases
324  m_cmd_x2y = std::make_unique<MultiBlockCommMetaData>
326  m_cmd_y2x = std::make_unique<MultiBlockCommMetaData>
328  }
329 #endif
330 #if (AMREX_SPACEDIM == 3)
331  if (! m_cz.empty() ) {
332  if (m_slab_decomp) {
333  // comm meta-data between xy and z phases
334  m_cmd_x2z = std::make_unique<MultiBlockCommMetaData>
336  m_cmd_z2x = std::make_unique<MultiBlockCommMetaData>
338  } else {
339  // comm meta-data between y and z phases
340  m_cmd_y2z = std::make_unique<MultiBlockCommMetaData>
342  m_cmd_z2y = std::make_unique<MultiBlockCommMetaData>
344  }
345  }
346 #endif
347 
348  //
349  // make plans
350  //
351 
352  if (myproc < m_rx.size())
353  {
354  Box const& box = m_rx.box(myproc);
355  auto* pr = m_rx[myproc].dataPtr();
356  auto* pc = (typename Plan<T>::VendorComplex *)m_cx[myproc].dataPtr();
357 #ifdef AMREX_USE_SYCL
358  m_fft_fwd_x.template init_r2c<Direction::forward>(box, pr, pc, m_slab_decomp);
360 #else
361  if constexpr (D == Direction::both || D == Direction::forward) {
362  m_fft_fwd_x.template init_r2c<Direction::forward>(box, pr, pc, m_slab_decomp);
363  }
364  if constexpr (D == Direction::both || D == Direction::backward) {
365  m_fft_bwd_x.template init_r2c<Direction::backward>(box, pr, pc, m_slab_decomp);
366  }
367 #endif
368  }
369 
370 #if (AMREX_SPACEDIM >= 2)
371  if (! m_cy.empty()) {
373  }
374 #endif
375 #if (AMREX_SPACEDIM == 3)
376  if (! m_cz.empty()) {
378  }
379 #endif
380 }
381 
382 template <typename T, Direction D, DomainStrategy S>
384 {
385  if (m_fft_bwd_x.plan != m_fft_fwd_x.plan) {
386  m_fft_bwd_x.destroy();
387  }
388  if (m_fft_bwd_y.plan != m_fft_fwd_y.plan) {
389  m_fft_bwd_y.destroy();
390  }
391  if (m_fft_bwd_z.plan != m_fft_fwd_z.plan) {
392  m_fft_bwd_z.destroy();
393  }
394  m_fft_fwd_x.destroy();
395  m_fft_fwd_y.destroy();
396  m_fft_fwd_z.destroy();
397 }
398 
399 template <typename T, Direction D, DomainStrategy S>
400 template <Direction DIR, std::enable_if_t<DIR == Direction::forward ||
401  DIR == Direction::both, int> >
402 void R2C<T,D,S>::forward (MF const& inmf)
403 {
404  BL_PROFILE("FFT::R2C::forward(in)");
405 
406  if (&m_rx != &inmf) {
407  m_rx.ParallelCopy(inmf, 0, 0, 1);
408  }
409  m_fft_fwd_x.template compute_r2c<Direction::forward>();
410 
411  if ( m_cmd_x2y) {
412  ParallelCopy(m_cy, m_cx, *m_cmd_x2y, 0, 0, 1, m_dtos_x2y);
413  }
414  m_fft_fwd_y.template compute_c2c<Direction::forward>();
415 
416  if ( m_cmd_y2z) {
417  ParallelCopy(m_cz, m_cy, *m_cmd_y2z, 0, 0, 1, m_dtos_y2z);
418  }
419 #if (AMREX_SPACEDIM == 3)
420  else if ( m_cmd_x2z) {
421  if (m_openbc_half) {
422  Box upper_half = m_spectral_domain_z;
423  // Note that z-direction's index is 0 because we z is the unit-stride direction here.
424  upper_half.growLo (0,-m_spectral_domain_z.length(0)/2);
425  if (! m_cmd_x2z_half) {
426  Box bottom_half = m_spectral_domain_z;
427  bottom_half.growHi(0,-m_spectral_domain_z.length(0)/2);
428  m_cmd_x2z_half = std::make_unique<MultiBlockCommMetaData>
429  (m_cz, bottom_half, m_cx, IntVect(0), m_dtos_x2z);
430  }
432  {NonLocalBC::PackComponents{}, m_dtos_x2z};
433  auto handler = ParallelCopy_nowait(m_cz, m_cx, *m_cmd_x2z_half, packing);
434  m_cz.setVal(0, upper_half, 0, 1);
435  ParallelCopy_finish(m_cz, std::move(handler), *m_cmd_x2z_half, packing);
436  } else {
437  ParallelCopy(m_cz, m_cx, *m_cmd_x2z, 0, 0, 1, m_dtos_x2z);
438  }
439  }
440 #endif
441  m_fft_fwd_z.template compute_c2c<Direction::forward>();
442 }
443 
444 template <typename T, Direction D, DomainStrategy S>
445 template <Direction DIR, std::enable_if_t<DIR == Direction::both, int> >
447 {
448  backward_doit(outmf);
449 }
450 
451 template <typename T, Direction D, DomainStrategy S>
452 void R2C<T,D,S>::backward_doit (MF& outmf, IntVect const& ngout)
453 {
454  BL_PROFILE("FFT::R2C::backward(out)");
455 
456  m_fft_bwd_z.template compute_c2c<Direction::backward>();
457  if ( m_cmd_z2y) {
458  ParallelCopy(m_cy, m_cz, *m_cmd_z2y, 0, 0, 1, m_dtos_z2y);
459  }
460 #if (AMREX_SPACEDIM == 3)
461  else if ( m_cmd_z2x) {
462  if (m_openbc_half) {
463  Box upper_half = m_spectral_domain_x;
464  upper_half.growLo (2,-m_spectral_domain_x.length(2)/2);
465  if (! m_cmd_z2x_half) {
466  Box bottom_half = m_spectral_domain_x;
467  bottom_half.growHi(2,-m_spectral_domain_x.length(2)/2);
468  m_cmd_z2x_half = std::make_unique<MultiBlockCommMetaData>
469  (m_cx, bottom_half, m_cz, IntVect(0), m_dtos_z2x);
470  }
472  {NonLocalBC::PackComponents{}, m_dtos_z2x};
473  auto handler = ParallelCopy_nowait(m_cx, m_cz, *m_cmd_z2x_half, packing);
474  ParallelCopy_finish(m_cx, std::move(handler), *m_cmd_z2x_half, packing);
475  } else {
476  ParallelCopy(m_cx, m_cz, *m_cmd_z2x, 0, 0, 1, m_dtos_z2x);
477  }
478  }
479 #endif
480 
481  m_fft_bwd_y.template compute_c2c<Direction::backward>();
482  if ( m_cmd_y2x) {
483  ParallelCopy(m_cx, m_cy, *m_cmd_y2x, 0, 0, 1, m_dtos_y2x);
484  }
485 
486  m_fft_bwd_x.template compute_r2c<Direction::backward>();
487  outmf.ParallelCopy(m_rx, 0, 0, 1, IntVect(0), ngout);
488 }
489 
490 template <typename T, Direction D, DomainStrategy S>
491 std::pair<Plan<T>, Plan<T>>
493 {
494  Plan<T> fwd;
495  Plan<T> bwd;
496 
497  auto* fab = detail::get_fab(inout);
498  if (!fab) { return {fwd, bwd};}
499 
500  Box const& box = fab->box();
501  auto* pio = (typename Plan<T>::VendorComplex *)fab->dataPtr();
502 
503 #ifdef AMREX_USE_SYCL
504  fwd.template init_c2c<Direction::forward>(box, pio);
505  bwd = fwd;
506 #else
507  if constexpr (D == Direction::both || D == Direction::forward) {
508  fwd.template init_c2c<Direction::forward>(box, pio);
509  }
510  if constexpr (D == Direction::both || D == Direction::backward) {
511  bwd.template init_c2c<Direction::backward>(box, pio);
512  }
513 #endif
514 
515  return {fwd, bwd};
516 }
517 
518 template <typename T, Direction D, DomainStrategy S>
519 template <typename F>
520 void R2C<T,D,S>::post_forward_doit (F const& post_forward)
521 {
522  if (m_info.batch_mode) {
523  amrex::Abort("xxxxx todo: post_forward");
524  } else {
525  if ( ! m_cz.empty()) {
526  auto* spectral_fab = detail::get_fab(m_cz);
527  if (spectral_fab) {
528  auto const& a = spectral_fab->array(); // m_cz's ordering is z,x,y
529  ParallelFor(spectral_fab->box(),
530  [=] AMREX_GPU_DEVICE (int iz, int jx, int ky)
531  {
532  post_forward(jx,ky,iz,a(iz,jx,ky));
533  });
534  }
535  } else if ( ! m_cy.empty()) {
536  auto* spectral_fab = detail::get_fab(m_cy);
537  if (spectral_fab) {
538  auto const& a = spectral_fab->array(); // m_cy's ordering is y,x,z
539  ParallelFor(spectral_fab->box(),
540  [=] AMREX_GPU_DEVICE (int iy, int jx, int k)
541  {
542  post_forward(jx,iy,k,a(iy,jx,k));
543  });
544  }
545  } else {
546  auto* spectral_fab = detail::get_fab(m_cx);
547  if (spectral_fab) {
548  auto const& a = spectral_fab->array();
549  ParallelFor(spectral_fab->box(),
550  [=] AMREX_GPU_DEVICE (int i, int j, int k)
551  {
552  post_forward(i,j,k,a(i,j,k));
553  });
554  }
555  }
556  }
557 }
558 
559 template <typename T, Direction D, DomainStrategy S>
561 {
562 #if (AMREX_SPACEDIM == 3)
563  if (m_info.batch_mode) {
564  return T(1)/T(Long(m_real_domain.length(0)) *
565  Long(m_real_domain.length(1)));
566  } else
567 #endif
568  {
569  return T(1)/T(m_real_domain.numPts());
570  }
571 }
572 
573 template <typename T, Direction D, DomainStrategy S>
574 template <Direction DIR, std::enable_if_t<DIR == Direction::forward ||
575  DIR == Direction::both, int> >
576 std::pair<typename R2C<T,D,S>::cMF *, IntVect>
578 {
579  if (!m_cz.empty()) {
580  return std::make_pair(&m_cz, IntVect{AMREX_D_DECL(2,0,1)});
581  } else if (!m_cy.empty()) {
582  return std::make_pair(&m_cy, IntVect{AMREX_D_DECL(1,0,2)});
583  } else {
584  return std::make_pair(&m_cx, IntVect{AMREX_D_DECL(0,1,2)});
585  }
586 }
587 
588 template <typename T, Direction D, DomainStrategy S>
589 template <Direction DIR, std::enable_if_t<DIR == Direction::forward ||
590  DIR == Direction::both, int> >
591 void R2C<T,D,S>::forward (MF const& inmf, cMF& outmf)
592 {
593  BL_PROFILE("FFT::R2C::forward(inout)");
594 
595  forward(inmf);
596  if (!m_cz.empty()) { // m_cz's order (z,x,y) -> (x,y,z)
597  RotateBwd dtos{};
599  (outmf, m_spectral_domain_x, m_cz, IntVect(0), dtos);
600  ParallelCopy(outmf, m_cz, cmd, 0, 0, 1, dtos);
601  } else if (!m_cy.empty()) { // m_cy's order (y,x,z) -> (x,y,z)
603  (outmf, m_spectral_domain_x, m_cy, IntVect(0), m_dtos_y2x);
604  ParallelCopy(outmf, m_cy, cmd, 0, 0, 1, m_dtos_y2x);
605  } else {
606  outmf.ParallelCopy(m_cx, 0, 0, 1);
607  }
608 }
609 
610 template <typename T, Direction D, DomainStrategy S>
611 template <Direction DIR, std::enable_if_t<DIR == Direction::backward ||
612  DIR == Direction::both, int> >
613 void R2C<T,D,S>::backward (cMF const& inmf, MF& outmf)
614 {
615  BL_PROFILE("FFT::R2C::backward(inout)");
616 
617  if (!m_cz.empty()) { // (x,y,z) -> m_cz's order (z,x,y)
618  RotateFwd dtos{};
620  (m_cz, m_spectral_domain_z, inmf, IntVect(0), dtos);
621  ParallelCopy(m_cz, inmf, cmd, 0, 0, 1, dtos);
622  } else if (!m_cy.empty()) { // (x,y,z) -> m_cy's ordering (y,x,z)
624  (m_cy, m_spectral_domain_y, inmf, IntVect(0), m_dtos_x2y);
625  ParallelCopy(m_cy, inmf, cmd, 0, 0, 1, m_dtos_x2y);
626  } else {
627  m_cx.ParallelCopy(inmf, 0, 0, 1);
628  }
629  backward_doit(outmf);
630 }
631 
632 template <typename T, Direction D, DomainStrategy S>
633 std::pair<BoxArray,DistributionMapping>
635 {
636 #if (AMREX_SPACEDIM == 3)
637  if (!m_cz.empty()) {
638  BoxList bl = m_cz.boxArray().boxList();
639  for (auto& b : bl) {
640  auto lo = b.smallEnd();
641  auto hi = b.bigEnd();
642  std::swap(lo[0], lo[1]);
643  std::swap(lo[1], lo[2]);
644  std::swap(hi[0], hi[1]);
645  std::swap(hi[1], hi[2]);
646  b.setSmall(lo);
647  b.setBig(hi);
648  }
649  return std::make_pair(BoxArray(std::move(bl)), m_cz.DistributionMap());
650  } else
651 #endif
652 #if (AMREX_SPACEDIM >= 2)
653  if (!!m_cy.empty()) {
654  BoxList bl = m_cy.boxArray().boxList();
655  for (auto& b : bl) {
656  auto lo = b.smallEnd();
657  auto hi = b.bigEnd();
658  std::swap(lo[0], lo[1]);
659  std::swap(hi[0], hi[1]);
660  b.setSmall(lo);
661  b.setBig(hi);
662  }
663  return std::make_pair(BoxArray(std::move(bl)), m_cy.DistributionMap());
664  } else
665 #endif
666  {
667  return std::make_pair(m_cx.boxArray(), m_cx.DistributionMap());
668  }
669 }
670 
671 }
672 
673 #endif
#define BL_PROFILE(a)
Definition: AMReX_BLProfiler.H:551
#define AMREX_ALWAYS_ASSERT(EX)
Definition: AMReX_BLassert.H:50
#define AMREX_GPU_DEVICE
Definition: AMReX_GpuQualifiers.H:18
#define AMREX_D_DECL(a, b, c)
Definition: AMReX_SPACE.H:104
if(!(yy_init))
Definition: amrex_iparser.lex.nolint.H:935
A collection of Boxes stored in an Array.
Definition: AMReX_BoxArray.H:549
A class for managing a List of Boxes that share a common IndexType. This class implements operations ...
Definition: AMReX_BoxList.H:52
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & smallEnd() const &noexcept
Get the smallend of the BoxND.
Definition: AMReX_Box.H:105
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & bigEnd() const &noexcept
Get the bigend.
Definition: AMReX_Box.H:116
AMREX_GPU_HOST_DEVICE IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition: AMReX_Box.H:146
AMREX_GPU_HOST_DEVICE BoxND & growHi(int idir, int n_cell=1) noexcept
Grow the BoxND on the high end by n_cell cells in direction idir. NOTE: n_cell negative shrinks the B...
Definition: AMReX_Box.H:659
AMREX_GPU_HOST_DEVICE BoxND & growLo(int idir, int n_cell=1) noexcept
Grow the BoxND on the low end by n_cell cells in direction idir. NOTE: n_cell negative shrinks the Bo...
Definition: AMReX_Box.H:648
Calculates the distribution of FABs to MPI processes.
Definition: AMReX_DistributionMapping.H:41
Long size() const noexcept
Length of the underlying processor map.
Definition: AMReX_DistributionMapping.H:104
Definition: AMReX_FFT_OpenBCSolver.H:11
Parallel Discrete Fourier Transform.
Definition: AMReX_FFT_R2C.H:34
R2C(R2C const &)=delete
T scalingFactor() const
Definition: AMReX_FFT_R2C.H:560
std::pair< cMF *, IntVect > getSpectralData()
Get the internal spectral data.
RotateFwd m_dtos_x2z
Definition: AMReX_FFT_R2C.H:195
std::unique_ptr< MultiBlockCommMetaData > m_cmd_x2z_half
Definition: AMReX_FFT_R2C.H:189
Swap01 m_dtos_x2y
Definition: AMReX_FFT_R2C.H:191
Plan< T > m_fft_bwd_y
Definition: AMReX_FFT_R2C.H:176
static std::pair< Plan< T >, Plan< T > > make_c2c_plans(cMF &inout)
Definition: AMReX_FFT_R2C.H:492
Box m_real_domain
Definition: AMReX_FFT_R2C.H:206
Plan< T > m_fft_fwd_x
Definition: AMReX_FFT_R2C.H:173
Swap02 m_dtos_y2z
Definition: AMReX_FFT_R2C.H:193
std::unique_ptr< MultiBlockCommMetaData > m_cmd_x2y
Definition: AMReX_FFT_R2C.H:183
std::unique_ptr< MultiBlockCommMetaData > m_cmd_z2y
Definition: AMReX_FFT_R2C.H:186
Plan< T > m_fft_bwd_x
Definition: AMReX_FFT_R2C.H:174
R2C(R2C &&)=delete
void forward(MF const &inmf, cMF &outmf)
Forward transform.
Definition: AMReX_FFT_R2C.H:591
cMF m_cz
Definition: AMReX_FFT_R2C.H:201
std::unique_ptr< MultiBlockCommMetaData > m_cmd_z2x_half
Definition: AMReX_FFT_R2C.H:190
Plan< T > m_fft_bwd_z
Definition: AMReX_FFT_R2C.H:178
bool m_slab_decomp
Definition: AMReX_FFT_R2C.H:213
cMF m_cx
Definition: AMReX_FFT_R2C.H:199
void backward(MF &outmf)
Backward transform.
Definition: AMReX_FFT_R2C.H:446
Box m_spectral_domain_y
Definition: AMReX_FFT_R2C.H:208
RotateBwd m_dtos_z2x
Definition: AMReX_FFT_R2C.H:196
std::pair< BoxArray, DistributionMapping > getSpectralDataLayout() const
Get BoxArray and DistributionMapping for spectral data.
Definition: AMReX_FFT_R2C.H:634
Info m_info
Definition: AMReX_FFT_R2C.H:211
std::unique_ptr< MultiBlockCommMetaData > m_cmd_y2z
Definition: AMReX_FFT_R2C.H:185
Box m_spectral_domain_z
Definition: AMReX_FFT_R2C.H:209
std::unique_ptr< MultiBlockCommMetaData > m_cmd_z2x
Definition: AMReX_FFT_R2C.H:188
std::conditional_t< std::is_same_v< T, Real >, MultiFab, FabArray< BaseFab< T > > > MF
Definition: AMReX_FFT_R2C.H:37
Plan< T > m_fft_fwd_y
Definition: AMReX_FFT_R2C.H:175
R2C(Box const &domain, Info const &info=Info{})
Constructor.
Definition: AMReX_FFT_R2C.H:218
std::unique_ptr< MultiBlockCommMetaData > m_cmd_y2x
Definition: AMReX_FFT_R2C.H:184
bool m_openbc_half
Definition: AMReX_FFT_R2C.H:214
void post_forward_doit(F const &post_forward)
Definition: AMReX_FFT_R2C.H:520
Plan< T > m_fft_fwd_z
Definition: AMReX_FFT_R2C.H:177
std::unique_ptr< char, DataDeleter > m_data_2
Definition: AMReX_FFT_R2C.H:204
Swap02 m_dtos_z2y
Definition: AMReX_FFT_R2C.H:194
R2C & operator=(R2C const &)=delete
MF m_rx
Definition: AMReX_FFT_R2C.H:198
void backward_doit(MF &outmf, IntVect const &ngout=IntVect(0))
Definition: AMReX_FFT_R2C.H:452
Box m_spectral_domain_x
Definition: AMReX_FFT_R2C.H:207
Swap01 m_dtos_y2x
Definition: AMReX_FFT_R2C.H:192
std::unique_ptr< char, DataDeleter > m_data_1
Definition: AMReX_FFT_R2C.H:203
cMF m_cy
Definition: AMReX_FFT_R2C.H:200
~R2C()
Definition: AMReX_FFT_R2C.H:383
void backward(cMF const &inmf, MF &outmf)
Backward transform.
Definition: AMReX_FFT_R2C.H:613
void forward(MF const &inmf)
Forward transform.
Definition: AMReX_FFT_R2C.H:402
std::unique_ptr< MultiBlockCommMetaData > m_cmd_x2z
Definition: AMReX_FFT_R2C.H:187
void forwardThenBackward(MF const &inmf, MF &outmf, F const &post_forward)
Forward and then backward transform.
Definition: AMReX_FFT_R2C.H:78
bool empty() const noexcept
Definition: AMReX_FabArrayBase.H:88
An Array of FortranArrayBox(FAB)-like Objects.
Definition: AMReX_FabArray.H:344
void ParallelCopy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition: AMReX_FabArray.H:778
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, int ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Define this FabArray identically to that performed by the constructor having an analogous function si...
Definition: AMReX_FabArray.H:2027
A collection (stored as an array) of FArrayBox objects.
Definition: AMReX_MultiFab.H:38
FA::FABType::value_type * get_fab(FA &fa)
Definition: AMReX_FFT_Helper.H:1303
std::unique_ptr< char, DataDeleter > make_mfs_share(FA1 &fa1, FA2 &fa2)
Definition: AMReX_FFT_Helper.H:1314
DistributionMapping make_iota_distromap(Long n)
Definition: AMReX_FFT.cpp:88
Definition: AMReX_FFT.cpp:7
Direction
Definition: AMReX_FFT_Helper.H:46
DomainStrategy
Definition: AMReX_FFT_Helper.H:48
std::enable_if_t< IsBaseFab< FAB >) &&IsDataPacking< DataPacking, FAB >)> ParallelCopy_finish(FabArray< FAB > &dest, CommHandler handler, const FabArrayBase::CommMetaData &cmd, const DataPacking &data_packing)
Definition: AMReX_NonLocalBC.H:793
AMREX_NODISCARD CommHandler ParallelCopy_nowait(NoLocalCopy, FabArray< FAB > &dest, const FabArray< FAB > &src, const FabArrayBase::CommMetaData &cmd, const DataPacking &data_packing)
Definition: AMReX_NonLocalBC.H:701
int MyProcSub() noexcept
my sub-rank in current frame
Definition: AMReX_ParallelContext.H:76
int NProcsSub() noexcept
number of ranks in current frame
Definition: AMReX_ParallelContext.H:74
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void swap(T &a, T &b) noexcept
Definition: AMReX_algoim_K.H:113
@ min
Definition: AMReX_ParallelReduce.H:18
constexpr int iz
Definition: AMReX_Interp_3D_C.H:37
constexpr int iy
Definition: AMReX_Interp_2D_C.H:33
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition: AMReX_CTOParallelForImpl.H:200
IntVectND< AMREX_SPACEDIM > IntVect
Definition: AMReX_BaseFwd.H:30
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 length(Array4< T > const &a) noexcept
Definition: AMReX_Array4.H:322
BoxArray decompose(Box const &domain, int nboxes, Array< bool, AMREX_SPACEDIM > const &decomp={AMREX_D_DECL(true, true, true)}, bool no_overlap=false)
Decompose domain box into BoxArray.
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition: AMReX.cpp:225
void ParallelCopy(MF &dst, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &ng_src=IntVect(0), IntVect const &ng_dst=IntVect(0), Periodicity const &period=Periodicity::NonPeriodic())
dst = src w/ MPI communication
Definition: AMReX_FabArrayUtility.H:1672
Definition: AMReX_FFT_Helper.H:56
bool batch_mode
Definition: AMReX_FFT_Helper.H:60
int nprocs
Max number of processes to use.
Definition: AMReX_FFT_Helper.H:63
Definition: AMReX_FFT_Helper.H:111
std::conditional_t< std::is_same_v< float, T >, cuComplex, cuDoubleComplex > VendorComplex
Definition: AMReX_FFT_Helper.H:115
Definition: AMReX_FFT_Helper.H:1426
Definition: AMReX_FFT_Helper.H:1401
Definition: AMReX_FFT_Helper.H:1355
Definition: AMReX_FFT_Helper.H:1378
FabArray memory allocation information.
Definition: AMReX_FabArray.H:66
This class specializes behaviour on local copies and unpacking receive buffers.
Definition: AMReX_NonLocalBC.H:615
This is the index mapping based on the DTOS MultiBlockDestToSrc.
Definition: AMReX_NonLocalBC.H:210
Contains information about which components take part of the data transaction.
Definition: AMReX_NonLocalBC.H:528