-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathKokkosPythonKokkos.cmake
More file actions
280 lines (239 loc) · 10.8 KB
/
KokkosPythonKokkos.cmake
File metadata and controls
280 lines (239 loc) · 10.8 KB
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
#----------------------------------------------------------------------------------------#
# Kokkos submodule
#----------------------------------------------------------------------------------------#
INCLUDE_GUARD(GLOBAL)
INCLUDE(KokkosPythonUtilities) # miscellaneous macros and functions
# if first time cmake is run and no external/internal preference is specified,
# try to find already installed kokkos unless (A) the Kokkos targets already
# exist or (B) pykokkos-base is being build via scikit-build. In the case
# of scikit-build, we want to prefer the internal kokkos because it is
# unlikely the user will see or kokkos which kokkos is found
IF(NOT DEFINED ENABLE_INTERNAL_KOKKOS AND NOT TARGET Kokkos::kokkoscore AND NOT SKBUILD)
FIND_PACKAGE(Kokkos)
# set the default cache value
IF(Kokkos_FOUND)
SET(_INTERNAL_KOKKOS OFF)
# force using same compiler as kokkos
kokkos_compilation(GLOBAL)
ELSE()
SET(_INTERNAL_KOKKOS ON)
ENDIF()
ELSEIF(TARGET Kokkos::kokkoscore)
SET(_INTERNAL_KOKKOS OFF)
ELSEIF(NOT DEFINED ENABLE_INTERNAL_KOKKOS AND SKBUILD)
set(_INTERNAL_KOKKOS ON)
ELSE()
# make sure ADD_OPTION in KokkosPythonOptions has a value
SET(_INTERNAL_KOKKOS ${ENABLE_INTERNAL_KOKKOS})
ENDIF()
# force an error
IF(NOT _INTERNAL_KOKKOS AND NOT TARGET Kokkos::kokkoscore)
FIND_PACKAGE(Kokkos REQUIRED COMPONENTS launch_compiler)
kokkos_compilation(GLOBAL)
IF(NOT Kokkos_INCLUDE_DIR)
GET_TARGET_PROPERTY(Kokkos_INCLUDE_DIR Kokkos::kokkoscore INTERFACE_INCLUDE_DIRECTORIES)
ENDIF()
FIND_FILE(Kokkos_InterOp_Header
NO_DEFAULT_PATH
NAMES Kokkos_InterOp.hpp KokkosExp_InterOp.hpp
PATHS ${Kokkos_INCLUDE_DIR} ${Kokkos_ROOT}
HINTS ${Kokkos_INCLUDE_DIR} ${Kokkos_ROOT}
DOC "Path to Kokkos InterOp header"
PATH_SUFFIXES include ../../../include)
ADD_FEATURE(Kokkos_CXX_COMPILER "Compiler used to build Kokkos")
ADD_FEATURE(Kokkos_CXX_COMPILER_ID "Compiler ID used to build Kokkos")
ELSEIF(TARGET Kokkos::kokkoscore)
IF(NOT Kokkos_INCLUDE_DIR)
GET_TARGET_PROPERTY(Kokkos_INCLUDE_DIR Kokkos::kokkoscore INTERFACE_INCLUDE_DIRECTORIES)
ENDIF()
FIND_FILE(Kokkos_InterOp_Header
NO_DEFAULT_PATH
NAMES Kokkos_InterOp.hpp KokkosExp_InterOp.hpp
PATHS ${Kokkos_INCLUDE_DIR} ${Kokkos_ROOT}
HINTS ${Kokkos_INCLUDE_DIR} ${Kokkos_ROOT}
DOC "Path to Kokkos InterOp header"
PATH_SUFFIXES include ../../../include)
ADD_FEATURE(Kokkos_CXX_COMPILER "Compiler used to build Kokkos")
ADD_FEATURE(Kokkos_CXX_COMPILER_ID "Compiler ID used to build Kokkos")
ELSE()
FIND_FILE(Kokkos_InterOp_Header
NO_DEFAULT_PATH
NAMES Kokkos_InterOp.hpp KokkosExp_InterOp.hpp
PATHS ${PROJECT_SOURCE_DIR}/external/kokkos/core/src
HINTS ${PROJECT_SOURCE_DIR}/external/kokkos/core/src
DOC "Path to Kokkos InterOp header")
ENDIF()
#
IF(_INTERNAL_KOKKOS)
# try to find some packages quietly in order to set some defaults
SET(OpenMP_FOUND OFF)
SET(Threads_FOUND OFF)
SET(CUDA_FOUND OFF)
# Only search for OpenMP if not explicitly disabled and Threads not explicitly enabled
IF(NOT DEFINED Kokkos_ENABLE_THREADS OR NOT Kokkos_ENABLE_THREADS)
FIND_PACKAGE(OpenMP QUIET)
ENDIF()
# Only check for Threads if OpenMP was not found and not explicitly disabled
IF(NOT OpenMP_FOUND AND NOT DEFINED Kokkos_ENABLE_OPENMP)
FIND_PACKAGE(Threads QUIET)
ELSE()
SET(Threads_FOUND OFF)
ENDIF()
# Only enable CUDA if EXPLICITLY requested
SET(_CUDA_EXPLICITLY_ENABLED OFF)
# Check if explicitly enabled
IF((DEFINED ENABLE_CUDA AND ENABLE_CUDA) OR (DEFINED Kokkos_ENABLE_CUDA AND Kokkos_ENABLE_CUDA))
SET(_CUDA_EXPLICITLY_ENABLED ON)
ENDIF()
# Only search for CUDA if explicitly enabled
IF(_CUDA_EXPLICITLY_ENABLED)
FILE(GLOB CUDA_SEARCH_PATHS
"/usr/local/cuda-*"
"/usr/local/cuda"
"/opt/cuda-*"
"/opt/cuda"
)
# Add common CUDA paths to CMAKE_PREFIX_PATH to help find complete installations
IF(CUDA_SEARCH_PATHS)
LIST(SORT CUDA_SEARCH_PATHS ORDER DESCENDING) # Prefer newer versions
FOREACH(CUDA_PATH ${CUDA_SEARCH_PATHS})
IF(EXISTS "${CUDA_PATH}/bin/nvcc" AND EXISTS "${CUDA_PATH}/include/cuda_runtime.h")
LIST(APPEND CMAKE_PREFIX_PATH "${CUDA_PATH}")
ENDIF()
ENDFOREACH()
ENDIF()
# Find CUDA toolkit (REQUIRED if Kokkos_ENABLE_CUDA already defined, otherwise QUIET)
IF(DEFINED Kokkos_ENABLE_CUDA)
FIND_PACKAGE(CUDAToolkit REQUIRED)
ELSE()
FIND_PACKAGE(CUDAToolkit QUIET)
ENDIF()
IF(CUDAToolkit_FOUND)
SET(CUDA_FOUND ON)
# Set CUDA paths for the build system
GET_FILENAME_COMPONENT(CUDA_TOOLKIT_ROOT "${CUDAToolkit_BIN_DIR}" DIRECTORY)
# Verify we have cuda_runtime.h in the include directory
IF(NOT EXISTS "${CUDAToolkit_INCLUDE_DIRS}/cuda_runtime.h")
FOREACH(CUDA_PATH ${CUDA_SEARCH_PATHS})
IF(EXISTS "${CUDA_PATH}/include/cuda_runtime.h")
SET(CUDA_TOOLKIT_ROOT "${CUDA_PATH}")
SET(CUDAToolkit_BIN_DIR "${CUDA_PATH}/bin")
SET(CUDAToolkit_INCLUDE_DIRS "${CUDA_PATH}/include")
SET(CUDAToolkit_NVCC_EXECUTABLE "${CUDA_PATH}/bin/nvcc")
BREAK()
ENDIF()
ENDFOREACH()
ENDIF()
# Set up env for this build
SET(ENV{CUDA_HOME} "${CUDA_TOOLKIT_ROOT}")
SET(ENV{CUDACXX} "${CUDAToolkit_NVCC_EXECUTABLE}")
IF(NOT CMAKE_CUDA_COMPILER)
SET(CMAKE_CUDA_COMPILER "${CUDAToolkit_NVCC_EXECUTABLE}" CACHE FILEPATH "CUDA compiler" FORCE)
ENDIF()
# Enable CUDA language now that we have the correct compiler
INCLUDE(CheckLanguage)
CHECK_LANGUAGE(CUDA)
IF(CMAKE_CUDA_COMPILER)
ENABLE_LANGUAGE(CUDA)
ENDIF()
SET(Kokkos_CUDA_DIR "${CUDA_TOOLKIT_ROOT}" CACHE PATH "CUDA installation directory" FORCE)
INCLUDE_DIRECTORIES(SYSTEM ${CUDAToolkit_INCLUDE_DIRS})
ELSE()
SET(CUDA_FOUND OFF)
ENDIF()
ELSE()
# if CUDA not explicitly enabled
SET(CUDA_FOUND OFF)
ENDIF()
ADD_OPTION(ENABLE_SERIAL "Enable Serial backend when building Kokkos submodule" ON)
ADD_OPTION(ENABLE_OPENMP "Enable OpenMP when building Kokkos submodule" ${OpenMP_FOUND})
# Only enable Threads if OpenMP is not available
IF(OpenMP_FOUND)
ADD_OPTION(ENABLE_THREADS "Enable Pthreads when building Kokkos submodule" OFF)
ELSE()
ADD_OPTION(ENABLE_THREADS "Enable Pthreads when building Kokkos submodule" ${Threads_FOUND})
ENDIF()
# CUDA must be explicitly enabled - default to OFF
ADD_OPTION(ENABLE_CUDA "Enable CUDA when building Kokkos submodule" OFF)
# if OpenMP is enabled, ensure Threads is disabled (Kokkos doesn't allow both)
IF(ENABLE_OPENMP)
SET(ENABLE_THREADS OFF)
SET(Kokkos_ENABLE_THREADS OFF)
ENDIF()
# if Threads was explicitly enabled, disable OpenMP
IF(Kokkos_ENABLE_THREADS)
SET(ENABLE_OPENMP OFF)
SET(Kokkos_ENABLE_OPENMP OFF)
ENDIF()
# always disable pthread backend since pthreads are not supported on Windows
IF(WIN32)
SET(ENABLE_THREADS OFF)
SET(Kokkos_ENABLE_THREADS OFF)
ENDIF()
# make sure this pykokkos-base option is synced to Kokkos option
IF(DEFINED Kokkos_ENABLE_SERIAL)
SET(ENABLE_SERIAL ${Kokkos_ENABLE_SERIAL})
ENDIF()
# make sure this pykokkos-base option is synced to Kokkos option
IF(DEFINED Kokkos_ENABLE_OPENMP)
SET(ENABLE_OPENMP ${Kokkos_ENABLE_OPENMP})
ENDIF()
# make sure this pykokkos-base option is synced to Kokkos option
IF(DEFINED Kokkos_ENABLE_THREADS)
SET(ENABLE_THREADS ${Kokkos_ENABLE_THREADS})
ENDIF()
# make sure this pykokkos-base option is synced to Kokkos option
IF(DEFINED Kokkos_ENABLE_CUDA)
SET(ENABLE_CUDA ${Kokkos_ENABLE_CUDA})
ENDIF()
# Kokkos doesn't allow both OpenMP and Threads - enforce mutual exclusion
IF(ENABLE_OPENMP AND ENABLE_THREADS)
IF(Kokkos_ENABLE_OPENMP AND Kokkos_ENABLE_THREADS)
MESSAGE(FATAL_ERROR "Cannot enable both OpenMP and Threads execution spaces.")
ELSEIF(Kokkos_ENABLE_THREADS)
SET(ENABLE_OPENMP OFF)
SET(Kokkos_ENABLE_OPENMP OFF CACHE BOOL "" FORCE)
MESSAGE(STATUS "Disabling auto-detected OpenMP (Threads explicitly enabled)")
ELSE()
SET(ENABLE_THREADS OFF)
SET(Kokkos_ENABLE_THREADS OFF CACHE BOOL "" FORCE)
MESSAGE(STATUS "Disabling Threads (OpenMP enabled)")
ENDIF()
ENDIF()
# define the kokkos option as default and/or get it to display
IF(ENABLE_SERIAL)
ADD_OPTION(Kokkos_ENABLE_SERIAL "Build Kokkos submodule with serial support" ON)
ENDIF()
# define the kokkos option as default and/or get it to display
IF(ENABLE_OPENMP)
ADD_OPTION(Kokkos_ENABLE_OPENMP "Build Kokkos submodule with OpenMP support" ON)
ENDIF()
# define the kokkos option as default and/or get it to display
IF(ENABLE_THREADS)
ADD_OPTION(Kokkos_ENABLE_THREADS "Build Kokkos submodule with Pthread support" ON)
ENDIF()
# define the kokkos option as default and/or get it to display
IF(ENABLE_CUDA)
ADD_OPTION(Kokkos_ENABLE_CUDA "Build Kokkos submodule with CUDA support" ON)
ADD_OPTION(Kokkos_ENABLE_CUDA_UVM "Build Kokkos submodule with CUDA UVM support" ON)
ADD_OPTION(Kokkos_ENABLE_CUDA_LAMBDA "Build Kokkos submodule with CUDA lambda support" ON)
ENDIF()
# Check if we should use submodule or FetchContent
IF(EXISTS ${PROJECT_SOURCE_DIR}/external/kokkos/CMakeLists.txt)
# Use git submodule
ADD_SUBDIRECTORY(external)
SET(Kokkos_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/external/kokkos/core/src)
ELSE()
# Use FetchContent to download Kokkos
INCLUDE(FetchContent)
MESSAGE(STATUS "Fetching Kokkos via FetchContent")
FETCHCONTENT_DECLARE(
Kokkos
URL https://github.com/kokkos/kokkos/archive/refs/heads/release-candidate-4.7.01.zip
URL_HASH SHA256=e256f111716259ef0cec0339ddf44d716b1f495e5514ca0806fcf80635f5b4cc
)
FETCHCONTENT_MAKEAVAILABLE(Kokkos)
FETCHCONTENT_GETPROPERTIES(Kokkos SOURCE_DIR Kokkos_SOURCE_DIR)
SET(Kokkos_INCLUDE_DIR ${Kokkos_SOURCE_DIR}/core/src)
ENDIF()
ENDIF()