Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core(graph): adding documentation for Kokkos::Experimental::Graph #565

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/source/API/core-index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ API: Core
- Utility functionality part of Kokkos Core.
* - `Detection Idiom <core/Detection-Idiom.html>`__
- Used to recognize, in an SFINAE-friendly way, the validity of any C++ expression.
* - `Graph and related <core/Graph.html>`_
- Kokkos Graph abstraction.
* - `Macros <core/Macros.html>`__
- Global macros defined by Kokkos, used for architectures, general settings, etc.

Expand All @@ -60,4 +62,5 @@ API: Core
./core/Utilities
./core/Detection-Idiom
./core/Macros
./core/Graph
./core/Profiling
12 changes: 12 additions & 0 deletions docs/source/API/core/Graph.axpby.kokkos.graph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
auto graph = Kokkos::Experimental::create_graph(exec_A, [&](auto root){
auto node_xpy = root.then_parallel_for(N, MyAxpby{x, y, alpha, beta});
auto node_zpy = root.then_parallel_for(N, MyAxpby{z, y, gamma, beta});

auto node_dotp = Kokkos::Experimental::when_all(node_xpy, node_zpy).then_parallel_reduce(
N, MyDotp{x, z}, dotp
)
});

graph.submit(exec_A);

exec_A.fence();
73 changes: 73 additions & 0 deletions docs/source/API/core/Graph.axpby.kokkos.graph.p2300.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* This is some external library function to which we pass a sender.
* The sender might either be a regular @c Kokkos execution space instance
* or a graph-node-sender-like stuff.
* The asynchronicity within the function will either be provided by the graph
* or must be dealt with in the regular way (creating many space instances).
*/
sender library_stuff(sender start)
{
sender auto exec_A, exec_B;

if constexpr (Kokkos::is_a_sender<sender>) {
exec_A = exec_B = start;
} else {
/// How do we partition ?
exec_A = start;
exec_B = Kokkos::partition_space(start, 1);
}

auto node_xpy = Kokkos::parallel_for(exec_A, policy(N), MyAxpby{x, y, alpha, beta});
auto node_zpy = Kokkos::parallel_for(exec_B, policy(N), MyAxpby{z, y, gamma, beta});

/// In the non-graph case,how do we enforce that e.g. node_zpy is done and launch
/// the parallel-reduce on the same execution space instance as node_xpy without writing
/// any additional piece of code ?

/// No need to fence, because @c Kokkos::when_all will take care of that.
return Kokkos::parallel_reduce(
Kokkos::when_all(node_xpy, node_zpy),
policy(N),
MyDotp{x, z}, dotp
);
}

int main()
{
/// A @c Kokkos execution space instance is a scheduler.
stdexec::scheduler auto scheduler = Kokkos::DefaultExecutionSpace{};

/**
* Start the chain of nodes with an "empty" node, similar to @c std::execution::schedule.
* Under the hood, it creates the @c Kokkos::Graph.
* All nodes created from this sender will share a handle to the underlying @c Kokkos::Graph.
*/
stdexec::sender auto start = Kokkos::Graph::schedule(scheduler);

/// @c Kokkos::parallel_for would behave much like @c std::execution::bulk.
stdexec::sender auto my_work = Kokkos::parallel_for(start, policy(N), ForFunctor{...});

/// Pass our chain to some external library function.
stdexec::sender auto subgraph = library_stuff(mywork);

/// Add some work again.
stdexec::sender auto my_other_work = Kokkos::parallel_scan(subgraph, policy(N), ScanFunctor{...});

/// @c Kokkos::Graph has a free function for instantiating the underlying graph.
/// All nodes connected to the same handle (i.e. that are on the same chain) are notified
/// that they cannot be used as senders anymore,
/// because they are locked in an instantiated graph. In other words, the chain is a DAG, and it
/// cannot change anymore.
stdexec::sender auto executable_chain = Kokkos::Graph::instantiate(my_other_work);

/// Submission is a no-op if the passed sender is a @c Kokkos execution space instance.
/// Otherwise, it submits the underlying graph.
Kokkos::Graph::submit(scheduler, executable_chain)

::stdexec::sync_wait(scheduler);

/// Submit the chain again, using another scheduler.
/// In essence, what @c Kokkos::Graph::submit can do is pertty much similar to what
/// @c std::execution::starts_on does. It allows the sender to be executed elsewhere.
Kokkos::Graph::submit(another_scheduler, executable_chain);
}
8 changes: 8 additions & 0 deletions docs/source/API/core/Graph.axpby.kokkos.vanilla.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Kokkos::parallel_for(policy_t(exec_A, 0, N), MyAxpby{x, y, alpha, beta});
Kokkos::parallel_for(policy_t(exec_B, 0, N), MyAxpby{z, y, gamma, beta});

exec_B.fence();

Kokkos::parallel_reduce(policy_t(exec_A, 0, N), MyDotp{x, z}, dotp);

exec_A.fence();
Loading
Loading