diff --git a/include/nvexec/stream/common.cuh b/include/nvexec/stream/common.cuh index 1e2a03ac5..4aef7a2bf 100644 --- a/include/nvexec/stream/common.cuh +++ b/include/nvexec/stream/common.cuh @@ -663,7 +663,7 @@ namespace nv::execution opstate_base(OuterReceiver rcvr, context ctx) : ctx_(ctx) - , rcvr_(rcvr) + , rcvr_(static_cast(rcvr)) , stream_provider_(borrows_stream, ctx) {} diff --git a/include/nvexec/stream/upon_error.cuh b/include/nvexec/stream/upon_error.cuh index 38350b9ff..9bd367bbe 100644 --- a/include/nvexec/stream/upon_error.cuh +++ b/include/nvexec/stream/upon_error.cuh @@ -172,7 +172,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_error.cpp b/test/nvexec/upon_error.cpp index df3f1c491..8d049571b 100644 --- a/test/nvexec/upon_error.cpp +++ b/test/nvexec/upon_error.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include "common.cuh" #include "nvexec/stream_context.cuh" @@ -11,6 +13,23 @@ using nvexec::is_on_gpu; namespace { + struct move_only_error_handler + { + move_only_error_handler() = default; + move_only_error_handler(move_only_error_handler const &) = delete; + + STDEXEC_ATTRIBUTE(host, device) + move_only_error_handler(move_only_error_handler &&) = default; + + STDEXEC_ATTRIBUTE(host, device) auto operator()(int error) const -> int + { + return error; + } + }; + + static_assert(std::is_trivially_copyable_v); + static_assert(!std::is_copy_constructible_v); + TEST_CASE("nvexec upon_error returns a sender", "[cuda][stream][adaptors][upon_error]") { nvexec::stream_context stream_ctx{}; @@ -21,6 +40,18 @@ namespace (void) snd; } + TEST_CASE("nvexec upon_error supports move-only function objects", + "[cuda][stream][adaptors][upon_error]") + { + nvexec::stream_context stream_ctx{}; + + auto snd = ex::just_error(42) | ex::continues_on(stream_ctx.get_scheduler()) + | ex::upon_error(move_only_error_handler{}); + auto const [result] = STDEXEC::sync_wait(std::move(snd)).value(); + + REQUIRE(result == 42); + } + TEST_CASE("nvexec upon_error executes on GPU", "[cuda][stream][adaptors][upon_error]") { nvexec::stream_context stream_ctx{};