-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathCMakeLists.txt
324 lines (274 loc) · 13.9 KB
/
CMakeLists.txt
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
#
# Copyright 2023 Benjamin Worpitz, Erik Zenker, Axel Hübl, Jan Stephan, René Widera, Jeffrey Kelling, Andrea Bocci,
# Bernhard Manfred Gruber, Aurora Perego
# SPDX-License-Identifier: MPL-2.0
#
cmake_minimum_required(VERSION 3.20)
project(alpaka CXX)
# Add append compiler flags to a variable or target
#
# This method is automatically documenting all compile flags added into the variables
# alpaka_COMPILER_OPTIONS_HOST, alpaka_COMPILER_OPTIONS_DEVICE.
#
# scope - which compiler is effected: DEVICE, HOST, or HOST_DEVICE
# type - type of 'name': var, list, or target
# var: space separated list
# list: is semicolon separated
# name - name of the variable or target
# ... - parameter to appended to the variable or target 'name'
function(alpaka_set_compiler_options scope type name)
if(scope STREQUAL HOST)
set(alpaka_COMPILER_OPTIONS_HOST ${alpaka_COMPILER_OPTIONS_HOST} ${ARGN} PARENT_SCOPE)
elseif(scope STREQUAL DEVICE)
set(alpaka_COMPILER_OPTIONS_DEVICE ${alpaka_COMPILER_OPTIONS_DEVICE} ${ARGN} PARENT_SCOPE)
elseif(scope STREQUAL HOST_DEVICE)
set(alpaka_COMPILER_OPTIONS_HOST ${alpaka_COMPILER_OPTIONS_HOST} ${ARGN} PARENT_SCOPE)
set(alpaka_COMPILER_OPTIONS_DEVICE ${alpaka_COMPILER_OPTIONS_DEVICE} ${ARGN} PARENT_SCOPE)
else()
message(FATAL_ERROR "alpaka_set_compiler_option 'scope' unknown, value must be 'HOST', 'DEVICE', or 'HOST_DEVICE'.")
endif()
if(type STREQUAL "list")
set(${name} ${${name}} ${ARGN} PARENT_SCOPE)
elseif(type STREQUAL "var")
foreach(arg IN LISTS ARGN)
set(tmp "${tmp} ${arg}")
endforeach()
set(${name} "${${name}} ${tmp}" PARENT_SCOPE)
elseif(type STREQUAL "target")
foreach(arg IN LISTS ARGN)
target_compile_options(${name} INTERFACE ${arg})
endforeach()
else()
message(FATAL_ERROR "alpaka_set_compiler_option 'type=${type}' unknown, value must be 'list', 'var', or 'target'.")
endif()
endfunction()
# Compiler options
macro(alpaka_compiler_option name description default)
if(NOT DEFINED alpaka_${name})
set(alpaka_${name} ${default} CACHE STRING "${description}")
set_property(CACHE alpaka_${name} PROPERTY STRINGS "DEFAULT;ON;OFF")
endif()
endmacro()
# Check if compiler supports required C++ standard.
#
# language - can be CXX, HIP or CUDA
# min_cxx_standard - C++ standard which is the minimum requirement
function(checkCompilerCXXSupport language min_cxx_standard)
string(TOUPPER "${language}" language_upper_case)
string(TOLOWER "${language}" language_lower_case)
if(NOT "${language_lower_case}_std_${min_cxx_standard}" IN_LIST CMAKE_${language_upper_case}_COMPILE_FEATURES)
message(FATAL_ERROR "The ${language_upper_case} compiler does not support C++ ${min_cxx_standard}. \
Please upgrade your compiler or use alpaka 2.0 which supports C++20.")
endif()
endfunction()
set(alpaka_CXX_STANDARD 20)
checkCompilerCXXSupport(CXX ${alpaka_CXX_STANDARD})
set(CMAKE_CXX_STANDARD ${alpaka_CXX_STANDARD})
# This file's directory.
set(_alpaka_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR})
include("${_alpaka_ROOT_DIR}/cmake/addExecutable.cmake")
# Add alpaka_ADD_LIBRARY function.
include("${_alpaka_ROOT_DIR}/cmake/addLibrary.cmake")
# check for CUDA/HIP language support
include(CheckLanguage)
add_library(alpaka INTERFACE)
target_include_directories(${PROJECT_NAME} INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20)
option(alpaka_API_CUDA "Enable the CUDA GPU back-end" OFF)
option(alpaka_API_HIP "Enable the HIP GPU back-end" OFF)
option(alpaka_API_OMP "Enable the OMP back-end" ON)
## OpenMP
if(alpaka_API_OMP)
find_package(OpenMP REQUIRED COMPONENTS CXX)
target_link_libraries(alpaka INTERFACE OpenMP::OpenMP_CXX)
endif()
## CUDA
if(alpaka_API_CUDA)
check_language(CUDA)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:--expt-relaxed-constexpr>")
option(alpaka_CUDA_EXPT_EXTENDED_LAMBDA "Enable CUDA extended lambda support " ON)
if(alpaka_CUDA_EXPT_EXTENDED_LAMBDA)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:--extended-lambda>")
endif()
alpaka_compiler_option(CUDA_SHOW_REGISTER "Show kernel registers and create device ASM" DEFAULT)
if(alpaka_CUDA_SHOW_REGISTER STREQUAL ON)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:-Xptxas -v>")
endif()
alpaka_compiler_option(CUDA_KEEP_FILES "Keep all intermediate files that are generated during internal compilation steps 'CMakeFiles/<targetname>.dir'" DEFAULT)
if(alpaka_CUDA_KEEP_FILES STREQUAL ON)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:--keep>")
endif()
option(alpaka_CUDA_SHOW_CODELINES "Show kernel lines in cuda-gdb and cuda-memcheck. If alpaka_CUDA_KEEP_FILES is enabled source code will be inlined in ptx." OFF)
if(alpaka_CUDA_SHOW_CODELINES)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:--source-in-ptx -lineinfo>")
# This is shaky - We currently don't have a way of checking for the host compiler ID.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/20901
if(NOT MSVC)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:-Xcompiler -rdynamic>")
endif()
set(alpaka_CUDA_KEEP_FILES ON CACHE BOOL "activate keep files" FORCE)
endif()
enable_language(CUDA)
checkCompilerCXXSupport(CUDA ${alpaka_CXX_STANDARD})
if(alpaka_API_OMP)
if(NOT MSVC)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:-Xcompiler -fopenmp>")
# See https://github.com/alpaka-group/alpaka/issues/1755
if((${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") AND
(${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL 13))
message(STATUS "clang >= 13 detected. Force-setting OpenMP to version 4.5.")
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:-Xcompiler -fopenmp-version=45>")
endif()
else()
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:-Xcompiler /openmp>")
endif()
endif()
endif()
if(alpaka_API_HIP)
check_language(HIP)
if(CMAKE_HIP_COMPILER)
enable_language(HIP)
find_package(hip REQUIRED)
set(_alpaka_HIP_MIN_VER 6.0)
set(_alpaka_HIP_MAX_VER 6.2)
checkCompilerCXXSupport(HIP ${alpaka_CXX_STANDARD})
# construct hip version only with major and minor level
# cannot use hip_VERSION because of the patch level
# 6.0 is smaller than 6.0.1234, so _alpaka_HIP_MAX_VER would have to be defined with a large patch level or
# the next minor level, e.g. 6.1, would have to be used.
set(_hip_MAJOR_MINOR_VERSION "${hip_VERSION_MAJOR}.${hip_VERSION_MINOR}")
if(${_hip_MAJOR_MINOR_VERSION} VERSION_LESS ${_alpaka_HIP_MIN_VER} OR ${_hip_MAJOR_MINOR_VERSION} VERSION_GREATER ${_alpaka_HIP_MAX_VER})
message(WARNING "HIP ${_hip_MAJOR_MINOR_VERSION} is not official supported by alpaka. Supported versions: ${_alpaka_HIP_MIN_VER} - ${_alpaka_HIP_MAX_VER}")
endif()
# let the compiler find the HIP headers also when building host-only code
target_include_directories(alpaka SYSTEM INTERFACE ${hip_INCLUDE_DIR})
target_link_libraries(alpaka INTERFACE "$<$<LINK_LANGUAGE:CXX>:hip::host>")
alpaka_set_compiler_options(HOST_DEVICE target alpaka "$<$<COMPILE_LANGUAGE:CXX>:-D__HIP_PLATFORM_AMD__>")
alpaka_compiler_option(HIP_KEEP_FILES "Keep all intermediate files that are generated during internal compilation steps 'CMakeFiles/<targetname>.dir'" OFF)
if(alpaka_HIP_KEEP_FILES)
alpaka_set_compiler_options(HOST_DEVICE target alpaka "$<$<COMPILE_LANGUAGE:HIP>:SHELL:-save-temps>")
endif()
if(alpaka_FAST_MATH STREQUAL ON)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:HIP>:SHELL:-ffast-math>")
endif()
if(NOT alpaka_DISABLE_VENDOR_RNG)
# hiprand requires ROCm implementation of random numbers by rocrand
# hip::hiprand is currently not expressing this dependency
find_package(rocrand REQUIRED CONFIG
HINTS "${ROCM_ROOT_DIR}/rocrand"
HINTS "/opt/rocm/rocrand")
if(rocrand_FOUND)
target_link_libraries(alpaka INTERFACE roc::rocrand)
else()
MESSAGE(FATAL_ERROR "Could not find rocRAND (also searched in: ROCM_ROOT_DIR=${ROCM_ROOT_DIR}/rocrand).")
endif()
# HIP random numbers
find_package(hiprand REQUIRED CONFIG
HINTS "${HIP_ROOT_DIR}/hiprand"
HINTS "/opt/rocm/hiprand")
if(hiprand_FOUND)
target_link_libraries(alpaka INTERFACE hip::hiprand)
else()
MESSAGE(FATAL_ERROR "Could not find hipRAND (also searched in: HIP_ROOT_DIR=${HIP_ROOT_DIR}/hiprand).")
endif()
endif()
if(alpaka_RELOCATABLE_DEVICE_CODE STREQUAL ON)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:HIP>:SHELL:-fgpu-rdc>")
target_link_options(alpaka INTERFACE "$<$<LINK_LANGUAGE:HIP>:SHELL:-fgpu-rdc --hip-link>")
elseif(alpaka_RELOCATABLE_DEVICE_CODE STREQUAL OFF)
alpaka_set_compiler_options(DEVICE target alpaka "$<$<COMPILE_LANGUAGE:HIP>:SHELL:-fno-gpu-rdc>")
endif()
else()
message(FATAL_ERROR "Optional alpaka dependency HIP could not be found!")
endif()
endif()
## search for aqtomic ref
# Check for C++20 std::atomic_ref first
try_compile(alpaka_HAS_STD_ATOMIC_REF # Result stored here
"${PROJECT_BINARY_DIR}/alpakaFeatureTests" # Binary directory for output file
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/tests/StdAtomicRef.cpp" # Source file
CXX_STANDARD 20
CXX_STANDARD_REQUIRED TRUE
CXX_EXTENSIONS FALSE)
if(alpaka_HAS_STD_ATOMIC_REF AND (NOT alpaka_ACC_CPU_DISABLE_ATOMIC_REF))
message(STATUS "std::atomic_ref<T> found")
target_compile_definitions(alpaka INTERFACE ALPAKA_HAS_STD_ATOMIC_REF)
else()
message(STATUS "std::atomic_ref<T> NOT found")
endif()
if(NOT alpaka_HAS_STD_ATOMIC_REF)
if(Boost_ATOMIC_FOUND)
message(STATUS "boost::atomic_ref<T> found")
target_link_libraries(alpaka INTERFACE Boost::atomic)
else()
message(STATUS "boost::atomic_ref<T> NOT found")
endif()
endif()
if((NOT alpaka_HAS_STD_ATOMIC_REF) AND (NOT Boost_ATOMIC_FOUND))
message(STATUS "atomic_ref<T> or boost::atomic_ref<T> was not found or manually disabled. Falling back to lock-based CPU atomics.")
target_compile_definitions(alpaka INTERFACE ALPAKA_DISABLE_ATOMIC_ATOMICREF)
endif()
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
# alpaka IDE target to make source browsable/editable in IDEs
file(GLOB_RECURSE alpakaSources "${CMAKE_CURRENT_SOURCE_DIR}/include/**")
add_custom_target("alpakaIde" SOURCES ${alpakaSources})
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}/include/alpaka" FILES ${alpakaSources})
option(alpaka_TESTING "Enable/Disable testing" OFF)
option(alpaka_BENCHMARKS "Enable/Disable benchmarks" OFF)
option(alpaka_EXAMPLES "Enable/Disable examples" OFF)
include(CTest)
if (alpaka_TESTING OR alpaka_BENCHMARKS)
option(alpaka_SYSTEM_CATCH2 "Use the system provided Catch2." OFF)
if (alpaka_SYSTEM_CATCH2)
find_package(Catch2 3.5.3 REQUIRED)
include(Catch)
else()
# get Catch2 v3 and build it from source with the same C++ standard as the tests
Include(FetchContent)
FetchContent_Declare(Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.5.3)
FetchContent_MakeAvailable(Catch2)
target_compile_features(Catch2 PUBLIC cxx_std_20)
include(Catch)
# hide Catch2 cmake variables by default in cmake gui
get_cmake_property(variables VARIABLES)
foreach (var ${variables})
if (var MATCHES "^CATCH_")
mark_as_advanced(${var})
endif()
endforeach()
endif()
if (alpaka_TESTING)
file(GLOB_RECURSE testSources "${CMAKE_CURRENT_SOURCE_DIR}/tests/**")
alpaka_add_executable(tests ${testSources})
catch_discover_tests(tests)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}/tests" FILES ${testSources})
target_compile_features(tests PRIVATE cxx_std_20)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain alpaka::alpaka)
endif()
if (alpaka_BENCHMARKS)
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/benchmark")
endif()
endif()
if(alpaka_EXAMPLES)
add_subdirectory(example)
endif()
option(alpaka_EXEC_CpuSerial "Enable/Disable serial exeexecutor" ON)
if(NOT alpaka_EXEC_CpuSerial)
target_compile_definitions(alpaka INTERFACE ALPAKA_DISABLE_EXEC_CpuSerial)
endif()
option(alpaka_EXEC_CpuOmpBlocks "Enable/Disable openMP blocks exeexecutor" ON)
if(NOT alpaka_EXEC_CpuOmpBlocks)
target_compile_definitions(alpaka INTERFACE ALPAKA_DISABLE_EXEC_CpuOmpBlocks)
endif()
option(alpaka_EXEC_CpuOmpBlocksAndThreads "Enable/Disable openMP blocks exeexecutor" ON)
if(NOT alpaka_EXEC_CpuOmpBlocksAndThreads)
target_compile_definitions(alpaka INTERFACE ALPAKA_DISABLE_EXEC_CpuOmpBlocksAndThreads)
endif()
option(alpaka_EXEC_GpuCuda "Enable/Disable openMP blocks exeexecutor" ON)
if(NOT alpaka_EXEC_GpuCuda)
target_compile_definitions(alpaka INTERFACE ALPAKA_DISABLE_EXEC_GpuCuda)
endif()
option(alpaka_EXEC_GpuHip "Enable/Disable openMP blocks exeexecutor" ON)
if(NOT alpaka_EXEC_GpuHip)
target_compile_definitions(alpaka INTERFACE ALPAKA_DISABLE_EXEC_GpuHip)
endif()