-
Notifications
You must be signed in to change notification settings - Fork 407
/
kokkos_test_cxx_std.cmake
174 lines (159 loc) · 8.59 KB
/
kokkos_test_cxx_std.cmake
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
KOKKOS_CFG_DEPENDS(CXX_STD COMPILER_ID)
FUNCTION(kokkos_set_cxx_standard_feature standard)
SET(EXTENSION_NAME CMAKE_CXX${standard}_EXTENSION_COMPILE_OPTION)
SET(STANDARD_NAME CMAKE_CXX${standard}_STANDARD_COMPILE_OPTION)
SET(FEATURE_NAME cxx_std_${standard})
#CMake's way of telling us that the standard (or extension)
#flags are supported is the extension/standard variables
IF (NOT DEFINED CMAKE_CXX_EXTENSIONS)
IF(KOKKOS_DONT_ALLOW_EXTENSIONS)
GLOBAL_SET(KOKKOS_USE_CXX_EXTENSIONS OFF)
ELSE()
GLOBAL_SET(KOKKOS_USE_CXX_EXTENSIONS ON)
ENDIF()
ELSEIF(CMAKE_CXX_EXTENSIONS)
IF(KOKKOS_DONT_ALLOW_EXTENSIONS)
MESSAGE(FATAL_ERROR "The chosen configuration does not support CXX extensions flags: ${KOKKOS_DONT_ALLOW_EXTENSIONS}. Must set CMAKE_CXX_EXTENSIONS=OFF to continue")
ELSE()
GLOBAL_SET(KOKKOS_USE_CXX_EXTENSIONS ON)
ENDIF()
ELSE()
#For trilinos, we need to make sure downstream projects
GLOBAL_SET(KOKKOS_USE_CXX_EXTENSIONS OFF)
ENDIF()
IF (KOKKOS_USE_CXX_EXTENSIONS AND ${EXTENSION_NAME})
MESSAGE(STATUS "Using ${${EXTENSION_NAME}} for C++${standard} extensions as feature")
GLOBAL_SET(KOKKOS_CXX_STANDARD_FEATURE ${FEATURE_NAME})
ELSEIF(NOT KOKKOS_USE_CXX_EXTENSIONS AND ${STANDARD_NAME})
MESSAGE(STATUS "Using ${${STANDARD_NAME}} for C++${standard} standard as feature")
IF (KOKKOS_CXX_COMPILER_ID STREQUAL NVIDIA AND (KOKKOS_CXX_HOST_COMPILER_ID STREQUAL GNU OR KOKKOS_CXX_HOST_COMPILER_ID STREQUAL Clang))
IF(${KOKKOS_CXX_COMPILER_VERSION} VERSION_LESS 12.0.0)
SET(SUPPORTED_NVCC_FLAGS "-std=c++17")
ELSE()
SET(SUPPORTED_NVCC_FLAGS "-std=c++17" "-std=c++20")
ENDIF()
IF (NOT ${${STANDARD_NAME}} IN_LIST SUPPORTED_NVCC_FLAGS)
MESSAGE(FATAL_ERROR "CMake wants to use ${${STANDARD_NAME}} which is not supported by NVCC. Using a more recent host compiler or a more recent CMake version might help.")
ENDIF()
ENDIF()
GLOBAL_SET(KOKKOS_CXX_STANDARD_FEATURE ${FEATURE_NAME})
ELSEIF (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
#MSVC doesn't need a command line flag, that doesn't mean it has no support
MESSAGE(STATUS "Using no flag for C++${standard} standard as feature")
GLOBAL_SET(KOKKOS_CXX_STANDARD_FEATURE ${FEATURE_NAME})
ELSEIF((KOKKOS_CXX_COMPILER_ID STREQUAL "NVIDIA") AND WIN32)
MESSAGE(STATUS "Using no flag for C++${standard} standard as feature")
GLOBAL_SET(KOKKOS_CXX_STANDARD_FEATURE "")
ELSEIF((KOKKOS_CXX_COMPILER_ID STREQUAL "Fujitsu"))
MESSAGE(STATUS "Using no flag for C++${standard} standard as feature")
GLOBAL_SET(KOKKOS_CXX_STANDARD_FEATURE "")
ELSE()
#nope, we can't do anything here
MESSAGE(WARNING "C++${standard} is not supported as a compiler feature. We will choose custom flags for now, but this behavior has been deprecated. Please open an issue at https://github.com/kokkos/kokkos/issues reporting that ${KOKKOS_CXX_COMPILER_ID} ${KOKKOS_CXX_COMPILER_VERSION} failed for ${KOKKOS_CXX_STANDARD}, preferably including your CMake command.")
GLOBAL_SET(KOKKOS_CXX_STANDARD_FEATURE "")
ENDIF()
IF((NOT WIN32) AND (NOT ("${KOKKOS_CXX_COMPILER_ID}" STREQUAL "Fujitsu")))
IF(NOT ${FEATURE_NAME} IN_LIST CMAKE_CXX_COMPILE_FEATURES)
MESSAGE(FATAL_ERROR "Compiler ${KOKKOS_CXX_COMPILER_ID} should support ${FEATURE_NAME}, but CMake reports feature not supported")
ENDIF()
ENDIF()
ENDFUNCTION()
IF(KOKKOS_CXX_STANDARD STREQUAL "17")
kokkos_set_cxx_standard_feature(17)
SET(KOKKOS_CXX_INTERMEDIATE_STANDARD "1Z")
SET(KOKKOS_ENABLE_CXX17 ON)
ELSEIF(KOKKOS_CXX_STANDARD STREQUAL "20")
kokkos_set_cxx_standard_feature(20)
SET(KOKKOS_CXX_INTERMEDIATE_STANDARD "2A")
SET(KOKKOS_ENABLE_CXX20 ON)
ELSEIF(KOKKOS_CXX_STANDARD STREQUAL "23")
kokkos_set_cxx_standard_feature(23)
SET(KOKKOS_CXX_INTERMEDIATE_STANDARD "2B")
SET(KOKKOS_ENABLE_CXX23 ON)
ELSEIF(KOKKOS_CXX_STANDARD STREQUAL "26")
kokkos_set_cxx_standard_feature(26)
SET(KOKKOS_CXX_INTERMEDIATE_STANDARD "2C")
SET(KOKKOS_ENABLE_CXX26 ON)
ELSE()
MESSAGE(FATAL_ERROR "Kokkos requires C++17 or newer but requested ${KOKKOS_CXX_STANDARD}!")
ENDIF()
# Enforce that we can compile a simple C++17 program
TRY_COMPILE(CAN_COMPILE_CPP17
${KOKKOS_TOP_BUILD_DIR}/corner_cases
${KOKKOS_SOURCE_DIR}/cmake/compile_tests/cplusplus17.cpp
OUTPUT_VARIABLE ERROR_MESSAGE
CXX_STANDARD 17
)
if (NOT CAN_COMPILE_CPP17)
UNSET(CAN_COMPILE_CPP17 CACHE) #make sure CMake always re-runs this
MESSAGE(FATAL_ERROR "C++${KOKKOS_CXX_STANDARD}-compliant compiler detected, but unable to compile C++17 or later program. Verify that ${CMAKE_CXX_COMPILER_ID}:${CMAKE_CXX_COMPILER_VERSION} is set up correctly (e.g., check that correct library headers are being used).\nFailing output:\n ${ERROR_MESSAGE}")
ENDIF()
UNSET(CAN_COMPILE_CPP17 CACHE) #make sure CMake always re-runs this
# Enforce that extensions are turned off for nvcc_wrapper.
# For compiling CUDA code using nvcc_wrapper, we will use the host compiler's
# flags for turning on C++17. Since for compiler ID and versioning purposes
# CMake recognizes the host compiler when calling nvcc_wrapper, this just
# works. Both NVCC and nvcc_wrapper only recognize '-std=c++17' which means
# that we can only use host compilers for CUDA builds that use those flags.
# It also means that extensions (gnu++17) can't be turned on for CUDA builds.
IF(KOKKOS_CXX_COMPILER_ID STREQUAL NVIDIA)
IF(NOT DEFINED CMAKE_CXX_EXTENSIONS)
SET(CMAKE_CXX_EXTENSIONS OFF)
ELSEIF(CMAKE_CXX_EXTENSIONS)
MESSAGE(FATAL_ERROR "NVCC doesn't support C++ extensions. Set -DCMAKE_CXX_EXTENSIONS=OFF")
ENDIF()
ENDIF()
IF(KOKKOS_ENABLE_CUDA)
# ENFORCE that the compiler can compile CUDA code.
IF(KOKKOS_CXX_COMPILER_ID STREQUAL Clang)
IF(KOKKOS_CXX_COMPILER_VERSION VERSION_LESS 4.0.0)
MESSAGE(FATAL_ERROR "Compiling CUDA code directly with Clang requires version 4.0.0 or higher.")
ENDIF()
IF(NOT DEFINED CMAKE_CXX_EXTENSIONS)
SET(CMAKE_CXX_EXTENSIONS OFF)
ELSEIF(CMAKE_CXX_EXTENSIONS)
MESSAGE(FATAL_ERROR "Compiling CUDA code with clang doesn't support C++ extensions. Set -DCMAKE_CXX_EXTENSIONS=OFF")
ENDIF()
ELSEIF(NOT KOKKOS_CXX_COMPILER_ID STREQUAL NVIDIA AND NOT (Kokkos_ENABLE_IMPL_NVHPC_AS_DEVICE_COMPILER AND KOKKOS_CXX_COMPILER_ID STREQUAL NVHPC))
IF(KOKKOS_CXX_COMPILER_ID STREQUAL NVHPC)
MESSAGE(FATAL_ERROR "Invalid compiler for CUDA. To allow nvc++ as Cuda compiler, Kokkos_ENABLE_IMPL_NVHPC_AS_DEVICE_COMPILER=ON must be set!")
ELSE()
MESSAGE(FATAL_ERROR "Invalid compiler for CUDA. The compiler must be nvcc_wrapper or Clang or NVC++ or use kokkos_launch_compiler, but compiler ID was ${KOKKOS_CXX_COMPILER_ID}")
ENDIF()
ENDIF()
ENDIF()
IF (NOT KOKKOS_CXX_STANDARD_FEATURE)
#we need to pick the C++ flags ourselves
UNSET(CMAKE_CXX_STANDARD)
UNSET(CMAKE_CXX_STANDARD CACHE)
IF(KOKKOS_CXX_COMPILER_ID STREQUAL Cray)
INCLUDE(${KOKKOS_SRC_PATH}/cmake/cray.cmake)
kokkos_set_cray_flags(${KOKKOS_CXX_STANDARD} ${KOKKOS_CXX_INTERMEDIATE_STANDARD})
ELSEIF(KOKKOS_CXX_COMPILER_ID STREQUAL NVHPC)
INCLUDE(${KOKKOS_SRC_PATH}/cmake/pgi.cmake)
kokkos_set_pgi_flags(${KOKKOS_CXX_STANDARD} ${KOKKOS_CXX_INTERMEDIATE_STANDARD})
ELSEIF(KOKKOS_CXX_COMPILER_ID STREQUAL Intel)
INCLUDE(${KOKKOS_SRC_PATH}/cmake/intel.cmake)
kokkos_set_intel_flags(${KOKKOS_CXX_STANDARD} ${KOKKOS_CXX_INTERMEDIATE_STANDARD})
ELSEIF((KOKKOS_CXX_COMPILER_ID STREQUAL "MSVC") OR ((KOKKOS_CXX_COMPILER_ID STREQUAL "NVIDIA") AND WIN32))
INCLUDE(${KOKKOS_SRC_PATH}/cmake/msvc.cmake)
kokkos_set_msvc_flags(${KOKKOS_CXX_STANDARD} ${KOKKOS_CXX_INTERMEDIATE_STANDARD})
ELSE()
INCLUDE(${KOKKOS_SRC_PATH}/cmake/gnu.cmake)
kokkos_set_gnu_flags(${KOKKOS_CXX_STANDARD} ${KOKKOS_CXX_INTERMEDIATE_STANDARD})
ENDIF()
#check that the compiler accepts the C++ standard flag
INCLUDE(CheckCXXCompilerFlag)
IF (DEFINED CXX_STD_FLAGS_ACCEPTED)
UNSET(CXX_STD_FLAGS_ACCEPTED CACHE)
ENDIF()
CHECK_CXX_COMPILER_FLAG("${KOKKOS_CXX_STANDARD_FLAG}" CXX_STD_FLAGS_ACCEPTED)
IF (NOT CXX_STD_FLAGS_ACCEPTED)
CHECK_CXX_COMPILER_FLAG("${KOKKOS_CXX_INTERMEDIATE_STANDARD_FLAG}" CXX_INT_STD_FLAGS_ACCEPTED)
IF (NOT CXX_INT_STD_FLAGS_ACCEPTED)
MESSAGE(FATAL_ERROR "${KOKKOS_CXX_COMPILER_ID} did not accept ${KOKKOS_CXX_STANDARD_FLAG} or ${KOKKOS_CXX_INTERMEDIATE_STANDARD_FLAG}. You likely need to reduce the level of the C++ standard from ${KOKKOS_CXX_STANDARD}")
ENDIF()
SET(KOKKOS_CXX_STANDARD_FLAG ${KOKKOS_CXX_INTERMEDIATE_STANDARD_FLAG})
ENDIF()
MESSAGE(STATUS "Compiler features not supported, but ${KOKKOS_CXX_COMPILER_ID} accepts ${KOKKOS_CXX_STANDARD_FLAG}")
ENDIF()