summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/configure_cuda12.2_nvidia_common.cmake2
-rwxr-xr-x.gitlab/ci/docker/cuda12.2/install_deps.sh1
-rw-r--r--.gitlab/os-linux.yml2
-rw-r--r--Help/release/dev/FindOpenMP-CUDA.rst5
-rw-r--r--Modules/FindOpenMP.cmake78
-rw-r--r--Tests/FindOpenMP/CMakeLists.txt6
-rw-r--r--Tests/FindOpenMP/Test/CMakeLists.txt13
7 files changed, 70 insertions, 37 deletions
diff --git a/.gitlab/ci/configure_cuda12.2_nvidia_common.cmake b/.gitlab/ci/configure_cuda12.2_nvidia_common.cmake
index 51a2511..5dc1788 100644
--- a/.gitlab/ci/configure_cuda12.2_nvidia_common.cmake
+++ b/.gitlab/ci/configure_cuda12.2_nvidia_common.cmake
@@ -1,5 +1,7 @@
set(CMake_TEST_CUDA "NVIDIA" CACHE STRING "")
set(CMake_TEST_CUDA_CUPTI "ON" CACHE STRING "")
set(CMake_TEST_CUDA_STANDARDS "03;11;14;17;20" CACHE STRING "")
+set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_CUDA "ON" CACHE BOOL "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/docker/cuda12.2/install_deps.sh b/.gitlab/ci/docker/cuda12.2/install_deps.sh
index 94fbd98..4708277 100755
--- a/.gitlab/ci/docker/cuda12.2/install_deps.sh
+++ b/.gitlab/ci/docker/cuda12.2/install_deps.sh
@@ -14,6 +14,7 @@ env DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
g++ \
clang-18 \
+ libomp-18-dev \
curl \
git
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index fbe6720..3edef20 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -396,7 +396,7 @@
.cuda12.2:
extends: .cuda
- image: "kitware/cmake:ci-cuda12.2-x86_64-2024-04-05"
+ image: "kitware/cmake:ci-cuda12.2-x86_64-2024-09-25"
variables:
CMAKE_ARCH: x86_64
diff --git a/Help/release/dev/FindOpenMP-CUDA.rst b/Help/release/dev/FindOpenMP-CUDA.rst
new file mode 100644
index 0000000..3880855
--- /dev/null
+++ b/Help/release/dev/FindOpenMP-CUDA.rst
@@ -0,0 +1,5 @@
+FindOpenMP-CUDA
+---------------
+
+* The :module:`FindOpenMP` module gained support for ``CUDA`` when using
+ a CUDA compiler that supports OpenMP on the host.
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index f88e43c..32e4cf2 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -37,6 +37,10 @@ Result Variables
The module exposes the components ``C``, ``CXX``, and ``Fortran``.
Each of these controls the various languages to search OpenMP support for.
+.. versionadded:: 3.31
+ The ``CUDA`` language component is supported when using a CUDA compiler
+ that supports OpenMP on the host.
+
Depending on the enabled components the following variables will be set:
``OpenMP_FOUND``
@@ -48,7 +52,7 @@ Depending on the enabled components the following variables will be set:
or all enabled languages if no components were specified.
This module will set the following variables per language in your
-project, where ``<lang>`` is one of C, CXX, or Fortran:
+project, where ``<lang>`` is one of C, CXX, CUDA, or Fortran:
``OpenMP_<lang>_FOUND``
Variable indicating if OpenMP support for ``<lang>`` was detected.
@@ -153,11 +157,17 @@ function(_OPENMP_FLAG_CANDIDATES LANG)
set(OMP_FLAG_Fujitsu "-Kopenmp" "-KOMP")
set(OMP_FLAG_FujitsuClang "-fopenmp" "-Kopenmp")
+ if(CMAKE_${LANG}_COMPILER_ID STREQUAL "NVIDIA" AND CMAKE_${LANG}_HOST_COMPILER_ID)
+ set(compiler_id "${CMAKE_${LANG}_HOST_COMPILER_ID}")
+ else()
+ set(compiler_id "${CMAKE_${LANG}_COMPILER_ID}")
+ endif()
+
# If we know the correct flags, use those
- if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
- set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
- # Fall back to reasonable default tries otherwise
+ if(DEFINED OMP_FLAG_${compiler_id})
+ set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${compiler_id}}")
else()
+ # Fall back to reasonable default tries otherwise
set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
endif()
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
@@ -204,6 +214,9 @@ macro(_OPENMP_PREPARE_SOURCE LANG CONTENT_ID NAME_PREFIX FULLNAME_VAR CONTENT_VA
elseif("${LANG}" STREQUAL "CXX")
set(${FULLNAME_VAR} "${NAME_PREFIX}.cpp")
set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
+ elseif("${LANG}" STREQUAL "CUDA")
+ set(${FULLNAME_VAR} "${NAME_PREFIX}.cu")
+ set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
elseif("${LANG}" STREQUAL "Fortran")
set(${FULLNAME_VAR} "${NAME_PREFIX}.F90")
string(CONFIGURE "${OpenMP_Fortran_${CONTENT_ID}}" ${CONTENT_VAR} @ONLY)
@@ -217,29 +230,32 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
_OPENMP_PREPARE_SOURCE("${LANG}" TEST_SOURCE OpenMPTryFlag
_OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT)
- unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
- foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS)
- if(NOT _VERBOSE_OPTION MATCHES "^-Wl,")
- list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION})
- endif()
- endforeach()
foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
- set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
- if(OpenMP_VERBOSE_COMPILE_OPTIONS)
- string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}")
- endif()
string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
unset(_includeDirFlags)
if(OpenMP_${LANG}_INCLUDE_DIR)
set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
endif()
+ if(CMAKE_${LANG}_COMPILER_ID STREQUAL "NVIDIA")
+ # With NVCC we drive linking directly through the host compiler, but
+ # without language-wide flags since they may be specific to nvcc.
+ # Pass the candidate OpenMP flag to the host compiler when linking.
+ set(_OpenMP_LINK_OPTIONS "${OPENMP_FLAG}")
+ # Exclude CUDA runtime libraries that we may add ourselves.
+ # See the Compiler/NVIDIA module. Do not exclude pthread,
+ # as that is typically a dependency of OpenMP too.
+ set(_OpenMP_EXCLUDE_IMPLICIT_LIBS cudart cudart_static cudadevrt rt dl)
+ else()
+ set(_OpenMP_LINK_OPTIONS "")
+ set(_OpenMP_EXCLUDE_IMPLICIT_LIBS "")
+ endif()
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
LOG_DESCRIPTION "Detecting ${LANG} OpenMP compiler info"
- CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" ${_includeDirFlags}
- LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG}
+ CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAG}" ${_includeDirFlags}
+ LINK_OPTIONS ${OpenMP_VERBOSE_OPTIONS} ${_OpenMP_LINK_OPTIONS}
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
)
@@ -290,6 +306,7 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
+ OR "${_OPENMP_IMPLICIT_LIB}" IN_LIST _OpenMP_EXCLUDE_IMPLICIT_LIBS
OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)"
OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
if(_OPENMP_IMPLICIT_LIB_DIR)
@@ -310,6 +327,9 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
endif()
endforeach()
+ list(REVERSE _OPENMP_LIB_NAMES)
+ list(REMOVE_DUPLICATES _OPENMP_LIB_NAMES)
+ list(REVERSE _OPENMP_LIB_NAMES)
set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
else()
# We do not know how to extract implicit OpenMP libraries for this compiler.
@@ -336,8 +356,8 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'"
- CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
- LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
+ COMPILE_DEFINITIONS ${OPENMP_FLAG}
+ LINK_LIBRARIES ${OpenMP_libomp_LIBRARY}
)
if(NOT OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
find_path(OpenMP_${LANG}_INCLUDE_DIR omp.h)
@@ -347,9 +367,9 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}' and '${OpenMP_${LANG}_INCLUDE_DIR}'"
- CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
- "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}"
- LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
+ CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}"
+ COMPILE_DEFINITIONS ${OPENMP_FLAG}
+ LINK_LIBRARIES ${OpenMP_libomp_LIBRARY}
)
endif()
endif()
@@ -370,8 +390,8 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'"
- CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
- LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
+ COMPILE_DEFINITIONS ${OPENMP_FLAG}
+ LINK_LIBRARIES ${OpenMP_libomp_LIBRARY}
)
if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
@@ -383,8 +403,6 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
endforeach()
-
- unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
endfunction()
set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
@@ -499,7 +517,7 @@ macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
unset(OpenMP_SPEC_DATE_MAP)
endmacro()
-foreach(LANG IN ITEMS C CXX)
+foreach(LANG IN ITEMS C CXX CUDA)
if(CMAKE_${LANG}_COMPILER_LOADED)
if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
@@ -565,7 +583,7 @@ if(CMAKE_Fortran_COMPILER_LOADED)
endif()
if(NOT OpenMP_FIND_COMPONENTS)
- set(OpenMP_FINDLIST C CXX Fortran)
+ set(OpenMP_FINDLIST C CXX CUDA Fortran)
else()
set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
endif()
@@ -644,7 +662,7 @@ foreach(LANG IN LISTS OpenMP_FINDLIST)
endforeach()
unset(_OpenMP_REQ_VARS)
-foreach(LANG IN ITEMS C CXX Fortran)
+foreach(LANG IN ITEMS C CXX CUDA Fortran)
if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
endif()
@@ -666,8 +684,8 @@ if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
endif()
endif()
-if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
- message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
+if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_CUDA_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
+ message(SEND_ERROR "FindOpenMP requires the C, CXX, CUDA, or Fortran languages to be enabled")
endif()
unset(OpenMP_C_CXX_TEST_SOURCE)
diff --git a/Tests/FindOpenMP/CMakeLists.txt b/Tests/FindOpenMP/CMakeLists.txt
index ea90baa..c8d684a 100644
--- a/Tests/FindOpenMP/CMakeLists.txt
+++ b/Tests/FindOpenMP/CMakeLists.txt
@@ -1,4 +1,4 @@
-foreach(c C CXX Fortran)
+foreach(c C CXX CUDA Fortran)
if(CMake_TEST_FindOpenMP_${c})
set(CMake_TEST_FindOpenMP_FLAG_${c} 1)
else()
@@ -16,9 +16,13 @@ add_test(NAME FindOpenMP.Test COMMAND
--build-options ${build_options}
-DOpenMP_TEST_C=${CMake_TEST_FindOpenMP_FLAG_C}
-DOpenMP_TEST_CXX=${CMake_TEST_FindOpenMP_FLAG_CXX}
+ -DOpenMP_TEST_CUDA=${CMake_TEST_FindOpenMP_FLAG_CUDA}
-DOpenMP_TEST_Fortran=${CMake_TEST_FindOpenMP_FLAG_Fortran}
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+if(CMake_TEST_FindOpenMP_FLAG_CUDA)
+ set_property(TEST FindOpenMP.Test APPEND PROPERTY LABELS "CUDA")
+endif()
if(CMake_TEST_FindOpenMP_FLAG_Fortran)
set_property(TEST FindOpenMP.Test APPEND PROPERTY LABELS "Fortran")
endif()
diff --git a/Tests/FindOpenMP/Test/CMakeLists.txt b/Tests/FindOpenMP/Test/CMakeLists.txt
index 4083855..7b05372 100644
--- a/Tests/FindOpenMP/Test/CMakeLists.txt
+++ b/Tests/FindOpenMP/Test/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.12)
+cmake_minimum_required(VERSION 3.30)
project(TestFindOpenMP NONE)
include(CTest)
@@ -8,6 +8,9 @@ macro(source_code_mapper_helper LANG_NAME SRC_FILE_NAME)
elseif("${LANG_NAME}" STREQUAL "CXX")
configure_file("${SRC_FILE_NAME}.c" "${SRC_FILE_NAME}.cxx" COPYONLY)
set(OpenMPTEST_SOURCE_FILE "${SRC_FILE_NAME}.cxx")
+ elseif("${LANG_NAME}" STREQUAL "CUDA")
+ configure_file("${SRC_FILE_NAME}.c" "${SRC_FILE_NAME}.cu" COPYONLY)
+ set(OpenMPTEST_SOURCE_FILE "${SRC_FILE_NAME}.cu")
elseif("${LANG_NAME}" STREQUAL "Fortran")
set(OpenMPTEST_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SRC_FILE_NAME}.f90")
if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
@@ -19,7 +22,7 @@ macro(source_code_mapper_helper LANG_NAME SRC_FILE_NAME)
endif()
endmacro()
-foreach(c C CXX Fortran)
+foreach(c C CXX CUDA Fortran)
if("${OpenMP_TEST_${c}}")
message("Testing ${c}")
enable_language(${c})
@@ -41,7 +44,7 @@ if(test_msvc_runtime)
endif()
endif()
-foreach(c C CXX Fortran)
+foreach(c C CXX CUDA Fortran)
if(NOT "${OpenMP_TEST_${c}}")
continue()
endif()
@@ -65,11 +68,11 @@ foreach(c C CXX Fortran)
set_property(TARGET scalprod_${c} PROPERTY LINKER_LANGUAGE ${c})
endforeach()
-foreach(c C CXX Fortran)
+foreach(c C CXX CUDA Fortran)
if(NOT "${OpenMP_TEST_${c}}")
continue()
endif()
- foreach(d C CXX Fortran)
+ foreach(d C CXX CUDA Fortran)
if(NOT "${OpenMP_TEST_${d}}")
continue()
endif()