ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
P3MFFT.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024-2025 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <utils/Vector.hpp>
23
24#include <boost/mpi/communicator.hpp>
25
26#include <heffte.h>
27
28#include <algorithm>
29#include <array>
30#include <memory>
31
32template <typename T, std::size_t N>
34 std::array<T, N> res{};
35 std::copy(vec.begin(), vec.end(), res.begin());
36 return res;
37};
38
39template <typename FloatType> class P3MFFT {
40private:
41 using backend_tag = heffte::backend::default_backend<heffte::tag::cpu>::type;
42 using Box = heffte::box3d<>;
43 boost::mpi::communicator comm;
44 Utils::Vector3i m_memory_layout;
45 Utils::Vector3i m_global_mesh;
46 std::shared_ptr<Box> in_box;
47 std::shared_ptr<Box> out_box;
48 heffte::fft3d<backend_tag> fft3d;
49
50public:
51 P3MFFT(boost::mpi::communicator comm, Utils::Vector3i const &global_mesh,
55 : comm(comm), m_memory_layout(memory_layout), m_global_mesh(global_mesh),
56 in_box(std::make_shared<Box>(
58 to_array(rs_local_ur_index - Utils::Vector3i::broadcast(1)),
59 to_array(m_memory_layout))),
60 out_box(std::make_shared<Box>(
62 to_array(rs_local_ur_index - Utils::Vector3i::broadcast(1)),
63 to_array(m_memory_layout))),
64 fft3d(*in_box, *out_box, comm) {
65 init_fft();
66 }
67
69 auto const global_box = heffte::box3d<>(
70 {0, 0, 0}, to_array(m_global_mesh - Utils::Vector3i::broadcast(1)),
71 to_array(m_memory_layout));
72 auto all_boxes = heffte::split_world(
73 global_box, {node_grid[2], node_grid[1], node_grid[0]});
74 out_box = std::make_shared<Box>(all_boxes[comm.rank()]);
75 init_fft();
76 }
77
78 void init_fft() {
79 // at this stage we can manually adjust some HeFFTe options
80 heffte::plan_options options = heffte::default_options<backend_tag>();
81
82 // use strided 1-D FFT operations
83 // some backends work just as well when the entries of the data are not
84 // contiguous then there is no need to reorder the data in the intermediate
85 // stages which saves time
86 options.use_reorder = false;
87
88 // use point-to-point communications
89 // collaborative all-to-all and individual point-to-point communications are
90 // two alternatives one may be better than the other depending on the
91 // version of MPI, the hardware interconnect, and the problem size
92 options.algorithm = heffte::reshape_algorithm::p2p_plined;
93
94 // in the intermediate steps, the data can be shapes as either 2-D slabs or
95 // 1-D pencils for sufficiently large problem, it is expected that the
96 // pencil decomposition is better but for smaller problems, the slabs may
97 // perform better (depending on hardware and backend)
98 options.use_pencils = false;
99 fft3d = heffte::fft3d<backend_tag>(*in_box, *out_box, comm, options);
100 }
101
103 return Utils::Vector3i(out_box->low);
104 }
106 return Utils::Vector3i(out_box->high) + Utils::Vector3i::broadcast(1);
107 }
111 template <typename T> auto forward(T &in) { return fft3d.forward(in); }
112 template <typename In, typename Out> void forward(In in, Out out) {
113 fft3d.forward(in, out);
114 }
115 template <typename T> auto backward(T &in) { return fft3d.backward(in); }
116 template <typename T1, typename T2>
117 auto backward_batch(int n, T1 in, T2 out) {
118 return fft3d.backward(n, in, out);
119 }
120 auto const &get_memory_layout() const { return m_memory_layout; }
121};
auto to_array(Utils::Vector< T, N > const &vec)
Definition P3MFFT.hpp:33
Vector implementation and trait types for boost qvm interoperability.
Utils::Vector3i ks_local_ld_index() const
Definition P3MFFT.hpp:102
Utils::Vector3i ks_local_ur_index() const
Definition P3MFFT.hpp:105
auto backward(T &in)
Definition P3MFFT.hpp:115
void forward(In in, Out out)
Definition P3MFFT.hpp:112
P3MFFT(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 &memory_layout)
Definition P3MFFT.hpp:51
void init_fft()
Definition P3MFFT.hpp:78
Utils::Vector3i ks_local_size() const
Definition P3MFFT.hpp:108
auto forward(T &in)
Definition P3MFFT.hpp:111
void set_preferred_kspace_decomposition(Utils::Vector3i const &node_grid)
Definition P3MFFT.hpp:68
auto backward_batch(int n, T1 in, T2 out)
Definition P3MFFT.hpp:117
auto const & get_memory_layout() const
Definition P3MFFT.hpp:120
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.
Definition Vector.hpp:111
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
VectorXi< 3 > Vector3i
Definition Vector.hpp:174