Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
Kokkos_Graph.hpp
1//@HEADER
2// ************************************************************************
3//
4// Kokkos v. 4.0
5// Copyright (2022) National Technology & Engineering
6// Solutions of Sandia, LLC (NTESS).
7//
8// Under the terms of Contract DE-NA0003525 with NTESS,
9// the U.S. Government retains certain rights in this software.
10//
11// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12// See https://kokkos.org/LICENSE for license information.
13// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14//
15//@HEADER
16
17#ifndef KOKKOS_GRAPH_HPP
18#define KOKKOS_GRAPH_HPP
19#ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
20#define KOKKOS_IMPL_PUBLIC_INCLUDE
21#define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_GRAPH
22#endif
23
24#include <Kokkos_Macros.hpp>
25#include <impl/Kokkos_Error.hpp> // KOKKOS_EXPECTS
26
27#include <Kokkos_Graph_fwd.hpp>
28#include <impl/Kokkos_GraphImpl_fwd.hpp>
29
30// GraphAccess needs to be defined, not just declared
31#include <impl/Kokkos_GraphImpl.hpp>
32
33#include <functional>
34#include <memory>
35
36namespace Kokkos {
37namespace Experimental {
38
39//==============================================================================
40// <editor-fold desc="Graph"> {{{1
41
42template <class ExecutionSpace>
43struct [[nodiscard]] Graph {
44 public:
45 //----------------------------------------------------------------------------
46 // <editor-fold desc="public member types"> {{{2
47
48 using execution_space = ExecutionSpace;
49 using graph = Graph;
50
51 // </editor-fold> end public member types }}}2
52 //----------------------------------------------------------------------------
53
54 private:
55 //----------------------------------------------------------------------------
56 // <editor-fold desc="friends"> {{{2
57
58 friend struct Kokkos::Impl::GraphAccess;
59
60 // </editor-fold> end friends }}}2
61 //----------------------------------------------------------------------------
62
63 //----------------------------------------------------------------------------
64 // <editor-fold desc="private data members"> {{{2
65
66 using impl_t = Kokkos::Impl::GraphImpl<ExecutionSpace>;
67 std::shared_ptr<impl_t> m_impl_ptr = nullptr;
68
69 // </editor-fold> end private data members }}}2
70 //----------------------------------------------------------------------------
71
72 //----------------------------------------------------------------------------
73 // <editor-fold desc="private ctors"> {{{2
74
75 // Note: only create_graph() uses this constructor, but we can't just make
76 // that a friend instead of GraphAccess because of the way that friend
77 // function template injection works.
78 explicit Graph(std::shared_ptr<impl_t> arg_impl_ptr)
79 : m_impl_ptr(std::move(arg_impl_ptr)) {}
80
81 // </editor-fold> end private ctors }}}2
82 //----------------------------------------------------------------------------
83
84 public:
85 ExecutionSpace const& get_execution_space() const {
86 return m_impl_ptr->get_execution_space();
87 }
88
89 void instantiate() {
90 KOKKOS_EXPECTS(bool(m_impl_ptr))
91 (*m_impl_ptr).instantiate();
92 }
93
94 void submit(const execution_space& exec) const {
95 KOKKOS_EXPECTS(bool(m_impl_ptr))
96 (*m_impl_ptr).submit(exec);
97 }
98
99 void submit() const { submit(get_execution_space()); }
100
101 decltype(auto) native_graph();
102
103 decltype(auto) native_graph_exec();
104};
105
106// </editor-fold> end Graph }}}1
107//==============================================================================
108
109//==============================================================================
110// <editor-fold desc="when_all"> {{{1
111
112template <class... PredecessorRefs>
113// constraints (not intended for subsumption, though...)
114// ((remove_cvref_t<PredecessorRefs> is a specialization of
115// GraphNodeRef with get_root().get_graph_impl() as its GraphImpl)
116// && ...)
117auto when_all(PredecessorRefs&&... arg_pred_refs) {
118 // TODO @graph @desul-integration check the constraints and preconditions
119 // once we have folded conjunctions from
120 // desul
121 static_assert(sizeof...(PredecessorRefs) > 0,
122 "when_all() needs at least one predecessor.");
123 auto graph_ptr_impl =
124 Kokkos::Impl::GraphAccess::get_graph_weak_ptr(
125 std::get<0>(std::forward_as_tuple(arg_pred_refs...)))
126 .lock();
127 auto node_ptr_impl = graph_ptr_impl->create_aggregate_ptr(arg_pred_refs...);
128 graph_ptr_impl->add_node(node_ptr_impl);
129 (graph_ptr_impl->add_predecessor(node_ptr_impl, arg_pred_refs), ...);
130 return Kokkos::Impl::GraphAccess::make_graph_node_ref(
131 std::move(graph_ptr_impl), std::move(node_ptr_impl));
132}
133
134// </editor-fold> end when_all }}}1
135//==============================================================================
136
137//==============================================================================
138// <editor-fold desc="create_graph"> {{{1
139
140template <class ExecutionSpace, class Closure>
141Graph<ExecutionSpace> create_graph(ExecutionSpace ex, Closure&& arg_closure) {
142 // Create a shared pointer to the graph:
143 // We need an attorney class here so we have an implementation friend to
144 // create a Graph class without graph having public constructors. We can't
145 // just make `create_graph` itself a friend because of the way that friend
146 // function template injection works.
147 auto rv = Kokkos::Impl::GraphAccess::construct_graph(std::move(ex));
148 // Invoke the user's graph construction closure
149 ((Closure&&)arg_closure)(Kokkos::Impl::GraphAccess::create_root_ref(rv));
150 // and given them back the graph
151 // KOKKOS_ENSURES(rv.m_impl_ptr.use_count() == 1)
152 return rv;
153}
154
155template <class ExecutionSpace = DefaultExecutionSpace>
156std::enable_if_t<Kokkos::is_execution_space_v<ExecutionSpace>,
157 Graph<ExecutionSpace>>
158create_graph(ExecutionSpace exec = ExecutionSpace{}) {
159 return Kokkos::Impl::GraphAccess::construct_graph(std::move(exec));
160}
161
162template <
163 class ExecutionSpace = DefaultExecutionSpace,
164 class Closure = Kokkos::Impl::DoNotExplicitlySpecifyThisTemplateParameter>
165std::enable_if_t<
166 !Kokkos::is_execution_space_v<Kokkos::Impl::remove_cvref_t<Closure>>,
167 Graph<ExecutionSpace>>
168create_graph(Closure&& arg_closure) {
169 return create_graph(ExecutionSpace{}, (Closure&&)arg_closure);
170}
171
172// </editor-fold> end create_graph }}}1
173//==============================================================================
174
175template <class ExecutionSpace>
176decltype(auto) Graph<ExecutionSpace>::native_graph() {
177 KOKKOS_EXPECTS(bool(m_impl_ptr));
178#if defined(KOKKOS_ENABLE_CUDA)
179 if constexpr (std::is_same_v<ExecutionSpace, Kokkos::Cuda>) {
180 return m_impl_ptr->cuda_graph();
181 }
182#elif defined(KOKKOS_ENABLE_HIP) && defined(KOKKOS_IMPL_HIP_NATIVE_GRAPH)
183 if constexpr (std::is_same_v<ExecutionSpace, Kokkos::HIP>) {
184 return m_impl_ptr->hip_graph();
185 }
186#elif defined(KOKKOS_ENABLE_SYCL) && defined(SYCL_EXT_ONEAPI_GRAPH)
187 if constexpr (std::is_same_v<ExecutionSpace, Kokkos::SYCL>) {
188 return m_impl_ptr->sycl_graph();
189 }
190#endif
191}
192
193template <class ExecutionSpace>
194decltype(auto) Graph<ExecutionSpace>::native_graph_exec() {
195 KOKKOS_EXPECTS(bool(m_impl_ptr));
196#if defined(KOKKOS_ENABLE_CUDA)
197 if constexpr (std::is_same_v<ExecutionSpace, Kokkos::Cuda>) {
198 return m_impl_ptr->cuda_graph_exec();
199 }
200#elif defined(KOKKOS_ENABLE_HIP) && defined(KOKKOS_IMPL_HIP_NATIVE_GRAPH)
201 if constexpr (std::is_same_v<ExecutionSpace, Kokkos::HIP>) {
202 return m_impl_ptr->hip_graph_exec();
203 }
204#elif defined(KOKKOS_ENABLE_SYCL) && defined(SYCL_EXT_ONEAPI_GRAPH)
205 if constexpr (std::is_same_v<ExecutionSpace, Kokkos::SYCL>) {
206 return m_impl_ptr->sycl_graph_exec();
207 }
208#endif
209}
210
211} // end namespace Experimental
212} // namespace Kokkos
213
214// Even though these things are separable, include them here for now so that
215// the user only needs to include Kokkos_Graph.hpp to get the whole facility.
216#include <Kokkos_GraphNode.hpp>
217
218#include <impl/Kokkos_GraphNodeImpl.hpp>
219#include <impl/Kokkos_Default_Graph_Impl.hpp>
220#include <Cuda/Kokkos_Cuda_Graph_Impl.hpp>
221#if defined(KOKKOS_ENABLE_HIP)
222// The implementation of hipGraph in ROCm 5.2 is bugged, so we cannot use it.
223#if defined(KOKKOS_IMPL_HIP_NATIVE_GRAPH)
224#include <HIP/Kokkos_HIP_Graph_Impl.hpp>
225#endif
226#endif
227#ifdef SYCL_EXT_ONEAPI_GRAPH
228#include <SYCL/Kokkos_SYCL_Graph_Impl.hpp>
229#endif
230#ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_GRAPH
231#undef KOKKOS_IMPL_PUBLIC_INCLUDE
232#undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_GRAPH
233#endif
234#endif // KOKKOS_GRAPH_HPP