From 0022183fa6f479e52aea13e3efa255c11383b401 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Mon, 15 Apr 2024 17:54:20 +0900 Subject: [PATCH 1/6] Add shape getter in Plan class --- fft/src/KokkosFFT_Plans.hpp | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/fft/src/KokkosFFT_Plans.hpp b/fft/src/KokkosFFT_Plans.hpp index 1513901d..86e85129 100644 --- a/fft/src/KokkosFFT_Plans.hpp +++ b/fft/src/KokkosFFT_Plans.hpp @@ -286,22 +286,15 @@ class Plan { /// /// \param in [in] Input data /// \param out [in] Ouput data - /// \param direction [in] Direction of FFT (forward/backward) - /// \param axes [in] Axes over which FFT is performed - template - void good(const InViewType2& in, const OutViewType2& out, - KokkosFFT::Direction direction, axis_type axes) const { - static_assert(std::is_same_v, - "Plan::good: Execution spaces for plan and " - "execution are not identical."); + template + void good(const InViewType2& in, const OutViewType2& out) const { static_assert( Kokkos::SpaceAccessibility< - ExecutionSpace2, typename InViewType2::memory_space>::accessible, + ExecutionSpace, typename InViewType2::memory_space>::accessible, "Plan::good: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< - ExecutionSpace2, typename OutViewType2::memory_space>::accessible, + ExecutionSpace, typename OutViewType2::memory_space>::accessible, "Plan::good: execution_space cannot access data in OutViewType"); using nonConstInViewType2 = std::remove_cv_t; @@ -313,16 +306,21 @@ class Plan { "Plan::good: OutViewType for plan and " "execution are not identical."); - if (direction != m_direction) { + using in_value_type = typename InViewType2::non_const_value_type; + using out_value_type = typename OutViewType2::non_const_value_type; + + if (std::is_floating_point::value && + m_direction != KokkosFFT::Direction::forward) { throw std::runtime_error( - "Plan::good: directions for plan and execution are " - "not identical."); + "Plan::good: real to complex transform is constrcuted with backward " + "direction."); } - if (axes != m_axes) { + if (std::is_floating_point::value && + m_direction != KokkosFFT::Direction::backward) { throw std::runtime_error( - "Plan::good: axes for plan and execution are " - "not identical."); + "Plan::good: complex to real transform is constrcuted with forward " + "direction."); } auto in_extents = KokkosFFT::Impl::extract_extents(in); @@ -357,8 +355,6 @@ class Plan { extents_type shape() const { return m_shape; } map_type map() const { return m_map; } map_type map_inv() const { return m_map_inv; } - nonConstInViewType& in_T() { return m_in_T; } - nonConstOutViewType& out_T() { return m_out_T; } }; } // namespace Impl } // namespace KokkosFFT From bdb2ebf2bb2ab0240caefedaf15b7d669574ac4c Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Mon, 15 Apr 2024 17:55:01 +0900 Subject: [PATCH 2/6] Remove older APIs with plan as an argument --- fft/src/KokkosFFT_Transform.hpp | 1492 ++++--------------------------- 1 file changed, 186 insertions(+), 1306 deletions(-) diff --git a/fft/src/KokkosFFT_Transform.hpp b/fft/src/KokkosFFT_Transform.hpp index 90941878..2b5e8be3 100644 --- a/fft/src/KokkosFFT_Transform.hpp +++ b/fft/src/KokkosFFT_Transform.hpp @@ -43,35 +43,39 @@ // General Transform Interface namespace KokkosFFT { namespace Impl { + template -void _fft(const PlanType& plan, const InViewType& in, OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward) { +void exec_impl( + const PlanType& plan, const InViewType& in, OutViewType& out, + KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward) { static_assert(Kokkos::is_view::value, - "_fft: InViewType is not a Kokkos::View."); + "exec_impl: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, - "_fft: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "_fft: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "_fft: OutViewType must be either LayoutLeft or LayoutRight."); + "exec_impl: OutViewType is not a Kokkos::View."); + static_assert( + KokkosFFT::Impl::is_layout_left_or_right_v, + "exec_impl: InViewType must be either LayoutLeft or LayoutRight."); + static_assert( + KokkosFFT::Impl::is_layout_left_or_right_v, + "exec_impl: OutViewType must be either LayoutLeft or LayoutRight."); static_assert(InViewType::rank() == OutViewType::rank(), - "_fft: InViewType and OutViewType must have " + "exec_impl: InViewType and OutViewType must have " "the same rank."); static_assert(std::is_same_v, - "_fft: InViewType and OutViewType must have " + "exec_impl: InViewType and OutViewType must have " "the same Layout."); using ExecutionSpace = typename PlanType::execSpace; static_assert( Kokkos::SpaceAccessibility::accessible, - "_fft: execution_space cannot access data in InViewType"); + "exec_impl: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "_fft: execution_space cannot access data in OutViewType"); + "exec_impl: execution_space cannot access data in OutViewType"); using in_value_type = typename InViewType::non_const_value_type; using out_value_type = typename OutViewType::non_const_value_type; @@ -81,57 +85,50 @@ void _fft(const PlanType& plan, const InViewType& in, OutViewType& out, auto* odata = reinterpret_cast::type*>(out.data()); - auto const exec_space = plan.exec_space(); - auto const fft_direction = direction_type(plan.direction()); - KokkosFFT::Impl::_exec(plan.plan(), idata, odata, fft_direction, plan.info()); + auto const exec_space = plan.exec_space(); + auto const direction = direction_type(plan.direction()); + KokkosFFT::Impl::_exec(plan.plan(), idata, odata, direction, plan.info()); KokkosFFT::Impl::normalize(exec_space, out, plan.direction(), norm, plan.fft_size()); } -} // namespace Impl -} // namespace KokkosFFT - -namespace KokkosFFT { -/// \brief One dimensional FFT in forward direction -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param norm [in] How the normalization is applied (optional) -/// \param axis [in] Axis over which FFT is performed (optional) -/// \param n [in] Length of the transformed axis of the output (optional) -template -void fft(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - int axis = -1, std::optional n = std::nullopt) { +template +void fft_exec_impl( + const PlanType& plan, const InViewType& in, OutViewType& out, + // KokkosFFT::Direction direction, + KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward) { static_assert(Kokkos::is_view::value, - "fft: InViewType is not a Kokkos::View."); + "fft_exec_impl: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, - "fft: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fft: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fft: OutViewType must be either LayoutLeft or LayoutRight."); + "fft_exec_impl: OutViewType is not a Kokkos::View."); + static_assert( + KokkosFFT::Impl::is_layout_left_or_right_v, + "fft_exec_impl: InViewType must be either LayoutLeft or LayoutRight."); + static_assert( + KokkosFFT::Impl::is_layout_left_or_right_v, + "fft_exec_impl: OutViewType must be either LayoutLeft or LayoutRight."); + static_assert(InViewType::rank() == OutViewType::rank(), - "fft: InViewType and OutViewType must have " + "fft_exec_impl: InViewType and OutViewType must have " "the same rank."); static_assert(std::is_same_v, - "fft: InViewType and OutViewType must have " + "fft_exec_impl: InViewType and OutViewType must have " "the same Layout."); + using ExecutionSpace = typename PlanType::execSpace; static_assert( Kokkos::SpaceAccessibility::accessible, - "fft: execution_space cannot access data in InViewType"); + "fft_exec_impl: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "fft: execution_space cannot access data in OutViewType"); + "fft_exec_impl: execution_space cannot access data in OutViewType"); - KokkosFFT::Impl::Plan plan(exec_space, in, out, KokkosFFT::Direction::forward, - axis, n); + plan.template good(in, out); + + const auto exec_space = plan.exec_space(); InViewType _in; if (plan.is_crop_or_pad_needed()) { auto new_shape = plan.shape(); @@ -147,28 +144,30 @@ void fft(const ExecutionSpace& exec_space, const InViewType& in, KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); + KokkosFFT::Impl::exec_impl(plan, in_T, out_T, norm); KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); + KokkosFFT::Impl::exec_impl(plan, _in, out, norm); } } -/// \brief One dimensional FFT in forward direction with a given plan +} // namespace Impl +} // namespace KokkosFFT + +namespace KokkosFFT { +/// \brief One dimensional FFT in forward direction /// /// \param exec_space [in] Kokkos execution space /// \param in [in] Input data (complex) /// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for forward fft /// \param norm [in] How the normalization is applied (optional) /// \param axis [in] Axis over which FFT is performed (optional) /// \param n [in] Length of the transformed axis of the output (optional) -template +template void fft(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, + OutViewType& out, KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, int axis = -1, std::optional n = std::nullopt) { static_assert(Kokkos::is_view::value, @@ -196,31 +195,9 @@ void fft(const ExecutionSpace& exec_space, const InViewType& in, ExecutionSpace, typename OutViewType::memory_space>::accessible, "fft: execution_space cannot access data in OutViewType"); - plan.template good( - in, out, KokkosFFT::Direction::forward, axis_type<1>{axis}); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } + KokkosFFT::Impl::Plan plan(exec_space, in, out, KokkosFFT::Direction::forward, + axis, n); + KokkosFFT::Impl::fft_exec_impl(plan, in, out, norm); } /// \brief One dimensional FFT in backward direction @@ -263,96 +240,7 @@ void ifft(const ExecutionSpace& exec_space, const InViewType& in, KokkosFFT::Impl::Plan plan(exec_space, in, out, KokkosFFT::Direction::backward, axis, n); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief One dimensional FFT in backward direction with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for backward fft -/// \param norm [in] How the normalization is applied (optional) -/// \param axis [in] Axis over which FFT is performed (optional) -/// \param n [in] Length of the transformed axis of the output (optional) -template -void ifft(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - int axis = -1, std::optional n = std::nullopt) { - static_assert(Kokkos::is_view::value, - "ifft: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "ifft: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifft: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifft: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "ifft: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "ifft: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "ifft: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "ifft: execution_space cannot access data in OutViewType"); - - plan.template good( - in, out, KokkosFFT::Direction::backward, axis_type<1>{axis}); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } + KokkosFFT::Impl::fft_exec_impl(plan, in, out, norm); } /// \brief One dimensional FFT for real input @@ -404,57 +292,6 @@ void rfft(const ExecutionSpace& exec_space, const InViewType& in, fft(exec_space, in, out, norm, axis, n); } -/// \brief One dimensional FFT for real input with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (real) -/// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for forward fft -/// \param norm [in] How the normalization is applied (optional) -/// \param axis [in] Axis over which FFT is performed (optional) -/// \param n [in] Length of the transformed axis of the output (optional) -template -void rfft(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - int axis = -1, std::optional n = std::nullopt) { - static_assert(Kokkos::is_view::value, - "rfft: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "rfft: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfft: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfft: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "rfft: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "rfft: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "rfft: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "rfft: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - - static_assert(std::is_floating_point::value, - "rfft: InViewType must be real"); - static_assert(KokkosFFT::Impl::is_complex::value, - "rfft: OutViewType must be complex"); - - fft(exec_space, in, out, plan, norm, axis, n); -} - /// \brief Inverse of rfft /// /// \param exec_space [in] Kokkos execution space @@ -503,53 +340,6 @@ void irfft(const ExecutionSpace& exec_space, const InViewType& in, ifft(exec_space, in, out, norm, axis, n); } -/// \brief Inverse of rfft with a given -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (real) -/// \param plan [in] KokkosFFT Plan for irfft -/// \param norm [in] How the normalization is applied (optional) -/// \param axis [in] Axis over which FFT is performed (optional) -/// \param n [in] Length of the transformed axis of the output (optional) -template -void irfft(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - int axis = -1, std::optional n = std::nullopt) { - static_assert(Kokkos::is_view::value, - "irfft: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "irfft: OutViewType is not a Kokkos::View."); - static_assert(InViewType::rank() == OutViewType::rank(), - "irfft: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "irfft: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "irfft: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "irfft: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - - static_assert(KokkosFFT::Impl::is_complex::value, - "irfft: InViewType must be complex"); - static_assert(std::is_floating_point::value, - "irfft: OutViewType must be real"); - - ifft(exec_space, in, out, plan, norm, axis, n); -} - /// \brief One dimensional FFT of a signal that has Hermitian symmetry /// /// \param exec_space [in] Kokkos execution space @@ -606,78 +396,19 @@ void hfft(const ExecutionSpace& exec_space, const InViewType& in, irfft(exec_space, in_conj, out, new_norm, axis, n); } -/// \brief One dimensional FFT of a signal that has Hermitian symmetry with a -/// given plan +/// \brief Inverse of hfft /// /// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (real) -/// \param plan [in] KokkosFFT Plan for hfft +/// \param in [in] Input data (real) +/// \param out [out] Ouput data (complex) /// \param norm [in] How the normalization is applied (optional) /// \param axis [in] Axis over which FFT is performed (optional) /// \param n [in] Length of the transformed axis of the output (optional) -template -void hfft(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - int axis = -1, std::optional n = std::nullopt) { - static_assert(Kokkos::is_view::value, - "hfft: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "hfft: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "hfft: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "hfft: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "hfft: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "hfft: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "hfft: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "hfft: execution_space cannot access data in OutViewType"); - - // [TO DO] - // allow real type as input, need to obtain complex view type from in view - // type - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - static_assert(KokkosFFT::Impl::is_complex::value, - "hfft: InViewType must be complex"); - static_assert(std::is_floating_point::value, - "hfft: OutViewType must be real"); - auto new_norm = KokkosFFT::Impl::swap_direction(norm); - // using ComplexViewType = typename - // KokkosFFT::Impl::complex_view_type::type; - // ComplexViewType in_conj; - InViewType in_conj; - KokkosFFT::Impl::conjugate(exec_space, in, in_conj); - irfft(exec_space, in_conj, out, plan, new_norm, axis, n); -} - -/// \brief Inverse of hfft -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (real) -/// \param out [out] Ouput data (complex) -/// \param norm [in] How the normalization is applied (optional) -/// \param axis [in] Axis over which FFT is performed (optional) -/// \param n [in] Length of the transformed axis of the output (optional) -template -void ihfft(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - int axis = -1, std::optional n = std::nullopt) { +template +void ihfft(const ExecutionSpace& exec_space, const InViewType& in, + OutViewType& out, + KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, + int axis = -1, std::optional n = std::nullopt) { static_assert(Kokkos::is_view::value, "ihfft: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, @@ -717,60 +448,6 @@ void ihfft(const ExecutionSpace& exec_space, const InViewType& in, out = out_conj; } -/// \brief Inverse of hfft with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (real) -/// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for ihfft -/// \param norm [in] How the normalization is applied (optional) -/// \param axis [in] Axis over which FFT is performed (optional) -/// \param n [in] Length of the transformed axis of the output (optional) -template -void ihfft(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - int axis = -1, std::optional n = std::nullopt) { - static_assert(Kokkos::is_view::value, - "ihfft: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "ihfft: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ihfft: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ihfft: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "ihfft: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "ihfft: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "ihfft: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "ihfft: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - static_assert(std::is_floating_point::value, - "ihfft: InViewType must be real"); - static_assert(KokkosFFT::Impl::is_complex::value, - "ihfft: OutViewType must be complex"); - - auto new_norm = KokkosFFT::Impl::swap_direction(norm); - OutViewType out_conj; - rfft(exec_space, in, out, plan, new_norm, axis, n); - KokkosFFT::Impl::conjugate(exec_space, out, out_conj); - out = out_conj; -} - // 2D FFT /// \brief Two dimensional FFT in forward direction @@ -813,1101 +490,303 @@ void fft2(const ExecutionSpace& exec_space, const InViewType& in, KokkosFFT::Impl::Plan plan(exec_space, in, out, KokkosFFT::Direction::forward, axes, s); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief Two dimensional FFT in forward direction with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for fft2 -/// \param norm [in] How the normalization is applied (optional) -/// \param axes [in] Axes over which FFT is performed (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void fft2(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { - static_assert(Kokkos::is_view::value, - "fft2: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "fft2: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fft2: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fft2: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "fft2: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "fft2: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "fft2: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "fft2: execution_space cannot access data in OutViewType"); - - plan.template good( - in, out, KokkosFFT::Direction::forward, axes); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief Two dimensional FFT in backward direction -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param norm [in] How the normalization is applied (optional) -/// \param axes [in] Axes over which FFT is performed (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void ifft2(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { - static_assert(Kokkos::is_view::value, - "ifft2: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "ifft2: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifft2: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifft2: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "ifft2: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "ifft2: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "ifft2: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "ifft2: execution_space cannot access data in OutViewType"); - - KokkosFFT::Impl::Plan plan(exec_space, in, out, - KokkosFFT::Direction::backward, axes, s); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } + KokkosFFT::Impl::fft_exec_impl(plan, in, out, norm); } -/// \brief Two dimensional FFT in backward direction with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for ifft2 -/// \param norm [in] How the normalization is applied (optional) -/// \param axes [in] Axes over which FFT is performed (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void ifft2(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { - static_assert(Kokkos::is_view::value, - "ifft2: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "ifft2: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifft2: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifft2: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "ifft2: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "ifft2: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "ifft2: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "ifft2: execution_space cannot access data in OutViewType"); - - plan.template good( - in, out, KokkosFFT::Direction::backward, axes); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief Two dimensional FFT for real input -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (real) -/// \param out [out] Ouput data (complex) -/// \param norm [in] How the normalization is applied (optional) -/// \param axes [in] Axes over which FFT is performed (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void rfft2(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { - static_assert(Kokkos::is_view::value, - "rfft2: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "rfft2: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfft2: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfft2: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "rfft2: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "rfft2: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "rfft2: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "rfft2: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - - static_assert(std::is_floating_point::value, - "rfft2: InViewType must be real"); - static_assert(KokkosFFT::Impl::is_complex::value, - "rfft2: OutViewType must be complex"); - - fft2(exec_space, in, out, norm, axes, s); -} - -/// \brief Two dimensional FFT for real input with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (real) -/// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for ifft2 -/// \param norm [in] How the normalization is applied (optional) -/// \param axes [in] Axes over which FFT is performed (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void rfft2(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { - static_assert(Kokkos::is_view::value, - "rfft2: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "rfft2: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfft2: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfft2: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "rfft2: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "rfft2: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "rfft2: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "rfft2: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - - static_assert(std::is_floating_point::value, - "rfft2: InViewType must be real"); - static_assert(KokkosFFT::Impl::is_complex::value, - "rfft2: OutViewType must be complex"); - - fft2(exec_space, in, out, plan, norm, axes, s); -} - -/// \brief Inverse of rfft2 with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (real) -/// \param norm [in] How the normalization is applied (optional) -/// \param axes [in] Axes over which FFT is performed (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void irfft2(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { - static_assert(Kokkos::is_view::value, - "irfft2: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "irfft2: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "irfft2: InViewType must be either LayoutLeft or LayoutRight."); - static_assert( - KokkosFFT::Impl::is_layout_left_or_right_v, - "irfft2: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "irfft2: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "irfft2: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "irfft2: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "irfft2: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - - static_assert(KokkosFFT::Impl::is_complex::value, - "irfft2: InViewType must be complex"); - static_assert(std::is_floating_point::value, - "irfft2: OutViewType must be real"); - - ifft2(exec_space, in, out, norm, axes, s); -} - -/// \brief Inverse of rfft2 with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (real) -/// \param plan [in] KokkosFFT Plan for irfft2 -/// \param norm [in] How the normalization is applied (optional) -/// \param axes [in] Axes over which FFT is performed (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void irfft2(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { - static_assert(Kokkos::is_view::value, - "irfft2: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "irfft2: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "irfft2: InViewType must be either LayoutLeft or LayoutRight."); - static_assert( - KokkosFFT::Impl::is_layout_left_or_right_v, - "irfft2: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "irfft2: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "irfft2: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "irfft2: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "irfft2: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - - static_assert(KokkosFFT::Impl::is_complex::value, - "irfft2: InViewType must be complex"); - static_assert(std::is_floating_point::value, - "irfft2: OutViewType must be real"); - - ifft2(exec_space, in, out, plan, norm, axes, s); -} - -// ND FFT - -/// \brief N-dimensional FFT in forward direction -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void fftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { - static_assert(Kokkos::is_view::value, - "fftn: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "fftn: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fftn: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fftn: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "fftn: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "fftn: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "fftn: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "fftn: execution_space cannot access data in OutViewType"); - - // Create a default sequence of axes {-rank, -(rank-1), ..., -1} - constexpr std::size_t rank = InViewType::rank(); - constexpr int start = -static_cast(rank); - axis_type axes = KokkosFFT::Impl::index_sequence(start); - - InViewType _in; - shape_type zeros = {0}; // default shape means no crop or pad - if (s != zeros) { - auto modified_shape = KokkosFFT::Impl::get_modified_shape(in, s, axes); - if (KokkosFFT::Impl::is_crop_or_pad_needed(in, modified_shape)) { - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, modified_shape); - } else { - _in = in; - } - } else { - _in = in; - } - - KokkosFFT::Impl::Plan plan(exec_space, _in, out, - KokkosFFT::Direction::forward, axes); - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief N-dimensional FFT in forward direction with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param axes [in] Axes over which FFT is performed -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void fftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, axis_type axes, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { - static_assert(Kokkos::is_view::value, - "fftn: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "fftn: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fftn: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fftn: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "fftn: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "fftn: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "fftn: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "fftn: execution_space cannot access data in OutViewType"); - - KokkosFFT::Impl::Plan plan(exec_space, in, out, KokkosFFT::Direction::forward, - axes, s); - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief N-dimensional FFT in forward direction with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for fftn -/// \param axes [in] Axes over which FFT is performed -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void fftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, axis_type axes, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { - static_assert(Kokkos::is_view::value, - "fftn: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "fftn: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fftn: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "fftn: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "fftn: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "fftn: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "fftn: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "fftn: execution_space cannot access data in OutViewType"); - - plan.template good( - in, out, KokkosFFT::Direction::forward, axes); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief N-dimensional FFT in backward direction with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void ifftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { - static_assert(Kokkos::is_view::value, - "ifftn: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "ifftn: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifftn: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifftn: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "ifftn: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "ifftn: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "ifftn: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "ifftn: execution_space cannot access data in OutViewType"); - - // Create a default sequence of axes {-rank, -(rank-1), ..., -1} - constexpr std::size_t rank = InViewType::rank(); - constexpr int start = -static_cast(rank); - axis_type axes = KokkosFFT::Impl::index_sequence(start); - - InViewType _in; - shape_type zeros = {0}; // default shape means no crop or pad - if (s != zeros) { - auto modified_shape = KokkosFFT::Impl::get_modified_shape(in, s, axes); - if (KokkosFFT::Impl::is_crop_or_pad_needed(in, modified_shape)) { - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, modified_shape); - } else { - _in = in; - } - } else { - _in = in; - } - - KokkosFFT::Impl::Plan plan(exec_space, _in, out, - KokkosFFT::Direction::backward, axes); - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief N-dimensional FFT in backward direction with a given plan -/// -/// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (complex) -/// \param axes [in] Axes over which FFT is performed -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) -template -void ifftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, axis_type axes, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { - static_assert(Kokkos::is_view::value, - "ifftn: InViewType is not a Kokkos::View."); - static_assert(Kokkos::is_view::value, - "ifftn: OutViewType is not a Kokkos::View."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifftn: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifftn: OutViewType must be either LayoutLeft or LayoutRight."); - static_assert(InViewType::rank() == OutViewType::rank(), - "ifftn: InViewType and OutViewType must have " - "the same rank."); - static_assert(std::is_same_v, - "ifftn: InViewType and OutViewType must have " - "the same Layout."); - - static_assert( - Kokkos::SpaceAccessibility::accessible, - "ifftn: execution_space cannot access data in InViewType"); - static_assert( - Kokkos::SpaceAccessibility< - ExecutionSpace, typename OutViewType::memory_space>::accessible, - "ifftn: execution_space cannot access data in OutViewType"); - - KokkosFFT::Impl::Plan plan(exec_space, in, out, - KokkosFFT::Direction::backward, axes, s); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); - - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } -} - -/// \brief N-dimensional FFT in backward direction with a given plan +/// \brief Two dimensional FFT in backward direction /// /// \param exec_space [in] Kokkos execution space /// \param in [in] Input data (complex) /// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for ifftn -/// \param axes [in] Axes over which FFT is performed /// \param norm [in] How the normalization is applied (optional) +/// \param axes [in] Axes over which FFT is performed (optional) /// \param s [in] Shape of the transformed axis of the output (optional) -template -void ifftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, axis_type axes, +template +void ifft2(const ExecutionSpace& exec_space, const InViewType& in, + OutViewType& out, KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { + axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { static_assert(Kokkos::is_view::value, - "ifftn: InViewType is not a Kokkos::View."); + "ifft2: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, - "ifftn: OutViewType is not a Kokkos::View."); + "ifft2: OutViewType is not a Kokkos::View."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifftn: InViewType must be either LayoutLeft or LayoutRight."); + "ifft2: InViewType must be either LayoutLeft or LayoutRight."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "ifftn: OutViewType must be either LayoutLeft or LayoutRight."); + "ifft2: OutViewType must be either LayoutLeft or LayoutRight."); static_assert(InViewType::rank() == OutViewType::rank(), - "ifftn: InViewType and OutViewType must have " + "ifft2: InViewType and OutViewType must have " "the same rank."); static_assert(std::is_same_v, - "ifftn: InViewType and OutViewType must have " + "ifft2: InViewType and OutViewType must have " "the same Layout."); static_assert( Kokkos::SpaceAccessibility::accessible, - "ifftn: execution_space cannot access data in InViewType"); + "ifft2: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "ifftn: execution_space cannot access data in OutViewType"); - - plan.template good( - in, out, KokkosFFT::Direction::backward, axes); - - InViewType _in; - if (plan.is_crop_or_pad_needed()) { - auto new_shape = plan.shape(); - KokkosFFT::Impl::crop_or_pad(exec_space, in, _in, new_shape); - } else { - _in = in; - } - - if (plan.is_transpose_needed()) { - InViewType in_T; - OutViewType out_T; - - KokkosFFT::Impl::transpose(exec_space, _in, in_T, plan.map()); - KokkosFFT::Impl::transpose(exec_space, out, out_T, plan.map()); - - KokkosFFT::Impl::_fft(plan, in_T, out_T, norm); + "ifft2: execution_space cannot access data in OutViewType"); - KokkosFFT::Impl::transpose(exec_space, out_T, out, plan.map_inv()); - } else { - KokkosFFT::Impl::_fft(plan, _in, out, norm); - } + KokkosFFT::Impl::Plan plan(exec_space, in, out, + KokkosFFT::Direction::backward, axes, s); + KokkosFFT::Impl::fft_exec_impl(plan, in, out, norm); } -/// \brief N-dimensional FFT for real input with a given plan +/// \brief Two dimensional FFT for real input /// /// \param exec_space [in] Kokkos execution space /// \param in [in] Input data (real) /// \param out [out] Ouput data (complex) /// \param norm [in] How the normalization is applied (optional) +/// \param axes [in] Axes over which FFT is performed (optional) /// \param s [in] Shape of the transformed axis of the output (optional) -template -void rfftn(const ExecutionSpace& exec_space, const InViewType& in, +template +void rfft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { + axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { static_assert(Kokkos::is_view::value, - "rfftn: InViewType is not a Kokkos::View."); + "rfft2: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, - "rfftn: OutViewType is not a Kokkos::View."); + "rfft2: OutViewType is not a Kokkos::View."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfftn: InViewType must be either LayoutLeft or LayoutRight."); + "rfft2: InViewType must be either LayoutLeft or LayoutRight."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfftn: OutViewType must be either LayoutLeft or LayoutRight."); + "rfft2: OutViewType must be either LayoutLeft or LayoutRight."); static_assert(InViewType::rank() == OutViewType::rank(), - "rfftn: InViewType and OutViewType must have " + "rfft2: InViewType and OutViewType must have " "the same rank."); static_assert(std::is_same_v, - "rfftn: InViewType and OutViewType must have " + "rfft2: InViewType and OutViewType must have " "the same Layout."); static_assert( Kokkos::SpaceAccessibility::accessible, - "rfftn: execution_space cannot access data in InViewType"); + "rfft2: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "rfftn: execution_space cannot access data in OutViewType"); + "rfft2: execution_space cannot access data in OutViewType"); using in_value_type = typename InViewType::non_const_value_type; using out_value_type = typename OutViewType::non_const_value_type; static_assert(std::is_floating_point::value, - "rfftn: InViewType must be real"); + "rfft2: InViewType must be real"); static_assert(KokkosFFT::Impl::is_complex::value, - "rfftn: OutViewType must be complex"); + "rfft2: OutViewType must be complex"); - fftn(exec_space, in, out, norm, s); + fft2(exec_space, in, out, norm, axes, s); } -/// \brief N-dimensional FFT for real input with a given plan +/// \brief Inverse of rfft2 with a given plan /// /// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (real) -/// \param out [out] Ouput data (complex) -/// \param plan [in] KokkosFFT Plan for rfftn -/// \param axes [in] Axes over which FFT is performed +/// \param in [in] Input data (complex) +/// \param out [out] Ouput data (real) /// \param norm [in] How the normalization is applied (optional) +/// \param axes [in] Axes over which FFT is performed (optional) /// \param s [in] Shape of the transformed axis of the output (optional) -template -void rfftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, axis_type axes, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { +template +void irfft2(const ExecutionSpace& exec_space, const InViewType& in, + OutViewType& out, + KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, + axis_type<2> axes = {-2, -1}, shape_type<2> s = {0}) { static_assert(Kokkos::is_view::value, - "rfftn: InViewType is not a Kokkos::View."); + "irfft2: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, - "rfftn: OutViewType is not a Kokkos::View."); + "irfft2: OutViewType is not a Kokkos::View."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfftn: InViewType must be either LayoutLeft or LayoutRight."); - static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfftn: OutViewType must be either LayoutLeft or LayoutRight."); + "irfft2: InViewType must be either LayoutLeft or LayoutRight."); + static_assert( + KokkosFFT::Impl::is_layout_left_or_right_v, + "irfft2: OutViewType must be either LayoutLeft or LayoutRight."); static_assert(InViewType::rank() == OutViewType::rank(), - "rfftn: InViewType and OutViewType must have " + "irfft2: InViewType and OutViewType must have " "the same rank."); static_assert(std::is_same_v, - "rfftn: InViewType and OutViewType must have " + "irfft2: InViewType and OutViewType must have " "the same Layout."); static_assert( Kokkos::SpaceAccessibility::accessible, - "rfftn: execution_space cannot access data in InViewType"); + "irfft2: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "rfftn: execution_space cannot access data in OutViewType"); + "irfft2: execution_space cannot access data in OutViewType"); using in_value_type = typename InViewType::non_const_value_type; using out_value_type = typename OutViewType::non_const_value_type; - static_assert(std::is_floating_point::value, - "rfftn: InViewType must be real"); - static_assert(KokkosFFT::Impl::is_complex::value, - "rfftn: OutViewType must be complex"); + static_assert(KokkosFFT::Impl::is_complex::value, + "irfft2: InViewType must be complex"); + static_assert(std::is_floating_point::value, + "irfft2: OutViewType must be real"); - fftn(exec_space, in, out, plan, axes, norm, s); + ifft2(exec_space, in, out, norm, axes, s); } -/// \brief N-dimensional FFT for real input +// ND FFT + +/// \brief N-dimensional FFT in forward direction with a given plan /// /// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (real) +/// \param in [in] Input data (complex) /// \param out [out] Ouput data (complex) /// \param axes [in] Axes over which FFT is performed /// \param norm [in] How the normalization is applied (optional) /// \param s [in] Shape of the transformed axis of the output (optional) template -void rfftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, axis_type axes, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { +void fftn(const ExecutionSpace& exec_space, const InViewType& in, + OutViewType& out, axis_type axes, + KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, + shape_type s = {0}) { static_assert(Kokkos::is_view::value, - "rfftn: InViewType is not a Kokkos::View."); + "fftn: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, - "rfftn: OutViewType is not a Kokkos::View."); + "fftn: OutViewType is not a Kokkos::View."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfftn: InViewType must be either LayoutLeft or LayoutRight."); + "fftn: InViewType must be either LayoutLeft or LayoutRight."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "rfftn: OutViewType must be either LayoutLeft or LayoutRight."); + "fftn: OutViewType must be either LayoutLeft or LayoutRight."); static_assert(InViewType::rank() == OutViewType::rank(), - "rfftn: InViewType and OutViewType must have " + "fftn: InViewType and OutViewType must have " "the same rank."); static_assert(std::is_same_v, - "rfftn: InViewType and OutViewType must have " + "fftn: InViewType and OutViewType must have " "the same Layout."); static_assert( Kokkos::SpaceAccessibility::accessible, - "rfftn: execution_space cannot access data in InViewType"); + "fftn: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "rfftn: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - - static_assert(std::is_floating_point::value, - "rfftn: InViewType must be real"); - static_assert(KokkosFFT::Impl::is_complex::value, - "rfftn: OutViewType must be complex"); + "fftn: execution_space cannot access data in OutViewType"); - fftn(exec_space, in, out, axes, norm, s); + KokkosFFT::Impl::Plan plan(exec_space, in, out, KokkosFFT::Direction::forward, + axes, s); + KokkosFFT::Impl::fft_exec_impl(plan, in, out, norm); } -/// \brief Inverse of rfftn with a given plan +/// \brief N-dimensional FFT in backward direction with a given plan /// /// \param exec_space [in] Kokkos execution space /// \param in [in] Input data (complex) -/// \param out [out] Ouput data (real) +/// \param out [out] Ouput data (complex) +/// \param axes [in] Axes over which FFT is performed /// \param norm [in] How the normalization is applied (optional) /// \param s [in] Shape of the transformed axis of the output (optional) template -void irfftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { +void ifftn(const ExecutionSpace& exec_space, const InViewType& in, + OutViewType& out, axis_type axes, + KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, + shape_type s = {0}) { static_assert(Kokkos::is_view::value, - "irfftn: InViewType is not a Kokkos::View."); + "ifftn: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, - "irfftn: OutViewType is not a Kokkos::View."); + "ifftn: OutViewType is not a Kokkos::View."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "irfftn: InViewType must be either LayoutLeft or LayoutRight."); - static_assert( - KokkosFFT::Impl::is_layout_left_or_right_v, - "irfftn: OutViewType must be either LayoutLeft or LayoutRight."); + "ifftn: InViewType must be either LayoutLeft or LayoutRight."); + static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, + "ifftn: OutViewType must be either LayoutLeft or LayoutRight."); static_assert(InViewType::rank() == OutViewType::rank(), - "irfftn: InViewType and OutViewType must have " + "ifftn: InViewType and OutViewType must have " "the same rank."); static_assert(std::is_same_v, - "irfftn: InViewType and OutViewType must have " + "ifftn: InViewType and OutViewType must have " "the same Layout."); static_assert( Kokkos::SpaceAccessibility::accessible, - "irfftn: execution_space cannot access data in InViewType"); + "ifftn: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "irfftn: execution_space cannot access data in OutViewType"); - - using in_value_type = typename InViewType::non_const_value_type; - using out_value_type = typename OutViewType::non_const_value_type; - - static_assert(KokkosFFT::Impl::is_complex::value, - "irfftn: InViewType must be complex"); - static_assert(std::is_floating_point::value, - "irfftn: OutViewType must be real"); + "ifftn: execution_space cannot access data in OutViewType"); - ifftn(exec_space, in, out, norm, s); + KokkosFFT::Impl::Plan plan(exec_space, in, out, + KokkosFFT::Direction::backward, axes, s); + KokkosFFT::Impl::fft_exec_impl(plan, in, out, norm); } -/// \brief Inverse of rfftn +/// \brief N-dimensional FFT for real input /// /// \param exec_space [in] Kokkos execution space -/// \param in [in] Input data (complex) -/// \param out [out] Ouput data (real) +/// \param in [in] Input data (real) +/// \param out [out] Ouput data (complex) /// \param axes [in] Axes over which FFT is performed /// \param norm [in] How the normalization is applied (optional) /// \param s [in] Shape of the transformed axis of the output (optional) template -void irfftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, axis_type axes, - KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, - shape_type s = {0}) { +void rfftn(const ExecutionSpace& exec_space, const InViewType& in, + OutViewType& out, axis_type axes, + KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, + shape_type s = {0}) { static_assert(Kokkos::is_view::value, - "irfftn: InViewType is not a Kokkos::View."); + "rfftn: InViewType is not a Kokkos::View."); static_assert(Kokkos::is_view::value, - "irfftn: OutViewType is not a Kokkos::View."); + "rfftn: OutViewType is not a Kokkos::View."); static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, - "irfftn: InViewType must be either LayoutLeft or LayoutRight."); - static_assert( - KokkosFFT::Impl::is_layout_left_or_right_v, - "irfftn: OutViewType must be either LayoutLeft or LayoutRight."); + "rfftn: InViewType must be either LayoutLeft or LayoutRight."); + static_assert(KokkosFFT::Impl::is_layout_left_or_right_v, + "rfftn: OutViewType must be either LayoutLeft or LayoutRight."); static_assert(InViewType::rank() == OutViewType::rank(), - "irfftn: InViewType and OutViewType must have " + "rfftn: InViewType and OutViewType must have " "the same rank."); static_assert(std::is_same_v, - "irfftn: InViewType and OutViewType must have " + "rfftn: InViewType and OutViewType must have " "the same Layout."); static_assert( Kokkos::SpaceAccessibility::accessible, - "irfftn: execution_space cannot access data in InViewType"); + "rfftn: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "irfftn: execution_space cannot access data in OutViewType"); + "rfftn: execution_space cannot access data in OutViewType"); using in_value_type = typename InViewType::non_const_value_type; using out_value_type = typename OutViewType::non_const_value_type; - static_assert(KokkosFFT::Impl::is_complex::value, - "irfftn: InViewType must be complex"); - static_assert(std::is_floating_point::value, - "irfftn: OutViewType must be real"); + static_assert(std::is_floating_point::value, + "rfftn: InViewType must be real"); + static_assert(KokkosFFT::Impl::is_complex::value, + "rfftn: OutViewType must be complex"); - ifftn(exec_space, in, out, axes, norm, s); + fftn(exec_space, in, out, axes, norm, s); } -/// \brief Inverse of rfftn with a given plan +/// \brief Inverse of rfftn /// /// \param exec_space [in] Kokkos execution space /// \param in [in] Input data (complex) /// \param out [out] Ouput data (real) -/// \param plan [in] KokkosFFT Plan for irfftn /// \param axes [in] Axes over which FFT is performed /// \param norm [in] How the normalization is applied (optional) /// \param s [in] Shape of the transformed axis of the output (optional) template + std::size_t DIM = 1> void irfftn(const ExecutionSpace& exec_space, const InViewType& in, - OutViewType& out, const PlanType& plan, axis_type axes, + OutViewType& out, axis_type axes, KokkosFFT::Normalization norm = KokkosFFT::Normalization::backward, shape_type s = {0}) { static_assert(Kokkos::is_view::value, @@ -1930,11 +809,11 @@ void irfftn(const ExecutionSpace& exec_space, const InViewType& in, static_assert( Kokkos::SpaceAccessibility::accessible, - "ifftn: execution_space cannot access data in InViewType"); + "irfftn: execution_space cannot access data in InViewType"); static_assert( Kokkos::SpaceAccessibility< ExecutionSpace, typename OutViewType::memory_space>::accessible, - "ifftn: execution_space cannot access data in OutViewType"); + "irfftn: execution_space cannot access data in OutViewType"); using in_value_type = typename InViewType::non_const_value_type; using out_value_type = typename OutViewType::non_const_value_type; @@ -1944,8 +823,9 @@ void irfftn(const ExecutionSpace& exec_space, const InViewType& in, static_assert(std::is_floating_point::value, "irfftn: OutViewType must be real"); - ifftn(exec_space, in, out, plan, axes, norm, s); + ifftn(exec_space, in, out, axes, norm, s); } + } // namespace KokkosFFT #endif \ No newline at end of file From 4204a2fac8d33eb33971ea5633512d38843fc590 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Mon, 15 Apr 2024 17:55:47 +0900 Subject: [PATCH 3/6] Use new APIs to reuse plan in tests --- fft/unit_test/Test_Transform.cpp | 312 +++++++++++-------------------- 1 file changed, 107 insertions(+), 205 deletions(-) diff --git a/fft/unit_test/Test_Transform.cpp b/fft/unit_test/Test_Transform.cpp index d1f12234..834964c8 100644 --- a/fft/unit_test/Test_Transform.cpp +++ b/fft/unit_test/Test_Transform.cpp @@ -178,19 +178,19 @@ void test_fft1_identity_reuse_plan(T atol = 1.0e-12) { int axis = -1; KokkosFFT::Impl::Plan fft_plan(execution_space(), a, out, KokkosFFT::Direction::forward, axis); - KokkosFFT::fft(execution_space(), a, out, fft_plan); + KokkosFFT::Impl::fft_exec_impl(fft_plan, a, out); KokkosFFT::Impl::Plan ifft_plan(execution_space(), out, _a, KokkosFFT::Direction::backward, axis); - KokkosFFT::ifft(execution_space(), out, _a, ifft_plan); + KokkosFFT::Impl::fft_exec_impl(ifft_plan, out, _a); KokkosFFT::Impl::Plan rfft_plan(execution_space(), ar, outr, KokkosFFT::Direction::forward, axis); - KokkosFFT::rfft(execution_space(), ar, outr, rfft_plan); + KokkosFFT::Impl::fft_exec_impl(rfft_plan, ar, outr); KokkosFFT::Impl::Plan irfft_plan(execution_space(), outr, _ar, KokkosFFT::Direction::backward, axis); - KokkosFFT::irfft(execution_space(), outr, _ar, irfft_plan); + KokkosFFT::Impl::fft_exec_impl(irfft_plan, outr, _ar); EXPECT_TRUE(allclose(_a, a_ref, 1.e-5, atol)); EXPECT_TRUE(allclose(_ar, ar_ref, 1.e-5, atol)); @@ -223,52 +223,17 @@ void test_fft1_identity_reuse_plan(T atol = 1.0e-12) { KokkosFFT::Impl::Plan irfft_plan(execution_space(), outr, _ar, KokkosFFT::Direction::backward, axis); - // Check if errors are correctly raised aginst wrong axis - int wrong_axis = 0; - EXPECT_THROW(KokkosFFT::fft(execution_space(), a, out, fft_plan, - KokkosFFT::Normalization::backward, wrong_axis), - std::runtime_error); - - EXPECT_THROW(KokkosFFT::ifft(execution_space(), out, _a, ifft_plan, - KokkosFFT::Normalization::backward, wrong_axis), - std::runtime_error); - - EXPECT_THROW(KokkosFFT::rfft(execution_space(), ar, outr, rfft_plan, - KokkosFFT::Normalization::backward, wrong_axis), - std::runtime_error); - - EXPECT_THROW(KokkosFFT::irfft(execution_space(), outr, _ar, irfft_plan, - KokkosFFT::Normalization::backward, wrong_axis), - std::runtime_error); - // Check if errors are correctly raised aginst wrong dirction - KokkosFFT::Direction wrong_fft_direction = KokkosFFT::Direction::backward; - KokkosFFT::Impl::Plan wrong_fft_plan(execution_space(), a, out, - wrong_fft_direction, axis); - + KokkosFFT::Direction wrong_fft_direction = KokkosFFT::Direction::backward; KokkosFFT::Direction wrong_ifft_direction = KokkosFFT::Direction::forward; - KokkosFFT::Impl::Plan wrong_ifft_plan(execution_space(), out, _a, - wrong_ifft_direction, axis); - KokkosFFT::Impl::Plan wrong_rfft_plan(execution_space(), ar, outr, wrong_fft_direction, axis); KokkosFFT::Impl::Plan wrong_irfft_plan(execution_space(), outr, _ar, wrong_ifft_direction, axis); - EXPECT_THROW(KokkosFFT::fft(execution_space(), a, out, wrong_fft_plan, - KokkosFFT::Normalization::backward, axis), - std::runtime_error); - - EXPECT_THROW(KokkosFFT::ifft(execution_space(), out, _a, wrong_ifft_plan, - KokkosFFT::Normalization::backward, axis), - std::runtime_error); - - EXPECT_THROW(KokkosFFT::rfft(execution_space(), ar, outr, wrong_rfft_plan, - KokkosFFT::Normalization::backward, axis), + EXPECT_THROW(KokkosFFT::Impl::fft_exec_impl(wrong_rfft_plan, ar, outr), std::runtime_error); - - EXPECT_THROW(KokkosFFT::irfft(execution_space(), outr, _ar, wrong_irfft_plan, - KokkosFFT::Normalization::backward, axis), + EXPECT_THROW(KokkosFFT::Impl::fft_exec_impl(wrong_irfft_plan, outr, _ar), std::runtime_error); // Check if errors are correctly raised aginst wrong extents @@ -280,47 +245,53 @@ void test_fft1_identity_reuse_plan(T atol = 1.0e-12) { // fft // With incorrect input shape - EXPECT_THROW(KokkosFFT::fft(execution_space(), a_wrong, out, fft_plan, - KokkosFFT::Normalization::backward, axis), + EXPECT_THROW(KokkosFFT::Impl::fft_exec_impl( + fft_plan, a_wrong, out, KokkosFFT::Normalization::backward), std::runtime_error); // With incorrect output shape - EXPECT_THROW(KokkosFFT::fft(execution_space(), a, out_wrong, fft_plan, - KokkosFFT::Normalization::backward, axis), + EXPECT_THROW(KokkosFFT::Impl::fft_exec_impl( + fft_plan, a, out_wrong, KokkosFFT::Normalization::backward), std::runtime_error); // ifft // With incorrect input shape - EXPECT_THROW(KokkosFFT::ifft(execution_space(), out_wrong, _a, ifft_plan, - KokkosFFT::Normalization::backward, axis), - std::runtime_error); + EXPECT_THROW( + KokkosFFT::Impl::fft_exec_impl(ifft_plan, out_wrong, _a, + KokkosFFT::Normalization::backward), + std::runtime_error); // With incorrect output shape - EXPECT_THROW(KokkosFFT::ifft(execution_space(), out, _a_wrong, ifft_plan, - KokkosFFT::Normalization::backward, axis), - std::runtime_error); + EXPECT_THROW( + KokkosFFT::Impl::fft_exec_impl(ifft_plan, out, _a_wrong, + KokkosFFT::Normalization::backward), + std::runtime_error); // rfft // With incorrect input shape - EXPECT_THROW(KokkosFFT::rfft(execution_space(), ar_wrong, outr, rfft_plan, - KokkosFFT::Normalization::backward, axis), - std::runtime_error); + EXPECT_THROW( + KokkosFFT::Impl::fft_exec_impl(rfft_plan, ar_wrong, outr, + KokkosFFT::Normalization::backward), + std::runtime_error); // With incorrect output shape - EXPECT_THROW(KokkosFFT::rfft(execution_space(), ar, out_wrong, rfft_plan, - KokkosFFT::Normalization::backward, axis), - std::runtime_error); + EXPECT_THROW( + KokkosFFT::Impl::fft_exec_impl(rfft_plan, ar, out_wrong, + KokkosFFT::Normalization::backward), + std::runtime_error); // irfft // With incorrect input shape - EXPECT_THROW(KokkosFFT::irfft(execution_space(), outr_wrong, _ar, irfft_plan, - KokkosFFT::Normalization::backward, axis), - std::runtime_error); + EXPECT_THROW( + KokkosFFT::Impl::fft_exec_impl(irfft_plan, outr_wrong, _ar, + KokkosFFT::Normalization::backward), + std::runtime_error); // With incorrect output shape - EXPECT_THROW(KokkosFFT::irfft(execution_space(), outr, _ar_wrong, irfft_plan, - KokkosFFT::Normalization::backward, axis), - std::runtime_error); + EXPECT_THROW( + KokkosFFT::Impl::fft_exec_impl(irfft_plan, outr, _ar_wrong, + KokkosFFT::Normalization::backward), + std::runtime_error); } template @@ -457,34 +428,6 @@ void test_fft1_1dhfft_1dview() { EXPECT_TRUE(allclose(out_b, out, 1.e-5, 1.e-6)); EXPECT_TRUE(allclose(out_o, out, 1.e-5, 1.e-6)); EXPECT_TRUE(allclose(out_f, out, 1.e-5, 1.e-6)); - - // Reuse plans - int axis = -1; - - Kokkos::deep_copy(x_herm, x_herm_ref); - KokkosFFT::Impl::Plan hfft_plan(execution_space(), x_herm, out, - KokkosFFT::Direction::backward, axis); - KokkosFFT::hfft(execution_space(), x_herm, out, hfft_plan); - - Kokkos::deep_copy(x_herm, x_herm_ref); - KokkosFFT::hfft(execution_space(), x_herm, out_b, hfft_plan, - KokkosFFT::Normalization::backward); - - Kokkos::deep_copy(x_herm, x_herm_ref); - KokkosFFT::hfft(execution_space(), x_herm, out_o, hfft_plan, - KokkosFFT::Normalization::ortho); - - Kokkos::deep_copy(x_herm, x_herm_ref); - KokkosFFT::hfft(execution_space(), x_herm, out_f, hfft_plan, - KokkosFFT::Normalization::forward); - - multiply(out_o, sqrt(static_cast(len))); - multiply(out_f, static_cast(len)); - - EXPECT_TRUE(allclose(out, ref, 1.e-5, 1.e-6)); - EXPECT_TRUE(allclose(out_b, out, 1.e-5, 1.e-6)); - EXPECT_TRUE(allclose(out_o, out, 1.e-5, 1.e-6)); - EXPECT_TRUE(allclose(out_f, out, 1.e-5, 1.e-6)); } template @@ -545,42 +488,6 @@ void test_fft1_1dihfft_1dview() { EXPECT_TRUE(allclose(out2_b, x_herm_ref, 1.e-5, 1.e-6)); EXPECT_TRUE(allclose(out2_o, x_herm_ref, 1.e-5, 1.e-6)); EXPECT_TRUE(allclose(out2_f, x_herm_ref, 1.e-5, 1.e-6)); - - // Reuse plans - int axis = -1; - KokkosFFT::Impl::Plan hfft_plan(execution_space(), x_herm, out1, - KokkosFFT::Direction::backward, axis); - KokkosFFT::Impl::Plan ihfft_plan(execution_space(), out1, out2, - KokkosFFT::Direction::forward, axis); - - Kokkos::deep_copy(x_herm, x_herm_ref); - KokkosFFT::hfft(execution_space(), x_herm, out1, - hfft_plan); // default: KokkosFFT::Normalization::backward - KokkosFFT::ihfft(execution_space(), out1, out2, - ihfft_plan); // default: KokkosFFT::Normalization::backward - - Kokkos::deep_copy(x_herm, x_herm_ref); - KokkosFFT::hfft(execution_space(), x_herm, out1_b, hfft_plan, - KokkosFFT::Normalization::backward); - KokkosFFT::ihfft(execution_space(), out1_b, out2_b, ihfft_plan, - KokkosFFT::Normalization::backward); - - Kokkos::deep_copy(x_herm, x_herm_ref); - KokkosFFT::hfft(execution_space(), x_herm, out1_o, hfft_plan, - KokkosFFT::Normalization::ortho); - KokkosFFT::ihfft(execution_space(), out1_o, out2_o, ihfft_plan, - KokkosFFT::Normalization::ortho); - - Kokkos::deep_copy(x_herm, x_herm_ref); - KokkosFFT::hfft(execution_space(), x_herm, out1_f, hfft_plan, - KokkosFFT::Normalization::forward); - KokkosFFT::ihfft(execution_space(), out1_f, out2_f, ihfft_plan, - KokkosFFT::Normalization::forward); - - EXPECT_TRUE(allclose(out2, x_herm_ref, 1.e-5, 1.e-6)); - EXPECT_TRUE(allclose(out2_b, x_herm_ref, 1.e-5, 1.e-6)); - EXPECT_TRUE(allclose(out2_o, x_herm_ref, 1.e-5, 1.e-6)); - EXPECT_TRUE(allclose(out2_f, x_herm_ref, 1.e-5, 1.e-6)); } template @@ -1425,14 +1332,14 @@ void test_fft2_2dfft_2dview() { axes_type axes = {-2, -1}; KokkosFFT::Impl::Plan fft2_plan(execution_space(), x, out, KokkosFFT::Direction::forward, axes); - KokkosFFT::fft2(execution_space(), x, out, - fft2_plan); // default: KokkosFFT::Normalization::backward - KokkosFFT::fft2(execution_space(), x, out_b, fft2_plan, - KokkosFFT::Normalization::backward); - KokkosFFT::fft2(execution_space(), x, out_o, fft2_plan, - KokkosFFT::Normalization::ortho); - KokkosFFT::fft2(execution_space(), x, out_f, fft2_plan, - KokkosFFT::Normalization::forward); + + KokkosFFT::Impl::fft_exec_impl(fft2_plan, x, out); + KokkosFFT::Impl::fft_exec_impl(fft2_plan, x, out_b, + KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(fft2_plan, x, out_o, + KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(fft2_plan, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, sqrt(static_cast(n0 * n1))); multiply(out_f, static_cast(n0 * n1)); @@ -1467,12 +1374,13 @@ void test_fft2_2dfft_2dview() { // Reuse plans np.fft2(axes=(-1, -2)) KokkosFFT::Impl::Plan fft2_plan_axes10(execution_space(), x, out, KokkosFFT::Direction::forward, axes10); - KokkosFFT::fft2(execution_space(), x, out_b, fft2_plan_axes10, - KokkosFFT::Normalization::backward, axes10); - KokkosFFT::fft2(execution_space(), x, out_o, fft2_plan_axes10, - KokkosFFT::Normalization::ortho, axes10); - KokkosFFT::fft2(execution_space(), x, out_f, fft2_plan_axes10, - KokkosFFT::Normalization::forward, axes10); + + KokkosFFT::Impl::fft_exec_impl(fft2_plan_axes10, x, out_b, + KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(fft2_plan_axes10, x, out_o, + KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(fft2_plan_axes10, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, sqrt(static_cast(n0 * n1))); multiply(out_f, static_cast(n0 * n1)); @@ -1529,14 +1437,13 @@ void test_fft2_2difft_2dview() { KokkosFFT::Impl::Plan ifft2_plan(execution_space(), x, out, KokkosFFT::Direction::backward, axes); - KokkosFFT::ifft2(execution_space(), x, out, - ifft2_plan); // default: KokkosFFT::Normalization::backward - KokkosFFT::ifft2(execution_space(), x, out_b, ifft2_plan, - KokkosFFT::Normalization::backward); - KokkosFFT::ifft2(execution_space(), x, out_o, ifft2_plan, - KokkosFFT::Normalization::ortho); - KokkosFFT::ifft2(execution_space(), x, out_f, ifft2_plan, - KokkosFFT::Normalization::forward); + KokkosFFT::Impl::fft_exec_impl(ifft2_plan, x, out); + KokkosFFT::Impl::fft_exec_impl(ifft2_plan, x, out_b, + KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(ifft2_plan, x, out_o, + KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(ifft2_plan, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, 1.0 / sqrt(static_cast(n0 * n1))); multiply(out_f, 1.0 / static_cast(n0 * n1)); @@ -1570,12 +1477,12 @@ void test_fft2_2difft_2dview() { KokkosFFT::Impl::Plan ifft2_plan_axes10( execution_space(), x, out, KokkosFFT::Direction::backward, axes10); - KokkosFFT::ifft2(execution_space(), x, out_b, ifft2_plan_axes10, - KokkosFFT::Normalization::backward, axes10); - KokkosFFT::ifft2(execution_space(), x, out_o, ifft2_plan_axes10, - KokkosFFT::Normalization::ortho, axes10); - KokkosFFT::ifft2(execution_space(), x, out_f, ifft2_plan_axes10, - KokkosFFT::Normalization::forward, axes10); + KokkosFFT::Impl::fft_exec_impl(ifft2_plan_axes10, x, out_b, + KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(ifft2_plan_axes10, x, out_o, + KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(ifft2_plan_axes10, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, 1.0 / sqrt(static_cast(n0 * n1))); multiply(out_f, 1.0 / static_cast(n0 * n1)); @@ -1640,20 +1547,19 @@ void test_fft2_2drfft_2dview() { KokkosFFT::Direction::forward, axes); Kokkos::deep_copy(x, x_ref); - KokkosFFT::rfft2(execution_space(), x, out, - rfft2_plan); // default: KokkosFFT::Normalization::backward + KokkosFFT::Impl::fft_exec_impl(rfft2_plan, x, out); Kokkos::deep_copy(x, x_ref); - KokkosFFT::rfft2(execution_space(), x, out_b, rfft2_plan, - KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(rfft2_plan, x, out_b, + KokkosFFT::Normalization::backward); Kokkos::deep_copy(x, x_ref); - KokkosFFT::rfft2(execution_space(), x, out_o, rfft2_plan, - KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(rfft2_plan, x, out_o, + KokkosFFT::Normalization::ortho); Kokkos::deep_copy(x, x_ref); - KokkosFFT::rfft2(execution_space(), x, out_f, rfft2_plan, - KokkosFFT::Normalization::forward); + KokkosFFT::Impl::fft_exec_impl(rfft2_plan, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, sqrt(static_cast(n0 * n1))); multiply(out_f, static_cast(n0 * n1)); @@ -1719,21 +1625,20 @@ void test_fft2_2dirfft_2dview() { KokkosFFT::Direction::backward, axes); Kokkos::deep_copy(x, x_ref); - KokkosFFT::irfft2( - execution_space(), x, out, - irfft2_plan); // default: KokkosFFT::Normalization::backward + KokkosFFT::Impl::fft_exec_impl( + irfft2_plan, x, out); // default: KokkosFFT::Normalization::backward Kokkos::deep_copy(x, x_ref); - KokkosFFT::irfft2(execution_space(), x, out_b, irfft2_plan, - KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(irfft2_plan, x, out_b, + KokkosFFT::Normalization::backward); Kokkos::deep_copy(x, x_ref); - KokkosFFT::irfft2(execution_space(), x, out_o, irfft2_plan, - KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(irfft2_plan, x, out_o, + KokkosFFT::Normalization::ortho); Kokkos::deep_copy(x, x_ref); - KokkosFFT::irfft2(execution_space(), x, out_f, irfft2_plan, - KokkosFFT::Normalization::forward); + KokkosFFT::Impl::fft_exec_impl(irfft2_plan, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, 1.0 / sqrt(static_cast(n0 * n1))); multiply(out_f, 1.0 / static_cast(n0 * n1)); @@ -2449,14 +2354,13 @@ void test_fftn_2dfft_2dview() { KokkosFFT::Impl::Plan fftn_plan(execution_space(), x, out, KokkosFFT::Direction::forward, axes); - KokkosFFT::fftn(execution_space(), x, out, fftn_plan, - axes); // default: KokkosFFT::Normalization::backward - KokkosFFT::fftn(execution_space(), x, out_b, fftn_plan, axes, - KokkosFFT::Normalization::backward); - KokkosFFT::fftn(execution_space(), x, out_o, fftn_plan, axes, - KokkosFFT::Normalization::ortho); - KokkosFFT::fftn(execution_space(), x, out_f, fftn_plan, axes, - KokkosFFT::Normalization::forward); + KokkosFFT::Impl::fft_exec_impl(fftn_plan, x, out); + KokkosFFT::Impl::fft_exec_impl(fftn_plan, x, out_b, + KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(fftn_plan, x, out_o, + KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(fftn_plan, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, sqrt(static_cast(n0 * n1))); multiply(out_f, static_cast(n0 * n1)); @@ -2514,14 +2418,14 @@ void test_ifftn_2dfft_2dview() { // Reuse plans KokkosFFT::Impl::Plan ifftn_plan(execution_space(), x, out, KokkosFFT::Direction::backward, axes); - KokkosFFT::ifftn(execution_space(), x, out, ifftn_plan, - axes); // default: KokkosFFT::Normalization::backward - KokkosFFT::ifftn(execution_space(), x, out_b, ifftn_plan, axes, - KokkosFFT::Normalization::backward); - KokkosFFT::ifftn(execution_space(), x, out_o, ifftn_plan, axes, - KokkosFFT::Normalization::ortho); - KokkosFFT::ifftn(execution_space(), x, out_f, ifftn_plan, axes, - KokkosFFT::Normalization::forward); + + KokkosFFT::Impl::fft_exec_impl(ifftn_plan, x, out); + KokkosFFT::Impl::fft_exec_impl(ifftn_plan, x, out_b, + KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(ifftn_plan, x, out_o, + KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(ifftn_plan, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, 1.0 / sqrt(static_cast(n0 * n1))); multiply(out_f, 1.0 / static_cast(n0 * n1)); @@ -2587,20 +2491,19 @@ void test_rfftn_2dfft_2dview() { KokkosFFT::Direction::forward, axes); Kokkos::deep_copy(x, x_ref); - KokkosFFT::rfftn(execution_space(), x, out, rfftn_plan, - axes); // default: KokkosFFT::Normalization::backward + KokkosFFT::Impl::fft_exec_impl(rfftn_plan, x, out); Kokkos::deep_copy(x, x_ref); - KokkosFFT::rfftn(execution_space(), x, out_b, rfftn_plan, axes, - KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(rfftn_plan, x, out_b, + KokkosFFT::Normalization::backward); Kokkos::deep_copy(x, x_ref); - KokkosFFT::rfftn(execution_space(), x, out_o, rfftn_plan, axes, - KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(rfftn_plan, x, out_o, + KokkosFFT::Normalization::ortho); Kokkos::deep_copy(x, x_ref); - KokkosFFT::rfftn(execution_space(), x, out_f, rfftn_plan, axes, - KokkosFFT::Normalization::forward); + KokkosFFT::Impl::fft_exec_impl(rfftn_plan, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, sqrt(static_cast(n0 * n1))); multiply(out_f, static_cast(n0 * n1)); @@ -2666,20 +2569,19 @@ void test_irfftn_2dfft_2dview() { KokkosFFT::Impl::Plan irfftn_plan(execution_space(), x, out, KokkosFFT::Direction::backward, axes); Kokkos::deep_copy(x, x_ref); - KokkosFFT::irfftn(execution_space(), x, out, irfftn_plan, - axes); // default: KokkosFFT::Normalization::backward + KokkosFFT::Impl::fft_exec_impl(irfftn_plan, x, out); Kokkos::deep_copy(x, x_ref); - KokkosFFT::irfftn(execution_space(), x, out_b, irfftn_plan, axes, - KokkosFFT::Normalization::backward); + KokkosFFT::Impl::fft_exec_impl(irfftn_plan, x, out_b, + KokkosFFT::Normalization::backward); Kokkos::deep_copy(x, x_ref); - KokkosFFT::irfftn(execution_space(), x, out_o, irfftn_plan, axes, - KokkosFFT::Normalization::ortho); + KokkosFFT::Impl::fft_exec_impl(irfftn_plan, x, out_o, + KokkosFFT::Normalization::ortho); Kokkos::deep_copy(x, x_ref); - KokkosFFT::irfftn(execution_space(), x, out_f, irfftn_plan, axes, - KokkosFFT::Normalization::forward); + KokkosFFT::Impl::fft_exec_impl(irfftn_plan, x, out_f, + KokkosFFT::Normalization::forward); multiply(out_o, 1.0 / sqrt(static_cast(n0 * n1))); multiply(out_f, 1.0 / static_cast(n0 * n1)); From a6a8cc4832ff2f21a664eb4be0b111244fe6713d Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Mon, 15 Apr 2024 17:56:01 +0900 Subject: [PATCH 4/6] Use new APIs to reuse plan in example --- .../06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp b/examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp index 674aac46..ddc2ff09 100644 --- a/examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp +++ b/examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp @@ -30,12 +30,14 @@ int main(int argc, char* argv[]) { int axis = -1; KokkosFFT::Impl::Plan fft_plan(exec, xc2c, xc2c_hat, KokkosFFT::Direction::forward, axis); - KokkosFFT::fft(exec, xc2c, xc2c_hat, fft_plan); + // KokkosFFT::fft(exec, xc2c, xc2c_hat, fft_plan); + KokkosFFT::Impl::fft_exec_impl(fft_plan, xc2c, xc2c_hat); exec.fence(); KokkosFFT::Impl::Plan ifft_plan(exec, xc2c_hat, xc2c_inv, KokkosFFT::Direction::backward, axis); - KokkosFFT::ifft(exec, xc2c_hat, xc2c_inv, ifft_plan); + // KokkosFFT::ifft(exec, xc2c_hat, xc2c_inv, ifft_plan); + KokkosFFT::Impl::fft_exec_impl(ifft_plan, xc2c_hat, xc2c_inv); exec.fence(); // 1D R2C FFT @@ -46,7 +48,8 @@ int main(int argc, char* argv[]) { KokkosFFT::Impl::Plan rfft_plan(exec, xr2c, xr2c_hat, KokkosFFT::Direction::forward, axis); - KokkosFFT::rfft(exec, xr2c, xr2c_hat, rfft_plan); + // KokkosFFT::rfft(exec, xr2c, xr2c_hat, rfft_plan); + KokkosFFT::Impl::fft_exec_impl(rfft_plan, xr2c, xr2c_hat); exec.fence(); // 1D C2R FFT @@ -57,7 +60,8 @@ int main(int argc, char* argv[]) { KokkosFFT::Impl::Plan irfft_plan(exec, xc2r, xc2r_hat, KokkosFFT::Direction::backward, axis); - KokkosFFT::irfft(exec, xc2r, xc2r_hat, irfft_plan); + // KokkosFFT::irfft(exec, xc2r, xc2r_hat, irfft_plan); + KokkosFFT::Impl::fft_exec_impl(irfft_plan, xc2r, xc2r_hat); exec.fence(); } Kokkos::finalize(); From 7148151a1341247dcece315d2e0a8d3e47ad4c25 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Mon, 15 Apr 2024 18:02:52 +0900 Subject: [PATCH 5/6] Remove cunused linesfrom an example --- examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp b/examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp index ddc2ff09..a8d06cb3 100644 --- a/examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp +++ b/examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp @@ -30,13 +30,11 @@ int main(int argc, char* argv[]) { int axis = -1; KokkosFFT::Impl::Plan fft_plan(exec, xc2c, xc2c_hat, KokkosFFT::Direction::forward, axis); - // KokkosFFT::fft(exec, xc2c, xc2c_hat, fft_plan); KokkosFFT::Impl::fft_exec_impl(fft_plan, xc2c, xc2c_hat); exec.fence(); KokkosFFT::Impl::Plan ifft_plan(exec, xc2c_hat, xc2c_inv, KokkosFFT::Direction::backward, axis); - // KokkosFFT::ifft(exec, xc2c_hat, xc2c_inv, ifft_plan); KokkosFFT::Impl::fft_exec_impl(ifft_plan, xc2c_hat, xc2c_inv); exec.fence(); @@ -48,7 +46,6 @@ int main(int argc, char* argv[]) { KokkosFFT::Impl::Plan rfft_plan(exec, xr2c, xr2c_hat, KokkosFFT::Direction::forward, axis); - // KokkosFFT::rfft(exec, xr2c, xr2c_hat, rfft_plan); KokkosFFT::Impl::fft_exec_impl(rfft_plan, xr2c, xr2c_hat); exec.fence(); @@ -60,7 +57,6 @@ int main(int argc, char* argv[]) { KokkosFFT::Impl::Plan irfft_plan(exec, xc2r, xc2r_hat, KokkosFFT::Direction::backward, axis); - // KokkosFFT::irfft(exec, xc2r, xc2r_hat, irfft_plan); KokkosFFT::Impl::fft_exec_impl(irfft_plan, xc2r, xc2r_hat); exec.fence(); } From e03c547b8c54d99fdb365d68eec455cb58df382c Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Mon, 15 Apr 2024 18:09:29 +0900 Subject: [PATCH 6/6] Update docs for api since we have removed overloads with a plan argument --- docs/api/hermitian/hfft.rst | 1 - docs/api/hermitian/ihfft.rst | 1 - docs/api/real/irfft.rst | 3 +-- docs/api/real/irfft2.rst | 3 +-- docs/api/real/irfftn.rst | 5 ++--- docs/api/real/rfft.rst | 3 +-- docs/api/real/rfft2.rst | 3 +-- docs/api/real/rfftn.rst | 3 +-- docs/api/standard/fft.rst | 3 +-- docs/api/standard/fft2.rst | 3 +-- docs/api/standard/fftn.rst | 4 +--- docs/api/standard/ifft.rst | 3 +-- docs/api/standard/ifft2.rst | 1 - docs/api/standard/ifftn.rst | 4 +--- 14 files changed, 12 insertions(+), 28 deletions(-) diff --git a/docs/api/hermitian/hfft.rst b/docs/api/hermitian/hfft.rst index fd6a31c9..1c2663fc 100644 --- a/docs/api/hermitian/hfft.rst +++ b/docs/api/hermitian/hfft.rst @@ -6,4 +6,3 @@ KokkosFFT::hfft --------------- .. doxygenfunction:: KokkosFFT::hfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) -.. doxygenfunction:: KokkosFFT::hfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization, int axis, std::optional n) diff --git a/docs/api/hermitian/ihfft.rst b/docs/api/hermitian/ihfft.rst index ab159ed5..4adecc24 100644 --- a/docs/api/hermitian/ihfft.rst +++ b/docs/api/hermitian/ihfft.rst @@ -6,4 +6,3 @@ KokkosFFT::ihfft ---------------- .. doxygenfunction:: KokkosFFT::ihfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) -.. doxygenfunction:: KokkosFFT::ihfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization, int axis, std::optional n) diff --git a/docs/api/real/irfft.rst b/docs/api/real/irfft.rst index 6105edc5..d490a7e4 100644 --- a/docs/api/real/irfft.rst +++ b/docs/api/real/irfft.rst @@ -5,5 +5,4 @@ KokkosFFT::irfft ---------------- -.. doxygenfunction:: KokkosFFT::irfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) -.. doxygenfunction:: KokkosFFT::irfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization, int axis, std::optional n) \ No newline at end of file +.. doxygenfunction:: KokkosFFT::irfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) \ No newline at end of file diff --git a/docs/api/real/irfft2.rst b/docs/api/real/irfft2.rst index f0bc1b35..63f21598 100644 --- a/docs/api/real/irfft2.rst +++ b/docs/api/real/irfft2.rst @@ -4,5 +4,4 @@ KokkosFFT::irfft2 ----------------- -.. doxygenfunction:: KokkosFFT::irfft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, axis_type<2> axes, shape_type s) -.. doxygenfunction:: KokkosFFT::irfft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization norm, axis_type<2> axes, shape_type s) +.. doxygenfunction:: KokkosFFT::irfft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, axis_type<2> axes, shape_type<2> s) diff --git a/docs/api/real/irfftn.rst b/docs/api/real/irfftn.rst index af36985f..f01b5931 100644 --- a/docs/api/real/irfftn.rst +++ b/docs/api/real/irfftn.rst @@ -4,7 +4,6 @@ KokkosFFT::irfftn ----------------- -.. doxygenfunction:: KokkosFFT::irfftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, shape_type s) -.. doxygenfunction:: KokkosFFT::irfftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, axis_type axes, KokkosFFT::Normalization, shape_type s) -.. doxygenfunction:: KokkosFFT::irfftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, axis_type axes, KokkosFFT::Normalization norm, shape_type s) + +.. doxygenfunction:: KokkosFFT::irfftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, axis_type axes, KokkosFFT::Normalization, shape_type s) \ No newline at end of file diff --git a/docs/api/real/rfft.rst b/docs/api/real/rfft.rst index 056d230f..c365a730 100644 --- a/docs/api/real/rfft.rst +++ b/docs/api/real/rfft.rst @@ -5,5 +5,4 @@ KokkosFFT::rfft --------------- -.. doxygenfunction:: KokkosFFT::rfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) -.. doxygenfunction:: KokkosFFT::rfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization, int axis, std::optional n) \ No newline at end of file +.. doxygenfunction:: KokkosFFT::rfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) \ No newline at end of file diff --git a/docs/api/real/rfft2.rst b/docs/api/real/rfft2.rst index 5cb64454..77f40c7c 100644 --- a/docs/api/real/rfft2.rst +++ b/docs/api/real/rfft2.rst @@ -5,5 +5,4 @@ KokkosFFT::rfft2 ---------------- -.. doxygenfunction:: KokkosFFT::rfft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, axis_type<2> axes, shape_type s) -.. doxygenfunction:: KokkosFFT::rfft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization norm, axis_type<2> axes, shape_type s) \ No newline at end of file +.. doxygenfunction:: KokkosFFT::rfft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, axis_type<2> axes, shape_type<2> s) \ No newline at end of file diff --git a/docs/api/real/rfftn.rst b/docs/api/real/rfftn.rst index 0c5776af..1d4ba83f 100644 --- a/docs/api/real/rfftn.rst +++ b/docs/api/real/rfftn.rst @@ -4,6 +4,5 @@ KokkosFFT::rfftn ---------------- -.. doxygenfunction:: KokkosFFT::rfftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, shape_type s) + .. doxygenfunction:: KokkosFFT::rfftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, axis_type axes, KokkosFFT::Normalization, shape_type s) -.. doxygenfunction:: KokkosFFT::rfftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, axis_type axes, KokkosFFT::Normalization norm, shape_type s) diff --git a/docs/api/standard/fft.rst b/docs/api/standard/fft.rst index 1f9387a8..5d8b29a4 100644 --- a/docs/api/standard/fft.rst +++ b/docs/api/standard/fft.rst @@ -5,5 +5,4 @@ KokkosFFT::fft -------------- -.. doxygenfunction:: KokkosFFT::fft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) -.. doxygenfunction:: KokkosFFT::fft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization norm, int axis, std::optional n) \ No newline at end of file +.. doxygenfunction:: KokkosFFT::fft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) \ No newline at end of file diff --git a/docs/api/standard/fft2.rst b/docs/api/standard/fft2.rst index 8dcc895e..dd767faf 100644 --- a/docs/api/standard/fft2.rst +++ b/docs/api/standard/fft2.rst @@ -5,5 +5,4 @@ KokkosFFT::fft2 --------------- -.. doxygenfunction:: KokkosFFT::fft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, axis_type<2> axes, shape_type s) -.. doxygenfunction:: KokkosFFT::fft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization norm, axis_type<2> axes, shape_type s) \ No newline at end of file +.. doxygenfunction:: KokkosFFT::fft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, axis_type<2> axes, shape_type<2> s) \ No newline at end of file diff --git a/docs/api/standard/fftn.rst b/docs/api/standard/fftn.rst index 9e4db111..7052392e 100644 --- a/docs/api/standard/fftn.rst +++ b/docs/api/standard/fftn.rst @@ -5,6 +5,4 @@ KokkosFFT::fftn --------------- -.. doxygenfunction:: KokkosFFT::fftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, shape_type s) -.. doxygenfunction:: KokkosFFT::fftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, axis_type axes, KokkosFFT::Normalization, shape_type s) -.. doxygenfunction:: KokkosFFT::fftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, axis_type axes, KokkosFFT::Normalization norm, shape_type s) \ No newline at end of file +.. doxygenfunction:: KokkosFFT::fftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, axis_type axes, KokkosFFT::Normalization, shape_type s) \ No newline at end of file diff --git a/docs/api/standard/ifft.rst b/docs/api/standard/ifft.rst index 2395677f..c826a0b5 100644 --- a/docs/api/standard/ifft.rst +++ b/docs/api/standard/ifft.rst @@ -5,5 +5,4 @@ KokkosFFT::ifft --------------- -.. doxygenfunction:: KokkosFFT::ifft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) -.. doxygenfunction:: KokkosFFT::ifft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization, int axis, std::optional n) \ No newline at end of file +.. doxygenfunction:: KokkosFFT::ifft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, int axis, std::optional n) \ No newline at end of file diff --git a/docs/api/standard/ifft2.rst b/docs/api/standard/ifft2.rst index 1c4f2f41..e52c2334 100644 --- a/docs/api/standard/ifft2.rst +++ b/docs/api/standard/ifft2.rst @@ -6,4 +6,3 @@ KokkosFFT::ifft2 ---------------- .. doxygenfunction:: KokkosFFT::ifft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, axis_type<2> axes, shape_type s) -.. doxygenfunction:: KokkosFFT::ifft2(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, KokkosFFT::Normalization norm, axis_type<2> axes, shape_type s) diff --git a/docs/api/standard/ifftn.rst b/docs/api/standard/ifftn.rst index d7fcc22d..8b64b947 100644 --- a/docs/api/standard/ifftn.rst +++ b/docs/api/standard/ifftn.rst @@ -5,6 +5,4 @@ KokkosFFT::ifftn ---------------- -.. doxygenfunction:: KokkosFFT::ifftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, KokkosFFT::Normalization, shape_type s) -.. doxygenfunction:: KokkosFFT::ifftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, axis_type axes, KokkosFFT::Normalization, shape_type s) -.. doxygenfunction:: KokkosFFT::ifftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, const PlanType& plan, axis_type axes, KokkosFFT::Normalization norm, shape_type s) \ No newline at end of file +.. doxygenfunction:: KokkosFFT::ifftn(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, axis_type axes, KokkosFFT::Normalization, shape_type s) \ No newline at end of file