Skip to content

[CUB] Refactor cub::DeviceFor to always take an environment - #11013

Open
macdonaldezra wants to merge 7 commits into
NVIDIA:mainfrom
macdonaldezra:refactor-device-for-env
Open

[CUB] Refactor cub::DeviceFor to always take an environment#11013
macdonaldezra wants to merge 7 commits into
NVIDIA:mainfrom
macdonaldezra:refactor-device-for-env

Conversation

@macdonaldezra

Copy link
Copy Markdown
Contributor

Description

Part of #9875 (the DeviceFor row).

Replaces the trailing cudaStream_t parameter of the two-phase Bulk, ForEachN, ForEach, ForEachCopyN, ForEachCopy, ForEachInExtents, and ForEachInLayout overloads with an execution environment, and removes the bare-stream single-phase overloads and their SFINAE, which are no longer needed now that environments are taken by const& (#10105).

Notes:

  • A new static_assert rejects env types whose conversion to cudaStream_t is not const-qualified — previously served by the removed overloads, these would otherwise silently launch on the default stream. Flagged for discussion: happy to generalize it into cuda::get_stream/env_dispatch.cuh as a follow-up, or drop it for exact parity with the sibling migrations.
  • Also fixes a fast_div_mod assertion failure for empty extents in ForEachInExtents, the mislabeled ForEachInLayout NVTX range, and its param docs.

Checklist

  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

@macdonaldezra
macdonaldezra requested a review from a team as a code owner August 26, 2026 02:57
@macdonaldezra
macdonaldezra requested review from pauleonix and a lite review from Copilot August 26, 2026 02:57
@github-project-automation github-project-automation Bot moved this to Todo in CCCL Aug 26, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the CUB device-scope API migration away from a trailing cudaStream_t parameter by refactoring cub::DeviceFor to consistently accept an execution environment (const Env&) for both single-phase and two-phase overloads. It also tightens environment/stream querying behavior to avoid silent fallback to the default stream for env types that are only non-const convertible to cudaStream_t, and fixes ForEachInExtents behavior for empty extents plus a mislabeled NVTX range.

Changes:

  • Replaced cudaStream_t parameters in DeviceFor two-phase overloads with const Env&, and removed the bare-stream single-phase overloads/SFINAE.
  • Added a compile-time guard to reject env types whose stream conversion cannot be queried through a const& (preventing silent default-stream launches).
  • Fixed ForEachInExtents empty-extent handling (avoids fast_div_mod assertion) and corrected the ForEachInLayout NVTX range name; expanded/updated Catch2 coverage accordingly.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
cub/cub/device/device_for.cuh Refactors DeviceFor APIs to use environments everywhere, adds const-query static_assert guard, fixes empty-extents path, and corrects NVTX labeling/docs.
cub/test/catch2_test_device_for_env.cu Adds broad environment-kind acceptance tests, stream-routing verification, and two-phase tuning propagation coverage for the updated env-based APIs.
cub/test/catch2_test_device_for_api.cu Updates unambiguity guard tests and adds size-query guards for extents/layout plus a runtime test for empty-extents handling.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Device iteration APIs now support execution environments for stream selection across bulk, foreach, copy, extent, and layout operations.
    • Added support for stream, wrapper, property, GPU, and tuning environments.
    • Improved CUDA graph-capture behavior with environment-selected streams.
  • Bug Fixes

    • Empty extents are handled safely without unnecessary setup.
    • Improved overload resolution for temporary-storage and size-query operations.
  • Tests

    • Added comprehensive coverage for environments, tuning, extents, layouts, and graph capture.

Walkthrough

Changes

DeviceFor operations now use execution environments for stream selection. Legacy cudaStream_t overloads and related constraints were removed. Extent and layout dispatch now handle empty shapes and add NVTX instrumentation. Tests cover environment variants, stream routing, tuning, and overload resolution.

Changes

DeviceFor execution environments

Layer / File(s) Summary
Environment-based API contracts
cub/cub/device/device_for.cuh
Temporary-storage and execution overloads now accept execution environments. Legacy stream overloads and related constraints were removed. Internal temporary-storage dispatch forwards the environment.
Extent and layout dispatch
cub/cub/device/device_for.cuh
Extent and layout APIs forward environments through internal dispatch. Public calls add NVTX ranges, const-qualify internal data, and handle empty shapes before division-helper construction.
Environment and API validation
cub/test/catch2_test_device_for_api.cu, cub/test/catch2_test_device_for_env.cu
Tests cover environment variants, stream routing, stream capture, two-phase tuning, overload resolution, and empty dynamic extents.

Suggested reviewers: pauleonix, bernhardmgruber

Merge Risk: ⚪ Minimal · up to 32017

The API refactor and associated fixes have no demonstrated merge-blocking correctness, security, availability, or deployment risk at the current head; the remaining item is limited to a localized const-qualification style cleanup.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
cub/cub/device/device_for.cuh (1)

1278-1289: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

suggestion: extents, shape, sub_sizes_div_array, extents_div_array, and op_wrapper are never modified after initialization. Declare them const.

-    auto extents                   = layout_mapping.extents();
+    const auto extents             = layout_mapping.extents();
     using ShapeT                   = implicit_prom_t<extent_index_type>;
-    auto shape                     = static_cast<ShapeT>(cub::detail::size(extents));
+    const auto shape               = static_cast<ShapeT>(cub::detail::size(extents));
     // must precede the fast_div_mod arrays below, whose constructor asserts a positive divisor
     if (shape == 0)
     {
       return cudaSuccess;
     }
-    fast_mod_array_t sub_sizes_div_array = cub::detail::sub_sizes_fast_div_mod<is_layout_right>(extents, seq);
-    fast_mod_array_t extents_div_array   = cub::detail::extents_fast_div_mod(extents, seq);
-    for_each::op_wrapper_extents_t<OpType, extents_type, is_layout_right, fast_mod_array_t> op_wrapper{
+    const fast_mod_array_t sub_sizes_div_array = cub::detail::sub_sizes_fast_div_mod<is_layout_right>(extents, seq);
+    const fast_mod_array_t extents_div_array   = cub::detail::extents_fast_div_mod(extents, seq);
+    const for_each::op_wrapper_extents_t<OpType, extents_type, is_layout_right, fast_mod_array_t> op_wrapper{
       op, extents, sub_sizes_div_array, extents_div_array};

As per coding guidelines: "All variables that are not modified must be declared const, including cast results, function return values, and loop-invariant computations."

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 38b95cf6-a477-4750-b9e7-9fe3ee2c9994

📥 Commits

Reviewing files that changed from the base of the PR and between ffddb67 and 626229e.

📒 Files selected for processing (3)
  • cub/cub/device/device_for.cuh
  • cub/test/catch2_test_device_for_api.cu
  • cub/test/catch2_test_device_for_env.cu

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

Comment thread cub/cub/device/device_for.cuh Outdated
Comment on lines +137 to +142
// `env` is queried through a const reference, so a conversion operator or accessor that is not
// const-qualified is unreachable and would silently fall back to the default stream.
static_assert(!(::cuda::std::is_convertible_v<EnvT, cudaStream_t>
&& !::cuda::std::__is_callable_v<::cuda::get_stream_t, const EnvT&>),
"a type convertible to cudaStream_t must have a const-qualified conversion operator to be usable "
"as a DeviceFor environment");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unfortunately not valid. We allow user to provide environments without a stream and are falling back to a default stream

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah kk, I removed the assert and added a test pinning the default-stream fallback for these types instead here.

Comment on lines -171 to -172
template <class RandomAccessIteratorT, class NumItemsT, class OpT>
[[nodiscard]] CUB_RUNTIME_FUNCTION static cudaError_t __for_each_n(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical: This overload cannot be removed. The intention here is to query for the necessary temporary storage size.

The overload needs to be updated to take a const _Env&

@macdonaldezra macdonaldezra Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof, yup, I mistakenly thought this was dead code. I updated the function and added a test case for the overload update in this commit.

Comment thread cub/cub/device/device_for.cuh
@github-project-automation github-project-automation Bot moved this from In Review to In Progress in CCCL Aug 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cbd4e601-3346-4d85-9f7c-1677215a9eb4

📥 Commits

Reviewing files that changed from the base of the PR and between 577e221 and 3201778.

📒 Files selected for processing (2)
  • cub/cub/device/device_for.cuh
  • cub/test/catch2_test_device_for_env.cu

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Comment thread cub/test/catch2_test_device_for_env.cu
@macdonaldezra
macdonaldezra requested a review from miscco August 26, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

3 participants