Skip to content

[CUB] Use the vectorized load machinery in AgentFind - #12216

Open
miscco wants to merge 1 commit into
vectorized_agent_reducefrom
vectorized_agent_find
Open

miscco wants to merge 1 commit into
vectorized_agent_reducefrom
vectorized_agent_find

Conversation

@miscco

@miscco miscco commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

This uses the new machinery only on find


Stack created with GitHub Stacks CLI • Give Feedback 💬

@miscco
miscco requested a review from a team as a code owner October 23, 2026 12:39
@miscco
miscco requested review from gonidelis and removed request for a team October 23, 2026 12:39
@github-project-automation github-project-automation Bot moved this to Todo in CCCL Oct 23, 2026
@cccl-authenticator-app cccl-authenticator-app Bot moved this from Todo to In Review in CCCL Oct 23, 2026
@miscco
miscco added this pull request to stack #12219 October 23, 2026 12:39
@miscco
miscco requested a review from a team as a code owner October 23, 2026 12:43
@miscco
miscco requested a review from griwes October 23, 2026 12:43
@miscco
miscco force-pushed the vectorized_agent_find branch from bc2248b to fcbff2f Compare October 23, 2026 12:43
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

📝 Summary

Summary by CodeRabbit

  • Refactor
    • Updated internal input processing for certain eligible data types. This is an implementation-level change; no user-facing behavior changes are noted. The release does not add or remove any documented capabilities, and no changes to public interfaces are reported.

AgentFind now uses CUDA’s byte-oriented vector type for vectorized loads. Vectorization eligibility excludes volatile input values. The alignment check and vectorized load use the class-level vector type.

Changes: AgentFind vectorization

Layer / File(s) Summary
Vector type and vectorization conditions
cub/cub/agent/agent_find.cuh
VectorT now uses cuda::__as_bytes_vectorized_t. Vectorization eligibility requires contiguous iterators and trivially copyable, non-volatile input values. The alignment check and vectorized-load path use the class-level VectorT.

Suggested reviewers: bernhardmgruber

Priority: Low

Change: Refactor

Merge Risk: Low · up to 96300

AgentFind can fail to compile for volatile pointer inputs; guard the iterator reference before merging.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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: 1


ℹ️ Review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 07211fb and fcbff2f.

📒 Files selected for processing: 1
  • cub/cub/agent/agent_find.cuh

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 4 remain after this review.

Comment thread cub/cub/agent/agent_find.cuh Outdated
Comment on lines +40 to +48
// Cache modified loads are at most 16 bytes wide, so they gain nothing from a stricter alignment
using VectorT = ::cuda::__as_bytes_vectorized_t<InputT, VecSize>;

static constexpr int tile_size = ThreadsPerBlock * ItemsPerThread;

// Can vectorize according to the policy if the input iterator is a native pointer to a primitive type
static constexpr bool attempt_vectorization =
(VecSize > 1) && (ItemsPerThread % VecSize == 0) && (THRUST_NS_QUALIFIER::is_contiguous_iterator_v<InputIteratorT>)
&& ::cuda::is_trivially_copyable_v<InputT>;
&& ::cuda::is_trivially_copyable_v<InputT> && ::cuda::__is_vectorizable<InputT>();

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

git diff --find-renames 07211fb006a72bcb8a4e628d78214d1fed311934 fcbff2fed03c788fd594491093f7137b49274a39 -- cub/cub/agent/agent_find.cuh
sed -n '1,125p' cub/cub/agent/agent_find.cuh
rg -n "__as_bytes_vectorized_t|__is_vectorizable|LoadDirectBlockedVectorized" cub cuda include 2>/dev/null | head -120

Repository: NVIDIA/cccl

Length of output: 9215


🏁 Script executed:

set -eu
printf '%s\n' '--- as_bytes_vectorized and trait definitions ---'
rg -n -F --glob '*.h' --glob '*.cuh' -e '__as_bytes_vectorized_t' -e '__is_vectorizable' cuda libcudacxx cub | head -120
for f in $(rg -l -F --glob '*.h' --glob '*.cuh' -e '__as_bytes_vectorized_t' cuda libcudacxx 2>/dev/null | head -10); do
  echo "--- $f"
  sed -n '1,240p' "$f"
done
printf '%s\n' '--- CubVector definition ---'
rg -n -F -- 'struct CubVector' cub/cub
rg -n -F -- 'CubVector<' cub/cub/detail cub/cub/agent/agent_find.cuh | head -40
printf '%s\n' '--- complete AgentFind implementation ---'
nl -ba cub/cub/agent/agent_find.cuh | sed -n '1,210p'
printf '%s\n' '--- AgentFind instantiations and iterator contracts ---'
rg -n -F --glob '*.cuh' --glob '*.cu' -e 'detail::find::agent_t' -e 'find::agent_t' -e 'AgentFind' cub/test cub/cub | head -160
printf '%s\n' '--- vectorized load implementation ---'
nl -ba cub/cub/block/block_load.cuh | sed -n '175,295p'

Repository: NVIDIA/cccl

Length of output: 35784


🏁 Script executed:

set -eu
printf '%s\n' '--- CacheModifiedInputIterator ---'
rg -n -F -- 'class CacheModifiedInputIterator' cub/cub/iterator
f=$(rg -l -F -- 'class CacheModifiedInputIterator' cub/cub/iterator | head -1)
nl -ba "$f" | sed -n '1,230p'
printf '%s\n' '--- alignment predicate ---'
rg -n -F -- 'is_aligned' libcudacxx/include/cuda/__memory cub/cub | head -80
for f in $(rg -l -F -- 'is_aligned' libcudacxx/include/cuda/__memory 2>/dev/null | head -10); do
  echo "--- $f"
  nl -ba "$f" | sed -n '1,180p'
done
printf '%s\n' '--- comparable AgentReduce vector load ---'
nl -ba cub/cub/agent/agent_reduce.cuh | sed -n '180,285p'
printf '%s\n' '--- AgentFind base and current diff ---'
git show 07211fb006a72bcb8a4e628d78214d1fed311934:cub/cub/agent/agent_find.cuh | nl -ba | sed -n '25,155p'
git diff --find-renames 07211fb006a72bcb8a4e628d78214d1fed311934 fcbff2fed03c788fd594491093f7137b49274a39 -- cub/cub/agent/agent_find.cuh
printf '%s\n' '--- vector alias uses and AgentFind callers ---'
rg -n -F --glob '*.cuh' --glob '*.cu' -e 'agent_t<' -e 'agent_t::' -e 'AgentFind' cub | head -200

Repository: NVIDIA/cccl

Length of output: 38706


🏁 Script executed:

set -eu
printf '%s\n' '--- AgentFind policy and dispatch ---'
nl -ba cub/cub/device/dispatch/dispatch_find.cuh | sed -n '1,150p'
rg -n -F --glob '*.cuh' --glob '*.cu' -e 'AgentFindPolicy' -e 'VECTOR_LOAD_LENGTH' -e 'agent_t<' -e 'PolicyHub' cub/cub/device cub/cub/agent | head -240
printf '%s\n' '--- CubVector definition ---'
nl -ba cub/cub/detail/cub_vector.cuh | sed -n '1,210p'
printf '%s\n' '--- ThreadLoad implementation ---'
rg -n -F -- 'ThreadLoad' cub/cub/thread/thread_load.cuh | head -40
nl -ba cub/cub/thread/thread_load.cuh | sed -n '1,260p'
printf '%s\n' '--- alignment validation ---'
nl -ba libcudacxx/include/cuda/__memory/is_valid_alignment.h | sed -n '1,130p'
printf '%s\n' '--- AgentFind policy declarations ---'
rg -n -F --glob '*.cuh' --glob '*.cu' -e 'find_policy' -e 'FindPolicy' -e 'AgentFind' cub | head -240

Repository: NVIDIA/cccl

Length of output: 41935


🏁 Script executed:

set -eu
printf '%s\n' '--- Find tuning policies ---'
nl -ba cub/cub/device/dispatch/tuning/tuning_find.cuh | sed -n '1,180p'
printf '%s\n' '--- full CubVector type declarations ---'
nl -ba cub/cub/detail/cub_vector.cuh | sed -n '20,190p'
printf '%s\n' '--- remaining ThreadLoad implementation ---'
nl -ba cub/cub/thread/thread_load.cuh | sed -n '255,390p'
printf '%s\n' '--- Find policy tests/custom policy values ---'
nl -ba cub/test/catch2_test_device_find_env_api.cu | sed -n '95,160p'
rg -n -F --glob '*.cuh' --glob '*.cu' -e 'FindIfPolicy<' -e 'vec_size' cub/cub/device/dispatch/tuning cub/test/catch2_test_device_find* | head -180

Repository: NVIDIA/cccl

Length of output: 28769


important: Use alignof(VectorT) for the alignment check.

If a custom FindIfPolicy sets vec_size to 3, InputT = float passes the vectorization gate and VectorT has size 12. cuda::is_aligned requires a power-of-two alignment, so passing sizeof(VectorT) can trigger its assertion and applies an invalid alignment mask.

Suggested fix
-      return full_tile && ::cuda::is_aligned(d_in + tile_offset, sizeof(VectorT));
+      return full_tile && ::cuda::is_aligned(d_in + tile_offset, alignof(VectorT));

@github-actions

This comment has been minimized.

@miscco
miscco force-pushed the vectorized_agent_find branch 2 times, most recently from 4ad1d95 to 8c405cb Compare October 24, 2026 17:35
@github-actions

This comment has been minimized.

@miscco
miscco force-pushed the vectorized_agent_find branch from 8c405cb to ccf7112 Compare October 26, 2026 09:25
Load vectors of `cuda::__as_bytes_vectorized_t` instead of `CubVector` and only attempt to vectorize types that are not more aligned than the widest vector access. The vector type is now only defined once at class scope.
@miscco
miscco force-pushed the vectorized_agent_find branch from ccf7112 to 9630079 Compare October 26, 2026 09:26

@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
Commits

Reviewing files that changed from the base of the PR and between 8c405cb and 9630079.

Files selected for processing: 1
  • cub/cub/agent/agent_find.cuh

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 9 remain after this review.

static constexpr bool attempt_vectorization =
(VecSize > 1) && (ItemsPerThread % VecSize == 0) && (THRUST_NS_QUALIFIER::is_contiguous_iterator_v<InputIteratorT>)
&& ::cuda::is_trivially_copyable_v<InputT>;
&& ::cuda::is_trivially_copyable_v<InputT> && !::cuda::std::is_volatile_v<InputT>;

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.

Minor · Functional Correctness · Quick win

🔎 Supported by static analysis

Script executed:

git diff --find-renames b01a64d1a43bc665f3973058e583474c61c08eaf3 963007903d25758fbed9cd269c35faf3b5e7f22f -- cub/cub/agent/agent_find.cuh
sed -n '1,125p' cub/cub/agent/agent_find.cuh
rg -n 'CacheModifiedInputIterator|LoadDirectBlockedVectorized|__as_bytes_vectorized_t|iterator_traits' cub/cub/agent libcudacxx/include/cuda/std/__iterator libcudacxx/include/cuda 2>/dev/null | head -240

Repository: NVIDIA/cccl

Length of output: 39114


Script executed:

set -eu
printf '%s\n' '--- iterator_traits raw pointer specialization ---'
nl -ba libcudacxx/include/cuda/std/__iterator/iterator_traits.h | sed -n '480,515p'
printf '%s\n' '--- contiguous iterator trait binding ---'
rg -n -F --glob '*.{h,hpp,cuh,cpp}' -e 'is_contiguous_iterator' thrust libcudacxx cub | head -80
printf '%s\n' '--- CacheModifiedInputIterator declaration and load path ---'
rg -n -F --glob '*.{h,hpp,cuh}' -e 'class CacheModifiedInputIterator' -e 'struct CacheModifiedInputIterator' -e 'operator[]' cub/cub/iterator/cache_modified_input_iterator.cuh cub/cub/thread/thread_load.cuh
nl -ba cub/cub/iterator/cache_modified_input_iterator.cuh | sed -n '1,220p'
nl -ba cub/cub/thread/thread_load.cuh | sed -n '1,180p'
printf '%s\n' '--- byte-vectorized type definition ---'
nl -ba libcudacxx/include/cuda/__memory/as_bytes_vectorized.h | sed -n '1,180p'
printf '%s\n' '--- AgentFind complete relevant block ---'
nl -ba cub/cub/agent/agent_find.cuh | sed -n '30,125p'

Repository: NVIDIA/cccl

Length of output: 38739


Script executed:

set -eu
printf '%s\n' '--- contiguous iterator implementation ---'
nl -ba thrust/thrust/type_traits/is_contiguous_iterator.h | sed -n '70,140p'
printf '%s\n' '--- ThreadLoad overloads and generic dispatch ---'
nl -ba cub/cub/thread/thread_load.cuh | sed -n '170,390p'
printf '%s\n' '--- CacheModifiedInputIterator contiguous unwrap helper ---'
nl -ba cub/cub/iterator/cache_modified_input_iterator.cuh | sed -n '220,250p'

Repository: NVIDIA/cccl

Length of output: 19586


Script executed:

set -eu
if command -v g++ >/dev/null 2>&1; then
  cat >/tmp/volatile_reinterpret_cast_probe.cpp <<'EOF'
struct V {};
void f(volatile int* p) {
  auto q = reinterpret_cast<const V*>(p);
  (void)q;
}
EOF
  if g++ -std=c++17 -fsyntax-only /tmp/volatile_reinterpret_cast_probe.cpp >/tmp/volatile_probe.out 2>&1; then
    echo 'g++ accepted the cv-removing reinterpret_cast'
  else
    echo 'g++ rejected the cv-removing reinterpret_cast'
    cat /tmp/volatile_probe.out
  fi
else
  echo 'g++ unavailable'
fi
printf '%s\n' '--- AgentFind dispatch to ConsumeTile ---'
rg -n -F -- 'ConsumeTile(' cub/cub/agent/agent_find.cuh
nl -ba cub/cub/agent/agent_find.cuh | sed -n '120,230p'

Repository: NVIDIA/cccl

Length of output: 4104


important: Guard against volatile iterator references.

For volatile T*, value_type is non-volatile, but reference is volatile T&, so attempt_vectorization remains true. Process can select the vectorized ConsumeTile branch, where reinterpret_cast<const VectorT*>(d_in + ...) removes volatile. This cast is ill-formed, so the volatile specialization can fail to compile rather than perform a non-volatile read.

Check remove_reference_t<typename iterator_traits<InputIteratorT>::reference> instead. Checking the pointee type is equivalent for native pointers, but the iterator reference is the correct generic check.

@github-actions

Copy link
Copy Markdown
Contributor

🥳 CI Workflow Results

🟩 Finished in 3h 15m: Pass: 100%/210 | Total: 9d 21h | Max: 3h 15m | Hits: 40%/1288695

See results here.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

1 participant