From 6b6b1134425f87260be02262e5f53988af15c68e Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Wed, 12 Aug 2026 01:45:26 +0200 Subject: [PATCH 1/2] Fix nvexec upon_stopped callable forwarding --- include/nvexec/stream/upon_stopped.cuh | 2 +- test/nvexec/upon_stopped.cpp | 31 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/nvexec/stream/upon_stopped.cuh b/include/nvexec/stream/upon_stopped.cuh index 83b88fd63..85121582d 100644 --- a/include/nvexec/stream/upon_stopped.cuh +++ b/include/nvexec/stream/upon_stopped.cuh @@ -160,7 +160,7 @@ namespace nv::execution::_strm static_cast(self).sndr_, static_cast(rcvr), [&](_strm::opstate_base& stream_provider) -> _receiver_t - { return _receiver_t(self.fun_, stream_provider); }); + { return _receiver_t(static_cast(self).fun_, stream_provider); }); } STDEXEC_EXPLICIT_THIS_END(connect) diff --git a/test/nvexec/upon_stopped.cpp b/test/nvexec/upon_stopped.cpp index 1b7438f8b..85e0ab304 100644 --- a/test/nvexec/upon_stopped.cpp +++ b/test/nvexec/upon_stopped.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include "common.cuh" #include "nvexec/stream_context.cuh" @@ -12,6 +14,23 @@ using nvexec::is_on_gpu; namespace { + struct move_only_stopped_handler + { + move_only_stopped_handler() = default; + move_only_stopped_handler(move_only_stopped_handler const &) = delete; + + STDEXEC_ATTRIBUTE(host, device) + move_only_stopped_handler(move_only_stopped_handler &&) = default; + + STDEXEC_ATTRIBUTE(host, device) auto operator()() const -> int + { + return 42; + } + }; + + static_assert(std::is_trivially_copyable_v); + static_assert(!std::is_copy_constructible_v); + struct move_only_result { STDEXEC_ATTRIBUTE(host, device) @@ -83,6 +102,18 @@ namespace REQUIRE(flags_storage.all_set_once()); } + TEST_CASE("nvexec upon_stopped supports move-only function objects", + "[cuda][stream][adaptors][upon_stopped]") + { + nvexec::stream_context stream_ctx{}; + + auto snd = ex::just_stopped() | ex::continues_on(stream_ctx.get_scheduler()) + | ex::upon_stopped(move_only_stopped_handler{}); + auto const [result] = STDEXEC::sync_wait(std::move(snd)).value(); + + REQUIRE(result == 42); + } + TEST_CASE("nvexec upon_stopped moves its result", "[cuda][stream][adaptors][upon_stopped]") { nvexec::stream_context stream_ctx{}; From fb50b1c3f4abe4e27e397d0accaba8b5afcf23f4 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Fri, 14 Aug 2026 23:25:37 +0000 Subject: [PATCH 2/2] clang-format --- test/nvexec/upon_stopped.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nvexec/upon_stopped.cpp b/test/nvexec/upon_stopped.cpp index 85e0ab304..1cac5a096 100644 --- a/test/nvexec/upon_stopped.cpp +++ b/test/nvexec/upon_stopped.cpp @@ -39,7 +39,7 @@ namespace {} STDEXEC_ATTRIBUTE(host, device) - move_only_result(move_only_result&& other) noexcept + move_only_result(move_only_result &&other) noexcept : value_(other.value_) { other.value_ = 0;