24#include "communication.hpp"
31#include <boost/mpi/communicator.hpp>
34#include <heffte_backends.h>
38#include <initializer_list>
41#if defined(__CUDACC__)
48template <
typename FloatType, Arch Architecture,
class FFTConfig>
class P3MFFT {
50 using OutputType =
typename heffte::fft_output<FloatType>::type;
52 std::conditional_t<Architecture ==
Arch::CPU, heffte::backend::fftw,
53 heffte::backend::cufft>;
54 template <
class T = OutputType>
59 std::conditional_t<FFTConfig::use_r2c, heffte::fft3d_r2c<backend>,
60 heffte::fft3d<backend>>;
61 using Box = heffte::box3d<>;
63 heffte::backend::device_instance<heffte::tag::gpu>::stream_type;
66 std::unique_ptr<Box> in_box;
68 std::unique_ptr<Box> out_box;
72 std::unique_ptr<FFT3D> fft3d;
73 std::shared_ptr<boost::mpi::environment> m_mpi_env_lock;
75 template <
typename T, std::
size_t N>
77 std::array<T, N> res{};
78 std::ranges::copy(vec, res.
begin());
85 m_mpi_env_lock.reset();
87 P3MFFT(stream_type gpu_stream, boost::mpi::communicator comm,
92 auto constexpr row_major_order = std::array<int, 3>{2, 1, 0};
93 auto constexpr col_major_order = std::array<int, 3>{0, 1, 2};
94 auto constexpr in_box_order =
98 auto constexpr out_box_order =
104 auto const global_out_box_full = Box({0, 0, 0}, high, out_box_order);
105 auto const global_out_box =
106 FFTConfig::use_r2c ? global_out_box_full.r2c(FFTConfig::r2c_dir)
107 : global_out_box_full;
108 auto best_grid = node_grid;
109 for (
auto i : {0u, 1u, 2u}) {
110 if (global_mesh[i] % (2 * n_procs) == 0) {
111 best_grid = {n_procs, 1, 1};
116 auto out_boxes = heffte::split_world(global_out_box, to_array(best_grid));
117 out_box = std::make_unique<Box>(out_boxes[comm.rank()]);
119 in_box = std::make_unique<Box>(
120 to_array(rs_local_ld_index),
125 heffte::plan_options options = heffte::default_options<backend>();
131 options.use_reorder =
true;
137 options.algorithm = heffte::reshape_algorithm::p2p_plined;
143 options.use_pencils =
true;
144#if defined(__CUDACC__)
154 auto const trap_pause = (Architecture ==
Arch::CUDA)
159 if constexpr (FFTConfig::use_r2c) {
160 fft3d = std::make_unique<FFT3D>(gpu_stream, *in_box, *out_box,
161 FFTConfig::r2c_dir, comm, options);
164 std::make_unique<FFT3D>(gpu_stream, *in_box, *out_box, comm, options);
166 m_workspace =
decltype(m_workspace)(fft3d->size_workspace());
185 fft3d->forward(in, out, m_workspace.data());
188 fft3d->backward(in, out, m_workspace.data());
199template <
typename FloatType,
class FFTConfig>
210 : m_impl(nullptr, comm, global_mesh, rs_local_ld_index, rs_local_ur_index,
238 std::vector<RSpaceScalar> m_input;
Vector implementation and trait types for boost qvm interoperability.
void backward(auto &&in, auto &&out)
Utils::Vector3i ks_local_size() const
void forward(auto &&in, auto &&out)
Utils::Vector3i ks_local_ur_index() const
Utils::Vector3i rs_local_size() const
typename heffte::fft_output< FloatType >::type OutputType
heffte::fft3d< backend >::template buffer_container< T > buffer_container
P3MFFT(stream_type gpu_stream, boost::mpi::communicator comm, Utils::Vector3i const &global_mesh, Utils::Vector3i const &rs_local_ld_index, Utils::Vector3i const &rs_local_ur_index, Utils::Vector3i const &node_grid)
std::conditional_t< Architecture==Arch::CPU, heffte::backend::fftw, heffte::backend::cufft > backend
Utils::Vector3i ks_local_ld_index() const
DEVICE_QUALIFIER constexpr iterator begin() noexcept
static DEVICE_QUALIFIER constexpr Vector< T, N > broadcast(typename Base::value_type const &value) noexcept
Create a vector that has all entries set to the same value.
static std::shared_ptr< scoped_pause > make_shared_pause_scoped()
Generate a shared handle to temporarily disable any currently active exception trap for the lifetime ...
std::unique_ptr< CommunicationEnvironment > communication_environment
T product(Vector< T, N > const &v)
Abstract interface for the P3M reciprocal-space FFT.
std::complex< FloatType > ComplexType
FloatType RSpaceScalar
Real-space scalar type.
heFFTe-backed implementation of the P3M FFT interface.
Utils::Vector3i rs_local_size() const override
typename Base::RSpaceScalar RSpaceScalar
Utils::Vector3i ks_local_ld_index() const override
void forward(RSpaceScalar const *in, ComplexType *out) override
Utils::Vector3i ks_local_size() const override
RSpaceScalar * forward_input_buffer() override
P3MFFTHeffte(boost::mpi::communicator comm, Utils::Vector3i const &global_mesh, Utils::Vector3i const &rs_local_ld_index, Utils::Vector3i const &rs_local_ur_index, Utils::Vector3i const &node_grid)
Utils::Vector3i ks_local_ur_index() const override
void backward(ComplexType *in, RSpaceScalar *out) override
typename Base::ComplexType ComplexType