forked from NVIDIA/thrust
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes NVIDIA#1159. Also fixes or works around these issues: - WAR NVIDIA#1167: Disable arches 53, 62, 72 by default. - Fixes NVIDIA#1168: Set RUN_SERIAL on OpenMP tests. - WAR ccache/ccache#598: nvcc flags `s/-Werror all-warnings/-Xcudafe --promote_warnings/g` - WAR NVIDIA#1174: remove warning promotion from tbb.cuda targets. - WAR NVIDIA#976: Add options to enable/disable tests, examples, header_tests: - THRUST_ENABLE_TESTING - THRUST_ENABLE_EXAMPLES - THRUST_ENABLE_HEADER_TESTING Summary: - Bump CMake to 3.15 - Needed for CUDA_COMPILER_ID generator expression. - Removed workarounds for older CMake versions. - Removed warning flag specific to for C++98. - Dialects are now configured through target properties. Add new THRUST_CPP_DIALECT option for single config mode, and remove logic that modified CMAKE_CXX_STANDARD and CMAKE_CUDA_STANDARD. - Move testing related CMake code to `testing/CMakeLists.txt` - Move example related CMake code to `examples/CMakeLists.txt` - Move header testing related CMake code to `cmake/ThrustHeaderTesting.cmake` - Move CUDA configuration logic to `cmake/ThrustCUDAConfig.cmake`. - Explicitly `include(cmake/*.cmake)` files rather than searching CMAKE_MODULE_PATH -- we only want to use the ones in the repo. - Added ThrustMultiConfig.cmake - Handle MultiConfig (and single config) logic. - Added ThrustBuildTargetList.cmake - Builds the THRUST_TARGETS list, which contains one interface target for each enabled host/device/dialect configuration. - Added ThrustBuildCompilerTargets.cmake - Move warning flag, etc setup into it, bind compile interfaces to targets instead of global variables. - Renamed common_variables.cmake to ThrustCommonVariables.cmake - Removed THRUST_TREAT_FILE_AS_CXX - This worked by setting a cmake SOURCE_FILE property, which no longer works since multiconfig may build the same source file with both CXX and CUDA. - Instead, the `.cu` files are wrapped in a `.cpp` file that does nothing but include the `.cu` file. The `.cpp` files are then added to the CXX targets as sources. - See `cmake/ThrustUtilities.cmake` for implementation. - Fix bug in thrust-config.cmake where an internal var was not cached as expected.
- Loading branch information
1 parent
311f3d8
commit c678e37
Showing
15 changed files
with
1,037 additions
and
620 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# | ||
# This file defines the `thrust_build_compiler_targets()` function, which | ||
# creates the following interface targets: | ||
# | ||
# thrust.compiler_interface | ||
# - Interface target providing compiler-specific options needed to build | ||
# Thrust's tests, examples, etc. | ||
# | ||
# thrust.promote_cudafe_warnings | ||
# - Interface target that adds warning promotion for NVCC cudafe invocations. | ||
# - Only exists to work around github issue #1174 on tbb.cuda configurations. | ||
# - May be combined with thrust.compiler_interface when #1174 is fully resolved. | ||
|
||
function(thrust_build_compiler_targets) | ||
set(cxx_compile_definitions) | ||
set(cxx_compile_options) | ||
|
||
thrust_update_system_found_flags() | ||
|
||
if (THRUST_TBB_FOUND) | ||
# There's a ton of these in the TBB backend, even though the code is correct. | ||
# TODO: silence these warnings in code instead | ||
append_option_if_available("-Wno-unused-parameter" cxx_compile_options) | ||
endif() | ||
|
||
if ("MSVC" STREQUAL "${CMAKE_CXX_COMPILER_ID}") | ||
# TODO Enable /Wall | ||
append_option_if_available("/WX" cxx_compile_options) | ||
|
||
# Disabled loss-of-data conversion warnings. | ||
# TODO Re-enable. | ||
append_option_if_available("/wd4244" cxx_compile_options) | ||
append_option_if_available("/wd4267" cxx_compile_options) | ||
|
||
# Suppress numeric conversion-to-bool warnings. | ||
# TODO Re-enable. | ||
append_option_if_available("/wd4800" cxx_compile_options) | ||
|
||
# Disable warning about applying unary operator- to unsigned type. | ||
append_option_if_available("/wd4146" cxx_compile_options) | ||
|
||
# MSVC STL assumes that `allocator_traits`'s allocator will use raw pointers, | ||
# and the `__DECLSPEC_ALLOCATOR` macro causes issues with thrust's universal | ||
# allocators: | ||
# warning C4494: 'std::allocator_traits<_Alloc>::allocate' : | ||
# Ignoring __declspec(allocator) because the function return type is not | ||
# a pointer or reference | ||
# See https://github.com/microsoft/STL/issues/696 | ||
append_option_if_available("/wd4494" cxx_compile_options) | ||
|
||
# Some of the async tests require /bigobj to fit all their sections into the | ||
# object files: | ||
append_option_if_available("/bigobj" cxx_compile_options) | ||
|
||
# "Oh right, this is Visual Studio." | ||
list(APPEND cxx_compile_definitions "NOMINMAX") | ||
else() | ||
append_option_if_available("-Werror" cxx_compile_options) | ||
append_option_if_available("-Wall" cxx_compile_options) | ||
append_option_if_available("-Wextra" cxx_compile_options) | ||
append_option_if_available("-Winit-self" cxx_compile_options) | ||
append_option_if_available("-Woverloaded-virtual" cxx_compile_options) | ||
append_option_if_available("-Wcast-qual" cxx_compile_options) | ||
append_option_if_available("-Wno-cast-align" cxx_compile_options) | ||
append_option_if_available("-Wno-long-long" cxx_compile_options) | ||
append_option_if_available("-Wno-variadic-macros" cxx_compile_options) | ||
append_option_if_available("-Wno-unused-function" cxx_compile_options) | ||
append_option_if_available("-Wno-unused-variable" cxx_compile_options) | ||
endif() | ||
|
||
if ("GNU" STREQUAL "${CMAKE_CXX_COMPILER_ID}") | ||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5) | ||
# In GCC 4.4, the CUDA backend's kernel launch templates cause | ||
# impossible-to-decipher "'<anonymous>' is used uninitialized in this | ||
# function" warnings, so we disable uninitialized variable warnings. | ||
append_option_if_available("-Wno-uninitialized" cxx_compile_options) | ||
endif() | ||
|
||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.5) | ||
# This isn't available until GCC 4.3, and misfires on TMP code until | ||
# GCC 4.5. | ||
append_option_if_available("-Wlogical-op" cxx_compile_options) | ||
endif() | ||
|
||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.3) | ||
# GCC 7.3 complains about name mangling changes due to `noexcept` | ||
# becoming part of the type system; we don't care. | ||
append_option_if_available("-Wno-noexcept-type" cxx_compile_options) | ||
endif() | ||
endif() | ||
|
||
if (("Clang" STREQUAL "${CMAKE_CXX_COMPILER_ID}") OR | ||
("XL" STREQUAL "${CMAKE_CXX_COMPILER_ID}")) | ||
# xlC and Clang warn about unused parameters in uninstantiated templates. | ||
# This causes xlC to choke on the OMP backend, which is mostly #ifdef'd out | ||
# (and thus has unused parameters) when you aren't using it. | ||
append_option_if_available("-Wno-unused-parameters" cxx_compile_options) | ||
endif() | ||
|
||
if ("Clang" STREQUAL "${CMAKE_CXX_COMPILER_ID}") | ||
# -Wunneeded-internal-declaration misfires in the unit test framework | ||
# on older versions of Clang. | ||
append_option_if_available("-Wno-unneeded-internal-declaration" cxx_compile_options) | ||
endif() | ||
|
||
if ("Feta" STREQUAL "${CMAKE_CUDA_COMPILER_ID}") | ||
# Today: | ||
# * NVCC accepts CUDA C++ in .cu files but not .cpp files. | ||
# * Feta accepts CUDA C++ in .cpp files but not .cu files. | ||
# TODO: This won't be necessary in the future. | ||
list(APPEND cxx_compile_options -cppsuffix=cu) | ||
endif() | ||
|
||
add_library(thrust.compiler_interface INTERFACE) | ||
|
||
foreach (cxx_option IN LISTS cxx_compile_options) | ||
target_compile_options(thrust.compiler_interface INTERFACE | ||
$<$<COMPILE_LANGUAGE:CXX>:${cxx_option}> | ||
# Only use -Xcompiler with NVCC, not Feta. | ||
# | ||
# CMake can't split genexs, so this can't be formatted better :( | ||
# This is: | ||
# if (using CUDA and CUDA_COMPILER is NVCC) add -Xcompiler=opt: | ||
$<$<AND:$<COMPILE_LANGUAGE:CUDA>,$<CUDA_COMPILER_ID:NVIDIA>>:-Xcompiler=${cxx_option}> | ||
) | ||
endforeach() | ||
|
||
foreach (cxx_definition IN LISTS cxx_compile_definitions) | ||
# Add these for both CUDA and CXX targets: | ||
target_compile_definitions(thrust.compiler_interface INTERFACE | ||
${cxx_definition} | ||
) | ||
endforeach() | ||
|
||
# Display warning numbers from nvcc cudafe errors: | ||
target_compile_options(thrust.compiler_interface INTERFACE | ||
# If using CUDA w/ NVCC... | ||
$<$<AND:$<COMPILE_LANGUAGE:CUDA>,$<CUDA_COMPILER_ID:NVIDIA>>:-Xcudafe=--display_error_number> | ||
) | ||
|
||
# This is kept separate for Github issue #1174. | ||
add_library(thrust.promote_cudafe_warnings INTERFACE) | ||
target_compile_options(thrust.promote_cudafe_warnings INTERFACE | ||
$<$<AND:$<COMPILE_LANGUAGE:CUDA>,$<CUDA_COMPILER_ID:NVIDIA>>:-Xcudafe=--promote_warnings> | ||
) | ||
endfunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
# This file provides utilities for building and working with thrust | ||
# configuration targets. | ||
# | ||
# THRUST_TARGETS | ||
# - Built by the calling the `thrust_build_target_list()` function. | ||
# - Each item is the name of a thrust interface target that is configured for a | ||
# certain combination of host/device/dialect. | ||
# | ||
# thrust_build_target_list() | ||
# - Creates the THRUST_TARGETS list. | ||
# | ||
# The following functions can be used to test/set metadata on a thrust target: | ||
# | ||
# thrust_get_target_property(<prop_var> <target_name> <prop>) | ||
# - Checks the ${prop} target property on thrust target ${target_name} | ||
# and sets the ${prop_var} variable in the caller's scope. | ||
# - <prop_var> is any valid cmake identifier. | ||
# - <target_name> is the name of a thrust target. | ||
# - <prop> is one of the following: | ||
# - HOST: The host system. Valid values: CPP, OMP, TBB. | ||
# - DEVICE: The device system. Valid values: CUDA, CPP, OMP, TBB. | ||
# - DIALECT: The C++ dialect. Valid values: 11, 14, 17. | ||
# - PREFIX: A unique prefix that should be used to name all | ||
# targets/tests/examples that use this configuration. | ||
# | ||
# thrust_get_target_properties(<target_name>) | ||
# - Defines ${target_name}_${prop} in the caller's scope, for `prop` in: | ||
# HOST, DEVICE, DIALECT, PREFIX. See above for details. | ||
# | ||
# thrust_clone_target_properties(<dst_target> <src_target>) | ||
# - Set the HOST, DEVICE, DIALECT, PREFIX metadata on ${dst_target} to match | ||
# ${src_target}. See above for details. | ||
# - This *MUST* be called on any targets that link to another thrust target | ||
# to ensure that dialect information is updated correctly, e.g. | ||
# `thrust_clone_target_properties(${my_thrust_test} ${some_thrust_target})` | ||
|
||
define_property(TARGET PROPERTY _THRUST_HOST | ||
BRIEF_DOCS "A target's host system: CPP, TBB, or OMP." | ||
FULL_DOCS "A target's host system: CPP, TBB, or OMP." | ||
) | ||
define_property(TARGET PROPERTY _THRUST_DEVICE | ||
BRIEF_DOCS "A target's device system: CUDA, CPP, TBB, or OMP." | ||
FULL_DOCS "A target's device system: CUDA, CPP, TBB, or OMP." | ||
) | ||
define_property(TARGET PROPERTY _THRUST_DIALECT | ||
BRIEF_DOCS "A target's C++ dialect: 11, 14, or 17." | ||
FULL_DOCS "A target's C++ dialect: 11, 14, or 17." | ||
) | ||
define_property(TARGET PROPERTY _THRUST_PREFIX | ||
BRIEF_DOCS "A prefix describing the config, eg. 'thrust.cpp.cuda.cpp14'." | ||
FULL_DOCS "A prefix describing the config, eg. 'thrust.cpp.cuda.cpp14'." | ||
) | ||
|
||
function(thrust_set_target_properties target_name host device dialect prefix) | ||
set_property(TARGET ${target_name} PROPERTY _THRUST_HOST ${host}) | ||
set_property(TARGET ${target_name} PROPERTY _THRUST_DEVICE ${device}) | ||
set_property(TARGET ${target_name} PROPERTY _THRUST_DIALECT ${dialect}) | ||
set_property(TARGET ${target_name} PROPERTY _THRUST_PREFIX ${prefix}) | ||
|
||
get_target_property(type ${target_name} TYPE) | ||
if (NOT ${type} STREQUAL "INTERFACE_LIBRARY") | ||
set_property(TARGET ${target_name} PROPERTY CXX_STANDARD ${dialect}) | ||
set_property(TARGET ${target_name} PROPERTY CUDA_STANDARD ${dialect}) | ||
endif() | ||
endfunction() | ||
|
||
# Get a thrust property from a target and store it in var_name | ||
# thrust_get_target_property(<var_name> <target_name> [HOST|DEVICE|DIALECT|PREFIX] | ||
macro(thrust_get_target_property prop_var target_name prop) | ||
get_property(${prop_var} TARGET ${target_name} PROPERTY _THRUST_${prop}) | ||
endmacro() | ||
|
||
# Defines the following string variables in the caller's scope: | ||
# - ${target_name}_HOST | ||
# - ${target_name}_DEVICE | ||
# - ${target_name}_DIALECT | ||
# - ${target_name}_PREFIX | ||
macro(thrust_get_target_properties target_name) | ||
thrust_get_target_property(${target_name}_HOST ${target_name} HOST) | ||
thrust_get_target_property(${target_name}_DEVICE ${target_name} DEVICE) | ||
thrust_get_target_property(${target_name}_DIALECT ${target_name} DIALECT) | ||
thrust_get_target_property(${target_name}_PREFIX ${target_name} PREFIX) | ||
endmacro() | ||
|
||
# Set one target's THRUST_* properties to match another target | ||
function(thrust_clone_target_properties dst_target src_target) | ||
thrust_get_target_properties(${src_target}) | ||
thrust_set_target_properties(${dst_target} | ||
${${src_target}_HOST} | ||
${${src_target}_DEVICE} | ||
${${src_target}_DIALECT} | ||
${${src_target}_PREFIX} | ||
) | ||
endfunction() | ||
|
||
# Set ${var_name} to TRUE or FALSE in the caller's scope | ||
function(_thrust_is_config_valid var_name host device dialect) | ||
if (THRUST_MULTICONFIG_ENABLE_SYSTEM_${host} AND | ||
THRUST_MULTICONFIG_ENABLE_SYSTEM_${device} AND | ||
THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${dialect} AND | ||
"${host}_${device}" IN_LIST THRUST_MULTICONFIG_WORKLOAD_${THRUST_MULTICONFIG_WORKLOAD}_CONFIGS) | ||
set(${var_name} TRUE PARENT_SCOPE) | ||
else() | ||
set(${var_name} FALSE PARENT_SCOPE) | ||
endif() | ||
endfunction() | ||
|
||
function(_thrust_init_target_list) | ||
set(THRUST_TARGETS "" CACHE INTERNAL "" FORCE) | ||
endfunction() | ||
|
||
function(_thrust_add_target_to_target_list target_name host device dialect prefix) | ||
thrust_set_target_properties(${target_name} ${host} ${device} ${dialect} ${prefix}) | ||
|
||
target_link_libraries(${target_name} INTERFACE | ||
thrust.compiler_interface | ||
) | ||
|
||
# Workaround Github issue #1174. cudafe promote TBB header warnings to | ||
# errors, even when they're -isystem includes. | ||
if ((NOT host STREQUAL "TBB") OR (NOT device STREQUAL "CUDA")) | ||
target_link_libraries(${target_name} INTERFACE | ||
thrust.promote_cudafe_warnings | ||
) | ||
endif() | ||
|
||
set(THRUST_TARGETS ${THRUST_TARGETS} ${target_name} CACHE INTERNAL "" FORCE) | ||
|
||
set(label "${host}.${device}.cpp${dialect}") | ||
string(TOLOWER "${label}" label) | ||
message(STATUS "Enabling configuration: ${label}") | ||
endfunction() | ||
|
||
function(_thrust_build_target_list_multiconfig) | ||
# Find thrust and all of the required systems: | ||
set(req_systems) | ||
if (THRUST_MULTICONFIG_ENABLE_SYSTEM_CUDA) | ||
list(APPEND req_systems CUDA) | ||
endif() | ||
if (THRUST_MULTICONFIG_ENABLE_SYSTEM_CPP) | ||
list(APPEND req_systems CPP) | ||
endif() | ||
if (THRUST_MULTICONFIG_ENABLE_SYSTEM_TBB) | ||
list(APPEND req_systems TBB) | ||
endif() | ||
if (THRUST_MULTICONFIG_ENABLE_SYSTEM_OMP) | ||
list(APPEND req_systems OMP) | ||
endif() | ||
|
||
find_package(Thrust REQUIRED CONFIG | ||
NO_DEFAULT_PATH # Only check the explicit path in HINTS: | ||
HINTS "${Thrust_SOURCE_DIR}" | ||
COMPONENTS ${req_systems} | ||
) | ||
|
||
# This must be called after backends are loaded but | ||
# before _thrust_add_target_to_target_list. | ||
thrust_build_compiler_targets() | ||
|
||
# Build THRUST_TARGETS | ||
foreach(host IN LISTS THRUST_HOST_SYSTEM_OPTIONS) | ||
foreach(device IN LISTS THRUST_DEVICE_SYSTEM_OPTIONS) | ||
foreach(dialect IN LISTS THRUST_CPP_DIALECT_OPTIONS) | ||
_thrust_is_config_valid(config_valid ${host} ${device} ${dialect}) | ||
if (config_valid) | ||
set(prefix "thrust.${host}.${device}.cpp${dialect}") | ||
string(TOLOWER "${prefix}" prefix) | ||
|
||
# Configure a thrust interface target for this host/device | ||
set(target_name "${prefix}") | ||
thrust_create_target(${target_name} | ||
HOST ${host} | ||
DEVICE ${device} | ||
${THRUST_TARGET_FLAGS} | ||
) | ||
|
||
# Set configuration metadata for this thrust interface target: | ||
_thrust_add_target_to_target_list(${target_name} | ||
${host} ${device} ${dialect} ${prefix} | ||
) | ||
endif() | ||
endforeach() # dialects | ||
endforeach() # devices | ||
endforeach() # hosts | ||
|
||
list(LENGTH THRUST_TARGETS count) | ||
message(STATUS "${count} unique host.device.dialect configurations generated") | ||
endfunction() | ||
|
||
function(_thrust_build_target_list_singleconfig) | ||
thrust_create_target(thrust FROM_OPTIONS ${THRUST_TARGET_FLAGS}) | ||
thrust_debug_target(thrust "${THRUST_VERSION}") | ||
|
||
set(host ${THRUST_HOST_SYSTEM}) | ||
set(device ${THRUST_DEVICE_SYSTEM}) | ||
set(dialect ${THRUST_CPP_DIALECT}) | ||
set(prefix "thrust") # single config | ||
|
||
# This depends on the backends loaded by thrust_create_target, and must | ||
# be called before _thrust_add_target_to_target_list. | ||
thrust_build_compiler_targets() | ||
|
||
_thrust_add_target_to_target_list(thrust ${host} ${device} ${dialect} ${prefix}) | ||
endfunction() | ||
|
||
# Build a ${THRUST_TARGETS} list containing target names for all | ||
# requested configurations | ||
function(thrust_build_target_list) | ||
# Clear the list of targets: | ||
_thrust_init_target_list() | ||
|
||
# Generic config flags: | ||
set(THRUST_TARGET_FLAGS) | ||
macro(add_flag_option flag docstring default) | ||
set(opt "THRUST_${flag}") | ||
option(${opt} "${docstring}" "${default}") | ||
mark_as_advanced(${opt}) | ||
if (${${opt}}) | ||
list(APPEND THRUST_TARGET_FLAGS ${flag}) | ||
endif() | ||
endmacro() | ||
add_flag_option(IGNORE_DEPRECATED_CPP_DIALECT "Don't warn about any deprecated C++ standards and compilers." OFF) | ||
add_flag_option(IGNORE_DEPRECATED_CPP_11 "Don't warn about deprecated C++11." OFF) | ||
add_flag_option(IGNORE_DEPRECATED_COMPILER "Don't warn about deprecated COMPILERS." OFF) | ||
add_flag_option(IGNORE_CUB_VERSION_CHECK "Don't warn about mismatched CUB versions." OFF) | ||
|
||
if (THRUST_ENABLE_MULTICONFIG) | ||
_thrust_build_target_list_multiconfig() | ||
else() | ||
_thrust_build_target_list_singleconfig() | ||
endif() | ||
|
||
# Create meta targets for each config: | ||
foreach(thrust_target IN LISTS THRUST_TARGETS) | ||
thrust_get_target_property(config_prefix ${thrust_target} PREFIX) | ||
add_custom_target(${config_prefix}.all) | ||
endforeach() | ||
endfunction() |
Oops, something went wrong.