Skip to content

[cuco] Adds support for 1 and 2 byte key and value types in fixed_capacity_map - #10025

Open
ryanjspears wants to merge 5 commits into
NVIDIA:mainfrom
ryanjspears:small-key-types-cuco
Open

[cuco] Adds support for 1 and 2 byte key and value types in fixed_capacity_map#10025
ryanjspears wants to merge 5 commits into
NVIDIA:mainfrom
ryanjspears:small-key-types-cuco

Conversation

@ryanjspears

Copy link
Copy Markdown
Contributor

Description

Makes progress on #9987

Adds support for 1 and 2 byte key and value types in fixed_capacity_map

The insert and contains tests now cover 1 and 2 byte types and dynamically assign the number of keys based on byte size. This is needed because 400 could not fit into 1 byte, thus needs to be changed accordingly.

Checklist

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

@copy-pr-bot

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

@github-project-automation github-project-automation Bot moved this to Todo in CCCL Jul 20, 2026
@cccl-authenticator-app cccl-authenticator-app Bot moved this from Todo to In Progress in CCCL Jul 20, 2026
@ryanjspears
ryanjspears force-pushed the small-key-types-cuco branch from 2eb1181 to df921f8 Compare July 20, 2026 19:39
@ryanjspears
ryanjspears marked this pull request as ready for review July 20, 2026 19:41
@ryanjspears
ryanjspears requested a review from a team as a code owner July 20, 2026 19:41
@ryanjspears
ryanjspears requested a review from caugonnet July 20, 2026 19:41
@cccl-authenticator-app cccl-authenticator-app Bot moved this from In Progress to In Review in CCCL Jul 20, 2026
@coderabbitai

coderabbitai Bot commented Jul 20, 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

fixed_capacity_map now supports smaller size-compatible key/value types, derives exact-width packed CAS operands, and adds positive and expected-failure compile-time coverage for size constraints.

Packed map type support

Layer / File(s) Summary
Packed type constraints and representation
cudax/include/cuda/experimental/__cuco/detail/open_addressing/open_addressing_ref_impl.cuh, cudax/include/cuda/experimental/__cuco/fixed_capacity_map_ref.cuh
packed_cas derives its unsigned operand type from value bit width. fixed_capacity_map_ref allows mapped types up to eight bytes and requires power-of-two key and pair sizes.
Expanded fixed-capacity map coverage
cudax/test/cuco/fixed_capacity_map/test_insert_and_contains.cu
Tests add 8-bit and 16-bit keys, adjust key-dependent sizing and sentinels, and validate supported slot sizes.
Constraint diagnostic tests
cudax/test/CMakeLists.txt, cudax/test/cuco/fixed_capacity_map/test_*_fail.cu
Expected-failure targets verify diagnostics for non-power-of-two key and slot sizes.

Possibly related PRs

Suggested labels: cuco

Suggested reviewers: caugonnet


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

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/__cuco/detail/open_addressing/open_addressing_ref_impl.cuh (1)

701-710: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

important: device_buffer<__value_type> only guarantees alignof(__value_type), but packed_type can need stricter alignment. Reinterpreting __address, __expected, and __desired as packed_type* is UB for small pair-like slots such as uint8_t/uint8_t or uint16_t/uint16_t. Add an aligned packed contract or gate this path on alignof(__value_type) >= alignof(packed_type).

🧹 Nitpick comments (1)
cudax/test/cuco/fixed_capacity_map/test_insert_and_contains.cu (1)

38-39: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

suggestion: Add mixed-width key/value instantiations. map_type uses key_type for both template arguments, so these cases cover (uint8_t, uint8_t) and (uint16_t, uint16_t) but not the independently changed mapped-type contract, such as 32-bit keys with 8/16-bit values. Add a separate key/value type list or a few explicit mixed-width cases. The supplied map_type alias and new type list show that only same-width pairs are currently exercised.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f4680b6f-be66-4b99-97c2-382fbccbe2b1

📥 Commits

Reviewing files that changed from the base of the PR and between 73a1a4b and df921f8.

📒 Files selected for processing (3)
  • cudax/include/cuda/experimental/__cuco/detail/open_addressing/open_addressing_ref_impl.cuh
  • cudax/include/cuda/experimental/__cuco/fixed_capacity_map_ref.cuh
  • cudax/test/cuco/fixed_capacity_map/test_insert_and_contains.cu

Comment thread cudax/include/cuda/experimental/__cuco/fixed_capacity_map_ref.cuh
Comment thread cudax/test/cuco/fixed_capacity_map/test_insert_and_contains.cu
@ryanjspears
ryanjspears force-pushed the small-key-types-cuco branch 2 times, most recently from ddadb4d to b886248 Compare July 20, 2026 20:36

@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: c9f14394-1f67-4604-9307-997d26e163f6

📥 Commits

Reviewing files that changed from the base of the PR and between df921f8 and ddadb4d.

📒 Files selected for processing (3)
  • cudax/include/cuda/experimental/__cuco/detail/open_addressing/open_addressing_ref_impl.cuh
  • cudax/include/cuda/experimental/__cuco/fixed_capacity_map_ref.cuh
  • cudax/test/cuco/fixed_capacity_map/test_insert_and_contains.cu
🚧 Files skipped from review as they are similar to previous changes (1)
  • cudax/include/cuda/experimental/__cuco/detail/open_addressing/open_addressing_ref_impl.cuh

Comment thread cudax/test/cuco/fixed_capacity_map/test_insert_and_contains.cu Outdated
@ryanjspears
ryanjspears force-pushed the small-key-types-cuco branch from b886248 to da4bc4a Compare July 20, 2026 21:08

@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 (1)
cudax/test/cuco/fixed_capacity_map/test_insert_and_contains.cu (1)

140-149: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

suggestion: Exercise a mixed-width pair through insert and contains, not only sizeof. The <uint8_t, uint32_t> assertion checks map instantiation and layout, but does not execute the packed CAS path where width or representation mismatches would surface.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 81d8afdd-0f78-460f-8331-697a0c6abea1

📥 Commits

Reviewing files that changed from the base of the PR and between b886248 and da4bc4a.

📒 Files selected for processing (6)
  • cudax/include/cuda/experimental/__cuco/detail/open_addressing/open_addressing_ref_impl.cuh
  • cudax/include/cuda/experimental/__cuco/fixed_capacity_map_ref.cuh
  • cudax/test/CMakeLists.txt
  • cudax/test/cuco/fixed_capacity_map/test_insert_and_contains.cu
  • cudax/test/cuco/fixed_capacity_map/test_key_size_fail.cu
  • cudax/test/cuco/fixed_capacity_map/test_slot_size_fail.cu
🚧 Files skipped from review as they are similar to previous changes (2)
  • cudax/include/cuda/experimental/__cuco/fixed_capacity_map_ref.cuh
  • cudax/include/cuda/experimental/__cuco/detail/open_addressing/open_addressing_ref_impl.cuh

Comment thread cudax/test/cuco/fixed_capacity_map/test_key_size_fail.cu
Comment thread cudax/include/cuda/experimental/__cuco/fixed_capacity_map_ref.cuh Outdated
Comment thread cudax/include/cuda/experimental/__cuco/fixed_capacity_map_ref.cuh Outdated
@ryanjspears
ryanjspears force-pushed the small-key-types-cuco branch from da4bc4a to eb7d9a9 Compare July 21, 2026 15:16
@sleeepyjack sleeepyjack added the cuco cuCollections label Jul 21, 2026
@sleeepyjack

Copy link
Copy Markdown
Contributor

Thanks @ryanjspears for working on this!
Note that there is another open PR that might result in some conflicts: #10001 . CC @PointKernel

@PointKernel PointKernel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is probably not a simple task to target right now. The original cuco::pair uses the next power-of-two alignment. Consequently, cuco::pair<int, int> is 8-byte aligned and cuco::pair<int16_t, int16_t> is 4-byte aligned, whereas the corresponding cuda::std::pair types are only 4- and 2-byte aligned.

When possible, cuco packs the key-value pair into a single integer and updates it with packed_cas. For example, a 4-byte key and 4-byte value use one 8-byte atomic CAS, which requires 8-byte alignment, not the 4-byte alignment provided by cuda::std::pair<int, int>. A power-of-two size check alone does not guarantee this alignment. The default allocation may happen to be sufficiently aligned, but external span storage and the local expected and desired objects are not guaranteed to be.

@ryanjspears Thanks for working on this. I haven’t found a clean way to preserve the original slot-alignment guarantee with cuda::std::pair yet, so we should resolve that design question before proceeding with subword support.

@github-project-automation github-project-automation Bot moved this from In Review to In Progress in CCCL Jul 21, 2026
@PointKernel

Copy link
Copy Markdown
Member

@ryanjspears I thought about this more, and I think we have a clean way forward without losing the packed CAS optimization.

Currently, packed_cas accesses the local expected and desired objects through packed_type*, although their declared types do not guarantee the required alignment. We can avoid these potentially misaligned accesses by bit-casting them into packed_type values.

For the storage, we only need to check the base address when constructing the storage reference. The slots are contiguous and sizeof(value_type) == sizeof(packed_type), so if the first slot satisfies atomic_ref<packed_type>::required_alignment, every slot does.

The storage reference can retain that result and use packed_cas only for suitably aligned, bitwise-compatible slot types, falling back to the existing non-packed path otherwise. This preserves the single CAS for common aligned cases such as cuda::std::pair<int, int> while safely supporting external storage.

The resulting dispatch would be approximately:

if constexpr (has_packable_representation)
{
  if (storage_ref.is_packed_cas_aligned())
  {
    return packed_cas(...);
  }
}

return non_packed_cas(...);

Could you please update the PR along these lines?

@ryanjspears

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback @PointKernel. Yes, I will submit an update shortly!

@ryanjspears
ryanjspears force-pushed the small-key-types-cuco branch from 5fec78d to 7d91903 Compare July 24, 2026 21:40
@ryanjspears
ryanjspears requested a review from a team as a code owner July 24, 2026 21:40
@ryanjspears

Copy link
Copy Markdown
Contributor Author

@PointKernel I updated the dispatch to your suggestion. I also created test_misaligned_storage.cu which tests insertions over an under-aligned external storage to hit the non-packed fallback.

@PointKernel

Copy link
Copy Markdown
Member

/ok to test 71d8664

@PointKernel

Copy link
Copy Markdown
Member

@ryanjspears Thanks for the fast turnaround. The code looks great. I just pushed a single line change where the old code checks against __expected while we only update __expected_packed. Will ship it once CI passes.

@ryanjspears

Copy link
Copy Markdown
Contributor Author

Thanks @PointKernel , is there another cuco issue that would be good for me to tackle? Shall I tackle #9989?

@PointKernel

Copy link
Copy Markdown
Member

Thanks @PointKernel , is there another cuco issue that would be good for me to tackle? Shall I tackle #9989?

That will be great!

@PointKernel
PointKernel requested a review from a team as a code owner July 27, 2026 19:37
@PointKernel
PointKernel requested a review from ericniebler July 27, 2026 19:37
{
constexpr uint64_t __alignmask = (sizeof(uint16_t) - 1);
uint16_t* __aligned = (uint16_t*) ((intptr_t) __ptr & (~__alignmask));
uint16_t* __aligned = (uint16_t*) ((intptr_t) __ptr & (~__alignmask)); // NOLINT(performance-no-int-to-ptr)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The new small-type tests expose the existing clang-tidy false positive; atomic behavior is unchanged.

@PointKernel

Copy link
Copy Markdown
Member

/ok to test b6ce4f2

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

Labels

cuco cuCollections

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

5 participants