1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
|
cmake_minimum_required(VERSION 3.22)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE FORCE)
# include our cmake snippets
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# =================================================================================================
# REQUIRE OUT-OF-SOURCE BUILDS
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH)
if (EXISTS "${LOC_PATH}")
message(
FATAL_ERROR
"You cannot build in a source directory (or any directory with a CMakeLists.txt file). Please make a build subdirectory."
)
endif ()
# =================================================================================================
# PROJECT AND VERSION
include(GetGitRevisionDescription)
git_describe(GIT_DESC)
if (GIT_DESC)
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_DESC}")
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR
"${GIT_DESC}")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH
"${GIT_DESC}")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+(.*)" "\\1" VERSION_GIT
"${GIT_DESC}")
git_local_changes(GIT_STATE)
if ("${GIT_STATE}" STREQUAL "DIRTY")
set(VERSION_GIT "${VERSION_GIT}-dirty")
endif ()
execute_process(
COMMAND git log -1 --format=%ai
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_DATE
OUTPUT_STRIP_TRAILING_WHITESPACE)
# take only the date from the git timestamp:
string(REGEX REPLACE "^([0-9\\-]+) .*" "\\1" VERSION_DATE
"${GIT_COMMIT_DATE}")
else ()
file(STRINGS VERSION VERSION_INFO)
foreach (line ${VERSION_INFO})
if (${line} MATCHES "^([^#].*)=[ \t]*(.*)$")
set(key ${CMAKE_MATCH_1})
set(value ${CMAKE_MATCH_2})
string(REGEX REPLACE "[ \t\n]+$" "" key "${key}")
string(REGEX REPLACE "[ \t\n]+$" "" value "${value}")
set(VERSION_${key} "${value}")
continue()
endif ()
endforeach ()
endif ()
project(
dbcsr
DESCRIPTION
"DBCSR: Distributed Block Compressed Sparse Row matrix library (https://dbcsr.cp2k.org)"
)
set(dbcsr_VERSION
${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_GIT})
set(dbcsr_APIVERSION ${VERSION_MAJOR}.${VERSION_MINOR})
# =================================================================================================
# OPTIONS
include(CMakeDependentOption)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
option(USE_OPENMP "Build with OpenMP support" ON)
option(USE_MPI "Build with MPI support" ON)
option(USE_MPI_F08 "Build with the mpi_f08 module support" OFF)
cmake_dependent_option(
WITH_C_API "Build the C API (ISO_C_BINDINGS)" ON "USE_MPI" OFF
)# the ISO_C_BINDINGS require MPI unconditionally
cmake_dependent_option(WITH_EXAMPLES "Build the examples" ON "USE_MPI" OFF
)# all examples require MPI
set(TEST_MPI_RANKS
2
CACHE STRING "Number of MPI ranks for testing")
set(TEST_OMP_THREADS
2
CACHE STRING "Number of OpenMP threads for testing")
set(USE_SMM
"blas"
CACHE STRING
"Small Matrix Multiplication implementation to use (default: blas)")
set_property(CACHE USE_SMM PROPERTY STRINGS blas libxsmm)
set(USE_ACCEL
""
CACHE STRING "Build with acceleration support (default: none)")
set_property(CACHE USE_ACCEL PROPERTY STRINGS "" opencl cuda hip)
set(SUPPORTED_CUDA_ARCHITECTURES
K20X
K40
K80
P100
V100
A100
H100)
set(SUPPORTED_HIP_ARCHITECTURES Mi50 Mi100 Mi250)
set(WITH_GPU
$<IF:$<STREQUAL:${USE_ACCEL},"opencl">,"","P100">
CACHE
STRING
"Select GPU arch. and embed parameters (default: CUDA/HIP=P100, OPENCL=all)"
)
set(WITH_GPU_PARAMS "${WITH_GPU}")
set_property(CACHE WITH_GPU PROPERTY STRINGS ${SUPPORTED_CUDA_ARCHITECTURES}
${SUPPORTED_HIP_ARCHITECTURES})
option(WITH_CUDA_PROFILING "Enable profiling within CUDA" OFF)
option(WITH_HIP_PROFILING "Enable profiling within HIP" OFF)
# =================================================================================================
# LANGUAGES AND TESTING
enable_language(Fortran)
if (WITH_C_API AND WITH_EXAMPLES)
enable_language(CXX)
enable_language(C)
endif ()
# always use at least C++11
set(CMAKE_CXX_STANDARD 11)
# =================================== OpenMP
if (USE_OPENMP)
find_package(OpenMP REQUIRED)
endif ()
if ((USE_ACCEL MATCHES "opencl") AND (NOT USE_SMM MATCHES "libxsmm"))
message(FATAL_ERROR "OpenCL requires USE_SMM=libxsmm")
endif ()
# =================================== SMM (Small Matrix-Matrix multiplication)
if (USE_SMM MATCHES "blas")
message(STATUS "Using BLAS for Small Matrix Multiplication")
elseif (USE_SMM MATCHES "libxsmm")
message(STATUS "Using libxsmm for Small Matrix Multiplication")
else ()
message(FATAL_ERROR "Unknown SMM library specified")
endif ()
# =================================== LIBXSMM (rely on pkg-config)
if (USE_SMM MATCHES "libxsmm")
find_package(PkgConfig REQUIRED)
if (USE_OPENMP)
if (NOT USE_SMM MATCHES "libxsmm-shared")
pkg_check_modules(LIBXSMMEXT IMPORTED_TARGET GLOBAL libxsmmext-static)
endif ()
if (NOT LIBXSMMEXT_FOUND)
pkg_check_modules(LIBXSMMEXT REQUIRED IMPORTED_TARGET GLOBAL libxsmmext)
endif ()
endif ()
if (NOT USE_SMM MATCHES "libxsmm-shared")
pkg_check_modules(LIBXSMM IMPORTED_TARGET GLOBAL libxsmmf-static)
endif ()
if (NOT LIBXSMM_FOUND)
pkg_check_modules(LIBXSMM REQUIRED IMPORTED_TARGET GLOBAL libxsmmf)
endif ()
endif ()
# =================================== BLAS & LAPACK, PkgConfig
find_package(LAPACK REQUIRED) # needed for some of the integrated test routines,
# also calls find_package(BLAS)
# =================================== Python this module looks preferably for
# version 3 of Python. If not found, version 2 is searched. In CMake 3.15, if a
# python virtual environment is activated, it will search the virtual
# environment for a python interpreter before searching elsewhere in the system.
# In CMake <3.15, the system is searched before the virtual environment.
if (NOT Python_EXECUTABLE)
# If the python interpreter is not specified (command line), try finding it:
find_package(
Python
COMPONENTS Interpreter
REQUIRED)
endif ()
# =================================== MPI
if (USE_MPI)
get_property(REQUIRED_MPI_COMPONENTS GLOBAL PROPERTY ENABLED_LANGUAGES)
if (NOT CMAKE_CROSSCOMPILING) # when cross compiling, assume the users know
# what they are doing
set(MPI_DETERMINE_LIBRARY_VERSION TRUE)
endif ()
find_package(
MPI
COMPONENTS ${REQUIRED_MPI_COMPONENTS}
REQUIRED)
if (NOT MPI_Fortran_HAVE_F90_MODULE)
message(
FATAL_ERROR
"\
The listed MPI implementation does not provide the required mpi.mod interface. \
When using the GNU compiler in combination with Intel MPI, please use the \
Intel MPI compiler wrappers. Check the INSTALL.md for more information.")
endif ()
if (USE_MPI_F08)
if (NOT MPI_Fortran_HAVE_F08_MODULE)
message(
FATAL_ERROR
"The listed MPI implementation does not provide the required mpi_f08.mod interface."
)
endif ()
endif ()
if ("${MPI_Fortran_LIBRARY_VERSION_STRING}" MATCHES "Open MPI v2.1"
OR "${MPI_Fortran_LIBRARY_VERSION_STRING}" MATCHES "Open MPI v3.1")
message(
WARNING
"RMA with ${MPI_Fortran_LIBRARY_VERSION_STRING} is not supported due to issues with its implementation."
" Please use a newer version of OpenMPI or switch to MPICH if you plan on using MPI-RMA."
)
endif ()
endif ()
# =================================== GPU backends
if (USE_ACCEL MATCHES "opencl")
find_package(OpenCL REQUIRED)
enable_language(C)
endif ()
if (USE_ACCEL MATCHES "cuda|hip")
enable_language(CXX)
set(GPU_ARCH_NUMBER_K20X 35)
set(GPU_ARCH_NUMBER_K40 35)
set(GPU_ARCH_NUMBER_K80 37)
set(GPU_ARCH_NUMBER_P100 60)
set(GPU_ARCH_NUMBER_V100 70)
set(GPU_ARCH_NUMBER_A100 80)
set(GPU_ARCH_NUMBER_H100 90)
set(GPU_ARCH_NUMBER_Mi50 gfx906)
set(GPU_ARCH_NUMBER_Mi100 gfx908)
set(GPU_ARCH_NUMBER_Mi250 gfx90a)
endif ()
if (USE_ACCEL MATCHES "cuda")
enable_language(CUDA)
find_package(CUDAToolkit REQUIRED)
if (CUDAToolkit_VERSION LESS 5.5)
message(FATAL_ERROR "CUDA version >= 5.5 is required.")
endif ()
# Make sure the GPU required is supported
list(FIND SUPPORTED_CUDA_ARCHITECTURES ${WITH_GPU} GPU_SUPPORTED)
if (GPU_SUPPORTED EQUAL -1)
message(
FATAL_ERROR "GPU architecture requested (${WITH_GPU}) is not supported. "
"Please choose from: ${SUPPORTED_CUDA_ARCHITECTURES}")
endif ()
# set cuda architecture number and compilation flags
set(ACC_ARCH_NUMBER ${GPU_ARCH_NUMBER_${WITH_GPU}})
message(STATUS "GPU target architecture: " ${WITH_GPU})
message(STATUS "Kernel parameters: " ${WITH_GPU_PARAMS})
message(STATUS "GPU architecture number: " ${ACC_ARCH_NUMBER})
message(STATUS "GPU profiling enabled: " ${WITH_CUDA_PROFILING})
endif ()
if (USE_ACCEL MATCHES "hip")
if (NOT CMAKE_HIP_ARCHITECTURES)
set(CMAKE_HIP_ARCHITECTURES OFF)
endif ()
enable_language(HIP)
# Make sure the GPU required is supported
list(FIND SUPPORTED_HIP_ARCHITECTURES ${WITH_GPU} GPU_SUPPORTED)
if (GPU_SUPPORTED EQUAL -1)
message(
FATAL_ERROR "GPU architecture requested (${WITH_GPU}) is not supported. "
"Please choose from: ${SUPPORTED_HIP_ARCHITECTURES}")
endif ()
# ROCm is typically installed in /opt/rocm; otherwise let the user set
# ROCM_PATH as an environment variable or define.
if (NOT DEFINED ROCM_PATH)
if (NOT DEFINED ENV{ROCM_PATH})
set(ROCM_PATH
"/opt/rocm"
CACHE PATH "Path to ROCm installation")
else ()
set(ROCM_PATH
$ENV{ROCM_PATH}
CACHE PATH "Path to ROCm installation")
endif ()
endif ()
# Notice: this is not FindHIP.cmake for hip language support, but
# hip-config.cmake which contains targets like hip::host for jitting.
find_package(hip CONFIG REQUIRED HINTS ${ROCM_PATH})
message(STATUS "Build with HIP ${hip_VERSION}")
if (hip_VERSION LESS 4.4.0)
message(FATAL_ERROR "HIP version >= 4.4.0 is required.")
endif ()
set(ACC_ARCH_NUMBER ${GPU_ARCH_NUMBER_${WITH_GPU}})
message(STATUS "GPU target architecture: " ${WITH_GPU})
message(STATUS "Kernel parameters: " ${WITH_GPU_PARAMS})
message(STATUS "GPU architecture number: " ${ACC_ARCH_NUMBER})
message(STATUS "GPU profiling enabled: " ${WITH_HIP_PROFILING})
# =================================== BLAS on GPU backend
find_package(hipblas CONFIG REQUIRED HINTS ${ROCM_PATH})
endif ()
# =================================================================================================
# OPTION HANDLING
# make sure that the default build type is RELEASE
set(default_build_type "Release")
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(
STATUS
"Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE
"${default_build_type}"
CACHE STRING
"Choose the type of build, options are: Debug Release Coverage."
FORCE)
# set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"Coverage")
endif ()
# compiler configuration could have impacted package discovery (above)
include(CompilerConfiguration)
include(CheckCompilerSupport)
# subdirectories
add_subdirectory(src)
include(CTest)
if (BUILD_TESTING)
add_subdirectory(tests)
endif ()
if (WITH_EXAMPLES)
add_subdirectory(examples)
endif ()
add_subdirectory(docs)
include(CustomTargets)
# Disable LTO
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE FORCE)
|