Skip to content

Commit

Permalink
Update docs (#144)
Browse files Browse the repository at this point in the history
* docs: Add default explanations for APIs

* Add docs for unmanaged view example

* docs: Explain the meanings of axes

* docs: we do not rely on assertions any more

* docs: fix based on a review

* docs: fix title for unmanaged view example

* fix: docs  of fftshift based on reviews

* docs: improve the explanations for axes parameters

* docs: further fix

* docs: fixed typo based on reviews

---------

Co-authored-by: Yuuichi Asahi <[email protected]>
  • Loading branch information
yasahi-hpc and Yuuichi Asahi authored Oct 4, 2024
1 parent 81ece5b commit 545dc69
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 53 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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++
Expand Down
10 changes: 6 additions & 4 deletions common/src/KokkosFFT_Helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename ExecutionSpace, typename RealType>
Expand Down Expand Up @@ -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 <typename ExecutionSpace, typename RealType>
Expand Down Expand Up @@ -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, optional
/// \param axes [in] Axes over which to shift (default: nullopt, shifting over
/// all axes)
template <typename ExecutionSpace, typename ViewType>
void fftshift(const ExecutionSpace& exec_space, ViewType& inout,
std::optional<int> axes = std::nullopt) {
Expand Down Expand Up @@ -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, optional
/// \param axes [in] Axes over which to shift (default: nullopt, shifting over
/// all axes)
template <typename ExecutionSpace, typename ViewType>
void ifftshift(const ExecutionSpace& exec_space, ViewType& inout,
std::optional<int> axes = std::nullopt) {
Expand Down
5 changes: 3 additions & 2 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Examples

There are some `examples
<https://github.com/kokkos/kokkos-fft/tree/main/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
<https://github.com/kokkos/kokkos-fft/tree/main/examples/01_1DFFT>`_ includes,

Expand All @@ -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
samples/06_1DFFT_reuse_plans.rst
samples/07_unmanaged_views.rst
48 changes: 47 additions & 1 deletion docs/intro/using.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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++
Expand Down Expand Up @@ -130,3 +130,49 @@ 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. If we consider that default View layout is C layout (row-major or ``Kokkos::LayoutRight``),
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.

The following listing shows examples of axes parameters with negative or positive values.

.. code-block:: C++

template <typename T> using View2D = Kokkos::View<T**, Kokkos::LayoutLeft, execution_space>;
template <typename T> using View3D = Kokkos::View<T***, Kokkos::LayoutLeft, execution_space>;
constexpr int n0 = 4, n1 = 8, n2 = 5;

View2D<double> x2("x2", n0, n1);
View3D<double> x3("x3", n0, n1, n2);
View2D<Kokkos::complex<double> > x2_hat("x2_hat", n0/2+1, n1);
View3D<Kokkos::complex<double> > x3_hat("x3_hat", n0, n1/2+1, n2);

// 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(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});
KokkosFFT::rfft2(execution_space(), x3, x3_hat, /*axes=*/{2, 1});

.. note::

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.
14 changes: 14 additions & 0 deletions docs/samples/07_unmanaged_views.rst
Original file line number Diff line number Diff line change
@@ -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:

Using Unmanaged Views
=====================

KokkosFFT
---------

.. literalinclude:: ../../examples/07_unmanaged_views/07_unmanaged_views.cpp
:language: C++
7 changes: 4 additions & 3 deletions fft/src/KokkosFFT_Plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<DIM> axes, shape_type<DIM> s = {0})
axis_type<DIM> axes, shape_type<DIM> s = {})
: m_exec_space(exec_space), m_axes(axes), m_direction(direction) {
static_assert(KokkosFFT::Impl::is_AllowedSpace_v<ExecutionSpace>,
"Plan::Plan: ExecutionSpace is not allowed ");
Expand Down
Loading

0 comments on commit 545dc69

Please sign in to comment.