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 {
19 inline namespace _V1 {
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:
135  RTDeviceBinaryImage() : Bin(nullptr) {}
137  // Explicitly delete copy constructor/operator= to avoid unintentional copies
140  // Explicitly retain move constructors to facilitate potential moves across
141  // collections
144 
145  virtual ~RTDeviceBinaryImage() {}
146 
147  bool supportsSpecConstants() const {
149  }
150 
151  const pi_device_binary_struct &getRawData() const { return *get(); }
152 
153  virtual void print() const;
154  virtual void dump(std::ostream &Out) const;
155 
156  size_t getSize() const {
157  assert(Bin && "binary image data not set");
158  return static_cast<size_t>(Bin->BinaryEnd - Bin->BinaryStart);
159  }
160 
161  const char *getCompileOptions() const {
162  assert(Bin && "binary image data not set");
163  return Bin->CompileOptions;
164  }
165 
166  const char *getLinkOptions() const {
167  assert(Bin && "binary image data not set");
168  return Bin->LinkOptions;
169  }
170 
173  assert(Bin && "binary image data not set");
174  return Format;
175  }
176 
178  pi_device_binary_property getProperty(const char *PropName) const;
179 
204  const PropertyRange &getSpecConstants() const { return SpecConstIDMap; }
207  }
210  return KernelParamOptInfo;
211  }
212  const PropertyRange &getAssertUsed() const { return AssertUsed; }
215  const PropertyRange &getDeviceGlobals() const { return DeviceGlobals; }
217  return DeviceRequirements;
218  }
219  const PropertyRange &getHostPipes() const { return HostPipes; }
220 
221  std::uintptr_t getImageID() const {
222  assert(Bin && "Image ID is not available without a binary image.");
223  return ImageId;
224  }
225 
226 protected:
227  void init(pi_device_binary Bin);
228  pi_device_binary get() const { return Bin; }
229 
231 
243 
244 private:
245  static std::atomic<uintptr_t> ImageCounter;
246  uintptr_t ImageId = 0;
247 };
248 
249 // Dynamically allocated device binary image, which de-allocates its binary
250 // data in destructor.
252 public:
253  DynRTDeviceBinaryImage(std::unique_ptr<char[]> &&DataPtr, size_t DataSize);
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 } // 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)
friend std::ostream & operator<<(std::ostream &Out, const DeviceBinaryProperty &P)
DeviceBinaryProperty(const _pi_device_binary_property_struct *Prop)
const _pi_device_binary_property_struct * Prop
DynRTDeviceBinaryImage(std::unique_ptr< char[]> &&DataPtr, size_t DataSize)
std::remove_pointer< pi_device_binary_property >::type ValTy
RTDeviceBinaryImage & operator=(const RTDeviceBinaryImage &)=delete
virtual void dump(std::ostream &Out) const
const pi_device_binary_struct & getRawData() const
pi_device_binary_property getProperty(const char *PropName) const
Returns a single property from SYCL_MISC_PROP category.
RTDeviceBinaryImage::PropertyRange ProgramMetadata
RTDeviceBinaryImage(RTDeviceBinaryImage &&)=default
RTDeviceBinaryImage::PropertyRange SpecConstIDMap
RTDeviceBinaryImage(const RTDeviceBinaryImage &)=delete
RTDeviceBinaryImage::PropertyRange DeviceLibReqMask
const PropertyRange & getHostPipes() const
const PropertyRange & getSpecConstants() const
Gets the iterator range over specialization constants in this binary image.
RTDeviceBinaryImage::PropertyRange AssertUsed
RTDeviceBinaryImage & operator=(RTDeviceBinaryImage &&)=default
const PropertyRange & getSpecConstantsDefaultValues() const
RTDeviceBinaryImage::PropertyRange KernelParamOptInfo
const PropertyRange & getAssertUsed() const
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.
RTDeviceBinaryImage::PropertyRange HostPipes
__SYCL_EXTERN_STREAM_ATTRS ostream cerr
Linked to standard error (unbuffered)
::pi_device_binary_type PiDeviceBinaryType
Definition: pi.hpp:134
std::ostream & operator<<(std::ostream &os, std::optional< T > const &opt)
Definition: access.hpp:18
uint32_t pi_uint32
Definition: pi.h:213
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_SPIRV
Definition: pi.h:946
_pi_device_binary_property_struct * pi_device_binary_property
Definition: pi.h:927
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_NONE
Definition: pi.h:941
C++ wrapper of extern "C" PI interfaces.
This struct is a record of the device binary information.
Definition: pi.h:1025
const char * LinkOptions
a null-terminated string; target- and compiler-specific options which are suggested to use to "link" ...
Definition: pi.h:1051
const char * CompileOptions
a null-terminated string; target- and compiler-specific options which are suggested to use to "compil...
Definition: pi.h:1048
const unsigned char * BinaryEnd
Pointer to the target code end.
Definition: pi.h:1059
const unsigned char * BinaryStart
Pointer to the target code start.
Definition: pi.h:1057