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>
13 #include <sycl/detail/export.hpp>
14 #include <sycl/device.hpp>
15 #include <sycl/device_selector.hpp>
16 #include <sycl/info/info_desc.hpp>
17 
18 #include <algorithm>
19 
20 namespace sycl {
22 namespace detail {
24  if (t == info::device_type::all) {
25  t = ft;
26  } else if (ft != info::device_type::all && t != ft) {
27  throw sycl::invalid_parameter_error("No device of forced type.",
28  PI_ERROR_INVALID_OPERATION);
29  }
30 }
31 } // namespace detail
32 
33 device::device() : device(default_selector_v) {}
34 
35 device::device(cl_device_id DeviceId) {
36  // The implementation constructor takes ownership of the native handle so we
37  // must retain it in order to adhere to SYCL 1.2.1 spec (Rev6, section 4.3.1.)
38  detail::RT::PiDevice Device;
39  auto Plugin = detail::RT::getPlugin<backend::opencl>();
41  detail::pi::cast<pi_native_handle>(DeviceId), nullptr, &Device);
42  auto Platform =
44  impl = Platform->getOrMakeDeviceImpl(Device, Platform);
45  Plugin.call<detail::PiApiKind::piDeviceRetain>(impl->getHandleRef());
46 }
47 
48 device::device(const device_selector &deviceSelector) {
49  *this = deviceSelector.select_device();
50 }
51 
52 std::vector<device> device::get_devices(info::device_type deviceType) {
53  std::vector<device> devices;
54  detail::device_filter_list *FilterList =
56  detail::ods_target_list *OdsTargetList =
58 
59  auto thePlatforms = platform::get_platforms();
60  for (const auto &plt : thePlatforms) {
61  // If SYCL_DEVICE_FILTER is set, skip platforms that is incompatible
62  // with the filter specification.
63  backend platformBackend = plt.get_backend();
64  if (FilterList && !FilterList->backendCompatible(platformBackend))
65  continue;
66  if (OdsTargetList && !OdsTargetList->backendCompatible(platformBackend))
67  continue;
68 
69  std::vector<device> found_devices(plt.get_devices(deviceType));
70  if (!found_devices.empty())
71  devices.insert(devices.end(), found_devices.begin(), found_devices.end());
72  }
73 
74  return devices;
75 }
76 
77 cl_device_id device::get() const { return impl->get(); }
78 
79 bool device::is_host() const {
80  bool IsHost = impl->is_host();
81  assert(!IsHost && "device::is_host should not be called in implementation.");
82  return IsHost;
83 }
84 
85 bool device::is_cpu() const { return impl->is_cpu(); }
86 
87 bool device::is_gpu() const { return impl->is_gpu(); }
88 
89 bool device::is_accelerator() const { return impl->is_accelerator(); }
90 
91 platform device::get_platform() const { return impl->get_platform(); }
92 
93 template <info::partition_property prop>
94 std::vector<device> device::create_sub_devices(size_t ComputeUnits) const {
95  return impl->create_sub_devices(ComputeUnits);
96 }
97 
98 template __SYCL_EXPORT std::vector<device>
99 device::create_sub_devices<info::partition_property::partition_equally>(
100  size_t ComputeUnits) const;
101 
102 template <info::partition_property prop>
103 std::vector<device>
104 device::create_sub_devices(const std::vector<size_t> &Counts) const {
105  return impl->create_sub_devices(Counts);
106 }
107 
108 template __SYCL_EXPORT std::vector<device>
109 device::create_sub_devices<info::partition_property::partition_by_counts>(
110  const std::vector<size_t> &Counts) const;
111 
112 template <info::partition_property prop>
113 std::vector<device> device::create_sub_devices(
114  info::partition_affinity_domain AffinityDomain) const {
115  return impl->create_sub_devices(AffinityDomain);
116 }
117 
118 template __SYCL_EXPORT std::vector<device> device::create_sub_devices<
120  info::partition_affinity_domain AffinityDomain) const;
121 
122 template <info::partition_property prop>
123 std::vector<device> device::create_sub_devices() const {
124  return impl->create_sub_devices();
125 }
126 
127 template __SYCL_EXPORT std::vector<device> device::create_sub_devices<
129 
130 bool device::has_extension(const std::string &extension_name) const {
131  return impl->has_extension(extension_name);
132 }
133 
134 template <typename Param>
137  return impl->template get_info<Param>();
138 }
139 
140 // Explicit override. Not fulfilled by #include device_traits.def below.
141 template <>
142 __SYCL_EXPORT device device::get_info<info::device::parent_device>() const {
143  // With ONEAPI_DEVICE_SELECTOR the impl.MRootDevice is preset and may be
144  // overridden (ie it may be nullptr on a sub-device) The PI of the sub-devices
145  // have parents, but we don't want to return them. They must pretend to be
146  // parentless root devices.
147  if (impl->isRootDevice())
148  throw invalid_object_error(
149  "No parent for device because it is not a subdevice",
150  PI_ERROR_INVALID_DEVICE);
151  else
152  return impl->template get_info<info::device::parent_device>();
153 }
154 
155 template <>
156 __SYCL_EXPORT std::vector<sycl::aspect>
157 device::get_info<info::device::aspects>() const {
158  std::vector<sycl::aspect> DeviceAspects{
159 #define __SYCL_ASPECT(ASPECT, ID) aspect::ASPECT,
160 #include <sycl/info/aspects.def>
161 #undef __SYCL_ASPECT
162  };
163 
164  auto UnsupportedAspects = std::remove_if(
165  DeviceAspects.begin(), DeviceAspects.end(), [&](aspect Aspect) {
166  try {
167  return !impl->has(Aspect);
168  } catch (const runtime_error &ex) {
169  if (ex.get_cl_code() == PI_ERROR_INVALID_DEVICE)
170  return true;
171  throw;
172  }
173  });
174 
175  DeviceAspects.erase(UnsupportedAspects, DeviceAspects.end());
176 
177  return DeviceAspects;
178 }
179 
180 #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \
181  template __SYCL_EXPORT ReturnT device::get_info<info::device::Desc>() const;
182 
183 #define __SYCL_PARAM_TRAITS_SPEC_SPECIALIZED(DescType, Desc, ReturnT, PiCode)
184 
185 #include <sycl/info/device_traits.def>
186 #undef __SYCL_PARAM_TRAITS_SPEC_SPECIALIZED
187 #undef __SYCL_PARAM_TRAITS_SPEC
188 
189 #define __SYCL_PARAM_TRAITS_SPEC(Namespace, DescType, Desc, ReturnT, PiCode) \
190  template __SYCL_EXPORT ReturnT \
191  device::get_info<Namespace::info::DescType::Desc>() const;
192 
193 #include <sycl/info/ext_codeplay_device_traits.def>
194 #include <sycl/info/ext_intel_device_traits.def>
195 #include <sycl/info/ext_oneapi_device_traits.def>
196 #undef __SYCL_PARAM_TRAITS_SPEC
197 
198 backend device::get_backend() const noexcept { return getImplBackend(impl); }
199 
200 pi_native_handle device::getNative() const { return impl->getNative(); }
201 
202 bool device::has(aspect Aspect) const { return impl->has(Aspect); }
203 
204 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
205 } // namespace sycl
sycl::_V1::device::get_platform
platform get_platform() const
Get associated SYCL platform.
Definition: device.cpp:91
sycl::_V1::info::partition_affinity_domain
partition_affinity_domain
Definition: info_desc.hpp:63
sycl::_V1::detail::platform_impl::getPlatformFromPiDevice
static std::shared_ptr< platform_impl > getPlatformFromPiDevice(RT::PiDevice PiDevice, const plugin &Plugin)
Queries the cache for the specified platform based on an input device.
Definition: platform_impl.cpp:61
sycl::_V1::backend
backend
Definition: backend_types.hpp:21
sycl::_V1::platform::get_platforms
static std::vector< platform > get_platforms()
Returns all available SYCL platforms in the system.
Definition: platform.cpp:53
device_filter.hpp
sycl::_V1::detail::is_device_info_desc
Definition: info_desc_helpers.hpp:21
config.hpp
device_selector.hpp
sycl::_V1::detail::force_type
void force_type(info::device_type &t, const info::device_type &ft)
Definition: device.cpp:23
device.hpp
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::detail::pi::PiDevice
::pi_device PiDevice
Definition: pi.hpp:124
piDeviceRetain
pi_result piDeviceRetain(pi_device device)
Definition: pi_esimd_emulator.cpp:572
sycl::_V1::detail::ods_target_list::backendCompatible
bool backendCompatible(backend Backend)
Definition: device_filter.cpp:273
piextDeviceCreateWithNativeHandle
pi_result piextDeviceCreateWithNativeHandle(pi_native_handle nativeHandle, pi_platform platform, pi_device *device)
Creates PI device object from a native handle.
Definition: pi_esimd_emulator.cpp:831
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
device_impl.hpp
sycl::_V1::device::device
device()
Constructs a SYCL device instance using the default device.
Definition: device.cpp:33
sycl::_V1::default_selector_v
class __SYCL2020_DEPRECATED("Host device is no longer supported.") host_selector int default_selector_v(const device &dev)
Selects SYCL host device.
Definition: device_selector.cpp:178
sycl::_V1::info::partition_property::ext_intel_partition_by_cslice
@ ext_intel_partition_by_cslice
sycl::_V1::device::get_backend
backend get_backend() const noexcept
Returns the backend associated with this device.
Definition: device.cpp:198
sycl::_V1::device::has_extension
bool has_extension(const std::string &extension_name) const
Check SYCL extension support by device.
Definition: device.cpp:130
sycl::_V1::detail::getImplBackend
backend getImplBackend(const T &Impl)
Definition: backend_impl.hpp:17
sycl::_V1::detail::device_filter_list::backendCompatible
bool backendCompatible(backend Backend)
Definition: device_filter.cpp:384
export.hpp
std::get
constexpr tuple_element< I, tuple< Types... > >::type & get(sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:199
sycl::_V1::info::partition_property::partition_by_affinity_domain
@ partition_by_affinity_domain
sycl::_V1::device::is_gpu
bool is_gpu() const
Check if device is a GPU device.
Definition: device.cpp:87
device_selector
sycl::_V1::device::is_accelerator
bool is_accelerator() const
Check if device is an accelerator device.
Definition: device.cpp:89
sycl::_V1::device
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:49
sycl::_V1::info::device_type
device_type
Definition: info_desc.hpp:44
pi_native_handle
uintptr_t pi_native_handle
Definition: pi.h:133
sycl::_V1::device::get_devices
static std::vector< device > get_devices(info::device_type deviceType=info::device_type::all)
Query available SYCL devices.
Definition: device.cpp:52
sycl::_V1::device::has
bool has(aspect Aspect) const
Indicates if the SYCL device has the given feature.
Definition: device.cpp:202
sycl::_V1::detail::device_filter_list
Definition: device_filter.hpp:84
sycl::_V1::device::get_info
detail::is_device_info_desc< Param >::return_type get_info() const
Queries this SYCL device for information requested by the template parameter param.
Definition: device.cpp:136
sycl::_V1::detail::ods_target_list
Definition: device_filter.hpp:55
sycl::_V1::device::is_cpu
bool is_cpu() const
Check if device is a CPU device.
Definition: device.cpp:85
backend_impl.hpp
info_desc.hpp
sycl::_V1::platform
Encapsulates a SYCL platform on which kernels may be executed.
Definition: platform.hpp:45
sycl::_V1::device::create_sub_devices
std::vector< device > create_sub_devices() const
Partition device into sub devices.
Definition: device.cpp:123
sycl::_V1::detail::SYCLConfig::get
static const char * get()
Definition: config.hpp:114