DPC++ Runtime
Runtime libraries for oneAPI DPC++
context.cpp
Go to the documentation of this file.
1 //==---------------- context.cpp - SYCL context ----------------------------==//
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/context_impl.hpp>
11 #include <sycl/context.hpp>
12 #include <sycl/detail/common.hpp>
13 #include <sycl/device.hpp>
14 #include <sycl/device_selector.hpp>
15 #include <sycl/exception.hpp>
16 #include <sycl/exception_list.hpp>
17 #include <sycl/platform.hpp>
19 #include <sycl/stl.hpp>
20 
21 #include <algorithm>
22 #include <memory>
23 #include <utility>
24 
25 // 4.6.2 Context class
26 
27 namespace sycl {
29 
30 context::context(const property_list &PropList)
31  : context(default_selector().select_device(), PropList) {}
32 
33 context::context(const async_handler &AsyncHandler,
34  const property_list &PropList)
35  : context(default_selector().select_device(), AsyncHandler, PropList) {}
36 
37 context::context(const device &Device, const property_list &PropList)
38  : context(std::vector<device>(1, Device), PropList) {}
39 
40 context::context(const device &Device, async_handler AsyncHandler,
41  const property_list &PropList)
42  : context(std::vector<device>(1, Device), AsyncHandler, PropList) {}
43 
44 context::context(const platform &Platform, const property_list &PropList)
45  : context(Platform.get_devices(), PropList) {}
46 
47 context::context(const platform &Platform, async_handler AsyncHandler,
48  const property_list &PropList)
49  : context(Platform.get_devices(), AsyncHandler, PropList) {}
50 
51 context::context(const std::vector<device> &DeviceList,
52  const property_list &PropList)
53  : context(DeviceList, detail::defaultAsyncHandler, PropList) {}
54 
55 context::context(const std::vector<device> &DeviceList,
56  async_handler AsyncHandler, const property_list &PropList) {
57  if (DeviceList.empty()) {
58  throw invalid_parameter_error("DeviceList is empty.",
59  PI_ERROR_INVALID_VALUE);
60  }
61  auto NonHostDeviceIter = std::find_if_not(
62  DeviceList.begin(), DeviceList.end(), [&](const device &CurrentDevice) {
63  return detail::getSyclObjImpl(CurrentDevice)->is_host();
64  });
65  if (NonHostDeviceIter == DeviceList.end())
66  impl = std::make_shared<detail::context_impl>(DeviceList[0], AsyncHandler,
67  PropList);
68  else {
69  const device &NonHostDevice = *NonHostDeviceIter;
70  const auto &NonHostPlatform =
71  detail::getSyclObjImpl(NonHostDevice.get_platform())->getHandleRef();
72  if (std::any_of(DeviceList.begin(), DeviceList.end(),
73  [&](const device &CurrentDevice) {
74  return (
75  detail::getSyclObjImpl(CurrentDevice)->is_host() ||
76  (detail::getSyclObjImpl(CurrentDevice.get_platform())
77  ->getHandleRef() != NonHostPlatform));
78  }))
79  throw invalid_parameter_error(
80  "Can't add devices across platforms to a single context.",
81  PI_ERROR_INVALID_DEVICE);
82  else
83  impl = std::make_shared<detail::context_impl>(DeviceList, AsyncHandler,
84  PropList);
85  }
86 }
87 context::context(cl_context ClContext, async_handler AsyncHandler) {
88  const auto &Plugin = RT::getPlugin<backend::opencl>();
89  impl = std::make_shared<detail::context_impl>(
90  detail::pi::cast<detail::RT::PiContext>(ClContext), AsyncHandler, Plugin);
91 }
92 
93 template <typename Param>
94 typename detail::is_context_info_desc<Param>::return_type
96  return impl->template get_info<Param>();
97 }
98 
99 #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \
100  template __SYCL_EXPORT ReturnT context::get_info<info::DescType::Desc>() \
101  const;
102 
103 #include <sycl/info/context_traits.def>
104 
105 #undef __SYCL_PARAM_TRAITS_SPEC
106 
107 #define __SYCL_PARAM_TRAITS_SPEC(param_type) \
108  template <> \
109  __SYCL_EXPORT bool context::has_property<param_type>() const noexcept { \
110  return impl->has_property<param_type>(); \
111  }
112 #include <sycl/detail/properties_traits.def>
113 
114 #undef __SYCL_PARAM_TRAITS_SPEC
115 
116 #define __SYCL_PARAM_TRAITS_SPEC(param_type) \
117  template <> \
118  __SYCL_EXPORT param_type context::get_property<param_type>() const { \
119  return impl->get_property<param_type>(); \
120  }
121 #include <sycl/detail/properties_traits.def>
122 
123 #undef __SYCL_PARAM_TRAITS_SPEC
124 
125 cl_context context::get() const { return impl->get(); }
126 
127 bool context::is_host() const {
128  bool IsHost = impl->is_host();
129  assert(!IsHost && "context::is_host should not be called in implementation.");
130  return IsHost;
131 }
132 
133 backend context::get_backend() const noexcept { return getImplBackend(impl); }
134 
136  return impl->get_info<info::context::platform>();
137 }
138 
139 std::vector<device> context::get_devices() const {
140  return impl->get_info<info::context::devices>();
141 }
142 
143 context::context(std::shared_ptr<detail::context_impl> Impl) : impl(Impl) {}
144 
145 pi_native_handle context::getNative() const { return impl->getNative(); }
146 
147 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
148 } // namespace sycl
sycl::_V1::device::get_platform
platform get_platform() const
Get associated SYCL platform.
Definition: device.cpp:91
sycl::_V1::property_list
Objects of the property_list class are containers for the SYCL properties.
Definition: property_list.hpp:24
sycl::_V1::backend
backend
Definition: backend_types.hpp:21
context_impl.hpp
stl.hpp
device_selector.hpp
device.hpp
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::context::get_devices
std::vector< device > get_devices() const
Gets devices associated with this SYCL context.
Definition: context.cpp:139
context.hpp
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
sycl::_V1::detail::getImplBackend
backend getImplBackend(const T &Impl)
Definition: backend_impl.hpp:17
std::get
constexpr tuple_element< I, tuple< Types... > >::type & get(sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:199
all_properties.hpp
sycl::_V1::detail::select_device
device select_device(const DSelectorInvocableType &DeviceSelectorInvocable)
Definition: device_selector.cpp:136
common.hpp
sycl::_V1::device
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:49
sycl::_V1::context::get_backend
backend get_backend() const noexcept
Returns the backend associated with this context.
Definition: context.cpp:133
sycl::_V1::context::context
context(const property_list &PropList={})
Constructs a SYCL context instance using an instance of default_selector.
Definition: context.cpp:30
pi_native_handle
uintptr_t pi_native_handle
Definition: pi.h:133
sycl::_V1::detail::defaultAsyncHandler
void defaultAsyncHandler(exception_list Exceptions)
Definition: exception_list.hpp:59
sycl::_V1::context::get_info
detail::is_context_info_desc< Param >::return_type get_info() const
Constructs a SYCL context instance from OpenCL cl_context.
Definition: context.cpp:95
platform.hpp
exception.hpp
std
Definition: accessor.hpp:3230
sycl::_V1::context::get_platform
platform get_platform() const
Gets platform associated with this SYCL context.
Definition: context.cpp:135
sycl::_V1::async_handler
std::function< void(sycl::exception_list)> async_handler
Definition: exception_list.hpp:54
backend_impl.hpp
exception_list.hpp
any_of
bool any_of(const simd_mask< _Tp, _Abi > &) noexcept
sycl::_V1::platform
Encapsulates a SYCL platform on which kernels may be executed.
Definition: platform.hpp:45
sycl::_V1::detail::getSyclObjImpl
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: common.hpp:300
sycl::_V1::context
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:41