Files
project_6/cccl_upstream/c2h/include/c2h/check_results.cuh
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

155 lines
5.3 KiB
Plaintext

// SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include <cub/detail/type_traits.cuh>
#include <cub/util_device.cuh>
#include <cuda/std/complex>
#include <cuda/std/type_traits>
#include <test_util.h>
#include <catch2/matchers/catch_matchers_floating_point.hpp>
template <typename T>
void verify_results(const c2h::host_vector<T>& expected_data, const c2h::host_vector<T>& test_results)
{
using namespace cub::detail;
int device_id = 0;
CubDebugExit(cudaGetDevice(&device_id));
int ptx_version = 0;
CubDebugExit(CUB_NS_QUALIFIER::PtxVersion(ptx_version, device_id));
if (ptx_version < 80 && is_any_bfloat16_v<T>)
{
return;
}
if (ptx_version < 53 && is_any_half_v<T>)
{
return;
}
if constexpr (cuda::std::is_floating_point_v<T>)
{
REQUIRE_APPROX_EQ(expected_data, test_results);
}
else if constexpr (cuda::std::is_same_v<T, __nv_bfloat16> || cuda::std::is_same_v<T, __half>)
{
constexpr auto rel_err = cuda::std::is_same_v<T, __half> ? 0.08f : 0.2f;
REQUIRE_APPROX_EQ_EPSILON(expected_data, test_results, rel_err);
}
else if constexpr (cuda::std::is_same_v<T, float2>)
{
for (size_t i = 0; i < test_results.size(); ++i)
{
REQUIRE_THAT(expected_data[i].x, Catch::Matchers::WithinRel(test_results[i].x, 0.01f));
REQUIRE_THAT(expected_data[i].y, Catch::Matchers::WithinRel(test_results[i].y, 0.01f));
}
}
else if constexpr (cuda::std::is_same_v<T, __nv_bfloat162> || cuda::std::is_same_v<T, __half2>)
{
constexpr auto rel_err = cuda::std::is_same_v<T, __half2> ? 0.08f : 0.2f;
for (size_t i = 0; i < test_results.size(); ++i)
{
REQUIRE_THAT(expected_data[i].x, Catch::Matchers::WithinRel(test_results[i].x, rel_err));
REQUIRE_THAT(expected_data[i].y, Catch::Matchers::WithinRel(test_results[i].y, rel_err));
}
}
else if constexpr (cuda::std::is_same_v<T, cuda::std::complex<__nv_bfloat16>>
|| cuda::std::is_same_v<T, cuda::std::complex<__half>>)
{
constexpr auto rel_err = cuda::std::is_same_v<T, cuda::std::complex<__half>> ? 0.08f : 0.2f;
for (size_t i = 0; i < test_results.size(); ++i)
{
auto expected_real = static_cast<float>(expected_data[i].real());
auto test_real = test_results[i].real();
auto expected_imag = static_cast<float>(expected_data[i].imag());
auto test_imag = test_results[i].imag();
REQUIRE_THAT(expected_real, Catch::Matchers::WithinRel(test_real, rel_err));
REQUIRE_THAT(expected_imag, Catch::Matchers::WithinRel(test_imag, rel_err));
}
}
else if constexpr (cuda::std::__is_cuda_std_complex_v<T>)
{
for (size_t i = 0; i < test_results.size(); ++i)
{
auto expected_real = expected_data[i].real();
auto test_real = test_results[i].real();
auto expected_imag = expected_data[i].imag();
auto test_imag = test_results[i].imag();
REQUIRE_THAT(expected_real, Catch::Matchers::WithinRel(test_real));
REQUIRE_THAT(expected_imag, Catch::Matchers::WithinRel(test_imag));
}
}
else
{
REQUIRE(expected_data == test_results);
}
}
template <typename T>
void verify_results(const c2h::host_vector<T>& expected_data, const c2h::device_vector<T>& test_results)
{
c2h::host_vector<T> test_results_host = test_results;
verify_results(expected_data, test_results_host);
}
//----------------------------------------------------------------------------------------------------------------------
// Min/Max comparison requires bitwise identical results (excluding NaN). Vector Types require only the first element to
// match due to how it defined the operator<
template <typename T>
void verify_results_exact(const c2h::host_vector<T>& expected_data, const c2h::host_vector<T>& test_results)
{
using namespace cub::detail;
int device_id = 0;
int compute_capability_major = 0;
int compute_capability_minor = 0;
CubDebugExit(cudaGetDevice(&device_id));
CubDebugExit(cudaDeviceGetAttribute(&compute_capability_major, cudaDevAttrComputeCapabilityMajor, device_id));
CubDebugExit(cudaDeviceGetAttribute(&compute_capability_minor, cudaDevAttrComputeCapabilityMinor, device_id));
int compute_capability = 10 * compute_capability_major + compute_capability_minor;
if (compute_capability < 80 && is_any_bfloat16_v<T>)
{
return;
}
if (compute_capability < 53 && is_any_half_v<T>)
{
return;
}
if constexpr (is_vector2_fp_type_v<T>)
{
for (size_t i = 0; i < test_results.size(); ++i)
{
auto expected = static_cast<float>(expected_data[i].x);
auto test_result = static_cast<float>(test_results[i].x);
REQUIRE(expected == test_result);
}
}
if constexpr (is_vector2_type_v<T>)
{
for (size_t i = 0; i < test_results.size(); ++i)
{
REQUIRE(expected_data[i].x == test_results[i].x);
}
}
else
{
REQUIRE_BITWISE_EQ(expected_data, test_results);
}
}
template <typename T>
void verify_results_exact(const c2h::host_vector<T>& expected_data, const c2h::device_vector<T>& test_results)
{
c2h::host_vector<T> test_results_host = test_results;
if constexpr (is_vector2_type_v<T> || cuda::is_floating_point_v<T>)
{
verify_results_exact(expected_data, test_results_host);
}
else
{
verify_results(expected_data, test_results_host);
}
}