ReleaseNVIDIANVIDIApublished Oct 14, 2025seen Jun 26

NVIDIA/cccl v3.1.0

NVIDIA/cccl

Open original ↗

Captured source

source ↗
published Oct 14, 2025seen Jun 26captured Aug 31http 200method plain

v3.1.0

Repository: NVIDIA/cccl

Tag: v3.1.0

Published: 2025-10-14T22:04:54Z

Prerelease: no

Release notes:

Highlights

New options for deterministic reductions in cub::DeviceReduce

Due to non-associativity of floating point addition, cub::DeviceReduce historically only guaranteed bitwise identical results run-to-run on the same GPU.

Starting with CCCL 3.1, formalizes three different levels of determinism with difference performance trade-offs

  • Not-guaranteed (new!) - new single-pass reduction using atomics
  • Run-to-run (status quo) - existing two-pass implementation
  • GPU-to-GPU (new!) - based on reproducible reduction in @maddyscientis GTC 2024 talk
// Pick your desired trade-off of performance and determinism
// auto env = cuda::execution::require(cuda::execution::determinism::not_guaranteed);
// auto env = cuda::execution::require(cuda::execution::determinism::run_to_run);
// auto env = cuda::execution::require(cuda::execution::determinism::gpu_to_gpu);
cub::DeviceReduce::Sum(..., env);

More convenient single-phase CUB APIs

Nearly every CUB algorithm requires temporary storage for intermediate scratch space to carry out the algorithm.

Historically, it was the users responsibility to query and allocate the necessary temporary storage through a two-phase call pattern that is cumbersome and error-prone if arguments aren’t passed the same between two invocations.

CCCL 3.1 adds new overloads of some CUB algorithms that accept a memory resource so you skip the temp-storage query/allocate/free pattern.

Before

// determine temporary storage size
cub::DeviceScan::ExclusiveSum(d_temp_storage,
temp_storage_bytes,
nullptr, ...);

// Allocate the required temporary storage
cudaMallocAsync(&d_temp_storage,
temp_storage_bytes, stream);

// run the actual scan
cub::DeviceScan::ExclusiveSum(d_temp_storage,
temp_storage_bytes,
d_input...);

// Free the temporary storage
cudaFreeAsync(temp_storage, stream);

After

// Pool mr uses cudaMallocAsync under the hood
cuda::device_memory_pool mr{cuda::devices[0]};

// Single call. Temp storage is handled by the pool.
cub::DeviceScan::ExclusiveSum(d_input,..., mr);

What's Changed

🚀 Thrust / CUB

libcu++

📚 Libcudacxx

Excerpt shown — open the source for the full document.