DPC++ Runtime
Runtime libraries for oneAPI DPC++
kernel_bundle.hpp
Go to the documentation of this file.
1 //==------- kernel_bundle.hpp - SYCL kernel_bundle and free functions ------==//
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 
11 #include <sycl/backend_types.hpp> // for backend, backend_return_t
12 #include <sycl/context.hpp> // for context
13 #include <sycl/detail/export.hpp> // for __SYCL_EXPORT
14 #include <sycl/detail/kernel_desc.hpp> // for get_spec_constant_symboli...
15 #include <sycl/detail/owner_less_base.hpp> // for OwnerLessBase
16 #include <sycl/detail/pi.h> // for pi_native_handle
17 #include <sycl/detail/pi.hpp> // for cast
19 #include <sycl/device.hpp> // for device
20 #include <sycl/kernel.hpp> // for kernel, kernel_bundle
21 #include <sycl/kernel_bundle_enums.hpp> // for bundle_state
22 #include <sycl/property_list.hpp> // for property_list
23 
24 #include <sycl/ext/oneapi/properties/properties.hpp> // PropertyT
25 #include <sycl/ext/oneapi/properties/property.hpp> // build_options
27 
28 #include <array> // for array
29 #include <cstddef> // for std::byte
30 #include <cstring> // for size_t, memcpy
31 #include <functional> // for function
32 #include <iterator> // for distance
33 #include <memory> // for shared_ptr, operator==, hash
34 #include <string> // for string
35 #include <type_traits> // for enable_if_t, remove_refer...
36 #include <utility> // for move
37 #include <variant> // for hash
38 #include <vector> // for vector
39 
40 namespace sycl {
41 inline namespace _V1 {
42 // Forward declaration
43 template <backend Backend> class backend_traits;
44 template <backend Backend, bundle_state State>
45 auto get_native(const kernel_bundle<State> &Obj)
46  -> backend_return_t<Backend, kernel_bundle<State>>;
47 
48 namespace detail {
49 class kernel_id_impl;
50 class kernel_impl;
51 } // namespace detail
52 
53 template <typename KernelName> kernel_id get_kernel_id();
54 
58 class __SYCL_EXPORT kernel_id : public detail::OwnerLessBase<kernel_id> {
59 public:
60  kernel_id() = delete;
61 
63  const char *get_name() const noexcept;
64 
65  bool operator==(const kernel_id &RHS) const { return impl == RHS.impl; }
66 
67  bool operator!=(const kernel_id &RHS) const { return !(*this == RHS); }
68 
69 private:
70  kernel_id(const char *Name);
71 
72  kernel_id(const std::shared_ptr<detail::kernel_id_impl> &Impl)
73  : impl(std::move(Impl)) {}
74 
75  std::shared_ptr<detail::kernel_id_impl> impl;
76 
77  template <class Obj>
78  friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);
79 
80  template <class T>
81  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
82 };
83 
84 namespace detail {
85 class device_image_impl;
86 using DeviceImageImplPtr = std::shared_ptr<device_image_impl>;
87 
88 // The class is used as a base for device_image for "untemplating" public
89 // methods.
90 class __SYCL_EXPORT device_image_plain {
91 public:
93  : impl(std::move(Impl)) {}
94 
95  bool operator==(const device_image_plain &RHS) const {
96  return impl == RHS.impl;
97  }
98 
99  bool operator!=(const device_image_plain &RHS) const {
100  return !(*this == RHS);
101  }
102 
103  bool has_kernel(const kernel_id &KernelID) const noexcept;
104 
105  bool has_kernel(const kernel_id &KernelID, const device &Dev) const noexcept;
106 
107  pi_native_handle getNative() const;
108 
109 protected:
111 
112  template <class Obj>
113  friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);
114 
115  template <class T>
116  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
117 };
118 } // namespace detail
119 
121 template <sycl::bundle_state State>
123  public detail::OwnerLessBase<device_image<State>> {
124 public:
125  device_image() = delete;
126 
129  bool has_kernel(const kernel_id &KernelID) const noexcept {
130  return device_image_plain::has_kernel(KernelID);
131  }
132 
135  bool has_kernel(const kernel_id &KernelID, const device &Dev) const noexcept {
136  return device_image_plain::has_kernel(KernelID, Dev);
137  }
138 
139 private:
141  : device_image_plain(std::move(Impl)) {}
142 
143  template <class Obj>
144  friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);
145 
146  template <class T>
147  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
148 };
149 
150 namespace detail {
151 class kernel_bundle_impl;
152 using KernelBundleImplPtr = std::shared_ptr<detail::kernel_bundle_impl>;
153 
154 // The class is used as a base for kernel_bundle to "untemplate" it's methods
155 class __SYCL_EXPORT kernel_bundle_plain {
156 public:
158  : impl(std::move(Impl)) {}
159 
160  bool operator==(const kernel_bundle_plain &RHS) const {
161  return impl == RHS.impl;
162  }
163 
164  bool operator!=(const kernel_bundle_plain &RHS) const {
165  return !(*this == RHS);
166  }
167 
168  bool empty() const noexcept;
169 
170  backend get_backend() const noexcept;
171 
172  context get_context() const noexcept;
173 
174  std::vector<device> get_devices() const noexcept;
175 
176  bool has_kernel(const kernel_id &KernelID) const noexcept;
177 
178  bool has_kernel(const kernel_id &KernelID, const device &Dev) const noexcept;
179 
180  std::vector<kernel_id> get_kernel_ids() const;
181 
182  bool contains_specialization_constants() const noexcept;
183 
184  bool native_specialization_constant() const noexcept;
185 
186  bool ext_oneapi_has_kernel(const std::string &name);
187 
188  kernel ext_oneapi_get_kernel(const std::string &name);
189 
190 protected:
191  // \returns a kernel object which represents the kernel identified by
192  // kernel_id passed
193  kernel get_kernel(const kernel_id &KernelID) const;
194 
195  // \returns an iterator to the first device image kernel_bundle contains
196  const device_image_plain *begin() const;
197 
198  // \returns an iterator to the last device image kernel_bundle contains
199  const device_image_plain *end() const;
200 
201  bool has_specialization_constant_impl(const char *SpecName) const noexcept;
202 
203  void set_specialization_constant_impl(const char *SpecName, void *Value,
204  size_t Size) noexcept;
205 
206  void get_specialization_constant_impl(const char *SpecName,
207  void *Value) const noexcept;
208 
209  // \returns a bool value which indicates if specialization constant was set to
210  // a value different from default value.
211  bool is_specialization_constant_set(const char *SpecName) const noexcept;
212 
213  detail::KernelBundleImplPtr impl;
214 };
215 
216 } // namespace detail
217 
222 template <bundle_state State>
223 class kernel_bundle : public detail::kernel_bundle_plain,
224  public detail::OwnerLessBase<kernel_bundle<State>> {
225 public:
227 
228  kernel_bundle() = delete;
229 
231  template <
232  bundle_state _State = State,
233  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
234  bool empty() const noexcept {
236  }
237 
241  }
242 
246  }
247 
249  std::vector<device> get_devices() const noexcept {
251  }
252 
255  template <
256  bundle_state _State = State,
257  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
258  bool has_kernel(const kernel_id &KernelID) const noexcept {
259  return kernel_bundle_plain::has_kernel(KernelID);
260  }
261 
265  template <
266  bundle_state _State = State,
267  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
268  bool has_kernel(const kernel_id &KernelID, const device &Dev) const noexcept {
269  return kernel_bundle_plain::has_kernel(KernelID, Dev);
270  }
271 
274  template <
275  typename KernelName, bundle_state _State = State,
276  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
277  bool has_kernel() const noexcept {
278  return has_kernel(get_kernel_id<KernelName>());
279  }
280 
283  template <
284  typename KernelName, bundle_state _State = State,
285  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
286  bool has_kernel(const device &Dev) const noexcept {
287  return has_kernel(get_kernel_id<KernelName>(), Dev);
288  }
289 
291  template <
292  bundle_state _State = State,
293  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
294  std::vector<kernel_id> get_kernel_ids() const {
296  }
297 
300  template <
301  bundle_state _State = State,
302  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
305  }
306 
309  template <
310  bundle_state _State = State,
311  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
314  }
315 
318  template <bundle_state _State = State,
319  typename = std::enable_if_t<_State == bundle_state::executable>>
320  kernel get_kernel(const kernel_id &KernelID) const {
322  }
323 
326  template <typename KernelName, bundle_state _State = State,
327  typename = std::enable_if_t<_State == bundle_state::executable>>
328  kernel get_kernel() const {
329  return detail::kernel_bundle_plain::get_kernel(get_kernel_id<KernelName>());
330  }
331 
334  template <
335  auto &SpecName, bundle_state _State = State,
336  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
338  const char *SpecSymName = detail::get_spec_constant_symbolic_ID<SpecName>();
339  return has_specialization_constant_impl(SpecSymName);
340  }
341 
345  template <auto &SpecName, bundle_state _State = State,
346  typename = std::enable_if_t<_State == bundle_state::input>>
348  typename std::remove_reference_t<decltype(SpecName)>::value_type Value) {
349  const char *SpecSymName = detail::get_spec_constant_symbolic_ID<SpecName>();
350  set_specialization_constant_impl(SpecSymName, &Value,
351  sizeof(decltype(Value)));
352  }
353 
356  template <
357  auto &SpecName, bundle_state _State = State,
358  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
359  typename std::remove_reference_t<decltype(SpecName)>::value_type
361  using SCType =
362  typename std::remove_reference_t<decltype(SpecName)>::value_type;
363 
364  const char *SpecSymName = detail::get_spec_constant_symbolic_ID<SpecName>();
365  SCType Res{SpecName.getDefaultValue()};
366  if (!is_specialization_constant_set(SpecSymName))
367  return Res;
368 
369  std::array<char, sizeof(SCType)> RetValue;
370  get_specialization_constant_impl(SpecSymName, RetValue.data());
371  std::memcpy(&Res, RetValue.data(), sizeof(SCType));
372 
373  return Res;
374  }
375 
377  template <
378  bundle_state _State = State,
379  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
381  return reinterpret_cast<device_image_iterator>(
383  }
384 
386  template <
387  bundle_state _State = State,
388  typename = std::enable_if_t<_State != bundle_state::ext_oneapi_source>>
390  return reinterpret_cast<device_image_iterator>(kernel_bundle_plain::end());
391  }
392 
394  // ext_oneapi_has_kernel
395  // only true if created from source and has this kernel
397  template <bundle_state _State = State,
398  typename = std::enable_if_t<_State == bundle_state::executable>>
399  bool ext_oneapi_has_kernel(const std::string &name) {
401  }
402 
404  // ext_oneapi_get_kernel
405  // kernel_bundle must be created from source, throws if not present
407  template <bundle_state _State = State,
408  typename = std::enable_if_t<_State == bundle_state::executable>>
409  kernel ext_oneapi_get_kernel(const std::string &name) {
411  }
412 
413 private:
415  : kernel_bundle_plain(std::move(Impl)) {}
416 
417  template <class Obj>
418  friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);
419 
420  template <class T>
421  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
422 
423  template <backend Backend, bundle_state StateB>
424  friend auto get_native(const kernel_bundle<StateB> &Obj)
426 
427  template <backend Backend>
429  // NOTE: implementation assumes that the return type is a
430  // derivative of std::vector.
432  ReturnValue.reserve(std::distance(begin(), end()));
433 
434  for (const device_image<State> &DevImg : *this) {
435  ReturnValue.push_back(
436  detail::pi::cast<typename decltype(ReturnValue)::value_type>(
437  DevImg.getNative()));
438  }
439 
440  return ReturnValue;
441  }
442 };
443 template <bundle_state State>
445 
447 // get_kernel_id API
449 
450 namespace detail {
451 // Internal non-template versions of get_kernel_id API which is used by public
452 // onces
453 __SYCL_EXPORT kernel_id get_kernel_id_impl(string_view KernelName);
454 } // namespace detail
455 
457 template <typename KernelName> kernel_id get_kernel_id() {
458  // FIXME: This must fail at link-time if KernelName not in any available
459  // translation units.
460  using KI = sycl::detail::KernelInfo<KernelName>;
461  return detail::get_kernel_id_impl(detail::string_view{KI::getName()});
462 }
463 
465 __SYCL_EXPORT std::vector<kernel_id> get_kernel_ids();
466 
468 // get_kernel_bundle API
470 
471 namespace detail {
472 
473 // Internal non-template versions of get_kernel_bundle API which is used by
474 // public onces
475 __SYCL_EXPORT detail::KernelBundleImplPtr
476 get_kernel_bundle_impl(const context &Ctx, const std::vector<device> &Devs,
477  bundle_state State);
478 
479 __SYCL_EXPORT const std::vector<device>
480 removeDuplicateDevices(const std::vector<device> &Devs);
481 
482 } // namespace detail
483 
488 template <bundle_state State>
490  const std::vector<device> &Devs) {
491  std::vector<device> UniqueDevices = detail::removeDuplicateDevices(Devs);
492 
494  detail::get_kernel_bundle_impl(Ctx, UniqueDevices, State);
495 
496  return detail::createSyclObjFromImpl<kernel_bundle<State>>(Impl);
497 }
498 
499 template <bundle_state State>
501  return get_kernel_bundle<State>(Ctx, Ctx.get_devices());
502 }
503 
504 namespace detail {
505 
506 // Internal non-template versions of get_kernel_bundle API which is used by
507 // public onces
508 __SYCL_EXPORT detail::KernelBundleImplPtr
509 get_kernel_bundle_impl(const context &Ctx, const std::vector<device> &Devs,
510  const std::vector<kernel_id> &KernelIDs,
511  bundle_state State);
512 } // namespace detail
513 
522 template <bundle_state State>
523 kernel_bundle<State>
524 get_kernel_bundle(const context &Ctx, const std::vector<device> &Devs,
525  const std::vector<kernel_id> &KernelIDs) {
526  std::vector<device> UniqueDevices = detail::removeDuplicateDevices(Devs);
527 
529  detail::get_kernel_bundle_impl(Ctx, UniqueDevices, KernelIDs, State);
530  return detail::createSyclObjFromImpl<kernel_bundle<State>>(Impl);
531 }
532 
533 template <bundle_state State>
534 kernel_bundle<State>
535 get_kernel_bundle(const context &Ctx, const std::vector<kernel_id> &KernelIDs) {
536  return get_kernel_bundle<State>(Ctx, Ctx.get_devices(), KernelIDs);
537 }
538 
539 template <typename KernelName, bundle_state State>
541  return get_kernel_bundle<State>(Ctx, Ctx.get_devices(),
542  {get_kernel_id<KernelName>()});
543 }
544 
545 template <typename KernelName, bundle_state State>
547  const std::vector<device> &Devs) {
548  return get_kernel_bundle<State>(Ctx, Devs, {get_kernel_id<KernelName>()});
549 }
550 
551 namespace detail {
552 
553 // Stable selector function type for passing thru library boundaries
555  std::function<bool(const detail::DeviceImageImplPtr &DevImgImpl)>;
556 
557 // Internal non-template versions of get_kernel_bundle API which is used by
558 // public onces
559 __SYCL_EXPORT detail::KernelBundleImplPtr
560 get_kernel_bundle_impl(const context &Ctx, const std::vector<device> &Devs,
561  bundle_state State, const DevImgSelectorImpl &Selector);
562 
563 // Internal non-template versions of get_empty_interop_kernel_bundle API which
564 // is used by public onces
565 __SYCL_EXPORT detail::KernelBundleImplPtr
567  const std::vector<device> &Devs);
568 
571 template <bundle_state State>
575  return detail::createSyclObjFromImpl<sycl::kernel_bundle<State>>(Impl);
576 }
577 } // namespace detail
578 
581 template <bundle_state State, typename SelectorT>
583  const std::vector<device> &Devs,
584  SelectorT Selector) {
585  std::vector<device> UniqueDevices = detail::removeDuplicateDevices(Devs);
586 
587  detail::DevImgSelectorImpl SelectorWrapper =
588  [Selector](const detail::DeviceImageImplPtr &DevImg) {
589  return Selector(
591  };
592 
594  Ctx, UniqueDevices, State, SelectorWrapper);
595 
596  return detail::createSyclObjFromImpl<sycl::kernel_bundle<State>>(Impl);
597 }
598 
599 template <bundle_state State, typename SelectorT>
600 kernel_bundle<State> get_kernel_bundle(const context &Ctx, SelectorT Selector) {
601  return get_kernel_bundle<State>(Ctx, Ctx.get_devices(), Selector);
602 }
603 
605 // has_kernel_bundle API
607 
608 namespace detail {
609 
610 __SYCL_EXPORT bool has_kernel_bundle_impl(const context &Ctx,
611  const std::vector<device> &Devs,
612  bundle_state State);
613 
614 __SYCL_EXPORT bool
615 has_kernel_bundle_impl(const context &Ctx, const std::vector<device> &Devs,
616  const std::vector<kernel_id> &kernelIds,
617  bundle_state State);
618 } // namespace detail
619 
630 template <bundle_state State>
631 bool has_kernel_bundle(const context &Ctx, const std::vector<device> &Devs) {
632  return detail::has_kernel_bundle_impl(Ctx, Devs, State);
633 }
634 
635 template <bundle_state State>
636 bool has_kernel_bundle(const context &Ctx, const std::vector<device> &Devs,
637  const std::vector<kernel_id> &KernelIDs) {
638  return detail::has_kernel_bundle_impl(Ctx, Devs, KernelIDs, State);
639 }
640 
641 template <bundle_state State> bool has_kernel_bundle(const context &Ctx) {
642  return has_kernel_bundle<State>(Ctx, Ctx.get_devices());
643 }
644 
645 template <bundle_state State>
646 bool has_kernel_bundle(const context &Ctx,
647  const std::vector<kernel_id> &KernelIDs) {
648  return has_kernel_bundle<State>(Ctx, Ctx.get_devices(), KernelIDs);
649 }
650 
651 template <typename KernelName, bundle_state State>
652 bool has_kernel_bundle(const context &Ctx) {
653  return has_kernel_bundle<State>(Ctx, {get_kernel_id<KernelName>()});
654 }
655 
656 template <typename KernelName, bundle_state State>
657 bool has_kernel_bundle(const context &Ctx, const std::vector<device> &Devs) {
658  return has_kernel_bundle<State>(Ctx, Devs, {get_kernel_id<KernelName>()});
659 }
660 
662 // is_compatible API
664 
667 __SYCL_EXPORT bool is_compatible(const std::vector<kernel_id> &KernelIDs,
668  const device &Dev);
669 
670 template <typename KernelName> bool is_compatible(const device &Dev) {
671  return is_compatible({get_kernel_id<KernelName>()}, Dev);
672 }
673 
675 // join API
677 
678 namespace detail {
679 
680 __SYCL_EXPORT std::shared_ptr<detail::kernel_bundle_impl>
681 join_impl(const std::vector<detail::KernelBundleImplPtr> &Bundles,
682  bundle_state State);
683 } // namespace detail
684 
687 template <sycl::bundle_state State>
689 join(const std::vector<sycl::kernel_bundle<State>> &Bundles) {
690  // Convert kernel_bundle<State> to impls to abstract template parameter away
691  std::vector<detail::KernelBundleImplPtr> KernelBundleImpls;
692  KernelBundleImpls.reserve(Bundles.size());
693  for (const sycl::kernel_bundle<State> &Bundle : Bundles)
694  KernelBundleImpls.push_back(detail::getSyclObjImpl(Bundle));
695 
696  std::shared_ptr<detail::kernel_bundle_impl> Impl =
697  detail::join_impl(KernelBundleImpls, State);
698  return detail::createSyclObjFromImpl<kernel_bundle<State>>(Impl);
699 }
700 
702 // compile API
704 
705 namespace detail {
706 
707 __SYCL_EXPORT std::shared_ptr<detail::kernel_bundle_impl>
708 compile_impl(const kernel_bundle<bundle_state::input> &InputBundle,
709  const std::vector<device> &Devs, const property_list &PropList);
710 }
711 
716 inline kernel_bundle<bundle_state::object>
718  const std::vector<device> &Devs, const property_list &PropList = {}) {
719  std::vector<device> UniqueDevices = detail::removeDuplicateDevices(Devs);
720 
722  detail::compile_impl(InputBundle, UniqueDevices, PropList);
724  kernel_bundle<sycl::bundle_state::object>>(Impl);
725 }
726 
727 inline kernel_bundle<bundle_state::object>
729  const property_list &PropList = {}) {
730  return compile(InputBundle, InputBundle.get_devices(), PropList);
731 }
732 
734 // link API
736 
737 namespace detail {
738 __SYCL_EXPORT std::vector<sycl::device> find_device_intersection(
739  const std::vector<kernel_bundle<bundle_state::object>> &ObjectBundles);
740 
741 __SYCL_EXPORT std::shared_ptr<detail::kernel_bundle_impl>
742 link_impl(const std::vector<kernel_bundle<bundle_state::object>> &ObjectBundles,
743  const std::vector<device> &Devs, const property_list &PropList);
744 } // namespace detail
745 
751 inline kernel_bundle<bundle_state::executable>
752 link(const std::vector<kernel_bundle<bundle_state::object>> &ObjectBundles,
753  const std::vector<device> &Devs, const property_list &PropList = {}) {
754  std::vector<device> UniqueDevices = detail::removeDuplicateDevices(Devs);
755 
757  detail::link_impl(ObjectBundles, UniqueDevices, PropList);
759  kernel_bundle<sycl::bundle_state::executable>>(Impl);
760 }
761 
762 inline kernel_bundle<bundle_state::executable>
764  const property_list &PropList = {}) {
765  return link(std::vector<kernel_bundle<bundle_state::object>>{ObjectBundle},
766  ObjectBundle.get_devices(), PropList);
767 }
768 
769 inline kernel_bundle<bundle_state::executable>
770 link(const std::vector<kernel_bundle<bundle_state::object>> &ObjectBundles,
771  const property_list &PropList = {}) {
772  std::vector<sycl::device> IntersectDevices =
773  find_device_intersection(ObjectBundles);
774  return link(ObjectBundles, IntersectDevices, PropList);
775 }
776 
777 inline kernel_bundle<bundle_state::executable>
779  const std::vector<device> &Devs, const property_list &PropList = {}) {
780  return link(std::vector<kernel_bundle<bundle_state::object>>{ObjectBundle},
781  Devs, PropList);
782 }
783 
785 // build API
787 
788 namespace detail {
789 __SYCL_EXPORT std::shared_ptr<detail::kernel_bundle_impl>
790 build_impl(const kernel_bundle<bundle_state::input> &InputBundle,
791  const std::vector<device> &Devs, const property_list &PropList);
792 }
793 
798 inline kernel_bundle<bundle_state::executable>
800  const std::vector<device> &Devs, const property_list &PropList = {}) {
801  std::vector<device> UniqueDevices = detail::removeDuplicateDevices(Devs);
802 
804  detail::build_impl(InputBundle, UniqueDevices, PropList);
806  kernel_bundle<sycl::bundle_state::executable>>(Impl);
807 }
808 
809 inline kernel_bundle<bundle_state::executable>
811  const property_list &PropList = {}) {
812  return build(InputBundle, InputBundle.get_devices(), PropList);
813 }
814 
815 namespace ext::oneapi::experimental {
816 
818 // PropertyT syclex::build_options
821  : detail::run_time_property_key<detail::PropKind::BuildOptions> {
822  std::vector<std::string> opts;
823  build_options(const std::string &optsArg) : opts{optsArg} {}
824  build_options(const std::vector<std::string> &optsArg) : opts(optsArg) {}
825 };
827 
828 template <>
830  sycl::kernel_bundle<bundle_state::ext_oneapi_source>>
831  : std::true_type {};
832 
834 // PropertyT syclex::save_log
836 struct save_log : detail::run_time_property_key<detail::PropKind::BuildLog> {
837  std::string *log;
838  save_log(std::string *logArg) : log(logArg) {}
839 };
841 
842 template <>
844  sycl::kernel_bundle<bundle_state::ext_oneapi_source>>
845  : std::true_type {};
846 
848 // syclex::is_source_kernel_bundle_supported
850 __SYCL_EXPORT bool is_source_kernel_bundle_supported(backend BE,
851  source_language Language);
852 
854 // syclex::create_kernel_bundle_from_source
856 
858 create_kernel_bundle_from_source(const context &SyclContext,
859  source_language Language,
860  const std::string &Source);
861 
862 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
864 create_kernel_bundle_from_source(const context &SyclContext,
865  source_language Language,
866  const std::vector<std::byte> &Bytes);
867 #endif
868 
870 // syclex::build(source_kb) => exe_kb
872 namespace detail {
873 // forward decl
876  const std::vector<device> &Devices,
877  const std::vector<std::string> &BuildOptions,
878  std::string *LogPtr);
879 
880 } // namespace detail
881 
882 template <typename PropertyListT = detail::empty_properties_t,
883  typename = std::enable_if_t<
884  is_property_list_v<PropertyListT> &&
887  PropertyListT>::value>>
888 
891  const std::vector<device> &Devices, PropertyListT props = {}) {
892  std::vector<std::string> BuildOptionsVec;
893  std::string *LogPtr = nullptr;
894  if constexpr (props.template has_property<build_options>()) {
895  BuildOptionsVec = props.template get_property<build_options>().opts;
896  }
897  if constexpr (props.template has_property<save_log>()) {
898  LogPtr = props.template get_property<save_log>().log;
899  }
900  return detail::build_from_source(SourceKB, Devices, BuildOptionsVec, LogPtr);
901 }
902 
903 template <typename PropertyListT = detail::empty_properties_t,
904  typename = std::enable_if_t<
905  is_property_list_v<PropertyListT> &&
906  detail::all_props_are_keys_of<
908  PropertyListT>::value>>
911  PropertyListT props = {}) {
912  return build<PropertyListT>(SourceKB, SourceKB.get_devices(), props);
913 }
914 
915 } // namespace ext::oneapi::experimental
916 
917 } // namespace _V1
918 } // namespace sycl
919 
920 namespace std {
921 template <> struct hash<sycl::kernel_id> {
922  size_t operator()(const sycl::kernel_id &KernelID) const {
923  return hash<std::shared_ptr<sycl::detail::kernel_id_impl>>()(
924  sycl::detail::getSyclObjImpl(KernelID));
925  }
926 };
927 
928 template <sycl::bundle_state State> struct hash<sycl::device_image<State>> {
929  size_t operator()(const sycl::device_image<State> &DeviceImage) const {
930  return hash<std::shared_ptr<sycl::detail::device_image_impl>>()(
931  sycl::detail::getSyclObjImpl(DeviceImage));
932  }
933 };
934 
935 template <sycl::bundle_state State> struct hash<sycl::kernel_bundle<State>> {
936  size_t operator()(const sycl::kernel_bundle<State> &KernelBundle) const {
937  return hash<std::shared_ptr<sycl::detail::kernel_bundle_impl>>()(
938  sycl::detail::getSyclObjImpl(KernelBundle));
939  }
940 };
941 } // namespace std
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
bool operator==(const device_image_plain &RHS) const
device_image_plain(const detail::DeviceImageImplPtr &Impl)
bool operator!=(const device_image_plain &RHS) const
detail::DeviceImageImplPtr impl
pi_native_handle getNative() const
bool contains_specialization_constants() const noexcept
std::vector< kernel_id > get_kernel_ids() const
bool operator!=(const kernel_bundle_plain &RHS) const
bool ext_oneapi_has_kernel(const std::string &name)
const device_image_plain * end() const
bool native_specialization_constant() const noexcept
context get_context() const noexcept
detail::KernelBundleImplPtr impl
std::vector< device > get_devices() const noexcept
kernel_bundle_plain(const detail::KernelBundleImplPtr &Impl)
backend get_backend() const noexcept
bool operator==(const kernel_bundle_plain &RHS) const
const device_image_plain * begin() const
bool has_kernel(const kernel_id &KernelID) const noexcept
kernel ext_oneapi_get_kernel(const std::string &name)
kernel get_kernel(const kernel_id &KernelID) const
Objects of the class represents an instance of an image in a specific state.
bool has_kernel(const kernel_id &KernelID, const device &Dev) const noexcept
bool has_kernel(const kernel_id &KernelID) const noexcept
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:64
The kernel_bundle class represents collection of device images in a particular state.
bool ext_oneapi_has_kernel(const std::string &name)
std::vector< kernel_id > get_kernel_ids() const
bool contains_specialization_constants() const noexcept
bool has_kernel(const kernel_id &KernelID) const noexcept
bool has_specialization_constant() const noexcept
device_image_iterator begin() const
device_image_iterator end() const
kernel get_kernel(const kernel_id &KernelID) const
bool has_kernel(const device &Dev) const noexcept
kernel ext_oneapi_get_kernel(const std::string &name)
backend get_backend() const noexcept
friend auto get_native(const kernel_bundle< StateB > &Obj) -> backend_return_t< Backend, kernel_bundle< StateB >>
std::vector< device > get_devices() const noexcept
bool has_kernel(const kernel_id &KernelID, const device &Dev) const noexcept
context get_context() const noexcept
bool has_kernel() const noexcept
bool empty() const noexcept
bool native_specialization_constant() const noexcept
std::remove_reference_t< decltype(SpecName)>::value_type get_specialization_constant() const
void set_specialization_constant(typename std::remove_reference_t< decltype(SpecName)>::value_type Value)
Sets the value of the specialization constant whose address is SpecName for this bundle.
Objects of the class identify kernel is some kernel_bundle related APIs.
bool operator!=(const kernel_id &RHS) const
Provides an abstraction of a SYCL kernel.
Definition: kernel.hpp:77
Objects of the property_list class are containers for the SYCL properties.
PiProgram cast(cl_program)=delete
std::vector< sycl::device > find_device_intersection(const std::vector< kernel_bundle< bundle_state::object >> &ObjectBundles)
std::shared_ptr< detail::kernel_bundle_impl > build_impl(const kernel_bundle< bundle_state::input > &InputBundle, const std::vector< device > &Devs, const property_list &PropList)
std::shared_ptr< device_image_impl > DeviceImageImplPtr
std::function< bool(const detail::DeviceImageImplPtr &DevImgImpl)> DevImgSelectorImpl
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: impl_utils.hpp:30
const std::vector< device > removeDuplicateDevices(const std::vector< device > &Devs)
detail::KernelBundleImplPtr get_kernel_bundle_impl(const context &Ctx, const std::vector< device > &Devs, bundle_state State)
T createSyclObjFromImpl(decltype(T::impl) ImplObj)
Definition: impl_utils.hpp:48
std::shared_ptr< detail::kernel_bundle_impl > compile_impl(const kernel_bundle< bundle_state::input > &InputBundle, const std::vector< device > &Devs, const property_list &PropList)
std::shared_ptr< detail::kernel_bundle_impl > join_impl(const std::vector< detail::KernelBundleImplPtr > &Bundles, bundle_state State)
kernel_id get_kernel_id_impl(string_view KernelName)
std::shared_ptr< detail::kernel_bundle_impl > KernelBundleImplPtr
kernel_bundle< State > get_empty_interop_kernel_bundle(const context &Ctx)
make_kernel may need an empty interop kernel bundle.
bool has_kernel_bundle_impl(const context &Ctx, const std::vector< device > &Devs, bundle_state State)
detail::KernelBundleImplPtr get_empty_interop_kernel_bundle_impl(const context &Ctx, const std::vector< device > &Devs)
std::shared_ptr< detail::kernel_bundle_impl > link_impl(const std::vector< kernel_bundle< bundle_state::object >> &ObjectBundles, const std::vector< device > &Devs, const property_list &PropList)
kernel_bundle< bundle_state::executable > build_from_source(kernel_bundle< bundle_state::ext_oneapi_source > &SourceKB, const std::vector< device > &Devices, const std::vector< std::string > &BuildOptions, std::string *LogPtr)
kernel_bundle< bundle_state::ext_oneapi_source > create_kernel_bundle_from_source(const context &SyclContext, source_language Language, const std::vector< std::byte > &Bytes)
bool is_source_kernel_bundle_supported(backend BE, source_language Language)
sycl::detail::kernel_bundle_impl kernel_bundle_impl
decltype(properties{}) empty_properties_t
Definition: properties.hpp:190
kernel_bundle(kernel_bundle< State > &&) -> kernel_bundle< State >
sycl::kernel_bundle< State > join(const std::vector< sycl::kernel_bundle< State >> &Bundles)
kernel_bundle< bundle_state::executable > build(const kernel_bundle< bundle_state::input > &InputBundle, const std::vector< device > &Devs, const property_list &PropList={})
kernel_id get_kernel_id()
kernel_bundle< bundle_state::object > compile(const kernel_bundle< bundle_state::input > &InputBundle, const std::vector< device > &Devs, const property_list &PropList={})
std::vector< kernel_id > get_kernel_ids()
bool is_compatible(const std::vector< kernel_id > &KernelIDs, const device &Dev)
bool has_kernel_bundle(const context &Ctx, const std::vector< device > &Devs)
kernel_bundle< State > get_kernel_bundle(const context &Ctx, const std::vector< device > &Devs)
A kernel bundle in state State which contains all of the kernels in the application which are compati...
ESIMD_NODEBUG ESIMD_INLINE sycl::ext::intel::esimd::simd< float, SZ > log(sycl::ext::intel::esimd::simd< float, SZ > x) __NOEXC
auto get_native(const SyclObjectT &Obj) -> backend_return_t< BackendName, SyclObjectT >
Definition: backend.hpp:136
typename backend_traits< Backend >::template return_type< SyclType > backend_return_t
Definition: backend.hpp:87
const void value_type
Definition: multi_ptr.hpp:457
kernel_bundle< bundle_state::executable > link(const std::vector< kernel_bundle< bundle_state::object >> &ObjectBundles, const std::vector< device > &Devs, const property_list &PropList={})
Definition: access.hpp:18
uintptr_t pi_native_handle
Definition: pi.h:224
C++ wrapper of extern "C" PI interfaces.
_Abi const simd< _Tp, _Abi > & noexcept
Definition: simd.hpp:1324
size_t operator()(const sycl::device_image< State > &DeviceImage) const
size_t operator()(const sycl::kernel_bundle< State > &KernelBundle) const
size_t operator()(const sycl::kernel_id &KernelID) const
build_options(const std::vector< std::string > &optsArg)