DPC++ Runtime
Runtime libraries for oneAPI DPC++
device.cpp
Go to the documentation of this file.
1 //==------------------- device.cpp -----------------------------------------==//
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 
10 #include <detail/config.hpp>
11 #include <detail/device_impl.hpp>
14 #include <sycl/detail/export.hpp>
15 #include <sycl/detail/ur.hpp>
16 #include <sycl/device.hpp>
17 #include <sycl/device_selector.hpp>
18 #include <sycl/info/info_desc.hpp>
19 
20 namespace sycl {
21 inline namespace _V1 {
22 namespace detail {
24  if (t == info::device_type::all) {
25  t = ft;
26  } else if (ft != info::device_type::all && t != ft) {
28  "No device of forced type.");
29  }
30 }
31 } // namespace detail
32 
34 
35 device::device(cl_device_id DeviceId) {
36  auto Plugin = sycl::detail::ur::getPlugin<backend::opencl>();
37  // The implementation constructor takes ownership of the native handle so we
38  // must retain it in order to adhere to SYCL 1.2.1 spec (Rev6, section 4.3.1.)
39  ur_device_handle_t Device;
40  Plugin->call(urDeviceCreateWithNativeHandle,
41  detail::ur::cast<ur_native_handle_t>(DeviceId),
42  Plugin->getUrPlatforms()[0], nullptr, &Device);
43  auto Platform =
45  impl = Platform->getOrMakeDeviceImpl(Device, Platform);
46  Plugin->call(urDeviceRetain, impl->getHandleRef());
47 }
48 
49 device::device(const device_selector &deviceSelector) {
50  *this = deviceSelector.select_device();
51 }
52 
53 std::vector<device> device::get_devices(info::device_type deviceType) {
54  std::vector<device> devices;
55  detail::ods_target_list *OdsTargetList =
57 
58  auto thePlatforms = platform::get_platforms();
59  for (const auto &plt : thePlatforms) {
60 
61  backend platformBackend = plt.get_backend();
62  if (OdsTargetList && !OdsTargetList->backendCompatible(platformBackend))
63  continue;
64 
65  std::vector<device> found_devices(plt.get_devices(deviceType));
66  if (!found_devices.empty())
67  devices.insert(devices.end(), found_devices.begin(), found_devices.end());
68  }
69 
70  return devices;
71 }
72 
73 cl_device_id device::get() const { return impl->get(); }
74 
75 bool device::is_cpu() const { return impl->is_cpu(); }
76 
77 bool device::is_gpu() const { return impl->is_gpu(); }
78 
79 bool device::is_accelerator() const { return impl->is_accelerator(); }
80 
81 platform device::get_platform() const { return impl->get_platform(); }
82 
83 template <info::partition_property prop>
84 std::vector<device> device::create_sub_devices(size_t ComputeUnits) const {
85  return impl->create_sub_devices(ComputeUnits);
86 }
87 
88 template __SYCL_EXPORT std::vector<device>
89 device::create_sub_devices<info::partition_property::partition_equally>(
90  size_t ComputeUnits) const;
91 
92 template <info::partition_property prop>
93 std::vector<device>
94 device::create_sub_devices(const std::vector<size_t> &Counts) const {
95  return impl->create_sub_devices(Counts);
96 }
97 
98 template __SYCL_EXPORT std::vector<device>
99 device::create_sub_devices<info::partition_property::partition_by_counts>(
100  const std::vector<size_t> &Counts) const;
101 
102 template <info::partition_property prop>
103 std::vector<device> device::create_sub_devices(
104  info::partition_affinity_domain AffinityDomain) const {
105  return impl->create_sub_devices(AffinityDomain);
106 }
107 
108 template __SYCL_EXPORT std::vector<device> device::create_sub_devices<
110  info::partition_affinity_domain AffinityDomain) const;
111 
112 template <info::partition_property prop>
113 std::vector<device> device::create_sub_devices() const {
114  return impl->create_sub_devices();
115 }
116 
117 template __SYCL_EXPORT std::vector<device> device::create_sub_devices<
119 
120 bool device::has_extension(detail::string_view ext_name) const {
121  return impl->has_extension(ext_name.data());
122 }
123 
124 template <typename Param>
125 detail::ABINeutralT_t<typename detail::is_device_info_desc<Param>::return_type>
126 device::get_info_impl() const {
127  return detail::convert_to_abi_neutral(impl->template get_info<Param>());
128 }
129 
130 // Explicit override. Not fulfilled by #include device_traits.def below.
131 template <>
132 __SYCL_EXPORT device
133 device::get_info_impl<info::device::parent_device>() const {
134  // With ONEAPI_DEVICE_SELECTOR the impl.MRootDevice is preset and may be
135  // overridden (ie it may be nullptr on a sub-device) The sub-devices
136  // have parents, but we don't want to return them. They must pretend to be
137  // parentless root devices.
138  if (impl->isRootDevice())
140  "No parent for device because it is not a subdevice");
141  else
142  return impl->template get_info<info::device::parent_device>();
143 }
144 
145 template <>
146 __SYCL_EXPORT std::vector<sycl::aspect>
147 device::get_info_impl<info::device::aspects>() const {
148  std::vector<sycl::aspect> DeviceAspects{
149 #define __SYCL_ASPECT(ASPECT, ID) aspect::ASPECT,
150 #include <sycl/info/aspects.def>
151 #undef __SYCL_ASPECT
152  };
153 
154  auto UnsupportedAspects =
155  std::remove_if(DeviceAspects.begin(), DeviceAspects.end(),
156  [&](aspect Aspect) { return !impl->has(Aspect); });
157 
158  DeviceAspects.erase(UnsupportedAspects, DeviceAspects.end());
159 
160  return DeviceAspects;
161 }
162 
163 template <>
164 __SYCL_EXPORT bool device::get_info_impl<info::device::image_support>() const {
165  // Explicit specialization is needed due to the class of info handle. The
166  // implementation is done in get_device_info_impl.
167  return impl->template get_info<info::device::image_support>();
168 }
169 
170 #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \
171  template __SYCL_EXPORT detail::ABINeutralT_t<ReturnT> \
172  device::get_info_impl<info::device::Desc>() const;
173 
174 #define __SYCL_PARAM_TRAITS_SPEC_SPECIALIZED(DescType, Desc, ReturnT, PiCode)
175 
176 #include <sycl/info/device_traits.def>
177 #undef __SYCL_PARAM_TRAITS_SPEC_SPECIALIZED
178 #undef __SYCL_PARAM_TRAITS_SPEC
179 
180 #define __SYCL_PARAM_TRAITS_SPEC(Namespace, DescType, Desc, ReturnT, PiCode) \
181  template __SYCL_EXPORT detail::ABINeutralT_t<ReturnT> \
182  device::get_info_impl<Namespace::info::DescType::Desc>() const;
183 
184 #include <sycl/info/ext_codeplay_device_traits.def>
185 #include <sycl/info/ext_intel_device_traits.def>
186 #include <sycl/info/ext_oneapi_device_traits.def>
187 #undef __SYCL_PARAM_TRAITS_SPEC
188 
189 template <typename Param>
190 typename detail::is_backend_info_desc<Param>::return_type
192  return impl->get_backend_info<Param>();
193 }
194 
195 #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, Picode) \
196  template __SYCL_EXPORT ReturnT \
197  device::get_backend_info<info::DescType::Desc>() const;
198 
199 #include <sycl/info/sycl_backend_traits.def>
200 
201 #undef __SYCL_PARAM_TRAITS_SPEC
202 
203 backend device::get_backend() const noexcept { return impl->getBackend(); }
204 
205 ur_native_handle_t device::getNative() const { return impl->getNative(); }
206 
207 bool device::has(aspect Aspect) const { return impl->has(Aspect); }
208 
210  ur_device_handle_t Device = impl->getHandleRef();
211  ur_device_handle_t Peer = peer.impl->getHandleRef();
212  if (Device != Peer) {
213  auto Plugin = impl->getPlugin();
214  Plugin->call(urUsmP2PEnablePeerAccessExp, Device, Peer);
215  }
216 }
217 
219  ur_device_handle_t Device = impl->getHandleRef();
220  ur_device_handle_t Peer = peer.impl->getHandleRef();
221  if (Device != Peer) {
222  auto Plugin = impl->getPlugin();
223  Plugin->call(urUsmP2PDisablePeerAccessExp, Device, Peer);
224  }
225 }
226 
229  ur_device_handle_t Device = impl->getHandleRef();
230  ur_device_handle_t Peer = peer.impl->getHandleRef();
231 
232  if (Device == Peer) {
233  return true;
234  }
235 
236  size_t returnSize;
237  int value;
238 
239  ur_exp_peer_info_t UrAttr = [&]() {
240  switch (attr) {
242  return UR_EXP_PEER_INFO_UR_PEER_ACCESS_SUPPORTED;
244  return UR_EXP_PEER_INFO_UR_PEER_ATOMICS_SUPPORTED;
245  }
247  "Unrecognized peer access attribute.");
248  }();
249  auto Plugin = impl->getPlugin();
250  Plugin->call(urUsmP2PPeerAccessGetInfoExp, Device, Peer, UrAttr, sizeof(int),
251  &value, &returnSize);
252 
253  return value == 1;
254 }
255 
258  return impl->extOneapiArchitectureIs(arch);
259 }
260 
263  return impl->extOneapiArchitectureIs(category);
264 }
265 
266 // kernel_compiler extension methods
269  return impl->extOneapiCanCompile(Language);
270 }
271 
273  ur_device_handle_t Device = impl->getHandleRef();
274  auto Plugin = impl->getPlugin();
275  uint32_t ipVersion = 0;
276  auto res =
277  Plugin->call_nocheck(urDeviceGetInfo, Device, UR_DEVICE_INFO_IP_VERSION,
278  sizeof(uint32_t), &ipVersion, nullptr);
279  if (res != UR_RESULT_SUCCESS)
280  return false;
281 
283  Feature.data(), ipVersion);
284 }
285 
287  const ext::oneapi::experimental::cl_version &Version) const {
288  ur_device_handle_t Device = impl->getHandleRef();
289  auto Plugin = impl->getPlugin();
290  uint32_t ipVersion = 0;
291  auto res =
292  Plugin->call_nocheck(urDeviceGetInfo, Device, UR_DEVICE_INFO_IP_VERSION,
293  sizeof(uint32_t), &ipVersion, nullptr);
294  if (res != UR_RESULT_SUCCESS)
295  return false;
296 
298  ipVersion);
299 }
300 
302  detail::string_view Name,
303  ext::oneapi::experimental::cl_version *VersionPtr) const {
304  ur_device_handle_t Device = impl->getHandleRef();
305  auto Plugin = impl->getPlugin();
306  uint32_t ipVersion = 0;
307  auto res =
308  Plugin->call_nocheck(urDeviceGetInfo, Device, UR_DEVICE_INFO_IP_VERSION,
309  sizeof(uint32_t), &ipVersion, nullptr);
310  if (res != UR_RESULT_SUCCESS)
311  return false;
312 
314  Name.data(), VersionPtr, ipVersion);
315 }
316 
317 std::string device::ext_oneapi_cl_profile() const {
318  ur_device_handle_t Device = impl->getHandleRef();
319  auto Plugin = impl->getPlugin();
320  uint32_t ipVersion = 0;
321  auto res =
322  Plugin->call_nocheck(urDeviceGetInfo, Device, UR_DEVICE_INFO_IP_VERSION,
323  sizeof(uint32_t), &ipVersion, nullptr);
324  if (res != UR_RESULT_SUCCESS)
325  return "";
326 
328 }
329 
330 } // namespace _V1
331 } // namespace sycl
static const char * get()
Definition: config.hpp:115
bool backendCompatible(backend Backend)
static std::shared_ptr< platform_impl > getPlatformFromUrDevice(ur_device_handle_t UrDevice, const PluginPtr &Plugin)
Queries the cache for the specified platform based on an input device.
const char * data() const noexcept
Definition: string_view.hpp:38
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:64
bool ext_oneapi_supports_cl_extension(const std::string &name, ext::oneapi::experimental::cl_version *version=nullptr) const
If the device supports kernel bundles using the OpenCL extension identified by name and if version is...
Definition: device.hpp:325
bool ext_oneapi_can_access_peer(const device &peer, ext::oneapi::peer_access value=ext::oneapi::peer_access::access_supported)
Definition: device.cpp:227
detail::is_backend_info_desc< Param >::return_type get_backend_info() const
Queries this SYCL device for SYCL backend-specific information.
Definition: device.cpp:191
bool is_accelerator() const
Check if device is an accelerator device.
Definition: device.cpp:79
bool is_gpu() const
Check if device is a GPU device.
Definition: device.cpp:77
bool has_extension(const std::string &extension_name) const
Check SYCL extension support by device.
Definition: device.hpp:231
static std::vector< device > get_devices(info::device_type deviceType=info::device_type::all)
Query available SYCL devices.
Definition: device.cpp:53
bool ext_oneapi_can_compile(ext::oneapi::experimental::source_language Language)
kernel_compiler extension
Definition: device.cpp:267
backend get_backend() const noexcept
Returns the backend associated with this device.
Definition: device.cpp:203
bool ext_oneapi_architecture_is(ext::oneapi::experimental::architecture arch)
Indicates if the SYCL device architecture equals to the one passed to the function.
Definition: device.cpp:256
bool ext_oneapi_supports_cl_c_version(const ext::oneapi::experimental::cl_version &Version) const
Indicates if the device supports kernel bundles written in a particular OpenCL C version.
Definition: device.cpp:286
bool is_cpu() const
Get instance of device.
Definition: device.cpp:75
bool ext_oneapi_supports_cl_c_feature(const std::string &Feature)
Indicates if the device supports a given feature when compiling the OpenCL C language.
Definition: device.hpp:305
std::vector< device > create_sub_devices() const
Partition device into sub devices.
Definition: device.cpp:113
void ext_oneapi_enable_peer_access(const device &peer)
Definition: device.cpp:209
void ext_oneapi_disable_peer_access(const device &peer)
Definition: device.cpp:218
std::string ext_oneapi_cl_profile() const
Retrieve the OpenCl Device Profile.
Definition: device.cpp:317
device()
Constructs a SYCL device instance using the default device.
Definition: device.cpp:33
platform get_platform() const
Get associated SYCL platform.
Definition: device.cpp:81
bool has(aspect Aspect) const __SYCL_WARN_IMAGE_ASPECT(Aspect)
Indicates if the SYCL device has the given feature.
Definition: device.cpp:207
Encapsulates a SYCL platform on which kernels may be executed.
Definition: platform.hpp:99
static std::vector< platform > get_platforms()
Returns all available SYCL platforms in the system.
Definition: platform.cpp:51
constexpr tuple_element< I, tuple< Types... > >::type & get(sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:198
auto convert_to_abi_neutral(ParamT &&Info)
Definition: platform.hpp:58
void force_type(info::device_type &t, const info::device_type &ft)
Definition: device.cpp:23
bool OpenCLC_Feature_Available(const std::string &Feature, uint32_t IPVersion)
bool OpenCLC_Supports_Extension(const std::string &Name, ext::oneapi::experimental::cl_version *VersionPtr, uint32_t IPVersion)
bool OpenCLC_Supports_Version(const ext::oneapi::experimental::cl_version &Version, uint32_t IPVersion)
int default_selector_v(const device &dev)
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
Definition: exception.cpp:65
Definition: access.hpp:18
_Abi const simd< _Tp, _Abi > & noexcept
Definition: simd.hpp:1324
C++ utilities for Unified Runtime integration.