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 {
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 
61 pi_uint32 DeviceBinaryProperty::asUint32() const {
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 
69 ByteArray DeviceBinaryProperty::asByteArray() const {
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 << " OSModuleHandle : " << ModuleHandle << "\n";
111  std::cerr << " Compile options : "
112  << (Bin->CompileOptions ? Bin->CompileOptions : "NULL") << "\n";
113  std::cerr << " Link options : "
114  << (Bin->LinkOptions ? Bin->LinkOptions : "NULL") << "\n";
115  std::cerr << " Entries : ";
116  for (_pi_offload_entry EntriesIt = Bin->EntriesBegin;
117  EntriesIt != Bin->EntriesEnd; ++EntriesIt)
118  std::cerr << EntriesIt->name << " ";
119  std::cerr << "\n";
120  std::cerr << " Properties [" << Bin->PropertySetsBegin << "-"
121  << Bin->PropertySetsEnd << "]:\n";
122 
123  for (pi_device_binary_property_set PS = Bin->PropertySetsBegin;
124  PS != Bin->PropertySetsEnd; ++PS) {
125  std::cerr << " Category " << PS->Name << " [" << PS->PropertiesBegin
126  << "-" << PS->PropertiesEnd << "]:\n";
127 
129  P != PS->PropertiesEnd; ++P) {
130  std::cerr << " " << DeviceBinaryProperty(P) << "\n";
131  }
132  }
133 }
134 
135 void RTDeviceBinaryImage::dump(std::ostream &Out) const {
136  size_t ImgSize = getSize();
137  Out.write(reinterpret_cast<const char *>(Bin->BinaryStart), ImgSize);
138 }
139 
141 RTDeviceBinaryImage::getProperty(const char *PropName) const {
143  BoolProp.init(Bin, __SYCL_PI_PROPERTY_SET_SYCL_MISC_PROP);
144  if (!BoolProp.isAvailable())
145  return nullptr;
146  auto It = std::find_if(BoolProp.begin(), BoolProp.end(),
147  [=](pi_device_binary_property Prop) {
148  return !strcmp(PropName, Prop->Name);
149  });
150  if (It == BoolProp.end())
151  return nullptr;
152 
153  return *It;
154 }
155 
156 void RTDeviceBinaryImage::init(pi_device_binary Bin) {
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 
165  if (Format == PI_DEVICE_BINARY_TYPE_NONE)
166  // try to determine the format; may remain "NONE"
167  Format = pi::getBinaryImageFormat(Bin->BinaryStart, getSize());
168 
169  SpecConstIDMap.init(Bin, __SYCL_PI_PROPERTY_SET_SPEC_CONST_MAP);
170  SpecConstDefaultValuesMap.init(
172  DeviceLibReqMask.init(Bin, __SYCL_PI_PROPERTY_SET_DEVICELIB_REQ_MASK);
173  KernelParamOptInfo.init(Bin, __SYCL_PI_PROPERTY_SET_KERNEL_PARAM_OPT_INFO);
174  AssertUsed.init(Bin, __SYCL_PI_PROPERTY_SET_SYCL_ASSERT_USED);
175  ProgramMetadata.init(Bin, __SYCL_PI_PROPERTY_SET_PROGRAM_METADATA);
176  ExportedSymbols.init(Bin, __SYCL_PI_PROPERTY_SET_SYCL_EXPORTED_SYMBOLS);
177  DeviceGlobals.init(Bin, __SYCL_PI_PROPERTY_SET_SYCL_DEVICE_GLOBALS);
178  DeviceRequirements.init(Bin, __SYCL_PI_PROPERTY_SET_SYCL_DEVICE_REQUIREMENTS);
179 }
180 
181 DynRTDeviceBinaryImage::DynRTDeviceBinaryImage(
182  std::unique_ptr<char[]> &&DataPtr, size_t DataSize, OSModuleHandle M)
183  : RTDeviceBinaryImage(M) {
184  Data = std::move(DataPtr);
188  Bin->CompileOptions = "";
189  Bin->LinkOptions = "";
190  Bin->ManifestStart = nullptr;
191  Bin->ManifestEnd = nullptr;
192  Bin->BinaryStart = reinterpret_cast<unsigned char *>(Data.get());
193  Bin->BinaryEnd = Bin->BinaryStart + DataSize;
194  Bin->EntriesBegin = nullptr;
195  Bin->EntriesEnd = nullptr;
197  switch (Bin->Format) {
200  break;
201  default:
203  }
204  init(Bin);
205 }
206 
208  delete Bin;
209  Bin = nullptr;
210 }
211 
212 } // namespace detail
213 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
214 } // namespace sycl
const _pi_device_binary_property_struct * Prop
#define __SYCL_INLINE_VER_NAMESPACE(X)
__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:635
std::enable_if<!std::is_pointer< T >::value, void >::type print(T val)
::pi_device_binary_type PiDeviceBinaryType
Definition: pi.hpp:113
std::ostream & operator<<(std::ostream &Out, const DeviceBinaryProperty &P)
intptr_t OSModuleHandle
Uniquely identifies an operating system module (executable or a dynamic library)
Definition: os_util.hpp:48
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
#define __SYCL_PI_PROPERTY_SET_SYCL_DEVICE_GLOBALS
PropertySetRegistry::SYCL_DEVICE_GLOBALS defined in PropertySetIO.h.
Definition: pi.h:765
#define __SYCL_PI_PROPERTY_SET_SPEC_CONST_DEFAULT_VALUES_MAP
PropertySetRegistry::SYCL_SPEC_CONSTANTS_DEFAULT_VALUES defined in PropertySetIO.h.
Definition: pi.h:750
#define __SYCL_PI_PROPERTY_SET_DEVICELIB_REQ_MASK
PropertySetRegistry::SYCL_DEVICELIB_REQ_MASK defined in PropertySetIO.h.
Definition: pi.h:753
#define __SYCL_PI_PROPERTY_SET_KERNEL_PARAM_OPT_INFO
PropertySetRegistry::SYCL_KERNEL_PARAM_OPT_INFO defined in PropertySetIO.h.
Definition: pi.h:755
@ PI_PROPERTY_TYPE_UINT32
Definition: pi.h:671
@ PI_PROPERTY_TYPE_BYTE_ARRAY
Definition: pi.h:672
@ PI_PROPERTY_TYPE_STRING
Definition: pi.h:673
#define __SYCL_PI_PROPERTY_SET_SYCL_EXPORTED_SYMBOLS
PropertySetRegistry::SYCL_EXPORTED_SYMBOLS defined in PropertySetIO.h.
Definition: pi.h:763
#define __SYCL_PI_PROPERTY_SET_PROGRAM_METADATA
PropertySetRegistry::SYCL_KERNEL_PROGRAM_METADATA defined in PropertySetIO.h.
Definition: pi.h:757
uint32_t pi_uint32
Definition: pi.h:103
static const uint16_t PI_DEVICE_BINARY_VERSION
Definition: pi.h:711
#define __SYCL_PI_DEVICE_BINARY_TARGET_SPIRV64
SPIR-V 64-bit image <-> "spir64", 64-bit OpenCL device.
Definition: pi.h:727
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_SPIRV
Definition: pi.h:706
#define __SYCL_PI_PROPERTY_SET_SYCL_DEVICE_REQUIREMENTS
PropertySetRegistry::SYCL_DEVICE_REQUIREMENTS defined in PropertySetIO.h.
Definition: pi.h:767
#define __SYCL_PI_DEVICE_BINARY_TARGET_UNKNOWN
Target identification strings for pi_device_binary_struct.DeviceTargetSpec.
Definition: pi.h:723
static const uint8_t PI_DEVICE_BINARY_OFFLOAD_KIND_SYCL
Definition: pi.h:714
#define __SYCL_PI_PROPERTY_SET_SYCL_ASSERT_USED
PropertySetRegistry::SYCL_ASSERT_USED defined in PropertySetIO.h.
Definition: pi.h:761
#define __SYCL_PI_PROPERTY_SET_SPEC_CONST_MAP
Device binary image property set names recognized by the SYCL runtime.
Definition: pi.h:747
#define __SYCL_PI_PROPERTY_SET_SYCL_MISC_PROP
PropertySetRegistry::SYCL_MISC_PROP defined in PropertySetIO.h.
Definition: pi.h:759
static constexpr pi_device_binary_type PI_DEVICE_BINARY_TYPE_NONE
Definition: pi.h:701
C++ wrapper of extern "C" PI interfaces.
pi_device_binary_property PropertiesBegin
Definition: pi.h:692
pi_device_binary_property PropertiesEnd
Definition: pi.h:693
Definition: pi.h:658
This struct is a record of the device binary information.
Definition: pi.h:780
_pi_offload_entry EntriesEnd
Definition: pi.h:817
const char * LinkOptions
a null-terminated string; target- and compiler-specific options which are suggested to use to "link" ...
Definition: pi.h:806
_pi_offload_entry EntriesBegin
the offload entry table
Definition: pi.h:816
const char * CompileOptions
a null-terminated string; target- and compiler-specific options which are suggested to use to "compil...
Definition: pi.h:803
const unsigned char * BinaryEnd
Pointer to the target code end.
Definition: pi.h:814
const char * ManifestStart
Pointer to the manifest data start.
Definition: pi.h:808
uint16_t Version
version of this structure - for backward compatibility; all modifications which change order/type/off...
Definition: pi.h:784
const char * DeviceTargetSpec
null-terminated string representation of the device's target architecture which holds one of: __SYCL_...
Definition: pi.h:800
pi_device_binary_property_set PropertySetsEnd
Definition: pi.h:821
pi_device_binary_property_set PropertySetsBegin
Definition: pi.h:820
uint8_t Format
format of the binary data - SPIR-V, LLVM IR bitcode,...
Definition: pi.h:788
const char * ManifestEnd
Pointer to the manifest data end.
Definition: pi.h:810
uint8_t Kind
the type of offload model the binary employs; must be 4 for SYCL
Definition: pi.h:786
const unsigned char * BinaryStart
Pointer to the target code start.
Definition: pi.h:812