forked from LLNL/Aluminum
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
275 lines (234 loc) · 8.82 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
cmake_minimum_required(VERSION 3.9)
# 3.9 is required for CUDA as a first-class language.
#
# 3.8 is required for cxx_std_11 compile feature. Otherwise we could
# set the CMAKE_CXX_STANDARD flag, but the compile features are a more
# elegant solution.
#
# Version setup
#
set(ALUMINUM_VERSION_MAJOR 0)
set(ALUMINUM_VERSION_MINOR 2)
set(ALUMINUM_VERSION_PATCH 1)
set(ALUMINUM_VERSION "${ALUMINUM_VERSION_MAJOR}.${ALUMINUM_VERSION_MINOR}.${ALUMINUM_VERSION_PATCH}")
project(ALUMINUM VERSION ${ALUMINUM_VERSION} LANGUAGES CXX)
# Not "CUDA" because no CUDA sources being compiled, so don't need
# NVCC, just cuda runtime.
if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds are prohibited. "
"Create a new directory and build there.")
endif ()
include(GNUInstallDirs)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# Options
option(ALUMINUM_ENABLE_CUDA "Enable CUDA support." OFF)
option(ALUMINUM_ENABLE_MPI_CUDA "Enable MPI-CUDA support." OFF)
option(ALUMINUM_ENABLE_NCCL "Enable NCCL support." OFF)
option(ALUMINUM_ENABLE_MPI_CUDA_RMA "Enable RMA in MPI-CUDA." OFF)
if (ALUMINUM_ENABLE_MPI_CUDA_RMA AND NOT ALUMINUM_ENABLE_MPI_CUDA)
message(STATUS "RMA in MPI-CUDA requested; enabling MPI-CUDA support, too.")
set(ALUMINUM_ENABLE_CUDA ON)
endif ()
if (ALUMINUM_ENABLE_MPI_CUDA AND NOT ALUMINUM_ENABLE_CUDA)
message(STATUS "MPI-CUDA support requested; enabling CUDA support, too.")
set(ALUMINUM_ENABLE_CUDA ON)
endif ()
if (ALUMINUM_ENABLE_NCCL AND NOT ALUMINUM_ENABLE_CUDA)
message(STATUS "NCCL support requested; enabling CUDA support, too.")
set(ALUMINUM_ENABLE_CUDA ON)
endif ()
option(ALUMINUM_DEBUG_HANG_CHECK "Enable hang checking." OFF)
option(ALUMINUM_ENABLE_NVPROF "Enable profiling via nvprof/NVTX." OFF)
option(ALUMINUM_ENABLE_STREAM_MEM_OPS "Enable stream memory operations." OFF)
option(ALUMINUM_HT_USE_PASSTHROUGH "Host-transfer allreduces use MPI directly." OFF)
option(ALUMINUM_ENABLE_TRACE "Enable runtime tracing." OFF)
if (ALUMINUM_ENABLE_CUDA
AND NOT ALUMINUM_ENABLE_NCCL
AND NOT ALUMINUM_ENABLE_MPI_CUDA)
message(FATAL_ERROR
"CUDA has been enabled without a backend. "
"This should not happen. "
"Please turn on \"ALUMINUM_ENABLE_NCCL\" and/or "
"\"ALUMINUM_ENABLE_MPI_CUDA\" and reconfigure.")
endif ()
if (CMAKE_BUILD_TYPE MATCHES Debug)
set(AL_DEBUG ON)
endif ()
if (ALUMINUM_DEBUG_HANG_CHECK)
set(AL_DEBUG_HANG_CHECK ON)
endif ()
if (ALUMINUM_ENABLE_STREAM_MEM_OPS)
set(AL_USE_STREAM_MEM_OPS ON)
endif ()
if (ALUMINUM_HT_USE_PASSTHROUGH)
set(AL_HT_USE_PASSTHROUGH ON)
endif ()
if (ALUMINUM_ENABLE_TRACE)
set(AL_TRACE ON)
endif ()
# Setup CXX requirements
set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -g")
# -faligned-new is needed to use new alignment-aware new when available.
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-faligned-new" CXX_COMPILER_HAS_FALIGNED_NEW)
if (CXX_COMPILER_HAS_FALIGNED_NEW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -faligned-new")
endif ()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if (NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON)
endif ()
# Dependencies
find_package(MPI 3.0 REQUIRED COMPONENTS CXX)
# Fix the imported target
# FIXME (trb): We should split the library into language-specific
# targets. That is, the .cu files should never need MPI linkage or
# OpenMP, so they should be built into a separate target without
# MPI::MPI_CXX or OpenMP::OpenMP_CXX "linkage".
get_target_property(
__mpi_compile_options MPI::MPI_CXX INTERFACE_COMPILE_OPTIONS)
if (__mpi_compile_options)
set_property(TARGET MPI::MPI_CXX PROPERTY
INTERFACE_COMPILE_OPTIONS
$<$<COMPILE_LANGUAGE:CXX>:${__mpi_compile_options}>)
unset(__mpi_compile_options)
endif ()
# Assuming this target is excluded from all device-link steps, this
# should not be necessary after the above FIXME is resolved.
get_property(_TMP_MPI_LINK_LIBRARIES TARGET MPI::MPI_CXX
PROPERTY INTERFACE_LINK_LIBRARIES)
foreach(lib IN LISTS _TMP_MPI_LINK_LIBRARIES)
if ("${lib}" MATCHES "-Wl*")
list(APPEND _MPI_LINK_FLAGS "${lib}")
else()
list(APPEND _MPI_LINK_LIBRARIES "${lib}")
endif ()
endforeach()
# The link flags *should* be propagated into this target somehow, but
# "LINK_FLAGS" is not a "whitelisted" property, so the INTERFACE
# target MPI::MPI_CXX cannot set them. But there's a clash with CUDA
# if they're added as "libraries".
#set_property(TARGET MPI::MPI_CXX PROPERTY LINK_FLAGS ${_MPI_LINK_FLAGS})
set_property(TARGET MPI::MPI_CXX
PROPERTY INTERFACE_LINK_LIBRARIES ${_MPI_LINK_LIBRARIES})
find_package(OpenMP REQUIRED COMPONENTS CXX)
find_package(HWLOC REQUIRED)
# Fix an issue with OpenMP's egregious use of non-language-specific
# compiler flags.
if (OPENMP_FOUND)
get_target_property(
__omp_compile_options OpenMP::OpenMP_CXX INTERFACE_COMPILE_OPTIONS)
set_property(TARGET OpenMP::OpenMP_CXX PROPERTY
INTERFACE_COMPILE_OPTIONS
$<$<COMPILE_LANGUAGE:CXX>:${__omp_compile_options}>)
unset(__omp_compile_options)
if (${CMAKE_CXX_COMPILER} MATCHES ".*xl[cC]")
set_property(TARGET OpenMP::OpenMP_CXX APPEND PROPERTY
INTERFACE_LINK_LIBRARIES "${OpenMP_CXX_FLAGS}")
endif ()
endif (OPENMP_FOUND)
if (ALUMINUM_ENABLE_CUDA)
find_package(CUDA 9.0)
if (CUDA_FOUND)
enable_language(CUDA)
set(AL_HAS_CUDA TRUE)
if (ALUMINUM_ENABLE_MPI_CUDA)
set(AL_HAS_CUDA TRUE)
set(AL_HAS_MPI_CUDA TRUE)
if (ALUMINUM_ENABLE_MPI_CUDA_RMA)
set(AL_HAS_MPI_CUDA_RMA TRUE)
endif ()
endif ()
# Add the cuda imported target
if (NOT TARGET cuda::cuda)
add_library(cuda::cuda INTERFACE IMPORTED)
endif ()
set_property(TARGET cuda::cuda
PROPERTY INTERFACE_LINK_LIBRARIES ${CUDA_LIBRARIES})
set_property(TARGET cuda::cuda
PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CUDA_INCLUDE_DIRS})
if (ALUMINUM_ENABLE_NCCL)
find_package(NCCL 2.0.0 REQUIRED)
set(AL_HAS_NCCL TRUE)
set_property(TARGET cuda::cuda APPEND
PROPERTY INTERFACE_LINK_LIBRARIES cuda::nccl)
endif ()
if (ALUMINUM_ENABLE_NVPROF)
find_package(NVTX REQUIRED)
set(AL_HAS_NVPROF ON)
endif ()
else ()
message(WARNING "CUDA support requested but not found. Disabling.")
set(ALUMINUM_ENABLE_CUDA OFF)
set(ALUMINUM_ENABLE_MPI_CUDA OFF)
set(ALUMINUM_ENABLE_NCCL OFF)
set(ALUMINUM_ENABLE_NVPROF OFF)
set(AL_HAS_CUDA FALSE)
set(AL_HAS_MPI_CUDA FALSE)
set(AL_HAS_NCCL FALSE)
set(AL_HAS_NVPROF OFF)
endif ()
# Check that a backend is found
if (NOT AL_HAS_NCCL AND NOT AL_HAS_MPI_CUDA)
set(ALUMINUM_ENABLE_CUDA FALSE)
set(AL_HAS_CUDA FALSE)
endif ()
endif ()
# Build library and executables
# Write the configuration file
configure_file(
"${CMAKE_SOURCE_DIR}/cmake/Al_config.hpp.in"
"${CMAKE_BINARY_DIR}/Al_config.hpp" @ONLY)
# Macro for setting up full paths
macro(set_full_path VAR)
unset(__tmp_names)
foreach(filename ${ARGN})
unset(__name)
get_filename_component(__name "${filename}" ABSOLUTE)
list(APPEND __tmp_names "${__name}")
endforeach()
set(${VAR} "${__tmp_names}")
endmacro()
add_subdirectory(src)
add_subdirectory(benchmark)
# Testing
include(CTest)
add_subdirectory(test)
#
# Install target
#
include(CMakePackageConfigHelpers)
# Build directory
export(EXPORT AluminumTargets NAMESPACE AL:: FILE AluminumTargets.cmake)
write_basic_package_version_file(
"${CMAKE_BINARY_DIR}/AluminumConfigVersion.cmake" VERSION
${ALUMINUM_VERSION} COMPATIBILITY AnyNewerVersion )
set(INCLUDE_INSTALL_DIRS ${CMAKE_SOURCE_DIR}/src)
set(LIB_INSTALL_DIR src)
set(CMAKE_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(CMAKE_MODULE_LOCATION "${CMAKE_SOURCE_DIR}/cmake")
set(REAL_CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}")
configure_package_config_file(cmake/AluminumConfig.cmake.in
"${CMAKE_BINARY_DIR}/AluminumConfig.cmake" INSTALL_DESTINATION
"${CMAKE_INSTALL_DIR}" PATH_VARS INCLUDE_INSTALL_DIRS LIB_INSTALL_DIR)
set(CMAKE_INSTALL_PREFIX "${REAL_CMAKE_INSTALL_PREFIX}")
# Install directory
set(INCLUDE_INSTALL_DIRS ${CMAKE_INSTALL_INCLUDEDIR}/aluminum)
set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
set(CMAKE_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/aluminum)
set(CMAKE_MODULE_LOCATION "\$\{CMAKE_CURRENT_LIST_DIR\}")
configure_package_config_file(cmake/AluminumConfig.cmake.in
"${CMAKE_BINARY_DIR}/AluminumConfig.cmake.install" INSTALL_DESTINATION
${CMAKE_INSTALL_DIR} PATH_VARS INCLUDE_INSTALL_DIRS LIB_INSTALL_DIR)
# Install the install-tree files
install(FILES "${CMAKE_BINARY_DIR}/AluminumConfig.cmake.install"
RENAME "AluminumConfig.cmake" DESTINATION ${CMAKE_INSTALL_DIR})
install(FILES
"${CMAKE_BINARY_DIR}/AluminumConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_DIR})
install(FILES
"${CMAKE_BINARY_DIR}/Al_config.hpp" DESTINATION ${INCLUDE_INSTALL_DIRS})
# Install the CMake modules we need
install(FILES cmake/FindHWLOC.cmake cmake/FindNCCL.cmake
DESTINATION ${CMAKE_INSTALL_DIR})