[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,169 +0,0 @@
|
||||
import builtins
|
||||
from collections.abc import Generator
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from cuda.core import Device, Stream
|
||||
|
||||
try:
|
||||
from cuda.compute._build_info import USING_V2
|
||||
except ImportError:
|
||||
USING_V2 = False
|
||||
|
||||
check_ldl_stl_in_sass = False
|
||||
|
||||
|
||||
# Define a pytest fixture that returns random arrays with different dtypes
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
np.int8,
|
||||
np.int16,
|
||||
np.int32,
|
||||
np.int64,
|
||||
np.uint8,
|
||||
np.uint16,
|
||||
np.uint32,
|
||||
np.uint64,
|
||||
np.float16,
|
||||
np.float32,
|
||||
np.float64,
|
||||
np.complex64,
|
||||
np.complex128,
|
||||
]
|
||||
)
|
||||
def input_array(request):
|
||||
dtype = np.dtype(request.param)
|
||||
sample_size = 1000
|
||||
|
||||
# Generate random values based on the dtype
|
||||
if np.issubdtype(dtype, np.integer):
|
||||
is_unsigned = dtype.kind == "u"
|
||||
# For integer types, use np.random.randint for random integers
|
||||
if is_unsigned:
|
||||
low_inclusive, high_exclusive = 0, 8
|
||||
else:
|
||||
low_inclusive, high_exclusive = -5, 6
|
||||
array = np.random.randint(
|
||||
low=low_inclusive, high=high_exclusive, size=sample_size, dtype=dtype
|
||||
)
|
||||
elif np.issubdtype(dtype, np.floating):
|
||||
# For floating-point types, use np.random.random and cast to the required dtype
|
||||
array = np.random.random(sample_size).astype(dtype)
|
||||
elif np.issubdtype(dtype, np.complexfloating):
|
||||
# For complex types, generate random real and imaginary parts
|
||||
packed = np.random.random(2 * sample_size)
|
||||
real_part = packed[:sample_size]
|
||||
imag_part = packed[sample_size:]
|
||||
array = (real_part + 1j * imag_part).astype(dtype)
|
||||
|
||||
return array
|
||||
|
||||
|
||||
# Define a pytest fixture that returns random floating-point arrays only
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
np.float32,
|
||||
np.float64,
|
||||
]
|
||||
)
|
||||
def floating_array(request):
|
||||
dtype = np.dtype(request.param)
|
||||
sample_size = 1000
|
||||
|
||||
# Generate random floating-point values
|
||||
array = np.random.random(sample_size).astype(dtype)
|
||||
return array
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def cuda_stream() -> Generator[Stream, None, None]:
|
||||
device = Device()
|
||||
device.set_current()
|
||||
stream = device.create_stream()
|
||||
try:
|
||||
yield stream
|
||||
finally:
|
||||
stream.close()
|
||||
|
||||
|
||||
@pytest.fixture(scope="function", autouse=True)
|
||||
def verify_sass(request):
|
||||
if request.node.get_closest_marker("no_verify_sass"):
|
||||
return
|
||||
|
||||
if not check_ldl_stl_in_sass:
|
||||
return
|
||||
|
||||
# Pull monkeypatch dynamically rather than as a fixture parameter so this
|
||||
# autouse fixture does not add monkeypatch to every test's static fixture
|
||||
# closure. pytest-run-parallel treats monkeypatch as thread-unsafe based on
|
||||
# that closure, so a parameter here would serialize the entire free-threaded
|
||||
# parallel sweep -- even though this fixture only patches on the opt-in
|
||||
# SASS-check path (check_ldl_stl_in_sass, off by default and in CI).
|
||||
monkeypatch = request.getfixturevalue("monkeypatch")
|
||||
|
||||
import cuda.compute._cccl_interop
|
||||
|
||||
monkeypatch.setattr(
|
||||
cuda.compute._cccl_interop,
|
||||
"_check_sass",
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def raise_on_numba_import(monkeypatch):
|
||||
"""This fixture will raise if a test attempts to import numba"""
|
||||
real_import = builtins.__import__
|
||||
|
||||
def guarded_import(name, *args, **kwargs):
|
||||
if name == "numba" or name.startswith("numba."):
|
||||
raise ModuleNotFoundError(
|
||||
"This test is marked 'no_numba' but attempted to import it"
|
||||
)
|
||||
return real_import(name, *args, **kwargs)
|
||||
|
||||
monkeypatch.setattr(builtins, "__import__", guarded_import)
|
||||
|
||||
|
||||
def pytest_collection_modifyitems(config, items):
|
||||
"""Runs after pytest collects the tests. Makes a test marked no_numba fail
|
||||
if it imports numba, and skips a test marked serialization when running on
|
||||
the v2 (HostJIT) backend."""
|
||||
serialization_skip = pytest.mark.skip(
|
||||
reason="serialization not supported on v2 (HostJIT) backend"
|
||||
)
|
||||
|
||||
# Tests marked no_numba must not import numba. We enforce that by attaching
|
||||
# the raise_on_numba_import fixture defined above to each one; it raises if
|
||||
# numba is imported.
|
||||
#
|
||||
# We skip attaching it during a real pytest-run-parallel sweep of more than
|
||||
# one thread: the fixture uses monkeypatch, which pytest-run-parallel
|
||||
# serializes as thread-unsafe, so attaching it to every no_numba test would
|
||||
# make the whole sweep run serially and defeat its purpose. A single-threaded
|
||||
# run has no sweep to protect, so we attach it and keep the check.
|
||||
#
|
||||
# config.getoption gives the --parallel-threads value as an int for the
|
||||
# default but a str when passed on the command line; normalize to str and
|
||||
# count the run as parallel only for an explicit number > 1:
|
||||
#
|
||||
# pytest ... -> 1 single-threaded, attach
|
||||
# pytest --parallel-threads=1 ... -> "1" single-threaded, attach
|
||||
# pytest --parallel-threads=8 ... -> "8" parallel, skip (CI sweep)
|
||||
# pytest --parallel-threads=auto ... -> "auto" single-threaded, attach
|
||||
#
|
||||
# "auto" counts as single-threaded on purpose: it can resolve to one CPU, so
|
||||
# keeping the check is safer than dropping it on a non-parallel run. isdigit
|
||||
# also stops int() from raising on the non-numeric "auto".
|
||||
parallel_threads = str(config.getoption("parallel_threads", 1))
|
||||
running_parallel = parallel_threads.isdigit() and int(parallel_threads) > 1
|
||||
for item in items:
|
||||
# no_numba: add raise_on_numba_import unless we skip it for the sweep
|
||||
if item.get_closest_marker("no_numba") and not running_parallel:
|
||||
if "raise_on_numba_import" not in item.fixturenames:
|
||||
item.fixturenames.append("raise_on_numba_import")
|
||||
# serialization is unsupported on v2 (HostJIT); skip those tests there
|
||||
if USING_V2 and item.get_closest_marker("serialization"):
|
||||
item.add_marker(serialization_skip)
|
||||
Reference in New Issue
Block a user