Skip to content

[STF] Drive parallel_for and data placement from structured partitions#9808

Merged
caugonnet merged 18 commits into
NVIDIA:mainfrom
caugonnet:stf-cute-parallel-for
Jul 17, 2026
Merged

[STF] Drive parallel_for and data placement from structured partitions#9808
caugonnet merged 18 commits into
NVIDIA:mainfrom
caugonnet:stf-cute-parallel-for

Conversation

@caugonnet

@caugonnet caugonnet commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Description

Built on #9804, now merged. This PR contains only the six compute-integration follow-up commits.

This completes the "one object drives compute and data" arc of #9804: the same user-facing ctx.parallel_for(partitioner, place, shape, deps…) now accepts a cute_partition instance, which decides both the per-place kernel decomposition and (through the task's affine composite data place) the physical placement of the data those kernels touch.

  • Stateful partitioners through the existing entry point. The machinery was generic in shape but assumed statelessness at three points: the instance was dropped, apply() was invoked as a static, and the composite data place was default-constructed. The instance is now kept ([[no_unique_address]], an empty stand-in for the partitioner-less case) and used at both sites. The classic partitioners compile through the identical path (static-through-instance invocation) — no behavior change for any existing parallel_for.
  • Predicated iteration (the CuTe predication idiom): cute_partition::apply() returns a trivially-copyable cute_sub_shape enumerating the place's own coordinates, with per-dimension [lo, hi) bounds consumed by a contains() predicate that the parallel_for loops honor when a shape provides one (if constexpr on a trait — codegen for existing shapes is unchanged). This handles padding phantoms (uneven extents work end to end) and interior regions (apply(box, place): the box is a region within the tensor the partition was built for, containment-validated; each place iterates its owned coordinates restricted to the box, keeping compute aligned with data ownership). SASS-verified: kernels contain zero calls — decode, predicate and body are one flat inlined stream, the predicate being a handful of ISETPs against an iteration dominated by the pre-existing decode divmods.
  • Slice data interfaces route partition-backed composite places to a direct localized_array allocation (a stateful owner cannot use the fn-pointer-keyed recycling cache; such arrays park in the cache at deallocation and free at finalization — recycling them is a recorded follow-up). is_composite() becomes a virtual on data_place_interface (was typeid-exact).
  • fdtd_mgpu adapted as the demonstration: one make_partition call decides which dimension splits for all ten tasks — init over the full shape, updates over interior boxes, the source point — and the same object places the data. Changing the split dimension is editing one spec entry, which the classic blocked_partition (last-dimension-only) cannot express.
  • Boundary/thin regions: deliberately not solved with per-place interval intersection (it would force per-dimension ownership knowledge into the policy-agnostic leaf representation). The supported pattern — iterate the face with a classic scale-free partitioner while explicit deps keep placement on the partition's composite — is test-guarded, including the structural-equality property it relies on (separately constructed composites compare equal → single instance identity).

Tests: cudax/test/stf/places/cute_parallel_for.cu — 1-D blocked, 3-D dimension-1 split, classic partitioner passthrough, uneven extents through the runtime, interior region with untouched boundary, and the mixed boundary pattern.

Recorded follow-ups: run-structured decode in cute_sub_shape (amortizes the per-element divmods — the dominant arithmetic per the SASS), recycling partition-backed arrays in the composite cache, optionally_static leaf/extent refinement.

Checklist

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

🤖 Generated with Claude Code

@caugonnet
caugonnet requested review from a team as code owners July 13, 2026 08:03
@caugonnet
caugonnet requested a review from ericniebler July 13, 2026 08:03
@github-project-automation github-project-automation Bot moved this to Todo in CCCL Jul 13, 2026
@caugonnet
caugonnet requested a review from griwes July 13, 2026 08:03
@copy-pr-bot

copy-pr-bot Bot commented Jul 13, 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.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

The PR refactors CuTe partitions into typed partitions and runtime descriptors, integrates stateful partitioning and predicate-aware regions into STF parallel_for, adds geometry-aware composite caching, updates examples, and expands tests and documentation.

Structured partition execution

Layer / File(s) Summary
Typed partition and placement core
cudax/include/cuda/experimental/__places/cute_partition.cuh, cudax/include/cuda/experimental/__stf/internal/stf_places_extended_exports.cuh
Adds typed partition specifications, runtime descriptors, ownership decoding, comparison, builders, and composite-place support.
Stateful parallel_for and predicate-aware shapes
cudax/include/cuda/experimental/__stf/internal/backend_ctx.cuh, cudax/include/cuda/experimental/__stf/internal/parallel_for_scope.cuh, cudax/include/cuda/experimental/__stf/internal/slice.cuh, cudax/include/cuda/experimental/__stf/utility/dimensions.cuh, cudax/examples/stf/custom_data_interface.cu
Forwards partition instances through execution scopes, applies per-place sub-shapes, skips coordinates outside predicates, and uses CUDA standard-library coordinate arrays.
Geometry-aware composite allocation cache
cudax/include/cuda/experimental/__places/data_place_interface.cuh, cudax/include/cuda/experimental/__places/places.cuh, cudax/include/cuda/experimental/__stf/localization/composite_slice.cuh, cudax/include/cuda/experimental/__stf/graph/interfaces/slice.cuh, cudax/include/cuda/experimental/__stf/stream/interfaces/slice.cuh
Adds polymorphic composite detection, partition-aware cache entries, dimension validation, and updated graph and stream cache calls.
Partition-backed examples
cudax/examples/stf/fdtd_mgpu.cu, cudax/examples/stf/partitioned_axpy.cu
Uses explicit typed partitions for FDTD field allocation and execution, and updates AXPY partition construction to partition_spec helpers.
Partition validation and usage documentation
cudax/test/places/placement.cu, cudax/test/stf/places/cute_parallel_for.cu, cudax/test/stf/CMakeLists.txt, docs/cudax/places.rst, cudax/include/cuda/experimental/__places/cute_partition.cuh
Adds coverage for partition execution, cache reuse, padding, regions, graph execution, and descriptor semantics, and documents structured partition usage.ғ

Possibly related PRs

  • NVIDIA/cccl#9804: Refactors the same cute_partition and partition-spec machinery and related STF placement paths.
  • NVIDIA/cccl#9892: Exposes related structured-partition and placement functionality through STF C APIs and Python bindings.

Suggested labels: places

Suggested reviewers: ericniebler, griwes


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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8af68fc3-d748-4a5e-8ae9-14231140e485

📥 Commits

Reviewing files that changed from the base of the PR and between 6992cf8 and a381119.

📒 Files selected for processing (20)
  • cudax/examples/places/thrust_device_data_place_allocator.cu
  • cudax/examples/stf/CMakeLists.txt
  • cudax/examples/stf/fdtd_mgpu.cu
  • cudax/examples/stf/partitioned_axpy.cu
  • cudax/include/cuda/experimental/__places/cute_partition.cuh
  • cudax/include/cuda/experimental/__places/data_place_interface.cuh
  • cudax/include/cuda/experimental/__places/localized_array.cuh
  • cudax/include/cuda/experimental/__places/places.cuh
  • cudax/include/cuda/experimental/__stf/graph/interfaces/slice.cuh
  • cudax/include/cuda/experimental/__stf/internal/backend_ctx.cuh
  • cudax/include/cuda/experimental/__stf/internal/parallel_for_scope.cuh
  • cudax/include/cuda/experimental/__stf/internal/stf_places_extended_exports.cuh
  • cudax/include/cuda/experimental/__stf/stream/interfaces/slice.cuh
  • cudax/include/cuda/experimental/__stf/utility/dimensions.cuh
  • cudax/include/cuda/experimental/places.cuh
  • cudax/test/places/CMakeLists.txt
  • cudax/test/places/placement.cu
  • cudax/test/stf/CMakeLists.txt
  • cudax/test/stf/places/cute_parallel_for.cu
  • docs/cudax/places.rst

Comment thread cudax/examples/stf/partitioned_axpy.cu
Comment thread cudax/include/cuda/experimental/__stf/graph/interfaces/slice.cuh Outdated

@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: 1eb5f8a2-b5cd-4232-8645-4f38167b6452

📥 Commits

Reviewing files that changed from the base of the PR and between a381119 and 105f228.

📒 Files selected for processing (1)
  • docs/cudax/places.rst

Comment thread docs/cudax/places.rst Outdated
@caugonnet caugonnet self-assigned this Jul 15, 2026
@caugonnet caugonnet added the stf Sequential Task Flow programming model label Jul 15, 2026
@caugonnet
caugonnet force-pushed the stf-cute-parallel-for branch from 47c75f0 to 6a6fb2e Compare July 16, 2026 07:29

@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

🧹 Nitpick comments (3)
cudax/include/cuda/experimental/__stf/graph/interfaces/slice.cuh (2)

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

suggestion: Add <functional> directly. Line 124 uses ::std::function; this header must not rely on transitive includes. As per coding guidelines, “Include all headers needed by the symbols being used; do not rely on transitive includes.”

Source: Coding guidelines


101-131: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

suggestion: Declare unmodified locals const, including delinearize, cute_place, part, and cute_base. As per coding guidelines, “All variables that are not modified must be declared const.”

Source: Coding guidelines

cudax/test/stf/CMakeLists.txt (1)

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

suggestion: Add a graph_ctx structured-partition test. places/cute_parallel_for.cu exercises stream_ctx, while this PR adds a separate graph allocation branch in slice_graph_interface; graph-only failures remain untested. As per path instructions, cudax reviews must focus on correctness and tests.

Source: Path instructions


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c9639889-676a-41b9-b0d6-0f0fab484257

📥 Commits

Reviewing files that changed from the base of the PR and between 47c75f0 and 6a6fb2e.

📒 Files selected for processing (20)
  • cudax/examples/places/thrust_device_data_place_allocator.cu
  • cudax/examples/stf/CMakeLists.txt
  • cudax/examples/stf/fdtd_mgpu.cu
  • cudax/examples/stf/partitioned_axpy.cu
  • cudax/include/cuda/experimental/__places/cute_partition.cuh
  • cudax/include/cuda/experimental/__places/data_place_interface.cuh
  • cudax/include/cuda/experimental/__places/localized_array.cuh
  • cudax/include/cuda/experimental/__places/places.cuh
  • cudax/include/cuda/experimental/__stf/graph/interfaces/slice.cuh
  • cudax/include/cuda/experimental/__stf/internal/backend_ctx.cuh
  • cudax/include/cuda/experimental/__stf/internal/parallel_for_scope.cuh
  • cudax/include/cuda/experimental/__stf/internal/stf_places_extended_exports.cuh
  • cudax/include/cuda/experimental/__stf/stream/interfaces/slice.cuh
  • cudax/include/cuda/experimental/__stf/utility/dimensions.cuh
  • cudax/include/cuda/experimental/places.cuh
  • cudax/test/places/CMakeLists.txt
  • cudax/test/places/placement.cu
  • cudax/test/stf/CMakeLists.txt
  • cudax/test/stf/places/cute_parallel_for.cu
  • docs/cudax/places.rst
🚧 Files skipped from review as they are similar to previous changes (18)
  • cudax/include/cuda/experimental/places.cuh
  • cudax/include/cuda/experimental/__stf/internal/backend_ctx.cuh
  • cudax/examples/stf/CMakeLists.txt
  • cudax/include/cuda/experimental/__places/data_place_interface.cuh
  • cudax/include/cuda/experimental/__stf/internal/stf_places_extended_exports.cuh
  • docs/cudax/places.rst
  • cudax/examples/places/thrust_device_data_place_allocator.cu
  • cudax/test/places/CMakeLists.txt
  • cudax/examples/stf/fdtd_mgpu.cu
  • cudax/include/cuda/experimental/__stf/utility/dimensions.cuh
  • cudax/test/places/placement.cu
  • cudax/examples/stf/partitioned_axpy.cu
  • cudax/test/stf/places/cute_parallel_for.cu
  • cudax/include/cuda/experimental/__stf/stream/interfaces/slice.cuh
  • cudax/include/cuda/experimental/__places/places.cuh
  • cudax/include/cuda/experimental/__stf/internal/parallel_for_scope.cuh
  • cudax/include/cuda/experimental/__places/localized_array.cuh
  • cudax/include/cuda/experimental/__places/cute_partition.cuh

Comment thread cudax/include/cuda/experimental/__stf/graph/interfaces/slice.cuh Outdated
caugonnet and others added 6 commits July 16, 2026 18:46
The parallel_for machinery was generic over partitioners in shape but
assumed statelessness: the instance received by the public entry point
was dropped, apply() was invoked as a static, and the composite data
place was built by default-constructing a fresh partitioner. Keep the
instance instead ([[no_unique_address]], with an empty stand-in for the
partitioner-less case), invoke apply through it (static-through-
instance keeps the classic partitioners bit-identical), and construct
the composite place from it - via the fn-pointer path when the
partitioner has a static get_executor, or from the stateful object
otherwise.

cute_partition gains the partitioner-contract apply(): it derives the
per-place sub-shape (cute_sub_shape - trivially copyable, iterated by
the existing parallel_for kernels through size()/index_to_coords()).
Restricted to exact covers for now: the shape interface has no notion
of skipping the phantom coordinates padding would introduce, so uneven
extents are rejected with an exception rather than silently computing
on them.

The slice data interfaces route composite places backed by a
structured partition to a direct localized_array allocation (the
stateful owner function cannot use the fn-pointer keyed recycling
cache; recycling such arrays is a recorded follow-up - they are parked
in the cache on deallocation and released at finalization).
is_composite() becomes a virtual on data_place_interface (previously
typeid-exact, which excluded the cute composite).

The user-facing entry point is unchanged: the same
ctx.parallel_for(partitioner, place, shape, deps...) now accepts both
classic partitioners and cute_partition instances, and one partition
object decides both the kernel decomposition and the data placement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Covers 1-D blocked, the motivating 3-D dimension-1 split, the classic
stateless partitioners passing through the same entry unchanged, and
the exact-cover rejection of uneven extents at the apply() contract
level (a partitioner throwing mid-task is not recoverable by design,
so the runtime path is not exercised for the failure case).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extend the cute_partition parallel_for path with the predication idiom
(iterate each place's own coordinates, skip those outside the region)
instead of restructuring iteration:

- cute_sub_shape carries per-dimension [lo, hi) bounds and a contains()
  predicate; the parallel_for loops (device kernels and the host
  callback) skip coordinates outside it when the shape provides one.
- apply() no longer rejects uneven extents: padding phantoms are
  excluded by the predicate, so odd sizes work end to end.
- apply(box, place): the box is a region within the coordinate space of
  the tensor the partition was built for (the partition remains the
  authority on the extents, validated by containment). Each place
  iterates its owned coordinates restricted to the box, keeping the
  compute decomposition aligned with data ownership - unlike scale-free
  partitioners, which split the box itself and misalign with ownership
  at the region edges.

Adapt fdtd_mgpu as the demonstration: one make_partition call decides
which dimension splits for all ten tasks (init over the full shape,
updates over interior boxes, the source point), and the same object
places the data. The test gains uneven-extent and interior-region
coverage, boundary values verified untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Thin regions (boundary faces) invert the predication density trade-off,
and per-place interval intersection is not worth its structural cost
(apply works policy-agnostically on leaves; intersection would need
per-dimension ownership knowledge). The supported pattern is simpler:
iterate the face with a classic scale-free partitioner (tight, no
discarded lanes) while explicit deps keep placement on the cute
composite. This relies on separately constructed cute composites
comparing equal (single instance identity across tasks), which the
test now guards.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The compute-side companion of the structured-partitions section: the
unchanged parallel_for entry point, regions (boxes) within the
partition's tensor, the predication cost model (dense regions yes,
thin regions no), the boundary-update menu, and the fdtd_mgpu
demonstration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The owner lambda called data_dims.index_to_pos() directly, bypassing
the dimensions == 0 guard the shared delinearize helper provides for
scalar slices.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Cedric AUGONNET <caugonnet@nvidia.com>
@caugonnet
caugonnet force-pushed the stf-cute-parallel-for branch from 7369680 to 6a0ecf3 Compare July 16, 2026 17:04
caugonnet and others added 3 commits July 16, 2026 19:11
Reuse CuTe-backed VMM allocations and their prerequisites through a value-keyed cache while preserving the classic partitioner cache path.
Describe value-defined CuTe ownership precisely and centralize the composite-place downcast used by cache operations.
Rely on the STF places bridge instead of repeating redundant namespace imports in the structured-partition coverage.
Reject rank and allocation extent mismatches, avoid dense point-source predication, and cover the graph backend.
Keep rank and leaf counts available to kernel code while erasing partitions only at runtime boundaries, reducing launch state without sacrificing cache or interop support.
@caugonnet

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

caugonnet and others added 2 commits July 17, 2026 08:42
Keep the internal cache protocol on cuda::std types and verify that structured allocations reject equal-size tensors with mismatched shapes.
@caugonnet

Copy link
Copy Markdown
Contributor Author

/ok to test c9dbab9

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cudax/include/cuda/experimental/__places/cute_partition.cuh (1)

1165-1181: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

important: guard the partition padding arithmetic against overflow. e.block * nplaces can wrap to zero, making the following division undefined; the ceil additions and final multiplication can also wrap. Use checked multiplication and overflow-safe ceiling division.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d0eee0b2-3463-4d4c-83b4-71420a595078

📥 Commits

Reviewing files that changed from the base of the PR and between 47c75f0 and 8486a02.

📒 Files selected for processing (18)
  • cudax/examples/stf/custom_data_interface.cu
  • cudax/examples/stf/fdtd_mgpu.cu
  • cudax/examples/stf/partitioned_axpy.cu
  • cudax/include/cuda/experimental/__places/cute_partition.cuh
  • cudax/include/cuda/experimental/__places/data_place_interface.cuh
  • cudax/include/cuda/experimental/__places/places.cuh
  • cudax/include/cuda/experimental/__stf/graph/interfaces/slice.cuh
  • cudax/include/cuda/experimental/__stf/internal/backend_ctx.cuh
  • cudax/include/cuda/experimental/__stf/internal/parallel_for_scope.cuh
  • cudax/include/cuda/experimental/__stf/internal/slice.cuh
  • cudax/include/cuda/experimental/__stf/internal/stf_places_extended_exports.cuh
  • cudax/include/cuda/experimental/__stf/localization/composite_slice.cuh
  • cudax/include/cuda/experimental/__stf/stream/interfaces/slice.cuh
  • cudax/include/cuda/experimental/__stf/utility/dimensions.cuh
  • cudax/test/places/placement.cu
  • cudax/test/stf/CMakeLists.txt
  • cudax/test/stf/places/cute_parallel_for.cu
  • docs/cudax/places.rst
🚧 Files skipped from review as they are similar to previous changes (7)
  • cudax/include/cuda/experimental/__stf/internal/stf_places_extended_exports.cuh
  • cudax/test/places/placement.cu
  • cudax/include/cuda/experimental/__stf/internal/backend_ctx.cuh
  • cudax/examples/stf/fdtd_mgpu.cu
  • cudax/test/stf/CMakeLists.txt
  • cudax/include/cuda/experimental/__stf/internal/parallel_for_scope.cuh
  • cudax/examples/stf/partitioned_axpy.cu

Comment thread cudax/include/cuda/experimental/__places/cute_partition.cuh
Comment thread cudax/test/stf/places/cute_parallel_for.cu Outdated
@github-actions

This comment has been minimized.

Use host standard traits for the coordinate-predicate detector because NVCC 12.0 fails to discard the cuda::std::void_t specialization for shapes without contains().
Reject reversed iteration boxes before dispatch and ensure cache/equality coverage uses independently constructed equivalent partitions.
@caugonnet

Copy link
Copy Markdown
Contributor Author

/ok to test e2f011d

Use overload-based shape predication so NVCC 12 never instantiates a missing contains() member, including inside device lambdas.
@caugonnet

Copy link
Copy Markdown
Contributor Author

/ok to test 7bd0aa1

Use std::pair for the host-only cache API to avoid CUDA 12 compiling event_list's move path for device code.
@caugonnet

Copy link
Copy Markdown
Contributor Author

/ok to test 1d9cd7c

@github-actions

Copy link
Copy Markdown
Contributor

🥳 CI Workflow Results

🟩 Finished in 1h 10m: Pass: 100%/57 | Total: 1d 04h | Max: 1h 10m | Hits: 13%/187274

See results here.

@caugonnet
caugonnet merged commit e7a624b into NVIDIA:main Jul 17, 2026
75 of 78 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stf Sequential Task Flow programming model

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants