[INFRA] Import NVIDIA/CCCL upstream as optimization reference library

CCCL (CUDA C++ Core Libraries) provides:
- CUB: device/block/warp-level GPU primitives (reduce, scan, sort, topk)
- Thrust: high-level parallel algorithms (transform_reduce, sort, scan)
- libcudacxx: CUDA C++ standard library (atomics, barriers, memory)
- cudax: experimental features (memory resources, allocators)
- Tuning policies: per-SM hardware-specific algorithm parameters

Competition optimization vectors mapped to CCCL:
- Output TPS (83% weight): warp_reduce, block_reduce, device_topk
- Input TPS (14% weight): device_scan, block_load, prefetch
- Cache TPS (3% weight): prefix caching strategy patterns
- Memory (0.9 util): pooled/cached/buddy allocators

Source: https://github.com/NVIDIA/cccl (shallow clone, HEAD only)
License: Apache-2.0
This commit is contained in:
EngineX CI
2026-07-30 09:35:51 +00:00
parent b4d01f481e
commit 56fd68e7dd
8871 changed files with 1454674 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
cccl_get_c2h()
# v2 reuses the same test sources as v1 from c/parallel/test/, compiled with
# CCCL_C_PARALLEL_V2 defined. The shared source files contain a small number
# of #ifdef CCCL_C_PARALLEL_V2 branches that select v2's backend (hostjit
# bitcode vs nvrtc LTO-IR) and skip v1-only test variants.
set(v1_test_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../parallel/test")
function(cccl_c_parallel_v2_add_test target_name_var source)
get_filename_component(target_name "${source}" NAME_WE)
string(
REGEX REPLACE
"test_([^.]*)"
"cccl.c.parallel.v2.test.\\1"
target_name
"${target_name}"
)
set(${target_name_var} ${target_name} PARENT_SCOPE)
add_executable(${target_name} "${source}")
cccl_configure_target(${target_name} DIALECT 20)
set_target_properties(${target_name} PROPERTIES CUDA_RUNTIME_LIBRARY STATIC)
target_link_libraries(
${target_name}
PRIVATE
cccl.compiler_interface
cccl.c.parallel.v2
cccl.c.parallel.v2.hostjit_lib
CUDA::cudart_static
CUDA::nvrtc
cccl.c2h.main
)
target_include_directories(
${target_name}
PRIVATE
"${v1_test_dir}"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/hostjit/include"
)
list(GET CUDAToolkit_INCLUDE_DIRS 0 CUDA_FIRST_INCLUDE_DIR)
target_compile_definitions(
${target_name}
PRIVATE
CCCL_C_PARALLEL_V2=1
TEST_CUB_PATH="-I${CCCL_SOURCE_DIR}/cub"
TEST_THRUST_PATH="-I${CCCL_SOURCE_DIR}/thrust"
TEST_LIBCUDACXX_PATH="-I${CCCL_SOURCE_DIR}/libcudacxx/include"
TEST_CTK_PATH="-I${CUDA_FIRST_INCLUDE_DIR}"
TEST_INCLUDE_PATH="${v1_test_dir}"
)
add_test(NAME ${target_name} COMMAND ${target_name})
endfunction()
file(
GLOB test_srcs
RELATIVE "${v1_test_dir}"
CONFIGURE_DEPENDS
"${v1_test_dir}/*.cu"
"${v1_test_dir}/*.cpp"
)
foreach (test_src IN LISTS test_srcs)
cccl_c_parallel_v2_add_test(test_target "${v1_test_dir}/${test_src}")
endforeach()
add_subdirectory(freestanding)

View File

@@ -0,0 +1,36 @@
cccl_get_c2h()
function(cccl_c_parallel_v2_add_freestanding_test target_name_var source)
get_filename_component(target_name "${source}" NAME_WE)
string(
REGEX REPLACE
"test_([^.]*)"
"cccl.c.parallel.v2.test.freestanding.\\1"
target_name
"${target_name}"
)
set(target_name_var ${target_name} PARENT_SCOPE)
cccl_add_executable(
${target_name}
ADD_CTEST
NO_METATARGETS
DIALECT 20
SOURCES "${source}"
)
target_link_libraries(
${target_name}
PRIVATE cccl.c.parallel.v2.hostjit_lib CUDA::cudart
)
endfunction()
file(
GLOB freestanding_srcs
RELATIVE "${CMAKE_CURRENT_LIST_DIR}"
CONFIGURE_DEPENDS
*.cpp
)
foreach (freestanding_src IN LISTS freestanding_srcs)
cccl_c_parallel_v2_add_freestanding_test(test_target "${freestanding_src}")
endforeach()

View File

@@ -0,0 +1,69 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#include <cassert>
#include <cstdio>
#include <cuda_runtime.h>
#include <hostjit/config.hpp>
#include <hostjit/jit_compiler.hpp>
static const char* k_source = R"(
#include <cuda/std/initializer_list>
#include <cuda_runtime.h>
__global__ void device_kernel(int* ptr)
{
::cuda::std::initializer_list<::std::size_t> meow {42ull, 1337ull};
*ptr = static_cast<int>(::std::move(*meow.begin()));
}
extern "C" _CCCL_VISIBILITY_EXPORT void host_entry(int* ptr)
{
device_kernel<<<1, 1>>>(ptr);
}
)";
int main()
{
// Detect Clang/CUDA configuration from the build environment
auto config = hostjit::detectDefaultConfig();
hostjit::JITCompiler compiler(config);
if (!compiler.compile(k_source))
{
std::fprintf(stderr, "HostJIT compilation failed:\n%s\n", compiler.getLastError().c_str());
return 1;
}
auto host_fn = compiler.getFunction<void (*)(int*)>("host_entry");
if (!host_fn)
{
std::fprintf(stderr, "Symbol 'host_entry' not found\n");
return 1;
}
int* d_ptr = nullptr;
cudaMalloc(&d_ptr, sizeof(int));
host_fn(d_ptr);
cudaDeviceSynchronize();
int result = 0;
cudaMemcpy(&result, d_ptr, sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(d_ptr);
assert(result == 42 && "device kernel did not write expected value");
std::printf("freestanding compiler test passed (result=%d)\n", result);
return 0;
}

View File

@@ -0,0 +1,66 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#include <cassert>
#include <cstdio>
#include <cuda_runtime.h>
#include <hostjit/config.hpp>
#include <hostjit/jit_compiler.hpp>
static const char* k_source = R"(
#include <cuda_runtime.h>
#include <cuda/std/version>
__global__ void device_kernel(int* ptr)
{
*ptr = 42;
}
extern "C" _CCCL_VISIBILITY_EXPORT void host_entry(int* ptr)
{
device_kernel<<<1, 1>>>(ptr);
}
)";
int main()
{
// Detect Clang/CUDA configuration from the build environment
auto config = hostjit::detectDefaultConfig();
hostjit::JITCompiler compiler(config);
if (!compiler.compile(k_source))
{
std::fprintf(stderr, "HostJIT compilation failed:\n%s\n", compiler.getLastError().c_str());
return 1;
}
auto host_fn = compiler.getFunction<void (*)(int*)>("host_entry");
if (!host_fn)
{
std::fprintf(stderr, "Symbol 'host_entry' not found\n");
return 1;
}
int* d_ptr = nullptr;
cudaMalloc(&d_ptr, sizeof(int));
host_fn(d_ptr);
cudaDeviceSynchronize();
int result = 0;
cudaMemcpy(&result, d_ptr, sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(d_ptr);
assert(result == 42 && "device kernel did not write expected value");
std::printf("freestanding compiler test passed (result=%d)\n", result);
return 0;
}

View File

@@ -0,0 +1,131 @@
#include <iostream>
#include <numeric>
#include <cuda_runtime.h>
#include "test_util.h"
#include <hostjit/config.hpp>
#include <hostjit/jit_compiler.hpp>
static const char* cuda_source = R"(
#include <cuda_runtime.h>
#include <cub/device/device_adjacent_difference.cuh>
#include <cuda/std/functional>
extern "C" _CCCL_VISIBILITY_EXPORT int adjacentDifference(
const int* d_input, int* d_output, int num_items) {
void* d_temp_storage = nullptr;
size_t temp_storage_bytes = 0;
// Query temp storage
cudaError_t err = cub::DeviceAdjacentDifference::SubtractLeftCopy(
d_temp_storage, temp_storage_bytes, d_input, d_output, num_items,
cuda::std::minus<int>{});
if (err != cudaSuccess) return -1;
// Allocate temp storage
err = cudaMalloc(&d_temp_storage, temp_storage_bytes);
if (err != cudaSuccess) return -2;
// Run adjacent difference
err = cub::DeviceAdjacentDifference::SubtractLeftCopy(
d_temp_storage, temp_storage_bytes, d_input, d_output, num_items,
cuda::std::minus<int>{});
if (err != cudaSuccess) {
cudaFree(d_temp_storage);
return -3;
}
err = cudaDeviceSynchronize();
cudaFree(d_temp_storage);
return (err == cudaSuccess) ? 0 : -4;
}
)";
int main()
{
// Detect Clang/CUDA configuration from the build environment
auto config = hostjit::detectDefaultConfig();
hostjit::JITCompiler compiler(config);
if (!compiler.compile(cuda_source))
{
std::fprintf(stderr, "HostJIT compilation failed:\n%s\n", compiler.getLastError().c_str());
return 1;
}
auto adjacentDiff = compiler.getFunction<int (*)(const int*, int*, int)>("adjacentDifference");
if (!adjacentDiff)
{
std::cerr << "Failed to get function: " << compiler.getLastError() << "\n";
return 1;
}
// Prepare test data: [1, 2, 3, 4, 5, ...]
const int N = 8;
std::vector<int> h_input(N);
std::iota(h_input.begin(), h_input.end(), 1);
// Expected: SubtractLeft produces [d[0], d[1]-d[0], d[2]-d[1], ...]
// For input [1,2,3,4,5,6,7,8]: output [1,1,1,1,1,1,1,1]
std::vector<int> expected(N);
expected[0] = h_input[0];
for (int i = 1; i < N; i++)
{
expected[i] = h_input[i] - h_input[i - 1];
}
int *d_input, *d_output;
CUDA_CHECK(cudaMalloc(&d_input, N * sizeof(int)));
CUDA_CHECK(cudaMalloc(&d_output, N * sizeof(int)));
CUDA_CHECK(cudaMemcpy(d_input, h_input.data(), N * sizeof(int), cudaMemcpyHostToDevice));
std::cout << "Computing adjacent differences of " << N << " integers...\n";
int status = adjacentDiff(d_input, d_output, N);
if (status != 0)
{
std::cerr << "adjacentDifference failed with status: " << status << "\n";
CUDA_CHECK(cudaFree(d_input));
CUDA_CHECK(cudaFree(d_output));
return 1;
}
std::vector<int> h_output(N);
CUDA_CHECK(cudaMemcpy(h_output.data(), d_output, N * sizeof(int), cudaMemcpyDeviceToHost));
std::cout << "Input: [";
for (int i = 0; i < N; i++)
{
std::cout << (i ? ", " : "") << h_input[i];
}
std::cout << "]\n";
std::cout << "Output: [";
for (int i = 0; i < N; i++)
{
std::cout << (i ? ", " : "") << h_output[i];
}
std::cout << "]\n";
std::cout << "Expected: [";
for (int i = 0; i < N; i++)
{
std::cout << (i ? ", " : "") << expected[i];
}
std::cout << "]\n";
bool success = (h_output == expected);
if (success)
{
std::cout << "Results verified successfully!\n";
}
else
{
std::cerr << "Mismatch!\n";
}
CUDA_CHECK(cudaFree(d_input));
CUDA_CHECK(cudaFree(d_output));
return success ? 0 : 1;
}

View File

@@ -0,0 +1,169 @@
#include <filesystem>
#include <fstream>
#include <iostream>
#include <numeric>
#include <cuda_runtime.h>
#include "test_util.h"
#include <hostjit/config.hpp>
#include <hostjit/jit_compiler.hpp>
// LLVM IR for an add operator with alwaysinline attribute
// This IR defines a function: float user_op(float a, float b) { return a + b; }
const char* user_op_llvm_ir = R"(
target datalayout = "e-p6:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64"
target triple = "nvptx64-nvidia-cuda"
define float @user_op(float %a, float %b) alwaysinline {
entry:
%result = fadd float %a, %b
ret float %result
}
)";
// Write LLVM IR text to a file (parseIRFile in the compiler handles both .ll and .bc)
bool writeIRFile(const std::string& llvm_ir, const std::string& output_path)
{
std::ofstream ir_file(output_path);
if (!ir_file)
{
std::cerr << "Failed to write LLVM IR file\n";
return false;
}
ir_file << llvm_ir;
ir_file.close();
std::cout << "Generated IR file: " << output_path << "\n";
return true;
}
static const char* cuda_source = R"(
#include <cuda_runtime.h>
#include <cub/device/device_reduce.cuh>
// External declaration - resolved from linked bitcode
extern "C" __device__ float user_op(float a, float b);
// Functor wrapping the external function
struct UserOp {
__device__ __forceinline__
float operator()(float a, float b) const {
return user_op(a, b);
}
};
extern "C" _CCCL_VISIBILITY_EXPORT int computeReduce(float* d_input, int num_items, float* result) {
float* d_output = nullptr;
void* d_temp_storage = nullptr;
size_t temp_storage_bytes = 0;
float init = HOSTJIT_REDUCE_INIT;
UserOp op;
cudaError_t err = cudaMalloc(&d_output, sizeof(float));
if (err != cudaSuccess) return -1;
err = cub::DeviceReduce::Reduce(d_temp_storage, temp_storage_bytes,
d_input, d_output, num_items, op, init);
if (err != cudaSuccess) {
cudaFree(d_output);
return -2;
}
err = cudaMalloc(&d_temp_storage, temp_storage_bytes);
if (err != cudaSuccess) {
cudaFree(d_output);
return -3;
}
err = cub::DeviceReduce::Reduce(d_temp_storage, temp_storage_bytes,
d_input, d_output, num_items, op, init);
if (err != cudaSuccess) {
cudaFree(d_temp_storage);
cudaFree(d_output);
return -4;
}
err = cudaDeviceSynchronize();
if (err != cudaSuccess) {
cudaFree(d_temp_storage);
cudaFree(d_output);
return -5;
}
err = cudaMemcpy(result, d_output, sizeof(float), cudaMemcpyDeviceToHost);
cudaFree(d_temp_storage);
cudaFree(d_output);
return (err == cudaSuccess) ? 0 : -6;
}
)";
int main()
{
// Step 1: Write LLVM IR file with the custom operator
std::string ir_path = (std::filesystem::temp_directory_path() / "user_op.ll").string();
if (!writeIRFile(user_op_llvm_ir, ir_path))
{
std::cerr << "Failed to write IR file\n";
return 1;
}
auto config = hostjit::detectDefaultConfig();
config.device_bitcode_files.push_back(ir_path);
config.macro_definitions["HOSTJIT_REDUCE_INIT"] = "0.0f";
hostjit::JITCompiler compiler(config);
if (!compiler.compile(cuda_source))
{
std::cerr << "Failed to get function: " << compiler.getLastError() << "\n";
return 1;
}
auto computeReduce = compiler.getFunction<int (*)(float*, int, float*)>("computeReduce");
if (!computeReduce)
{
std::cerr << "Failed to get function: " << compiler.getLastError() << "\n";
return 1;
}
// Prepare test data
const int N = 1024;
std::vector<float> h_input(N);
// Initialize with values 1.0 to N
std::iota(h_input.begin(), h_input.end(), 1.0f);
const float expected = static_cast<float>(N) * (N + 1) / 2.0f; // Sum of 1..N
// Allocate device memory
float* d_input;
CUDA_CHECK(cudaMalloc(&d_input, N * sizeof(float)));
// Copy data to device
CUDA_CHECK(cudaMemcpy(d_input, h_input.data(), N * sizeof(float), cudaMemcpyHostToDevice));
float result = -1.0f;
int status = computeReduce(d_input, N, &result);
if (status != 0)
{
std::cerr << "computeReduce failed with status: " << status << "\n";
CUDA_CHECK(cudaFree(d_input));
return 1;
}
// Verify result
std::cout << "\nResult: " << result << " (expected: " << expected << ")\n";
bool success = std::abs(result - expected) < 0.01f;
if (success)
{
std::cout << "\n*** SUCCESS: Custom operator was inlined and executed correctly! ***\n";
}
else
{
std::cerr << "\nMismatch! Got " << result << " but expected " << expected << "\n";
}
// Cleanup
CUDA_CHECK(cudaFree(d_input));
return success ? 0 : 1;
}

View File

@@ -0,0 +1,131 @@
#include <iostream>
#include <numeric>
#include <cuda_runtime.h>
#include "test_util.h"
#include <hostjit/config.hpp>
#include <hostjit/jit_compiler.hpp>
static const char* cuda_source = R"(
#include <cuda_runtime.h>
#include <cub/device/device_reduce.cuh>
// External declaration - resolved from linked bitcode
extern "C" __device__ float user_op(float a, float b);
// Functor wrapping the external function
struct UserOp {
__device__ __forceinline__
float operator()(float a, float b) const {
return ::cuda::std::min(a, b);
}
};
extern "C" _CCCL_VISIBILITY_EXPORT int computeReduce(float* d_input, int num_items, float* result) {
float* d_output = nullptr;
void* d_temp_storage = nullptr;
size_t temp_storage_bytes = 0;
float init = 1e38f;
UserOp op;
cudaError_t err = cudaMalloc(&d_output, sizeof(float));
if (err != cudaSuccess) return -1;
err = cub::DeviceReduce::Reduce(d_temp_storage, temp_storage_bytes,
d_input, d_output, num_items, op, init);
if (err != cudaSuccess) {
cudaFree(d_output);
return -2;
}
err = cudaMalloc(&d_temp_storage, temp_storage_bytes);
if (err != cudaSuccess) {
cudaFree(d_output);
return -3;
}
err = cub::DeviceReduce::Reduce(d_temp_storage, temp_storage_bytes,
d_input, d_output, num_items, op, init);
if (err != cudaSuccess) {
cudaFree(d_temp_storage);
cudaFree(d_output);
return -4;
}
err = cudaDeviceSynchronize();
if (err != cudaSuccess) {
cudaFree(d_temp_storage);
cudaFree(d_output);
return -5;
}
err = cudaMemcpy(result, d_output, sizeof(float), cudaMemcpyDeviceToHost);
cudaFree(d_temp_storage);
cudaFree(d_output);
return (err == cudaSuccess) ? 0 : -6;
}
)";
int main()
{
// Detect Clang/CUDA configuration from the build environment
auto config = hostjit::detectDefaultConfig();
hostjit::JITCompiler compiler(config);
if (!compiler.compile(cuda_source))
{
std::cerr << "Failed to get function: " << compiler.getLastError() << "\n";
return 1;
}
auto computeReduce = compiler.getFunction<int (*)(float*, int, float*)>("computeReduce");
if (!computeReduce)
{
std::cerr << "Failed to get function: " << compiler.getLastError() << "\n";
return 1;
}
// Prepare test data
const int N = 1024;
std::vector<float> h_input(N);
// Initialize with values 1.0 to N
std::iota(h_input.begin(), h_input.end(), 1.0f);
const float expected = 1.0f; // Minimum value in the array
// Allocate device memory
float* d_input;
CUDA_CHECK(cudaMalloc(&d_input, N * sizeof(float)));
// Copy data to device
CUDA_CHECK(cudaMemcpy(d_input, h_input.data(), N * sizeof(float), cudaMemcpyHostToDevice));
float result = -1.0f;
int status = computeReduce(d_input, N, &result);
if (status != 0)
{
std::cerr << "computeReduce failed with status: " << status << "\n";
CUDA_CHECK(cudaFree(d_input));
return 1;
}
// Verify result
std::cout << "\nResult: " << result << " (expected: " << expected << ")\n";
bool success = std::abs(result - expected) < 0.01f;
if (success)
{
std::cout << "\n*** SUCCESS: Custom operator was inlined and executed correctly! ***\n";
}
else
{
std::cerr << "\nMismatch! Got " << result << " but expected " << expected << "\n";
}
// Cleanup
CUDA_CHECK(cudaFree(d_input));
return success ? 0 : 1;
}

View File

@@ -0,0 +1,145 @@
#include <iostream>
#include <numeric>
#include <cuda_runtime.h>
#include "test_util.h"
#include <hostjit/config.hpp>
#include <hostjit/jit_compiler.hpp>
static const char* cuda_source = R"(
#include <cuda_runtime.h>
#include <cub/device/device_reduce.cuh>
#include <cuda/std/functional>
#include <cuda/__execution/determinism.h>
#include <cuda/__execution/require.h>
extern "C" _CCCL_VISIBILITY_EXPORT int computeSumDeterministic(float* d_input, int num_items, float* result) {
float* d_output = nullptr;
// Allocate output
cudaError_t err = cudaMalloc(&d_output, sizeof(float));
if (err != cudaSuccess) return -1;
// Run deterministic sum reduction with gpu_to_gpu determinism
auto env = cuda::execution::require(cuda::execution::determinism::gpu_to_gpu);
err = cub::DeviceReduce::Sum(d_input, d_output, num_items, env);
if (err != cudaSuccess) {
cudaFree(d_output);
return -2;
}
// Synchronize
err = cudaDeviceSynchronize();
if (err != cudaSuccess) {
cudaFree(d_output);
return -3;
}
// Copy result back
err = cudaMemcpy(result, d_output, sizeof(float), cudaMemcpyDeviceToHost);
if (err != cudaSuccess) {
cudaFree(d_output);
return -4;
}
// Cleanup
cudaFree(d_output);
return 0;
}
)";
int main()
{
// Detect Clang/CUDA configuration from the build environment
auto config = hostjit::detectDefaultConfig();
hostjit::JITCompiler compiler(config);
if (!compiler.compile(cuda_source))
{
std::fprintf(stderr, "HostJIT compilation failed:\n%s\n", compiler.getLastError().c_str());
return 1;
}
auto computeSumDeterministic = compiler.getFunction<int (*)(float*, int, float*)>("computeSumDeterministic");
if (!computeSumDeterministic)
{
std::cerr << "Failed to get function: " << compiler.getLastError() << "\n";
return 1;
}
// Prepare test data
const int N = 1024;
std::vector<float> h_input(N);
// Initialize with values 1.0 to N
std::iota(h_input.begin(), h_input.end(), 1.0f);
// Expected sum: N*(N+1)/2
float expected_sum = static_cast<float>(N) * (N + 1) / 2;
// Allocate device memory
float* d_input;
CUDA_CHECK(cudaMalloc(&d_input, N * sizeof(float)));
// Copy data to device
CUDA_CHECK(cudaMemcpy(d_input, h_input.data(), N * sizeof(float), cudaMemcpyHostToDevice));
// Call the JIT-compiled function
std::cout << "Computing deterministic sum of " << N << " floats using CUB...\n";
float result = 0;
int status = computeSumDeterministic(d_input, N, &result);
if (status != 0)
{
std::cerr << "computeSumDeterministic failed with status: " << status << "\n";
CUDA_CHECK(cudaFree(d_input));
return 1;
}
// Verify result
std::cout << "Result: " << result << " (expected: " << expected_sum << ")\n";
// Verify determinism: run multiple times and check results are identical
const int num_runs = 10;
bool deterministic = true;
for (int i = 0; i < num_runs; ++i)
{
float run_result = 0;
status = computeSumDeterministic(d_input, N, &run_result);
if (status != 0)
{
std::cerr << "Run " << i << " failed with status: " << status << "\n";
CUDA_CHECK(cudaFree(d_input));
return 1;
}
if (run_result != result)
{
std::cerr << "Run " << i << " produced different result: " << run_result << " vs " << result << "\n";
deterministic = false;
}
}
bool success = (result == expected_sum) && deterministic;
if (success)
{
std::cout << "Results verified successfully! (" << num_runs << " runs produced identical results)\n";
}
else
{
if (result != expected_sum)
{
std::cerr << "Mismatch! Got " << result << " but expected " << expected_sum << "\n";
}
if (!deterministic)
{
std::cerr << "Non-deterministic results detected!\n";
}
}
// Cleanup
CUDA_CHECK(cudaFree(d_input));
return success ? 0 : 1;
}

View File

@@ -0,0 +1,108 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION.
//
//===----------------------------------------------------------------------===//
// Repro harness: feeds a CUDA source string to v1's hostjit and reports
// whether compilation succeeds. If a path is passed via argv[1] or
// $REPRO_SOURCE_FILE, that file's contents are compiled instead of the
// built-in minimal source. Used to test whether v2's actual CubCall-generated
// host_input.cu compiles under v1's hostjit infrastructure.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <cuda_runtime.h>
#include <hostjit/config.hpp>
#include <hostjit/jit_compiler.hpp>
static const char* default_source = R"(
#include <cuda_runtime.h>
#include <cub/device/device_reduce.cuh>
using in_0_it_t = int*;
using out_0_it_t = unsigned long long*;
struct Op_0 {
__device__ __forceinline__
unsigned long long operator()(unsigned long long a, unsigned long long b) const {
return a + b;
}
};
extern "C" __attribute__((visibility("default"))) int cccl_jit_reduce(
void* d_temp_storage,
size_t* temp_storage_bytes,
void* d_in_state,
void* d_out_state,
unsigned long long num_items,
void* /*op_state*/,
void* init_state)
{
in_0_it_t d_in = static_cast<in_0_it_t>(d_in_state);
out_0_it_t d_out = static_cast<out_0_it_t>(d_out_state);
unsigned long long init = *static_cast<unsigned long long*>(init_state);
Op_0 op;
cudaError_t err = cub::DeviceReduce::Reduce<in_0_it_t, out_0_it_t, Op_0, int, unsigned long long>(
d_temp_storage, *temp_storage_bytes, d_in, d_out,
static_cast<int>(num_items), op, init);
return err == cudaSuccess ? 0 : -1;
}
)";
int main(int argc, char** argv)
{
std::string source_str;
std::string source_path;
if (argc > 1)
{
source_path = argv[1];
}
else if (const char* env = std::getenv("REPRO_SOURCE_FILE"))
{
source_path = env;
}
if (!source_path.empty())
{
std::ifstream f(source_path);
if (!f)
{
std::cerr << "Failed to open: " << source_path << std::endl;
return 2;
}
std::stringstream ss;
ss << f.rdbuf();
source_str = ss.str();
std::cerr << "Loaded " << source_str.size() << " bytes from " << source_path << std::endl;
}
else
{
source_str = default_source;
std::cerr << "Using built-in default source." << std::endl;
}
hostjit::CompilerConfig config = hostjit::detectDefaultConfig();
config.sm_version = 80;
config.verbose = false;
hostjit::JITCompiler compiler(config);
if (!compiler.compile(source_str))
{
std::cerr << "JIT compilation FAILED:\n" << compiler.getLastError() << std::endl;
return 1;
}
std::cout << "JIT compilation succeeded." << std::endl;
return 0;
}

View File

@@ -0,0 +1,71 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#include <cassert>
#include <cstdio>
#include <cuda_runtime.h>
#include <hostjit/config.hpp>
#include <hostjit/jit_compiler.hpp>
static const char* k_source = R"(
#include <initializer_list>
#include <utility>
#include <cuda/std/version>
#include <cuda_runtime.h>
__global__ void device_kernel(int* ptr)
{
::std::initializer_list<::std::size_t> meow {42ull, 1337ull};
*ptr = static_cast<int>(::std::move(*meow.begin()));
}
extern "C" _CCCL_VISIBILITY_EXPORT void host_entry(int* ptr)
{
device_kernel<<<1, 1>>>(ptr);
}
)";
int main()
{
// Detect Clang/CUDA configuration from the build environment
auto config = hostjit::detectDefaultConfig();
hostjit::JITCompiler compiler(config);
if (!compiler.compile(k_source))
{
std::fprintf(stderr, "HostJIT compilation failed:\n%s\n", compiler.getLastError().c_str());
return 1;
}
auto host_fn = compiler.getFunction<void (*)(int*)>("host_entry");
if (!host_fn)
{
std::fprintf(stderr, "Symbol 'host_entry' not found\n");
return 1;
}
int* d_ptr = nullptr;
cudaMalloc(&d_ptr, sizeof(int));
host_fn(d_ptr);
cudaDeviceSynchronize();
int result = 0;
cudaMemcpy(&result, d_ptr, sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(d_ptr);
assert(result == 42 && "device kernel did not write expected value");
std::printf("freestanding compiler test passed (result=%d)\n", result);
return 0;
}

View File

@@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#ifndef C_PARALLEL_FREESTANDING_TEST_UTIL_H
#define C_PARALLEL_FREESTANDING_TEST_UTIL_H
#include <cassert>
#include <iostream>
#include <cuda_runtime.h>
#define CUDA_CHECK(call) \
do \
{ \
cudaError_t err = call; \
if (err != cudaSuccess) \
{ \
std::cerr << "CUDA error at " << __FILE__ << ":" << __LINE__ << ": " << cudaGetErrorString(err) << "\n"; \
return 1; \
} \
} while (0)
#endif // C_PARALLEL_FREESTANDING_TEST_UTIL_H