From 93d0b77d9ed4b3aec03578d6f03d86f42c6aca4d Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Tue, 1 Oct 2024 19:24:25 +0900 Subject: [PATCH 01/10] docs: Add default explanations for APIs --- common/src/KokkosFFT_Helpers.hpp | 8 +-- fft/src/KokkosFFT_Plans.hpp | 7 +-- fft/src/KokkosFFT_Transform.hpp | 90 +++++++++++++++++--------------- 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/common/src/KokkosFFT_Helpers.hpp b/common/src/KokkosFFT_Helpers.hpp index 91012d36..576f549e 100644 --- a/common/src/KokkosFFT_Helpers.hpp +++ b/common/src/KokkosFFT_Helpers.hpp @@ -151,7 +151,7 @@ namespace KokkosFFT { /// /// \param exec_space [in] Kokkos execution space /// \param n [in] Window length -/// \param d [in] Sample spacing +/// \param d [in] Sample spacing (default, 1) /// /// \return Sampling frequency template @@ -186,7 +186,7 @@ auto fftfreq(const ExecutionSpace&, const std::size_t n, /// /// \param exec_space [in] Kokkos execution space /// \param n [in] Window length -/// \param d [in] Sample spacing +/// \param d [in] Sample spacing (default, 1) /// /// \return Sampling frequency starting from zero template @@ -215,7 +215,7 @@ auto rfftfreq(const ExecutionSpace&, const std::size_t n, /// /// \param exec_space [in] Kokkos execution space /// \param inout [in,out] Spectrum -/// \param axes [in] Axes over which to shift, optional +/// \param axes [in] Axes over which to shift (default, nullopt) template void fftshift(const ExecutionSpace& exec_space, ViewType& inout, std::optional axes = std::nullopt) { @@ -264,7 +264,7 @@ void fftshift(const ExecutionSpace& exec_space, ViewType& inout, /// /// \param exec_space [in] Kokkos execution space /// \param inout [in,out] Spectrum -/// \param axes [in] Axes over which to shift, optional +/// \param axes [in] Axes over which to shift (default, nullopt) template void ifftshift(const ExecutionSpace& exec_space, ViewType& inout, std::optional axes = std::nullopt) { diff --git a/fft/src/KokkosFFT_Plans.hpp b/fft/src/KokkosFFT_Plans.hpp index eebc022d..05758499 100644 --- a/fft/src/KokkosFFT_Plans.hpp +++ b/fft/src/KokkosFFT_Plans.hpp @@ -153,7 +153,8 @@ class Plan { /// \param out [in] Ouput data /// \param direction [in] Direction of FFT (forward/backward) /// \param axis [in] Axis over which FFT is performed - /// \param n [in] Length of the transformed axis of the output (optional) + /// \param n [in] Length of the transformed axis of the output (default, + /// nullopt) // explicit Plan(const ExecutionSpace& exec_space, InViewType& in, OutViewType& out, KokkosFFT::Direction direction, int axis, @@ -211,11 +212,11 @@ class Plan { /// \param out [in] Ouput data /// \param direction [in] Direction of FFT (forward/backward) /// \param axes [in] Axes over which FFT is performed - /// \param s [in] Shape of the transformed axis of the output (optional) + /// \param s [in] Shape of the transformed axis of the output (default, {}) // explicit Plan(const ExecutionSpace& exec_space, InViewType& in, OutViewType& out, KokkosFFT::Direction direction, - axis_type axes, shape_type s = {0}) + axis_type axes, shape_type s = {}) : m_exec_space(exec_space), m_axes(axes), m_direction(direction) { static_assert(KokkosFFT::Impl::is_AllowedSpace_v, "Plan::Plan: ExecutionSpace is not allowed "); diff --git a/fft/src/KokkosFFT_Transform.hpp b/fft/src/KokkosFFT_Transform.hpp index 490e3d7d..7b9028ce 100644 --- a/fft/src/KokkosFFT_Transform.hpp +++ b/fft/src/KokkosFFT_Transform.hpp @@ -123,9 +123,10 @@ namespace KokkosFFT { /// \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) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axis [in] Axis over which FFT is performed (default, -1) +/// \param n [in] Length of the transformed axis of the output (default, +/// nullopt) template void fft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, @@ -152,9 +153,10 @@ void fft(const ExecutionSpace& exec_space, const InViewType& in, /// \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) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axis [in] Axis over which FFT is performed (default, -1) +/// \param n [in] Length of the transformed axis of the output (default, +/// nullopt) template void ifft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, @@ -181,9 +183,10 @@ void ifft(const ExecutionSpace& exec_space, const InViewType& in, /// \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) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axis [in] Axis over which FFT is performed (default, -1) +/// \param n [in] Length of the transformed axis of the output (default, +/// nullopt) template void rfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, @@ -216,9 +219,10 @@ void rfft(const ExecutionSpace& exec_space, const InViewType& in, /// \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 axis [in] Axis over which FFT is performed (optional) -/// \param n [in] Length of the transformed axis of the output (optional) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axis [in] Axis over which FFT is performed (default, -1) +/// \param n [in] Length of the transformed axis of the output (default, +/// nullopt) template void irfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, @@ -252,9 +256,10 @@ void irfft(const ExecutionSpace& exec_space, const InViewType& in, /// \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 axis [in] Axis over which FFT is performed (optional) -/// \param n [in] Length of the transformed axis of the output (optional) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axis [in] Axis over which FFT is performed (default, -1) +/// \param n [in] Length of the transformed axis of the output (default, +/// nullopt) template void hfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, @@ -295,9 +300,10 @@ void hfft(const ExecutionSpace& exec_space, const InViewType& in, /// \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) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axis [in] Axis over which FFT is performed (default, -1) +/// \param n [in] Length of the transformed axis of the output (default, +/// nullopt) template void ihfft(const ExecutionSpace& exec_space, const InViewType& in, OutViewType& out, @@ -336,14 +342,14 @@ void ihfft(const ExecutionSpace& exec_space, const InViewType& in, /// \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) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axes [in] Axes over which FFT is performed (default, {-2, -1}) +/// \param s [in] Shape of the transformed axis of the output (default, {}) template void fft2(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}) { + axis_type<2> axes = {-2, -1}, shape_type<2> s = {}) { static_assert( KokkosFFT::Impl::are_operatable_views_v, @@ -365,14 +371,14 @@ void fft2(const ExecutionSpace& exec_space, const InViewType& in, /// \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) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axes [in] Axes over which FFT is performed (default, {-2, -1}) +/// \param s [in] Shape of the transformed axis of the output (default, {}) 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}) { + axis_type<2> axes = {-2, -1}, shape_type<2> s = {}) { static_assert( KokkosFFT::Impl::are_operatable_views_v, @@ -395,14 +401,14 @@ void ifft2(const ExecutionSpace& exec_space, const InViewType& in, /// \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) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axes [in] Axes over which FFT is performed (default, {-2, -1}) +/// \param s [in] Shape of the transformed axis of the output (default, {}) 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}) { + axis_type<2> axes = {-2, -1}, shape_type<2> s = {}) { static_assert( KokkosFFT::Impl::are_operatable_views_v, @@ -431,14 +437,14 @@ void rfft2(const ExecutionSpace& exec_space, const InViewType& in, /// \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) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param axes [in] Axes over which FFT is performed (default, {-2, -1}) +/// \param s [in] Shape of the transformed axis of the output (default, {}) 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}) { + axis_type<2> axes = {-2, -1}, shape_type<2> s = {}) { static_assert( KokkosFFT::Impl::are_operatable_views_v, @@ -470,8 +476,8 @@ void irfft2(const ExecutionSpace& exec_space, const InViewType& in, /// \param in [in] Input data (complex) /// \param out [out] Ouput data (complex) /// \param axes [in] Axes over which FFT is performed (default, all axes) -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param s [in] Shape of the transformed axis of the output (default, {}) #if defined(DOXY) template @@ -510,8 +516,8 @@ void fftn( /// \param in [in] Input data (complex) /// \param out [out] Ouput data (complex) /// \param axes [in] Axes over which FFT is performed (default, all axes) -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param s [in] Shape of the transformed axis of the output (default, {}) #if defined(DOXY) template @@ -552,8 +558,8 @@ void ifftn( /// \param in [in] Input data (real) /// \param out [out] Ouput data (complex) /// \param axes [in] Axes over which FFT is performed (default, all axes) -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param s [in] Shape of the transformed axis of the output (default, {}) #if defined(DOXY) template @@ -600,8 +606,8 @@ void rfftn( /// \param in [in] Input data (complex) /// \param out [out] Ouput data (real) /// \param axes [in] Axes over which FFT is performed (default, all axes) -/// \param norm [in] How the normalization is applied (optional) -/// \param s [in] Shape of the transformed axis of the output (optional) +/// \param norm [in] How the normalization is applied (default, backward) +/// \param s [in] Shape of the transformed axis of the output (default, {}) #if defined(DOXY) template From 7b8ad7680cac96401eead1a01a80aec57fd982b8 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Tue, 1 Oct 2024 19:27:37 +0900 Subject: [PATCH 02/10] Add docs for unmanaged view example --- docs/examples.rst | 5 +++-- docs/samples/07_unmanaged_views.rst | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 docs/samples/07_unmanaged_views.rst diff --git a/docs/examples.rst b/docs/examples.rst index 21ca75bb..f6cc304d 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -9,7 +9,7 @@ Examples There are some `examples `_ in the -Kokkos-fft repository. Each example includes Kokkos and numpy implementations. +Kokkos-fft repository. Most of the examples include Kokkos and numpy implementations. For example, `01_1DFFT `_ includes, @@ -32,4 +32,5 @@ Please find the examples from following links. samples/03_NDFFT.rst samples/04_batchedFFT.rst samples/05_1DFFT_HOST_DEVICE.rst - samples/06_1DFFT_reuse_plans.rst \ No newline at end of file + samples/06_1DFFT_reuse_plans.rst + samples/07_unmanaged_views.rst \ No newline at end of file diff --git a/docs/samples/07_unmanaged_views.rst b/docs/samples/07_unmanaged_views.rst new file mode 100644 index 00000000..09db80fd --- /dev/null +++ b/docs/samples/07_unmanaged_views.rst @@ -0,0 +1,14 @@ +.. SPDX-FileCopyrightText: (C) The Kokkos-FFT development team, see COPYRIGHT.md file +.. +.. SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception + +.. _07_unmanaged_views: + +Reuse FFT plan +============== + +KokkosFFT +--------- + +.. literalinclude:: ../../examples/07_unmanaged_views/07_unmanaged_views.cpp + :language: C++ From 74beb8292ef447c6c666a1eec14d9eb754ab8071 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Tue, 1 Oct 2024 21:25:25 +0900 Subject: [PATCH 03/10] docs: Explain the meanings of axes --- docs/intro/using.rst | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/intro/using.rst b/docs/intro/using.rst index b8f669d3..44e6aec2 100644 --- a/docs/intro/using.rst +++ b/docs/intro/using.rst @@ -34,7 +34,7 @@ If the rank of Views is higher than the dimension of FFT, a batched FFT plan is APIs start from ``i`` represent inverse transforms. For Real FFTs, users have to pay attention to the input and output data types as well as their extents. Inconsistent data types are suppressed by compilation errors. If extents are inconsistent, -it will raise runtime errors (C++ exceptions or assertions). +it will raise runtime errors (C++ ``std::runtime_error``). The following listing shows good and bad examples of Real FFTs. .. code-block:: C++ @@ -130,3 +130,43 @@ In some backend, FFT plan creation leads to some overhead, wherein we need this .. note:: Input and Output Views used to call FFT APIs must have the same types and extents as the ones used for plan creation. + +Axes parameters +--------------- + +As well as ``numpy.fft``, you can specify negative axes to perform FFT over chosen axes, which is not common in C++. +Actually for FFT APIs, default axes are set as ``{-DIM, -(DIM-1), ...}`` where ``DIM`` is the rank of the FFT dimensions, +corresponding to the FFTs over last ``DIM`` axes. For example, ``KokkosFFT::fft2(execution_space(), in, out)`` is equivalent to ``KokkosFFT::fft2(execution_space(), in, out, axis_type<2>({-2, -1}))``. +Negative axes are counted from the last axis, which is the same as ``numpy.fft``. +For example, ``-1`` means the last axis, ``-2`` means the second last axis, and so on. +Negative axes ``-1`` and ``-2`` respectively correspond to ``rank-1`` and ``rank-2``, where the ``rank`` is the rank of the Views. + +The following listing shows examples of axes parameters with negative or positive values. + +.. code-block:: C++ + + template using View2D = Kokkos::View; + template using View3D = Kokkos::View; + constexpr int n0 = 4, n1 = 8, n2 = 5; + + View2D x2("x2", n0, n1); + View3D x3("x3", n0, n1, n2); + View2D > x2_hat("x2_hat", n0/2+1, n1); + View3D > x3_hat("x3_hat", n0, n1/2+1, n2); + + // Follwoing codes are all equivalent to np.fft(np.rfft(axis=0), axis=1) + KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{-1, -2}); + KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{-1, 0}); + KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{1, -2}); + KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{1, 0}); + + // Follwoing codes are all equivalent to np.fft(np.rfft(axis=1), axis=2) + KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{-1, -2}); + KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{-1, 1}); + KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{2, -2}); + KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{2, 1}); + +.. note:: + + If you rely on negative axes, the corresponding positve axes are different depending on the rank of Views. + Thus, it is recommended to use negative axes for simplicity. From 3cc0c1102da6cdb2f10dc55505bd0ce06f6fc46b Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Tue, 1 Oct 2024 21:27:12 +0900 Subject: [PATCH 04/10] docs: we do not rely on assertions any more --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b5dab8e7..6bf68c7d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception > EXPERIMENTAL FFT interfaces for Kokkos C++ Performance Portability Programming EcoSystem Kokkos-fft implements local interfaces between [Kokkos](https://github.com/kokkos/kokkos) and de facto standard FFT libraries, including [fftw](http://www.fftw.org), [cufft](https://developer.nvidia.com/cufft), [hipfft](https://github.com/ROCm/hipFFT) ([rocfft](https://github.com/ROCm/rocFFT)), and [oneMKL](https://spec.oneapi.io/versions/latest/elements/oneMKL/source/index.html). "Local" means not using MPI, or running within a single MPI process without knowing about MPI. We are inclined to implement the [numpy.fft](https://numpy.org/doc/stable/reference/routines.fft.html)-like interfaces adapted for [Kokkos](https://github.com/kokkos/kokkos). -A key concept is that **"As easy as numpy, as fast as vendor libraries"**. Accordingly, our API follows the API by [numpy.fft](https://numpy.org/doc/stable/reference/routines.fft.html) with minor differences. A fft library dedicated to Kokkos Device backend (e.g. [cufft](https://developer.nvidia.com/cufft) for CUDA backend) is automatically used. If something is wrong with runtime values (say `View` extents), it will raise runtime errors (C++ exceptions or assertions). See [documentations](https://kokkosfft.readthedocs.io/) for more information. +A key concept is that **"As easy as numpy, as fast as vendor libraries"**. Accordingly, our API follows the API by [numpy.fft](https://numpy.org/doc/stable/reference/routines.fft.html) with minor differences. A fft library dedicated to Kokkos Device backend (e.g. [cufft](https://developer.nvidia.com/cufft) for CUDA backend) is automatically used. If something is wrong with runtime values (say `View` extents), it will raise runtime errors (C++ `std::runtime_error`). See [documentations](https://kokkosfft.readthedocs.io/) for more information. Here is an example for 1D real to complex transform with `rfft` in Kokkos-fft. ```C++ From 8d7db179dfd9d5e5dcca02186e6cb971eb894ad5 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Tue, 1 Oct 2024 23:16:45 +0900 Subject: [PATCH 05/10] docs: fix based on a review --- docs/intro/using.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/intro/using.rst b/docs/intro/using.rst index 44e6aec2..0055d32f 100644 --- a/docs/intro/using.rst +++ b/docs/intro/using.rst @@ -154,13 +154,13 @@ The following listing shows examples of axes parameters with negative or positiv View2D > x2_hat("x2_hat", n0/2+1, n1); View3D > x3_hat("x3_hat", n0, n1/2+1, n2); - // Follwoing codes are all equivalent to np.fft(np.rfft(axis=0), axis=1) + // Following codes are all equivalent to np.fft(np.rfft(axis=0), axis=1) KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{-1, -2}); KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{-1, 0}); KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{1, -2}); KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{1, 0}); - // Follwoing codes are all equivalent to np.fft(np.rfft(axis=1), axis=2) + // Following codes are all equivalent to np.fft(np.rfft(axis=1), axis=2) KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{-1, -2}); KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{-1, 1}); KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{2, -2}); From fad531f5ba12cb7a55239c714811cc40e580f646 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Tue, 1 Oct 2024 23:20:45 +0900 Subject: [PATCH 06/10] docs: fix title for unmanaged view example --- docs/samples/07_unmanaged_views.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/samples/07_unmanaged_views.rst b/docs/samples/07_unmanaged_views.rst index 09db80fd..5c63c110 100644 --- a/docs/samples/07_unmanaged_views.rst +++ b/docs/samples/07_unmanaged_views.rst @@ -4,8 +4,8 @@ .. _07_unmanaged_views: -Reuse FFT plan -============== +Using Unmanaged Views +===================== KokkosFFT --------- From 0c51afbd7d70e40e91596af3a5ac7499d4454b71 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Fri, 4 Oct 2024 21:29:15 +0900 Subject: [PATCH 07/10] fix: docs of fftshift based on reviews --- common/src/KokkosFFT_Helpers.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/src/KokkosFFT_Helpers.hpp b/common/src/KokkosFFT_Helpers.hpp index 576f549e..d44aa48c 100644 --- a/common/src/KokkosFFT_Helpers.hpp +++ b/common/src/KokkosFFT_Helpers.hpp @@ -215,7 +215,8 @@ auto rfftfreq(const ExecutionSpace&, const std::size_t n, /// /// \param exec_space [in] Kokkos execution space /// \param inout [in,out] Spectrum -/// \param axes [in] Axes over which to shift (default, nullopt) +/// \param axes [in] Axes over which to shift (default: nullopt, shifting over +/// all axes) template void fftshift(const ExecutionSpace& exec_space, ViewType& inout, std::optional axes = std::nullopt) { @@ -264,7 +265,8 @@ void fftshift(const ExecutionSpace& exec_space, ViewType& inout, /// /// \param exec_space [in] Kokkos execution space /// \param inout [in,out] Spectrum -/// \param axes [in] Axes over which to shift (default, nullopt) +/// \param axes [in] Axes over which to shift (default: nullopt, shifting over +/// all axes) template void ifftshift(const ExecutionSpace& exec_space, ViewType& inout, std::optional axes = std::nullopt) { From 56c7e16e67a306bb13186c4a4e0e7771cc3feaaf Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Fri, 4 Oct 2024 21:46:44 +0900 Subject: [PATCH 08/10] docs: improve the explanations for axes parameters --- docs/intro/using.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/intro/using.rst b/docs/intro/using.rst index 0055d32f..71350ff6 100644 --- a/docs/intro/using.rst +++ b/docs/intro/using.rst @@ -136,7 +136,8 @@ Axes parameters As well as ``numpy.fft``, you can specify negative axes to perform FFT over chosen axes, which is not common in C++. Actually for FFT APIs, default axes are set as ``{-DIM, -(DIM-1), ...}`` where ``DIM`` is the rank of the FFT dimensions, -corresponding to the FFTs over last ``DIM`` axes. For example, ``KokkosFFT::fft2(execution_space(), in, out)`` is equivalent to ``KokkosFFT::fft2(execution_space(), in, out, axis_type<2>({-2, -1}))``. +corresponding to the FFTs over last ``DIM`` axes. If we consider that default View layout is C layout (row-major or ``Kokkos::LayoutRight``), +this default value results in FFTs performed over the contiguous directions. For example, ``KokkosFFT::fft2(execution_space(), in, out)`` is equivalent to ``KokkosFFT::fft2(execution_space(), in, out, axis_type<2>({-2, -1}))``. Negative axes are counted from the last axis, which is the same as ``numpy.fft``. For example, ``-1`` means the last axis, ``-2`` means the second last axis, and so on. Negative axes ``-1`` and ``-2`` respectively correspond to ``rank-1`` and ``rank-2``, where the ``rank`` is the rank of the Views. @@ -154,13 +155,17 @@ The following listing shows examples of axes parameters with negative or positiv View2D > x2_hat("x2_hat", n0/2+1, n1); View3D > x3_hat("x3_hat", n0, n1/2+1, n2); - // Following codes are all equivalent to np.fft(np.rfft(axis=0), axis=1) + // Following codes are all equivalent to np.fft(np.rfft(x2, axis=0), axis=1) + // negative axes are converted as follows: + // -2 -> 0 (= Rank(2) - 2), -1 -> 1 (= Rank(2) - 1) KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{-1, -2}); KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{-1, 0}); KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{1, -2}); KokkosFFT::rfft2(execution_space(), x2, x2_hat, /*axes=*/{1, 0}); - // Following codes are all equivalent to np.fft(np.rfft(axis=1), axis=2) + // Following codes are all equivalent to np.fft(np.rfft(x3, axis=1), axis=2) + // negative axes are converted as follows: + // -2 -> 1 (= Rank(3) - 2), -1 -> 2 (= Rank(3) - 1) KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{-1, -2}); KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{-1, 1}); KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{2, -2}); From e3367dbe1d7591fb29e8ae2f312e77112bf1e8bb Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Fri, 4 Oct 2024 21:50:16 +0900 Subject: [PATCH 09/10] docs: further fix --- docs/intro/using.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/intro/using.rst b/docs/intro/using.rst index 71350ff6..bc5ea8c8 100644 --- a/docs/intro/using.rst +++ b/docs/intro/using.rst @@ -137,7 +137,7 @@ Axes parameters As well as ``numpy.fft``, you can specify negative axes to perform FFT over chosen axes, which is not common in C++. Actually for FFT APIs, default axes are set as ``{-DIM, -(DIM-1), ...}`` where ``DIM`` is the rank of the FFT dimensions, corresponding to the FFTs over last ``DIM`` axes. If we consider that default View layout is C layout (row-major or ``Kokkos::LayoutRight``), -this default value results in FFTs performed over the contiguous directions. For example, ``KokkosFFT::fft2(execution_space(), in, out)`` is equivalent to ``KokkosFFT::fft2(execution_space(), in, out, axis_type<2>({-2, -1}))``. +this default axes parameter results in FFTs performed over the contiguous dimensions. For example, ``KokkosFFT::fft2(execution_space(), in, out)`` is equivalent to ``KokkosFFT::fft2(execution_space(), in, out, axis_type<2>({-2, -1}))``. Negative axes are counted from the last axis, which is the same as ``numpy.fft``. For example, ``-1`` means the last axis, ``-2`` means the second last axis, and so on. Negative axes ``-1`` and ``-2`` respectively correspond to ``rank-1`` and ``rank-2``, where the ``rank`` is the rank of the Views. From 57daa9492a27271973a7fd624db1b132cae4c165 Mon Sep 17 00:00:00 2001 From: Yuuichi Asahi Date: Fri, 4 Oct 2024 22:30:46 +0900 Subject: [PATCH 10/10] docs: fixed typo based on reviews --- docs/intro/using.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/intro/using.rst b/docs/intro/using.rst index bc5ea8c8..81fad685 100644 --- a/docs/intro/using.rst +++ b/docs/intro/using.rst @@ -173,5 +173,6 @@ The following listing shows examples of axes parameters with negative or positiv .. note:: - If you rely on negative axes, the corresponding positve axes are different depending on the rank of Views. + If you rely on negative axes, you can specify last axes no matter what the rank of Views is. + However, the corresponding positive axes to last axes are different depending on the rank of Views. Thus, it is recommended to use negative axes for simplicity.