Skip to content

Commit dc42a39

Browse files
committed
Removing Manifest from the offload binary structure.
1 parent 54e7f77 commit dc42a39

File tree

3 files changed

+293
-24
lines changed

3 files changed

+293
-24
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// REQUIRES: system-linux || system-windows
2+
3+
// End-to-end clang-offload-wrapper executable test: check that -batch options
4+
// works, and that the tool generates data properly accessible at runtime.
5+
6+
// --- Prepare test data
7+
// - create the first binary image
8+
// RUN: echo -e -n 'device binary image1\n' > %t.bin
9+
// RUN: echo -e -n '[Category1]\nint_prop1=1|10\n[Category2]\nint_prop2=1|20\n' > %t.props
10+
// RUN: echo -e -n 'kernel1\nkernel2\n' > %t.sym
11+
12+
// - create the second binary image with byte array property values
13+
// RUN: echo -e -n 'device binary image2\n' > %t_1.bin
14+
// RUN: echo -e -n '[Category3]\n' > %t_1.props
15+
// RUN: echo -e -n 'kernel1=2|IAAAAAAAAAQA\n' >> %t_1.props
16+
// RUN: echo -e -n 'kernel2=2|oAAAAAAAAAw///3/wB\n' >> %t_1.props
17+
18+
// - create the batch file input for the wrapper
19+
// RUN: echo '[Code|Properties|Symbols]' > %t.batch
20+
// RUN: echo %t.bin"|"%t.props"|"%t.sym >> %t.batch
21+
// RUN: echo %t_1.bin"|"%t_1.props"|" >> %t.batch
22+
// --- Generate "gold" output
23+
// RUN: cat %t.bin %t.props %t.sym > %t.all
24+
// --- Create the wrapper object
25+
// -host omitted - generate object for the host triple:
26+
// RUN: clang-offload-wrapper -kind=sycl -target=TARGET -format=native -batch %t.batch -o %t.wrapped.bc -fpreview-breaking-changes
27+
// RUN: llc --filetype=obj %t.wrapped.bc -o %t.wrapped.o
28+
// --- Compile & link the test with the wrapper
29+
// RUN: %clangxx %t.wrapped.o %s -o %t.batch.exe -v -fpreview-breaking-changes
30+
// --- Run and check ignoring white spaces
31+
// RUN: %t.batch.exe > %t.batch.exe.out
32+
// RUN: diff -b %t.batch.exe.out %t.all
33+
34+
#include <cassert>
35+
#include <cstdint>
36+
#include <cstring>
37+
#include <iostream>
38+
#include <string>
39+
40+
// Data types created by the offload wrapper and inserted in the wrapper object.
41+
// Match those defined in SYCL runtime Plugin Interface.
42+
struct _pi_offload_entry_struct {
43+
void *addr;
44+
char *name;
45+
size_t size;
46+
int32_t flags;
47+
int32_t reserved;
48+
};
49+
50+
typedef _pi_offload_entry_struct *_pi_offload_entry;
51+
52+
struct _pi_device_binary_property_struct {
53+
char *Name; // null-terminated property name
54+
void *ValAddr; // address of property value
55+
uint32_t Type; // pi_property_type
56+
uint64_t ValSize; // size of property value in bytes
57+
};
58+
59+
typedef _pi_device_binary_property_struct *pi_device_binary_property;
60+
61+
struct _pi_device_binary_property_set_struct {
62+
char *Name; // the name
63+
pi_device_binary_property PropertiesBegin; // array start
64+
pi_device_binary_property PropertiesEnd; // array end
65+
};
66+
67+
typedef _pi_device_binary_property_set_struct *pi_device_binary_property_set;
68+
69+
struct pi_device_binary_struct {
70+
uint16_t Version;
71+
uint8_t Kind; // 4 for SYCL
72+
uint8_t Format; // 1 for native
73+
const char *DeviceTargetSpec;
74+
const char *CompileOptions;
75+
const char *LinkOptions;
76+
const unsigned char *BinaryStart;
77+
const unsigned char *BinaryEnd;
78+
_pi_offload_entry EntriesBegin;
79+
_pi_offload_entry EntriesEnd;
80+
pi_device_binary_property_set PropertySetsBegin;
81+
pi_device_binary_property_set PropertySetsEnd;
82+
};
83+
typedef pi_device_binary_struct *pi_device_binary;
84+
85+
struct pi_device_binaries_struct {
86+
uint16_t Version;
87+
uint16_t NumDeviceBinaries;
88+
pi_device_binary DeviceBinaries;
89+
_pi_offload_entry *HostEntriesBegin;
90+
_pi_offload_entry *HostEntriesEnd;
91+
};
92+
typedef pi_device_binaries_struct *pi_device_binaries;
93+
94+
static pi_device_binaries BinDesc = nullptr;
95+
96+
// Wrapper object has code which calls these 2 functions below
97+
extern "C" void __sycl_register_lib(pi_device_binaries desc) {
98+
BinDesc = desc;
99+
}
100+
101+
extern "C" void __sycl_unregister_lib() {}
102+
103+
#define ASSERT(Cond, Msg) \
104+
if (!(Cond)) { \
105+
std::cerr << "*** ERROR: wrong " << Msg << "\n"; \
106+
return 1; \
107+
}
108+
109+
static std::string getString(const unsigned char *B, const unsigned char *E) {
110+
return std::string(reinterpret_cast<const char *>(B), E - B);
111+
}
112+
113+
static int getInt(void *Addr) {
114+
const char *Ptr = reinterpret_cast<const char *>(Addr);
115+
return Ptr[0] | (Ptr[1] << 8) | (Ptr[2] << 16) | (Ptr[3] << 24);
116+
}
117+
118+
using byte = unsigned char;
119+
120+
static void printProp(const pi_device_binary_property &Prop) {
121+
std::cerr << "Property " << Prop->Name << " {\n";
122+
std::cerr << " Type: " << Prop->Type << "\n";
123+
if (Prop->Type != 1)
124+
std::cerr << " Size = " << Prop->ValSize << "\n";
125+
126+
std::cerr << " Value = ";
127+
if (Prop->Type == 1)
128+
std::cerr << getInt(&Prop->ValSize);
129+
else {
130+
std::cerr << " {\n ";
131+
132+
byte *Ptr = (byte *)Prop->ValAddr;
133+
134+
for (auto I = 0; I < Prop->ValSize && I < 100; ++I) {
135+
std::cerr << " 0x" << std::hex << (unsigned int)Ptr[I];
136+
std::cerr << std::dec;
137+
}
138+
std::cerr << "\n }";
139+
}
140+
std::cerr << "\n";
141+
std::cerr << "}\n";
142+
}
143+
144+
static int dumpBinary0() {
145+
pi_device_binary Bin = &BinDesc->DeviceBinaries[0];
146+
ASSERT(Bin->Kind == 4, "Bin->Kind");
147+
ASSERT(Bin->Format == 1, "Bin->Format");
148+
149+
// dump code
150+
std::cout << getString(Bin->BinaryStart, Bin->BinaryEnd);
151+
// dump properties
152+
for (pi_device_binary_property_set PropSet = Bin->PropertySetsBegin; PropSet != Bin->PropertySetsEnd; ++PropSet) {
153+
std::cout << "[" << PropSet->Name << "]"
154+
<< "\n";
155+
156+
for (pi_device_binary_property Prop = PropSet->PropertiesBegin; Prop != PropSet->PropertiesEnd; ++Prop) {
157+
ASSERT(Prop->Type == 1, "Prop->Type");
158+
std::cout << Prop->Name << "=" << Prop->Type << "|" << getInt(&Prop->ValSize) << "\n";
159+
}
160+
}
161+
// dump symbols
162+
for (_pi_offload_entry Entry = Bin->EntriesBegin; Entry != Bin->EntriesEnd; ++Entry)
163+
std::cout << Entry->name << "\n";
164+
return 0;
165+
}
166+
167+
// Clang offload wrapper does Base64 decoding on byte array property values, so
168+
// they can't be dumped as is and compared to the original. Instead, this
169+
// testcase checks that the byte array in the property value is equal to the
170+
// pre-decoded byte array.
171+
static int checkBinary1() {
172+
// Decoded from "IAAAAAAAAAQA":
173+
const byte Arr0[] = {8, 0, 0, 0, 0, 0, 0, 0, 0x1};
174+
// Decoded from "oAAAAAAAAAw///3/wB":
175+
const byte Arr1[] = {40, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0x7F, 0xFF, 0x70};
176+
177+
struct {
178+
const byte *Ptr;
179+
const size_t Size;
180+
} GoldArrays[] = {
181+
{Arr0, sizeof(Arr0)},
182+
{Arr1, sizeof(Arr1)}};
183+
pi_device_binary Bin = &BinDesc->DeviceBinaries[1];
184+
ASSERT(Bin->Kind == 4, "Bin->Kind");
185+
ASSERT(Bin->Format == 1, "Bin->Format");
186+
187+
for (pi_device_binary_property_set PropSet = Bin->PropertySetsBegin; PropSet != Bin->PropertySetsEnd; ++PropSet) {
188+
int Cnt = 0;
189+
190+
for (pi_device_binary_property Prop = PropSet->PropertiesBegin; Prop != PropSet->PropertiesEnd; ++Prop, ++Cnt) {
191+
ASSERT(Prop->Type == 2, "Prop->Type"); // must be a byte array
192+
char *Ptr = reinterpret_cast<char *>(Prop->ValAddr);
193+
int Cmp = std::memcmp(Prop->ValAddr, GoldArrays[Cnt].Ptr, GoldArrays[Cnt].Size);
194+
ASSERT(Cmp == 0, "byte array property");
195+
}
196+
}
197+
return 0;
198+
}
199+
200+
int main(int argc, char **argv) {
201+
ASSERT(BinDesc->NumDeviceBinaries == 2, "BinDesc->NumDeviceBinaries");
202+
ASSERT(BinDesc->Version == 3, "BinDesc->Version");
203+
204+
if (dumpBinary0() != 0)
205+
return 1;
206+
if (checkBinary1() != 0)
207+
return 1;
208+
return 0;
209+
}

clang/test/Driver/clang-offload-wrapper-exe.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// End-to-end clang-offload-wrapper executable test: check that -batch options
44
// works, and that the tool generates data properly accessible at runtime.
55

6+
// PREVIEW_BREAKING_CHANGES: Delete this test when the preview changes are enabled by default.
7+
// Rename clang-offload-wrapper-exe-preview.cpp to clang-offload-wrapper-exe.cpp
8+
69
// --- Prepare test data
710
// - create the first binary image
811
// RUN: echo -e -n 'device binary image1\n' > %t.bin

0 commit comments

Comments
 (0)