mirror of
https://github.com/Kitware/CMake.git
synced 2026-03-15 05:51:07 -05:00
FindOpenMP: Add support for CUDA when supported by the toolchain
NVCC supports OpenMP on the host when the host compiler does.
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
set(CMake_TEST_CUDA "NVIDIA" CACHE STRING "")
|
set(CMake_TEST_CUDA "NVIDIA" CACHE STRING "")
|
||||||
set(CMake_TEST_CUDA_CUPTI "ON" 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_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")
|
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
|
||||||
|
|||||||
5
Help/release/dev/FindOpenMP-CUDA.rst
Normal file
5
Help/release/dev/FindOpenMP-CUDA.rst
Normal file
@@ -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.
|
||||||
@@ -37,6 +37,10 @@ Result Variables
|
|||||||
The module exposes the components ``C``, ``CXX``, and ``Fortran``.
|
The module exposes the components ``C``, ``CXX``, and ``Fortran``.
|
||||||
Each of these controls the various languages to search OpenMP support for.
|
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:
|
Depending on the enabled components the following variables will be set:
|
||||||
|
|
||||||
``OpenMP_FOUND``
|
``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.
|
or all enabled languages if no components were specified.
|
||||||
|
|
||||||
This module will set the following variables per language in your
|
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``
|
``OpenMP_<lang>_FOUND``
|
||||||
Variable indicating if OpenMP support for ``<lang>`` was detected.
|
Variable indicating if OpenMP support for ``<lang>`` was detected.
|
||||||
@@ -153,7 +157,11 @@ function(_OPENMP_FLAG_CANDIDATES LANG)
|
|||||||
set(OMP_FLAG_Fujitsu "-Kopenmp" "-KOMP")
|
set(OMP_FLAG_Fujitsu "-Kopenmp" "-KOMP")
|
||||||
set(OMP_FLAG_FujitsuClang "-fopenmp" "-Kopenmp")
|
set(OMP_FLAG_FujitsuClang "-fopenmp" "-Kopenmp")
|
||||||
|
|
||||||
set(compiler_id "${CMAKE_${LANG}_COMPILER_ID}")
|
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 we know the correct flags, use those
|
||||||
if(DEFINED OMP_FLAG_${compiler_id})
|
if(DEFINED OMP_FLAG_${compiler_id})
|
||||||
@@ -206,6 +214,9 @@ macro(_OPENMP_PREPARE_SOURCE LANG CONTENT_ID NAME_PREFIX FULLNAME_VAR CONTENT_VA
|
|||||||
elseif("${LANG}" STREQUAL "CXX")
|
elseif("${LANG}" STREQUAL "CXX")
|
||||||
set(${FULLNAME_VAR} "${NAME_PREFIX}.cpp")
|
set(${FULLNAME_VAR} "${NAME_PREFIX}.cpp")
|
||||||
set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
|
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")
|
elseif("${LANG}" STREQUAL "Fortran")
|
||||||
set(${FULLNAME_VAR} "${NAME_PREFIX}.F90")
|
set(${FULLNAME_VAR} "${NAME_PREFIX}.F90")
|
||||||
string(CONFIGURE "${OpenMP_Fortran_${CONTENT_ID}}" ${CONTENT_VAR} @ONLY)
|
string(CONFIGURE "${OpenMP_Fortran_${CONTENT_ID}}" ${CONTENT_VAR} @ONLY)
|
||||||
@@ -227,11 +238,24 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
|
|||||||
if(OpenMP_${LANG}_INCLUDE_DIR)
|
if(OpenMP_${LANG}_INCLUDE_DIR)
|
||||||
set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
|
set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
|
||||||
endif()
|
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}
|
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
|
||||||
SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
|
SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
|
||||||
LOG_DESCRIPTION "Detecting ${LANG} OpenMP compiler info"
|
LOG_DESCRIPTION "Detecting ${LANG} OpenMP compiler info"
|
||||||
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAG}" ${_includeDirFlags}
|
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAG}" ${_includeDirFlags}
|
||||||
LINK_OPTIONS ${OpenMP_VERBOSE_OPTIONS}
|
LINK_OPTIONS ${OpenMP_VERBOSE_OPTIONS} ${_OpenMP_LINK_OPTIONS}
|
||||||
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
|
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -282,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_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
|
||||||
string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
|
string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
|
||||||
if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
|
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}_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})( |$)" ) )
|
OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
|
||||||
if(_OPENMP_IMPLICIT_LIB_DIR)
|
if(_OPENMP_IMPLICIT_LIB_DIR)
|
||||||
@@ -302,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})
|
list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
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)
|
set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
|
||||||
else()
|
else()
|
||||||
# We do not know how to extract implicit OpenMP libraries for this compiler.
|
# We do not know how to extract implicit OpenMP libraries for this compiler.
|
||||||
@@ -489,7 +517,7 @@ macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
|
|||||||
unset(OpenMP_SPEC_DATE_MAP)
|
unset(OpenMP_SPEC_DATE_MAP)
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
foreach(LANG IN ITEMS C CXX)
|
foreach(LANG IN ITEMS C CXX CUDA)
|
||||||
if(CMAKE_${LANG}_COMPILER_LOADED)
|
if(CMAKE_${LANG}_COMPILER_LOADED)
|
||||||
if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
|
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")
|
OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
|
||||||
@@ -555,7 +583,7 @@ if(CMAKE_Fortran_COMPILER_LOADED)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT OpenMP_FIND_COMPONENTS)
|
if(NOT OpenMP_FIND_COMPONENTS)
|
||||||
set(OpenMP_FINDLIST C CXX Fortran)
|
set(OpenMP_FINDLIST C CXX CUDA Fortran)
|
||||||
else()
|
else()
|
||||||
set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
|
set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
|
||||||
endif()
|
endif()
|
||||||
@@ -634,7 +662,7 @@ foreach(LANG IN LISTS OpenMP_FINDLIST)
|
|||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
unset(_OpenMP_REQ_VARS)
|
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)
|
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")
|
list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
|
||||||
endif()
|
endif()
|
||||||
@@ -656,8 +684,8 @@ if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
|
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 or Fortran languages to be enabled")
|
message(SEND_ERROR "FindOpenMP requires the C, CXX, CUDA, or Fortran languages to be enabled")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
unset(OpenMP_C_CXX_TEST_SOURCE)
|
unset(OpenMP_C_CXX_TEST_SOURCE)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
foreach(c C CXX Fortran)
|
foreach(c C CXX CUDA Fortran)
|
||||||
if(CMake_TEST_FindOpenMP_${c})
|
if(CMake_TEST_FindOpenMP_${c})
|
||||||
set(CMake_TEST_FindOpenMP_FLAG_${c} 1)
|
set(CMake_TEST_FindOpenMP_FLAG_${c} 1)
|
||||||
else()
|
else()
|
||||||
@@ -16,9 +16,13 @@ add_test(NAME FindOpenMP.Test COMMAND
|
|||||||
--build-options ${build_options}
|
--build-options ${build_options}
|
||||||
-DOpenMP_TEST_C=${CMake_TEST_FindOpenMP_FLAG_C}
|
-DOpenMP_TEST_C=${CMake_TEST_FindOpenMP_FLAG_C}
|
||||||
-DOpenMP_TEST_CXX=${CMake_TEST_FindOpenMP_FLAG_CXX}
|
-DOpenMP_TEST_CXX=${CMake_TEST_FindOpenMP_FLAG_CXX}
|
||||||
|
-DOpenMP_TEST_CUDA=${CMake_TEST_FindOpenMP_FLAG_CUDA}
|
||||||
-DOpenMP_TEST_Fortran=${CMake_TEST_FindOpenMP_FLAG_Fortran}
|
-DOpenMP_TEST_Fortran=${CMake_TEST_FindOpenMP_FLAG_Fortran}
|
||||||
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
|
--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)
|
if(CMake_TEST_FindOpenMP_FLAG_Fortran)
|
||||||
set_property(TEST FindOpenMP.Test APPEND PROPERTY LABELS "Fortran")
|
set_property(TEST FindOpenMP.Test APPEND PROPERTY LABELS "Fortran")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.30)
|
||||||
project(TestFindOpenMP NONE)
|
project(TestFindOpenMP NONE)
|
||||||
include(CTest)
|
include(CTest)
|
||||||
|
|
||||||
@@ -8,6 +8,9 @@ macro(source_code_mapper_helper LANG_NAME SRC_FILE_NAME)
|
|||||||
elseif("${LANG_NAME}" STREQUAL "CXX")
|
elseif("${LANG_NAME}" STREQUAL "CXX")
|
||||||
configure_file("${SRC_FILE_NAME}.c" "${SRC_FILE_NAME}.cxx" COPYONLY)
|
configure_file("${SRC_FILE_NAME}.c" "${SRC_FILE_NAME}.cxx" COPYONLY)
|
||||||
set(OpenMPTEST_SOURCE_FILE "${SRC_FILE_NAME}.cxx")
|
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")
|
elseif("${LANG_NAME}" STREQUAL "Fortran")
|
||||||
set(OpenMPTEST_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SRC_FILE_NAME}.f90")
|
set(OpenMPTEST_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SRC_FILE_NAME}.f90")
|
||||||
if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
|
if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
|
||||||
@@ -19,7 +22,7 @@ macro(source_code_mapper_helper LANG_NAME SRC_FILE_NAME)
|
|||||||
endif()
|
endif()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
foreach(c C CXX Fortran)
|
foreach(c C CXX CUDA Fortran)
|
||||||
if("${OpenMP_TEST_${c}}")
|
if("${OpenMP_TEST_${c}}")
|
||||||
message("Testing ${c}")
|
message("Testing ${c}")
|
||||||
enable_language(${c})
|
enable_language(${c})
|
||||||
@@ -41,7 +44,7 @@ if(test_msvc_runtime)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(c C CXX Fortran)
|
foreach(c C CXX CUDA Fortran)
|
||||||
if(NOT "${OpenMP_TEST_${c}}")
|
if(NOT "${OpenMP_TEST_${c}}")
|
||||||
continue()
|
continue()
|
||||||
endif()
|
endif()
|
||||||
@@ -65,11 +68,11 @@ foreach(c C CXX Fortran)
|
|||||||
set_property(TARGET scalprod_${c} PROPERTY LINKER_LANGUAGE ${c})
|
set_property(TARGET scalprod_${c} PROPERTY LINKER_LANGUAGE ${c})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
foreach(c C CXX Fortran)
|
foreach(c C CXX CUDA Fortran)
|
||||||
if(NOT "${OpenMP_TEST_${c}}")
|
if(NOT "${OpenMP_TEST_${c}}")
|
||||||
continue()
|
continue()
|
||||||
endif()
|
endif()
|
||||||
foreach(d C CXX Fortran)
|
foreach(d C CXX CUDA Fortran)
|
||||||
if(NOT "${OpenMP_TEST_${d}}")
|
if(NOT "${OpenMP_TEST_${d}}")
|
||||||
continue()
|
continue()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
Reference in New Issue
Block a user