Skip to content

[SYCL][Graph] Add initial support for SYCL Graph (1/4) #9728

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

Merged
merged 37 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
16fc23a
initial split
reble Jun 2, 2023
51252d1
remove remaining command buffer traces
reble Jun 2, 2023
44c438b
Merge branch 'sycl' into sycl-graph-release-patch1
reble Jun 2, 2023
77b5787
fix clang format messed by merge
reble Jun 2, 2023
f99add6
fix issues intr. by merge
reble Jun 3, 2023
c930c7a
update linux symbol reference
reble Jun 6, 2023
a6f2485
[SYCL][Graph] Bugfix empty cgf explicit mode (#207)
reble Jun 6, 2023
ef71ba3
update symbol refs and layout for abi tests
reble Jun 6, 2023
441449b
[SYCL][Graphs] Remove blocking wait from graph enqueue.
EwanC May 25, 2023
28fa544
clang-format
reble Jun 6, 2023
5ae93e3
Merge branch 'sycl' into pablo/sycl-graph-release-patch1-rebase
reble Jun 7, 2023
e29548b
Apply suggestions from code review
reble Jun 8, 2023
24a3bfe
[SYCL] Apply more suggestions from code review (#212)
reble Jun 8, 2023
ad372ad
[SYCL][Graphs] Fix Windows stdcpp_compat.cpp fail
EwanC May 31, 2023
0f7535e
[SYCL][Graph] Fix layout handler reference for abi test
reble Jun 9, 2023
25bd76f
[SYCL][Graph] Fix scheduler regression test
EwanC Jun 8, 2023
3843e3a
[SYCL][Graph] Add Windows symbols
EwanC May 29, 2023
4c8b3f7
[SYCL][Graph] Remove symbols from test
EwanC Jun 9, 2023
5d648c5
Merge branch 'intel:sycl' into sycl-graph-release-patch1
reble Jun 9, 2023
5494e9d
[SYCL][Graph] Consistent use of make_error_code (#217)
reble Jun 12, 2023
b71c0e0
[SYCL][Graph] Remove dead code in unit-test (#216)
reble Jun 12, 2023
3fdddfe
[SYCL][Graph] Apply LLVM coding style to non-public interfaces (#220)
reble Jun 12, 2023
9dd076c
clang-format
reble Jun 12, 2023
c100136
fix handler layout reference
reble Jun 12, 2023
21227a4
fix layout handler reference (cont.)
reble Jun 12, 2023
b213ba8
fix abi test layout handler
reble Jun 12, 2023
fb0c1c2
[SYCL][Graph] Update Windows symbols (#223)
EwanC Jun 13, 2023
7ab1d0d
Merge branch 'sycl' into sycl-graph-release-patch1
EwanC Jun 13, 2023
85a649b
[SYCL][Graph] Including more feedback from PR (#222)
reble Jun 14, 2023
16ca50e
[SYCL][Graph] Make internal constructor private (#219)
reble Jun 14, 2023
6953c1f
Merge branch 'sycl' into sycl-graph-release-patch1
reble Jun 15, 2023
ae54b1a
Update queue.hpp
reble Jun 14, 2023
164560f
clang format queue.hpp
reble Jun 15, 2023
4f21586
adapt changes from #9837
reble Jun 15, 2023
13d0919
[SYCL][Graph] Fix test-e2e host task related fails (#226)
EwanC Jun 15, 2023
af8e79d
[SYCL][Graph] Update scheduler regresion test to use shared_ptr (#228)
EwanC Jun 15, 2023
2b30beb
[SYCL][Graph] Update windows symbol tests
EwanC Jun 15, 2023
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
21 changes: 16 additions & 5 deletions sycl/include/sycl/detail/cg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class CG {
CopyToDeviceGlobal = 19,
CopyFromDeviceGlobal = 20,
ReadWriteHostPipe = 21,
ExecCommandBuffer = 22,
};

struct StorageInitHelper {
Expand All @@ -89,6 +90,7 @@ class CG {
MSharedPtrStorage(std::move(SharedPtrStorage)),
MRequirements(std::move(Requirements)), MEvents(std::move(Events)) {}
StorageInitHelper(StorageInitHelper &&) = default;
StorageInitHelper(const StorageInitHelper &) = default;
// The following storages are needed to ensure that arguments won't die
// while we are using them.
/// Storage for standard layout arguments.
Expand Down Expand Up @@ -119,16 +121,23 @@ class CG {
}

CG(CG &&CommandGroup) = default;
CG(const CG &CommandGroup) = default;

CGTYPE getType() { return MType; }

std::vector<std::vector<char>> &getArgsStorage() { return MData.MArgsStorage; }
std::vector<detail::AccessorImplPtr> &getAccStorage() { return MData.MAccStorage; }
std::vector<std::vector<char>> &getArgsStorage() {
return MData.MArgsStorage;
}
std::vector<detail::AccessorImplPtr> &getAccStorage() {
return MData.MAccStorage;
}
std::vector<std::shared_ptr<const void>> &getSharedPtrStorage() {
return MData.MSharedPtrStorage;
}

std::vector<AccessorImplHost *> &getRequirements() { return MData.MRequirements; }
std::vector<AccessorImplHost *> &getRequirements() {
return MData.MRequirements;
}
std::vector<detail::EventImplPtr> &getEvents() { return MData.MEvents; }

virtual ~CG() = default;
Expand All @@ -151,7 +160,7 @@ class CGExecKernel : public CG {
public:
/// Stores ND-range description.
NDRDescT MNDRDesc;
std::unique_ptr<HostKernelBase> MHostKernel;
std::shared_ptr<HostKernelBase> MHostKernel;
std::shared_ptr<detail::kernel_impl> MSyclKernel;
std::shared_ptr<detail::kernel_bundle_impl> MKernelBundle;
std::vector<ArgDesc> MArgs;
Expand All @@ -160,7 +169,7 @@ class CGExecKernel : public CG {
std::vector<std::shared_ptr<const void>> MAuxiliaryResources;
RT::PiKernelCacheConfig MKernelCacheConfig;

CGExecKernel(NDRDescT NDRDesc, std::unique_ptr<HostKernelBase> HKernel,
CGExecKernel(NDRDescT NDRDesc, std::shared_ptr<HostKernelBase> HKernel,
std::shared_ptr<detail::kernel_impl> SyclKernel,
std::shared_ptr<detail::kernel_bundle_impl> KernelBundle,
CG::StorageInitHelper CGData, std::vector<ArgDesc> Args,
Expand All @@ -180,6 +189,8 @@ class CGExecKernel : public CG {
"Wrong type of exec kernel CG.");
}

CGExecKernel(const CGExecKernel &CGExec) = default;

std::vector<ArgDesc> getArguments() const { return MArgs; }
std::string getKernelName() const { return MKernelName; }
std::vector<std::shared_ptr<detail::stream_impl>> getStreams() const {
Expand Down
6 changes: 4 additions & 2 deletions sycl/include/sycl/detail/property_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ enum DataLessPropKind {
QueuePriorityNormal = 16,
QueuePriorityLow = 17,
QueuePriorityHigh = 18,
GraphNoCycleCheck = 19,
// Indicates the last known dataless property.
LastKnownDataLessPropKind = 18,
LastKnownDataLessPropKind = 19,
// Exceeding 32 may cause ABI breaking change on some of OSes.
DataLessPropKindSize = 32
};
Expand All @@ -58,7 +59,8 @@ enum PropWithDataKind {
BufferMemChannel = 4,
AccPropBufferLocation = 5,
QueueComputeIndex = 6,
PropWithDataKindSize = 7,
GraphNodeDependencies = 7,
PropWithDataKindSize = 8
};

// Base class for dataless properties, needed to check that the type of an
Expand Down
253 changes: 253 additions & 0 deletions sycl/include/sycl/ext/oneapi/experimental/graph.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
//==--------- graph.hpp --- SYCL graph extension ---------------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

#include <memory>
#include <vector>

#include <sycl/detail/common.hpp>
#include <sycl/detail/defines_elementary.hpp>
#include <sycl/property_list.hpp>

namespace sycl {
__SYCL_INLINE_VER_NAMESPACE(_V1) {

class handler;
class queue;
class device;
namespace ext {
namespace oneapi {
namespace experimental {

namespace detail {
class node_impl;
class graph_impl;
class exec_graph_impl;

} // namespace detail

/// State to template the command_graph class on.
enum class graph_state {
modifiable, ///< In modifiable state, commands can be added to graph.
executable, ///< In executable state, the graph is ready to execute.
};

/// Class representing a node in the graph, returned by command_graph::add().
class __SYCL_EXPORT node {
private:
node(const std::shared_ptr<detail::node_impl> &Impl) : impl(Impl) {}

template <class Obj>
friend decltype(Obj::impl)
sycl::detail::getSyclObjImpl(const Obj &SyclObject);
template <class T>
friend T sycl::detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);

std::shared_ptr<detail::node_impl> impl;
};

namespace property {
namespace graph {

/// Property passed to command_graph constructor to disable checking for cycles.
///
/// \todo Cycle check not yet implemented.
class no_cycle_check : public ::sycl::detail::DataLessProperty<
::sycl::detail::GraphNoCycleCheck> {
public:
no_cycle_check() = default;
};

} // namespace graph

namespace node {

/// Property used to define dependent nodes when creating a new node with
/// command_graph::add().
class depends_on : public ::sycl::detail::PropertyWithData<
::sycl::detail::GraphNodeDependencies> {
public:
template <typename... NodeTN> depends_on(NodeTN... nodes) : MDeps{nodes...} {}

const std::vector<::sycl::ext::oneapi::experimental::node> &
get_dependencies() const {
return MDeps;
}

private:
const std::vector<::sycl::ext::oneapi::experimental::node> MDeps;
};

} // namespace node
} // namespace property

/// Graph in the modifiable state.
template <graph_state State = graph_state::modifiable>
class __SYCL_EXPORT command_graph {
public:
/// Constructor.
/// @param SyclContext Context to use for graph.
/// @param SyclDevice Device all nodes will be associated with.
/// @param PropList Optional list of properties to pass.
command_graph(const context &SyclContext, const device &SyclDevice,
const property_list &PropList = {});

/// Add an empty node to the graph.
/// @param PropList Property list used to pass [0..n] predecessor nodes.
/// @return Constructed empty node which has been added to the graph.
node add(const property_list &PropList = {}) {
if (PropList.has_property<property::node::depends_on>()) {
auto Deps = PropList.get_property<property::node::depends_on>();
return addImpl(Deps.get_dependencies());
}
return addImpl({});
}

/// Add a command-group node to the graph.
/// @param CGF Command-group function to create node with.
/// @param PropList Property list used to pass [0..n] predecessor nodes.
/// @return Constructed node which has been added to the graph.
template <typename T> node add(T CGF, const property_list &PropList = {}) {
if (PropList.has_property<property::node::depends_on>()) {
auto Deps = PropList.get_property<property::node::depends_on>();
return addImpl(CGF, Deps.get_dependencies());
}
return addImpl(CGF, {});
}

/// Add a dependency between two nodes.
/// @param Src Node which will be a dependency of \p Dest.
/// @param Dest Node which will be dependent on \p Src.
void make_edge(node &Src, node &Dest);

/// Finalize modifiable graph into an executable graph.
/// @param PropList Property list used to pass properties for finalization.
/// @return Executable graph object.
command_graph<graph_state::executable>
finalize(const property_list &PropList = {}) const;

/// Change the state of a queue to be recording and associate this graph with
/// it.
/// @param RecordingQueue The queue to change state on and associate this
/// graph with.
/// @return True if the queue had its state changed from executing to
/// recording.
bool begin_recording(queue &RecordingQueue);

/// Change the state of multiple queues to be recording and associate this
/// graph with each of them.
/// @param RecordingQueues The queues to change state on and associate this
/// graph with.
/// @return True if any queue had its state changed from executing to
/// recording.
bool begin_recording(const std::vector<queue> &RecordingQueues);

/// Set all queues currently recording to this graph to the executing state.
/// @return True if any queue had its state changed from recording to
/// executing.
bool end_recording();

/// Set a queue currently recording to this graph to the executing state.
/// @param RecordingQueue The queue to change state on.
/// @return True if the queue had its state changed from recording to
/// executing.
bool end_recording(queue &RecordingQueue);

/// Set multiple queues currently recording to this graph to the executing
/// state.
/// @param RecordingQueues The queues to change state on.
/// @return True if any queue had its state changed from recording to
/// executing.
bool end_recording(const std::vector<queue> &RecordingQueues);

private:
/// Constructor used internally by the runtime.
/// @param Impl Detail implementation class to construct object with.
command_graph(const std::shared_ptr<detail::graph_impl> &Impl) : impl(Impl) {}

/// Template-less implementation of add() for CGF nodes.
/// @param CGF Command-group function to add.
/// @param Dep List of predecessor nodes.
/// @return Node added to the graph.
node addImpl(std::function<void(handler &)> CGF,
const std::vector<node> &Dep);

/// Template-less implementation of add() for empty nodes.
/// @param Dep List of predecessor nodes.
/// @return Node added to the graph.
node addImpl(const std::vector<node> &Dep);

template <class Obj>
friend decltype(Obj::impl)
sycl::detail::getSyclObjImpl(const Obj &SyclObject);
template <class T>
friend T sycl::detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);

std::shared_ptr<detail::graph_impl> impl;
};

template <> class __SYCL_EXPORT command_graph<graph_state::executable> {
public:
/// An executable command-graph is not user constructable.
command_graph() = delete;

/// Update the inputs & output of the graph.
/// @param Graph Graph to use the inputs and outputs of.
void update(const command_graph<graph_state::modifiable> &Graph);

private:
/// Constructor used by internal runtime.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the modifiable command_graph constructor is private, whereas the executable command_graph constructor is public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in reble#219

/// @param Graph Detail implementation class to construct with.
/// @param Ctx Context to use for graph.
command_graph(const std::shared_ptr<detail::graph_impl> &Graph,
const sycl::context &Ctx);

template <class Obj>
friend decltype(Obj::impl)
sycl::detail::getSyclObjImpl(const Obj &SyclObject);

/// Creates a backend representation of the graph in \p impl member variable.
void finalizeImpl();

int MTag;
std::shared_ptr<detail::exec_graph_impl> impl;

friend class command_graph<graph_state::modifiable>;
};

/// Additional CTAD deduction guide.
template <graph_state State = graph_state::modifiable>
command_graph(const context &SyclContext, const device &SyclDevice,
const property_list &PropList) -> command_graph<State>;

} // namespace experimental
} // namespace oneapi
} // namespace ext

template <>
struct is_property<ext::oneapi::experimental::property::graph::no_cycle_check>
: std::true_type {};

template <>
struct is_property<ext::oneapi::experimental::property::node::depends_on>
: std::true_type {};

template <>
struct is_property_of<
ext::oneapi::experimental::property::graph::no_cycle_check,
ext::oneapi::experimental::command_graph<
ext::oneapi::experimental::graph_state::modifiable>> : std::true_type {
};

template <>
struct is_property_of<ext::oneapi::experimental::property::node::depends_on,
ext::oneapi::experimental::node> : std::true_type {};

} // __SYCL_INLINE_VER_NAMESPACE(_V1)
} // namespace sycl
Loading