[CCCL] 瘦身 + 补全: 移除 cudax/python/libcudacxx-tests 冗余文件, 新增 c2h 测试助手 + cmake 构建系统 + 8 个 CUDA thrust examples
变更摘要:
- 删除: cudax/ (783 files, 7.2M) — 实验性组件,竞赛不需要
- 删除: python/ (226 files, 2.0M) — Python 绑定,竞赛不需要
- 删除: libcudacxx/{test,benchmarks,codegen,cmake,share} (4432 files, 31M)
保留: libcudacxx/include/ (1463 headers, cuda::std 编译依赖)
- 新增: c2h/ (27 files) — CUB Catch2 测试辅助头文件,编译 243 个测试必需
- 新增: cmake/ (29 files) — CCCL 原生 CMake 构建系统
- 新增: thrust/examples/cuda/ (7 files) + cpp_integration/ (1 file)
async_reduce, custom_temporary_allocation, explicit_cuda_stream,
global_device_vector, range_view, unwrap_pointer, wrap_pointer, device
结果: cccl_upstream 从 74M→35M (瘦身 53%), 核心内容 100% 保留:
27/27 tuning headers, 78 benchmarks, 243 tests,
60 thrust examples, 18 CUB examples, 全部编译头文件
This commit is contained in:
@@ -1,82 +0,0 @@
|
||||
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
"""
|
||||
Python benchmark for reduce custom operation using cuda.compute.reduce_into.
|
||||
|
||||
C++ equivalent: cub/benchmarks/bench/reduce/custom.cu
|
||||
|
||||
Notes:
|
||||
- Uses a custom max operator (not OpKind) to exercise generic path
|
||||
- int128 and complex32 are not supported by cupy
|
||||
- Migration: Python limits to basic numeric types; C++ includes int128/complex.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
import cupy as cp
|
||||
import numpy as np
|
||||
from utils import SIGNED_TYPES as TYPE_MAP
|
||||
from utils import as_cupy_stream, generate_data_with_entropy
|
||||
|
||||
import cuda.bench as bench
|
||||
from cuda.compute import make_reduce_into
|
||||
|
||||
|
||||
def max_op(a, b):
|
||||
return a if a > b else b
|
||||
|
||||
|
||||
def bench_reduce_custom(state: bench.State):
|
||||
type_str = state.get_string("T{ct}")
|
||||
dtype = TYPE_MAP[type_str]
|
||||
num_items = int(state.get_int64("Elements{io}"))
|
||||
|
||||
alloc_stream = as_cupy_stream(state.get_stream())
|
||||
with alloc_stream:
|
||||
d_in = generate_data_with_entropy(num_items, dtype, "1.000", alloc_stream)
|
||||
d_out = cp.empty(1, dtype=dtype)
|
||||
|
||||
h_init = np.zeros(1, dtype=dtype)
|
||||
|
||||
reducer = make_reduce_into(d_in=d_in, d_out=d_out, op=max_op, h_init=h_init)
|
||||
|
||||
temp_storage_bytes = reducer(
|
||||
temp_storage=None,
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
num_items=num_items,
|
||||
op=max_op,
|
||||
h_init=h_init,
|
||||
)
|
||||
with alloc_stream:
|
||||
temp_storage = cp.empty(temp_storage_bytes, dtype=np.uint8)
|
||||
|
||||
state.add_element_count(num_items)
|
||||
state.add_global_memory_reads(num_items * d_in.dtype.itemsize, "Size")
|
||||
state.add_global_memory_writes(d_out.dtype.itemsize)
|
||||
|
||||
def launcher(launch: bench.Launch):
|
||||
reducer(
|
||||
temp_storage=temp_storage,
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
num_items=num_items,
|
||||
op=max_op,
|
||||
h_init=h_init,
|
||||
stream=launch.get_stream(),
|
||||
)
|
||||
|
||||
state.exec(launcher, batched=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
b = bench.register(bench_reduce_custom)
|
||||
b.set_name("base")
|
||||
b.add_string_axis("T{ct}", list(TYPE_MAP.keys()))
|
||||
b.add_int64_power_of_two_axis("Elements{io}", range(16, 29, 4))
|
||||
bench.run_all_benchmarks(sys.argv)
|
||||
@@ -1,85 +0,0 @@
|
||||
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
"""
|
||||
Python benchmark for reduce min operation using cuda.compute.reduce_into.
|
||||
|
||||
C++ equivalent: cub/benchmarks/bench/reduce/min.cu
|
||||
|
||||
Notes:
|
||||
- Uses OpKind.MINIMUM for minimum reduction
|
||||
- C++ uses cuda::minimum<> which CUB recognizes for optimized code paths (DPX on Hopper+)
|
||||
- int128 and complex32 are not supported by cupy
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
import cupy as cp
|
||||
import numpy as np
|
||||
from utils import FUNDAMENTAL_TYPES as TYPE_MAP
|
||||
from utils import as_cupy_stream, generate_data_with_entropy
|
||||
|
||||
import cuda.bench as bench
|
||||
from cuda.compute import OpKind, make_reduce_into
|
||||
|
||||
|
||||
def bench_reduce_min(state: bench.State):
|
||||
type_str = state.get_string("T{ct}")
|
||||
dtype = TYPE_MAP[type_str]
|
||||
num_items = int(state.get_int64("Elements{io}"))
|
||||
|
||||
alloc_stream = as_cupy_stream(state.get_stream())
|
||||
with alloc_stream:
|
||||
d_in = generate_data_with_entropy(num_items, dtype, "1.000", alloc_stream)
|
||||
d_out = cp.empty(1, dtype=dtype)
|
||||
|
||||
# Initial value for min reduction (max value of type)
|
||||
if np.issubdtype(dtype, np.integer):
|
||||
init_val = np.iinfo(dtype).max
|
||||
else:
|
||||
init_val = np.finfo(dtype).max
|
||||
h_init = np.array([init_val], dtype=dtype)
|
||||
|
||||
reducer = make_reduce_into(d_in=d_in, d_out=d_out, op=OpKind.MINIMUM, h_init=h_init)
|
||||
|
||||
temp_storage_bytes = reducer(
|
||||
temp_storage=None,
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
num_items=num_items,
|
||||
op=OpKind.MINIMUM,
|
||||
h_init=h_init,
|
||||
)
|
||||
with alloc_stream:
|
||||
temp_storage = cp.empty(temp_storage_bytes, dtype=np.uint8)
|
||||
|
||||
state.add_element_count(num_items)
|
||||
state.add_global_memory_reads(num_items * d_in.dtype.itemsize, "Size")
|
||||
state.add_global_memory_writes(d_out.dtype.itemsize)
|
||||
|
||||
def launcher(launch: bench.Launch):
|
||||
reducer(
|
||||
temp_storage=temp_storage,
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
num_items=num_items,
|
||||
op=OpKind.MINIMUM,
|
||||
h_init=h_init,
|
||||
stream=launch.get_stream(),
|
||||
)
|
||||
|
||||
state.exec(launcher, batched=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
b = bench.register(bench_reduce_min)
|
||||
b.set_name("base")
|
||||
|
||||
b.add_string_axis("T{ct}", list(TYPE_MAP.keys()))
|
||||
b.add_int64_power_of_two_axis("Elements{io}", range(16, 29, 4))
|
||||
|
||||
bench.run_all_benchmarks(sys.argv)
|
||||
@@ -1,87 +0,0 @@
|
||||
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
"""
|
||||
Python benchmark for nondeterministic reduce sum using cuda.compute.reduce_into.
|
||||
|
||||
C++ equivalent: cub/benchmarks/bench/reduce/nondeterministic.cu
|
||||
|
||||
Notes:
|
||||
- Uses Determinism.NOT_GUARANTEED
|
||||
- C++ tests int32, int64, float, double
|
||||
- Migration: Python fixes offsets; C++ exposes an OffsetT axis.
|
||||
- OffsetT axis is omitted because the Python API does not expose offset type.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
import cupy as cp
|
||||
import numpy as np
|
||||
from utils import ALL_TYPES as _ALL_TYPES
|
||||
from utils import as_cupy_stream, generate_data_with_entropy
|
||||
|
||||
import cuda.bench as bench
|
||||
from cuda.compute import Determinism, OpKind, make_reduce_into
|
||||
|
||||
TYPE_MAP = {k: _ALL_TYPES[k] for k in ("I32", "I64", "F32", "F64")}
|
||||
|
||||
|
||||
def bench_reduce_nondeterministic(state: bench.State):
|
||||
type_str = state.get_string("T{ct}")
|
||||
dtype = TYPE_MAP[type_str]
|
||||
num_items = int(state.get_int64("Elements{io}"))
|
||||
|
||||
alloc_stream = as_cupy_stream(state.get_stream())
|
||||
with alloc_stream:
|
||||
d_in = generate_data_with_entropy(num_items, dtype, "1.000", alloc_stream)
|
||||
d_out = cp.empty(1, dtype=dtype)
|
||||
|
||||
h_init = np.zeros(1, dtype=dtype)
|
||||
|
||||
reducer = make_reduce_into(
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
op=OpKind.PLUS,
|
||||
h_init=h_init,
|
||||
determinism=Determinism.NOT_GUARANTEED,
|
||||
)
|
||||
|
||||
temp_storage_bytes = reducer(
|
||||
temp_storage=None,
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
num_items=num_items,
|
||||
op=OpKind.PLUS,
|
||||
h_init=h_init,
|
||||
)
|
||||
with alloc_stream:
|
||||
temp_storage = cp.empty(temp_storage_bytes, dtype=np.uint8)
|
||||
|
||||
state.add_element_count(num_items)
|
||||
state.add_global_memory_reads(num_items * d_in.dtype.itemsize, "Size")
|
||||
state.add_global_memory_writes(1 * d_out.dtype.itemsize)
|
||||
|
||||
def launcher(launch: bench.Launch):
|
||||
reducer(
|
||||
temp_storage=temp_storage,
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
num_items=num_items,
|
||||
op=OpKind.PLUS,
|
||||
h_init=h_init,
|
||||
stream=launch.get_stream(),
|
||||
)
|
||||
|
||||
state.exec(launcher, batched=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
b = bench.register(bench_reduce_nondeterministic)
|
||||
b.set_name("base")
|
||||
b.add_string_axis("T{ct}", list(TYPE_MAP.keys()))
|
||||
b.add_int64_power_of_two_axis("Elements{io}", range(16, 29, 4))
|
||||
bench.run_all_benchmarks(sys.argv)
|
||||
@@ -1,80 +0,0 @@
|
||||
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
"""
|
||||
Python benchmark for reduce sum operation using cuda.compute.reduce_into.
|
||||
|
||||
C++ equivalent: cub/benchmarks/bench/reduce/sum.cu
|
||||
|
||||
Notes:
|
||||
- int128 and complex32 are not supported by cupy
|
||||
- Migration: Python excludes int128/complex; C++ supports more types/tuning.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
import cupy as cp
|
||||
import numpy as np
|
||||
from utils import SIGNED_TYPES as TYPE_MAP
|
||||
from utils import as_cupy_stream, generate_data_with_entropy
|
||||
|
||||
import cuda.bench as bench
|
||||
from cuda.compute import OpKind, make_reduce_into
|
||||
|
||||
|
||||
def bench_reduce_sum(state: bench.State):
|
||||
type_str = state.get_string("T{ct}")
|
||||
dtype = TYPE_MAP[type_str]
|
||||
num_items = int(state.get_int64("Elements{io}"))
|
||||
|
||||
alloc_stream = as_cupy_stream(state.get_stream())
|
||||
with alloc_stream:
|
||||
d_in = generate_data_with_entropy(num_items, dtype, "1.000", alloc_stream)
|
||||
d_out = cp.empty(1, dtype=dtype)
|
||||
|
||||
# Initial value for reduction
|
||||
h_init = np.zeros(1, dtype=dtype)
|
||||
|
||||
reducer = make_reduce_into(d_in=d_in, d_out=d_out, op=OpKind.PLUS, h_init=h_init)
|
||||
|
||||
temp_storage_bytes = reducer(
|
||||
temp_storage=None,
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
num_items=num_items,
|
||||
op=OpKind.PLUS,
|
||||
h_init=h_init,
|
||||
)
|
||||
with alloc_stream:
|
||||
temp_storage = cp.empty(temp_storage_bytes, dtype=np.uint8)
|
||||
|
||||
state.add_element_count(num_items)
|
||||
state.add_global_memory_reads(num_items * d_in.dtype.itemsize, "Size")
|
||||
state.add_global_memory_writes(d_out.dtype.itemsize)
|
||||
|
||||
def launcher(launch: bench.Launch):
|
||||
reducer(
|
||||
temp_storage=temp_storage,
|
||||
d_in=d_in,
|
||||
d_out=d_out,
|
||||
num_items=num_items,
|
||||
op=OpKind.PLUS,
|
||||
h_init=h_init,
|
||||
stream=launch.get_stream(),
|
||||
)
|
||||
|
||||
state.exec(launcher, batched=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
b = bench.register(bench_reduce_sum)
|
||||
b.set_name("base")
|
||||
|
||||
b.add_string_axis("T{ct}", list(TYPE_MAP.keys()))
|
||||
b.add_int64_power_of_two_axis("Elements{io}", range(16, 29, 4))
|
||||
|
||||
bench.run_all_benchmarks(sys.argv)
|
||||
Reference in New Issue
Block a user