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

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions examples/01_1DFFT/01_1DFFT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ using View1D = Kokkos::View<T*, execution_space>;

int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
KokkosFFT::initialize();
{
const int n0 = 128;
const Kokkos::complex<double> z(1.0, 1.0);
Expand Down Expand Up @@ -44,6 +45,7 @@ int main(int argc, char* argv[]) {
KokkosFFT::irfft(exec, xc2r, xc2r_hat);
exec.fence();
}
KokkosFFT::finalize();
Kokkos::finalize();

return 0;
Expand Down
2 changes: 2 additions & 0 deletions examples/02_2DFFT/02_2DFFT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ using View2D = Kokkos::View<T**, execution_space>;

int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
KokkosFFT::initialize();
{
const int n0 = 128, n1 = 128;
const Kokkos::complex<double> z(1.0, 1.0);
Expand Down Expand Up @@ -44,6 +45,7 @@ int main(int argc, char* argv[]) {
KokkosFFT::irfft2(exec, xc2r, xc2r_hat);
exec.fence();
}
KokkosFFT::finalize();
Kokkos::finalize();

return 0;
Expand Down
2 changes: 2 additions & 0 deletions examples/03_NDFFT/03_NDFFT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ using axis_type = KokkosFFT::axis_type<DIM>;

int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
KokkosFFT::initialize();
{
const int n0 = 128, n1 = 128, n2 = 16;
const Kokkos::complex<double> z(1.0, 1.0);
Expand Down Expand Up @@ -46,6 +47,7 @@ int main(int argc, char* argv[]) {
KokkosFFT::irfftn(exec, xc2r, xc2r_hat, axis_type<3>{-3, -2, -1});
exec.fence();
}
KokkosFFT::finalize();
Kokkos::finalize();

return 0;
Expand Down
2 changes: 2 additions & 0 deletions examples/04_batchedFFT/04_batchedFFT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ using View3D = Kokkos::View<T***, execution_space>;

int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
KokkosFFT::initialize();
{
const int n0 = 128, n1 = 128, n2 = 16;
const Kokkos::complex<double> z(1.0, 1.0);
Expand Down Expand Up @@ -48,6 +49,7 @@ int main(int argc, char* argv[]) {
/*axis=*/-1);
exec.fence();
}
KokkosFFT::finalize();
Kokkos::finalize();

return 0;
Expand Down
2 changes: 2 additions & 0 deletions examples/05_1DFFT_HOST_DEVICE/05_1DFFT_HOST_DEVICE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ using HostView1D = Kokkos::View<T*, host_execution_space>;

int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
KokkosFFT::initialize();
{
const int n0 = 128;
const Kokkos::complex<double> z(1.0, 1.0);
Expand Down Expand Up @@ -79,6 +80,7 @@ int main(int argc, char* argv[]) {
host_exec.fence();
#endif
}
KokkosFFT::finalize();
Kokkos::finalize();

return 0;
Expand Down
2 changes: 2 additions & 0 deletions examples/06_1DFFT_reuse_plans/06_1DFFT_reuse_plans.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ using View1D = Kokkos::View<T*, execution_space>;

int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
KokkosFFT::initialize();
{
const int n0 = 128;
const Kokkos::complex<double> z(1.0, 1.0);
Expand Down Expand Up @@ -54,6 +55,7 @@ int main(int argc, char* argv[]) {
irfft_plan.execute(xc2r, xc2r_hat);
exec.fence();
}
KokkosFFT::finalize();
Kokkos::finalize();

return 0;
Expand Down
2 changes: 2 additions & 0 deletions examples/07_unmanaged_views/07_unmanaged_views.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ using shape_type = KokkosFFT::shape_type<DIM>;

int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
KokkosFFT::initialize();
{
const int n0 = 128, n1 = 128, n2 = 16;
const Kokkos::complex<double> z(1.0, 1.0);
Expand Down Expand Up @@ -63,6 +64,7 @@ int main(int argc, char* argv[]) {
KokkosFFT::Normalization::backward, shape);
exec.fence();
}
KokkosFFT::finalize();
Kokkos::finalize();

return 0;
Expand Down
2 changes: 2 additions & 0 deletions examples/08_inplace_FFT/08_inplace_FFT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ using RightView2D = Kokkos::View<T **, Kokkos::LayoutRight, execution_space>;

int main(int argc, char *argv[]) {
Kokkos::initialize(argc, argv);
KokkosFFT::initialize();
{
const int n0 = 128, n1 = 128;
const Kokkos::complex<double> z(1.0, 1.0);
Expand Down Expand Up @@ -69,6 +70,7 @@ int main(int argc, char *argv[]) {

exec.fence();
}
KokkosFFT::finalize();
Kokkos::finalize();

return 0;
Expand Down
6 changes: 3 additions & 3 deletions fft/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
#
# SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception

add_library(fft INTERFACE)
add_library(fft STATIC KokkosFFT_Core.cpp)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
add_library(fft STATIC KokkosFFT_Core.cpp)
add_library(fft KokkosFFT_Core.cpp)

I would not force it to be STATIC to allow people to use BUILD_SHARED_LIBS, https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html.


target_link_libraries(fft
INTERFACE
PUBLIC
common
Kokkos::kokkos
)

target_include_directories(fft INTERFACE
target_include_directories(fft PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}>
)
Expand Down
1 change: 1 addition & 0 deletions fft/src/KokkosFFT.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
#include "KokkosFFT_Helpers.hpp"
#include "KokkosFFT_Plans.hpp"
#include "KokkosFFT_Transform.hpp"
#include "KokkosFFT_Core.hpp"

#endif
79 changes: 79 additions & 0 deletions fft/src/KokkosFFT_Core.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-FileCopyrightText: (C) The kokkos-fft development team, see COPYRIGHT.md file
//
// SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception

#include <Kokkos_Core.hpp>
#include "KokkosFFT_Core.hpp"
#include "KokkosFFT_default_types.hpp"

namespace {
bool g_is_initialized = false;
bool g_is_finalized = false;

bool kokkosfft_initialize_was_called() {
return KokkosFFT::is_initialized() || KokkosFFT::is_finalized();
}
bool kokkosfft_finalize_was_called() { return KokkosFFT::is_finalized(); }

void initialize_internal() {
KokkosFFT::Impl::initialize_host();
KokkosFFT::Impl::initialize_device();
}

void finalize_internal() {
KokkosFFT::Impl::finalize_host();
KokkosFFT::Impl::finalize_device();
}
} // namespace

[[nodiscard]] bool KokkosFFT::is_initialized() noexcept {
return g_is_initialized;
}

[[nodiscard]] bool KokkosFFT::is_finalized() noexcept { return g_is_finalized; }

void KokkosFFT::initialize() {
if (!(Kokkos::is_initialized() || Kokkos::is_finalized())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!(Kokkos::is_initialized() || Kokkos::is_finalized())) {
if (!Kokkos::is_initialized()) {

Do we need to test is_finalized ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to exclude the situation after finalization, where Kokkos::is_initialized() returns false and Kokkos::is_finalized() returns true. Accordingly, if we just check Kokkos::is_initialized(), we do not know whether Kokkos is before initialization or after finalization.

Kokkos::abort(
"Error: KokkosFFT::initialize() must not be called before initializing "
"Kokkos.\n");
}
if (Kokkos::is_finalized()) {
Kokkos::abort(
"Error: KokkosFFT::initialize() must not be called after finalizing "
"Kokkos.\n");
}
if (kokkosfft_initialize_was_called()) {
Kokkos::abort(
"Error: KokkosFFT::initialize() has already been called."
" KokkosFFT can be initialized at most once.\n");
}
initialize_internal();
g_is_initialized = true;
}

void KokkosFFT::finalize() {
if (!(Kokkos::is_initialized() || Kokkos::is_finalized())) {
Kokkos::abort(
"Error: KokkosFFT::finalize() may only be called after Kokkos has been "
"initialized.\n");
}
if (Kokkos::is_finalized()) {
Kokkos::abort(
"Error: KokkosFFT::finalize() must be called before finalizing "
"Kokkos.\n");
}

if (!kokkosfft_initialize_was_called()) {
Kokkos::abort(
"Error: KokkosFFT::finalize() may only be called after KokkosFFT has "
"been "
"initialized.\n");
}
if (kokkosfft_finalize_was_called()) {
Kokkos::abort("Error: KokkosFFT::finalize() has already been called.\n");
}
finalize_internal();
g_is_initialized = false;
g_is_finalized = true;
}
17 changes: 17 additions & 0 deletions fft/src/KokkosFFT_Core.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: (C) The kokkos-fft development team, see COPYRIGHT.md file
//
// SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception

#ifndef KOKKOSFFT_CORE_HPP
#define KOKKOSFFT_CORE_HPP

namespace KokkosFFT {
void initialize();

[[nodiscard]] bool is_initialized() noexcept;
[[nodiscard]] bool is_finalized() noexcept;

void finalize();
} // namespace KokkosFFT

#endif
6 changes: 6 additions & 0 deletions fft/src/KokkosFFT_Cuda_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,13 @@ template <typename ExecutionSpace>
auto direction_type(Direction direction) {
return direction == Direction::forward ? CUFFT_FORWARD : CUFFT_INVERSE;
}

inline void initialize_host() {}
inline void finalize_host() {}
#endif

inline void initialize_device() {}
inline void finalize_device() {}
} // namespace Impl
} // namespace KokkosFFT

Expand Down
22 changes: 22 additions & 0 deletions fft/src/KokkosFFT_FFTW_Types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,28 @@ struct ScopedFFTWPlan {
}
};

#if defined(KOKKOS_ENABLE_OPENMP) || defined(KOKKOS_ENABLE_THREADS)
inline void initialize_host() {
fftwf_init_threads();
fftw_init_threads();
}
inline void finalize_host() {
fftwf_cleanup_threads();
fftw_cleanup_threads();
}
#else
inline void initialize_host() {}
inline void finalize_host() {}
#endif

// If non of device backend is enabled, then FFTW is responsible
// for the device cleanup. Otherwise, device backend will cleanup
#if !(defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || \
defined(KOKKOS_ENABLE_SYCL))
inline void initialize_device() {}
inline void finalize_device() {}
#endif

} // namespace Impl
} // namespace KokkosFFT

Expand Down
6 changes: 6 additions & 0 deletions fft/src/KokkosFFT_HIP_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,13 @@ template <typename ExecutionSpace>
auto direction_type(Direction direction) {
return direction == Direction::forward ? HIPFFT_FORWARD : HIPFFT_BACKWARD;
}

inline void initialize_host() {}
inline void finalize_host() {}
#endif

inline void initialize_device() {}
inline void finalize_device() {}
} // namespace Impl
} // namespace KokkosFFT

Expand Down
12 changes: 12 additions & 0 deletions fft/src/KokkosFFT_ROCM_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,19 @@ template <typename ExecutionSpace>
auto direction_type(Direction direction) {
return direction == Direction::forward ? ROCFFT_FORWARD : ROCFFT_BACKWARD;
}

inline void initialize_host() {}
inline void finalize_host() {}
#endif

inline void initialize_device() {
rocfft_status status = rocfft_setup();
if (status != rocfft_status_success) Kokkos::abort("rocfft_setup failed");
}
inline void finalize_device() {
rocfft_status status = rocfft_cleanup();
if (status != rocfft_status_success) Kokkos::abort("rocfft_cleanup failed");
}
} // namespace Impl
} // namespace KokkosFFT

Expand Down
6 changes: 6 additions & 0 deletions fft/src/KokkosFFT_SYCL_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,13 @@ template <typename ExecutionSpace>
auto direction_type(Direction direction) {
return direction == Direction::forward ? MKL_FFT_FORWARD : MKL_FFT_BACKWARD;
}

inline void initialize_host() {}
inline void finalize_host() {}
#endif

inline void initialize_device() {}
inline void finalize_device() {}
} // namespace Impl
} // namespace KokkosFFT

Expand Down
10 changes: 9 additions & 1 deletion fft/unit_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ add_executable(unit-tests-kokkos-fft-core
Test_Transform.cpp
)

target_compile_features(unit-tests-kokkos-fft-core PUBLIC cxx_std_17)
add_executable(unit-tests-kokkos-fft-core-no-init
Test_MainNoInit.cpp
Test_InitializeFinalize.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)

target_compile_features(unit-tests-kokkos-fft-core-no-init PUBLIC cxx_std_17)
target_link_libraries(unit-tests-kokkos-fft-core-no-init PUBLIC KokkosFFT::fft GTest::gtest)

# Enable GoogleTest
include(GoogleTest)
gtest_discover_tests(unit-tests-kokkos-fft-core PROPERTIES DISCOVERY_TIMEOUT 600 DISCOVERY_MODE PRE_TEST)
gtest_discover_tests(unit-tests-kokkos-fft-core-no-init PROPERTIES DISCOVERY_TIMEOUT 600 DISCOVERY_MODE PRE_TEST)
Loading
Loading