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

Introduce global setup/cleanup in APIs #220

Merged
merged 12 commits into from
Feb 24, 2025
20 changes: 20 additions & 0 deletions fft/src/KokkosFFT_Cuda_plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@

namespace KokkosFFT {
namespace Impl {

template <typename ExecutionSpace, typename T,
std::enable_if_t<std::is_same_v<ExecutionSpace, Kokkos::Cuda>,
std::nullptr_t> = nullptr>
void setup() {
static bool once = [] {
if (!(Kokkos::is_initialized() || Kokkos::is_finalized())) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called before initializing "
"Kokkos.\n");
}
if (Kokkos::is_finalized()) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called after finalizing "
"Kokkos.\n");
}
return true;
}();
}

// 1D transform
template <typename ExecutionSpace, typename PlanType, typename InViewType,
typename OutViewType,
Expand Down
20 changes: 20 additions & 0 deletions fft/src/KokkosFFT_HIP_plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@

namespace KokkosFFT {
namespace Impl {

template <typename ExecutionSpace, typename T,
std::enable_if_t<std::is_same_v<ExecutionSpace, Kokkos::HIP>,
std::nullptr_t> = nullptr>
void setup() {
[[maybe_unused]] static bool once = [] {
if (!(Kokkos::is_initialized() || Kokkos::is_finalized())) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called before initializing "
"Kokkos.\n");
}
if (Kokkos::is_finalized()) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called after finalizing "
"Kokkos.\n");
}
return true;
}();
}

// 1D transform
template <typename ExecutionSpace, typename PlanType, typename InViewType,
typename OutViewType,
Expand Down
39 changes: 39 additions & 0 deletions fft/src/KokkosFFT_Host_plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,45 @@

namespace KokkosFFT {
namespace Impl {

template <typename ExecutionSpace, typename T,
std::enable_if_t<is_AnyHostSpace_v<ExecutionSpace>, std::nullptr_t> =
nullptr>
void setup() {
[[maybe_unused]] static bool once = [] {
if (!(Kokkos::is_initialized() || Kokkos::is_finalized())) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called before initializing "
"Kokkos.\n");
}
if (Kokkos::is_finalized()) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called after finalizing "
"Kokkos.\n");
}
#if defined(KOKKOS_ENABLE_OPENMP) || defined(KOKKOS_ENABLE_THREADS)
if constexpr (std::is_same_v<ExecutionSpace,
Kokkos::DefaultHostExecutionSpace>) {
if constexpr (std::is_same_v<T, float>) {
fftwf_init_threads();
} else {
fftw_init_threads();
}

// Register cleanup function as a hook in Kokkos::finalize
Kokkos::push_finalize_hook([]() {
if constexpr (std::is_same_v<T, float>) {
fftwf_cleanup_threads();
} else {
fftw_cleanup_threads();
}
});
}
#endif
return true;
}();
}

// batched transform, over ND Views
template <typename ExecutionSpace, typename PlanType, typename InViewType,
typename OutViewType, std::size_t fft_rank = 1,
Expand Down
2 changes: 2 additions & 0 deletions fft/src/KokkosFFT_Plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class Plan {
"In-place transform is not supported with reshape. "
"Please use out-of-place transform.");

KokkosFFT::Impl::setup<ExecutionSpace, float_type>();
m_fft_size = KokkosFFT::Impl::create_plan(
exec_space, m_plan, in, out, direction, m_axes, s, m_is_inplace);
}
Expand Down Expand Up @@ -264,6 +265,7 @@ class Plan {
"In-place transform is not supported with reshape. "
"Please use out-of-place transform.");

KokkosFFT::Impl::setup<ExecutionSpace, float_type>();
m_fft_size = KokkosFFT::Impl::create_plan(exec_space, m_plan, in, out,
direction, axes, s, m_is_inplace);
}
Expand Down
29 changes: 29 additions & 0 deletions fft/src/KokkosFFT_ROCM_plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,35 @@
namespace KokkosFFT {
namespace Impl {

template <typename ExecutionSpace, typename T,
std::enable_if_t<std::is_same_v<ExecutionSpace, Kokkos::HIP>,
std::nullptr_t> = nullptr>
void setup() {
[[maybe_unused]] static bool once = [] {
if (!(Kokkos::is_initialized() || Kokkos::is_finalized())) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called before initializing "
"Kokkos.\n");
}
if (Kokkos::is_finalized()) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called after finalizing "
"Kokkos.\n");
}

rocfft_status status = rocfft_setup();
if (status != rocfft_status_success) Kokkos::abort("rocfft_setup failed");

// Register cleanup function as a hook in Kokkos::finalize
Kokkos::push_finalize_hook([]() {
rocfft_status status = rocfft_cleanup();
if (status != rocfft_status_success)
Kokkos::abort("rocfft_cleanup failed");
});
return true;
}();
}

// batched transform, over ND Views
template <typename ExecutionSpace, typename PlanType, typename InViewType,
typename OutViewType, std::size_t fft_rank = 1,
Expand Down
21 changes: 21 additions & 0 deletions fft/src/KokkosFFT_SYCL_plans.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@

namespace KokkosFFT {
namespace Impl {

template <
typename ExecutionSpace, typename T,
std::enable_if_t<std::is_same_v<ExecutionSpace, Kokkos::Experimental::SYCL>,
std::nullptr_t> = nullptr>
void setup() {
static bool once = [] {
if (!(Kokkos::is_initialized() || Kokkos::is_finalized())) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called before initializing "
"Kokkos.\n");
}
if (Kokkos::is_finalized()) {
Kokkos::abort(
"Error: KokkosFFT APIs must not be called after finalizing "
"Kokkos.\n");
}
return true;
}();
}

// Helper to convert the integer type of vectors
template <typename InType, typename OutType>
auto convert_int_type(std::vector<InType>& in) -> std::vector<OutType> {
Expand Down
1 change: 0 additions & 1 deletion fft/unit_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
add_executable(unit-tests-kokkos-fft-core Test_Main.cpp Test_Plans.cpp Test_Transform.cpp)

target_compile_features(unit-tests-kokkos-fft-core PUBLIC cxx_std_17)

target_link_libraries(unit-tests-kokkos-fft-core PUBLIC KokkosFFT::fft GTest::gtest)

# Enable GoogleTest
Expand Down
19 changes: 5 additions & 14 deletions fft/unit_test/Test_Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,16 @@
//
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <Kokkos_Core.hpp>
#include <gtest/gtest.h>

namespace testing::internal {
// accessing gtest internals is not very clean, but gtest provides no public
// access...
extern bool g_help_flag;
} // namespace testing::internal
#include <Kokkos_Core.hpp>

int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);

int result = 0;
if (::testing::GTEST_FLAG(list_tests) || ::testing::internal::g_help_flag) {
result = RUN_ALL_TESTS();
} else {
Kokkos::initialize(argc, argv);
result = RUN_ALL_TESTS();
Kokkos::finalize();
}
Kokkos::initialize(argc, argv);
result = RUN_ALL_TESTS();
Kokkos::finalize();

return result;
}
Loading