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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions