nvexec `let_value` et al assumes sender returned from lambda is a stream sender
ericniebler opened this issue · 0 comments
nvexec's customization of let_value
calls the lambda and constructs the result sender in temporary storage (good), but it unconditionally attaches a propagate_receiver_t
. If that sender is not a stream sender, and if it completes with reference(s) to objects in host memory (say, if it passes to propagate_receiver_t
's set_value
references to temporaries that live on the host caller's stack, then when device code accesses the values, the process will crash because host memory is inaccessible.
E.g., this crashes:
nvexec::stream_context ctx;
auto snd = stdexec::schedule( ctx.get_scheduler() )
| stdexec::let_value( [] {
// this sender will complete with an rvalue reference to
// an integer in host memory:
return stdexec::just() | stdexec::then( [] { return 42; } );
})
// This sender's receiver, wrapped in `propagate_receiver_t`,
// will accept the reference to host memory and pass it into
// a kernel that calls this lambda, causing an access violation.
| stdexec::then( [] (int i) { ... } );
stdexec::sync_wait( std::move(snd) );
The stream scheduler's let_value
customization must assume, if the result sender is not a stream sender, that any values/errors it may complete with are kept in host memory and defensively copy them into device memory.