Files
project_6/cccl_upstream/c2h/include/c2h/catch2_test_macros.h
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

201 lines
12 KiB
C

// SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#pragma once
#include <cuda/std/detail/__config>
#include <nv/target>
#include <catch2/catch_message.hpp>
#include <catch2/catch_template_test_macros.hpp>
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers.hpp>
// This file implements Catch2's test macros that work both in host and device code. We globally define the
// CATCH_CONFIG_PREFIX_ALL macro to force Catch2 to prepend it's macros with CATCH_ prefix. That allows us to implement
// the non-prefixed versions ourselves.
//
// In host code, we just use the CATCH_-prefixed variant, in device code we implement the functionality, so it
// corresponds the desired functionality.
//
// Only a subset of the Catch2's macro are provided. If needed, feel free to extend the support. Host-only macros can
// be determined by missing NV_IF_ELSE_TARGET wrapper and immediate dispatch to CATCH_-prefixed variant.
// workaround for error #3185-D: no '#pragma diagnostic push' was found to match this 'diagnostic pop'
#if _CCCL_COMPILER(NVHPC)
# undef CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
# undef CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("diag push")
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("diag pop")
#endif
// The nv_diagnostic pragmas in Catch2 macros cause cicc to hang indefinitely in CTK 13.0.
// See NVBugs 5475335.
#if _CCCL_VERSION_COMPARE(_CCCL_CTK_, _CCCL_CTK, ==, 13, 0)
# undef CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
# undef CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#endif
// workaround for error
// * MSVC14.39: #3185-D: no '#pragma diagnostic push' was found to match this 'diagnostic pop'
// * MSVC14.29: internal error: assertion failed: alloc_copy_of_pending_pragma: copied pragma has source sequence entry
// (pragma.c, line 526 in alloc_copy_of_pending_pragma)
// see also upstream Catch2 issue: https://github.com/catchorg/Catch2/issues/2636
#if _CCCL_COMPILER(MSVC)
# undef CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
# undef CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
# undef CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS
#endif
// We must pass the COND as a cstring parameter, because it might contain the '%' character that would break the printf
// formatting.
#define C2H_INTERNAL_DEVICE_TEST_PRINT(KIND, COND) \
::printf( \
__FILE__ \
":" _CCCL_TO_STRING(__LINE__) ":\n " KIND "(%s) failed\n block [%u, %u, %u], thread [%u, %u, %u]\n\n", \
COND, \
blockIdx.x, \
blockIdx.y, \
blockIdx.z, \
threadIdx.x, \
threadIdx.y, \
threadIdx.z)
// <catch2/catch2_test_macros.hpp>
#define REQUIRE(...) \
NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_REQUIRE(__VA_ARGS__);), ({ \
if (!(__VA_ARGS__)) \
{ \
C2H_INTERNAL_DEVICE_TEST_PRINT("REQUIRE", #__VA_ARGS__); \
::__trap(); \
} \
}))
#define REQUIRE_FALSE(...) \
NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_REQUIRE_FALSE(__VA_ARGS__);), ({ \
if (__VA_ARGS__) \
{ \
C2H_INTERNAL_DEVICE_TEST_PRINT("REQUIRE_FALSE", #__VA_ARGS__); \
::__trap(); \
} \
}))
#define REQUIRE_THROWS(...) CATCH_REQUIRE_THROWS(__VA_ARGS__)
#define REQUIRE_THROWS_AS(...) CATCH_REQUIRE_THROWS_AS(__VA_ARGS__)
#define REQUIRE_NOTHROW(...) NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_REQUIRE_NOTHROW(__VA_ARGS__);), (__VA_ARGS__;))
#define CHECK(...) \
NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_CHECK(__VA_ARGS__);), ({ \
if (!(__VA_ARGS__)) \
{ \
C2H_INTERNAL_DEVICE_TEST_PRINT("CHECK", #__VA_ARGS__); \
::__trap(); \
} \
}))
#define CHECK_FALSE(...) \
NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_CHECK_FALSE(__VA_ARGS__);), ({ \
if (__VA_ARGS__) \
{ \
C2H_INTERNAL_DEVICE_TEST_PRINT("CHECK_FALSE", #__VA_ARGS__); \
::__trap(); \
} \
}))
#define CHECKED_IF(...) CATCH_CHECKED_IF(__VA_ARGS__)
#define CHECKED_ELSE(...) CATCH_CHECKED_ELSE(__VA_ARGS__)
#define CHECK_NOFAIL(...) CATCH_CHECK_NOFAIL(__VA_ARGS__)
#define CHECK_THROWS(...) CATCH_CHECK_THROWS(__VA_ARGS__)
#define CHECK_THROWS_AS(...) CATCH_CHECK_THROWS_AS(__VA_ARGS__)
#define CHECK_NOTHROW(...) NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_CHECK_NOTHROW(__VA_ARGS__);), (__VA_ARGS__;))
#define TEST_CASE(...) CATCH_TEST_CASE(__VA_ARGS__)
#define TEST_CASE_METHOD(...) CATCH_TEST_CASE_METHOD(__VA_ARGS__)
#define METHOD_AS_TEST_CASE(...) CATCH_METHOD_AS_TEST_CASE(__VA_ARGS__)
#define REGISTER_TEST_CASE(...) CATCH_REGISTER_TEST_CASE(__VA_ARGS__)
#define SECTION(...) CATCH_SECTION(__VA_ARGS__)
#define DYNAMIC_SECTION(...) CATCH_DYNAMIC_SECTION(__VA_ARGS__)
#define FAIL(...) \
NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_FAIL(__VA_ARGS__);), ({ \
C2H_INTERNAL_DEVICE_TEST_PRINT("FAIL", #__VA_ARGS__); \
::__trap(); \
}))
#define FAIL_CHECK(...) CATCH_FAIL_CHECK(__VA_ARGS__)
#define SUCCEED(...) CATCH_SUCCEED(__VA_ARGS__)
#define SKIP(...) CATCH_SKIP(__VA_ARGS__)
#define STATIC_REQUIRE(...) \
NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_STATIC_REQUIRE(__VA_ARGS__);), (static_assert(__VA_ARGS__, #__VA_ARGS__);))
#define STATIC_REQUIRE_FALSE(...) \
NV_IF_ELSE_TARGET( \
NV_IS_HOST, (CATCH_STATIC_REQUIRE_FALSE(__VA_ARGS__);), (static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")");))
#define STATIC_CHECK(...) \
NV_IF_ELSE_TARGET(NV_IS_HOST, (CATCH_STATIC_CHECK(__VA_ARGS__);), (static_assert(__VA_ARGS__, #__VA_ARGS__);))
#define STATIC_CHECK_FALSE(...) \
NV_IF_ELSE_TARGET( \
NV_IS_HOST, (CATCH_STATIC_CHECK_FALSE(__VA_ARGS__);), (static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")");))
#define SCENARIO(...) CATCH_SCENARIO(__VA_ARGS__)
#define SCENARIO_METHOD(...) CATCH_SCENARIO_METHOD(__VA_ARGS__)
#define GIVEN(...) CATCH_GIVEN(__VA_ARGS__)
#define AND_GIVEN(...) CATCH_AND_GIVEN(__VA_ARGS__)
#define WHEN(...) CATCH_WHEN(__VA_ARGS__)
#define AND_WHEN(...) CATCH_AND_WHEN(__VA_ARGS__)
#define THEN(...) CATCH_THEN(__VA_ARGS__)
#define AND_THEN(...) CATCH_AND_THEN(__VA_ARGS__)
// <catch2/catch_message.hpp>
#define INFO(...) CATCH_INFO(__VA_ARGS__)
#define UNSCOPED_INFO(...) CATCH_UNSCOPED_INFO(__VA_ARGS__)
#define WARN(...) CATCH_WARN(__VA_ARGS__)
#define CAPTURE(...) CATCH_CAPTURE(__VA_ARGS__)
// <catch2/catch_template_test_macros.hpp>
#define TEMPLATE_TEST_CASE(...) CATCH_TEMPLATE_TEST_CASE(__VA_ARGS__)
#define TEMPLATE_TEST_CASE_SIG(...) CATCH_TEMPLATE_TEST_CASE_SIG(__VA_ARGS__)
#define TEMPLATE_TEST_CASE_METHOD(...) CATCH_TEMPLATE_TEST_CASE_METHOD(__VA_ARGS__)
#define TEMPLATE_TEST_CASE_METHOD_SIG(...) CATCH_TEMPLATE_TEST_CASE_METHOD_SIG(__VA_ARGS__)
#define TEMPLATE_PRODUCT_TEST_CASE(...) CATCH_TEMPLATE_PRODUCT_TEST_CASE(__VA_ARGS__)
#define TEMPLATE_PRODUCT_TEST_CASE_SIG(...) CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(__VA_ARGS__)
#define TEMPLATE_PRODUCT_TEST_CASE_METHOD(...) CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD(__VA_ARGS__)
#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(...) CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG(__VA_ARGS__)
#define TEMPLATE_LIST_TEST_CASE(...) CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
#define TEMPLATE_LIST_TEST_CASE_METHOD(...) CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(__VA_ARGS__)
// <catch2/matchers/catch_matchers.hpp>
#define REQUIRE_THROWS_WITH(...) CATCH_REQUIRE_THROWS_WITH(__VA_ARGS__)
#define REQUIRE_THROWS_MATCHES(...) CATCH_REQUIRE_THROWS_MATCHES(__VA_ARGS__)
#define CHECK_THROWS_WITH(...) CATCH_CHECK_THROWS_WITH(__VA_ARGS__)
#define CHECK_THROWS_MATCHES(...) CATCH_CHECK_THROWS_MATCHES(__VA_ARGS__)
#define CHECK_THAT(...) CATCH_CHECK_THAT(__VA_ARGS__)
#define REQUIRE_THAT(...) CATCH_REQUIRE_THAT(__VA_ARGS__)
// extensions
// Sometimes clang-cuda has problems with REQUIRE(...) when used in __device__ function - it tries to instantiate the
// host path. This is related to clang-cuda's compilation trajectory. For these cases, we provide REQUIRE_DEVICE(...) as
// a fallback.
#define REQUIRE_DEVICE(...) \
do \
{ \
if (!(__VA_ARGS__)) \
{ \
C2H_INTERNAL_DEVICE_TEST_PRINT("REQUIRE", #__VA_ARGS__); \
::__trap(); \
} \
} while (false)
// Macros to require/check success of a CUDA Driver call.
#define REQUIRE_CUDA(...) REQUIRE((__VA_ARGS__) == CUDA_SUCCESS)
#define CHECK_CUDA(...) CHECK((__VA_ARGS__) == CUDA_SUCCESS)
// Macros to require/check success of a CUDA Runtime call.
#define REQUIRE_CUDART(...) REQUIRE((__VA_ARGS__) == cudaSuccess)
#define CHECK_CUDART(...) CHECK((__VA_ARGS__) == cudaSuccess)