DPC++ Runtime
Runtime libraries for oneAPI DPC++
device_binary_image.cpp
Go to the documentation of this file.
1 //==----- device_binary_image.cpp --- 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 
10 #include <sycl/detail/pi.hpp>
11 
12 #include <algorithm>
13 #include <cstring>
14 #include <memory>
15 
16 namespace sycl {
17 inline namespace _V1 {
18 namespace detail {
19 
20 std::ostream &operator<<(std::ostream &Out, const DeviceBinaryProperty &P) {
21  switch (P.Prop->Type) {
23  Out << "[UINT32] ";
24  break;
26  Out << "[Byte array] ";
27  break;
29  Out << "[String] ";
30  break;
31  default:
32  assert(false && "unsupported property");
33  return Out;
34  }
35  Out << P.Prop->Name << "=";
36 
37  switch (P.Prop->Type) {
39  Out << P.asUint32();
40  break;
42  ByteArray BA = P.asByteArray();
43  std::ios_base::fmtflags FlagsBackup = Out.flags();
44  Out << std::hex;
45  for (const auto &Byte : BA) {
46  Out << "0x" << static_cast<unsigned>(Byte) << " ";
47  }
48  Out.flags(FlagsBackup);
49  break;
50  }
52  Out << P.asCString();
53  break;
54  default:
55  assert(false && "Unsupported property");
56  return Out;
57  }
58  return Out;
59 }
60 
62  assert(Prop->Type == PI_PROPERTY_TYPE_UINT32 && "property type mismatch");
63  // if type fits into the ValSize - it is used to store the property value
64  assert(Prop->ValAddr == nullptr && "primitive types must be stored inline");
65  const auto *P = reinterpret_cast<const unsigned char *>(&Prop->ValSize);
66  return (*P) | (*(P + 1) << 8) | (*(P + 2) << 16) | (*(P + 3) << 24);
67 }
68 
70  assert(Prop->Type == PI_PROPERTY_TYPE_BYTE_ARRAY && "property type mismatch");
71  assert(Prop->ValSize > 0 && "property size mismatch");
72  const auto *Data = pi::cast<const std::uint8_t *>(Prop->ValAddr);
73  return {Data, Prop->ValSize};
74 }
75 
76 const char *DeviceBinaryProperty::asCString() const {
77  assert(Prop->Type == PI_PROPERTY_TYPE_STRING && "property type mismatch");
78  assert(Prop->ValSize > 0 && "property size mismatch");
79  return pi::cast<const char *>(Prop->ValAddr);
80 }
81 
82 void RTDeviceBinaryImage::PropertyRange::init(pi_device_binary Bin,
83  const char *PropSetName) {
84  assert(!this->Begin && !this->End && "already initialized");
85  pi_device_binary_property_set PS = nullptr;
86 
87  for (PS = Bin->PropertySetsBegin; PS != Bin->PropertySetsEnd; ++PS) {
88  assert(PS->Name && "nameless property set - bug in the offload wrapper?");
89  if (!strcmp(PropSetName, PS->Name))
90  break;
91  }
92  if (PS == Bin->PropertySetsEnd) {
93  Begin = End = nullptr;
94  return;
95  }
96  Begin = PS->PropertiesBegin;
97  End = Begin ? PS->PropertiesEnd : nullptr;
98 }
99 
101  std::cerr << " --- Image " << Bin << "\n";
102  if (!Bin)
103  return;
104  std::cerr << " Version : " << (int)Bin->Version << "\n";
105  std::cerr << " Kind : " << (int)Bin->Kind << "\n";
106  std::cerr << " Format : " << (int)Bin->Format << "\n";
107  std::cerr << " Target : " << Bin->DeviceTargetSpec << "\n";
108  std::cerr << " Bin size : "
109  << ((intptr_t)Bin->BinaryEnd - (intptr_t)Bin->BinaryStart) << "\n";
110  std::cerr << " Compile options : "
111  << (Bin->CompileOptions ? Bin->CompileOptions : "NULL") << "\n";
112  std::cerr << " Link options : "
113  << (Bin->LinkOptions ? Bin->LinkOptions : "NULL") << "\n";
114  std::cerr << " Entries : ";
115  for (_pi_offload_entry EntriesIt = Bin->EntriesBegin;
116  EntriesIt != Bin->EntriesEnd; ++EntriesIt)
117  std::cerr << EntriesIt->name << " ";
118  std::cerr << "\n";
119  std::cerr << " Properties [" << Bin->PropertySetsBegin << "-"
120  << Bin->PropertySetsEnd << "]:\n";
121 
123  PS != Bin->PropertySetsEnd; ++PS) {
124  std::cerr << " Category " << PS->Name << " [" << PS->PropertiesBegin
125  << "-" << PS->PropertiesEnd << "]:\n";
126 
128  P != PS->PropertiesEnd; ++P) {
129  std::cerr << " " << DeviceBinaryProperty(P) << "\n";
130  }
131  }
132 }
133 
134 void RTDeviceBinaryImage::dump(std::ostream &Out) const {
135  size_t ImgSize = getSize();
136  Out.write(reinterpret_cast<const char *>(Bin->BinaryStart), ImgSize);
137 }
138 
140 RTDeviceBinaryImage::getProperty(const char *PropName) const {
143  if (!BoolProp.isAvailable())
144  return nullptr;
145  auto It = std::find_if(BoolProp.begin(), BoolProp.end(),
146  [=](pi_device_binary_property Prop) {
147  return !strcmp(PropName, Prop->Name);
148  });
149  if (It == BoolProp.end())
150  return nullptr;
151 
152  return *It;
153 }
154 
156  // Bin != nullptr is guaranteed here.
157  this->Bin = Bin;
158  // If device binary image format wasn't set by its producer, then can't change
159  // now, because 'Bin' data is part of the executable image loaded into memory
160  // which can't be modified (easily).
161  // TODO clang driver + ClangOffloadWrapper can figure out the format and set
162  // it when invoking the offload wrapper job
163  Format = static_cast<pi::PiDeviceBinaryType>(Bin->Format);
164 
166  // try to determine the format; may remain "NONE"
168 
180 
181  ImageId = ImageCounter++;
182 }
183 
184 std::atomic<uintptr_t> RTDeviceBinaryImage::ImageCounter = 1;
185 
187  std::unique_ptr<char[]> &&DataPtr, size_t DataSize)
188  : RTDeviceBinaryImage() {
189  Data = std::move(DataPtr);
193  Bin->CompileOptions = "";
194  Bin->LinkOptions = "";
195  Bin->ManifestStart = nullptr;
196  Bin->ManifestEnd = nullptr;
197  Bin->BinaryStart = reinterpret_cast<unsigned char *>(Data.get());
198  Bin->BinaryEnd = Bin->BinaryStart + DataSize;
199  Bin->EntriesBegin = nullptr;
200  Bin->EntriesEnd = nullptr;
202  switch (Bin->Format) {
205  break;
206  default:
208  }
209  init(Bin);
210 }
211 
213  delete Bin;
214  Bin = nullptr;
215 }
216 
217 } // namespace detail
218 } // namespace _V1
219 } // namespace sycl
const _pi_device_binary_property_struct * Prop
DynRTDeviceBinaryImage(std::unique_ptr< char[]> &&DataPtr, size_t DataSize)
virtual void dump(std::ostream &Out) const
pi_device_binary_property getProperty(const char *PropName) const
Returns a single property from SYCL_MISC_PROP category.
RTDeviceBinaryImage::PropertyRange ProgramMetadata
RTDeviceBinaryImage::PropertyRange SpecConstIDMap
RTDeviceBinaryImage::PropertyRange DeviceLibReqMask
RTDeviceBinaryImage::PropertyRange AssertUsed
RTDeviceBinaryImage::PropertyRange KernelParamOptInfo
RTDeviceBinaryImage::PropertyRange DeviceGlobals
RTDeviceBinaryImage::PropertyRange ExportedSymbols
RTDeviceBinaryImage::PropertyRange SpecConstDefaultValuesMap
RTDeviceBinaryImage::PropertyRange DeviceRequirements
RTDeviceBinaryImage::PropertyRange HostPipes
__SYCL_EXTERN_STREAM_ATTRS ostream cerr
Linked to standard error (unbuffered)
PiDeviceBinaryType getBinaryImageFormat(const unsigned char *ImgData, size_t ImgSize)
Tries to determine the device binary image foramat.
Definition: pi.cpp:626
::pi_device_binary_type PiDeviceBinaryType
Definition: pi.hpp:134
std::ostream & operator<<(std::ostream &os, std::optional< T > const &opt)
Definition: access.hpp:18
#define __SYCL_PI_PROPERTY_SET_SYCL_DEVICE_GLOBALS
PropertySetRegistry::SYCL_DEVICE_GLOBALS defined in PropertySetIO.h.
Definition: pi.h:1005
#define __SYCL_PI_PROPERTY_SET_SPEC_CONST_DEFAULT_VALUES_MAP
PropertySetRegistry::SYCL_SPEC_CONSTANTS_DEFAULT_VALUES defined in PropertySetIO.h.
Definition: pi.h:990
#define __SYCL_PI_PROPERTY_SET_DEVICELIB_REQ_MASK
PropertySetRegistry::SYCL_DEVICELIB_REQ_MASK defined in PropertySetIO.h.
Definition: pi.h:993
#define __SYCL_PI_PROPERTY_SET_KERNEL_PARAM_OPT_INFO
PropertySetRegistry::SYCL_KERNEL_PARAM_OPT_INFO defined in PropertySetIO.h.
Definition: pi.h:995
@ PI_PROPERTY_TYPE_UINT32
Definition: pi.h:911
@ PI_PROPERTY_TYPE_BYTE_ARRAY
Definition: pi.h:912
@ PI_PROPERTY_TYPE_STRING
Definition: pi.h:913
#define __SYCL_PI_PROPERTY_SET_SYCL_EXPORTED_SYMBOLS
PropertySetRegistry::SYCL_EXPORTED_SYMBOLS defined in PropertySetIO.h.
Definition: pi.h:1003
#define __SYCL_PI_PROPERTY_SET_PROGRAM_METADATA
PropertySetRegistry::SYCL_KERNEL_PROGRAM_METADATA defined in PropertySetIO.h.
Definition: pi.h:997
uint32_t pi_uint32
Definition: pi.h:213
static const uint16_t PI_DEVICE_BINARY_VERSION
Definition: pi.h:951
#define __SYCL_PI_DEVICE_BINARY_TARGET_SPIRV64
SPIR-V 64-bit image <-> "spir64", 64-bit OpenCL device.
Definition: pi.h:967
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_SPIRV
Definition: pi.h:946
#define __SYCL_PI_PROPERTY_SET_SYCL_HOST_PIPES
PropertySetRegistry::SYCL_HOST_PIPES defined in PropertySetIO.h.
Definition: pi.h:1010
#define __SYCL_PI_PROPERTY_SET_SYCL_DEVICE_REQUIREMENTS
PropertySetRegistry::SYCL_DEVICE_REQUIREMENTS defined in PropertySetIO.h.
Definition: pi.h:1007
#define __SYCL_PI_DEVICE_BINARY_TARGET_UNKNOWN
Target identification strings for pi_device_binary_struct.DeviceTargetSpec.
Definition: pi.h:963
static const uint8_t PI_DEVICE_BINARY_OFFLOAD_KIND_SYCL
Definition: pi.h:954
#define __SYCL_PI_PROPERTY_SET_SYCL_ASSERT_USED
PropertySetRegistry::SYCL_ASSERT_USED defined in PropertySetIO.h.
Definition: pi.h:1001
#define __SYCL_PI_PROPERTY_SET_SPEC_CONST_MAP
Device binary image property set names recognized by the SYCL runtime.
Definition: pi.h:987
#define __SYCL_PI_PROPERTY_SET_SYCL_MISC_PROP
PropertySetRegistry::SYCL_MISC_PROP defined in PropertySetIO.h.
Definition: pi.h:999
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_NONE
Definition: pi.h:941
C++ wrapper of extern "C" PI interfaces.
pi_device_binary_property PropertiesBegin
Definition: pi.h:932
pi_device_binary_property PropertiesEnd
Definition: pi.h:933
Definition: pi.h:898
This struct is a record of the device binary information.
Definition: pi.h:1025
_pi_offload_entry EntriesEnd
Definition: pi.h:1062
const char * LinkOptions
a null-terminated string; target- and compiler-specific options which are suggested to use to "link" ...
Definition: pi.h:1051
_pi_offload_entry EntriesBegin
the offload entry table
Definition: pi.h:1061
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 char * ManifestStart
Pointer to the manifest data start.
Definition: pi.h:1053
uint16_t Version
version of this structure - for backward compatibility; all modifications which change order/type/off...
Definition: pi.h:1029
const char * DeviceTargetSpec
null-terminated string representation of the device's target architecture which holds one of: __SYCL_...
Definition: pi.h:1045
pi_device_binary_property_set PropertySetsEnd
Definition: pi.h:1066
pi_device_binary_property_set PropertySetsBegin
Definition: pi.h:1065
uint8_t Format
format of the binary data - SPIR-V, LLVM IR bitcode,...
Definition: pi.h:1033
const char * ManifestEnd
Pointer to the manifest data end.
Definition: pi.h:1055
uint8_t Kind
the type of offload model the binary employs; must be 4 for SYCL
Definition: pi.h:1031
const unsigned char * BinaryStart
Pointer to the target code start.
Definition: pi.h:1057