Skip to content

Operation state cooperation that goes through uncustomized sender layers (sort of forwarding environment) #1802

@romintomasetti

Description

@romintomasetti

We are currently working (with @maartenarnst) on a customization for a scheduler that builds a Kokkos::Experimental::Graph under the hood.

To add a node to a Kokkos::Experimental::Graph, we need to know its predecessor(s).

Here’s an example of a diamond-shaped Kokkos::Experimental::Graph:

auto root = graph.get_root();

auto A = root.then(...);

auto B = A.then(...);
auto C = A.then(...);

auto D = Kokkos::Experimental::when_all(std::move(B), std::move(C)).then(...);

Conceptually, we’d like this to naturally translate to something like the following using exec::fork_join:

stdexec::sync_wait(
    stdexec::schedule(graph_scheduler)
    | then(...A...)
    | exec::fork_join(
          stdexec::on(graph_scheduler, ...B...),
          stdexec::on(graph_scheduler, ...C...))
    | then(...D...)
);

As mentioned, we need the predecessor(s) in order to add a new node to the graph. We create the node in the operation state.

We have already customized when_all, but we are now running into what feels like a limitation (or at least an awkward spot — or something I'm missing) in the std::execution framework:

There is no built-in mechanism to propagate information from inner to outer operation states.

In our example, A is the innermost node. How would B or C query the node created by A? Obviously (?), this cannot be done through the receiver’s environment, which only propagates information upstream from B/C to A.

Currently, we rely on the fact that the operation states of our customizations provide a get_node() member function. However, this approach breaks when exec::fork_join introduces intermediate layers between A and B/C, because those intermediate layers hide the underlying operation states.

One potential solution would be to make exec::fork_join itself customizable to forward this information. But we feel like the problem could be more general than just ours, so we wonder how more experienced people would handle it 😉

Any suggestion is appreciated !

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions