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.
Showing
10 changed files
with
680 additions
and
405 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,119 @@ | ||
# For every public header, build a translation unit containing `#include <header>` | ||
# to let the compiler try to figure out warnings in that header if it is not otherwise | ||
# included in tests, and also to verify if the headers are modular enough. | ||
# .inl files are not globbed for, because they are not supposed to be used as public | ||
# entrypoints. | ||
|
||
foreach(thrust_target IN LISTS THRUST_TARGETS) | ||
thrust_get_target_property(config_host ${thrust_target} HOST) | ||
thrust_get_target_property(config_device ${thrust_target} DEVICE) | ||
thrust_get_target_property(config_prefix ${thrust_target} PREFIX) | ||
|
||
string(TOLOWER "${config_host}" host_lower) | ||
string(TOLOWER "${config_device}" device_lower) | ||
|
||
# GLOB ALL THE THINGS | ||
set(headers_globs thrust/*.h) | ||
set(headers_exclude_systems_globs thrust/system/*/*) | ||
set(headers_systems_globs | ||
thrust/system/${host_lower}/* | ||
thrust/system/${device_lower}/* | ||
) | ||
set(headers_exclude_details_globs | ||
thrust/detail/* | ||
thrust/*/detail/* | ||
thrust/*/*/detail/* | ||
) | ||
|
||
# Get all .h files... | ||
file(GLOB_RECURSE headers | ||
RELATIVE "${Thrust_SOURCE_DIR}/thrust" | ||
${CMAKE_CONFIGURE_DEPENDS} | ||
${headers_globs} | ||
) | ||
|
||
# ...then remove all system specific headers... | ||
file(GLOB_RECURSE headers_exclude_systems | ||
RELATIVE "${Thrust_SOURCE_DIR}/thrust" | ||
${CMAKE_CONFIGURE_DEPENDS} | ||
${headers_exclude_systems_globs} | ||
) | ||
list(REMOVE_ITEM headers ${headers_exclude_systems}) | ||
|
||
# ...then add all headers specific to the selected host and device systems back again... | ||
file(GLOB_RECURSE headers_systems | ||
RELATIVE ${Thrust_SOURCE_DIR}/thrust | ||
${CMAKE_CONFIGURE_DEPENDS} | ||
${headers_systems_globs} | ||
) | ||
list(APPEND headers ${headers_systems}) | ||
|
||
# ...and remove all the detail headers (also removing the detail headers from the selected systems). | ||
file(GLOB_RECURSE headers_exclude_details | ||
RELATIVE "${Thrust_SOURCE_DIR}/thrust" | ||
${CMAKE_CONFIGURE_DEPENDS} | ||
${headers_exclude_details_globs} | ||
) | ||
list(REMOVE_ITEM headers ${headers_exclude_details}) | ||
|
||
# List of headers that aren't implemented for all backends, but are implemented for CUDA. | ||
set(partially_implemented_CUDA | ||
async/copy.h | ||
async/for_each.h | ||
async/reduce.h | ||
async/sort.h | ||
async/transform.h | ||
event.h | ||
future.h | ||
) | ||
|
||
# List of headers that aren't implemented for all backends, but are implemented for CPP. | ||
set(partially_implemented_CPP | ||
) | ||
|
||
# List of headers that aren't implemented for all backends, but are implemented for TBB. | ||
set(partially_implemented_TBB | ||
) | ||
|
||
# List of headers that aren't implemented for all backends, but are implemented for OMP. | ||
set(partially_implemented_OMP | ||
) | ||
|
||
# List of all partially implemented headers. | ||
set(partially_implemented | ||
${partially_implemented_CUDA} | ||
${partially_implemented_CPP} | ||
${partially_implemented_TBB} | ||
${partially_implemented_OMP} | ||
) | ||
list(REMOVE_DUPLICATES partially_implemented) | ||
|
||
set(headertest_srcs) | ||
|
||
foreach (header IN LISTS headers) | ||
if ("${header}" IN_LIST partially_implemented) | ||
# This header is partially implemented on _some_ backends... | ||
if (NOT "${header}" IN_LIST partially_implemented_${config_device}) | ||
# ...but not on the selected one. | ||
continue() | ||
endif() | ||
endif() | ||
|
||
set(headertest_src_ext .cpp) | ||
if ("CUDA" STREQUAL "${config_device}") | ||
set(headertest_src_ext .cu) | ||
endif() | ||
|
||
set(headertest_src "headers/${config_prefix}/${header}${headertest_src_ext}") | ||
configure_file("${Thrust_SOURCE_DIR}/cmake/header_test.in" "${headertest_src}") | ||
|
||
list(APPEND headertest_srcs "${headertest_src}") | ||
endforeach() | ||
|
||
set(headertest_target ${config_prefix}.headers) | ||
add_library(${headertest_target} OBJECT ${headertest_srcs}) | ||
target_link_libraries(${headertest_target} PUBLIC ${thrust_target}) | ||
thrust_clone_target_properties(${headertest_target} ${thrust_target}) | ||
|
||
add_dependencies(${config_prefix}.meta ${headertest_target}) | ||
endforeach() |
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,275 @@ | ||
# This file handles thrust target creation and multiconfig. | ||
# | ||
# - Target names: (example) Thrust.cpp.cuda.cpp14 for multiconfig, or | ||
# Thrust for single config | ||
# - Target properties: | ||
# - _THRUST_HOST: {CPP, OMP, TBB} | ||
# - _THRUST_DEVICE: {CUDA, CPP, OMP, TBB} | ||
# - _THRUST_DIALECT: {11, 14, 17} | ||
# - _THRUST_PREFIX: (example) "thrust.cpp.cuda.cpp14" for multiconfig, or | ||
# "thrust" for single config | ||
# - THRUST_TARGETS list stores target names for each requested config | ||
# | ||
|
||
# Multiconfig setup: | ||
option(THRUST_ENABLE_MULTICONFIG "Enable multiconfig options for coverage testing." OFF) | ||
|
||
if (THRUST_ENABLE_MULTICONFIG) | ||
# Dialects: | ||
set(THRUST_MULTICONFIG_DIALECT_OPTIONS 11 14 17) | ||
option(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP11 "Generate C++11 build configurations." OFF) | ||
option(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP14 "Generate C++14 build configurations." ON) | ||
option(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP17 "Generate C++17 build configurations." OFF) | ||
|
||
# Default to CPP14 if all are disabled | ||
if (NOT THRUST_MULTICONFIG_ENABLE_DIALECT_CPP11 AND | ||
NOT THRUST_MULTICONFIG_ENABLE_DIALECT_CPP14 AND | ||
NOT THRUST_MULTICONFIG_ENABLE_DIALECT_CPP17) | ||
set(THRUST_MULTICONFIG_ENABLE_DIALECT_CPP14 ON) | ||
endif() | ||
|
||
# Systems: | ||
option(THRUST_MULTICONFIG_ENABLE_SYSTEM_CPP "Generate build configurations that use CPP." ON) | ||
option(THRUST_MULTICONFIG_ENABLE_SYSTEM_CUDA "Generate build configurations that use CUDA." ON) | ||
option(THRUST_MULTICONFIG_ENABLE_SYSTEM_OMP "Generate build configurations that use OpenMP." OFF) | ||
option(THRUST_MULTICONFIG_ENABLE_SYSTEM_TBB "Generate build configurations that use TBB." OFF) | ||
|
||
# Workload: | ||
# - `FULL`: [12 configs] The complete cross product of all possible build configurations. | ||
# - `LARGE`: [7 configs] All configurations that have likely usecases. | ||
# - `MEDIUM`: [5 configs] Removes somewhat redundant cases. | ||
# - `SMALL`: [3 configs] Minimal validation of each device system against the `CPP` host. | ||
# | ||
# Config | Workloads | Note | ||
# -------------------------------------------------------------------- | ||
# CPP/CUDA | F L M S | Essential: validates CUDA against CPP | ||
# CPP/TBB | F L M S | Essential: validates TBB against CPP | ||
# CPP/OMP | F L M S | Essential: validates OMP against CPP | ||
# TBB/CUDA | F L M | Important: validates TBB/CUDA interop | ||
# OMP/CUDA | F L M | Important: validates OMP/CUDA interop | ||
# TBB/TBB | F L | Somewhat redundant with CPP/TBB and TBB/CUDA | ||
# OMP/OMP | F L | Somewhat redundant with CPP/OMP and OMP/CUDA | ||
# CPP/CPP | F | Very unlikely | ||
# TBB/CPP | F | Very unlikely | ||
# OMP/CPP | F | Very unlikely | ||
# TBB/OMP | F | Very unlikely | ||
# OMP/TBB | F | Very unlikely | ||
set(THRUST_MULTICONFIG_WORKLOAD SMALL CACHE STRING | ||
"Limit host/device configs: SMALL (up to 3 h/d combos), MEDIUM(5), LARGE(7), FULL(12)" | ||
) | ||
set_property(CACHE THRUST_MULTICONFIG_WORKLOAD PROPERTY STRINGS | ||
SMALL MEDIUM LARGE FULL | ||
) | ||
set(THRUST_MULTICONFIG_WORKLOAD_SMALL_CONFIGS | ||
CPP_CUDA CPP_TBB CPP_OMP | ||
) | ||
set(THRUST_MULTICONFIG_WORKLOAD_MEDIUM_CONFIGS | ||
${THRUST_MULTICONFIG_WORKLOAD_SMALL_CONFIGS} | ||
TBB_CUDA OMP_CUDA | ||
) | ||
set(THRUST_MULTICONFIG_WORKLOAD_LARGE_CONFIGS | ||
${THRUST_MULTICONFIG_WORKLOAD_MEDIUM_CONFIGS} | ||
TBB_TBB OMP_OMP | ||
) | ||
set(THRUST_MULTICONFIG_WORKLOAD_FULL_CONFIGS | ||
${THRUST_MULTICONFIG_WORKLOAD_LARGE_CONFIGS} | ||
CPP_CPP TBB_CPP OMP_CPP TBB_OMP OMP_TBB | ||
) | ||
endif() | ||
|
||
# These are used with the targets we create to store useful metadata for generic | ||
# target handling | ||
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 _THRUST_CONFIG_VALID to TRUE or FALSE in the caller's scope | ||
function(_thrust_is_config_valid 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(_THRUST_CONFIG_VALID TRUE PARENT_SCOPE) | ||
else() | ||
set(_THRUST_CONFIG_VALID 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) | ||
set(THRUST_TARGETS ${THRUST_TARGETS} ${target_name} CACHE INTERNAL "" FORCE) | ||
endfunction() | ||
|
||
function(_thrust_build_target_list_multiconfig) | ||
# Hide the single config options if they exist: | ||
if (DEFINED THRUST_HOST_SYSTEM) | ||
set_property(CACHE THRUST_HOST_SYSTEM PROPERTY TYPE INTERNAL) | ||
set_property(CACHE THRUST_DEVICE_SYSTEM PROPERTY TYPE INTERNAL) | ||
endif() | ||
|
||
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} | ||
) | ||
|
||
# Build THRUST_TARGETS | ||
foreach(host IN LISTS THRUST_HOST_SYSTEM_OPTIONS) | ||
foreach(device IN LISTS THRUST_DEVICE_SYSTEM_OPTIONS) | ||
foreach(dialect IN LISTS THRUST_MULTICONFIG_DIALECT_OPTIONS) | ||
_thrust_is_config_valid(${host} ${device} ${dialect}) | ||
if (_THRUST_CONFIG_VALID) | ||
set(label "${host}.${device}.cpp${dialect}") | ||
string(TOLOWER "${label}" label) | ||
|
||
message(STATUS "Initializing configuration: ${label}") | ||
|
||
set(target_name "Thrust.${label}") | ||
thrust_create_target(${target_name} | ||
HOST ${host} | ||
DEVICE ${device} | ||
${THRUST_TARGET_FLAGS} | ||
) | ||
|
||
set(prefix "thrust.${label}") | ||
thrust_set_target_properties(${target_name} ${host} ${device} ${dialect} ${prefix}) | ||
_thrust_add_target_to_target_list(${target_name}) | ||
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) | ||
# Restore system option visibility if these cache options already exist: | ||
if (DEFINED THRUST_HOST_SYSTEM) | ||
set_property(CACHE THRUST_HOST_SYSTEM PROPERTY TYPE STRING) | ||
set_property(CACHE THRUST_DEVICE_SYSTEM PROPERTY TYPE STRING) | ||
endif() | ||
|
||
# Use our find_package config to assemble the Thrust library components we need: | ||
find_package(Thrust REQUIRED CONFIG | ||
NO_DEFAULT_PATH # Only check the explicit path in HINTS: | ||
HINTS "${Thrust_SOURCE_DIR}" | ||
) | ||
|
||
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 ${CMAKE_CXX_STANDARD}) | ||
set(prefix "thrust") # single config | ||
|
||
thrust_set_target_properties(Thrust ${host} ${device} ${dialect} ${prefix}) | ||
_thrust_add_target_to_target_list(Thrust) | ||
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}.meta) | ||
endforeach() | ||
endfunction() |
Oops, something went wrong.