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
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
.. _libcudacxx-extended-api-functional-always-true-false:
|
||||
|
||||
``cuda::always_true`` and ``cuda::always_false``
|
||||
================================================
|
||||
|
||||
Defined in the header ``<cuda/functional>``.
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
struct always_true {
|
||||
template <typename... Ts>
|
||||
[[nodiscard]] __host__ __device__ constexpr bool operator()(Ts&&...) const noexcept;
|
||||
};
|
||||
|
||||
struct always_false {
|
||||
template <typename... Ts>
|
||||
[[nodiscard]] __host__ __device__ constexpr bool operator()(Ts&&...) const noexcept;
|
||||
};
|
||||
|
||||
``cuda::always_true`` is a function object that always returns ``true`` regardless of the number and type of arguments
|
||||
passed. ``cuda::always_false`` is a function object that always returns ``false`` regardless of the number and type of
|
||||
arguments passed.
|
||||
|
||||
Both types are empty, trivially copyable, and their ``operator()`` is ``constexpr`` and ``noexcept``.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
#include <cuda/functional>
|
||||
|
||||
__global__ void example_kernel() {
|
||||
cuda::always_true pred_true{};
|
||||
cuda::always_false pred_false{};
|
||||
|
||||
// Returns true regardless of arguments
|
||||
static_assert(pred_true());
|
||||
static_assert(pred_true(1, 2, 3));
|
||||
|
||||
// Returns false regardless of arguments
|
||||
static_assert(!pred_false());
|
||||
static_assert(!pred_false(1, 2, 3));
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
.. _libcudacxx-extended-api-functional-maximum-minimum:
|
||||
|
||||
``cuda::maximum`` and ``cuda::minimum``
|
||||
=======================================
|
||||
|
||||
Defined in the header ``<cuda/functional>``.
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
template <typename T>
|
||||
struct maximum {
|
||||
[[nodiscard]] __host__ __device__ constexpr
|
||||
T operator()(const T& a, const T& b) const noexcept(/* see below */);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct maximum<void> {
|
||||
template <typename T1, typename T2>
|
||||
[[nodiscard]] __host__ __device__ constexpr
|
||||
cuda::std::common_type_t<T1, T2> operator()(const T1& a, const T2& b) const noexcept(/* see below */);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct minimum {
|
||||
[[nodiscard]] __host__ __device__ constexpr
|
||||
T operator()(const T& a, const T& b) const noexcept(/* see below */);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum<void> {
|
||||
template <typename T1, typename T2>
|
||||
[[nodiscard]] __host__ __device__ constexpr
|
||||
cuda::std::common_type_t<T1, T2> operator()(const T1& a, const T2& b) const noexcept(/* see below */);
|
||||
};
|
||||
|
||||
Function objects for performing maximum and minimum operations. The ``operator()`` is ``noexcept`` when the comparison between the values is also ``noexcept``.
|
||||
|
||||
.. note::
|
||||
|
||||
Differently from ``std::plus`` and other functional operators, ``cuda::maximum`` and ``cuda::minimum`` specialized for ``void`` returns ``cuda::std::common_type_t`` and not the implicit promotion
|
||||
|
||||
Floating-Point Behavior
|
||||
-----------------------
|
||||
|
||||
For floating-point types (and extended floating-point types), ``cuda::maximum`` uses ``cuda::std::fmax`` and ``cuda::minimum`` uses ``cuda::std::fmin`` instead of the comparison operator, following the ``std::fmax``/``std::fmin`` specification for handling special values such as ``NaN``.
|
||||
|
||||
This also makes ``cuda::maximum`` and ``cuda::minimum`` commutative for floating-point types, unlike a plain comparison-based approach.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
#include <cuda/functional>
|
||||
#include <cuda/std/cstdint>
|
||||
#include <cstdio>
|
||||
#include <numeric>
|
||||
|
||||
__global__ void maximum_minimum_kernel() {
|
||||
uint16_t v1 = 7;
|
||||
uint16_t v2 = 3;
|
||||
printf("%d\n", cuda::maximum<uint16_t>{}(v1, v2)); // print "7" (uint16_t)
|
||||
printf("%d\n", cuda::minimum{}(v1, v2)); // print "3" (int)
|
||||
}
|
||||
|
||||
int main() {
|
||||
maximum_minimum_kernel<<<1, 1>>>();
|
||||
cudaDeviceSynchronize();
|
||||
int array[] = {3, 7, 5, 2};
|
||||
printf("%d\n", std::accumulate(array, array + 4, 0, cuda::maximum{})); // 7
|
||||
return 0;
|
||||
}
|
||||
|
||||
`See it on Godbolt 🔗 <https://godbolt.org/z/44fdTerre>`_
|
||||
@@ -0,0 +1,340 @@
|
||||
.. _libcudacxx-extended-api-functional-operator-properties:
|
||||
|
||||
Operator Properties
|
||||
===================
|
||||
|
||||
Defined in the header ``<cuda/functional>``.
|
||||
|
||||
The operator properties traits provide compile-time information about algebraic properties of binary operators.
|
||||
These traits are useful for generic algorithms that can apply optimizations based on operator properties,
|
||||
such as parallel reductions that can reorder operations for associative operators.
|
||||
|
||||
Associativity
|
||||
-------------
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
namespace cuda {
|
||||
|
||||
template <class Op, class T, class Enable = void>
|
||||
inline constexpr bool is_associative_v;
|
||||
|
||||
} // namespace cuda
|
||||
|
||||
Determines whether a binary operator ``Op`` is associative for type ``T``, meaning ``op(op(a, b), c) == op(a, op(b, c))``
|
||||
for all values ``a``, ``b``, ``c`` of type ``T``. This allows the implementation to reorder operations.
|
||||
|
||||
**Supported operators and types:**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 35 35
|
||||
:header-rows: 1
|
||||
|
||||
* - Operator
|
||||
- Integer Types
|
||||
- Floating-Point Types
|
||||
* - ``cuda::std::plus``
|
||||
- ``true``
|
||||
- ``false`` (due to rounding errors)
|
||||
* - ``cuda::std::multiplies``
|
||||
- ``true``
|
||||
- ``false`` (due to rounding errors)
|
||||
* - ``cuda::std::minus``
|
||||
- ``false``
|
||||
- ``false``
|
||||
* - ``cuda::std::divides``
|
||||
- ``false``
|
||||
- ``false``
|
||||
* - ``cuda::std::modulus``
|
||||
- ``false``
|
||||
- N/A
|
||||
* - ``cuda::std::bit_and``
|
||||
- ``true``
|
||||
- N/A
|
||||
* - ``cuda::std::bit_or``
|
||||
- ``true``
|
||||
- N/A
|
||||
* - ``cuda::std::bit_xor``
|
||||
- ``true``
|
||||
- N/A
|
||||
* - ``cuda::std::logical_and``
|
||||
- ``true`` (``bool`` only)
|
||||
- N/A
|
||||
* - ``cuda::std::logical_or``
|
||||
- ``true`` (``bool`` only)
|
||||
- N/A
|
||||
* - ``cuda::minimum``
|
||||
- ``true``
|
||||
- ``true``
|
||||
* - ``cuda::maximum``
|
||||
- ``true``
|
||||
- ``true``
|
||||
|
||||
.. note::
|
||||
|
||||
In the strictest sense of the term, the operations of plus and multiplication for integral values may result in undefined behaviour due to overflow. However, in the context of parallel algorithms, they are considered to be associative.
|
||||
|
||||
Commutativity
|
||||
-------------
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
namespace cuda {
|
||||
|
||||
template <class Op, class T, class Enable = void>
|
||||
inline constexpr bool is_commutative_v;
|
||||
|
||||
} // namespace cuda
|
||||
|
||||
Determines whether a binary operator ``Op`` is commutative for type ``T``, meaning ``op(a, b) == op(b, a)``
|
||||
for all values ``a``, ``b`` of type ``T``.
|
||||
|
||||
**Supported operators and types:**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 35 35
|
||||
:header-rows: 1
|
||||
|
||||
* - Operator
|
||||
- Integer Types
|
||||
- Floating-Point Types
|
||||
* - ``cuda::std::plus``
|
||||
- ``true``
|
||||
- ``true``
|
||||
* - ``cuda::std::multiplies``
|
||||
- ``true``
|
||||
- ``true``
|
||||
* - ``cuda::std::minus``
|
||||
- ``false``
|
||||
- ``false``
|
||||
* - ``cuda::std::divides``
|
||||
- ``false``
|
||||
- ``false``
|
||||
* - ``cuda::std::modulus``
|
||||
- ``false``
|
||||
- N/A
|
||||
* - ``cuda::std::bit_and``
|
||||
- ``true``
|
||||
- N/A
|
||||
* - ``cuda::std::bit_or``
|
||||
- ``true``
|
||||
- N/A
|
||||
* - ``cuda::std::bit_xor``
|
||||
- ``true``
|
||||
- N/A
|
||||
* - ``cuda::std::logical_and``
|
||||
- ``true`` (``bool`` only)
|
||||
- N/A
|
||||
* - ``cuda::std::logical_or``
|
||||
- ``true`` (``bool`` only)
|
||||
- N/A
|
||||
* - ``cuda::minimum``
|
||||
- ``true``
|
||||
- ``true``
|
||||
* - ``cuda::maximum``
|
||||
- ``true``
|
||||
- ``true``
|
||||
|
||||
Identity Element
|
||||
----------------
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
namespace cuda {
|
||||
|
||||
template <class Op, class T>
|
||||
__host__ __device__
|
||||
constexpr auto identity_element() noexcept;
|
||||
|
||||
template <class Op, class T, class Enable = void>
|
||||
inline constexpr bool has_identity_element_v;
|
||||
|
||||
} // namespace cuda
|
||||
|
||||
Provides the identity element for operator ``Op`` and type ``T``. The identity element ``e`` satisfies
|
||||
``op(e, x) == op(x, e) == x`` for all values ``x`` of type ``T``.
|
||||
|
||||
The function ``identity_element<Op, T>()`` returns the identity element at compile time. If no identity element
|
||||
exists for the given operator and type combination, it returns an internal sentinel type.
|
||||
|
||||
``has_identity_element_v`` evaluates to ``true`` if an identity element is defined for the given operator and type.
|
||||
|
||||
**Identity elements by operator:**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 35 35
|
||||
:header-rows: 1
|
||||
|
||||
* - Operator
|
||||
- Integer Types
|
||||
- Floating-Point Types
|
||||
* - ``cuda::std::plus``
|
||||
- ``T{0}``
|
||||
- ``-0.0`` (negative zero)
|
||||
* - ``cuda::std::multiplies``
|
||||
- ``T{1}``
|
||||
- ``1.0``
|
||||
* - ``cuda::std::bit_and``
|
||||
- ``~T{0}`` (all bits set)
|
||||
- N/A
|
||||
* - ``cuda::std::bit_or``
|
||||
- ``T{0}``
|
||||
- N/A
|
||||
* - ``cuda::std::bit_xor``
|
||||
- ``T{0}``
|
||||
- N/A
|
||||
* - ``cuda::std::logical_and``
|
||||
- ``true`` (``bool`` only)
|
||||
- N/A
|
||||
* - ``cuda::std::logical_or``
|
||||
- ``false`` (``bool`` only)
|
||||
- N/A
|
||||
* - ``cuda::minimum``
|
||||
- ``numeric_limits<T>::max()``
|
||||
- ``+infinity``
|
||||
* - ``cuda::maximum``
|
||||
- ``numeric_limits<T>::lowest()``
|
||||
- ``-infinity``
|
||||
|
||||
.. note::
|
||||
|
||||
For floating-point ``plus``, the identity element is negative zero (``-0.0``) rather than positive zero.
|
||||
This preserves the sign when adding: ``-0.0 + (-0.0) == -0.0``.
|
||||
|
||||
.. note::
|
||||
|
||||
``cuda::std::minus``, ``cuda::std::divides``, and ``cuda::std::modulus`` do not have identity elements.
|
||||
|
||||
Absorbing Element
|
||||
-----------------
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
namespace cuda {
|
||||
|
||||
template <class Op, class T>
|
||||
__host__ __device__
|
||||
constexpr auto absorbing_element() noexcept;
|
||||
|
||||
template <class Op, class T, class Enable = void>
|
||||
inline constexpr bool has_absorbing_element_v;
|
||||
|
||||
} // namespace cuda
|
||||
|
||||
Provides the absorbing (annihilating) element for operator ``Op`` and type ``T``. The absorbing element ``z`` satisfies
|
||||
``op(z, x) == op(x, z) == z`` for all values ``x`` of type ``T``.
|
||||
|
||||
The function ``absorbing_element<Op, T>()`` returns the absorbing element at compile time. If no absorbing element
|
||||
exists for the given operator and type combination, it returns an internal sentinel type.
|
||||
|
||||
``has_absorbing_element_v`` evaluates to ``true`` if an absorbing element is defined for the given operator and type.
|
||||
|
||||
**Absorbing elements by operator:**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 35 35
|
||||
:header-rows: 1
|
||||
|
||||
* - Operator
|
||||
- Integer Types
|
||||
- Floating-Point Types
|
||||
* - ``cuda::std::multiplies``
|
||||
- ``T{0}``
|
||||
- N/A (see note)
|
||||
* - ``cuda::std::bit_and``
|
||||
- ``T{0}``
|
||||
- N/A
|
||||
* - ``cuda::std::bit_or``
|
||||
- ``~T{0}`` (all bits set)
|
||||
- N/A
|
||||
* - ``cuda::std::logical_and``
|
||||
- ``false`` (``bool`` only)
|
||||
- N/A
|
||||
* - ``cuda::std::logical_or``
|
||||
- ``true`` (``bool`` only)
|
||||
- N/A
|
||||
* - ``cuda::minimum``
|
||||
- ``numeric_limits<T>::lowest()``
|
||||
- ``-infinity``
|
||||
* - ``cuda::maximum``
|
||||
- ``numeric_limits<T>::max()``
|
||||
- ``+infinity``
|
||||
|
||||
.. note::
|
||||
|
||||
Floating-point ``multiplies`` does not have an absorbing element because:
|
||||
|
||||
- ``0 * NaN = NaN`` (not ``0``)
|
||||
- ``0 * infinity = NaN`` (not ``0``)
|
||||
- ``(-1) * (+0) = -0`` (not ``+0``)
|
||||
|
||||
.. note::
|
||||
|
||||
``cuda::std::plus``, ``cuda::std::minus``, ``cuda::std::divides``, ``cuda::std::modulus``, and ``cuda::std::bit_xor``
|
||||
do not have absorbing elements.
|
||||
|
||||
Supported Types
|
||||
---------------
|
||||
|
||||
The functionality supports all integer and floating-point types, including extended floating-point types.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
#include <cuda/functional>
|
||||
#include <cuda/std/cstdio>
|
||||
|
||||
template <class Op, class T>
|
||||
__host__ __device__ void print_properties() {
|
||||
printf("Associative: %s\n", cuda::is_associative_v<Op, T> ? "yes" : "no");
|
||||
printf("Commutative: %s\n", cuda::is_commutative_v<Op, T> ? "yes" : "no");
|
||||
printf("Has identity: %s\n", cuda::has_identity_element_v<Op, T> ? "yes" : "no");
|
||||
printf("Has absorbing: %s\n", cuda::has_absorbing_element_v<Op, T> ? "yes" : "no");
|
||||
|
||||
if constexpr (cuda::has_identity_element_v<Op, T>) {
|
||||
printf("Identity element exists\n");
|
||||
}
|
||||
if constexpr (cuda::has_absorbing_element_v<Op, T>) {
|
||||
printf("Absorbing element exists\n");
|
||||
}
|
||||
}
|
||||
|
||||
__global__ void example_kernel() {
|
||||
// Integer plus: associative, commutative, identity=0, no absorbing
|
||||
print_properties<cuda::std::plus<int>, int>();
|
||||
|
||||
// Integer plus: NOT associative, commutative, identity=-0.0f, no absorbing
|
||||
print_properties<cuda::std::plus<float>, float>();
|
||||
|
||||
// identity element
|
||||
constexpr int sum_identity = cuda::identity_element<cuda::std::plus<int>, int>(); // 0
|
||||
constexpr int mul_identity = cuda::identity_element<cuda::std::multiplies<int>, int>(); // 1
|
||||
}
|
||||
|
||||
Customization
|
||||
-------------
|
||||
|
||||
Users can extend the operator properties traits to support custom operators or custom types by specializing
|
||||
the internal variable templates. The following specializations are available:
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
template <>
|
||||
inline constexpr bool cuda::is_associative_v<MyOperator, MyType> = true;
|
||||
|
||||
template <>
|
||||
inline constexpr bool cuda::is_commutative_v<MyOperator, MyType> = true;
|
||||
|
||||
template <>
|
||||
__host__ __device__
|
||||
constexpr auto cuda::identity_element<MyOperator, MyType>() noexcept {
|
||||
return /* MyType identity element */;
|
||||
}
|
||||
|
||||
template <>
|
||||
__host__ __device__
|
||||
constexpr auto cuda::absorbing_element<MyOperator, MyType>() noexcept {
|
||||
return /* MyType absorbing element */;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
.. _libcudacxx-extended-api-functional-proclaim-return-type:
|
||||
|
||||
``cuda::proclaim_return_type``
|
||||
==============================
|
||||
|
||||
Defined in the header ``<cuda/functional>``:
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
template <class Ret, class Fn>
|
||||
__host__ __device__
|
||||
unspecified<Ret, Fn> proclaim_return_type(Fn&& fn) {
|
||||
return unspecified<Ret, Fn>{fn};
|
||||
}
|
||||
|
||||
``cuda::proclaim_return_type`` creates a forwarding call wrapper that uses ``Ret`` as a return type.
|
||||
The wrapper is useful in the case of extended device lambdas since an attempt to determine the return type of
|
||||
their ``operator()`` function may work incorrectly in host code.
|
||||
|
||||
Template Parameters
|
||||
-------------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 25 75
|
||||
:header-rows: 0
|
||||
|
||||
* - ``Ret``
|
||||
- Return type that's being proclaimed
|
||||
* - ``Fn``
|
||||
- Callable object type that's being wrapped
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. list-table::
|
||||
:widths: 25 75
|
||||
:header-rows: 0
|
||||
|
||||
* - ``fn``
|
||||
- Callable object that's being wrapped
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code:: cuda
|
||||
|
||||
#include <cuda/functional>
|
||||
|
||||
template <class T, class Fn>
|
||||
__global__ void example_kernel(T *out, Fn fn) {
|
||||
*out = fn();
|
||||
}
|
||||
|
||||
__host__ void example() {
|
||||
auto fn = cuda::proclaim_return_type<char>([] __device__ () { return 'd'; });
|
||||
using rt = cuda::std::invoke_result_t<decltype(fn)>;
|
||||
|
||||
rt* out {};
|
||||
cudaMalloc(&out, sizeof(rt));
|
||||
|
||||
example_kernel<<<1, 1>>>(out, fn);
|
||||
|
||||
// ...
|
||||
}
|
||||
Reference in New Issue
Block a user