Spaces:
Runtime error
Runtime error
File size: 9,064 Bytes
be11144 |
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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# This file provides utilities for building and working with CUB
# configuration targets.
#
# CUB_TARGETS
# - Built by the calling the `cub_build_target_list()` function.
# - Each item is the name of a CUB interface target that is configured for a
# certain build configuration. Currently only C++ standard dialect is
# considered.
#
# cub_build_target_list()
# - Creates the CUB_TARGETS list.
#
# The following functions can be used to test/set metadata on a CUB target:
#
# cub_get_target_property(<prop_var> <target_name> <prop>)
# - Checks the ${prop} target property on CUB 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 CUB target.
# - <prop> is one of the following:
# - 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.
#
# cub_get_target_properties(<target_name>)
# - Defines ${target_name}_${prop} in the caller's scope, for `prop` in:
# {DIALECT, PREFIX}. See above for details.
#
# cub_clone_target_properties(<dst_target> <src_target>)
# - Set the {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 CUB target
# to ensure that dialect information is updated correctly, e.g.
# `cub_clone_target_properties(${my_cub_test} ${some_cub_target})`
# Dialects:
set(CUB_CPP_DIALECT_OPTIONS
11 14 17
CACHE INTERNAL "C++ dialects supported by CUB." FORCE
)
define_property(TARGET PROPERTY _CUB_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 _CUB_PREFIX
BRIEF_DOCS "A prefix describing the config, eg. 'cub.cpp14'."
FULL_DOCS "A prefix describing the config, eg. 'cub.cpp14'."
)
function(cub_set_target_properties target_name dialect prefix)
set_target_properties(${target_name}
PROPERTIES
_CUB_DIALECT ${dialect}
_CUB_PREFIX ${prefix}
)
get_target_property(type ${target_name} TYPE)
if (NOT ${type} STREQUAL "INTERFACE_LIBRARY")
set_target_properties(${target_name}
PROPERTIES
CXX_STANDARD ${dialect}
CUDA_STANDARD ${dialect}
ARCHIVE_OUTPUT_DIRECTORY "${CUB_LIBRARY_OUTPUT_DIR}"
LIBRARY_OUTPUT_DIRECTORY "${CUB_LIBRARY_OUTPUT_DIR}"
RUNTIME_OUTPUT_DIRECTORY "${CUB_EXECUTABLE_OUTPUT_DIR}"
)
# CMake still emits errors about empty CUDA_ARCHITECTURES when CMP0104
# is set to OLD. This suppresses the errors for good.
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
set_target_properties(${target_name}
PROPERTIES
CUDA_ARCHITECTURES OFF
)
endif()
endif()
endfunction()
# Get a cub property from a target and store it in var_name
# cub_get_target_property(<var_name> <target_name> [DIALECT|PREFIX]
macro(cub_get_target_property prop_var target_name prop)
get_property(${prop_var} TARGET ${target_name} PROPERTY _CUB_${prop})
endmacro()
# Defines the following string variables in the caller's scope:
# - ${target_name}_DIALECT
# - ${target_name}_PREFIX
macro(cub_get_target_properties target_name)
cub_get_target_property(${target_name}_DIALECT ${target_name} DIALECT)
cub_get_target_property(${target_name}_PREFIX ${target_name} PREFIX)
endmacro()
# Set one target's _CUB_* properties to match another target
function(cub_clone_target_properties dst_target src_target)
cub_get_target_properties(${src_target})
cub_set_target_properties(${dst_target}
${${src_target}_DIALECT}
${${src_target}_PREFIX}
)
endfunction()
# Set ${var_name} to TRUE or FALSE in the caller's scope
function(_cub_is_config_valid var_name dialect)
if (CUB_ENABLE_DIALECT_CPP${dialect})
set(${var_name} TRUE PARENT_SCOPE)
else()
set(${var_name} FALSE PARENT_SCOPE)
endif()
endfunction()
function(_cub_init_target_list)
set(CUB_TARGETS "" CACHE INTERNAL "" FORCE)
endfunction()
function(_cub_add_target_to_target_list target_name dialect prefix)
cub_set_target_properties(${target_name} ${dialect} ${prefix})
target_link_libraries(${target_name} INTERFACE
CUB::CUB
cub.compiler_interface
)
if (TARGET cub.thrust)
target_link_libraries(${target_name} INTERFACE cub.thrust)
endif()
set(CUB_TARGETS ${CUB_TARGETS} ${target_name} CACHE INTERNAL "" FORCE)
set(label "cpp${dialect}")
string(TOLOWER "${label}" label)
message(STATUS "Enabling CUB configuration: ${label}")
endfunction()
# Build a ${CUB_TARGETS} list containing target names for all
# requested configurations
function(cub_build_target_list)
# Clear the list of targets:
_cub_init_target_list()
# Handle dialect options:
foreach (dialect IN LISTS CUB_CPP_DIALECT_OPTIONS)
if (CUB_IN_THRUST)
# Just use Thrust's settings:
if (THRUST_ENABLE_MULTICONFIG)
set(CUB_ENABLE_DIALECT_CPP${dialect}
${THRUST_MULTICONFIG_ENABLE_DIALECT_CPP${dialect}}
)
else()
set(val OFF)
if (dialect EQUAL ${THRUST_CPP_DIALECT})
set(val ON)
endif()
set(CUB_ENABLE_DIALECT_CPP${dialect} ${val})
endif()
else()
# Create CMake options:
set(default_value OFF)
if (dialect EQUAL 14) # Default to just 14 on:
set(default_value ON)
endif()
option(CUB_ENABLE_DIALECT_CPP${dialect}
"Generate C++${dialect} build configurations."
${default_value}
)
endif()
endforeach()
# CMake added C++17 support for CUDA targets in 3.18:
if (CUB_ENABLE_DIALECT_CPP17)
cmake_minimum_required(VERSION 3.18)
endif()
# Supported versions of MSVC do not distinguish between C++11 and C++14.
# Warn the user that they may be generating a ton of redundant targets.
if ("MSVC" STREQUAL "${CMAKE_CXX_COMPILER_ID}" AND
CUB_ENABLE_DIALECT_CPP11)
message(WARNING
"Supported versions of MSVC (2017+) do not distinguish between C++11 "
"and C++14. The requested C++11 targets will be built with C++14."
)
endif()
# Generic config flags:
macro(add_flag_option flag docstring default)
set(cub_opt "CUB_${flag}")
if (CUB_IN_THRUST)
set(thrust_opt "THRUST_${flag}")
# Use thrust's settings:
set(${cub_opt} ${${thrust_opt}})
else()
option(${cub_opt} "${docstring}" "${default}")
mark_as_advanced(${cub_opt})
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)
# Build cub.compiler_interface with warning flags, etc
# This must be called before _cub_add_target_to_target_list.
cub_build_compiler_targets()
# Set up the CUB target while testing out our find_package scripts.
find_package(CUB REQUIRED CONFIG
NO_DEFAULT_PATH # Only check the explicit path in HINTS:
HINTS "${CUB_SOURCE_DIR}"
)
# TODO
# Some of the iterators and unittests depend on thrust. We should break the
# cyclical dependency by migrating CUB's Thrust bits into Thrust.
find_package(Thrust ${CUB_VERSION} EXACT CONFIG
HINTS "../../" # Check if we are in thrust/dependencies/cub
)
if (Thrust_FOUND)
thrust_set_CUB_target(CUB::CUB)
thrust_create_target(cub.thrust HOST CPP DEVICE CUDA)
else()
message(STATUS
"Thrust was not found. Set CMake variable 'Thrust_DIR' to the "
"thrust-config.cmake file of a Thrust ${CUB_VERSION} installation to "
"enable additional testing."
)
endif()
# Build CUB_TARGETS
foreach(dialect IN LISTS CUB_CPP_DIALECT_OPTIONS)
_cub_is_config_valid(config_valid ${dialect})
if (config_valid)
set(prefix "cub.cpp${dialect}")
string(TOLOWER "${prefix}" prefix)
set(target_name "${prefix}")
add_library(${target_name} INTERFACE)
# Set configuration metadata for this cub interface target:
_cub_add_target_to_target_list(${target_name} ${dialect} ${prefix})
endif()
endforeach() # dialects
list(LENGTH CUB_TARGETS count)
message(STATUS "${count} unique cub.dialect configurations generated")
# Top level meta-target. Makes it easier to just build CUB targets when
# building both CUB and Thrust. Add all project files here so IDEs will be
# aware of them. This will not generate build rules.
file(GLOB_RECURSE all_sources
RELATIVE "${CMAKE_CURRENT_LIST_DIR}"
"${CUB_SOURCE_DIR}/cub/*.cuh"
)
add_custom_target(cub.all SOURCES ${all_sources})
# Create meta targets for each config:
foreach(cub_target IN LISTS CUB_TARGETS)
cub_get_target_property(config_prefix ${cub_target} PREFIX)
add_custom_target(${config_prefix}.all)
add_dependencies(cub.all ${config_prefix}.all)
endforeach()
endfunction()
|