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 <detail/compiler.hpp>
11 #include <sycl/detail/common.hpp>
12 #include <sycl/detail/os_util.hpp>
13 #include <sycl/detail/ur.hpp>
14 #include <ur_api.h>
15 #include "ur_utils.hpp"
16 
18 
19 #include <atomic>
20 #include <cstring>
21 #include <memory>
22 
23 namespace sycl {
24 inline namespace _V1 {
25 namespace detail {
26 
27 // A wrapper for passing around byte array properties
28 class ByteArray {
29 public:
30  using ConstIterator = const std::uint8_t *;
31 
32  ByteArray(const std::uint8_t *Ptr, std::size_t Size) : Ptr{Ptr}, Size{Size} {}
33  const std::uint8_t &operator[](std::size_t Idx) const { return Ptr[Idx]; }
34  std::size_t size() const { return Size; }
35  ConstIterator begin() const { return Ptr; }
36  ConstIterator end() const { return Ptr + Size; }
37 
38  template <typename... Ts> auto consume() {
39  if constexpr (sizeof...(Ts) == 1)
40  return consumeOneElem<Ts...>();
41  else
42  return std::tuple{consumeOneElem<Ts>()...};
43  }
44 
45  void dropBytes(std::size_t Bytes) {
46  assert(Bytes <= Size && "Not enough bytes left!");
47  Ptr += Bytes;
48  Size -= Bytes;
49  }
50 
51  template <typename T> void drop() { return dropBytes(sizeof(T)); }
52 
53  bool empty() const { return Size == 0; }
54 
55 private:
56  template <typename T> T consumeOneElem() {
57  assert(sizeof(T) <= Size && "Out of bounds!");
58  T Val;
59  std::memcpy(&Val, Ptr, sizeof(T));
60  drop<T>();
61  return Val;
62  }
63 
64  const std::uint8_t *Ptr;
65  std::size_t Size;
66 };
67 
68 // C++ wrapper over the _sycl_device_binary_property_struct structure.
70 public:
72  : Prop(Prop) {}
73 
74  uint32_t asUint32() const;
75  ByteArray asByteArray() const;
76  const char *asCString() const;
77 
78 protected:
79  friend std::ostream &operator<<(std::ostream &Out,
80  const DeviceBinaryProperty &P);
82 };
83 
84 std::ostream &operator<<(std::ostream &Out, const DeviceBinaryProperty &P);
85 
86 // SYCL RT wrapper over UR binary image.
88 public:
89  // Represents a range of properties to enable iteration over them.
90  // Implements the standard C++ STL input iterator interface.
91  class PropertyRange {
92  public:
93  using ValTy = std::remove_pointer<sycl_device_binary_property>::type;
94 
95  class ConstIterator {
97 
98  public:
99  using iterator_category = std::input_iterator_tag;
100  using value_type = ValTy;
101  using difference_type = ptrdiff_t;
104 
105  ConstIterator(sycl_device_binary_property Cur = nullptr) : Cur(Cur) {}
107  Cur++;
108  return *this;
109  }
111  ConstIterator Ret = *this;
112  ++(*this);
113  return Ret;
114  }
115  bool operator==(ConstIterator Other) const { return Cur == Other.Cur; }
116  bool operator!=(ConstIterator Other) const { return !(*this == Other); }
117  reference operator*() const { return Cur; }
118  };
119  ConstIterator begin() const { return ConstIterator(Begin); }
120  ConstIterator end() const { return ConstIterator(End); }
121  size_t size() const { return std::distance(begin(), end()); }
122  friend class RTDeviceBinaryImage;
123  bool isAvailable() const { return !(Begin == nullptr); }
124 
125  private:
126  PropertyRange() : Begin(nullptr), End(nullptr) {}
127  // Searches for a property set with given name and constructs a
128  // PropertyRange spanning all its elements. If property set is not found,
129  // the range will span zero elements.
130  PropertyRange(sycl_device_binary Bin, const char *PropSetName)
131  : PropertyRange() {
132  init(Bin, PropSetName);
133  };
134  void init(sycl_device_binary Bin, const char *PropSetName);
137  };
138 
139 public:
140  RTDeviceBinaryImage() : Bin(nullptr) {}
142  // Explicitly delete copy constructor/operator= to avoid unintentional copies
145  // Explicitly retain move constructors to facilitate potential moves across
146  // collections
149 
150  virtual ~RTDeviceBinaryImage() {}
151 
152  bool supportsSpecConstants() const {
154  }
155 
156  const sycl_device_binary_struct &getRawData() const { return *get(); }
157 
158  virtual void print() const;
159  virtual void dump(std::ostream &Out) const;
160 
161  size_t getSize() const {
162  assert(Bin && "binary image data not set");
163  return static_cast<size_t>(Bin->BinaryEnd - Bin->BinaryStart);
164  }
165 
166  const char *getCompileOptions() const {
167  assert(Bin && "binary image data not set");
168  return Bin->CompileOptions;
169  }
170 
171  const char *getLinkOptions() const {
172  assert(Bin && "binary image data not set");
173  return Bin->LinkOptions;
174  }
175 
178  assert(Bin && "binary image data not set");
179  return Format;
180  }
181 
183  sycl_device_binary_property getProperty(const char *PropName) const;
184 
209  const PropertyRange &getSpecConstants() const { return SpecConstIDMap; }
212  }
215  return KernelParamOptInfo;
216  }
217  const PropertyRange &getAssertUsed() const { return AssertUsed; }
219  const std::vector<ur_program_metadata_t> &getProgramMetadataUR() const {
220  return ProgramMetadataUR;
221  }
224  const PropertyRange &getDeviceGlobals() const { return DeviceGlobals; }
226  return DeviceRequirements;
227  }
228  const PropertyRange &getHostPipes() const { return HostPipes; }
230 
231  std::uintptr_t getImageID() const {
232  assert(Bin && "Image ID is not available without a binary image.");
233  return ImageId;
234  }
235 
236 protected:
238  sycl_device_binary get() const { return Bin; }
239 
241 
255 
256  std::vector<ur_program_metadata_t> ProgramMetadataUR;
257 
258 private:
259  static std::atomic<uintptr_t> ImageCounter;
260  uintptr_t ImageId = 0;
261 };
262 
263 // Dynamically allocated device binary image, which de-allocates its binary
264 // data in destructor.
266 public:
267  DynRTDeviceBinaryImage(std::unique_ptr<char[]> &&DataPtr, size_t DataSize);
268  ~DynRTDeviceBinaryImage() override;
269 
270  void print() const override {
272  std::cerr << " DYNAMICALLY CREATED\n";
273  }
274 
275 protected:
276  std::unique_ptr<char[]> Data;
277 };
278 
279 } // namespace detail
280 } // namespace _V1
281 } // 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 _sycl_device_binary_property_struct *Prop)
friend std::ostream & operator<<(std::ostream &Out, const DeviceBinaryProperty &P)
const _sycl_device_binary_property_struct * Prop
DynRTDeviceBinaryImage(std::unique_ptr< char[]> &&DataPtr, size_t DataSize)
std::remove_pointer< sycl_device_binary_property >::type ValTy
RTDeviceBinaryImage & operator=(const RTDeviceBinaryImage &)=delete
virtual void dump(std::ostream &Out) const
RTDeviceBinaryImage::PropertyRange ProgramMetadata
RTDeviceBinaryImage::PropertyRange ImportedSymbols
RTDeviceBinaryImage(RTDeviceBinaryImage &&)=default
RTDeviceBinaryImage::PropertyRange SpecConstIDMap
RTDeviceBinaryImage(const RTDeviceBinaryImage &)=delete
RTDeviceBinaryImage::PropertyRange DeviceLibReqMask
RTDeviceBinaryImage::PropertyRange VirtualFunctions
const PropertyRange & getHostPipes() const
const PropertyRange & getSpecConstants() const
Gets the iterator range over specialization constants in this binary image.
const sycl_device_binary_struct & getRawData() const
const PropertyRange & getVirtualFunctions() const
RTDeviceBinaryImage::PropertyRange AssertUsed
RTDeviceBinaryImage & operator=(RTDeviceBinaryImage &&)=default
ur::DeviceBinaryType getFormat() const
Returns the format of the binary image.
const PropertyRange & getSpecConstantsDefaultValues() const
RTDeviceBinaryImage::PropertyRange KernelParamOptInfo
const std::vector< ur_program_metadata_t > & getProgramMetadataUR() const
const PropertyRange & getAssertUsed() const
const PropertyRange & getProgramMetadata() const
sycl_device_binary_property getProperty(const char *PropName) const
Returns a single property from SYCL_MISC_PROP category.
const PropertyRange & getExportedSymbols() const
RTDeviceBinaryImage::PropertyRange DeviceGlobals
std::vector< ur_program_metadata_t > ProgramMetadataUR
const PropertyRange & getDeviceGlobals() const
const PropertyRange & getDeviceRequirements() const
const PropertyRange & getImportedSymbols() const
RTDeviceBinaryImage::PropertyRange ExportedSymbols
const PropertyRange & getKernelParamOptInfo() const
const PropertyRange & getDeviceLibReqMask() const
RTDeviceBinaryImage::PropertyRange SpecConstDefaultValuesMap
RTDeviceBinaryImage::PropertyRange DeviceRequirements
RTDeviceBinaryImage::PropertyRange HostPipes
sycl_device_binary_type
Types of device binary.
Definition: compiler.hpp:114
@ SYCL_DEVICE_BINARY_TYPE_SPIRV
Definition: compiler.hpp:117
@ SYCL_DEVICE_BINARY_TYPE_NONE
Definition: compiler.hpp:115
__SYCL_EXTERN_STREAM_ATTRS ostream cerr
Linked to standard error (unbuffered)
std::ostream & operator<<(std::ostream &os, std::optional< T > const &opt)
Definition: access.hpp:18
This struct is a record of the device binary information.
Definition: compiler.hpp:132
const char * LinkOptions
a null-terminated string; target- and compiler-specific options which are suggested to use to "link" ...
Definition: compiler.hpp:158
const char * CompileOptions
a null-terminated string; target- and compiler-specific options which are suggested to use to "compil...
Definition: compiler.hpp:155
const unsigned char * BinaryStart
Pointer to the target code start.
Definition: compiler.hpp:164
const unsigned char * BinaryEnd
Pointer to the target code end.
Definition: compiler.hpp:166
C++ utilities for Unified Runtime integration.
_sycl_device_binary_property_struct * sycl_device_binary_property
Definition: ur.hpp:35