IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
FFT.h
Go to the documentation of this file.
1//
2// Class FFT
3// The FFT class performs complex-to-complex,
4// real-to-complex on IPPL Fields.
5// FFT is templated on the type of transform to be performed,
6// the dimensionality of the Field to transform, and the
7// floating-point precision type of the Field (float or double).
8// Currently, we use heffte for taking the transforms and the class FFT
9// serves as an interface between IPPL and heffte. In making this interface,
10// we have referred Cabana library
11// https://github.com/ECP-copa/Cabana.
12//
13//
14
15#ifndef IPPL_FFT_FFT_H
16#define IPPL_FFT_FFT_H
17
18#include <Kokkos_Complex.hpp>
19#include <array>
20#include <heffte_fft3d.h>
21#include <heffte_fft3d_r2c.h>
22#include <memory>
23#include <type_traits>
24
27
28#include "Field/Field.h"
29
31#include "Index/NDIndex.h"
32
33namespace heffte {
34 template <>
35 struct is_ccomplex<Kokkos::complex<float>> : std::true_type {};
36
37 template <>
38 struct is_zcomplex<Kokkos::complex<double>> : std::true_type {};
39} // namespace heffte
40
41namespace ippl {
42
46 class CCTransform {};
47 class RCTransform {};
48 class SineTransform {};
49 class CosTransform {};
53 class Cos1Transform {};
54
55 enum FFTComm {
56 a2av = 0,
57 a2a = 1,
58 p2p = 2,
60 };
61
66
67 namespace detail {
72 template <typename>
74
75#if defined(Heffte_ENABLE_FFTW)
76 template <>
77 struct HeffteBackendType<Kokkos::HostSpace> {
78 using backend = heffte::backend::fftw;
79 using backendSine = heffte::backend::fftw_sin;
80 using backendCos = heffte::backend::fftw_cos;
81 using backendCos1 = heffte::backend::fftw_cos1;
82 };
83#elif defined(Heffte_ENABLE_MKL)
84 template <>
85 struct HeffteBackendType<Kokkos::HostSpace> {
86 using backend = heffte::backend::mkl;
87 using backendSine = heffte::backend::mkl_sin;
88 using backendCos = heffte::backend::mkl_cos;
89 };
90#endif
91
92#ifdef Heffte_ENABLE_CUDA
93#ifdef KOKKOS_ENABLE_CUDA
94 template <>
95 struct HeffteBackendType<Kokkos::CudaSpace> {
96 using backend = heffte::backend::cufft;
97 using backendSine = heffte::backend::cufft_sin;
98 using backendCos = heffte::backend::cufft_cos;
99 using backendCos1 = heffte::backend::cufft_cos1;
100 };
101#else
102#error cuFFT backend is enabled for heFFTe but CUDA is not enabled for Kokkos!
103#endif
104#endif
105
106#ifdef KOKKOS_ENABLE_HIP
107#ifdef Heffte_ENABLE_ROCM
108 template <>
109 struct HeffteBackendType<Kokkos::HIPSpace> {
110 using backend = heffte::backend::rocfft;
111 using backendSine = heffte::backend::rocfft_sin;
112 using backendCos = heffte::backend::rocfft_cos;
113 using backendCos1 = heffte::backend::rocfft_cos1;
114 };
115#else
116 template <>
117 struct HeffteBackendType<Kokkos::HIPSpace> {
118 using backend = heffte::backend::stock;
119 using backendSine = heffte::backend::stock_sin;
120 using backendCos = heffte::backend::stock_cos;
121 using backendCos1 = heffte::backend::stock_cos1;
122 };
123#endif
124#endif
125
126#if !defined(Heffte_ENABLE_MKL) && !defined(Heffte_ENABLE_FFTW)
131 template <>
132 struct HeffteBackendType<Kokkos::HostSpace> {
133 using backend = heffte::backend::stock;
134 using backendSine = heffte::backend::stock_sin;
135 using backendCos = heffte::backend::stock_cos;
136 using backendCos1 = heffte::backend::stock_cos1;
137 };
138#endif
139
140 } // namespace detail
141
142 template <typename Field, template <typename...> class FFT, typename Backend,
143 typename BufferType = typename Field::value_type>
144 class FFTBase {
145 constexpr static unsigned Dim = Field::dim;
146
147 public:
148 using heffteBackend = Backend;
149 using workspace_t = typename FFT<heffteBackend>::template buffer_container<BufferType>;
151
152 FFTBase(const Layout_t& layout, const ParameterList& params);
153 ~FFTBase() = default;
154
155 protected:
156 FFTBase() = default;
157
158 void domainToBounds(const NDIndex<Dim>& domain, std::array<long long, 3>& low,
159 std::array<long long, 3>& high);
160 void setup(const heffte::box3d<long long>& inbox, const heffte::box3d<long long>& outbox,
161 const ParameterList& params);
162
163 std::shared_ptr<FFT<heffteBackend, long long>> heffte_m;
165
166 template <typename FieldType>
168 typename Kokkos::View<typename FieldType::view_type::data_type, Kokkos::LayoutLeft,
169 typename FieldType::memory_space>::uniform_type;
171 };
172
173#define IN_PLACE_FFT_BASE_CLASS(Field, Backend) \
174 FFTBase<Field, heffte::fft3d, \
175 typename detail::HeffteBackendType<typename Field::memory_space>::Backend>
176#define EXT_FFT_BASE_CLASS(Field, Backend, Type) \
177 FFTBase<Field, heffte::fft3d_r2c, \
178 typename detail::HeffteBackendType<typename Field::memory_space>::Backend, \
179 typename Type>
180
184 template <class Transform, typename Field>
185 class FFT {};
186
190 template <typename ComplexField>
191 class FFT<CCTransform, ComplexField> : public IN_PLACE_FFT_BASE_CLASS(ComplexField, backend) {
192 constexpr static unsigned Dim = ComplexField::dim;
193 using Base = IN_PLACE_FFT_BASE_CLASS(ComplexField, backend);
194
195 public:
196 using Complex_t = typename ComplexField::value_type;
197
198 using Base::Base;
199 using typename Base::heffteBackend, typename Base::workspace_t, typename Base::Layout_t;
200
205 void warmup(ComplexField& f);
206
212 void transform(TransformDirection direction, ComplexField& f);
213 };
214
218 template <typename RealField>
219 class FFT<RCTransform, RealField>
220 : public EXT_FFT_BASE_CLASS(RealField, backend,
221 Kokkos::complex<typename RealField::value_type>) {
222 constexpr static unsigned Dim = RealField::dim;
223 using Real_t = typename RealField::value_type;
224 using Base = EXT_FFT_BASE_CLASS(RealField, backend,
225 Kokkos::complex<typename RealField::value_type>);
226
227 public:
228 using Complex_t = Kokkos::complex<Real_t>;
229 using ComplexField = typename Field<Complex_t, Dim, typename RealField::Mesh_t,
230 typename RealField::Centering_t,
231 typename RealField::execution_space>::uniform_type;
232
233 using typename Base::heffteBackend, typename Base::workspace_t, typename Base::Layout_t;
234
238 FFT(const Layout_t& layoutInput, const Layout_t& layoutOutput, const ParameterList& params);
239
245 void warmup(RealField& f, ComplexField& g);
246
253 void transform(TransformDirection direction, RealField& f, ComplexField& g);
254
255 private:
256 typename Base::template temp_view_type<ComplexField> tempFieldComplex;
257 };
258
262 template <typename Field>
263 class FFT<SineTransform, Field> : public IN_PLACE_FFT_BASE_CLASS(Field, backendSine) {
264 constexpr static unsigned Dim = Field::dim;
265 using Base = IN_PLACE_FFT_BASE_CLASS(Field, backendSine);
266
267 public:
268 using Base::Base;
269 using typename Base::heffteBackend, typename Base::workspace_t, typename Base::Layout_t;
270
275 void warmup(Field& f);
276
282 void transform(TransformDirection direction, Field& f);
283 };
284
287 template <typename Field>
288 class FFT<CosTransform, Field> : public IN_PLACE_FFT_BASE_CLASS(Field, backendCos) {
289 constexpr static unsigned Dim = Field::dim;
290 using Base = IN_PLACE_FFT_BASE_CLASS(Field, backendCos);
291
292 public:
293 using Base::Base;
294 using typename Base::heffteBackend, typename Base::workspace_t, typename Base::Layout_t;
295
300 void warmup(Field& f);
301
307 void transform(TransformDirection direction, Field& f);
308 };
309
312 template <typename Field>
313 class FFT<Cos1Transform, Field> : public IN_PLACE_FFT_BASE_CLASS(Field, backendCos1) {
314 constexpr static unsigned Dim = Field::dim;
315 using Base = IN_PLACE_FFT_BASE_CLASS(Field, backendCos1);
316
317 public:
318 using Base::Base;
319 using typename Base::heffteBackend, typename Base::workspace_t, typename Base::Layout_t;
320
325 void warmup(Field& f);
326
332 void transform(TransformDirection direction, Field& f);
333 };
334} // namespace ippl
335
336#include "FFT/FFT.hpp"
337
338#endif // IPPL_FFT_FFT_H
339
340// vi: set et ts=4 sw=4 sts=4:
341// Local Variables:
342// mode:c
343// c-basic-offset: 4
344// indent-tabs-mode: nil
345// require-final-newline: nil
346// End:
#define EXT_FFT_BASE_CLASS(Field, Backend, Type)
Definition FFT.h:176
#define IN_PLACE_FFT_BASE_CLASS(Field, Backend)
Definition FFT.h:173
Definition Archive.h:20
TransformDirection
Definition FFT.h:62
@ FORWARD
Definition FFT.h:63
@ BACKWARD
Definition FFT.h:64
FFTComm
Definition FFT.h:55
@ p2p_pl
Definition FFT.h:59
@ a2av
Definition FFT.h:56
@ p2p
Definition FFT.h:58
@ a2a
Definition FFT.h:57
Definition FFT.h:33
heffte::backend::stock_cos1 backendCos1
Definition FFT.h:136
~FFTBase()=default
Backend heffteBackend
Definition FFT.h:148
typename FFT< heffteBackend >::template buffer_container< BufferType > workspace_t
Definition FFT.h:149
typename Kokkos::View< typename FieldType::view_type::data_type, Kokkos::LayoutLeft, typename FieldType::memory_space >::uniform_type temp_view_type
Definition FFT.h:167
FieldLayout< Dim > Layout_t
Definition FFT.h:150
void domainToBounds(const NDIndex< Dim > &domain, std::array< long long, 3 > &low, std::array< long long, 3 > &high)
Definition FFT.hpp:46
workspace_t workspace_m
Definition FFT.h:164
temp_view_type< Field > tempField
Definition FFT.h:170
FFTBase()=default
static constexpr unsigned Dim
Definition FFT.h:145
void setup(const heffte::box3d< long long > &inbox, const heffte::box3d< long long > &outbox, const ParameterList &params)
Definition FFT.hpp:66
std::shared_ptr< FFT< heffteBackend, long long > > heffte_m
Definition FFT.h:163
FFTBase(const Layout_t &layout, const ParameterList &params)
Definition FFT.hpp:32
void transform(TransformDirection direction, ComplexField &f)
Definition FFT.hpp:118
IN_PLACE_FFT_BASE_CLASS(ComplexField, backend) Base
Definition FFT.h:193
void warmup(ComplexField &f)
Definition FFT.hpp:112
static constexpr unsigned Dim
Definition FFT.h:192
typename ComplexField::value_type Complex_t
Definition FFT.h:196
EXT_FFT_BASE_CLASS(RealField, backend, Kokkos::complex< typename RealField::value_type >) Base
Definition FFT.h:224
static constexpr unsigned Dim
Definition FFT.h:222
typename Field< Complex_t, Dim, typename RealField::Mesh_t, typename RealField::Centering_t, typename RealField::execution_space >::uniform_type ComplexField
Definition FFT.h:229
void transform(TransformDirection direction, RealField &f, ComplexField &g)
Definition FFT.hpp:203
typename RealField::value_type Real_t
Definition FFT.h:223
void warmup(RealField &f, ComplexField &g)
Definition FFT.hpp:197
Base::template temp_view_type< ComplexField > tempFieldComplex
Definition FFT.h:256
Kokkos::complex< Real_t > Complex_t
Definition FFT.h:228
FFT(const Layout_t &layoutInput, const Layout_t &layoutOutput, const ParameterList &params)
Definition FFT.hpp:172
static constexpr unsigned Dim
Definition FFT.h:264
void transform(TransformDirection direction, Field &f)
Definition FFT.hpp:272
IN_PLACE_FFT_BASE_CLASS(Field, backendSine) Base
Definition FFT.h:265
IN_PLACE_FFT_BASE_CLASS(Field, backendCos) Base
Definition FFT.h:290
void transform(TransformDirection direction, Field &f)
Definition FFT.hpp:331
static constexpr unsigned Dim
Definition FFT.h:289
void transform(TransformDirection direction, Field &f)
Definition FFT.hpp:390
IN_PLACE_FFT_BASE_CLASS(Field, backendCos1) Base
Definition FFT.h:315
static constexpr unsigned Dim
Definition FFT.h:314