11
11
#include < CL/sycl/detail/device_info.hpp>
12
12
#include < CL/sycl/detail/pi.hpp>
13
13
#include < CL/sycl/stl.hpp>
14
- #include < algorithm>
15
14
#include < memory>
16
15
17
16
namespace cl {
@@ -21,44 +20,141 @@ namespace sycl {
21
20
class platform ;
22
21
23
22
namespace detail {
24
- // TODO: 4.6.4 Partitioning into multiple SYCL devices
25
- // TODO: 4.6.4.2 Device information descriptors
23
+
24
+ // Forward declaration
25
+ class platform_impl ;
26
+ class platform_impl_pi ;
27
+
26
28
// TODO: Make code thread-safe
27
29
class device_impl {
28
30
public:
29
- virtual ~device_impl () = default ;
30
-
31
- virtual cl_device_id get () const = 0;
32
-
33
- // Returns underlying native device object (if any) w/o reference count
34
- // modification. Caller must ensure the returned object lives on stack only.
35
- // It can also be safely passed to the underlying native runtime API.
36
- // Warning. Returned reference will be invalid if device_impl was destroyed.
37
- //
38
- virtual RT::PiDevice &getHandleRef () = 0;
39
- virtual const RT::PiDevice &getHandleRef () const = 0;
40
-
41
- virtual bool is_host () const = 0;
42
-
43
- virtual bool is_cpu () const = 0;
44
-
45
- virtual bool is_gpu () const = 0;
46
-
47
- virtual bool is_accelerator () const = 0;
48
-
49
- virtual platform get_platform () const = 0;
31
+ // / Constructs a SYCL device instance as a host device.
32
+ device_impl ();
33
+ // / Constructs a SYCL device instance using the provided
34
+ // / PI device instance.
35
+ explicit device_impl (RT::PiDevice Device);
36
+
37
+ ~device_impl ();
38
+
39
+ // / Get instance of OpenCL device
40
+ // /
41
+ // / @return a valid cl_device_id instance in accordance with the requirements
42
+ // / described in 4.3.1.
43
+ cl_device_id get () const ;
44
+
45
+ // / Get reference to PI device
46
+ // /
47
+ // / For host device an exception is thrown
48
+ // /
49
+ // / @return non-constant reference to PI device
50
+ RT::PiDevice &getHandleRef () {
51
+ if (MIsHostDevice)
52
+ throw invalid_object_error (" This instance of device is a host instance" );
53
+
54
+ return MDevice;
55
+ }
56
+
57
+ // / Get constant reference to PI device
58
+ // /
59
+ // / For host device an exception is thrown
60
+ // /
61
+ // / @return constant reference to PI device
62
+ const RT::PiDevice &getHandleRef () const {
63
+ if (MIsHostDevice)
64
+ throw invalid_object_error (" This instance of device is a host instance" );
65
+
66
+ return MDevice;
67
+ }
68
+
69
+ // / Check if SYCL device is a host device
70
+ // /
71
+ // / @return true if SYCL device is a host device
72
+ bool is_host () const { return MIsHostDevice; }
73
+
74
+ // / Check if device is a CPU device
75
+ // /
76
+ // / @return true if SYCL device is a CPU device
77
+ bool is_cpu () const { return (MType == PI_DEVICE_TYPE_CPU); }
78
+
79
+ // / Check if device is a GPU device
80
+ // /
81
+ // / @return true if SYCL device is a GPU device
82
+ bool is_gpu () const { return (MType == PI_DEVICE_TYPE_GPU); }
83
+
84
+ // / Check if device is an accelerator device
85
+ // /
86
+ // / @return true if SYCL device is an accelerator device
87
+ bool is_accelerator () const { return (MType == PI_DEVICE_TYPE_ACC); }
88
+
89
+ // / Get associated SYCL platform
90
+ // /
91
+ // / If this SYCL device is an OpenCL device then the SYCL platform
92
+ // / must encapsulate the OpenCL cl_plaform_id associated with the
93
+ // / underlying OpenCL cl_device_id of this SYCL device. If this SYCL device
94
+ // / is a host device then the SYCL platform must be a host platform.
95
+ // / The value returned must be equal to that returned
96
+ // / by get_info<info::device::platform>().
97
+ // /
98
+ // / @return The associated SYCL platform.
99
+ platform get_platform () const ;
100
+
101
+ // / Check SYCL extension support by device
102
+ // /
103
+ // / @param ExtensionName is a name of queried extension.
104
+ // / @return true if SYCL device supports the extension.
105
+ bool has_extension (const string_class &ExtensionName) const ;
50
106
51
- virtual vector_class<device> create_sub_devices (size_t nbSubDev) const = 0;
52
-
53
- virtual vector_class<device>
54
- create_sub_devices (const vector_class<size_t > &counts) const = 0 ;
55
-
56
- virtual vector_class<device>
57
- create_sub_devices (info::partition_affinity_domain affinityDomain) const = 0 ;
58
-
59
- static vector_class<device>
60
- get_devices (info::device_type deviceType = info::device_type::all);
107
+ vector_class<device>
108
+ create_sub_devices (const cl_device_partition_property *Properties,
109
+ size_t SubDevicesCount) const ;
61
110
111
+ // / Partition device into sub devices
112
+ // /
113
+ // / If this SYCL device does not support info::partition_property::partition_equally
114
+ // / a feature_not_supported exception must be thrown.
115
+ // /
116
+ // / @param ComputeUnits is a desired count of compute units in each sub device.
117
+ // / @return A vector class of sub devices partitioned equally from this
118
+ // / SYCL device based on the ComputeUnits parameter.
119
+ vector_class<device> create_sub_devices (size_t ComputeUnits) const ;
120
+
121
+ // / Partition device into sub devices
122
+ // /
123
+ // / If this SYCL device does not support info::partition_property::partition_by_counts
124
+ // / a feature_not_supported exception must be thrown.
125
+ // /
126
+ // / @param Counts is a vector_class of desired compute units in sub devices.
127
+ // / @return a vector_class of sub devices partitioned from this SYCL device
128
+ // / by count sizes based on the Counts parameter.
129
+ vector_class<device>
130
+ create_sub_devices (const vector_class<size_t > &Counts) const ;
131
+
132
+ // / Partition device into sub devices
133
+ // /
134
+ // / If this SYCL device does not support info::partition_property::partition_by_affinity_domain
135
+ // / or the SYCL device does not support info::affinity_domain provided
136
+ // / a feature_not_supported exception must be thrown.
137
+ // /
138
+ // / @param AffinityDomain is one of the values described in Table 4.20 of SYCL Spec
139
+ // / @return a vector class of sub devices partitioned from this SYCL device
140
+ // / by affinity domain based on the AffinityDomain parameter
141
+ vector_class<device>
142
+ create_sub_devices (info::partition_affinity_domain AffinityDomain) const ;
143
+
144
+ // / Check if desired partition property supported by device
145
+ // /
146
+ // / @param Prop is one of info::partition_property::(partition_equally,
147
+ // / partition_by_counts, partition_by_affinity_domain)
148
+ // / @return true if Prop is supported by device.
149
+ bool is_partition_supported (info::partition_property Prop) const ;
150
+
151
+ // / Queries this SYCL device for information requested by the template parameter param
152
+ // /
153
+ // / Specializations of info::param_traits must be defined in accordance
154
+ // / with the info parameters in Table 4.20 of SYCL Spec to facilitate
155
+ // / returning the type associated with the param parameter.
156
+ // /
157
+ // / @return device info of type described in Table 4.20.
62
158
template <info::device param>
63
159
typename info::param_traits<info::device, param>::return_type
64
160
get_info () const {
@@ -70,163 +166,19 @@ class device_impl {
70
166
param>::_ (this ->getHandleRef ());
71
167
}
72
168
73
- bool is_partition_supported (info::partition_property Prop) const {
74
- auto SupportedProperties = get_info<info::device::partition_properties>();
75
- return std::find (SupportedProperties.begin (), SupportedProperties.end (),
76
- Prop) != SupportedProperties.end ();
77
- }
78
-
169
+ // / Check if affinity partitioning by specified domain is supported by device
170
+ // /
171
+ // / @param AffinityDomain is one of the values described in Table 4.20 of SYCL Spec
172
+ // / @return true if AffinityDomain is supported by device.
79
173
bool
80
- is_affinity_supported (info::partition_affinity_domain AffinityDomain) const {
81
- auto SupportedDomains =
82
- get_info<info::device::partition_affinity_domains>();
83
- return std::find (SupportedDomains.begin (), SupportedDomains.end (),
84
- AffinityDomain) != SupportedDomains.end ();
85
- }
86
-
87
- virtual bool has_extension (const string_class &extension_name) const = 0;
88
- };
89
-
90
- // TODO: 4.6.4 Partitioning into multiple SYCL devices
91
- // TODO: 4.6.4.2 Device information descriptors
92
- // TODO: Make code thread-safe
93
- class device_impl_pi : public device_impl {
94
- public:
95
- explicit device_impl_pi (RT::PiDevice a_device) : m_device(a_device) {
96
- // TODO catch an exception and put it to list of asynchronous exceptions
97
- PI_CALL (RT::piDeviceGetInfo (
98
- m_device, PI_DEVICE_INFO_TYPE, sizeof (RT::PiDeviceType), &m_type, 0 ));
99
-
100
- RT::PiDevice parent;
101
- // TODO catch an exception and put it to list of asynchronous exceptions
102
- PI_CALL (RT::piDeviceGetInfo (
103
- m_device, PI_DEVICE_INFO_PARENT, sizeof (RT::PiDevice), &parent, 0 ));
104
-
105
- m_isRootDevice = (nullptr == parent);
106
- if (!m_isRootDevice) {
107
- // TODO catch an exception and put it to list of asynchronous exceptions
108
- PI_CALL (RT::piDeviceRetain (m_device));
109
- }
110
- }
111
-
112
- ~device_impl_pi () {
113
- if (!m_isRootDevice) {
114
- // TODO catch an exception and put it to list of asynchronous exceptions
115
- CHECK_OCL_CODE_NO_EXC (RT::piDeviceRelease (m_device));
116
- }
117
- }
118
-
119
- cl_device_id get () const override {
120
- if (!m_isRootDevice) {
121
- // TODO catch an exception and put it to list of asynchronous exceptions
122
- PI_CALL (RT::piDeviceRetain (m_device));
123
- }
124
- // TODO: check that device is an OpenCL interop one
125
- return pi ::cast<cl_device_id >(m_device);
126
- }
127
-
128
- RT::PiDevice &getHandleRef () override { return m_device; }
129
- const RT::PiDevice &getHandleRef () const override { return m_device; }
130
-
131
- bool is_host () const override { return false ; }
132
-
133
- bool is_cpu () const override { return (m_type == PI_DEVICE_TYPE_CPU); }
134
-
135
- bool is_gpu () const override { return (m_type == PI_DEVICE_TYPE_GPU); }
136
-
137
- bool is_accelerator () const override {
138
- return (m_type == PI_DEVICE_TYPE_ACC);
139
- }
140
-
141
- platform get_platform () const override {
142
- RT::PiPlatform plt;
143
- // TODO catch an exception and put it to list of asynchronous exceptions
144
- PI_CALL (RT::piDeviceGetInfo (
145
- m_device, PI_DEVICE_INFO_PLATFORM, sizeof (plt), &plt, 0 ));
146
-
147
- // TODO: this possibly will violate common reference semantics,
148
- // particularly, equality comparison may fail for two consecutive
149
- // get_platform() on the same device, as it compares impl objects.
150
- return createSyclObjFromImpl<platform>(
151
- std::make_shared<platform_impl_pi>(plt));
152
- }
153
-
154
- bool has_extension (const string_class &extension_name) const override {
155
- string_class all_extension_names =
156
- get_device_info<string_class, info::device::extensions>::_ (m_device);
157
- return (all_extension_names.find (extension_name) != std::string::npos);
158
- }
159
-
160
- vector_class<device>
161
- create_sub_devices (const cl_device_partition_property *Properties,
162
- size_t SubDevicesCount) const ;
163
-
164
- vector_class<device>
165
- create_sub_devices (size_t ComputeUnits) const override ;
166
-
167
- vector_class<device>
168
- create_sub_devices (const vector_class<size_t > &Counts) const override ;
169
-
170
- vector_class<device>
171
- create_sub_devices (info::partition_affinity_domain AffinityDomain) const override ;
174
+ is_affinity_supported (info::partition_affinity_domain AffinityDomain) const ;
172
175
173
176
private:
174
- RT::PiDevice m_device = 0 ;
175
- RT::PiDeviceType m_type;
176
- bool m_isRootDevice = false ;
177
- }; // class device_impl_pi
178
-
179
- // TODO: 4.6.4 Partitioning into multiple SYCL devices
180
- // TODO: 4.6.4.2 Device information descriptors
181
- // TODO: Make code thread-safe
182
- class device_host : public device_impl {
183
- public:
184
- device_host () = default ;
185
- cl_device_id get () const override {
186
- throw invalid_object_error (" This instance of device is a host instance" );
187
- }
188
- RT::PiDevice &getHandleRef () override {
189
- throw invalid_object_error (" This instance of device is a host instance" );
190
- }
191
- const RT::PiDevice &getHandleRef () const override {
192
- throw invalid_object_error (" This instance of device is a host instance" );
193
- }
194
-
195
- bool is_host () const override { return true ; }
196
-
197
- bool is_cpu () const override { return false ; }
198
-
199
- bool is_gpu () const override { return false ; }
200
-
201
- bool is_accelerator () const override { return false ; }
202
-
203
- platform get_platform () const override { return platform (); }
204
-
205
- bool has_extension (const string_class &extension_name) const override {
206
- // TODO: implement extension management;
207
- return false ;
208
- }
209
-
210
- vector_class<device> create_sub_devices (size_t nbSubDev) const override {
211
- // TODO: implement host device partitioning
212
- throw runtime_error (
213
- " Partitioning to subdevices of the host device is not implemented yet" );
214
- }
215
-
216
- vector_class<device>
217
- create_sub_devices (const vector_class<size_t > &counts) const override {
218
- // TODO: implement host device partitioning
219
- throw runtime_error (
220
- " Partitioning to subdevices of the host device is not implemented yet" );
221
- }
222
-
223
- vector_class<device>
224
- create_sub_devices (info::partition_affinity_domain affinityDomain) const override {
225
- // TODO: implement host device partitioning
226
- throw runtime_error (
227
- " Partitioning to subdevices of the host device is not implemented yet" );
228
- }
229
- }; // class device_host
177
+ RT::PiDevice MDevice = 0 ;
178
+ RT::PiDeviceType MType;
179
+ bool MIsRootDevice = false ;
180
+ bool MIsHostDevice;
181
+ }; // class device_impl
230
182
231
183
} // namespace detail
232
184
} // namespace sycl
0 commit comments