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