Fix env-based DeviceReduce kernel-allowlist tests on MSVC + CUDA 13.3#9726
Fix env-based DeviceReduce kernel-allowlist tests on MSVC + CUDA 13.3#9726edenfunf wants to merge 2 commits into
Conversation
The environment-based DeviceReduce tests computed their expected kernel pointers with `decltype(d_in)` inside the `[&]` allowlist lambda. With nvcc 13.3 and MSVC as host compiler, decltype() of a variable captured by reference inside a lambda is misevaluated as a reference type, so the tests referenced (and instantiated) `Kernel<..., InputIt&, ...>` instead of the `Kernel<..., InputIt, ...>` the dispatch launches. The two are different instantiations with different host stubs, and the referenced one is never registered with the CUDA runtime, so the white-box kernel-allowlist check at catch2_test_env_launch_helper.h:97 failed. * Hoist the iterator type aliases out of the allowlist lambdas. * Build the allowlists from the same kernel-source types the dispatch uses, so the expected instantiations cannot drift from the launched ones. * Add DeterministicDeviceReduceKernelSource to the RFA dispatch, mirroring the KernelSource pattern used by the other dispatch layers, and pass the kernels into invoke_single_tile/invoke_passes as parameters. Verified on Windows with MSVC 14.50: CUDA 13.3.1 (previously failing) and CUDA 12.9 (regression check) both pass all 49 test cases. Fixes NVIDIA#9643
* Factor the near-identical allowlist lambdas of the two requirements-parametrized tests into one expected_reduce_kernels function template. As a function template, the iterator types are deduced at test scope, which also removes the lambda that triggered the decltype() misevaluation entirely. * Expose detail::rfa::default_kernel_source_t and use it both as the dispatch default and in the test, so the expected RFA kernel instantiations are derived from a single place. * Include <thrust/type_traits/unwrap_contiguous_iterator.h> directly instead of relying on transitive inclusion. * Document the decltype()-inside-lambda pitfall next to allowed_kernels() in the launch helper, where future allowlist tests will look. * Drop the redundant reduction_op_t alias and the stale commented-out UNSCOPED_CAPTURE block. Re-verified on Windows with MSVC 14.50 on both CUDA 13.3.1 and 12.9: reduce_env (lid_0 + lid_2), reduce_deterministic, reduce_nondeterministic, and reduce_env_api all pass.
📝 WalkthroughSummary by CodeRabbit
WalkthroughCompact metadata ChangesKernel Source Refactor
Assessment against linked issues
Possibly related PRs
Suggested reviewers: important: verify the suggestion: the doc comment addition in Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cub/test/catch2_test_device_reduce_env.cu (1)
505-520: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuesuggestion: The sum variant (Lines 550-565) is byte-identical to this block, and both mirror the
run_to_runbranch ofexpected_reduce_kernels. Extract a small helper so future kernel-source changes can't drift between the twonot_guaranteedtests. Optional.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 82c18609-29b3-482f-a43b-f810cba21503
📒 Files selected for processing (3)
cub/cub/device/dispatch/dispatch_reduce_deterministic.cuhcub/test/catch2_test_device_reduce_env.cucub/test/catch2_test_env_launch_helper.h
Description
closes #9643
The env-based
DeviceReducetests compute their expected kernel pointers fromdecltype(d_in)inside the[&]allowlist lambdas. With nvcc 13.3 and MSVC as host compiler,decltype()of a variable captured by reference inside a lambda is evaluated as a reference type (astatic_assert(!is_reference_v<decltype(d_in)>)inside the lambda fires on 13.3 and not on 12.9). The tests therefore referenceKernel<..., constant_iterator&, ...>while the dispatch launchesKernel<..., constant_iterator, ...>— a different instantiation with its own host stub that is never registered with the runtime (cudaFuncGetNameon the allowlist pointer returnscudaErrorInvalidDeviceFunction), so the pointer check atcatch2_test_env_launch_helper.h:97fails. Which lambda is affected shifts with unrelated code changes, hence the instantiation-specific failures in the issue.Changes:
expected_reduce_kernels) shared by both requirements-parametrized tests. Iterator types are now deduced at test scope, so nodecltype()of a capture remains, and the two near-identical per-test lambdas are gone.DeterministicDeviceReduceKernelSourceplus adefault_kernel_source_talias todispatch_reduce_deterministic.cuh, following the pattern of the other dispatch layers;invoke_single_tile/invoke_passestake the kernels as parameters likeDispatchReducedoes. No functional change.allowed_kernels()in the launch helper.Verified on Windows / MSVC 14.50 / C++17 / sm_120:
cub.test.device.reduce_env.lid_0reproduced the reported failure before the change and passes after.reduce_env.lid_2,reduce_deterministic,reduce_nondeterministic, andreduce_env_apialso pass.reduce_env.lid_0,reduce_deterministic,reduce_nondeterministicpass (regression check).The
decltype()misevaluation itself looks like a compiler regression worth tracking on the nvcc side. A trivial repro does not trigger it; it seems to need the surrounding template test function and a class-type iterator.Checklist