Skip to content

Commit

Permalink
Merge pull request #47 from CExA-project/improve-cmake
Browse files Browse the repository at this point in the history
Improve cmake
  • Loading branch information
yasahi-hpc authored Feb 12, 2024
2 parents 9b47ab4 + b12bca9 commit caf52c1
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 17 deletions.
54 changes: 42 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
cmake_minimum_required(VERSION 3.22)
project(KokkosFFT LANGUAGES CXX)

# Add cmake helpers for FFTW
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(KOKKOSFFT_TOP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})

# Set project
project(
KokkosFFT
VERSION 0.0.0
LANGUAGES CXX
)

# Add cmake helpers
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# Options
option(BUILD_EXAMPLES "Build KokkosFFT examples" ON)
Expand All @@ -11,26 +19,47 @@ option(KokkosFFT_INTERNAL_Kokkos "Build internal Kokkos instead of relying on ex
option(KokkosFFT_ENABLE_BENCHMARK "Build benchmarks for KokkosFFT" OFF)

# Version information
set(KokkosFFT_VERSION_MAJOR 0)
set(KokkosFFT_VERSION_MINOR 0)
set(KokkosFFT_VERSION_PATCH 00)
set(KokkosFFT_VERSION "${KokkosFFT_VERSION_MAJOR}.${KokkosFFT_VERSION_MINOR}.${KokkosFFT_VERSION_PATCH}")
set(KOKKOSFFT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(KOKKOSFFT_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(KOKKOSFFT_VERSION_PATCH ${PROJECT_VERSION_PATCH})

#Set variables for config file
math(EXPR KOKKOSFFT_VERSION "${KokkosFFT_VERSION_MAJOR} * 10000 + ${KokkosFFT_VERSION_MINOR} * 100 + ${KokkosFFT_VERSION_PATCH}")
math(EXPR KOKKOSFFT_VERSION_MAJOR "${KOKKOSFFT_VERSION} / 10000")
math(EXPR KOKKOSFFT_VERSION_MINOR "${KOKKOSFFT_VERSION} / 100 % 100")
math(EXPR KOKKOSFFT_VERSION_PATCH "${KOKKOSFFT_VERSION} % 100")
set(KOKKOS_REQUIRED_VERSION "4.2.00")

if (NOT KokkosFFT_INTERNAL_Kokkos)
# First check, Kokkos is added as subdirectory or not
if(NOT TARGET Kokkos::kokkos)
find_package(Kokkos REQUIRED)
endif()

# Kokkos version check
include(Kokkos_Version_Check)
check_minimum_required_kokkos(${KOKKOS_REQUIRED_VERSION})
else ()
add_subdirectory(tpls/kokkos)
endif ()

# Set tpls
set(KOKKOSFFT_TPL_LIST)
include(KokkosFFT_tpls)
get_tpls_list(KOKKOSFFT_TPL_LIST)

# ==================================================================
# CMake Summary
# ==================================================================

message("")
message(STATUS "KokkosFFT version: ${KOKKOSFFT_VERSION_MAJOR}.${KOKKOSFFT_VERSION_MINOR}.${KOKKOSFFT_VERSION_PATCH}")
message(STATUS "KokkosFFT TPLs:")
if(KOKKOSFFT_TPL_LIST)
foreach(TPL ${KOKKOSFFT_TPL_LIST})
# [TO DO] show more information about the library (like location)
message(STATUS " ${TPL}")
endforeach()
else()
message(STATUS " (None)")
endif()
message("")

# Googletest
include(CTest)
if(BUILD_TESTING)
Expand All @@ -44,6 +73,7 @@ endif()
if(KokkosFFT_ENABLE_BENCHMARK)
option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." OFF)
add_subdirectory(tpls/benchmark)
include(KokkosFFT_Git_Hash)

# [TO DO] Fix this, it detects benchmark not a googlebench
#find_package(benchmark QUIET)
Expand Down
105 changes: 105 additions & 0 deletions cmake/KokkosFFT_Git_Hash.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# https://jonathanhamberg.com/post/cmake-embedding-git-hash/

find_package(Git QUIET)

set(CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR})
set(pre_configure_file ${CURRENT_LIST_DIR}/KokkosFFT_Version_Info.hpp.in)
set(post_configure_file ${CMAKE_BINARY_DIR}/KokkosFFT_Version_Info.hpp)

FUNCTION(check_git_write git_hash git_clean_status)
FILE(
WRITE
${CMAKE_BINARY_DIR}/git-state.txt
"${git_hash}-${git_clean_status}")
ENDFUNCTION()

FUNCTION(check_git_read git_hash)
if(EXISTS ${CMAKE_BINARY_DIR}/git-state.txt)
FILE(STRINGS ${CMAKE_BINARY_DIR}/git-state.txt CONTENT)
LIST(GET CONTENT 0 var)

message(DEBUG "Cached Git hash: ${var}")
SET(${git_hash} ${var} PARENT_SCOPE)
else()
SET(${git_hash} "INVALID" PARENT_SCOPE)
endif()
ENDFUNCTION()

FUNCTION(check_git_version)
if(NOT Git_FOUND OR NOT EXISTS ${KOKKOSFFT_TOP_SOURCE_DIR}/.git)
configure_file(${pre_configure_file} ${post_configure_file} @ONLY)
return()
endif()

# Get the current working branch
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${KOKKOSFFT_TOP_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE)

# Get the latest commit description
execute_process(
COMMAND ${GIT_EXECUTABLE} show -s --format=%s
WORKING_DIRECTORY ${KOKKOSFFT_TOP_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_DESCRIPTION
OUTPUT_STRIP_TRAILING_WHITESPACE)

# Get the latest commit date
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --format=%cI
WORKING_DIRECTORY ${KOKKOSFFT_TOP_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_DATE
OUTPUT_STRIP_TRAILING_WHITESPACE)

# Check if repo is dirty / clean
execute_process(
COMMAND ${GIT_EXECUTABLE} diff-index --quiet HEAD --
WORKING_DIRECTORY ${KOKKOSFFT_TOP_SOURCE_DIR}
RESULT_VARIABLE IS_DIRTY
OUTPUT_STRIP_TRAILING_WHITESPACE)

if(IS_DIRTY EQUAL 0)
set(GIT_CLEAN_STATUS "CLEAN")
else()
set(GIT_CLEAN_STATUS "DIRTY")
endif()

# Get the latest abbreviated commit hash of the working branch
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --format=%h
WORKING_DIRECTORY ${KOKKOSFFT_TOP_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE)

check_git_read(GIT_HASH_CACHE)

# Only update the version header if the hash has changed. This will
# prevent us from rebuilding the project more than we need to.
if(NOT "${GIT_COMMIT_HASH}-${GIT_CLEAN_STATUS}" STREQUAL ${GIT_HASH_CACHE}
OR NOT EXISTS ${post_configure_file})
# Set the GIT_HASH_CACHE variable so the next build won't have
# to regenerate the source file.
check_git_write(${GIT_COMMIT_HASH} ${GIT_CLEAN_STATUS})

configure_file(${pre_configure_file} ${post_configure_file} @ONLY)
message(STATUS "Configured git information in ${post_configure_file}")
endif()
ENDFUNCTION()

FUNCTION(check_version_info)
add_custom_target(
AlwaysCheckGitInBenchmark COMMAND ${CMAKE_COMMAND}
-DRUN_CHECK_GIT_VERSION=1
-DKOKKOSFFT_TOP_SOURCE_DIR=${DKOKKOSFFT_TOP_SOURCE_DIR}
-P ${CURRENT_LIST_DIR}/KokkosFFT_Git_Hash.cmake
BYPRODUCTS ${post_configure_file})

add_dependencies(PerformanceTest_Benchmark AlwaysCheckGitInBenchmark)
check_git_version()
ENDFUNCTION()

# This is used to run this function from an external cmake process.
if(RUN_CHECK_GIT_VERSION)
check_git_version()
endif()
1 change: 0 additions & 1 deletion cmake/KokkosFFT_Version_Info.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ constexpr std::string_view GIT_CLEAN_STATUS = "@GIT_CLEAN_STATUS@";
constexpr std::string_view GIT_COMMIT_DESCRIPTION =
R"message(@GIT_COMMIT_DESCRIPTION@)message";
constexpr std::string_view GIT_COMMIT_DATE = "@GIT_COMMIT_DATE@";
constexpr std::string_view BENCHMARK_VERSION = "@BENCHMARK_VERSION@";

} // namespace Impl
} // namespace KokkosFFT
Expand Down
27 changes: 27 additions & 0 deletions cmake/KokkosFFT_tpls.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function(get_tpls_list tpls_list)
if(Kokkos_ENABLE_CUDA)
list(APPEND tpls_list CUFFT)
elseif(Kokkos_ENABLE_HIP)
list(APPEND tpls_list HIPFFT)
elseif(Kokkos_ENABLE_SYCL)
list(APPEND tpls_list ONEMKL)
elseif(Kokkos_ENABLE_OPENMP)
list(APPEND tpls_list FFTW_OPENMP)
elseif(Kokkos_ENABLE_THREADS)
list(APPEND tpls_list FFTW_THREADS)
elseif(Kokkos_ENABLE_SERIAL)
list(APPEND tpls_list FFTW)
endif()

if(KokkosFFT_ENABLE_HOST_AND_DEVICE)
if(Kokkos_ENABLE_OPENMP)
list(APPEND tpls_list FFTW_OPENMP)
elseif(Kokkos_ENABLE_THREADS)
list(APPEND tpls_list FFTW_THREADS)
else()
list(APPEND tpls_list FFTW)
endif()
endif()

set(${tpls_list} ${${tpls_list}} PARENT_SCOPE)
endfunction()
11 changes: 11 additions & 0 deletions cmake/Kokkos_Version_Check.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function(check_minimum_required_kokkos kokkos_required_version)
if(${Kokkos_VERSION} STREQUAL "")
message(FATAL_ERROR "Kokkos_VERSION not set. Cannot check Kokkos satisfies the minimum required version.")
else()
if(${Kokkos_VERSION} VERSION_GREATER_EQUAL ${kokkos_required_version})
message(STATUS "Found Kokkos version ${Kokkos_VERSION} at ${Kokkos_DIR}")
else()
message(FATAL_ERROR "Kokkos FFT ${KOKKOSFFT_VERSION} requires ${kokkos_required_version} or later.")
endif()
endif()
endfunction()
4 changes: 0 additions & 4 deletions fft/perf_test/Benchmark_Context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ inline void add_version_info() {
benchmark::AddCustomContext("GIT_COMMIT_DATE",
std::string(GIT_COMMIT_DATE));
}
if (!BENCHMARK_VERSION.empty()) {
benchmark::AddCustomContext("GOOGLE_BENCHMARK_VERSION",
std::string(BENCHMARK_VERSION));
}
}

inline void add_env_info() {
Expand Down
2 changes: 2 additions & 0 deletions fft/perf_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
set(BENCHMARK_NAME PerformanceTest_Benchmark)

check_git_version()

add_executable(
${BENCHMARK_NAME}
BenchmarkMain.cpp
Expand Down

0 comments on commit caf52c1

Please sign in to comment.