From 5bbdfe5b4fa17a24cf47196ade2aa9ccd74f1d5e Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Thu, 2 Feb 2023 17:11:28 -0500 Subject: [PATCH 1/9] enabled the use of heffte for the cpu backend --- cmake/Modules/Packages/KSPACE.cmake | 16 +++++++++++++ src/KSPACE/fft3d_wrap.cpp | 36 +++++++++++++++++++++++++++++ src/KSPACE/fft3d_wrap.h | 18 +++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/cmake/Modules/Packages/KSPACE.cmake b/cmake/Modules/Packages/KSPACE.cmake index de7e7e5b20..119c8fa867 100644 --- a/cmake/Modules/Packages/KSPACE.cmake +++ b/cmake/Modules/Packages/KSPACE.cmake @@ -46,6 +46,22 @@ else() target_compile_definitions(lammps PRIVATE -DFFT_KISS) endif() +option(FFT_HEFFTE "Use heFFTe as the distributed FFT engine." OFF) +if(FFT_HEFFTE) + # if FFT_HEFFTE is enabled, switch the builtin FFT engine with Heffte + if(FFT STREQUAL "FFTW3") # respect the backend choice, FFTW or MKL + set(HEFFTE_COMPONENTS "FFTW") + elseif(FFT STREQUAL "MKL") + set(HEFFTE_COMPONENTS "MKL") + else() + message(FATAL_ERROR "Using -DFFT_HEFFTE=ON, requires FFT either FFTW or MKL") + endif() + + find_package(Heffte 2.3.0 REQUIRED ${HEFFTE_COMPONENTS}) + target_compile_definitions(lammps PRIVATE -DHEFFTE) + target_link_libraries(lammps PRIVATE Heffte::Heffte) +endif() + set(FFT_PACK "array" CACHE STRING "Optimization for FFT") set(FFT_PACK_VALUES array pointer memcpy) set_property(CACHE FFT_PACK PROPERTY STRINGS ${FFT_PACK_VALUES}) diff --git a/src/KSPACE/fft3d_wrap.cpp b/src/KSPACE/fft3d_wrap.cpp index 478cf6fc9d..a6b4167d71 100644 --- a/src/KSPACE/fft3d_wrap.cpp +++ b/src/KSPACE/fft3d_wrap.cpp @@ -27,30 +27,66 @@ FFT3d::FFT3d(LAMMPS *lmp, MPI_Comm comm, int nfast, int nmid, int nslow, int out_klo, int out_khi, int scaled, int permute, int *nbuf, int usecollective) : Pointers(lmp) { + #ifndef HEFFTE plan = fft_3d_create_plan(comm,nfast,nmid,nslow, in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, scaled,permute,nbuf,usecollective); if (plan == nullptr) error->one(FLERR,"Could not create 3d FFT plan"); + #else + heffte::plan_options options = heffte::default_options(); + options.algorithm = (usecollective == 0) ? + heffte::reshape_algorithm::p2p_plined + : heffte::reshape_algorithm::alltoallv; + options.use_reorder = (permute != 0); + hscale = (scaled == 0) ? heffte::scale::none : heffte::scale::full; + + heffte_plan = std::unique_ptr>( + new heffte::fft3d( + heffte::box3d<>({in_ilo,in_jlo,in_klo}, {in_ihi, in_jhi, in_khi}), + heffte::box3d<>({out_ilo,out_jlo,out_klo}, {out_ihi, out_jhi, out_khi}), + comm, options) + ); + *nbuf = heffte_plan->size_workspace(); + heffte_workspace.resize(heffte_plan->size_workspace()); + #endif } /* ---------------------------------------------------------------------- */ FFT3d::~FFT3d() { + #ifndef HEFFTE fft_3d_destroy_plan(plan); + #endif } /* ---------------------------------------------------------------------- */ void FFT3d::compute(FFT_SCALAR *in, FFT_SCALAR *out, int flag) { + #ifndef HEFFTE fft_3d((FFT_DATA *) in,(FFT_DATA *) out,flag,plan); + #else + if (flag == 1) + heffte_plan->forward(reinterpret_cast*>(in), + reinterpret_cast*>(out), + reinterpret_cast*>(heffte_workspace.data()) + ); + else + heffte_plan->backward(reinterpret_cast*>(in), + reinterpret_cast*>(out), + reinterpret_cast*>(heffte_workspace.data()), + hscale + ); + #endif } /* ---------------------------------------------------------------------- */ void FFT3d::timing1d(FFT_SCALAR *in, int nsize, int flag) { + #ifndef HEFFTE fft_1d_only((FFT_DATA *) in,nsize,flag,plan); + #endif } diff --git a/src/KSPACE/fft3d_wrap.h b/src/KSPACE/fft3d_wrap.h index f72cfd4622..f34680d682 100644 --- a/src/KSPACE/fft3d_wrap.h +++ b/src/KSPACE/fft3d_wrap.h @@ -17,6 +17,17 @@ #include "fft3d.h" // IWYU pragma: export #include "pointers.h" +#ifdef HEFFTE +#include "heffte.h" +// select the backend +#if defined(FFT_FFTW3) +using heffte_backend = heffte::backend::fftw; +#elif defined(FFT_MKL) +using heffte_backend = heffte::backend::mkl; +#endif + +#endif // HEFFTE + namespace LAMMPS_NS { class FFT3d : protected Pointers { @@ -30,7 +41,14 @@ class FFT3d : protected Pointers { void timing1d(FFT_SCALAR *, int, int); private: + #ifdef HEFFTE + // the heFFTe plan supersedes the internal fft_plan_3d + std::unique_ptr> heffte_plan; + std::vector> heffte_workspace; + heffte::scale hscale; + #else struct fft_plan_3d *plan; + #endif }; } // namespace LAMMPS_NS From 03b6b2d03026698fdca12ce38b0ce21895d87d69 Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Thu, 2 Feb 2023 20:46:20 -0500 Subject: [PATCH 2/9] enable automatically downlowding of heffte --- cmake/Modules/Packages/KSPACE.cmake | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cmake/Modules/Packages/KSPACE.cmake b/cmake/Modules/Packages/KSPACE.cmake index 119c8fa867..7eb04f8f19 100644 --- a/cmake/Modules/Packages/KSPACE.cmake +++ b/cmake/Modules/Packages/KSPACE.cmake @@ -51,13 +51,27 @@ if(FFT_HEFFTE) # if FFT_HEFFTE is enabled, switch the builtin FFT engine with Heffte if(FFT STREQUAL "FFTW3") # respect the backend choice, FFTW or MKL set(HEFFTE_COMPONENTS "FFTW") + set(Heffte_ENABLE_FFTW "ON" CACHE BOOL "Enables FFTW backend for heFFTe") elseif(FFT STREQUAL "MKL") set(HEFFTE_COMPONENTS "MKL") + set(Heffte_ENABLE_MKL "ON" CACHE BOOL "Enables MKL backend for heFFTe") else() message(FATAL_ERROR "Using -DFFT_HEFFTE=ON, requires FFT either FFTW or MKL") endif() - find_package(Heffte 2.3.0 REQUIRED ${HEFFTE_COMPONENTS}) + find_package(Heffte 2.3.0 QUIET COMPONENTS ${HEFFTE_COMPONENTS}) + if (NOT Heffte_FOUND) # download and build + include(FetchContent) + FetchContent_Declare(HEFFTE_PROJECT # using v2.3.0 + URL "https://bitbucket.org/icl/heffte/get/f49e25969bd7abbcb09e338db9a5e59550c8a05a.tar.gz" + URL_HASH SHA256=27c0a8da8f7bc91c8715ecb640721ab7e0454e22f6e3f521fe5acc45c28d60a9 + ) + FetchContent_Populate(HEFFTE_PROJECT) + add_subdirectory(${heffte_project_SOURCE_DIR} ${heffte_project_BINARY_DIR}) + set_target_properties(lmp PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + set_target_properties(lammps PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + endif() + target_compile_definitions(lammps PRIVATE -DHEFFTE) target_link_libraries(lammps PRIVATE Heffte::Heffte) endif() From 77ad06745865dff460e4eb70518c72af8cee3bcd Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Mon, 6 Feb 2023 13:27:50 -0500 Subject: [PATCH 3/9] added documentation --- cmake/CMakeLists.txt | 5 +++++ doc/src/Build_settings.rst | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 28e02bbee7..8e3e38570b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -983,6 +983,11 @@ if(PKG_KSPACE) else() message(STATUS "Using non-threaded FFTs") endif() + if (FFT_HEFFTE) + message(STATUS "Using distributed algorithms from heFTTe") + else() + message(STATUS "Using builtin distributed algorithms") + endif() if(PKG_KOKKOS) if(Kokkos_ENABLE_CUDA) if(FFT STREQUAL "KISS") diff --git a/doc/src/Build_settings.rst b/doc/src/Build_settings.rst index 7576cae3eb..828e4bb2ed 100644 --- a/doc/src/Build_settings.rst +++ b/doc/src/Build_settings.rst @@ -43,6 +43,11 @@ When the KSPACE package is included in a LAMMPS build, the require use of an FFT library to compute 1d FFTs. The KISS FFT library is included with LAMMPS, but other libraries can be faster. LAMMPS can use them if they are available on your system. +Alternatively, LAMMPS can use the +`heFFTe `_ +library for the MPI communication algorithms, +currently heFFTe can be build only with CMake +and the value of FFT should be FFTW3 or MKL. .. tabs:: @@ -53,6 +58,7 @@ LAMMPS can use them if they are available on your system. -D FFT=value # FFTW3 or MKL or KISS, default is FFTW3 if found, else KISS -D FFT_SINGLE=value # yes or no (default), no = double precision -D FFT_PACK=value # array (default) or pointer or memcpy + -D FFT_HEFFTE=value # yes or no (default), yes links to heFFTe .. note:: @@ -76,6 +82,8 @@ LAMMPS can use them if they are available on your system. -D MKL_INCLUDE_DIR=path # ditto for Intel MKL library -D FFT_MKL_THREADS=on # enable using threaded FFTs with MKL libraries -D MKL_LIBRARY=path # path to MKL libraries + -D Heffte_ROOT=path # path to an existing heFFTe installation + .. tab:: Traditional make @@ -170,6 +178,16 @@ Depending on the machine, the size of the FFT grid, the number of processors used, one option may be slightly faster. The default is ARRAY mode. +When using ``-DFFT_HEFFTE`` CMake will first look for an existing install +with hints provided by ``-DHeffte_ROOT``, as recommended by the CMake +standard and note that the name is case sensitive. If CMake cannot find +a heFFTe installation with the correct backend (e.g., FFTW or MKL), +it will attempt to download and build the library automatically. +In this case, LAMMPS CMake will also accept all heFFTe specific variables +listed in the +`heFFTe documentation `_ +and those variables will be passed into the heFFTe build. + ---------- .. _size: From a6e629f4e48f503d82ad281bdb6890157c1a5640 Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Thu, 26 Oct 2023 14:46:08 -0400 Subject: [PATCH 4/9] update variable names --- cmake/CMakeLists.txt | 77 +++++++++++++++++------------ cmake/Modules/Packages/KSPACE.cmake | 16 +++--- src/KSPACE/fft3d_wrap.cpp | 8 +-- src/KSPACE/fft3d_wrap.h | 12 +++-- 4 files changed, 67 insertions(+), 46 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 8e3e38570b..37cb498595 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -971,38 +971,53 @@ if(PKG_KOKKOS) endif() endif() if(PKG_KSPACE) - message(STATUS "<<< FFT settings >>> --- Primary FFT lib: ${FFT}") - if(FFT_SINGLE) - message(STATUS "Using single precision FFTs") - else() - message(STATUS "Using double precision FFTs") - endif() - if(FFT_FFTW_THREADS OR FFT_MKL_THREADS) - message(STATUS "Using threaded FFTs") - else() - message(STATUS "Using non-threaded FFTs") - endif() - if (FFT_HEFFTE) - message(STATUS "Using distributed algorithms from heFTTe") - else() - message(STATUS "Using builtin distributed algorithms") - endif() - if(PKG_KOKKOS) - if(Kokkos_ENABLE_CUDA) - if(FFT STREQUAL "KISS") - message(STATUS "Kokkos FFT: KISS") - else() - message(STATUS "Kokkos FFT: cuFFT") - endif() - elseif(Kokkos_ENABLE_HIP) - if(FFT STREQUAL "KISS") - message(STATUS "Kokkos FFT: KISS") - else() - message(STATUS "Kokkos FFT: hipFFT") - endif() + if (LMP_HEFFTE) + message(STATUS "<<< FFT settings >>> +-- Primary FFT lib: heFFTe") + if (HEFFTE_BACKEND) + message(STATUS "heFFTe backend: ${HEFFTE_BACKEND}") else() - message(STATUS "Kokkos FFT: ${FFT}") + message(STATUS "heFFTe backend: stock (not intended for production)") + endif() + if(FFT_SINGLE) + message(STATUS "Using single precision FFTs") + else() + message(STATUS "Using double precision FFTs") + endif() + else() + message(STATUS "<<< FFT settings >>> +-- Primary FFT lib: ${FFT}") + if(FFT_SINGLE) + message(STATUS "Using single precision FFTs") + else() + message(STATUS "Using double precision FFTs") + endif() + if(FFT_FFTW_THREADS OR FFT_MKL_THREADS) + message(STATUS "Using threaded FFTs") + else() + message(STATUS "Using non-threaded FFTs") + endif() + if (FFT_HEFFTE) + message(STATUS "Using distributed algorithms from heFTTe") + else() + message(STATUS "Using builtin distributed algorithms") + endif() + if(PKG_KOKKOS) + if(Kokkos_ENABLE_CUDA) + if(FFT STREQUAL "KISS") + message(STATUS "Kokkos FFT: KISS") + else() + message(STATUS "Kokkos FFT: cuFFT") + endif() + elseif(Kokkos_ENABLE_HIP) + if(FFT STREQUAL "KISS") + message(STATUS "Kokkos FFT: KISS") + else() + message(STATUS "Kokkos FFT: hipFFT") + endif() + else() + message(STATUS "Kokkos FFT: ${FFT}") + endif() endif() endif() endif() diff --git a/cmake/Modules/Packages/KSPACE.cmake b/cmake/Modules/Packages/KSPACE.cmake index 7eb04f8f19..202009678a 100644 --- a/cmake/Modules/Packages/KSPACE.cmake +++ b/cmake/Modules/Packages/KSPACE.cmake @@ -46,17 +46,21 @@ else() target_compile_definitions(lammps PRIVATE -DFFT_KISS) endif() -option(FFT_HEFFTE "Use heFFTe as the distributed FFT engine." OFF) -if(FFT_HEFFTE) +option(LMP_HEFFTE "Use heFFTe as the distributed FFT engine, supersedes the FFT option." OFF) +if(LMP_HEFFTE) # if FFT_HEFFTE is enabled, switch the builtin FFT engine with Heffte - if(FFT STREQUAL "FFTW3") # respect the backend choice, FFTW or MKL + set(HEFFTE_BACKEND_VALUES FFTW MKL) + set(HEFFTE_BACKEND "" CACHE STRING "Select heFFTe backend, e.g., FFTW or MKL") + set_property(CACHE HEFFTE_BACKEND PROPERTY STRINGS ${HEFFTE_BACKEND_VALUES}) + + if(HEFFTE_BACKEND STREQUAL "FFTW") # respect the backend choice, FFTW or MKL set(HEFFTE_COMPONENTS "FFTW") set(Heffte_ENABLE_FFTW "ON" CACHE BOOL "Enables FFTW backend for heFFTe") - elseif(FFT STREQUAL "MKL") + elseif(HEFFTE_BACKEND STREQUAL "MKL") set(HEFFTE_COMPONENTS "MKL") set(Heffte_ENABLE_MKL "ON" CACHE BOOL "Enables MKL backend for heFFTe") else() - message(FATAL_ERROR "Using -DFFT_HEFFTE=ON, requires FFT either FFTW or MKL") + message(WARNING "HEFFTE_BACKEND not selected, defaulting to 'stock' backend, which is not intended for production") endif() find_package(Heffte 2.3.0 QUIET COMPONENTS ${HEFFTE_COMPONENTS}) @@ -72,7 +76,7 @@ if(FFT_HEFFTE) set_target_properties(lammps PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") endif() - target_compile_definitions(lammps PRIVATE -DHEFFTE) + target_compile_definitions(lammps PRIVATE -DLMP_HEFFTE "-DHEFFTE_${HEFFTE_BACKEND}") target_link_libraries(lammps PRIVATE Heffte::Heffte) endif() diff --git a/src/KSPACE/fft3d_wrap.cpp b/src/KSPACE/fft3d_wrap.cpp index a6b4167d71..c79ba8a780 100644 --- a/src/KSPACE/fft3d_wrap.cpp +++ b/src/KSPACE/fft3d_wrap.cpp @@ -27,7 +27,7 @@ FFT3d::FFT3d(LAMMPS *lmp, MPI_Comm comm, int nfast, int nmid, int nslow, int out_klo, int out_khi, int scaled, int permute, int *nbuf, int usecollective) : Pointers(lmp) { - #ifndef HEFFTE + #ifndef LMP_HEFFTE plan = fft_3d_create_plan(comm,nfast,nmid,nslow, in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, @@ -56,7 +56,7 @@ FFT3d::FFT3d(LAMMPS *lmp, MPI_Comm comm, int nfast, int nmid, int nslow, FFT3d::~FFT3d() { - #ifndef HEFFTE + #ifndef LMP_HEFFTE fft_3d_destroy_plan(plan); #endif } @@ -65,7 +65,7 @@ FFT3d::~FFT3d() void FFT3d::compute(FFT_SCALAR *in, FFT_SCALAR *out, int flag) { - #ifndef HEFFTE + #ifndef LMP_HEFFTE fft_3d((FFT_DATA *) in,(FFT_DATA *) out,flag,plan); #else if (flag == 1) @@ -86,7 +86,7 @@ void FFT3d::compute(FFT_SCALAR *in, FFT_SCALAR *out, int flag) void FFT3d::timing1d(FFT_SCALAR *in, int nsize, int flag) { - #ifndef HEFFTE + #ifndef LMP_HEFFTE fft_1d_only((FFT_DATA *) in,nsize,flag,plan); #endif } diff --git a/src/KSPACE/fft3d_wrap.h b/src/KSPACE/fft3d_wrap.h index f34680d682..505b4b195c 100644 --- a/src/KSPACE/fft3d_wrap.h +++ b/src/KSPACE/fft3d_wrap.h @@ -17,16 +17,18 @@ #include "fft3d.h" // IWYU pragma: export #include "pointers.h" -#ifdef HEFFTE +#ifdef LMP_HEFFTE #include "heffte.h" // select the backend -#if defined(FFT_FFTW3) +#if defined(HEFFTE_FFTW) using heffte_backend = heffte::backend::fftw; -#elif defined(FFT_MKL) +#elif defined(HEFFTE_MKL) using heffte_backend = heffte::backend::mkl; +#elif defined(HEFFTE_) +using heffte_backend = heffte::backend::stock; #endif -#endif // HEFFTE +#endif // LMP_HEFFTE namespace LAMMPS_NS { @@ -41,7 +43,7 @@ class FFT3d : protected Pointers { void timing1d(FFT_SCALAR *, int, int); private: - #ifdef HEFFTE + #ifdef LMP_HEFFTE // the heFFTe plan supersedes the internal fft_plan_3d std::unique_ptr> heffte_plan; std::vector> heffte_workspace; From f75648030f67ec7975ee1702f93582290e5e7f06 Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Tue, 31 Oct 2023 17:06:25 -0400 Subject: [PATCH 5/9] document traditional make --- doc/src/Build_settings.rst | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/doc/src/Build_settings.rst b/doc/src/Build_settings.rst index 828e4bb2ed..d285f1c28c 100644 --- a/doc/src/Build_settings.rst +++ b/doc/src/Build_settings.rst @@ -44,10 +44,11 @@ require use of an FFT library to compute 1d FFTs. The KISS FFT library is included with LAMMPS, but other libraries can be faster. LAMMPS can use them if they are available on your system. Alternatively, LAMMPS can use the -`heFFTe `_ +`heFFTe `_ library for the MPI communication algorithms, -currently heFFTe can be build only with CMake -and the value of FFT should be FFTW3 or MKL. +which comes with many optimizations for special cases, +e.g., leveraging 2D or 3D backend transforms or +better pipelining for packing and communication. .. tabs:: @@ -58,7 +59,7 @@ and the value of FFT should be FFTW3 or MKL. -D FFT=value # FFTW3 or MKL or KISS, default is FFTW3 if found, else KISS -D FFT_SINGLE=value # yes or no (default), no = double precision -D FFT_PACK=value # array (default) or pointer or memcpy - -D FFT_HEFFTE=value # yes or no (default), yes links to heFFTe + -D LMP_HEFFTE=value # yes or no (default), yes links to heFFTe .. note:: @@ -82,6 +83,7 @@ and the value of FFT should be FFTW3 or MKL. -D MKL_INCLUDE_DIR=path # ditto for Intel MKL library -D FFT_MKL_THREADS=on # enable using threaded FFTs with MKL libraries -D MKL_LIBRARY=path # path to MKL libraries + -D HEFFTE_BACKEND=value # FFTW or MKL or empty/undefined for the stock backend -D Heffte_ROOT=path # path to an existing heFFTe installation @@ -119,6 +121,22 @@ and the value of FFT should be FFTW3 or MKL. files in its default search path. You must specify ``FFT_LIB`` with the appropriate FFT libraries to include in the link. + Traditional make can also link to heFFTe using an existing installation + + .. code-block:: make + + include /share/heffte/HeffteMakefile.in + FFT_INC = -DLMP_HEFFTE -DHEFFTE_FFTW $(heffte_include) + FFT_PATH = + FFT_LIB = $(heffte_link) $(heffte_libs) + + The heFFTe install path will contain `HeffteMakefile.in`. + which will define the `heffte_` include variables needed to link to heFFTe from + an external project using traditional make. + The `-DLMP_HEFFTE` is required to switch to using heFFTe, while the optional `-DHEFFTE_FFTW` + selects the desired heFFTe backend, e.g., `-DHEFFTE_FFTW` or `-DHEFFTE_MKL`, + omitting the variable will default to the `stock` backend. + The `KISS FFT library `_ is included in the LAMMPS distribution. It is portable across all platforms. Depending on the size of the FFTs and the number of From d0ae489ddadcd23040a1970ea72f4d5bd96c6187 Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Thu, 9 Nov 2023 11:38:33 -0500 Subject: [PATCH 6/9] addressed some pr comments --- cmake/CMakeLists.txt | 2 +- cmake/Modules/Packages/KSPACE.cmake | 14 ++++++++------ doc/src/Build_settings.rst | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 37cb498595..f7e9b314bd 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -977,7 +977,7 @@ if(PKG_KSPACE) if (HEFFTE_BACKEND) message(STATUS "heFFTe backend: ${HEFFTE_BACKEND}") else() - message(STATUS "heFFTe backend: stock (not intended for production)") + message(STATUS "heFFTe backend: stock (builtin FFT implementation, tested for corrected but not optimized for production)") endif() if(FFT_SINGLE) message(STATUS "Using single precision FFTs") diff --git a/cmake/Modules/Packages/KSPACE.cmake b/cmake/Modules/Packages/KSPACE.cmake index 202009678a..9e8ab21160 100644 --- a/cmake/Modules/Packages/KSPACE.cmake +++ b/cmake/Modules/Packages/KSPACE.cmake @@ -46,7 +46,7 @@ else() target_compile_definitions(lammps PRIVATE -DFFT_KISS) endif() -option(LMP_HEFFTE "Use heFFTe as the distributed FFT engine, supersedes the FFT option." OFF) +option(LMP_HEFFTE "Use heFFTe as the distributed FFT engine, overrides the FFT option." OFF) if(LMP_HEFFTE) # if FFT_HEFFTE is enabled, switch the builtin FFT engine with Heffte set(HEFFTE_BACKEND_VALUES FFTW MKL) @@ -60,20 +60,22 @@ if(LMP_HEFFTE) set(HEFFTE_COMPONENTS "MKL") set(Heffte_ENABLE_MKL "ON" CACHE BOOL "Enables MKL backend for heFFTe") else() - message(WARNING "HEFFTE_BACKEND not selected, defaulting to 'stock' backend, which is not intended for production") + message(WARNING "HEFFTE_BACKEND not selected, defaulting to the builtin 'stock' backend, which is intended for testing and is not optimized for production runs") endif() - find_package(Heffte 2.3.0 QUIET COMPONENTS ${HEFFTE_COMPONENTS}) + find_package(Heffte 2.4.0 QUIET COMPONENTS ${HEFFTE_COMPONENTS}) if (NOT Heffte_FOUND) # download and build include(FetchContent) - FetchContent_Declare(HEFFTE_PROJECT # using v2.3.0 - URL "https://bitbucket.org/icl/heffte/get/f49e25969bd7abbcb09e338db9a5e59550c8a05a.tar.gz" - URL_HASH SHA256=27c0a8da8f7bc91c8715ecb640721ab7e0454e22f6e3f521fe5acc45c28d60a9 + FetchContent_Declare(HEFFTE_PROJECT # using v2.4.0 + URL "https://github.com/icl-utk-edu/heffte/archive/refs/tags/v2.4.0.tar.gz" + URL_HASH SHA256=02310fb4f9688df02f7181667e61c3adb7e38baf79611d80919d47452ff7881d ) FetchContent_Populate(HEFFTE_PROJECT) add_subdirectory(${heffte_project_SOURCE_DIR} ${heffte_project_BINARY_DIR}) set_target_properties(lmp PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") set_target_properties(lammps PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + add_library(Heffte::Heffte INTERFACE IMPORTED GLOBAL) + target_link_libraries(Heffte::Heffte INTERFACE Heffte) endif() target_compile_definitions(lammps PRIVATE -DLMP_HEFFTE "-DHEFFTE_${HEFFTE_BACKEND}") diff --git a/doc/src/Build_settings.rst b/doc/src/Build_settings.rst index d285f1c28c..b355d08238 100644 --- a/doc/src/Build_settings.rst +++ b/doc/src/Build_settings.rst @@ -47,7 +47,7 @@ Alternatively, LAMMPS can use the `heFFTe `_ library for the MPI communication algorithms, which comes with many optimizations for special cases, -e.g., leveraging 2D or 3D backend transforms or +e.g., leveraging 2D and 3D backend transforms and better pipelining for packing and communication. .. tabs:: From bc7d0f5d504aabe1d711e5881ce932079d54b506 Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Wed, 15 Nov 2023 11:53:12 -0500 Subject: [PATCH 7/9] renamed cmake option --- cmake/Modules/Packages/KSPACE.cmake | 4 ++-- doc/src/Build_settings.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/Modules/Packages/KSPACE.cmake b/cmake/Modules/Packages/KSPACE.cmake index 9e8ab21160..7e40e50941 100644 --- a/cmake/Modules/Packages/KSPACE.cmake +++ b/cmake/Modules/Packages/KSPACE.cmake @@ -46,8 +46,8 @@ else() target_compile_definitions(lammps PRIVATE -DFFT_KISS) endif() -option(LMP_HEFFTE "Use heFFTe as the distributed FFT engine, overrides the FFT option." OFF) -if(LMP_HEFFTE) +option(FFT_USE_HEFFTE "Use heFFTe as the distributed FFT engine, overrides the FFT option." OFF) +if(FFT_USE_HEFFTE) # if FFT_HEFFTE is enabled, switch the builtin FFT engine with Heffte set(HEFFTE_BACKEND_VALUES FFTW MKL) set(HEFFTE_BACKEND "" CACHE STRING "Select heFFTe backend, e.g., FFTW or MKL") diff --git a/doc/src/Build_settings.rst b/doc/src/Build_settings.rst index b355d08238..630be1d8eb 100644 --- a/doc/src/Build_settings.rst +++ b/doc/src/Build_settings.rst @@ -59,7 +59,7 @@ better pipelining for packing and communication. -D FFT=value # FFTW3 or MKL or KISS, default is FFTW3 if found, else KISS -D FFT_SINGLE=value # yes or no (default), no = double precision -D FFT_PACK=value # array (default) or pointer or memcpy - -D LMP_HEFFTE=value # yes or no (default), yes links to heFFTe + -D FFT_USE_HEFFTE=value # yes or no (default), yes links to heFFTe .. note:: From 3c331321b3b5c737f975bc1653cff3c1a660826e Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Wed, 15 Nov 2023 17:16:04 -0500 Subject: [PATCH 8/9] update the naming convention --- cmake/Modules/Packages/KSPACE.cmake | 14 +++++++------- doc/src/Build_settings.rst | 8 ++++---- src/KSPACE/fft3d_wrap.cpp | 8 ++++---- src/KSPACE/fft3d_wrap.h | 12 ++++++------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/cmake/Modules/Packages/KSPACE.cmake b/cmake/Modules/Packages/KSPACE.cmake index 7e40e50941..9c9c879cd4 100644 --- a/cmake/Modules/Packages/KSPACE.cmake +++ b/cmake/Modules/Packages/KSPACE.cmake @@ -49,18 +49,18 @@ endif() option(FFT_USE_HEFFTE "Use heFFTe as the distributed FFT engine, overrides the FFT option." OFF) if(FFT_USE_HEFFTE) # if FFT_HEFFTE is enabled, switch the builtin FFT engine with Heffte - set(HEFFTE_BACKEND_VALUES FFTW MKL) - set(HEFFTE_BACKEND "" CACHE STRING "Select heFFTe backend, e.g., FFTW or MKL") - set_property(CACHE HEFFTE_BACKEND PROPERTY STRINGS ${HEFFTE_BACKEND_VALUES}) + set(FFT_HEFFTE_BACKEND_VALUES FFTW MKL) + set(FFT_HEFFTE_BACKEND "" CACHE STRING "Select heFFTe backend, e.g., FFTW or MKL") + set_property(CACHE FFT_HEFFTE_BACKEND PROPERTY STRINGS ${FFT_HEFFTE_BACKEND_VALUES}) - if(HEFFTE_BACKEND STREQUAL "FFTW") # respect the backend choice, FFTW or MKL + if(FFT_HEFFTE_BACKEND STREQUAL "FFTW") # respect the backend choice, FFTW or MKL set(HEFFTE_COMPONENTS "FFTW") set(Heffte_ENABLE_FFTW "ON" CACHE BOOL "Enables FFTW backend for heFFTe") - elseif(HEFFTE_BACKEND STREQUAL "MKL") + elseif(FFT_HEFFTE_BACKEND STREQUAL "MKL") set(HEFFTE_COMPONENTS "MKL") set(Heffte_ENABLE_MKL "ON" CACHE BOOL "Enables MKL backend for heFFTe") else() - message(WARNING "HEFFTE_BACKEND not selected, defaulting to the builtin 'stock' backend, which is intended for testing and is not optimized for production runs") + message(WARNING "FFT_HEFFTE_BACKEND not selected, defaulting to the builtin 'stock' backend, which is intended for testing and is not optimized for production runs") endif() find_package(Heffte 2.4.0 QUIET COMPONENTS ${HEFFTE_COMPONENTS}) @@ -78,7 +78,7 @@ if(FFT_USE_HEFFTE) target_link_libraries(Heffte::Heffte INTERFACE Heffte) endif() - target_compile_definitions(lammps PRIVATE -DLMP_HEFFTE "-DHEFFTE_${HEFFTE_BACKEND}") + target_compile_definitions(lammps PRIVATE -DFFT_HEFFTE "-DFFT_HEFFTE_${FFT_HEFFTE_BACKEND}") target_link_libraries(lammps PRIVATE Heffte::Heffte) endif() diff --git a/doc/src/Build_settings.rst b/doc/src/Build_settings.rst index 630be1d8eb..d0004da606 100644 --- a/doc/src/Build_settings.rst +++ b/doc/src/Build_settings.rst @@ -83,7 +83,7 @@ better pipelining for packing and communication. -D MKL_INCLUDE_DIR=path # ditto for Intel MKL library -D FFT_MKL_THREADS=on # enable using threaded FFTs with MKL libraries -D MKL_LIBRARY=path # path to MKL libraries - -D HEFFTE_BACKEND=value # FFTW or MKL or empty/undefined for the stock backend + -D FFT_HEFFTE_BACKEND=value # FFTW or MKL or empty/undefined for the stock backend -D Heffte_ROOT=path # path to an existing heFFTe installation @@ -126,15 +126,15 @@ better pipelining for packing and communication. .. code-block:: make include /share/heffte/HeffteMakefile.in - FFT_INC = -DLMP_HEFFTE -DHEFFTE_FFTW $(heffte_include) + FFT_INC = -DFFT_HEFFTE -DFFT_HEFFTE_FFTW $(heffte_include) FFT_PATH = FFT_LIB = $(heffte_link) $(heffte_libs) The heFFTe install path will contain `HeffteMakefile.in`. which will define the `heffte_` include variables needed to link to heFFTe from an external project using traditional make. - The `-DLMP_HEFFTE` is required to switch to using heFFTe, while the optional `-DHEFFTE_FFTW` - selects the desired heFFTe backend, e.g., `-DHEFFTE_FFTW` or `-DHEFFTE_MKL`, + The `-DFFT_HEFFTE` is required to switch to using heFFTe, while the optional `-DFFT_HEFFTE_FFTW` + selects the desired heFFTe backend, e.g., `-DFFT_HEFFTE_FFTW` or `-DFFT_HEFFTE_MKL`, omitting the variable will default to the `stock` backend. The `KISS FFT library `_ is diff --git a/src/KSPACE/fft3d_wrap.cpp b/src/KSPACE/fft3d_wrap.cpp index c79ba8a780..7b00543eea 100644 --- a/src/KSPACE/fft3d_wrap.cpp +++ b/src/KSPACE/fft3d_wrap.cpp @@ -27,7 +27,7 @@ FFT3d::FFT3d(LAMMPS *lmp, MPI_Comm comm, int nfast, int nmid, int nslow, int out_klo, int out_khi, int scaled, int permute, int *nbuf, int usecollective) : Pointers(lmp) { - #ifndef LMP_HEFFTE + #ifndef FFT_HEFFTE plan = fft_3d_create_plan(comm,nfast,nmid,nslow, in_ilo,in_ihi,in_jlo,in_jhi,in_klo,in_khi, out_ilo,out_ihi,out_jlo,out_jhi,out_klo,out_khi, @@ -56,7 +56,7 @@ FFT3d::FFT3d(LAMMPS *lmp, MPI_Comm comm, int nfast, int nmid, int nslow, FFT3d::~FFT3d() { - #ifndef LMP_HEFFTE + #ifndef FFT_HEFFTE fft_3d_destroy_plan(plan); #endif } @@ -65,7 +65,7 @@ FFT3d::~FFT3d() void FFT3d::compute(FFT_SCALAR *in, FFT_SCALAR *out, int flag) { - #ifndef LMP_HEFFTE + #ifndef FFT_HEFFTE fft_3d((FFT_DATA *) in,(FFT_DATA *) out,flag,plan); #else if (flag == 1) @@ -86,7 +86,7 @@ void FFT3d::compute(FFT_SCALAR *in, FFT_SCALAR *out, int flag) void FFT3d::timing1d(FFT_SCALAR *in, int nsize, int flag) { - #ifndef LMP_HEFFTE + #ifndef FFT_HEFFTE fft_1d_only((FFT_DATA *) in,nsize,flag,plan); #endif } diff --git a/src/KSPACE/fft3d_wrap.h b/src/KSPACE/fft3d_wrap.h index 505b4b195c..04b828b7de 100644 --- a/src/KSPACE/fft3d_wrap.h +++ b/src/KSPACE/fft3d_wrap.h @@ -17,18 +17,18 @@ #include "fft3d.h" // IWYU pragma: export #include "pointers.h" -#ifdef LMP_HEFFTE +#ifdef FFT_HEFFTE #include "heffte.h" // select the backend -#if defined(HEFFTE_FFTW) +#if defined(FFT_HEFFTE_FFTW) using heffte_backend = heffte::backend::fftw; -#elif defined(HEFFTE_MKL) +#elif defined(FFT_HEFFTE_MKL) using heffte_backend = heffte::backend::mkl; -#elif defined(HEFFTE_) +#else using heffte_backend = heffte::backend::stock; #endif -#endif // LMP_HEFFTE +#endif // FFT_HEFFTE namespace LAMMPS_NS { @@ -43,7 +43,7 @@ class FFT3d : protected Pointers { void timing1d(FFT_SCALAR *, int, int); private: - #ifdef LMP_HEFFTE + #ifdef FFT_HEFFTE // the heFFTe plan supersedes the internal fft_plan_3d std::unique_ptr> heffte_plan; std::vector> heffte_workspace; From e41d9cb7467563af6102fdb0d7c693f6a8d9a126 Mon Sep 17 00:00:00 2001 From: Miroslav Stoyanov Date: Fri, 1 Dec 2023 15:21:23 -0500 Subject: [PATCH 9/9] added explanations about the stock backend to the cmake --- doc/src/Build_settings.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/src/Build_settings.rst b/doc/src/Build_settings.rst index d0004da606..e2b096c6e0 100644 --- a/doc/src/Build_settings.rst +++ b/doc/src/Build_settings.rst @@ -86,6 +86,12 @@ better pipelining for packing and communication. -D FFT_HEFFTE_BACKEND=value # FFTW or MKL or empty/undefined for the stock backend -D Heffte_ROOT=path # path to an existing heFFTe installation + .. note:: + + heFFTe comes with a builtin stock backend for FFTs; however, the backend + is intended for testing purposes and is not performance optimized + for large scale production runs. + .. tab:: Traditional make @@ -136,6 +142,8 @@ better pipelining for packing and communication. The `-DFFT_HEFFTE` is required to switch to using heFFTe, while the optional `-DFFT_HEFFTE_FFTW` selects the desired heFFTe backend, e.g., `-DFFT_HEFFTE_FFTW` or `-DFFT_HEFFTE_MKL`, omitting the variable will default to the `stock` backend. + The heFFTe `stock` backend is intended to be used for testing and debugging, + but is not performance optimized for large scale production runs. The `KISS FFT library `_ is included in the LAMMPS distribution. It is portable across all