DPC++ Runtime
Runtime libraries for oneAPI DPC++
device_binary_image.hpp
Go to the documentation of this file.
1 //==----- device_binary_image.hpp --- SYCL device binary image abstraction -==//
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 #pragma once
9 
10 #include <sycl/detail/common.hpp>
11 #include <sycl/detail/os_util.hpp>
12 #include <sycl/detail/pi.hpp>
13 
14 #include <atomic>
15 #include <cstring>
16 #include <memory>
17 
18 namespace sycl {
20 namespace detail {
21 
22 // A wrapper for passing around byte array properties
23 class ByteArray {
24 public:
25  using ConstIterator = const std::uint8_t *;
26 
27  ByteArray(const std::uint8_t *Ptr, std::size_t Size) : Ptr{Ptr}, Size{Size} {}
28  const std::uint8_t &operator[](std::size_t Idx) const { return Ptr[Idx]; }
29  std::size_t size() const { return Size; }
30  ConstIterator begin() const { return Ptr; }
31  ConstIterator end() const { return Ptr + Size; }
32 
33  template <typename... Ts> auto consume() {
34  if constexpr (sizeof...(Ts) == 1)
35  return consumeOneElem<Ts...>();
36  else
37  return std::tuple{consumeOneElem<Ts>()...};
38  }
39 
40  void dropBytes(std::size_t Bytes) {
41  assert(Bytes <= Size && "Not enough bytes left!");
42  Ptr += Bytes;
43  Size -= Bytes;
44  }
45 
46  template <typename T> void drop() { return dropBytes(sizeof(T)); }
47 
48  bool empty() const { return Size == 0; }
49 
50 private:
51  template <typename T> T consumeOneElem() {
52  assert(sizeof(T) <= Size && "Out of bounds!");
53  T Val;
54  std::memcpy(&Val, Ptr, sizeof(T));
55  drop<T>();
56  return Val;
57  }
58 
59  const std::uint8_t *Ptr;
60  std::size_t Size;
61 };
62 
63 // C++ wrapper over the _pi_device_binary_property_struct structure.
65 public:
67  : Prop(Prop) {}
68 
69  pi_uint32 asUint32() const;
70  ByteArray asByteArray() const;
71  const char *asCString() const;
72 
73 protected:
74  friend std::ostream &operator<<(std::ostream &Out,
75  const DeviceBinaryProperty &P);
77 };
78 
79 std::ostream &operator<<(std::ostream &Out, const DeviceBinaryProperty &P);
80 
81 // SYCL RT wrapper over PI binary image.
83 public:
84  // Represents a range of properties to enable iteration over them.
85  // Implements the standard C++ STL input iterator interface.
86  class PropertyRange {
87  public:
88  using ValTy = std::remove_pointer<pi_device_binary_property>::type;
89 
90  class ConstIterator {
92 
93  public:
94  using iterator_category = std::input_iterator_tag;
95  using value_type = ValTy;
96  using difference_type = ptrdiff_t;
99 
100  ConstIterator(pi_device_binary_property Cur = nullptr) : Cur(Cur) {}
102  Cur++;
103  return *this;
104  }
106  ConstIterator Ret = *this;
107  ++(*this);
108  return Ret;
109  }
110  bool operator==(ConstIterator Other) const { return Cur == Other.Cur; }
111  bool operator!=(ConstIterator Other) const { return !(*this == Other); }
112  reference operator*() const { return Cur; }
113  };
114  ConstIterator begin() const { return ConstIterator(Begin); }
115  ConstIterator end() const { return ConstIterator(End); }
116  size_t size() const { return std::distance(begin(), end()); }
117  friend class RTDeviceBinaryImage;
118  bool isAvailable() const { return !(Begin == nullptr); }
119 
120  private:
121  PropertyRange() : Begin(nullptr), End(nullptr) {}
122  // Searches for a property set with given name and constructs a
123  // PropertyRange spanning all its elements. If property set is not found,
124  // the range will span zero elements.
125  PropertyRange(pi_device_binary Bin, const char *PropSetName)
126  : PropertyRange() {
127  init(Bin, PropSetName);
128  };
129  void init(pi_device_binary Bin, const char *PropSetName);
132  };
133 
134 public:
136  : Bin(nullptr), ModuleHandle(ModuleHandle) {}
138  : ModuleHandle(ModuleHandle) {
139  init(Bin);
140  }
141  // Explicitly delete copy constructor/operator= to avoid unintentional copies
142  RTDeviceBinaryImage(const RTDeviceBinaryImage &) = delete;
144  // Explicitly retain move constructors to facilitate potential moves across
145  // collections
148 
149  OSModuleHandle getOSModuleHandle() const { return ModuleHandle; }
150 
151  virtual ~RTDeviceBinaryImage() {}
152 
153  bool supportsSpecConstants() const {
154  return getFormat() == PI_DEVICE_BINARY_TYPE_SPIRV;
155  }
156 
157  const pi_device_binary_struct &getRawData() const { return *get(); }
158 
159  virtual void print() const;
160  virtual void dump(std::ostream &Out) const;
161 
162  size_t getSize() const {
163  assert(Bin && "binary image data not set");
164  return static_cast<size_t>(Bin->BinaryEnd - Bin->BinaryStart);
165  }
166 
167  const char *getCompileOptions() const {
168  assert(Bin && "binary image data not set");
169  return Bin->CompileOptions;
170  }
171 
172  const char *getLinkOptions() const {
173  assert(Bin && "binary image data not set");
174  return Bin->LinkOptions;
175  }
176 
179  assert(Bin && "binary image data not set");
180  return Format;
181  }
182 
184  pi_device_binary_property getProperty(const char *PropName) const;
185 
210  const PropertyRange &getSpecConstants() const { return SpecConstIDMap; }
212  return SpecConstDefaultValuesMap;
213  }
214  const PropertyRange &getDeviceLibReqMask() const { return DeviceLibReqMask; }
216  return KernelParamOptInfo;
217  }
218  const PropertyRange &getAssertUsed() const { return AssertUsed; }
219  const PropertyRange &getProgramMetadata() const { return ProgramMetadata; }
220  const PropertyRange &getExportedSymbols() const { return ExportedSymbols; }
221  const PropertyRange &getDeviceGlobals() const { return DeviceGlobals; }
223  return DeviceRequirements;
224  }
225 
226  std::uintptr_t getImageID() const {
227  assert(Bin && "Image ID is not available without a binary image.");
228  return reinterpret_cast<std::uintptr_t>(Bin);
229  }
230 
231 protected:
232  void init(pi_device_binary Bin);
233  pi_device_binary get() const { return Bin; }
234 
237 
248 };
249 
250 // Dynamically allocated device binary image, which de-allocates its binary
251 // data in destructor.
253 public:
254  DynRTDeviceBinaryImage(std::unique_ptr<char[]> &&DataPtr, size_t DataSize,
255  OSModuleHandle M);
256  ~DynRTDeviceBinaryImage() override;
257 
258  void print() const override {
260  std::cerr << " DYNAMICALLY CREATED\n";
261  }
262 
263 protected:
264  std::unique_ptr<char[]> Data;
265 };
266 
267 } // namespace detail
268 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
269 } // namespace sycl
PI_DEVICE_BINARY_TYPE_NONE
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_NONE
Definition: pi.h:762
sycl::_V1::detail::RTDeviceBinaryImage::ExportedSymbols
RTDeviceBinaryImage::PropertyRange ExportedSymbols
Definition: device_binary_image.hpp:245
sycl::_V1::detail::RTDeviceBinaryImage::DeviceGlobals
RTDeviceBinaryImage::PropertyRange DeviceGlobals
Definition: device_binary_image.hpp:246
sycl::_V1::detail::RTDeviceBinaryImage::getKernelParamOptInfo
const PropertyRange & getKernelParamOptInfo() const
Definition: device_binary_image.hpp:215
sycl::_V1::detail::pi::PiDeviceBinaryType
::pi_device_binary_type PiDeviceBinaryType
Definition: pi.hpp:127
sycl::_V1::detail::RTDeviceBinaryImage::getRawData
const pi_device_binary_struct & getRawData() const
Definition: device_binary_image.hpp:157
sycl::_V1::detail::RTDeviceBinaryImage::getSize
size_t getSize() const
Definition: device_binary_image.hpp:162
PI_DEVICE_BINARY_TYPE_SPIRV
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_SPIRV
Definition: pi.h:767
sycl::_V1::detail::RTDeviceBinaryImage::ModuleHandle
OSModuleHandle ModuleHandle
Definition: device_binary_image.hpp:236
sycl::_V1::detail::RTDeviceBinaryImage::getDeviceLibReqMask
const PropertyRange & getDeviceLibReqMask() const
Definition: device_binary_image.hpp:214
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::detail::RTDeviceBinaryImage::AssertUsed
RTDeviceBinaryImage::PropertyRange AssertUsed
Definition: device_binary_image.hpp:243
sycl::_V1::detail::RTDeviceBinaryImage::getSpecConstantsDefaultValues
const PropertyRange & getSpecConstantsDefaultValues() const
Definition: device_binary_image.hpp:211
sycl::_V1::detail::ByteArray::operator[]
const std::uint8_t & operator[](std::size_t Idx) const
Definition: device_binary_image.hpp:28
sycl::_V1::detail::DeviceBinaryProperty::Prop
const _pi_device_binary_property_struct * Prop
Definition: device_binary_image.hpp:76
sycl::_V1::detail::ByteArray::empty
bool empty() const
Definition: device_binary_image.hpp:48
sycl::_V1::detail::RTDeviceBinaryImage::getAssertUsed
const PropertyRange & getAssertUsed() const
Definition: device_binary_image.hpp:218
sycl::_V1::detail::memcpy
void memcpy(void *Dst, const void *Src, size_t Size)
Definition: memcpy.hpp:16
sycl::_V1::detail::RTDeviceBinaryImage::getDeviceRequirements
const PropertyRange & getDeviceRequirements() const
Definition: device_binary_image.hpp:222
sycl::_V1::detail::ByteArray::begin
ConstIterator begin() const
Definition: device_binary_image.hpp:30
sycl::_V1::detail::RTDeviceBinaryImage::getOSModuleHandle
OSModuleHandle getOSModuleHandle() const
Definition: device_binary_image.hpp:149
os_util.hpp
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::operator++
ConstIterator operator++(int)
Definition: device_binary_image.hpp:105
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::size
size_t size() const
Definition: device_binary_image.hpp:116
pi.hpp
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::iterator_category
std::input_iterator_tag iterator_category
Definition: device_binary_image.hpp:94
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator
Definition: device_binary_image.hpp:90
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::difference_type
ptrdiff_t difference_type
Definition: device_binary_image.hpp:96
sycl::_V1::detail::ByteArray
Definition: device_binary_image.hpp:23
sycl::_V1::detail::DeviceBinaryProperty
Definition: device_binary_image.hpp:64
sycl::_V1::detail::RTDeviceBinaryImage::getLinkOptions
const char * getLinkOptions() const
Definition: device_binary_image.hpp:172
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::RTDeviceBinaryImage::DeviceRequirements
RTDeviceBinaryImage::PropertyRange DeviceRequirements
Definition: device_binary_image.hpp:247
sycl::_V1::detail::RTDeviceBinaryImage::DeviceLibReqMask
RTDeviceBinaryImage::PropertyRange DeviceLibReqMask
Definition: device_binary_image.hpp:241
pi_uint32
uint32_t pi_uint32
Definition: pi.h:129
sycl::_V1::detail::RTDeviceBinaryImage::supportsSpecConstants
bool supportsSpecConstants() const
Definition: device_binary_image.hpp:153
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::end
ConstIterator end() const
Definition: device_binary_image.hpp:115
pi_device_binary_struct
This struct is a record of the device binary information.
Definition: pi.h:842
sycl::_V1::detail::RTDeviceBinaryImage::ProgramMetadata
RTDeviceBinaryImage::PropertyRange ProgramMetadata
Definition: device_binary_image.hpp:244
sycl::_V1::ext::oneapi::experimental::operator=
annotated_arg & operator=(annotated_arg &)=default
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::ConstIterator
ConstIterator(pi_device_binary_property Cur=nullptr)
Definition: device_binary_image.hpp:100
sycl::_V1::detail::ByteArray::drop
void drop()
Definition: device_binary_image.hpp:46
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::operator==
bool operator==(ConstIterator Other) const
Definition: device_binary_image.hpp:110
sycl::_V1::detail::RTDeviceBinaryImage::getCompileOptions
const char * getCompileOptions() const
Definition: device_binary_image.hpp:167
common.hpp
std::cerr
__SYCL_EXTERN_STREAM_ATTRS ostream cerr
Linked to standard error (unbuffered)
sycl::_V1::detail::DynRTDeviceBinaryImage::print
void print() const override
Definition: device_binary_image.hpp:258
sycl::_V1::detail::RTDeviceBinaryImage::SpecConstDefaultValuesMap
RTDeviceBinaryImage::PropertyRange SpecConstDefaultValuesMap
Definition: device_binary_image.hpp:240
sycl::_V1::detail::RTDeviceBinaryImage::KernelParamOptInfo
RTDeviceBinaryImage::PropertyRange KernelParamOptInfo
Definition: device_binary_image.hpp:242
sycl::_V1::detail::pi::print
std::enable_if<!std::is_pointer< T >::value, void >::type print(T val)
Definition: plugin_printers.hpp:24
sycl::_V1::detail::RTDeviceBinaryImage::getExportedSymbols
const PropertyRange & getExportedSymbols() const
Definition: device_binary_image.hpp:220
_pi_device_binary_property_struct
Definition: pi.h:741
sycl::_V1::detail::OSModuleHandle
intptr_t OSModuleHandle
Uniquely identifies an operating system module (executable or a dynamic library)
Definition: os_util.hpp:48
sycl::_V1::detail::RTDeviceBinaryImage::getProgramMetadata
const PropertyRange & getProgramMetadata() const
Definition: device_binary_image.hpp:219
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::begin
ConstIterator begin() const
Definition: device_binary_image.hpp:114
sycl::_V1::detail::RTDeviceBinaryImage::getSpecConstants
const PropertyRange & getSpecConstants() const
Gets the iterator range over specialization constants in this binary image.
Definition: device_binary_image.hpp:210
sycl::_V1::detail::DynRTDeviceBinaryImage
Definition: device_binary_image.hpp:252
sycl::_V1::detail::RTDeviceBinaryImage::SpecConstIDMap
RTDeviceBinaryImage::PropertyRange SpecConstIDMap
Definition: device_binary_image.hpp:239
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::operator*
reference operator*() const
Definition: device_binary_image.hpp:112
sycl::_V1::detail::ByteArray::ByteArray
ByteArray(const std::uint8_t *Ptr, std::size_t Size)
Definition: device_binary_image.hpp:27
sycl::_V1::detail::ByteArray::end
ConstIterator end() const
Definition: device_binary_image.hpp:31
sycl::_V1::detail::ByteArray::consume
auto consume()
Definition: device_binary_image.hpp:33
sycl::_V1::detail::RTDeviceBinaryImage::getImageID
std::uintptr_t getImageID() const
Definition: device_binary_image.hpp:226
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ValTy
std::remove_pointer< pi_device_binary_property >::type ValTy
Definition: device_binary_image.hpp:88
sycl::_V1::detail::ByteArray::dropBytes
void dropBytes(std::size_t Bytes)
Definition: device_binary_image.hpp:40
pi_device_binary_property
_pi_device_binary_property_struct * pi_device_binary_property
Definition: pi.h:748
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::operator++
ConstIterator & operator++()
Definition: device_binary_image.hpp:101
sycl::_V1::detail::RTDeviceBinaryImage::RTDeviceBinaryImage
RTDeviceBinaryImage(pi_device_binary Bin, OSModuleHandle ModuleHandle)
Definition: device_binary_image.hpp:137
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::isAvailable
bool isAvailable() const
Definition: device_binary_image.hpp:118
sycl::_V1::detail::ByteArray::ConstIterator
const std::uint8_t * ConstIterator
Definition: device_binary_image.hpp:25
sycl::_V1::operator<<
std::ostream & operator<<(std::ostream &Out, backend be)
Definition: backend_types.hpp:47
sycl::_V1::detail::RTDeviceBinaryImage::~RTDeviceBinaryImage
virtual ~RTDeviceBinaryImage()
Definition: device_binary_image.hpp:151
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::value_type
ValTy value_type
Definition: device_binary_image.hpp:95
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange::ConstIterator::operator!=
bool operator!=(ConstIterator Other) const
Definition: device_binary_image.hpp:111
sycl::_V1::detail::RTDeviceBinaryImage::PropertyRange
Definition: device_binary_image.hpp:86
sycl::_V1::detail::RTDeviceBinaryImage::RTDeviceBinaryImage
RTDeviceBinaryImage(OSModuleHandle ModuleHandle)
Definition: device_binary_image.hpp:135
sycl::_V1::detail::ByteArray::size
std::size_t size() const
Definition: device_binary_image.hpp:29
sycl::_V1::detail::RTDeviceBinaryImage::get
pi_device_binary get() const
Definition: device_binary_image.hpp:233
sycl::_V1::detail::RTDeviceBinaryImage
Definition: device_binary_image.hpp:82
sycl::_V1::detail::RTDeviceBinaryImage::getFormat
pi::PiDeviceBinaryType getFormat() const
Returns the format of the binary image.
Definition: device_binary_image.hpp:178
sycl::_V1::detail::DynRTDeviceBinaryImage::Data
std::unique_ptr< char[]> Data
Definition: device_binary_image.hpp:264
sycl::_V1::detail::DeviceBinaryProperty::DeviceBinaryProperty
DeviceBinaryProperty(const _pi_device_binary_property_struct *Prop)
Definition: device_binary_image.hpp:66
sycl::_V1::detail::RTDeviceBinaryImage::Bin
pi_device_binary Bin
Definition: device_binary_image.hpp:235