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