Use thrust::is_contiguous_iterator_v over cuda::std::contiguous_iterator - #9894
Use thrust::is_contiguous_iterator_v over cuda::std::contiguous_iterator#9894bernhardmgruber wants to merge 3 commits into
thrust::is_contiguous_iterator_v over cuda::std::contiguous_iterator#9894Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughCUB load and store paths now use Thrust’s contiguous-iterator trait. Cache-modified iterator construction uses the trait and ChangesContiguous iterator trait migration
Suggested reviewers: Merge Risk: 🔵 Low · up to The PR changes contiguous-iterator handling and has a bounded include-hygiene follow-up to make the dependency on address conversion explicit and remove an unused include. It is otherwise mergeable with owner awareness. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
cub/cub/block/block_load.cuh (1)
1014-1017: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winsuggestion: Align both vectorization docs with the new selection rule. The implementation now uses Thrust’s contiguous-iterator trait plus
__can_to_address, so the existing “simple pointer” restrictions are stale.
cub/cub/block/block_load.cuh#L1014-L1017: update the BlockLoad vectorization requirements.cub/cub/block/block_store.cuh#L843-L846: update the BlockStore vectorization requirements. (raw.githubusercontent.com)cub/cub/iterator/cache_modified_input_iterator.cuh (1)
230-234: 🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy liftsuggestion: Validate the broadened iterator-unwrapping contract. This branch now admits additional Thrust pointer-like iterators, but still derives the base pointer through
raw_pointer_cast(&*it)and leaves a FIXME for a dedicated unwrap facility. Add compile coverage for the newly accepted iterator types and either adopt the supported unwrap operation or document why this expression is valid for every trait-positive type. (raw.githubusercontent.com)
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 9ae78556-04bf-4cfb-8ab5-2b87557b17f4
📒 Files selected for processing (6)
cub/cub/agent/agent_find.cuhcub/cub/block/block_load.cuhcub/cub/block/block_store.cuhcub/cub/iterator/cache_modified_input_iterator.cuhcub/cub/thread/thread_load.cuhcub/cub/thread/thread_store.cuh
This comment has been minimized.
This comment has been minimized.
f84862e to
1fadbdf
Compare
There was a problem hiding this comment.
Can we not just extend cuda::std::contiguous_iterator to cover these cases? Looking at the definition of thrust::is_contiguous_iterator_v:
template <typename Iterator>
inline constexpr bool is_contiguous_iterator_impl_v =
::cuda::std::contiguous_iterator<Iterator> || is_thrust_pointer_v<Iterator> || is_libcxx_wrap_iter_v<Iterator>
|| is_libstdcxx_normal_iterator_v<Iterator> || is_msvc_contiguous_iterator_v<Iterator>
|| proclaim_contiguous_iterator<Iterator>::value;The stdlib ones are OK (and correct even as a transparent extension) while is_thrust_pointer_v should be similarly doable since we can change the thrust pointer definitions to themselves proclaim contiguousness via the normal ways.
I think the only ones we wouldn't be able to do is proclaim_contiguous_iterator<Iterator>, but maybe we should provide a cuda::contiguous_iterator concept that covers this in addition?
cc @miscco
We cannot do that under any circumstances The only thing we can and should do is introduce an extended version of it under a different name. I believe we should rather use the standard |
This comment has been minimized.
This comment has been minimized.
| // 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) && (::cuda::std::contiguous_iterator<InputIteratorT>) | ||
| (VecSize > 1) && (ItemsPerThread % VecSize == 0) && (THRUST_NS_QUALIFIER::is_contiguous_iterator_v<InputIteratorT>) |
There was a problem hiding this comment.
I am not sure whether this is something we really want in the long run. We should rather make sure that to_address works properly
At the same time we do need to worry about cache modified iterators
| else if constexpr (THRUST_NS_QUALIFIER::is_contiguous_iterator_v<RandomAccessIterator> | ||
| && ::cuda::std::__can_to_address<RandomAccessIterator>) |
There was a problem hiding this comment.
I believe this is actually too much ^^
contiguous_iterator already requires to_address, so I believe the solution here is to just check for to_address. We can be a bit saver and also require random_access operations though
| else if constexpr (THRUST_NS_QUALIFIER::is_contiguous_iterator_v<RandomAccessIterator> | |
| && ::cuda::std::__can_to_address<RandomAccessIterator>) | |
| else if constexpr (::cuda::std::__has_random_access_traversal<RandomAccessIterator> | |
| && ::cuda::std::__can_to_address<RandomAccessIterator>) |
There was a problem hiding this comment.
Wait, why don't we just require cuda::std::__has_contiguous_traversal here? Wouldn't that solve our problem?
There was a problem hiding this comment.
While working on #10734 I realized that to_address works for too many types. For example, we __can_to_address<reverse_iterator<...>> but turning that into a pointer to read from the underlying memory does not preserve the right semantics. So I think we need to check for is_contiguous_iterator_v. But checking __can_to_address additionally is too much.
| if constexpr (THRUST_NS_QUALIFIER::is_contiguous_iterator_v<OutputIteratorT> | ||
| && ::cuda::std::__can_to_address<OutputIteratorT>) |
There was a problem hiding this comment.
Ditto this should probably just be
| if constexpr (THRUST_NS_QUALIFIER::is_contiguous_iterator_v<OutputIteratorT> | |
| && ::cuda::std::__can_to_address<OutputIteratorT>) | |
| if constexpr (::cuda::std::__has_random_access_traversal<OutputIteratorT> | |
| && ::cuda::std::__can_to_address<OutputIteratorT>) |
…erator` The former trait includes more types that we can turn into pointers
…tors With is_contiguous_iterator_v now matching thrust fancy iterators (e.g. normal_iterator<device_ptr<T>>), AgentDifference constructed its LoadIt directly from the raw input iterator, which no longer converts. Build it through try_make_cache_modified_iterator instead, and unwrap contiguous iterators via unwrap_contiguous_iterator (to_address) rather than raw_pointer_cast(&*it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1fadbdf to
fc45b0c
Compare
|
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. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
cub/cub/iterator/cache_modified_input_iterator.cuh (1)
25-27: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winimportant: Include
<cuda/std/__memory/pointer_traits.h>directly forcuda::std::to_address, and remove the unused<thrust/type_traits/unwrap_contiguous_iterator.h>include.Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 6831412c-c2a4-4ddb-9e46-9cb10d534f11
📒 Files selected for processing (3)
cub/cub/block/block_load.cuhcub/cub/block/block_store.cuhcub/cub/iterator/cache_modified_input_iterator.cuh
🚧 Files skipped from review as they are similar to previous changes (2)
- cub/cub/block/block_store.cuh
- cub/cub/block/block_load.cuh
Included review availability: Your plan includes up to 12 reviews per rolling hour; 8 remain after this review.
⏱️ CCCL compile-time benchmark comparison: Public headers compile-time benchResult: 0 regression row(s), 2 improvement row(s) above threshold.
Artifacts: reports and traces Direct file processing
🟢 Direct file processing — Improvements
|
🥳 CI Workflow Results🟩 Finished in 2h 54m: Pass: 100%/272 | Total: 13d 00h | Max: 2h 54m | Hits: 13%/1251260See results here. |
The former trait includes more types that we can turn into pointers