Added 863 files from NVIDIA/cccl sparse checkout: - c2h/ (27 files): Catch2 test helpers — generators, validators, runner - nvbench_helper/ (10 files): Benchmark harness utilities - cmake/ (29 files): CMake presets and build helpers - cudax/ (794 files): Experimental CUDA extensions - AGENTS.md: NVIDIA's official AI agent instructions for CCCL - CMakePresets.json: Standardized build configurations - cccl-version.json: Version tracking Also added CCCL_ASSET_MAP.md mapping all 4295 CCCL files to competition value and PRD items. cccl_upstream now covers 100% of competition-critical assets: - 27 tuning headers (SM80/90/100 benchmark data) - 32 dispatch headers (algorithm implementations) - 60 Thrust examples (correctness verification) - 217 CUB Catch2 tests (regression matrix) - 153 CUB benchmarks (parameter space search) - 18 CUB examples (API verification) - 27 test helpers + benchmark harness - 794 cudax experimental extensions
243 lines
8.1 KiB
CMake
243 lines
8.1 KiB
CMake
# Usage:
|
|
# cccl_generate_header_tests(<target_name> <project_include_path>
|
|
# [cccl_configure_target options]
|
|
# [LANGUAGE <CXX|CUDA>]
|
|
# [HEADER_TEMPLATE <template>]
|
|
# [GLOBS <glob1> [glob2 ...]]
|
|
# [EXCLUDES <glob1> [glob2 ...]]
|
|
# [HEADERS <header1> [header2 ...]]
|
|
# [PER_HEADER_DEFINES
|
|
# DEFINE <definition> <regex> [<regex> ...]
|
|
# [DEFINE <definition> <regex> [<regex> ...]] ...]
|
|
# )
|
|
#
|
|
# Options:
|
|
# target_name: The name of the meta-target that will build this set of header tests.
|
|
# project_include_path: The path to the project's include directory, relative to <CCCL_SOURCE_DIR>.
|
|
# cccl_configure_target options: Options to pass to cccl_configure_target. Must appear before any other named arguments.
|
|
# LANGUAGE: The language to use for the header tests. Defaults to CUDA.
|
|
# HEADER_TEMPLATE: A file that will be used as a template for each header test. The template will be configured for each header.
|
|
# GLOBS: All files that match these globbing patterns will be included in the header tests, unless they also match EXCLUDES.
|
|
# EXCLUDES: Files that match these globbing patterns will be excluded from the header tests.
|
|
# HEADERS: An explicit list of headers to include in the header tests.
|
|
# PER_HEADER_DEFINES: A list of definitions to add to specific headers. Each definition is followed by one or more regexes that match the headers it should be applied to.
|
|
# NO_METATARGETS: If specified, metatargets will not be created for the header test targets.
|
|
#
|
|
# Notes:
|
|
# - The header globs are applied relative to <project_include_path>.
|
|
# - If no HEADER_TEMPLATE is provided, a default template will be used.
|
|
# - The HEADER_TEMPLATE will be configured for each header, with the following variables:
|
|
# - @header@: The path to the target header, relative to <project_include_path>.
|
|
option(
|
|
CCCL_COMPILE_TIME_SAVE_PREPROCESSED_TUS
|
|
"Save preprocessed generated one-include CUDA TUs for compile-time benchmarks."
|
|
OFF
|
|
)
|
|
option(
|
|
CCCL_COMPILE_TIME_GENERATE_DEVICE_TIME_TRACES
|
|
"Emit NVCC device time traces for compile-time benchmarks."
|
|
OFF
|
|
)
|
|
mark_as_advanced(
|
|
CCCL_COMPILE_TIME_SAVE_PREPROCESSED_TUS
|
|
CCCL_COMPILE_TIME_GENERATE_DEVICE_TIME_TRACES
|
|
)
|
|
|
|
function(cccl_generate_header_tests target_name project_include_path)
|
|
set(options NO_METATARGETS)
|
|
set(oneValueArgs LANGUAGE HEADER_TEMPLATE)
|
|
set(multiValueArgs GLOBS EXCLUDES HEADERS PER_HEADER_DEFINES)
|
|
cmake_parse_arguments(
|
|
CGHT
|
|
"${options}"
|
|
"${oneValueArgs}"
|
|
"${multiValueArgs}"
|
|
${ARGN}
|
|
)
|
|
|
|
if (CGHT_UNPARSED_ARGUMENTS)
|
|
message(FATAL_ERROR "Unrecognized arguments: ${CGHT_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
# Setup defaults
|
|
if (NOT DEFINED CGHT_LANGUAGE)
|
|
set(CGHT_LANGUAGE CUDA)
|
|
endif()
|
|
|
|
if (NOT DEFINED CGHT_HEADER_TEMPLATE)
|
|
set(CGHT_HEADER_TEMPLATE "${CCCL_SOURCE_DIR}/cmake/header_test.cu.in")
|
|
endif()
|
|
|
|
# Derived vars:
|
|
if (${CGHT_LANGUAGE} STREQUAL "C")
|
|
set(extension "c")
|
|
elseif (${CGHT_LANGUAGE} STREQUAL "CXX")
|
|
set(extension "cpp")
|
|
elseif (${CGHT_LANGUAGE} STREQUAL "CUDA")
|
|
set(extension "cu")
|
|
else()
|
|
message(FATAL_ERROR "Unsupported language: ${CGHT_LANGUAGE}")
|
|
endif()
|
|
|
|
set(cccl_configure_target_options ${CGHT_UNPARSED_ARGUMENTS})
|
|
set(base_path "${CCCL_SOURCE_DIR}/${project_include_path}")
|
|
|
|
# Prepend the basepath to all globbing expressions:
|
|
if (DEFINED CGHT_GLOBS)
|
|
set(globs)
|
|
foreach (glob IN LISTS CGHT_GLOBS)
|
|
list(APPEND globs "${base_path}/${glob}")
|
|
endforeach()
|
|
set(CGHT_GLOBS ${globs})
|
|
endif()
|
|
if (DEFINED CGHT_EXCLUDES)
|
|
set(excludes)
|
|
foreach (exclude IN LISTS CGHT_EXCLUDES)
|
|
list(APPEND excludes "${base_path}/${exclude}")
|
|
endforeach()
|
|
set(CGHT_EXCLUDES ${excludes})
|
|
endif()
|
|
|
|
# Determine header list
|
|
set(headers)
|
|
|
|
# Add globs:
|
|
if (DEFINED CGHT_GLOBS)
|
|
file(
|
|
GLOB_RECURSE headers
|
|
RELATIVE "${base_path}"
|
|
CONFIGURE_DEPENDS
|
|
${CGHT_GLOBS}
|
|
)
|
|
endif()
|
|
|
|
# Remove excludes:
|
|
if (DEFINED CGHT_EXCLUDES)
|
|
file(
|
|
GLOB_RECURSE header_excludes
|
|
RELATIVE "${base_path}"
|
|
CONFIGURE_DEPENDS
|
|
${CGHT_EXCLUDES}
|
|
)
|
|
list(REMOVE_ITEM headers ${header_excludes})
|
|
endif()
|
|
|
|
# Add explicit headers:
|
|
if (DEFINED CGHT_HEADERS)
|
|
list(APPEND headers ${CGHT_HEADERS})
|
|
endif()
|
|
|
|
# Cleanup:
|
|
list(REMOVE_DUPLICATES headers)
|
|
|
|
# Helper function for applying per-header defines:
|
|
# header: The original header filepath
|
|
# src: The generated source file for the header test
|
|
function(cght_apply_per_header_defines header src)
|
|
if (NOT DEFINED CGHT_PER_HEADER_DEFINES)
|
|
return()
|
|
endif()
|
|
set(current_definition)
|
|
foreach (item IN LISTS CGHT_PER_HEADER_DEFINES)
|
|
if (item STREQUAL "DEFINE")
|
|
# New definition
|
|
set(current_definition)
|
|
elseif (NOT current_definition)
|
|
# First item after DEFINE is the definition
|
|
set(current_definition "${item}")
|
|
else()
|
|
# Subsequent items are regexes to match against the header
|
|
if (header MATCHES ${item})
|
|
set_property(
|
|
SOURCE "${src}"
|
|
APPEND
|
|
PROPERTY COMPILE_DEFINITIONS "${current_definition}"
|
|
)
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
endfunction()
|
|
|
|
# Configure header templates:
|
|
set(header_srcs)
|
|
foreach (header IN LISTS headers)
|
|
set(
|
|
header_src
|
|
"${CMAKE_CURRENT_BINARY_DIR}/headers/${target_name}/${header}.${extension}"
|
|
)
|
|
configure_file("${CGHT_HEADER_TEMPLATE}" "${header_src}" @ONLY)
|
|
cght_apply_per_header_defines("${header}" "${header_src}")
|
|
|
|
# Compile-time benchmark workflows can ask generated one-include CUDA TUs to
|
|
# preserve preprocessed artifacts and/or emit NVCC device time traces.
|
|
if (
|
|
(
|
|
CCCL_COMPILE_TIME_SAVE_PREPROCESSED_TUS
|
|
OR CCCL_COMPILE_TIME_GENERATE_DEVICE_TIME_TRACES
|
|
)
|
|
AND CGHT_LANGUAGE STREQUAL "CUDA"
|
|
)
|
|
get_filename_component(header_src_dir "${header_src}" DIRECTORY)
|
|
if ("${CMAKE_CUDA_COMPILER_ID}" STREQUAL "NVIDIA")
|
|
if (CCCL_COMPILE_TIME_SAVE_PREPROCESSED_TUS)
|
|
set_property(
|
|
SOURCE "${header_src}"
|
|
APPEND
|
|
PROPERTY COMPILE_OPTIONS "--keep" "--keep-dir=${header_src_dir}"
|
|
)
|
|
endif()
|
|
if (CCCL_COMPILE_TIME_GENERATE_DEVICE_TIME_TRACES)
|
|
set(trace_id "${header}")
|
|
string(REPLACE "/" "__" trace_id "${trace_id}")
|
|
string(REPLACE "." "_" trace_id "${trace_id}")
|
|
set(
|
|
trace_dir
|
|
"${CMAKE_BINARY_DIR}/compile_time/raw_traces/${target_name}"
|
|
)
|
|
file(MAKE_DIRECTORY "${trace_dir}")
|
|
set_property(
|
|
SOURCE "${header_src}"
|
|
APPEND
|
|
PROPERTY
|
|
COMPILE_OPTIONS "--fdevice-time-trace=${trace_dir}/${trace_id}"
|
|
)
|
|
endif()
|
|
elseif (
|
|
CCCL_COMPILE_TIME_SAVE_PREPROCESSED_TUS
|
|
AND "${CMAKE_CUDA_COMPILER_ID}" STREQUAL "Clang"
|
|
)
|
|
set_property(
|
|
SOURCE "${header_src}"
|
|
APPEND
|
|
PROPERTY COMPILE_OPTIONS "-save-temps=obj"
|
|
)
|
|
endif()
|
|
endif()
|
|
list(APPEND header_srcs "${header_src}")
|
|
endforeach()
|
|
|
|
# Object library that compiles each header:
|
|
add_library(${target_name} OBJECT ${header_srcs})
|
|
cccl_configure_target(${target_name} ${cccl_configure_target_options})
|
|
if (NOT CGHT_NO_METATARGETS)
|
|
cccl_ensure_metatargets(${target_name})
|
|
endif()
|
|
|
|
# Check that all functions in headers are either template functions or inline:
|
|
set(link_target ${target_name}.link_check)
|
|
cccl_add_executable(
|
|
${link_target}
|
|
SOURCES "${CCCL_SOURCE_DIR}/cmake/link_check_main.cpp"
|
|
NO_METATARGETS
|
|
)
|
|
# Linking both ${target_name} and $<TARGET_OBJECTS:${target_name}> forces CMake to
|
|
# link the same objects twice. The compiler will complain about duplicate symbols if
|
|
# any functions are missing inline markup.
|
|
target_link_libraries(
|
|
${link_target}
|
|
PRIVATE #
|
|
${target_name}
|
|
$<TARGET_OBJECTS:${target_name}>
|
|
)
|
|
endfunction()
|