Files
muh-bot 2a7ca101d7 feat(cccl): integrate missing CCCL directories — python/, ci/, .agent/, docs/, test/
Sparse-checkout from NVIDIA/cccl main branch to complete cccl_upstream:

Added:
- python/cuda_cccl/ (226 files) — Python bindings for device-level algorithms
  Critical for muh toolchain: cuda.compute.reduce_into, scan, radix_sort, etc.
  Includes 204 .py files with full test coverage for all 27 algorithms
- ci/ (163 files) — Build/test infrastructure
  build_cub.sh, test_cub.sh, build_and_test_targets.sh, matrix.yaml
  Directly maps to our [INFRA-CI] and [INFRA-BUILD] items
- .agent/skills/ (7 files) — NVIDIA's own agent skills for CCCL
  cccl-style/SKILL.md, cccl-test/SKILL.md, sass-diff/SKILL.md
- docs/ (491 files) — Official CCCL documentation
  CI references, CMake guides, Python compute docs, libcudacxx PTX docs
- test/ (12 files) — Top-level integration tests (cuda_smoke, stdpar)
- Root configs: .clang-format, .clang-tidy, CONTRIBUTING.md, pyproject.toml
- CLAUDE.md symlink → AGENTS.md (NVIDIA's standard)

cccl_upstream now mirrors full NVIDIA/cccl structure:
  Before: 42M (cub + thrust + libcudacxx + cudax + c + examples + benchmarks)
  After:  53M (+python +ci +docs +.agent +test +configs)

This completes the CCCL base needed for:
- [muh-bench] items: ci/util/build_and_test_targets.sh for targeted builds
- [CCCL-verify] items: python/cuda_cccl/tests/ as reference implementations
- [CCCL-test] items: ci/test_cub.sh, ci/test_thrust.sh
- Agent workflow: .agent/skills/ for consistent style and test patterns
2026-08-07 02:34:33 +00:00

254 lines
7.0 KiB
Python

# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
#
#
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
from __future__ import annotations
from ._bindings import Op, OpKind
from ._caching import CachableFunction, cache_with_registered_key_functions
from ._device_code import DeviceCode
def _is_well_known_op(op: OpKind) -> bool:
return isinstance(op, OpKind) and op not in (OpKind.STATELESS, OpKind.STATEFUL)
class _OpAdapter:
"""
Provides a unified interface for operators, whether they are:
- Well-known operations (OpKind.PLUS, OpKind.MAXIMUM, etc.)
- Stateless user-provided callables
- Stateful user-provided callables
"""
def compile(self, input_types, output_type=None) -> Op:
"""
Compile this operator to an Op for CCCL interop.
Args:
input_types: Tuple of TypeDescriptors for input arguments
output_type: Optional TypeDescriptor for return value (inferred if None)
Returns:
Compiled Op object for C++ interop
"""
raise NotImplementedError("Subclasses must implement this method")
@property
def is_stateful(self) -> bool:
"""Return True if this op has runtime state."""
return False
def get_state(self) -> bytes:
"""
Return the op's state bytes.
"""
return b""
def get_return_type(self, input_types):
"""Get the return type for this op given input types."""
raise NotImplementedError(
f"get_return_type not implemented for {self.__class__.__name__}"
)
class _WellKnownOp(_OpAdapter):
"""Internal wrapper for well-known OpKind values."""
__slots__ = ["_kind"]
def __init__(self, kind: OpKind):
if not _is_well_known_op(kind):
raise ValueError(
f"OpKind.{kind.name} is not a well-known operation. "
"Use OpKind.PLUS, OpKind.MAXIMUM, etc."
)
self._kind = kind
def compile(self, input_types, output_type=None) -> Op:
return Op(
operator_type=self._kind,
name="",
ltoir=b"",
state_alignment=1,
state=b"",
)
@property
def kind(self) -> OpKind:
"""The underlying OpKind."""
return self._kind
def __eq__(self, other):
if not isinstance(other, _WellKnownOp):
return False
return self._kind == other._kind
def __hash__(self):
return hash(self._kind)
class RawOp(_OpAdapter):
"""
``RawOp`` lets you supply pre-compiled device code (LTO-IR) implementing a
custom operator, bypassing the default Numba-based JIT pipeline.
Example:
Supplying C++ device code compiled to LTO-IR via NVRTC:
.. literalinclude:: ../../python/cuda_cccl/tests/compute/examples/raw_op/cpp_stateless.py
:language: python
:start-after: # example-begin
Args:
name: The ABI name of the operator.
ltoir: Raw ``bytes`` of pre-compiled LTO-IR implementing the operator
(for example, produced by ``nvcc -dlto`` or NVRTC).
state: Optional bytes representing the operator's state.
state_alignment: Alignment requirement for the state bytes (default: 1).
extra_ltoirs: Optional list of additional LTO-IR ``bytes`` to link.
Notes:
- The provided code must define a function with the specified name and the correct signature.
- The function must use untyped pointers for all parameters and return type. The function body
is responsible for correctly interpreting the pointer arguments based on the expected input and output types.
For stateless operators, the signature is
void func(void* arg1, void* arg2, ..., void* result)`
For stateful operators, the first parameter must be a pointer to the state:
void func(void* state, void* arg1, void* arg2, ...)
"""
__slots__ = [
"_ltoir",
"_name",
"_state",
"_state_alignment",
"_extra_ltoirs",
]
def __init__(
self,
*,
ltoir: bytes | DeviceCode,
name: str,
state: bytes = b"",
state_alignment: int = 1,
extra_ltoirs: list[bytes | DeviceCode] | None = None,
):
self._ltoir = ltoir
self._name = name
self._state = state
self._state_alignment = state_alignment
self._extra_ltoirs = extra_ltoirs or []
def compile(self, input_types, output_type=None) -> Op:
# Determine if stateful based on whether state is provided
op_kind = OpKind.STATEFUL if self._state else OpKind.STATELESS
return Op(
operator_type=op_kind,
name=self._name,
ltoir=self._ltoir,
state=self._state,
state_alignment=self._state_alignment,
extra_ltoirs=self._extra_ltoirs,
)
def get_state(self) -> bytes:
"""Return the op's state bytes."""
return self._state
@property
def _identity(self):
return (
self._ltoir,
self._name,
self._state,
self._state_alignment,
tuple(self._extra_ltoirs),
)
def __eq__(self, other):
if not isinstance(other, RawOp):
return False
return self._identity == other._identity
def __hash__(self):
return hash(self._identity)
# Public aliases
OpAdapter = _OpAdapter
def _jit_op_adapter_factory():
# helper that tries to import `_jit.py`. If it fails,
# returns a function that raises an appropriate error when called.
try:
from ._jit import to_jit_op_adapter
return to_jit_op_adapter
except ModuleNotFoundError as e:
if "numba" in str(e):
def _missing_jit_adapter(op):
raise ImportError(
"numba-cuda is required to JIT compile Python callables"
)
return _missing_jit_adapter
raise
to_jit_op_adapter = _jit_op_adapter_factory()
def make_op_adapter(op) -> OpAdapter:
"""
Create an Op from a callable or well-known OpKind.
Args:
op: Callable or OpKind
Returns:
A value with appropriate subtype of _BaseOp
"""
# Already an _OpAdapter instance:
if isinstance(op, _OpAdapter):
return op
# Well-known operation
if isinstance(op, OpKind):
return _WellKnownOp(op)
# It's a Python callable
return to_jit_op_adapter(op)
cache_with_registered_key_functions.register(
_WellKnownOp, lambda op: (op._kind.name, op._kind.value)
)
cache_with_registered_key_functions.register(
OpKind, lambda kind: (kind.name, kind.value)
)
cache_with_registered_key_functions.register(
type(lambda: None), lambda func: CachableFunction(func)
)
cache_with_registered_key_functions.register(RawOp, lambda op: op._identity)
__all__ = [
"OpAdapter",
"OpKind",
"make_op_adapter",
"RawOp",
]