Skip to content

Commit 48bcaf0

Browse files
[SYCL] Add property validation for kernel_bundle free functions and graph extension (#15647)
extra changes, follow up for #15253 --------- Signed-off-by: Tikhomirova, Kseniya <[email protected]>
1 parent fad00cc commit 48bcaf0

File tree

14 files changed

+416
-102
lines changed

14 files changed

+416
-102
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// --*- c++ -*---
2+
#ifndef __SYCL_DATA_LESS_PROP
3+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL)
4+
#endif
5+
#ifndef __SYCL_MANUALLY_DEFINED_PROP
6+
#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME)
7+
#endif
8+
9+
/// Property passed to command_graph constructor to disable checking for cycles.
10+
__SYCL_DATA_LESS_PROP(property::graph, no_cycle_check, GraphNoCycleCheck)
11+
12+
/// Property passed to command_graph constructor to allow buffers to be used
13+
/// with graphs. Passing this property represents a promise from the user that
14+
/// the buffer will outlive any graph that it is used in.
15+
__SYCL_DATA_LESS_PROP(property::graph, assume_buffer_outlives_graph, GraphAssumeBufferOutlivesGraph)
16+
17+
/// Property passed to command_graph<graph_state::modifiable>::finalize() to
18+
/// mark the resulting executable command_graph as able to be updated.
19+
__SYCL_DATA_LESS_PROP(property::graph, updatable, GraphUpdatable)
20+
21+
/// Property used to enable executable graph profiling. Enables profiling on
22+
/// events returned by submissions of the executable graph
23+
__SYCL_DATA_LESS_PROP(property::graph, enable_profiling, GraphEnableProfiling)
24+
25+
#undef __SYCL_DATA_LESS_PROP
26+
#undef __SYCL_MANUALLY_DEFINED_PROP
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//==----------- graph_properties.hpp --- SYCL graph properties -------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include <sycl/detail/property_helper.hpp> // for DataLessPropKind
12+
#include <sycl/properties/property_traits.hpp> // for is_property_of
13+
14+
#include <type_traits> // for true_type
15+
16+
namespace sycl {
17+
inline namespace _V1 {
18+
namespace ext {
19+
namespace oneapi {
20+
namespace experimental {
21+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \
22+
namespace NS_QUALIFIER { \
23+
class PROP_NAME \
24+
: public sycl::detail::DataLessProperty<sycl::detail::ENUM_VAL> {}; \
25+
}
26+
#include <sycl/ext/oneapi/experimental/detail/properties/graph_properties.def>
27+
28+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \
29+
namespace NS_QUALIFIER { \
30+
class PROP_NAME \
31+
: public sycl::detail::DataLessProperty<sycl::detail::ENUM_VAL> {}; \
32+
}
33+
#include <sycl/ext/oneapi/experimental/detail/properties/node_properties.def>
34+
35+
class node;
36+
namespace property::node {
37+
class depends_on;
38+
} // namespace property::node
39+
// Graph property trait specializations.
40+
enum class graph_state;
41+
template <graph_state State> class command_graph;
42+
43+
} // namespace experimental
44+
} // namespace oneapi
45+
} // namespace ext
46+
47+
#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \
48+
template <ext::oneapi::experimental::graph_state State> \
49+
struct is_property_of<ext::oneapi::experimental::NS_QUALIFIER::PROP_NAME, \
50+
ext::oneapi::experimental::command_graph<State>> \
51+
: std::true_type {};
52+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \
53+
__SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME)
54+
55+
#include <sycl/ext/oneapi/experimental/detail/properties/graph_properties.def>
56+
57+
#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \
58+
template <> \
59+
struct is_property_of<ext::oneapi::experimental::NS_QUALIFIER::PROP_NAME, \
60+
ext::oneapi::experimental::node> : std::true_type {};
61+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \
62+
__SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME)
63+
64+
#include <sycl/ext/oneapi/experimental/detail/properties/node_properties.def>
65+
66+
} // namespace _V1
67+
} // namespace sycl
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// --*- c++ -*---
2+
#ifndef __SYCL_DATA_LESS_PROP
3+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL)
4+
#endif
5+
#ifndef __SYCL_MANUALLY_DEFINED_PROP
6+
#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME)
7+
#endif
8+
9+
/// Property used to to add all previous graph leaves as dependencies when
10+
/// creating a new node with command_graph::add().
11+
__SYCL_DATA_LESS_PROP(property::node, depends_on_all_leaves, GraphDependOnAllLeaves)
12+
13+
// Contains data field, defined explicitly.
14+
__SYCL_MANUALLY_DEFINED_PROP(property::node, depends_on)
15+
16+
#undef __SYCL_DATA_LESS_PROP
17+
#undef __SYCL_MANUALLY_DEFINED_PROP

sycl/include/sycl/ext/oneapi/experimental/graph.hpp

Lines changed: 7 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <sycl/detail/string_view.hpp>
1919
#endif
2020
#include <sycl/device.hpp> // for device
21+
#include <sycl/ext/oneapi/experimental/detail/properties/graph_properties.hpp> // for graph properties classes
2122
#include <sycl/nd_range.hpp> // for range, nd_range
2223
#include <sycl/properties/property_traits.hpp> // for is_property, is_property_of
2324
#include <sycl/property_list.hpp> // for property_list
@@ -153,47 +154,7 @@ class __SYCL_EXPORT node {
153154
std::shared_ptr<detail::node_impl> impl;
154155
};
155156

156-
namespace property {
157-
namespace graph {
158-
159-
/// Property passed to command_graph constructor to disable checking for cycles.
160-
///
161-
class no_cycle_check : public ::sycl::detail::DataLessProperty<
162-
::sycl::detail::GraphNoCycleCheck> {
163-
public:
164-
no_cycle_check() = default;
165-
};
166-
167-
/// Property passed to command_graph constructor to allow buffers to be used
168-
/// with graphs. Passing this property represents a promise from the user that
169-
/// the buffer will outlive any graph that it is used in.
170-
///
171-
class assume_buffer_outlives_graph
172-
: public ::sycl::detail::DataLessProperty<
173-
::sycl::detail::GraphAssumeBufferOutlivesGraph> {
174-
public:
175-
assume_buffer_outlives_graph() = default;
176-
};
177-
178-
/// Property passed to command_graph<graph_state::modifiable>::finalize() to
179-
/// mark the resulting executable command_graph as able to be updated.
180-
class updatable
181-
: public ::sycl::detail::DataLessProperty<::sycl::detail::GraphUpdatable> {
182-
public:
183-
updatable() = default;
184-
};
185-
186-
/// Property used to enable executable graph profiling. Enables profiling on
187-
/// events returned by submissions of the executable graph
188-
class enable_profiling : public ::sycl::detail::DataLessProperty<
189-
::sycl::detail::GraphEnableProfiling> {
190-
public:
191-
enable_profiling() = default;
192-
};
193-
} // namespace graph
194-
195-
namespace node {
196-
157+
namespace property::node {
197158
/// Property used to define dependent nodes when creating a new node with
198159
/// command_graph::add().
199160
class depends_on : public ::sycl::detail::PropertyWithData<
@@ -209,17 +170,7 @@ class depends_on : public ::sycl::detail::PropertyWithData<
209170
private:
210171
const std::vector<::sycl::ext::oneapi::experimental::node> MDeps;
211172
};
212-
213-
/// Property used to to add all previous graph leaves as dependencies when
214-
/// creating a new node with command_graph::add().
215-
class depends_on_all_leaves : public ::sycl::detail::DataLessProperty<
216-
::sycl::detail::GraphDependOnAllLeaves> {
217-
public:
218-
depends_on_all_leaves() = default;
219-
};
220-
221-
} // namespace node
222-
} // namespace property
173+
} // namespace property::node
223174

224175
class __SYCL_EXPORT dynamic_command_group {
225176
public:
@@ -260,6 +211,7 @@ class __SYCL_EXPORT modifiable_command_graph
260211
/// @param PropList Property list used to pass [0..n] predecessor nodes.
261212
/// @return Constructed empty node which has been added to the graph.
262213
node add(const property_list &PropList = {}) {
214+
checkNodePropertiesAndThrow(PropList);
263215
if (PropList.has_property<property::node::depends_on>()) {
264216
auto Deps = PropList.get_property<property::node::depends_on>();
265217
node Node = addImpl(Deps.get_dependencies());
@@ -280,6 +232,7 @@ class __SYCL_EXPORT modifiable_command_graph
280232
/// @param PropList Property list used to pass [0..n] predecessor nodes.
281233
/// @return Constructed node which has been added to the graph.
282234
template <typename T> node add(T CGF, const property_list &PropList = {}) {
235+
checkNodePropertiesAndThrow(PropList);
283236
if (PropList.has_property<property::node::depends_on>()) {
284237
auto Deps = PropList.get_property<property::node::depends_on>();
285238
node Node = addImpl(CGF, Deps.get_dependencies());
@@ -391,6 +344,8 @@ class __SYCL_EXPORT modifiable_command_graph
391344
template <class T>
392345
friend T sycl::detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
393346
std::shared_ptr<detail::graph_impl> impl;
347+
348+
static void checkNodePropertiesAndThrow(const property_list &Properties);
394349
};
395350

396351
#ifndef ___INTEL_PREVIEW_BREAKING_CHANGES
@@ -555,24 +510,5 @@ command_graph(const context &SyclContext, const device &SyclDevice,
555510
} // namespace oneapi
556511
} // namespace ext
557512

558-
template <>
559-
struct is_property<ext::oneapi::experimental::property::graph::no_cycle_check>
560-
: std::true_type {};
561-
562-
template <>
563-
struct is_property<ext::oneapi::experimental::property::node::depends_on>
564-
: std::true_type {};
565-
566-
template <>
567-
struct is_property_of<
568-
ext::oneapi::experimental::property::graph::no_cycle_check,
569-
ext::oneapi::experimental::command_graph<
570-
ext::oneapi::experimental::graph_state::modifiable>> : std::true_type {
571-
};
572-
573-
template <>
574-
struct is_property_of<ext::oneapi::experimental::property::node::depends_on,
575-
ext::oneapi::experimental::node> : std::true_type {};
576-
577513
} // namespace _V1
578514
} // namespace sycl

sycl/source/detail/graph_impl.cpp

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,48 @@ void exec_graph_impl::makePartitions() {
302302
}
303303
}
304304

305+
static void checkGraphPropertiesAndThrow(const property_list &Properties) {
306+
auto CheckDataLessProperties = [](int PropertyKind) {
307+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \
308+
case NS_QUALIFIER::PROP_NAME::getKind(): \
309+
return true;
310+
#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME)
311+
switch (PropertyKind) {
312+
#include <sycl/ext/oneapi/experimental/detail/properties/graph_properties.def>
313+
default:
314+
return false;
315+
}
316+
};
317+
// No properties with data for graph now.
318+
auto NoAllowedPropertiesCheck = [](int) { return false; };
319+
sycl::detail::PropertyValidator::checkPropsAndThrow(
320+
Properties, CheckDataLessProperties, NoAllowedPropertiesCheck);
321+
}
322+
323+
graph_impl::graph_impl(const sycl::context &SyclContext,
324+
const sycl::device &SyclDevice,
325+
const sycl::property_list &PropList)
326+
: MContext(SyclContext), MDevice(SyclDevice), MRecordingQueues(),
327+
MEventsMap(), MInorderQueueMap() {
328+
checkGraphPropertiesAndThrow(PropList);
329+
if (PropList.has_property<property::graph::no_cycle_check>()) {
330+
MSkipCycleChecks = true;
331+
}
332+
if (PropList.has_property<property::graph::assume_buffer_outlives_graph>()) {
333+
MAllowBuffers = true;
334+
}
335+
336+
if (!SyclDevice.has(aspect::ext_oneapi_limited_graph) &&
337+
!SyclDevice.has(aspect::ext_oneapi_graph)) {
338+
std::stringstream Stream;
339+
Stream << SyclDevice.get_backend();
340+
std::string BackendString = Stream.str();
341+
throw sycl::exception(
342+
sycl::make_error_code(errc::invalid),
343+
BackendString + " backend is not supported by SYCL Graph extension.");
344+
}
345+
}
346+
305347
graph_impl::~graph_impl() {
306348
try {
307349
clearQueues();
@@ -872,7 +914,7 @@ exec_graph_impl::exec_graph_impl(sycl::context Context,
872914
MIsUpdatable(PropList.has_property<property::graph::updatable>()),
873915
MEnableProfiling(
874916
PropList.has_property<property::graph::enable_profiling>()) {
875-
917+
checkGraphPropertiesAndThrow(PropList);
876918
// If the graph has been marked as updatable then check if the backend
877919
// actually supports that. Devices supporting aspect::ext_oneapi_graph must
878920
// have support for graph update.
@@ -1699,7 +1741,9 @@ modifiable_command_graph::finalize(const sycl::property_list &PropList) const {
16991741

17001742
void modifiable_command_graph::begin_recording(
17011743
queue &RecordingQueue, const sycl::property_list &PropList) {
1702-
std::ignore = PropList;
1744+
// No properties is handled here originally, just check that properties are
1745+
// related to graph at all.
1746+
checkGraphPropertiesAndThrow(PropList);
17031747

17041748
auto QueueImpl = sycl::detail::getSyclObjImpl(RecordingQueue);
17051749
assert(QueueImpl);
@@ -1784,6 +1828,34 @@ std::vector<node> modifiable_command_graph::get_root_nodes() const {
17841828
return createNodesFromImpls(Impls);
17851829
}
17861830

1831+
void modifiable_command_graph::checkNodePropertiesAndThrow(
1832+
const property_list &Properties) {
1833+
auto CheckDataLessProperties = [](int PropertyKind) {
1834+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \
1835+
case NS_QUALIFIER::PROP_NAME::getKind(): \
1836+
return true;
1837+
#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME)
1838+
switch (PropertyKind) {
1839+
#include <sycl/ext/oneapi/experimental/detail/properties/node_properties.def>
1840+
default:
1841+
return false;
1842+
}
1843+
};
1844+
auto CheckPropertiesWithData = [](int PropertyKind) {
1845+
#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL)
1846+
#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \
1847+
case NS_QUALIFIER::PROP_NAME::getKind(): \
1848+
return true;
1849+
switch (PropertyKind) {
1850+
#include <sycl/ext/oneapi/experimental/detail/properties/node_properties.def>
1851+
default:
1852+
return false;
1853+
}
1854+
};
1855+
sycl::detail::PropertyValidator::checkPropsAndThrow(
1856+
Properties, CheckDataLessProperties, CheckPropertiesWithData);
1857+
}
1858+
17871859
executable_command_graph::executable_command_graph(
17881860
const std::shared_ptr<detail::graph_impl> &Graph, const sycl::context &Ctx,
17891861
const property_list &PropList)

sycl/source/detail/graph_impl.hpp

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -779,27 +779,7 @@ class graph_impl : public std::enable_shared_from_this<graph_impl> {
779779
/// @param SyclDevice Device to create nodes with.
780780
/// @param PropList Optional list of properties.
781781
graph_impl(const sycl::context &SyclContext, const sycl::device &SyclDevice,
782-
const sycl::property_list &PropList = {})
783-
: MContext(SyclContext), MDevice(SyclDevice), MRecordingQueues(),
784-
MEventsMap(), MInorderQueueMap() {
785-
if (PropList.has_property<property::graph::no_cycle_check>()) {
786-
MSkipCycleChecks = true;
787-
}
788-
if (PropList
789-
.has_property<property::graph::assume_buffer_outlives_graph>()) {
790-
MAllowBuffers = true;
791-
}
792-
793-
if (!SyclDevice.has(aspect::ext_oneapi_limited_graph) &&
794-
!SyclDevice.has(aspect::ext_oneapi_graph)) {
795-
std::stringstream Stream;
796-
Stream << SyclDevice.get_backend();
797-
std::string BackendString = Stream.str();
798-
throw sycl::exception(
799-
sycl::make_error_code(errc::invalid),
800-
BackendString + " backend is not supported by SYCL Graph extension.");
801-
}
802-
}
782+
const sycl::property_list &PropList = {});
803783

804784
~graph_impl();
805785

0 commit comments

Comments
 (0)