Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup #8

Merged
merged 9 commits into from
Dec 14, 2023
28 changes: 18 additions & 10 deletions common/src/KokkosFFT_normalization.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef __KOKKOSFFT_NORMALIZATION_HPP__
yasahi-hpc marked this conversation as resolved.
Show resolved Hide resolved
#define __KOKKOSFFT_NORMALIZATION_HPP__

#include <tuple>
#include "KokkosFFT_default_types.hpp"
#include "KokkosFFT_utils.hpp"

Expand All @@ -24,31 +25,38 @@ namespace KokkosFFT {

template <typename ViewType>
auto _coefficients(const ViewType& inout, FFTDirectionType direction, FFT_Normalization normalization, std::size_t fft_size) {
using value_type = real_type_t<typename ViewType::value_type>;
using value_type = real_type_t<typename ViewType::non_const_value_type>;
value_type coef = 1;
bool to_normalize = false;

switch (normalization) {
case FFT_Normalization::FORWARD:
yasahi-hpc marked this conversation as resolved.
Show resolved Hide resolved
coef = direction == KOKKOS_FFT_FORWARD
? static_cast<value_type>(1) / static_cast<value_type>(fft_size)
: 1;
if(direction == KOKKOS_FFT_FORWARD) {
coef = static_cast<value_type>(1) / static_cast<value_type>(fft_size);
to_normalize = true;
}

break;
case FFT_Normalization::BACKWARD:
coef = direction == KOKKOS_FFT_BACKWARD
? static_cast<value_type>(1) / static_cast<value_type>(fft_size)
: 1;
if(direction == KOKKOS_FFT_BACKWARD) {
coef = static_cast<value_type>(1) / static_cast<value_type>(fft_size);
to_normalize = true;
}

break;
case FFT_Normalization::ORTHO:
coef = static_cast<value_type>(1) / Kokkos::sqrt(static_cast<value_type>(fft_size));
to_normalize = true;

break;
};
return coef;
return std::tuple<value_type, bool> ({coef, to_normalize});
}

template <typename ViewType>
void normalize(ViewType& inout, FFTDirectionType direction, FFT_Normalization normalization, std::size_t fft_size) {
auto coef = _coefficients(inout, direction, normalization, fft_size);
_normalize(inout, coef);
auto [coef, to_normalize] = _coefficients(inout, direction, normalization, fft_size);
if(to_normalize) _normalize(inout, coef);
}
};

Expand Down
1,134 changes: 418 additions & 716 deletions common/unit_test/Test_Layouts.cpp

Large diffs are not rendered by default.

868 changes: 418 additions & 450 deletions common/unit_test/Test_Transpose.cpp

Large diffs are not rendered by default.

121 changes: 75 additions & 46 deletions common/unit_test/Test_Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#include "KokkosFFT_utils.hpp"
#include "Test_Types.hpp"

TEST(ConvertNegativeAxis, 1D) {
template <typename LayoutType>
void test_convert_negative_axes_1d() {
const int len = 30;
View1D<double> x("x", len);
using RealView1Dtype = Kokkos::View<double*, LayoutType, execution_space>;
RealView1Dtype x("x", len);

int converted_axis_0 = KokkosFFT::convert_negative_axis(x, /*axis=*/0);
int converted_axis_minus1 = KokkosFFT::convert_negative_axis(x, /*axis=*/-1);
Expand All @@ -16,53 +18,56 @@ TEST(ConvertNegativeAxis, 1D) {
EXPECT_EQ( converted_axis_minus1, ref_converted_axis_minus1 );
}

TEST(ConvertNegativeAxis, 2DLeft) {
const int n0 = 3, n1 = 5;
LeftView2D<double> x("x", n0, n1);

int converted_axis_0 = KokkosFFT::convert_negative_axis(x, /*axis=*/0);
int converted_axis_1 = KokkosFFT::convert_negative_axis(x, /*axis=*/1);
int converted_axis_minus1 = KokkosFFT::convert_negative_axis(x, /*axis=*/-1);

int ref_converted_axis_0 = 0;
int ref_converted_axis_1 = 1;
int ref_converted_axis_minus1 = 1;
TEST(ConvertNegativeAxis, 1DLeftView) {
test_convert_negative_axes_1d<Kokkos::LayoutLeft>();
}

EXPECT_EQ( converted_axis_0, ref_converted_axis_0 );
EXPECT_EQ( converted_axis_1, ref_converted_axis_1 );
EXPECT_EQ( converted_axis_minus1, ref_converted_axis_minus1 );
TEST(ConvertNegativeAxis, 1DRightView) {
test_convert_negative_axes_1d<Kokkos::LayoutRight>();
}

TEST(ConvertNegativeAxis, 2DRight) {
template <typename LayoutType>
void test_convert_negative_axes_2d() {
const int n0 = 3, n1 = 5;
RightView2D<double> x("x", n0, n1);
using RealView2Dtype = Kokkos::View<double**, LayoutType, execution_space>;
RealView2Dtype x("x", n0, n1);

int converted_axis_0 = KokkosFFT::convert_negative_axis(x, /*axis=*/0);
int converted_axis_1 = KokkosFFT::convert_negative_axis(x, /*axis=*/1);
int converted_axis_0 = KokkosFFT::convert_negative_axis(x, /*axis=*/0);
int converted_axis_1 = KokkosFFT::convert_negative_axis(x, /*axis=*/1);
int converted_axis_minus1 = KokkosFFT::convert_negative_axis(x, /*axis=*/-1);

int ref_converted_axis_0 = 0;
int ref_converted_axis_1 = 1;
int ref_converted_axis_0 = 0;
int ref_converted_axis_1 = 1;
int ref_converted_axis_minus1 = 1;

EXPECT_EQ( converted_axis_0, ref_converted_axis_0 );
EXPECT_EQ( converted_axis_1, ref_converted_axis_1 );
EXPECT_EQ( converted_axis_minus1, ref_converted_axis_minus1 );
}

TEST(ConvertNegativeAxis, 3DLeft) {
TEST(ConvertNegativeAxis, 2DLeftView) {
test_convert_negative_axes_2d<Kokkos::LayoutLeft>();
}

TEST(ConvertNegativeAxis, 2DRightView) {
test_convert_negative_axes_2d<Kokkos::LayoutRight>();
}

template <typename LayoutType>
void test_convert_negative_axes_3d() {
const int n0 = 3, n1 = 5, n2 = 8;
LeftView3D<double> x("x", n0, n1, n2);
using RealView3Dtype = Kokkos::View<double***, LayoutType, execution_space>;
RealView3Dtype x("x", n0, n1, n2);

int converted_axis_0 = KokkosFFT::convert_negative_axis(x, /*axis=*/0);
int converted_axis_1 = KokkosFFT::convert_negative_axis(x, /*axis=*/1);
int converted_axis_2 = KokkosFFT::convert_negative_axis(x, /*axis=*/2);
int converted_axis_0 = KokkosFFT::convert_negative_axis(x, /*axis=*/0);
int converted_axis_1 = KokkosFFT::convert_negative_axis(x, /*axis=*/1);
int converted_axis_2 = KokkosFFT::convert_negative_axis(x, /*axis=*/2);
int converted_axis_minus1 = KokkosFFT::convert_negative_axis(x, /*axis=*/-1);
int converted_axis_minus2 = KokkosFFT::convert_negative_axis(x, /*axis=*/-2);

int ref_converted_axis_0 = 0;
int ref_converted_axis_1 = 1;
int ref_converted_axis_2 = 2;
int ref_converted_axis_0 = 0;
int ref_converted_axis_1 = 1;
int ref_converted_axis_2 = 2;
int ref_converted_axis_minus1 = 2;
int ref_converted_axis_minus2 = 1;

Expand All @@ -73,27 +78,51 @@ TEST(ConvertNegativeAxis, 3DLeft) {
EXPECT_EQ( converted_axis_minus2, ref_converted_axis_minus2 );
}

TEST(ConvertNegativeAxis, 3DRight) {
const int n0 = 3, n1 = 5, n2 = 8;
RightView3D<double> x("x", n0, n1, n2);
TEST(ConvertNegativeAxis, 3DLeftView) {
test_convert_negative_axes_3d<Kokkos::LayoutLeft>();
}

int converted_axis_0 = KokkosFFT::convert_negative_axis(x, /*axis=*/0);
int converted_axis_1 = KokkosFFT::convert_negative_axis(x, /*axis=*/1);
int converted_axis_2 = KokkosFFT::convert_negative_axis(x, /*axis=*/2);
TEST(ConvertNegativeAxis, 3DRightView) {
test_convert_negative_axes_3d<Kokkos::LayoutRight>();
}

template <typename LayoutType>
void test_convert_negative_axes_4d() {
const int n0 = 3, n1 = 5, n2 = 8, n3 = 13;
using RealView4Dtype = Kokkos::View<double****, LayoutType, execution_space>;
RealView4Dtype x("x", n0, n1, n2, n3);

int converted_axis_0 = KokkosFFT::convert_negative_axis(x, /*axis=*/0);
int converted_axis_1 = KokkosFFT::convert_negative_axis(x, /*axis=*/1);
int converted_axis_2 = KokkosFFT::convert_negative_axis(x, /*axis=*/2);
int converted_axis_3 = KokkosFFT::convert_negative_axis(x, /*axis=*/3);
int converted_axis_minus1 = KokkosFFT::convert_negative_axis(x, /*axis=*/-1);
int converted_axis_minus2 = KokkosFFT::convert_negative_axis(x, /*axis=*/-2);
int converted_axis_minus3 = KokkosFFT::convert_negative_axis(x, /*axis=*/-3);

int ref_converted_axis_0 = 0;
int ref_converted_axis_1 = 1;
int ref_converted_axis_2 = 2;
int ref_converted_axis_minus1 = 2;
int ref_converted_axis_minus2 = 1;
int ref_converted_axis_0 = 0;
int ref_converted_axis_1 = 1;
int ref_converted_axis_2 = 2;
int ref_converted_axis_3 = 3;
int ref_converted_axis_minus1 = 3;
int ref_converted_axis_minus2 = 2;
int ref_converted_axis_minus3 = 1;

EXPECT_EQ( converted_axis_0, ref_converted_axis_0 );
EXPECT_EQ( converted_axis_1, ref_converted_axis_1 );
EXPECT_EQ( converted_axis_2, ref_converted_axis_2 );
EXPECT_EQ( converted_axis_3, ref_converted_axis_3 );
EXPECT_EQ( converted_axis_minus1, ref_converted_axis_minus1 );
EXPECT_EQ( converted_axis_minus2, ref_converted_axis_minus2 );
EXPECT_EQ( converted_axis_minus3, ref_converted_axis_minus3 );
}

TEST(ConvertNegativeAxis, 4DLeftView) {
test_convert_negative_axes_4d<Kokkos::LayoutLeft>();
}

TEST(ConvertNegativeAxis, 4DRightView) {
test_convert_negative_axes_4d<Kokkos::LayoutRight>();
}

TEST(IsTransposeNeeded, 1Dto3D) {
Expand Down Expand Up @@ -122,11 +151,11 @@ TEST(IsTransposeNeeded, 1Dto3D) {
TEST(GetIndex, Vectors) {
std::vector<int> v = {0, 1, 4, 2, 3};

EXPECT_EQ( KokkosFFT::get_index(v, 0), 0);
EXPECT_EQ( KokkosFFT::get_index(v, 1), 1);
EXPECT_EQ( KokkosFFT::get_index(v, 2), 3);
EXPECT_EQ( KokkosFFT::get_index(v, 3), 4);
EXPECT_EQ( KokkosFFT::get_index(v, 4), 2);
EXPECT_EQ( KokkosFFT::get_index(v, 0), 0 );
EXPECT_EQ( KokkosFFT::get_index(v, 1), 1 );
EXPECT_EQ( KokkosFFT::get_index(v, 2), 3 );
EXPECT_EQ( KokkosFFT::get_index(v, 3), 4 );
EXPECT_EQ( KokkosFFT::get_index(v, 4), 2 );

EXPECT_THROW(
KokkosFFT::get_index(v, -1),
Expand Down
1 change: 1 addition & 0 deletions fft/src/KokkosFFT_OpenMP_plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ namespace KokkosFFT {
istride,
idist,
odata,
out_extents.data(),
ostride,
odist,
FFTW_ESTIMATE
Expand Down
29 changes: 22 additions & 7 deletions fft/src/KokkosFFT_Plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "KokkosFFT_OpenMP_plans.hpp"
#else
using default_device = Kokkos::Serial;
#include "KokkosFFT_Serial_plans.hpp"
#include "KokkosFFT_OpenMP_plans.hpp"
#endif

namespace KokkosFFT {
Expand Down Expand Up @@ -49,9 +49,9 @@ namespace KokkosFFT {
// Available only for R2C or C2R
// For C2C, direction should be given by an user
static_assert(Kokkos::is_view<InViewType>::value,
"KokkosFFT::_create: InViewType is not a Kokkos::View.");
static_assert(Kokkos::is_view<InViewType>::value,
"KokkosFFT::_create: OutViewType is not a Kokkos::View.");
"KokkosFFT::Plan: InViewType is not a Kokkos::View.");
static_assert(Kokkos::is_view<OutViewType>::value,
"KokkosFFT::Plan: OutViewType is not a Kokkos::View.");

using in_value_type = typename InViewType::non_const_value_type;
using out_value_type = typename OutViewType::non_const_value_type;
Expand All @@ -72,9 +72,9 @@ namespace KokkosFFT {
// Available only for R2C or C2R
// For C2C, direction should be given by an user
static_assert(Kokkos::is_view<InViewType>::value,
"KokkosFFT::_create: InViewType is not a Kokkos::View.");
static_assert(Kokkos::is_view<InViewType>::value,
"KokkosFFT::_create: OutViewType is not a Kokkos::View.");
"KokkosFFT::Plan: InViewType is not a Kokkos::View.");
static_assert(Kokkos::is_view<OutViewType>::value,
"KokkosFFT::Plan: OutViewType is not a Kokkos::View.");

using in_value_type = typename InViewType::non_const_value_type;
using out_value_type = typename OutViewType::non_const_value_type;
Expand All @@ -92,17 +92,32 @@ namespace KokkosFFT {
}

explicit Plan(InViewType& in, OutViewType& out, FFTDirectionType direction) : m_fft_size(1), m_is_transpose_needed(false) {
static_assert(Kokkos::is_view<InViewType>::value,
"KokkosFFT::Plan: InViewType is not a Kokkos::View.");
static_assert(Kokkos::is_view<OutViewType>::value,
"KokkosFFT::Plan: OutViewType is not a Kokkos::View.");

/* Apply FFT over entire axes or along inner most directions */
m_fft_size = _create(m_plan, in, out, direction);
}

explicit Plan(InViewType& in, OutViewType& out, FFTDirectionType direction, int axis) : m_fft_size(1), m_is_transpose_needed(false) {
static_assert(Kokkos::is_view<InViewType>::value,
"KokkosFFT::Plan: InViewType is not a Kokkos::View.");
static_assert(Kokkos::is_view<OutViewType>::value,
"KokkosFFT::Plan: OutViewType is not a Kokkos::View.");

std::tie(m_map, m_map_inv) = KokkosFFT::get_map_axes(in, axis);
m_is_transpose_needed = KokkosFFT::is_transpose_needed(m_map);
m_fft_size = _create(m_plan, in, out, direction, axis_type<1>{axis});
}

explicit Plan(InViewType& in, OutViewType& out, FFTDirectionType direction, axis_type<DIM> axes) : m_fft_size(1), m_is_transpose_needed(false) {
static_assert(Kokkos::is_view<InViewType>::value,
"KokkosFFT::Plan: InViewType is not a Kokkos::View.");
static_assert(Kokkos::is_view<OutViewType>::value,
"KokkosFFT::Plan: OutViewType is not a Kokkos::View.");

std::tie(m_map, m_map_inv) = KokkosFFT::get_map_axes(in, axes);
m_is_transpose_needed = KokkosFFT::is_transpose_needed(m_map);
m_fft_size = _create(m_plan, in, out, direction, axes);
Expand Down
Loading