Skip to content

[libcu++] Fix __is_sequence definition for arguments framework#9271

Open
miscco wants to merge 1 commit into
NVIDIA:mainfrom
miscco:fix_argument_sequence_definition
Open

[libcu++] Fix __is_sequence definition for arguments framework#9271
miscco wants to merge 1 commit into
NVIDIA:mainfrom
miscco:fix_argument_sequence_definition

Conversation

@miscco
Copy link
Copy Markdown
Contributor

@miscco miscco commented Jun 5, 2026

The current is_sequence definition is thoroughly broken. An iterator is not a sequence and neither is a pointer.

The main problem here is that this precludes passing along iterators / pointers as values which is a reasonable use case.

It also completely deviates from any standard handling in C++.

Rather than reinventing the wheel in a bad way use standard terminology to determine what is a range and what not.

A user can always wrap iterators and pointers into views and spans, so there is not need for the current definition

@miscco miscco requested a review from a team as a code owner June 5, 2026 07:17
@miscco miscco requested a review from Jacobfaib June 5, 2026 07:17
@github-project-automation github-project-automation Bot moved this to Todo in CCCL Jun 5, 2026
@cccl-authenticator-app cccl-authenticator-app Bot moved this from Todo to In Review in CCCL Jun 5, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e5ded5c7-3443-4601-bffe-f3dc8a410fdc

📥 Commits

Reviewing files that changed from the base of the PR and between 171cb93 and f13ff25.

📒 Files selected for processing (4)
  • libcudacxx/include/cuda/__argument/argument.h
  • libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp
  • libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp
  • libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp
✅ Files skipped from review due to trivial changes (1)
  • libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp
🚧 Files skipped from review as they are similar to previous changes (3)
  • libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp
  • libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp
  • libcudacxx/include/cuda/__argument/argument.h

Note: CodeRabbit is enabled on this repository as a convenience for maintainers
and contributors. Use your best judgment when considering its review comments and
suggestions — a suggested change may be inadequate, unnecessary, or safe to ignore.
Contributors are not expected to address every comment. Human reviews are what
ultimately matter for merging.

Overview

This PR fixes the __is_sequence trait definition in the arguments framework to correctly identify what constitutes a sequence according to standard C++ terminology. The previous implementation incorrectly treated iterators and pointers as sequences, preventing them from being passed as values. The new definition uses standard-based criteria: a type is a sequence if it is an array or satisfies cuda::std::ranges::range.

Changes

Implementation (libcudacxx/include/cuda/__argument/argument.h)

  • Redefined __is_sequence_v: Changed from element-type-based logic to ::cuda::is_array_v<::cuda::remove_cvref_t<_Tp>> || ::cuda::std::ranges::range<_Tp>, aligning with standard C++ range semantics
  • Removed obsolete helpers: Eliminated __is_single_value_v and __is_iterable_v variable templates that depended on the old element-type machinery
  • Updated __traits_impl<_Tp>::is_single_value: Now defined as !__is_sequence_v<_Tp> instead of using the removed __is_single_value_v
  • Simplified validation dispatch: __immediate_sequence's runtime validation now uses __is_sequence_v directly; __constant_sequence's assertion message was adjusted accordingly

Tests

argument_traits.pass.cpp: Updated compile-time expectations for __is_sequence_v:

  • Pointers, cuda::counting_iterator, and custom wrapper types (range_like, element_type_like, value_type_like) are now correctly classified as not sequences
  • C arrays and standard containers (cuda::std::span, cuda::std::array) remain sequences
  • Added negative coverage for CUDA standard library types that should not be sequences: cuda::std::complex, cuda::std::pair, cuda::std::tuple, cuda::std::optional, cuda::std::expected
  • Updated cuda::__argument::__traits<int*>::is_single_value to expect true instead of false

dynamic_argument.pass.cpp: Inverted assertion in the "unwrapped types" section from __is_single_value_v to !__is_sequence_v

static_argument.pass.cpp: Updated scalar constant traits assertion from __is_single_value_v to !__is_sequence_v

Impact

Users can now correctly pass iterators and pointers as individual values without them being misidentified as sequences. When a sequence type is explicitly needed, users must wrap iterators or pointers using standard view or span types, following standard C++ conventions.

Walkthrough

suggestion: The PR reclassifies sequence detection: a sequence is now an array (after cv/ref removal) or a cuda::std::ranges::range. It removes __is_single_value_v/__is_iterable_v, updates immediate-sequence validation to use __is_sequence_v, and adjusts traits and tests accordingly.

Changes

Argument type classification by ranges::range

Layer / File(s) Summary
Core implementation: sequence and traits reclassification
libcudacxx/include/cuda/__argument/argument.h
Adds range/type-trait includes; redefines __is_sequence_v<_Tp> as `::cuda::std::is_array_v<::cuda::std::remove_cvref_t<_Tp>>
Test validation of classification changes
libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp, libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp, libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp
Updates test includes and static_assert expectations: int*, counting_iterator, and wrapper *_like types are now non-sequences; arrays and span/array remain sequences; inverts several is_single_value checks to use !__is_sequence_v instead of the removed predicate.
  • Possibly related PRs:

    • NVIDIA/cccl#8875: Updates argument.h sequence/single-value trait logic similar to this PR.
    • NVIDIA/cccl#9074: Refactors consumers to rely on ::cuda::__argument::__traits<> affected by these trait changes.
  • Suggested reviewers:

    • ericniebler
    • Jacobfaib
    • gevtushenko

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Infer (1.2.0)
libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp

libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp:11:10: fatal error: 'cuda/_argument' file not found
11 | #include <cuda/argument>
| ^~~~~~~~~~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/f13ff250a89da6bae7e336f74c8f3f19aecde1fb-07842b3345a172fc/tmp/clang_command_.tmp.a0d1ef.txt
++Contents of '/tmp/coderabbit-infer/f13ff250a89da6bae7e336f74c8f3f19aecde1fb-07842b3345a172fc/tmp/clang_command
.tmp.a0d1ef.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64-unknown-li

... [truncated 1169 characters] ...

al-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-fdeprecated-macro" "-ferror-limit" "19" "-fgnuc-version=4.2.1"
"-fskip-odr-check-in-gmf" "-fcxx-exceptions" "-fexceptions"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/07842b3345a172fc/file.o" "-x" "c++"
"libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp" "-O0"
"-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"

libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp

libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp:11:10: fatal error: 'cuda/_argument' file not found
11 | #include <cuda/_argument>
| ^~~~~~~~~~~~~~~~~~
1 error generated.
libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp:161:3-166:3: ERROR translating statement 'CompoundStmt'
Aborting translation of method 'test' in file 'libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp': "Assert_failure src/clang/cAst_utils.ml:249:53"
Uncaught Internal Error: "Assert_failure src/clang/cAst_utils.ml:249:53"
Error backtrace:
Raised at ClangFrontend__CAst_utils.get_decl_from_typ_ptr in file "src/clang/cAst_utils.ml", line 249, characters 53-65
Called from ClangFrontend__CTrans.CTrans_funct.get_destructor_decl_ref in file "src/clang/cTrans.ml", line 658, characters 12-59
Called from ClangFrontend__CTrans.CTrans_funct.destructor_calls.(fun) in file "src/clang/cTrans.ml", line 2048, characters 12-69
Called from Base__List.rev_filter

... [truncated 2200 characters] ...

from ClangFrontend__CTrans.CTrans_funct.exec_with_node_creation in file "src/clang/cTrans.ml" (inlined), line 104, characters 20-38
Called from ClangFrontend__CTrans.CTrans_funct.get_clang_stmt_trans in file "src/clang/cTrans.ml" (inlined), line 5395, characters 4-69
Called from ClangFrontend__CTrans.CTrans_funct.get_custom_stmt_trans in file "src/clang/cTrans.ml", line 5401, characters 8-55
Called from ClangFrontend__CTrans.CTrans_funct.exec_trans_instrs.exec_trans_instrs_rev in file "src/clang/cTrans.ml" (inlined), line 5365, characters 28-54
Called from ClangFrontend__CTrans.CTrans_funct.exec_trans_instrs in file "src/clang/cTrans.ml" (inlined), line 5389, characters 6-70
Called from ClangFrontend__CTrans.CTrans_funct.instructions_trans in file "src/clang/cTrans.ml", line 5451, characte

libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp

libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp:11:10: fatal error: 'cuda/_argument' file not found
11 | #include <cuda/_argument>
| ^~~~~~~~~~~~~~~~~~
1 error generated.
libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp:124:3-128:3: ERROR translating statement 'CompoundStmt'
Aborting translation of method 'test' in file 'libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp': "Assert_failure src/clang/cAst_utils.ml:249:53"
Uncaught Internal Error: "Assert_failure src/clang/cAst_utils.ml:249:53"
Error backtrace:
Raised at ClangFrontend__CAst_utils.get_decl_from_typ_ptr in file "src/clang/cAst_utils.ml", line 249, characters 53-65
Called from ClangFrontend__CTrans.CTrans_funct.get_destructor_decl_ref in file "src/clang/cTrans.ml", line 658, characters 12-59
Called from ClangFrontend__CTrans.CTrans_funct.destructor_calls.(fun) in file "src/clang/cTrans.ml", line 2048, characters 12-69
Called from Base__List.rev_filter_ma

... [truncated 2200 characters] ...

Frontend__CTrans.CTrans_funct.get_clang_stmt_trans in file "src/clang/cTrans.ml" (inlined), line 5395, characters 4-69
Called from ClangFrontend__CTrans.CTrans_funct.get_custom_stmt_trans in file "src/clang/cTrans.ml", line 5401, characters 8-55
Called from ClangFrontend__CTrans.CTrans_funct.exec_trans_instrs.exec_trans_instrs_rev in file "src/clang/cTrans.ml" (inlined), line 5365, characters 28-54
Called from ClangFrontend__CTrans.CTrans_funct.exec_trans_instrs in file "src/clang/cTrans.ml" (inlined), line 5389, characters 6-70
Called from ClangFrontend__CTrans.CTrans_funct.instructions_trans in file "src/clang/cTrans.ml", line 5451, characters 25-68
Called from ClangFrontend__CFrontend_decl.CFrontend_decl_funct.add_method.f in file "src/clang/cFrontend_decl.ml", line 48, characters 12-91


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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
libcudacxx/include/cuda/__argument/argument.h (1)

114-114: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

important: The static_assert error messages "must have a distinct element type" are now incorrect. The new __is_sequence_v checks whether a type is an array or satisfies ranges::range, not whether it has a distinct element type. Types like element_type_like<int> have a distinct element type but are not arrays or ranges, so they would fail this check for a different reason than the message suggests.

Update the messages to reflect the actual requirement, e.g., "must be an array or range type".

Proposed fix
-  static_assert(__is_sequence_v<value_type>, "constant sequence arguments must have a distinct element type");
+  static_assert(__is_sequence_v<value_type>, "constant sequence arguments must be an array or range type");

Apply similar changes to lines 304, 701, and 714.

Also applies to: 304-304, 701-701, 714-714


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6b49057a-ad0c-4843-8771-66b0fd1e7ae9

📥 Commits

Reviewing files that changed from the base of the PR and between 2b21bec and 171cb93.

📒 Files selected for processing (4)
  • libcudacxx/include/cuda/__argument/argument.h
  • libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp
  • libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp
  • libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp

@miscco miscco force-pushed the fix_argument_sequence_definition branch from 171cb93 to 90a8c02 Compare June 5, 2026 07:35
The  current is_sequence definition is thoroughly broken. An iterator is not a sequence and neither is a pointer.

The main problem here is that this precludes passing along iterators / pointers as values which is a reasonable use case.

It also completely deviates from any standard handling in C++.

Rather than reinventing the wheel in a bad way use standard terminology to determine what is a range and what not.

A user can always wrap iterators and pointers into views and spans, so there is not need for the current definition
@miscco miscco force-pushed the fix_argument_sequence_definition branch from 90a8c02 to f13ff25 Compare June 5, 2026 07:36
@miscco
Copy link
Copy Markdown
Contributor Author

miscco commented Jun 5, 2026

I have added some more tests to make sure this does not regresses again. I believe we can agree that complex<float> is not a range

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

😬 CI Workflow Results

🟥 Finished in 2h 01m: Pass: 91%/115 | Total: 19h 55m | Max: 1h 53m | Hits: 98%/338419

See results here.

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