Files
project_6/cccl_upstream/cmake/PrintCTestRunTimes.cmake
muh-bot dedf08166a [CCCL] Add missing CCCL components: c2h, nvbench_helper, cmake, cudax, AGENTS.md
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
2026-08-06 02:14:18 +00:00

136 lines
3.6 KiB
CMake

## This CMake script parses the output of ctest and prints a formatted list
## of individual test runtimes, sorted longest first.
##
## ctest > ctest_log
## cmake -DLOGFILE=ctest_log \
## -DMINSEC=10 \
## -P PrintCTestRunTimes.cmake
##
################################################################################
cmake_minimum_required(VERSION 3.15)
# Prepend the string with "0" until the string length equals the specified width
function(pad_string_with_zeros string_var width)
# gersemi: ignore
set(local_string "${${string_var}}")
string(LENGTH "${local_string}" size)
while(size LESS width)
string(PREPEND local_string "0")
string(LENGTH "${local_string}" size)
endwhile()
set(${string_var} "${local_string}" PARENT_SCOPE)
endfunction()
################################################################################
if (NOT LOGFILE)
message(FATAL_ERROR "Missing -DLOGFILE=<ctest output> argument.")
endif()
if (NOT DEFINED MINSEC)
set(MINSEC 10)
endif()
set(num_below_thresh 0)
# Check if logfile exists
if (NOT EXISTS "${LOGFILE}")
message(FATAL_ERROR "LOGFILE does not exist ('${LOGFILE}').")
endif()
# gersemi: off
string(JOIN "" regex
"[0-9]+/[0-9]+[ ]+Test[ ]+#"
"([0-9]+)" # Test ID
":[ ]+"
"([^ ]+)" # Test Name
"[ ]*\\.+[ ]*\\**[ ]*"
"([^ ]+)" # Result
"[ ]+"
"([0-9]+)" # Seconds
"\\.[0-9]+[ ]+sec"
)
# gersemi: on
message(DEBUG "LOGFILE: ${LOGFILE}")
message(DEBUG "MINSEC: ${MINSEC}")
message(DEBUG "regex: ${regex}")
# Read the logfile and generate a map / keylist
set(keys)
file(STRINGS "${LOGFILE}" lines)
foreach (line ${lines})
# Parse each build time
string(REGEX MATCH "${regex}" _DUMMY "${line}")
if (CMAKE_MATCH_COUNT EQUAL 4)
# gersemi: off
set(test_id "${CMAKE_MATCH_1}")
set(test_name "${CMAKE_MATCH_2}")
set(test_result "${CMAKE_MATCH_3}")
set(tmp "${CMAKE_MATCH_4}") # floor(runtime_seconds)
# gersemi: on
if (tmp LESS MINSEC)
math(EXPR num_below_thresh "${num_below_thresh} + 1")
continue()
endif()
# Compute human readable time
# gersemi: off
math(EXPR days "${tmp} / (60 * 60 * 24)")
math(EXPR tmp "${tmp} - (${days} * 60 * 60 * 24)")
math(EXPR hours "${tmp} / (60 * 60)")
math(EXPR tmp "${tmp} - (${hours} * 60 * 60)")
math(EXPR minutes "${tmp} / (60)")
math(EXPR tmp "${tmp} - (${minutes} * 60)")
math(EXPR seconds "${tmp}")
# gersemi: on
# Format time components
pad_string_with_zeros(days 3)
pad_string_with_zeros(hours 2)
pad_string_with_zeros(minutes 2)
pad_string_with_zeros(seconds 2)
# Construct table entry
# Later values in the file for the same command overwrite earlier entries
string(MAKE_C_IDENTIFIER "${test_id}" key)
string(
JOIN " | "
ENTRY_${key}
"${days}d ${hours}h ${minutes}m ${seconds}s"
"${test_result}"
"${test_id}: ${test_name}"
)
# Record the key:
list(APPEND keys "${key}")
endif()
endforeach()
list(REMOVE_DUPLICATES keys)
# Build the entry list:
set(entries)
foreach (key ${keys})
list(APPEND entries "${ENTRY_${key}}")
endforeach()
if (NOT entries)
message(STATUS "LOGFILE contained no test times ('${LOGFILE}').")
endif()
# Sort in descending order:
list(SORT entries ORDER DESCENDING)
# Dump table:
foreach (entry ${entries})
message(STATUS ${entry})
endforeach()
if (num_below_thresh GREATER 0)
message(STATUS "${num_below_thresh} additional tests took < ${MINSEC}s each.")
endif()