//@HEADER // ************************************************************************ // // Kokkos v. 4.0 // Copyright (2022) National Technology & Engineering // Solutions of Sandia, LLC (NTESS). // // Under the terms of Contract DE-NA0003525 with NTESS, // the U.S. Government retains certain rights in this software. // // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. // See https://kokkos.org/LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //@HEADER #ifndef KOKKOS_GRAPH_HPP #define KOKKOS_GRAPH_HPP #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE #define KOKKOS_IMPL_PUBLIC_INCLUDE #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_GRAPH #endif #include #include // KOKKOS_EXPECTS #include #include // GraphAccess needs to be defined, not just declared #include #include #include namespace Kokkos { namespace Experimental { //============================================================================== // {{{1 template struct [[nodiscard]] Graph { public: //---------------------------------------------------------------------------- // {{{2 using execution_space = ExecutionSpace; using graph = Graph; // end public member types }}}2 //---------------------------------------------------------------------------- private: //---------------------------------------------------------------------------- // {{{2 friend struct Kokkos::Impl::GraphAccess; // end friends }}}2 //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // {{{2 using impl_t = Kokkos::Impl::GraphImpl; std::shared_ptr m_impl_ptr = nullptr; // end private data members }}}2 //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // {{{2 // Note: only create_graph() uses this constructor, but we can't just make // that a friend instead of GraphAccess because of the way that friend // function template injection works. explicit Graph(std::shared_ptr arg_impl_ptr) : m_impl_ptr(std::move(arg_impl_ptr)) {} // end private ctors }}}2 //---------------------------------------------------------------------------- public: ExecutionSpace const& get_execution_space() const { return m_impl_ptr->get_execution_space(); } void submit() const { KOKKOS_EXPECTS(bool(m_impl_ptr)) (*m_impl_ptr).submit(); } }; // end Graph }}}1 //============================================================================== //============================================================================== // {{{1 template // constraints (not intended for subsumption, though...) // ((remove_cvref_t is a specialization of // GraphNodeRef with get_root().get_graph_impl() as its GraphImpl) // && ...) auto when_all(PredecessorRefs&&... arg_pred_refs) { // TODO @graph @desul-integration check the constraints and preconditions // once we have folded conjunctions from // desul static_assert(sizeof...(PredecessorRefs) > 0, "when_all() needs at least one predecessor."); auto graph_ptr_impl = Kokkos::Impl::GraphAccess::get_graph_weak_ptr( std::get<0>(std::forward_as_tuple(arg_pred_refs...))) .lock(); auto node_ptr_impl = graph_ptr_impl->create_aggregate_ptr(arg_pred_refs...); graph_ptr_impl->add_node(node_ptr_impl); (graph_ptr_impl->add_predecessor(node_ptr_impl, arg_pred_refs), ...); return Kokkos::Impl::GraphAccess::make_graph_node_ref( std::move(graph_ptr_impl), std::move(node_ptr_impl)); } // end when_all }}}1 //============================================================================== //============================================================================== // {{{1 template Graph create_graph(ExecutionSpace ex, Closure&& arg_closure) { // Create a shared pointer to the graph: // We need an attorney class here so we have an implementation friend to // create a Graph class without graph having public constructors. We can't // just make `create_graph` itself a friend because of the way that friend // function template injection works. auto rv = Kokkos::Impl::GraphAccess::construct_graph(std::move(ex)); // Invoke the user's graph construction closure ((Closure &&) arg_closure)(Kokkos::Impl::GraphAccess::create_root_ref(rv)); // and given them back the graph // KOKKOS_ENSURES(rv.m_impl_ptr.use_count() == 1) return rv; } template < class ExecutionSpace = DefaultExecutionSpace, class Closure = Kokkos::Impl::DoNotExplicitlySpecifyThisTemplateParameter> Graph create_graph(Closure&& arg_closure) { return create_graph(ExecutionSpace{}, (Closure &&) arg_closure); } // end create_graph }}}1 //============================================================================== } // end namespace Experimental } // namespace Kokkos // Even though these things are separable, include them here for now so that // the user only needs to include Kokkos_Graph.hpp to get the whole facility. #include #include #include #include #if defined(KOKKOS_ENABLE_HIP) // The implementation of hipGraph in ROCm 5.2 is bugged, so we cannot use it. #if !((HIP_VERSION_MAJOR == 5) && (HIP_VERSION_MINOR == 2)) #include #endif #endif #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_GRAPH #undef KOKKOS_IMPL_PUBLIC_INCLUDE #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_GRAPH #endif #endif // KOKKOS_GRAPH_HPP