DPC++ Runtime
Runtime libraries for oneAPI DPC++
context_impl.hpp
Go to the documentation of this file.
1 //==---------------- context_impl.hpp - SYCL context ------------*- C++-*---==//
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 #include <detail/device_impl.hpp>
12 #include <detail/platform_impl.hpp>
14 #include <sycl/detail/common.hpp>
15 #include <sycl/detail/os_util.hpp>
16 #include <sycl/detail/pi.hpp>
17 #include <sycl/exception_list.hpp>
18 #include <sycl/info/info_desc.hpp>
19 #include <sycl/property_list.hpp>
20 #include <sycl/stl.hpp>
21 
22 #include <map>
23 #include <memory>
24 #include <optional>
25 #include <set>
26 
27 namespace sycl {
29 // Forward declaration
30 class device;
31 namespace detail {
32 using PlatformImplPtr = std::shared_ptr<detail::platform_impl>;
33 class context_impl {
34 public:
44  context_impl(const device &Device, async_handler AsyncHandler,
45  const property_list &PropList);
46 
59  context_impl(const std::vector<sycl::device> DeviceList,
60  async_handler AsyncHandler, const property_list &PropList);
61 
72  const plugin &Plugin);
73 
74  ~context_impl();
75 
79  template <typename propertyT> bool has_property() const noexcept {
80  return MPropList.has_property<propertyT>();
81  }
82 
89  template <typename propertyT> propertyT get_property() const {
90  return MPropList.get_property<propertyT>();
91  }
92 
96  cl_context get() const;
97 
101  bool is_host() const;
102 
106  const async_handler &get_async_handler() const;
107 
109  const plugin &getPlugin() const { return MPlatform->getPlugin(); }
110 
112  PlatformImplPtr getPlatformImpl() const { return MPlatform; }
113 
117  template <typename Param> typename Param::return_type get_info() const;
118 
127  RT::PiContext &getHandleRef();
128 
137  const RT::PiContext &getHandleRef() const;
138 
141  const std::vector<device> &getDevices() const { return MDevices; }
142 
143  using CachedLibProgramsT =
144  std::map<std::pair<DeviceLibExt, RT::PiDevice>, RT::PiProgram>;
145 
160  return {MCachedLibPrograms, MCachedLibProgramsMutex};
161  }
162 
163  KernelProgramCache &getKernelProgramCache() const;
164 
166  bool hasDevice(std::shared_ptr<detail::device_impl> Device) const;
167 
173  // OpenCL does not support using descendants of context members within that
174  // context yet.
175  // TODO remove once this limitation is lifted
176  if (!is_host() && getPlugin().getBackend() == backend::opencl)
177  return hasDevice(Device);
178 
179  while (!hasDevice(Device)) {
180  if (Device->isRootDevice())
181  return false;
182  Device = detail::getSyclObjImpl(
183  Device->get_info<info::device::parent_device>());
184  }
185 
186  return true;
187  }
188 
191  DeviceImplPtr findMatchingDeviceImpl(RT::PiDevice &DevicePI) const;
192 
196  pi_native_handle getNative() const;
197 
198  // Returns true if buffer_location property is supported by devices
199  bool isBufferLocationSupported() const;
200 
202  void addAssociatedDeviceGlobal(const void *DeviceGlobalPtr);
203 
205  void addDeviceGlobalInitializer(RT::PiProgram Program,
206  const std::vector<device> &Devs,
207  const RTDeviceBinaryImage *BinImage);
208 
210  std::vector<RT::PiEvent>
211  initializeDeviceGlobals(pi::PiProgram NativePrg,
212  const std::shared_ptr<queue_impl> &QueueImpl);
213 
215  std::optional<RT::PiProgram>
216  getProgramForDeviceGlobal(const device &Device,
217  DeviceGlobalMapEntry *DeviceGlobalEntry);
218 
219  enum PropertySupport { NotSupported = 0, Supported = 1, NotChecked = 2 };
220 
221 private:
222  async_handler MAsyncHandler;
223  std::vector<device> MDevices;
224  RT::PiContext MContext;
225  PlatformImplPtr MPlatform;
226  property_list MPropList;
227  bool MHostContext;
228  CachedLibProgramsT MCachedLibPrograms;
229  std::mutex MCachedLibProgramsMutex;
230  mutable KernelProgramCache MKernelProgramCache;
231  mutable PropertySupport MSupportBufferLocationByDevices;
232 
233  std::set<const void *> MAssociatedDeviceGlobals;
234  std::mutex MAssociatedDeviceGlobalsMutex;
235 
236  struct DeviceGlobalInitializer {
237  DeviceGlobalInitializer() = default;
238  DeviceGlobalInitializer(const RTDeviceBinaryImage *BinImage)
239  : MBinImage(BinImage) {
240  // If there are no device globals, they are trivially fully initialized.
241  // Note: Lock is not needed during construction.
242  MDeviceGlobalsFullyInitialized = BinImage->getDeviceGlobals().size() == 0;
243  }
244 
246  void ClearEvents(const plugin &Plugin);
247 
249  const RTDeviceBinaryImage *MBinImage = nullptr;
250 
252  std::mutex MDeviceGlobalInitMutex;
253 
261  bool MDeviceGlobalsFullyInitialized = false;
262 
265  std::vector<RT::PiEvent> MDeviceGlobalInitEvents;
266  };
267 
268  std::map<std::pair<RT::PiProgram, RT::PiDevice>, DeviceGlobalInitializer>
269  MDeviceGlobalInitializers;
270  std::mutex MDeviceGlobalInitializersMutex;
271 };
272 
273 template <typename T, typename Capabilities>
274 void GetCapabilitiesIntersectionSet(const std::vector<sycl::device> &Devices,
275  std::vector<T> &CapabilityList) {
276  for (const sycl::device &Device : Devices) {
277  std::vector<T> NewCapabilityList;
278  std::vector<T> DeviceCapabilities = Device.get_info<Capabilities>();
279  std::set_intersection(
280  CapabilityList.begin(), CapabilityList.end(),
281  DeviceCapabilities.begin(), DeviceCapabilities.end(),
282  std::inserter(NewCapabilityList, NewCapabilityList.begin()));
283  CapabilityList = NewCapabilityList;
284  }
285  CapabilityList.shrink_to_fit();
286 }
287 
288 } // namespace detail
289 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
290 } // namespace sycl
sycl::_V1::detail::context_impl::has_property
bool has_property() const noexcept
Checks if this context_impl has a property of type propertyT.
Definition: context_impl.hpp:79
sycl::_V1::property_list
Objects of the property_list class are containers for the SYCL properties.
Definition: property_list.hpp:24
property_list.hpp
sycl::_V1::detail::PlatformImplPtr
std::shared_ptr< detail::platform_impl > PlatformImplPtr
Definition: context_impl.hpp:32
stl.hpp
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
kernel_program_cache.hpp
sycl::_V1::detail::DeviceImplPtr
std::shared_ptr< device_impl > DeviceImplPtr
Definition: program_manager.hpp:59
sycl::_V1::detail::pi::PiDevice
::pi_device PiDevice
Definition: pi.hpp:124
os_util.hpp
sycl::_V1::detail::DeviceGlobalMapEntry
Definition: device_global_map_entry.hpp:81
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
device_impl.hpp
sycl::_V1::detail::GetCapabilitiesIntersectionSet
void GetCapabilitiesIntersectionSet(const std::vector< sycl::device > &Devices, std::vector< T > &CapabilityList)
Definition: context_impl.hpp:274
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::size
size_t size() const
Definition: device_binary_image.hpp:116
pi.hpp
sycl::_V1::detail::pi::getPlugin
const plugin & getPlugin()
Definition: pi.cpp:506
sycl::_V1::detail::RTDeviceBinaryImage::getDeviceGlobals
const PropertyRange & getDeviceGlobals() const
Definition: device_binary_image.hpp:221
std::get
constexpr tuple_element< I, tuple< Types... > >::type & get(sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:199
sycl::_V1::detail::plugin
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
Definition: plugin.hpp:90
platform_impl.hpp
sycl::_V1::detail::context_impl::getPlugin
const plugin & getPlugin() const
Definition: context_impl.hpp:109
sycl::_V1::detail::context_impl::PropertySupport
PropertySupport
Definition: context_impl.hpp:219
sycl::_V1::detail::pi::PiContext
::pi_context PiContext
Definition: pi.hpp:128
sycl::_V1::detail::pi::PiProgram
::pi_program PiProgram
Definition: pi.hpp:130
common.hpp
sycl::_V1::device
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:49
_pi_program
Implementation of PI Program on CUDA Module object.
Definition: pi_cuda.hpp:760
sycl::_V1::access::target::device
@ device
sycl::_V1::detail::context_impl::getPlatformImpl
PlatformImplPtr getPlatformImpl() const
Definition: context_impl.hpp:112
program_manager.hpp
pi_native_handle
uintptr_t pi_native_handle
Definition: pi.h:133
sycl::_V1::detail::context_impl::getDevices
const std::vector< device > & getDevices() const
Unlike ‘get_info<info::context::devices>’, this function returns a reference.
Definition: context_impl.hpp:141
sycl::_V1::detail::context_impl::get_property
propertyT get_property() const
Gets the specified property of this context_impl.
Definition: context_impl.hpp:89
sycl::_V1::detail::Locked
Represents a reference to value with appropriate lock acquired.
Definition: locked.hpp:23
sycl::_V1::async_handler
std::function< void(sycl::exception_list)> async_handler
Definition: exception_list.hpp:54
exception_list.hpp
info_desc.hpp
sycl::_V1::detail::context_impl::acquireCachedLibPrograms
Locked< CachedLibProgramsT > acquireCachedLibPrograms()
In contrast to user programs, which are compiled from user code, library programs come from the SYCL ...
Definition: context_impl.hpp:159
sycl::_V1::detail::KernelProgramCache
Definition: kernel_program_cache.hpp:31
sycl::_V1::detail::context_impl::isDeviceValid
bool isDeviceValid(DeviceImplPtr Device)
Returns true if and only if the device can be used within this context.
Definition: context_impl.hpp:172
sycl::_V1::detail::RTDeviceBinaryImage
Definition: device_binary_image.hpp:82
sycl::_V1::detail::context_impl
Definition: context_impl.hpp:33
sycl::_V1::detail::getSyclObjImpl
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: common.hpp:300