Skip to content

Commit 2e5ef30

Browse files
jchodorCompute-Runtime-Automation
authored andcommitted
ocloc - checksum recalculation during reassembly
Resolves: NEO-2696 Change-Id: I2c049ac511e437679df9b58d00e4fb8d995bbe3e
1 parent 0fa5cee commit 2e5ef30

File tree

5 files changed

+238
-70
lines changed

5 files changed

+238
-70
lines changed

offline_compiler/decoder/binary_decoder.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,6 @@ int BinaryDecoder::processBinary(void *&ptr, std::ostream &ptmFile) {
257257
}
258258
dumpField(ptr, v, ptmFile);
259259
}
260-
if (patchListSize == 0) {
261-
messagePrinter.printf("Warning! Program's patch list size is 0.\n");
262-
}
263260
if (numberOfKernels == 0) {
264261
messagePrinter.printf("Warning! Number of Kernels is 0.\n");
265262
}

offline_compiler/decoder/binary_encoder.cpp

Lines changed: 96 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
#include "binary_encoder.h"
99

1010
#include "elf/writer.h"
11+
#include "runtime/helpers/aligned_memory.h"
1112
#include "runtime/helpers/file_io.h"
13+
#include "runtime/helpers/hash.h"
1214

1315
#include "CL/cl.h"
1416
#include "helper.h"
1517

1618
#include <algorithm>
1719
#include <cstring>
1820
#include <fstream>
21+
#include <sstream>
1922

2023
void BinaryEncoder::setMessagePrinter(const MessagePrinter &messagePrinter) {
2124
this->messagePrinter = messagePrinter;
@@ -49,19 +52,24 @@ void BinaryEncoder::calculatePatchListSizes(std::vector<std::string> &ptmFile) {
4952
}
5053
}
5154

52-
int BinaryEncoder::copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary) {
55+
bool BinaryEncoder::copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary, uint32_t *binaryLength) {
5356
std::ifstream ifs(srcFileName, std::ios::binary);
5457
if (!ifs.good()) {
5558
messagePrinter.printf("Cannot open %s.\n", srcFileName.c_str());
56-
return -1;
59+
return false;
5760
}
5861
ifs.seekg(0, ifs.end);
5962
auto length = static_cast<size_t>(ifs.tellg());
6063
ifs.seekg(0, ifs.beg);
6164
std::vector<char> binary(length);
6265
ifs.read(binary.data(), length);
6366
outBinary.write(binary.data(), length);
64-
return 0;
67+
68+
if (binaryLength) {
69+
*binaryLength = static_cast<uint32_t>(length);
70+
}
71+
72+
return true;
6573
}
6674

6775
int BinaryEncoder::createElf() {
@@ -169,56 +177,103 @@ int BinaryEncoder::processBinary(const std::vector<std::string> &ptmFile, std::o
169177
return 0;
170178
}
171179

172-
int BinaryEncoder::processKernel(size_t &i, const std::vector<std::string> &ptmFile, std::ostream &deviceBinary) {
173-
uint32_t kernelNameSize = 0;
174-
while (i < ptmFile.size()) {
175-
if (ptmFile[i].find("KernelName ") != std::string::npos) {
176-
break;
177-
} else if (ptmFile[i].find("KernelNameSize") != std::string::npos) {
178-
std::stringstream ss(ptmFile[i]);
180+
void BinaryEncoder::addPadding(std::ostream &out, size_t numBytes) {
181+
for (size_t i = 0; i < numBytes; ++i) {
182+
const char nullByte = 0;
183+
out.write(&nullByte, 1U);
184+
}
185+
}
186+
187+
int BinaryEncoder::processKernel(size_t &line, const std::vector<std::string> &ptmFileLines, std::ostream &deviceBinary) {
188+
auto kernelInfoBeginMarker = line;
189+
auto kernelInfoEndMarker = ptmFileLines.size();
190+
auto kernelNameMarker = ptmFileLines.size();
191+
auto kernelPatchtokensMarker = ptmFileLines.size();
192+
std::stringstream kernelBlob;
193+
194+
// Normally these are added by the compiler, need to take or of them when reassembling
195+
constexpr size_t isaPaddingSizeInBytes = 128;
196+
constexpr uint32_t kernelHeapAlignmentInBytes = 64;
197+
198+
uint32_t kernelNameSizeInBinary = 0;
199+
std::string kernelName;
200+
201+
// Scan PTM lines for kernel info
202+
while (line < ptmFileLines.size()) {
203+
if (ptmFileLines[line].find("KernelName ") != std::string::npos) {
204+
kernelName = std::string(ptmFileLines[line], ptmFileLines[line].find(' ') + 1);
205+
kernelNameMarker = line;
206+
kernelPatchtokensMarker = kernelNameMarker + 1; // patchtokens come after name
207+
} else if (ptmFileLines[line].find("KernelNameSize") != std::string::npos) {
208+
std::stringstream ss(ptmFileLines[line]);
179209
ss.ignore(32, ' ');
180210
ss.ignore(32, ' ');
181-
ss >> kernelNameSize;
182-
}
183-
if (writeDeviceBinary(ptmFile[i++], deviceBinary)) {
184-
messagePrinter.printf("Error while writing to binary.\n");
185-
return -1;
211+
ss >> kernelNameSizeInBinary;
212+
} else if (ptmFileLines[line].find("Kernel #") != std::string::npos) {
213+
kernelInfoEndMarker = line;
214+
break;
186215
}
216+
++line;
187217
}
188-
//KernelName
189-
if (i == ptmFile.size()) {
190-
messagePrinter.printf("Couldn't find KernelName line.\n");
191-
return -1;
192-
}
193-
std::string kernelName(ptmFile[i], ptmFile[i].find(' ') + 1);
194-
i++;
195218

196-
deviceBinary.write(kernelName.c_str(), kernelName.size());
197-
for (auto j = kernelName.size(); j < kernelNameSize; ++j) {
198-
uint8_t nullByte = 0;
199-
deviceBinary.write(reinterpret_cast<const char *>(&nullByte), sizeof(uint8_t));
200-
}
219+
// Write KernelName and padding
220+
kernelBlob.write(kernelName.c_str(), kernelName.size());
221+
addPadding(kernelBlob, kernelNameSizeInBinary - kernelName.size());
222+
223+
// Write KernelHeap and padding
224+
uint32_t kernelSizeUnpadded = 0U;
225+
bool heapsCopiedSuccesfully = copyBinaryToBinary(pathToDump + kernelName + "_KernelHeap.bin", kernelBlob, &kernelSizeUnpadded);
226+
227+
// Adding padding and alignment
228+
addPadding(kernelBlob, isaPaddingSizeInBytes);
229+
const uint32_t kernelHeapPaddedSize = kernelSizeUnpadded + isaPaddingSizeInBytes;
230+
const uint32_t kernelHeapAlignedSize = alignUp(kernelHeapPaddedSize, kernelHeapAlignmentInBytes);
231+
addPadding(kernelBlob, kernelHeapAlignedSize - kernelHeapPaddedSize);
201232

202-
// Writing KernelHeap, DynamicStateHeap, SurfaceStateHeap
233+
// Write GeneralStateHeap, DynamicStateHeap, SurfaceStateHeap
203234
if (fileExists(pathToDump + kernelName + "_GeneralStateHeap.bin")) {
204-
messagePrinter.printf("Warning! Adding GeneralStateHeap.\n");
205-
if (copyBinaryToBinary(pathToDump + kernelName + "_GeneralStateHeap.bin", deviceBinary)) {
206-
messagePrinter.printf("Couldn't copy %s_GeneralStateHeap.bin\n", kernelName.c_str());
207-
return -1;
208-
}
235+
heapsCopiedSuccesfully = heapsCopiedSuccesfully && copyBinaryToBinary(pathToDump + kernelName + "_GeneralStateHeap.bin", kernelBlob);
209236
}
210-
if (copyBinaryToBinary(pathToDump + kernelName + "_KernelHeap.bin", deviceBinary)) {
211-
messagePrinter.printf("Couldn't copy %s_KernelHeap.bin\n", kernelName.c_str());
237+
heapsCopiedSuccesfully = heapsCopiedSuccesfully && copyBinaryToBinary(pathToDump + kernelName + "_DynamicStateHeap.bin", kernelBlob);
238+
heapsCopiedSuccesfully = heapsCopiedSuccesfully && copyBinaryToBinary(pathToDump + kernelName + "_SurfaceStateHeap.bin", kernelBlob);
239+
if (false == heapsCopiedSuccesfully) {
212240
return -1;
213241
}
214-
if (copyBinaryToBinary(pathToDump + kernelName + "_DynamicStateHeap.bin", deviceBinary)) {
215-
messagePrinter.printf("Couldn't copy %s_DynamicStateHeap.bin\n", kernelName.c_str());
216-
return -1;
242+
243+
// Write kernel patchtokens
244+
for (size_t i = kernelPatchtokensMarker; i < kernelInfoEndMarker; ++i) {
245+
if (writeDeviceBinary(ptmFileLines[i], kernelBlob)) {
246+
messagePrinter.printf("Error while writing to binary.\n");
247+
return -1;
248+
}
217249
}
218-
if (copyBinaryToBinary(pathToDump + kernelName + "_SurfaceStateHeap.bin", deviceBinary)) {
219-
messagePrinter.printf("Couldn't copy %s_SurfaceStateHeap.bin\n", kernelName.c_str());
220-
return -1;
250+
251+
auto kernelBlobData = kernelBlob.str();
252+
uint64_t hashValue = NEO::Hash::hash(reinterpret_cast<const char *>(kernelBlobData.data()), kernelBlobData.size());
253+
uint32_t calcCheckSum = hashValue & 0xFFFFFFFF;
254+
255+
// Add kernel header
256+
for (size_t i = kernelInfoBeginMarker; i < kernelNameMarker; ++i) {
257+
if (ptmFileLines[i].find("CheckSum") != std::string::npos) {
258+
static_assert(std::is_same<decltype(calcCheckSum), uint32_t>::value, "");
259+
deviceBinary.write(reinterpret_cast<char *>(&calcCheckSum), sizeof(uint32_t));
260+
} else if (ptmFileLines[i].find("KernelHeapSize") != std::string::npos) {
261+
static_assert(sizeof(kernelHeapAlignedSize) == sizeof(uint32_t), "");
262+
deviceBinary.write(reinterpret_cast<const char *>(&kernelHeapAlignedSize), sizeof(uint32_t));
263+
} else if (ptmFileLines[i].find("KernelUnpaddedSize") != std::string::npos) {
264+
static_assert(sizeof(kernelSizeUnpadded) == sizeof(uint32_t), "");
265+
deviceBinary.write(reinterpret_cast<char *>(&kernelSizeUnpadded), sizeof(uint32_t));
266+
} else {
267+
if (writeDeviceBinary(ptmFileLines[i], deviceBinary)) {
268+
messagePrinter.printf("Error while writing to binary.\n");
269+
return -1;
270+
}
271+
}
221272
}
273+
274+
// Add kernel blob after the header
275+
deviceBinary.write(kernelBlobData.c_str(), kernelBlobData.size());
276+
222277
return 0;
223278
}
224279

offline_compiler/decoder/binary_encoder.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ class BinaryEncoder {
2727
MessagePrinter messagePrinter;
2828

2929
void calculatePatchListSizes(std::vector<std::string> &ptmFile);
30-
int copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary);
30+
MOCKABLE_VIRTUAL bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary, uint32_t *binaryLength);
31+
bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary) {
32+
return copyBinaryToBinary(srcFileName, outBinary, nullptr);
33+
}
3134
int createElf();
3235
void printHelp();
3336
int processBinary(const std::vector<std::string> &ptmFile, std::ostream &deviceBinary);
34-
int processKernel(size_t &i, const std::vector<std::string> &ptmFile, std::ostream &deviceBinary);
37+
int processKernel(size_t &i, const std::vector<std::string> &ptmFileLines, std::ostream &deviceBinary);
3538
template <typename T>
3639
void write(std::stringstream &in, std::ostream &deviceBinary);
3740
int writeDeviceBinary(const std::string &line, std::ostream &deviceBinary);
41+
void addPadding(std::ostream &out, size_t numBytes);
3842
};

0 commit comments

Comments
 (0)