diff --git a/fft_8hpp_source.html b/fft_8hpp_source.html
index 2b7da7366..f5001fb38 100644
--- a/fft_8hpp_source.html
+++ b/fft_8hpp_source.html
@@ -133,832 +133,494 @@
-
-
-
-
-
+
+
+
+
+
-
-
- 15#include <Kokkos_Core.hpp>
-
- 17#if fftw_serial_AVAIL || fftw_omp_AVAIL
-
-
-
-
-
-
-
- 25#include <cuda_runtime_api.h>
-
-
-
-
-
-
-
- 33#include <hip/hip_runtime_api.h>
- 34#include <hipfft/hipfft.h>
-
-
- 37#if fftw_serial_AVAIL || fftw_omp_AVAIL
- 38static_assert(
sizeof(fftwf_complex) ==
sizeof(Kokkos::complex<
float>));
- 39static_assert(
alignof(fftwf_complex) <=
alignof(Kokkos::complex<
float>));
-
- 41static_assert(
sizeof(fftw_complex) ==
sizeof(Kokkos::complex<
double>));
- 42static_assert(
alignof(fftw_complex) <=
alignof(Kokkos::complex<
double>));
-
- 44static_assert(
sizeof(fftwl_complex) ==
sizeof(Kokkos::complex<
long double>));
- 45static_assert(
alignof(fftwl_complex) <=
alignof(Kokkos::complex<
long double>));
-
-
-
- 49static_assert(
sizeof(cufftComplex) ==
sizeof(Kokkos::complex<
float>));
- 50static_assert(
alignof(cufftComplex) <=
alignof(Kokkos::complex<
float>));
-
- 52static_assert(
sizeof(cufftDoubleComplex) ==
sizeof(Kokkos::complex<
double>));
- 53static_assert(
alignof(cufftDoubleComplex) <=
alignof(Kokkos::complex<
double>));
-
-
-
- 57static_assert(
sizeof(hipfftComplex) ==
sizeof(Kokkos::complex<
float>));
- 58static_assert(
alignof(hipfftComplex) <=
alignof(Kokkos::complex<
float>));
-
- 60static_assert(
sizeof(hipfftDoubleComplex) ==
sizeof(Kokkos::complex<
double>));
- 61static_assert(
alignof(hipfftDoubleComplex) <=
alignof(Kokkos::complex<
double>));
-
-
-
-
-
- 67
- 68
- 69
- 70
- 71template <
typename Dim>
-
-
-
- 75
- 76
- 77
- 78
-
-
-
-
-
-
- 85
- 86
- 87
- 88
-
-
-
-
-
-
- 95
- 96
- 97
- 98
-
-
-
-
- 103namespace ddc::detail::fft {
-
-
-
-
-
+ 13#include <KokkosFFT.hpp>
+ 14#include <Kokkos_Core.hpp>
+
+
+
+
+ 19
+ 20
+ 21
+ 22
+ 23template <
typename Dim>
+
+
+
+ 27
+ 28
+ 29
+ 30
+
+
+
+
+
+
+ 37
+ 38
+ 39
+ 40
+
+
+
+
+
+
+ 47
+ 48
+ 49
+ 50
+
+
+
+
+ 55namespace ddc::detail::fft {
+
+
+
+
+
+
+
+
+ 64struct real_type<Kokkos::complex<T>>
+
+
+
+
+
+ 70using real_type_t =
typename real_type<T>::type;
+
+
+
+ 74struct is_complex : std::false_type
+
+
+
+
+ 79struct is_complex<Kokkos::complex<T>> : std::true_type
+
+
+
+
+ 84constexpr bool is_complex_v = is_complex<T>::value;
+
+
+ 87template <
typename T,
typename Dim,
typename Last>
+ 88KOKKOS_FUNCTION
constexpr T LastSelector(
const T a,
const T b)
+
+ 90 return std::is_same_v<Dim, Last> ? a : b;
+
+
+ 93template <
typename T,
typename Dim,
typename First,
typename Second,
typename... Tail>
+ 94KOKKOS_FUNCTION
constexpr T LastSelector(
const T a,
const T b)
+
+ 96 return LastSelector<T, Dim, Second, Tail...>(a, b);
+
+
+
+ 100
+ 101
+ 102
+ 103
+
+
+
+
+
-
- 112struct real_type<Kokkos::complex<T>>
-
-
-
-
-
- 118using real_type_t =
typename real_type<T>::type;
-
-
-
- 122struct is_complex : std::false_type
-
-
-
-
- 127struct is_complex<Kokkos::complex<T>> : std::true_type
-
-
-
-
- 132constexpr bool is_complex_v = is_complex<T>::value;
-
-
- 135template <
typename T,
typename Dim,
typename Last>
- 136KOKKOS_FUNCTION
constexpr T LastSelector(
const T a,
const T b)
+
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119template <
typename DDim,
typename... DDimX>
+
+
+
+ 123 (is_uniform_point_sampling_v<DDimX> && ...),
+ 124 "DDimX dimensions should derive from UniformPointSampling");
+ 125 return static_cast<
int>(x_mesh.
template extent<DDim>());
+
+
+ 128template <
typename... DDimX>
+ 129KokkosFFT::axis_type<
sizeof...(DDimX)> axes()
+
+ 131 return KokkosFFT::axis_type<
sizeof...(DDimX)> {
+ 132 static_cast<
int>(
ddc::type_seq_rank_v<DDimX,
ddc::detail::TypeSeq<DDimX...>>)...};
+
+
+ 135inline KokkosFFT::Normalization ddc_fft_normalization_to_kokkos_fft(
+
- 138 return std::is_same_v<Dim, Last> ? a : b;
-
-
- 141template <
typename T,
typename Dim,
typename First,
typename Second,
typename... Tail>
- 142KOKKOS_FUNCTION
constexpr T LastSelector(
const T a,
const T b)
-
- 144 return LastSelector<T, Dim, Second, Tail...>(a, b);
-
+
+
+ 140 return KokkosFFT::Normalization::none;
+
+
+
+ 144 return KokkosFFT::Normalization::forward;
+
-
- 148
- 149
- 150
- 151
- 152enum class TransformType { R2R, R2C, C2R, C2C };
-
- 154template <
typename T1,
typename T2>
-
-
- 157 static constexpr TransformType value = TransformType::R2R;
-
-
- 160template <
typename T1,
typename T2>
- 161struct transform_type<T1, Kokkos::complex<T2>>
-
- 163 static constexpr TransformType value = TransformType::R2C;
-
-
- 166template <
typename T1,
typename T2>
- 167struct transform_type<Kokkos::complex<T1>, T2>
-
- 169 static constexpr TransformType value = TransformType::C2R;
-
-
- 172template <
typename T1,
typename T2>
- 173struct transform_type<Kokkos::complex<T1>, Kokkos::complex<T2>>
-
- 175 static constexpr TransformType value = TransformType::C2C;
-
-
-
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186template <
typename T1,
typename T2>
- 187constexpr TransformType transform_type_v = transform_type<T1, T2>::value;
-
- 189#if fftw_serial_AVAIL || fftw_omp_AVAIL
-
-
-
-
-
-
-
-
- 198struct _fftw_type<Kokkos::complex<T>>
-
-
- 201 conditional_t<std::is_same_v<real_type_t<T>,
float>, fftwf_complex, fftw_complex>;
-
-
-
-
- 206using _fftw_plan = std::conditional_t<std::is_same_v<real_type_t<T>,
float>, fftwf_plan, fftw_plan>;
-
-
- 209template <
typename Tin,
typename Tout,
typename... Args,
typename PenultArg,
typename LastArg>
- 210_fftw_plan<Tin> _fftw_plan_many_dft(
- 211 [[maybe_unused]] PenultArg penultArg,
-
-
-
- 215 const TransformType transformType = transform_type_v<Tin, Tout>;
- 216 if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
float>) {
- 217 return fftwf_plan_many_dft_r2c(args..., lastArg);
- 218 }
else if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
double>) {
- 219 return fftw_plan_many_dft_r2c(args..., lastArg);
- 220 }
else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
float>) {
- 221 return fftwf_plan_many_dft_c2r(args..., lastArg);
- 222 }
else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
double>) {
- 223 return fftw_plan_many_dft_c2r(args..., lastArg);
- 224 }
else if constexpr (
- 225 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
float>>) {
- 226 return fftwf_plan_many_dft(args..., penultArg, lastArg);
- 227 }
else if constexpr (
- 228 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
double>>) {
- 229 return fftw_plan_many_dft(args..., penultArg, lastArg);
-
-
-
-
-
-
-
-
-
-
-
- 241 using type = std::conditional_t<std::is_same_v<T,
float>, cufftReal, cufftDoubleReal>;
-
-
-
- 245struct _cufft_type<Kokkos::complex<T>>
-
-
- 248 conditional_t<std::is_same_v<real_type_t<T>,
float>, cufftComplex, cufftDoubleComplex>;
-
-
-
- 252template <
typename Tin,
typename Tout>
- 253constexpr auto cufft_transform_type()
-
- 255 const TransformType transformType = transform_type_v<Tin, Tout>;
- 256 if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
float>)
-
- 258 else if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
double>)
-
- 260 else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
float>)
-
- 262 else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
double>)
-
-
- 265 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
float>>)
-
-
- 268 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
double>>)
-
-
-
-
-
-
-
- 276template <
typename Tin,
typename Tout,
typename... Args,
typename LastArg>
- 277cufftResult _cufftExec([[maybe_unused]] LastArg lastArg, Args... args)
-
- 279 const TransformType transformType = transform_type_v<Tin, Tout>;
- 280 if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
float>)
- 281 return cufftExecR2C(args...);
- 282 else if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
double>)
- 283 return cufftExecD2Z(args...);
- 284 else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
float>)
- 285 return cufftExecC2R(args...);
- 286 else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
double>)
- 287 return cufftExecZ2D(args...);
-
- 289 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
float>>)
- 290 return cufftExecC2C(args..., lastArg);
-
- 292 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
double>>)
- 293 return cufftExecZ2Z(args..., lastArg);
-
-
-
-
-
-
-
-
-
- 303 using type = std::conditional_t<std::is_same_v<T,
float>, hipfftReal, hipfftDoubleReal>;
-
-
-
- 307struct _hipfft_type<Kokkos::complex<T>>
-
- 309 using type = std::conditional_t<
- 310 std::is_same_v<real_type_t<T>,
float>,
-
- 312 hipfftDoubleComplex>;
-
-
-
- 316template <
typename Tin,
typename Tout>
- 317constexpr auto hipfft_transform_type()
-
- 319 const TransformType transformType = transform_type_v<Tin, Tout>;
- 320 if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
float>)
-
- 322 else if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
double>)
-
- 324 else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
float>)
-
- 326 else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
double>)
-
-
- 329 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
float>>)
-
-
- 332 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
double>>)
-
-
-
-
-
-
-
- 340template <
typename Tin,
typename Tout,
typename... Args,
typename LastArg>
- 341hipfftResult _hipfftExec([[maybe_unused]] LastArg lastArg, Args... args)
-
- 343 const TransformType transformType = transform_type_v<Tin, Tout>;
- 344 if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
float>)
- 345 return hipfftExecR2C(args...);
- 346 else if constexpr (transformType == TransformType::R2C && std::is_same_v<Tin,
double>)
- 347 return hipfftExecD2Z(args...);
- 348 else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
float>)
- 349 return hipfftExecC2R(args...);
- 350 else if constexpr (transformType == TransformType::C2R && std::is_same_v<Tout,
double>)
- 351 return hipfftExecZ2D(args...);
-
- 353 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
float>>)
- 354 return hipfftExecC2C(args..., lastArg);
-
- 356 transformType == TransformType::C2C && std::is_same_v<Tin, Kokkos::complex<
double>>)
- 357 return hipfftExecZ2Z(args..., lastArg);
-
-
-
-
-
-
- 364
- 365
- 366
- 367
-
-
-
-
-
-
-
-
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383template <
typename DDim,
typename... DDimX>
-
-
-
- 387 (is_uniform_point_sampling_v<DDimX> && ...),
- 388 "DDimX dimensions should derive from UniformPointSampling");
- 389 return static_cast<
int>(x_mesh.
template extent<DDim>());
-
-
-
- 393template <
typename Tin,
typename Tout,
typename ExecSpace,
typename MemorySpace,
typename... DDimX>
-
- 395 ExecSpace
const& exec_space,
-
-
-
- 399 const kwArgs_impl& kwargs)
-
-
- 402 std::is_same_v<real_type_t<Tin>,
float> || std::is_same_v<real_type_t<Tin>,
double>,
- 403 "Base type of Tin (and Tout) must be float or double.");
-
- 405 std::is_same_v<real_type_t<Tin>, real_type_t<Tout>>,
- 406 "Types Tin and Tout must be based on same type (float or double)");
+
+ 148 return KokkosFFT::Normalization::backward;
+
+
+
+ 152 return KokkosFFT::Normalization::ortho;
+
+
+ 155 throw std::runtime_error(
"ddc::FFT_Normalization not handled");
+
+
+
+
+ 160 typename ElementType,
+
+
+ 163 typename MemorySpace,
+
+
+ 166 ExecSpace
const& exec_space,
+ 167 ddc::
ChunkSpan<ElementType, DDom, Layout, MemorySpace>
const& chunk_span,
+
+
+ 170 ddc::parallel_for_each(
+ 171 "ddc_fft_normalization",
+
+
+ 174 KOKKOS_LAMBDA(
typename DDom::discrete_element_type
const i) {
+ 175 chunk_span(i) *= value;
+
+
+
+
+
+
+
+
+ 184 typename MemorySpace,
+
+
+
+
+
+ 190 ExecSpace
const& exec_space,
+
+
+ 193 kwArgs_impl
const& kwargs)
+
+
+ 196 std::is_same_v<real_type_t<Tin>,
float> || std::is_same_v<real_type_t<Tin>,
double>,
+ 197 "Base type of Tin (and Tout) must be float or double.");
+
+ 199 std::is_same_v<real_type_t<Tin>, real_type_t<Tout>>,
+ 200 "Types Tin and Tout must be based on same type (float or double)");
+
+ 202 Kokkos::SpaceAccessibility<ExecSpace, MemorySpace>::accessible,
+ 203 "MemorySpace has to be accessible for ExecutionSpace.");
+
+
+ 206 ddc::detail::mdspan_to_kokkos_element_t<Tin,
sizeof...(DDimIn)>,
+ 207 ddc::detail::mdspan_to_kokkos_layout_t<LayoutIn>,
+ 208 MemorySpace>
const in_view
+ 209 = in.allocation_kokkos_view();
+
+ 211 ddc::detail::mdspan_to_kokkos_element_t<Tout,
sizeof...(DDimIn)>,
+ 212 ddc::detail::mdspan_to_kokkos_layout_t<LayoutOut>,
+ 213 MemorySpace>
const out_view
+ 214 = out.allocation_kokkos_view();
+ 215 KokkosFFT::Normalization
const kokkos_fft_normalization
+ 216 = ddc_fft_normalization_to_kokkos_fft(kwargs.normalization);
+
+
+ 219 if constexpr (std::is_same_v<Tin, Tout>) {
+
+
+
+
+
+
+ 226 kokkos_fft_normalization);
+
+
+
+
+
+
+ 233 kokkos_fft_normalization);
+
+
+
+ 237 if constexpr (is_complex_v<Tout>) {
+ 238 assert(kwargs.direction == ddc::FFT_Direction::FORWARD);
+
+
+
+
+
+ 244 kokkos_fft_normalization);
+
+ 246 assert(kwargs.direction == ddc::FFT_Direction::BACKWARD);
+
+
+
+
+
+ 252 kokkos_fft_normalization);
+
+
+
+
+
+ 258 real_type_t<Tout> norm_coef;
+
+
+ 261 = (((coordinate(ddc::select<DDimIn>(in.domain()).back())
+ 262 - coordinate(ddc::select<DDimIn>(in.domain()).front()))
+ 263 / (ddc::get<DDimIn>(in.domain().extents()) - 1)
+ 264 / Kokkos::sqrt(2 * Kokkos::numbers::pi))
+
+
+
+ 268 = ((Kokkos::sqrt(2 * Kokkos::numbers::pi)
+ 269 / (coordinate(ddc::select<DDimOut>(out.domain()).back())
+ 270 - coordinate(ddc::select<DDimOut>(out.domain()).front()))
+ 271 * (ddc::get<DDimOut>(out.domain().extents()) - 1)
+ 272 / ddc::get<DDimOut>(out.domain().extents()))
+
+
+
+ 276 rescale(exec_space, out, norm_coef);
+
+
+
+
+
+
+
+
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303template <
typename DDimFx,
typename DDimX>
+
+
+
+
+ 308 is_uniform_point_sampling_v<DDimX>,
+ 309 "DDimX dimensions should derive from UniformPointSampling");
+
+ 311 is_periodic_sampling_v<DDimFx>,
+ 312 "DDimFx dimensions should derive from PeriodicSampling");
+ 313 auto [impl, ddom] = DDimFx::
template init<DDimFx>(
+ 314 ddc::Coordinate<
typename DDimFx::continuous_dimension_type>(0),
+ 315 ddc::Coordinate<
typename DDimFx::continuous_dimension_type>(
+ 316 2 * (
ddc::detail::fft::N<DDimX>(x_mesh) - 1)
+ 317 * (
ddc::detail::fft::N<DDimX>(x_mesh) - 1)
+ 318 /
static_cast<
double>(
+ 319 ddc::detail::fft::N<DDimX>(x_mesh)
+ 320 * (
ddc::coordinate(x_mesh.back()) -
ddc::coordinate(x_mesh.front())))
+ 321 * Kokkos::numbers::pi),
+
+
+ 324 return std::move(impl);
+
+
+
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342template <
typename... DDimFx,
typename... DDimX>
+
+
+
+ 346 (is_uniform_point_sampling_v<DDimX> && ...),
+ 347 "DDimX dimensions should derive from UniformPointSampling");
+
+ 349 (is_periodic_sampling_v<DDimFx> && ...),
+ 350 "DDimFx dimensions should derive from PeriodicPointSampling");
+
+ 352 ddc::DiscreteElement<DDimFx>(0),
+
+ 354 (C2C ?
ddc::detail::fft::N<DDimX>(x_mesh)
+ 355 :
ddc::detail::fft::LastSelector<
double, DDimX, DDimX...>(
+ 356 ddc::detail::fft::N<DDimX>(x_mesh) / 2 + 1,
+ 357 ddc::detail::fft::N<DDimX>(x_mesh)))))...);
+
+
+
+ 361
+ 362
+ 363
+ 364
+
+
+
+
+
+
+
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+
+
+
+
+
+
+ 398 typename MemorySpace,
+
+
+
+ 402 ExecSpace
const& exec_space,
+
+
+
+
- 408 Kokkos::SpaceAccessibility<ExecSpace, MemorySpace>::accessible,
- 409 "MemorySpace has to be accessible for ExecutionSpace.");
-
- 411 (is_uniform_point_sampling_v<DDimX> && ...),
- 412 "DDimX dimensions should derive from UniformPointSampling");
-
- 414 std::array<
int,
sizeof...(DDimX)> n = {
static_cast<
int>(
ddc::get<DDimX>(mesh.extents()))...};
-
-
- 417 for (std::size_t i = 0; i <
sizeof...(DDimX); ++i) {
- 418 idist = transform_type_v<Tin, Tout> == TransformType::C2R && i ==
sizeof...(DDimX) - 1
- 419 ? idist * (n[i] / 2 + 1)
-
- 421 odist = transform_type_v<Tin, Tout> == TransformType::R2C && i ==
sizeof...(DDimX) - 1
- 422 ? odist * (n[i] / 2 + 1)
-
-
-
-
- 427 if constexpr (std::is_same_v<ExecSpace, Kokkos::Serial>) {
- 428 _fftw_plan<Tin> plan = _fftw_plan_many_dft<Tin, Tout>(
-
-
- 431 static_cast<
int>(
sizeof...(DDimX)),
-
-
- 434 reinterpret_cast<
typename _fftw_type<Tin>::type*>(in_data),
- 435 static_cast<
int*>(
nullptr),
-
-
- 438 reinterpret_cast<
typename _fftw_type<Tout>::type*>(out_data),
- 439 static_cast<
int*>(
nullptr),
-
-
- 442 if constexpr (std::is_same_v<real_type_t<Tin>,
float>) {
-
- 444 fftwf_destroy_plan(plan);
-
-
- 447 fftw_destroy_plan(plan);
-
-
-
-
- 452 if constexpr (std::is_same_v<ExecSpace, Kokkos::OpenMP>) {
- 453 if constexpr (std::is_same_v<real_type_t<Tin>,
float>) {
- 454 fftwf_init_threads();
- 455 fftwf_plan_with_nthreads(exec_space.concurrency());
-
-
- 458 fftw_plan_with_nthreads(exec_space.concurrency());
-
- 460 _fftw_plan<Tin> plan = _fftw_plan_many_dft<Tin, Tout>(
- 461 kwargs.direction == ddc::FFT_Direction::FORWARD ? FFTW_FORWARD : FFTW_BACKWARD,
-
- 463 static_cast<
int>(
sizeof...(DDimX)),
-
-
- 466 reinterpret_cast<
typename _fftw_type<Tin>::type*>(in_data),
- 467 static_cast<
int*>(
nullptr),
-
-
- 470 reinterpret_cast<
typename _fftw_type<Tout>::type*>(out_data),
- 471 static_cast<
int*>(
nullptr),
-
-
- 474 if constexpr (std::is_same_v<real_type_t<Tin>,
float>) {
-
- 476 fftwf_destroy_plan(plan);
-
-
- 479 fftw_destroy_plan(plan);
-
-
-
-
- 484 if constexpr (std::is_same_v<ExecSpace, Kokkos::Cuda>) {
- 485 cudaStream_t stream = exec_space.cuda_stream();
-
- 487 cufftHandle unmanaged_plan = -1;
- 488 cufftResult cufft_rt = cufftCreate(&unmanaged_plan);
-
- 490 if (cufft_rt != CUFFT_SUCCESS)
- 491 throw std::runtime_error(
"cufftCreate failed");
-
- 493 std::unique_ptr<cufftHandle, std::function<
void(cufftHandle*)>>
const
- 494 managed_plan(&unmanaged_plan, [](cufftHandle* handle) { cufftDestroy(*handle); });
-
- 496 cufftSetStream(unmanaged_plan, stream);
- 497 cufft_rt = cufftPlanMany(
-
-
-
-
-
-
-
-
-
- 507 cufft_transform_type<Tin, Tout>(),
-
-
- 510 if (cufft_rt != CUFFT_SUCCESS)
- 511 throw std::runtime_error(
"cufftPlan failed");
-
- 513 cufft_rt = _cufftExec<Tin, Tout>(
- 514 kwargs.direction == ddc::FFT_Direction::FORWARD ? CUFFT_FORWARD : CUFFT_INVERSE,
-
- 516 reinterpret_cast<
typename _cufft_type<Tin>::type*>(in_data),
- 517 reinterpret_cast<
typename _cufft_type<Tout>::type*>(out_data));
- 518 if (cufft_rt != CUFFT_SUCCESS)
- 519 throw std::runtime_error(
"cufftExec failed");
-
-
-
- 523 if constexpr (std::is_same_v<ExecSpace, Kokkos::HIP>) {
- 524 hipStream_t stream = exec_space.hip_stream();
-
- 526 hipfftHandle unmanaged_plan;
- 527 hipfftResult hipfft_rt = hipfftCreate(&unmanaged_plan);
-
- 529 if (hipfft_rt != HIPFFT_SUCCESS)
- 530 throw std::runtime_error(
"hipfftCreate failed");
-
- 532 std::unique_ptr<hipfftHandle, std::function<
void(hipfftHandle*)>>
const
- 533 managed_plan(&unmanaged_plan, [](hipfftHandle* handle) { hipfftDestroy(*handle); });
-
- 535 hipfftSetStream(unmanaged_plan, stream);
- 536 hipfft_rt = hipfftPlanMany(
-
-
-
-
-
-
-
-
-
- 546 hipfft_transform_type<Tin, Tout>(),
-
-
- 549 if (hipfft_rt != HIPFFT_SUCCESS)
- 550 throw std::runtime_error(
"hipfftPlan failed");
-
- 552 hipfft_rt = _hipfftExec<Tin, Tout>(
- 553 kwargs.direction == ddc::FFT_Direction::FORWARD ? HIPFFT_FORWARD : HIPFFT_BACKWARD,
-
- 555 reinterpret_cast<
typename _hipfft_type<Tin>::type*>(in_data),
- 556 reinterpret_cast<
typename _hipfft_type<Tout>::type*>(out_data));
- 557 if (hipfft_rt != HIPFFT_SUCCESS)
- 558 throw std::runtime_error(
"hipfftExec failed");
-
-
-
-
- 563 real_type_t<Tout> norm_coef = 1;
-
-
- 566 norm_coef = 1. / (ddc::get<DDimX>(mesh.extents()) * ...);
-
-
-
- 570 norm_coef = 1. / (ddc::get<DDimX>(mesh.extents()) * ...);
-
-
- 573 norm_coef = 1. / Kokkos::sqrt((ddc::get<DDimX>(mesh.extents()) * ...));
-
-
-
- 577 = (((coordinate(ddc::select<DDimX>(mesh).back())
- 578 - coordinate(ddc::select<DDimX>(mesh).front()))
- 579 / (ddc::get<DDimX>(mesh.extents()) - 1)
- 580 / Kokkos::sqrt(2 * Kokkos::numbers::pi))
-
-
-
- 584 = ((Kokkos::sqrt(2 * Kokkos::numbers::pi)
- 585 / (coordinate(ddc::select<DDimX>(mesh).back())
- 586 - coordinate(ddc::select<DDimX>(mesh).front()))
- 587 * (ddc::get<DDimX>(mesh.extents()) - 1)
- 588 / ddc::get<DDimX>(mesh.extents()))
-
-
-
- 592 throw std::runtime_error(
"ddc::FFT_Normalization not handled");
-
-
- 595 Kokkos::parallel_for(
- 596 "ddc_fft_normalization",
- 597 Kokkos::RangePolicy<ExecSpace>(
-
-
- 600 is_complex_v<Tout> && transform_type_v<Tin, Tout> != TransformType::C2C
- 601 ? (LastSelector<
double, DDimX, DDimX...>(
- 602 ddc::get<DDimX>(mesh.extents()) / 2 + 1,
- 603 ddc::get<DDimX>(mesh.extents()))
-
- 605 : (ddc::get<DDimX>(mesh.extents()) * ...)),
- 606 KOKKOS_LAMBDA(
const int& i) { out_data[i] = out_data[i] * norm_coef; });
-
-
-
-
-
-
-
-
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633template <
typename DDimFx,
typename DDimX>
-
-
-
-
- 638 is_uniform_point_sampling_v<DDimX>,
- 639 "DDimX dimensions should derive from UniformPointSampling");
-
- 641 is_periodic_sampling_v<DDimFx>,
- 642 "DDimFx dimensions should derive from PeriodicSampling");
- 643 auto [impl, ddom] = DDimFx::
template init<DDimFx>(
- 644 ddc::Coordinate<
typename DDimFx::continuous_dimension_type>(0),
- 645 ddc::Coordinate<
typename DDimFx::continuous_dimension_type>(
- 646 2 * (
ddc::detail::fft::N<DDimX>(x_mesh) - 1)
- 647 * (
ddc::detail::fft::N<DDimX>(x_mesh) - 1)
- 648 /
static_cast<
double>(
- 649 ddc::detail::fft::N<DDimX>(x_mesh)
- 650 * (
ddc::coordinate(x_mesh.back()) -
ddc::coordinate(x_mesh.front())))
- 651 * Kokkos::numbers::pi),
-
-
- 654 return std::move(impl);
-
-
-
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672template <
typename... DDimFx,
typename... DDimX>
-
-
-
- 676 (is_uniform_point_sampling_v<DDimX> && ...),
- 677 "DDimX dimensions should derive from UniformPointSampling");
-
- 679 (is_periodic_sampling_v<DDimFx> && ...),
- 680 "DDimFx dimensions should derive from PeriodicPointSampling");
-
- 682 ddc::DiscreteElement<DDimFx>(0),
-
- 684 (C2C ?
ddc::detail::fft::N<DDimX>(x_mesh)
- 685 :
ddc::detail::fft::LastSelector<
double, DDimX, DDimX...>(
- 686 ddc::detail::fft::N<DDimX>(x_mesh) / 2 + 1,
- 687 ddc::detail::fft::N<DDimX>(x_mesh)))))...);
-
-
-
- 691
- 692
- 693
- 694
-
-
-
-
-
-
-
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
-
-
-
-
-
-
- 728 typename MemorySpace,
-
-
-
- 732 ExecSpace
const& exec_space,
-
-
-
-
-
- 738 std::is_same_v<LayoutIn, Kokkos::layout_right>
- 739 && std::is_same_v<LayoutOut, Kokkos::layout_right>,
- 740 "Layouts must be right-handed");
-
- 742 (is_uniform_point_sampling_v<DDimX> && ...),
- 743 "DDimX dimensions should derive from UniformPointSampling");
-
- 745 (is_periodic_sampling_v<DDimFx> && ...),
- 746 "DDimFx dimensions should derive from PeriodicPointSampling");
-
- 748 ddc::detail::fft::impl<Tin, Tout, ExecSpace, MemorySpace, DDimX...>(
-
-
-
-
-
-
-
-
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
-
-
-
-
-
-
- 785 typename MemorySpace,
-
-
-
- 789 ExecSpace
const& exec_space,
-
-
-
-
-
- 795 std::is_same_v<LayoutIn, Kokkos::layout_right>
- 796 && std::is_same_v<LayoutOut, Kokkos::layout_right>,
- 797 "Layouts must be right-handed");
-
- 799 (is_uniform_point_sampling_v<DDimX> && ...),
- 800 "DDimX dimensions should derive from UniformPointSampling");
-
- 802 (is_periodic_sampling_v<DDimFx> && ...),
- 803 "DDimFx dimensions should derive from PeriodicPointSampling");
-
- 805 ddc::detail::fft::impl<Tin, Tout, ExecSpace, MemorySpace, DDimX...>(
-
-
-
-
-
-
-
-
+ 408 std::is_same_v<LayoutIn, Kokkos::layout_right>
+ 409 && std::is_same_v<LayoutOut, Kokkos::layout_right>,
+ 410 "Layouts must be right-handed");
+
+ 412 (is_uniform_point_sampling_v<DDimX> && ...),
+ 413 "DDimX dimensions should derive from UniformPointSampling");
+
+ 415 (is_periodic_sampling_v<DDimFx> && ...),
+ 416 "DDimFx dimensions should derive from PeriodicPointSampling");
+
+
+
+
+
+
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+
+
+
+
+
+
+ 451 typename MemorySpace,
+
+
+
+ 455 ExecSpace
const& exec_space,
+
+
+
+
+
+ 461 std::is_same_v<LayoutIn, Kokkos::layout_right>
+ 462 && std::is_same_v<LayoutOut, Kokkos::layout_right>,
+ 463 "Layouts must be right-handed");
+
+ 465 (is_uniform_point_sampling_v<DDimX> && ...),
+ 466 "DDimX dimensions should derive from UniformPointSampling");
+
+ 468 (is_periodic_sampling_v<DDimFx> && ...),
+ 469 "DDimFx dimensions should derive from PeriodicPointSampling");
+
+
+
+
+
+
friend class DiscreteDomain
KOKKOS_FUNCTION constexpr bool operator!=(DiscreteVector< OTags... > const &rhs) const noexcept
The top-level namespace of DDC.
-ddc::FFT_Normalization normalization
Enum member to identify the type of normalization performed.
-void ifft(ExecSpace const &exec_space, ddc::ChunkSpan< Tout, ddc::DiscreteDomain< DDimX... >, LayoutOut, MemorySpace > out, ddc::ChunkSpan< Tin, ddc::DiscreteDomain< DDimFx... >, LayoutIn, MemorySpace > in, ddc::kwArgs_fft kwargs={ddc::FFT_Normalization::OFF})
Perform an inverse Fast Fourier Transform.
-void fft(ExecSpace const &exec_space, ddc::ChunkSpan< Tout, ddc::DiscreteDomain< DDimFx... >, LayoutOut, MemorySpace > out, ddc::ChunkSpan< Tin, ddc::DiscreteDomain< DDimX... >, LayoutIn, MemorySpace > in, ddc::kwArgs_fft kwargs={ddc::FFT_Normalization::OFF})
Perform a direct Fast Fourier Transform.
-ddc::DiscreteDomain< DDimFx... > FourierMesh(ddc::DiscreteDomain< DDimX... > x_mesh, bool C2C)
Get the Fourier mesh.
-FFT_Normalization
A named argument to choose the type of normalization of the FFT.
+ddc::FFT_Normalization normalization
Enum member to identify the type of normalization performed.
+void ifft(ExecSpace const &exec_space, ddc::ChunkSpan< Tout, ddc::DiscreteDomain< DDimX... >, LayoutOut, MemorySpace > out, ddc::ChunkSpan< Tin, ddc::DiscreteDomain< DDimFx... >, LayoutIn, MemorySpace > in, ddc::kwArgs_fft kwargs={ddc::FFT_Normalization::OFF})
Perform an inverse Fast Fourier Transform.
+void fft(ExecSpace const &exec_space, ddc::ChunkSpan< Tout, ddc::DiscreteDomain< DDimFx... >, LayoutOut, MemorySpace > out, ddc::ChunkSpan< Tin, ddc::DiscreteDomain< DDimX... >, LayoutIn, MemorySpace > in, ddc::kwArgs_fft kwargs={ddc::FFT_Normalization::OFF})
Perform a direct Fast Fourier Transform.
+ddc::DiscreteDomain< DDimFx... > FourierMesh(ddc::DiscreteDomain< DDimX... > x_mesh, bool C2C)
Get the Fourier mesh.
+FFT_Normalization
A named argument to choose the type of normalization of the FFT.
@ BACKWARD
No normalization for forward FFT, multiply by 1/N for backward FFT.
@ OFF
No normalization. Un-normalized FFT is sum_j f(x_j)*e^-ikx_j.
@ ORTHO
Multiply by 1/sqrt(N)
@ FULL
Multiply by dx/sqrt(2*pi) for forward FFT and dk/sqrt(2*pi) for backward FFT.
@ FORWARD
Multiply by 1/N for forward FFT, no normalization for backward FFT.
-DDimFx::template Impl< DDimFx, Kokkos::HostSpace > init_fourier_space(ddc::DiscreteDomain< DDimX > x_mesh)
Initialize a Fourier discrete dimension.
-FFT_Direction
A named argument to choose the direction of the FFT.
+DDimFx::template Impl< DDimFx, Kokkos::HostSpace > init_fourier_space(ddc::DiscreteDomain< DDimX > x_mesh)
Initialize a Fourier discrete dimension.
+FFT_Direction
A named argument to choose the direction of the FFT.
@ BACKWARD
Backward, corresponds to inverse FFT up to normalization.
@ FORWARD
Forward, corresponds to direct FFT up to normalization.
-A structure embedding the configuration of the exposed FFT function with the type of normalization.
+A structure embedding the configuration of the exposed FFT function with the type of normalization.
diff --git a/namespaceddc.html b/namespaceddc.html
index e4117355f..8a8bc7d14 100644
--- a/namespaceddc.html
+++ b/namespaceddc.html
@@ -624,7 +624,7 @@
| Initialize a Fourier discrete dimension.
|
|
template<typename... DDimFx, typename... DDimX> |
-ddc::DiscreteDomain< DDimFx... > | FourierMesh (ddc::DiscreteDomain< DDimX... > x_mesh, bool C2C) |
+ddc::DiscreteDomain< DDimFx... > | FourierMesh (ddc::DiscreteDomain< DDimX... > x_mesh, bool C2C) |
| Get the Fourier mesh.
|
|
template<typename Tin , typename Tout , typename... DDimFx, typename... DDimX, typename ExecSpace , typename MemorySpace , typename LayoutIn , typename LayoutOut > |
@@ -1165,7 +1165,7 @@