DPC++ Runtime
Runtime libraries for oneAPI DPC++
weak_object.hpp
Go to the documentation of this file.
1 //==-------------- weak_object.hpp --- SYCL weak objects -------------------==//
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/buffer.hpp>
14 
15 #include <optional>
16 
17 namespace sycl {
19 namespace ext::oneapi {
20 namespace detail {
21 // Helper for creating ranges for empty weak_objects.
22 template <int Dims> static range<Dims> createDummyRange() {
23  static_assert(Dims >= 0 && Dims < 4, "Invalid dimensionality in range.");
24  if constexpr (Dims == 0)
25  return {};
26  if constexpr (Dims == 1)
27  return {1};
28  else if constexpr (Dims == 2)
29  return {1, 1};
30  else
31  return {1, 1, 1};
32 }
33 } // namespace detail
34 
35 // The weak_object class.
36 // Since we use std::shared_ptr to implementations as a way to handle common
37 // reference semantics in SYCL classes, the implementation of the weak_object
38 // class holds a weak_ptr to the implementations. The weak_ptr is in the
39 // weak_object_base class.
40 template <typename SYCLObjT>
41 class weak_object : public detail::weak_object_base<SYCLObjT> {
42 public:
44 
45  constexpr weak_object() noexcept = default;
46  weak_object(const SYCLObjT &SYCLObj) noexcept
47  : detail::weak_object_base<SYCLObjT>(SYCLObj) {}
48  weak_object(const weak_object &Other) noexcept = default;
49  weak_object(weak_object &&Other) noexcept = default;
50 
51  weak_object &operator=(const SYCLObjT &SYCLObj) noexcept {
52  // Create weak_ptr from the shared_ptr to SYCLObj's implementation object.
53  this->MObjWeakPtr = sycl::detail::getSyclObjImpl(SYCLObj);
54  return *this;
55  }
56  weak_object &operator=(const weak_object &Other) noexcept = default;
57  weak_object &operator=(weak_object &&Other) noexcept = default;
58 
59  std::optional<SYCLObjT> try_lock() const noexcept {
60  auto MObjImplPtr = this->MObjWeakPtr.lock();
61  if (!MObjImplPtr)
62  return std::nullopt;
63  return sycl::detail::createSyclObjFromImpl<SYCLObjT>(MObjImplPtr);
64  }
65  SYCLObjT lock() const {
66  std::optional<SYCLObjT> OptionalObj = try_lock();
67  if (!OptionalObj)
68  throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
69  "Referenced object has expired.");
70  return *OptionalObj;
71  }
72 };
73 
74 // Specialization of weak_object for buffer as it needs additional members
75 // to reconstruct the original buffer.
76 template <typename T, int Dimensions, typename AllocatorT>
77 class weak_object<buffer<T, Dimensions, AllocatorT>>
78  : public detail::weak_object_base<buffer<T, Dimensions, AllocatorT>> {
79 private:
81 
82 public:
83  using object_type =
85 
86  constexpr weak_object() noexcept
87  : detail::weak_object_base<buffer_type>(),
88  MRange{detail::createDummyRange<Dimensions>()}, MOffsetInBytes{0},
89  MIsSubBuffer{false} {}
90  weak_object(const buffer_type &SYCLObj) noexcept
91  : detail::weak_object_base<buffer_type>(SYCLObj), MRange{SYCLObj.Range},
92  MOffsetInBytes{SYCLObj.OffsetInBytes},
93  MIsSubBuffer{SYCLObj.IsSubBuffer} {}
94  weak_object(const weak_object &Other) noexcept = default;
95  weak_object(weak_object &&Other) noexcept = default;
96 
97  weak_object &operator=(const buffer_type &SYCLObj) noexcept {
98  // Create weak_ptr from the shared_ptr to SYCLObj's implementation object.
99  this->MObjWeakPtr = sycl::detail::getSyclObjImpl(SYCLObj);
100  this->MRange = SYCLObj.Range;
101  this->MOffsetInBytes = SYCLObj.OffsetInBytes;
102  this->MIsSubBuffer = SYCLObj.IsSubBuffer;
103  return *this;
104  }
105  weak_object &operator=(const weak_object &Other) noexcept = default;
106  weak_object &operator=(weak_object &&Other) noexcept = default;
107 
108  std::optional<buffer_type> try_lock() const noexcept {
109  auto MObjImplPtr = this->MObjWeakPtr.lock();
110  if (!MObjImplPtr)
111  return std::nullopt;
112  // To reconstruct the buffer we use the reinterpret constructor.
113  return buffer_type{MObjImplPtr, MRange, MOffsetInBytes, MIsSubBuffer};
114  }
115  buffer_type lock() const {
116  std::optional<buffer_type> OptionalObj = try_lock();
117  if (!OptionalObj)
118  throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
119  "Referenced object has expired.");
120  return *OptionalObj;
121  }
122 
123 private:
124  // Additional members required for recreating buffers.
125  range<Dimensions> MRange;
126  size_t MOffsetInBytes;
127  bool MIsSubBuffer;
128 };
129 
130 } // namespace ext::oneapi
131 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
132 } // namespace sycl
sycl::_V1::ext::oneapi::detail::weak_object_base::object_type
SYCLObjT object_type
Definition: weak_object_base.hpp:28
sycl::_V1::make_error_code
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
Definition: exception.cpp:92
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::buffer
Defines a shared array that can be used by kernels in queues.
Definition: buffer.hpp:37
sycl::_V1::Dimensions
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
Definition: accessor.hpp:2854
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
sycl::_V1::ext::oneapi::weak_object::lock
SYCLObjT lock() const
Definition: weak_object.hpp:65
sycl::_V1::ext::oneapi::weak_object::operator=
weak_object & operator=(const SYCLObjT &SYCLObj) noexcept
Definition: weak_object.hpp:51
sycl::_V1::ext::oneapi::weak_object< buffer< T, Dimensions, AllocatorT > >::try_lock
std::optional< buffer_type > try_lock() const noexcept
Definition: weak_object.hpp:108
sycl::_V1::range< Dims >
defines_elementary.hpp
sycl::_V1::ext::oneapi::experimental::operator=
annotated_arg & operator=(annotated_arg &)=default
sycl::_V1::ext::oneapi::weak_object::object_type
typename detail::weak_object_base< SYCLObjT >::object_type object_type
Definition: weak_object.hpp:43
sycl::_V1::ext::oneapi::detail::createDummyRange
static range< Dims > createDummyRange()
Definition: weak_object.hpp:22
sycl::_V1::ext::oneapi::weak_object< buffer< T, Dimensions, AllocatorT > >::object_type
typename detail::weak_object_base< buffer_type >::object_type object_type
Definition: weak_object.hpp:84
sycl::_V1::ext::oneapi::weak_object
Definition: buffer.hpp:40
sycl::_V1::ext::oneapi::detail::weak_object_base
Definition: weak_object_base.hpp:16
sycl::_V1::ext::oneapi::weak_object::try_lock
std::optional< SYCLObjT > try_lock() const noexcept
Definition: weak_object.hpp:59
sycl::_V1::ext::oneapi::weak_object< buffer< T, Dimensions, AllocatorT > >::lock
buffer_type lock() const
Definition: weak_object.hpp:115
sycl::_V1::ext::oneapi::weak_object< buffer< T, Dimensions, AllocatorT > >::weak_object
constexpr weak_object() noexcept
Definition: weak_object.hpp:86
buffer.hpp
sycl::_V1::ext::oneapi::weak_object< buffer< T, Dimensions, AllocatorT > >::weak_object
weak_object(const buffer_type &SYCLObj) noexcept
Definition: weak_object.hpp:90
weak_object_base.hpp
sycl::_V1::ext::oneapi::weak_object< buffer< T, Dimensions, AllocatorT > >::operator=
weak_object & operator=(const buffer_type &SYCLObj) noexcept
Definition: weak_object.hpp:97
sycl::_V1::detail::getSyclObjImpl
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: common.hpp:300