Adding support for kernel disasm using IGA

Change-Id: Ic75540c9b42913f5d12d66438cc4e6dcc39ceb98
This commit is contained in:
Chodor, Jaroslaw
2019-06-26 21:19:34 +02:00
committed by sys_ocldev
parent 79e78e18c4
commit 2f42f332d8
21 changed files with 741 additions and 56 deletions

View File

@ -16,6 +16,7 @@ ${IGDRCL_SOURCE_DIR}/offline_compiler/offline_compiler.cpp
set(IGDRCL_SRCS_offline_compiler_mock
${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_decoder.h
${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_encoder.h
${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_iga_wrapper.h
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_compiler.h
)

View File

@ -46,8 +46,6 @@ TEST(DecoderTests, WhenMissingParametersThenValidateInputReturnsErrorCode) {
const char *argv[] = {
"ocloc",
"decoder",
"-file",
"test_files/binary.bin",
"-patch",
"test_files"};
@ -299,5 +297,7 @@ TEST(DecoderTests, GivenValidBinaryWhenProcessingBinaryThenProgramAndKernelAndPa
std::string expectedOutput = "ProgramBinaryHeader:\n\t4 Magic 1229870147\n\t4 Version 0\n\t4 Device 0\n\t4 GPUPointerSizeInBytes 0\n\t4 NumberOfKernels 1\n\t4 SteppingId 0\n\t4 PatchListSize 30\nPATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO:\n\t4 Token 42\n\t4 Size 16\n\t4 ConstantBufferIndex 0\n\t4 InlineDataSize 14\n\tHex 0 1 2 3 4 5 6 7 8 9 a b c d\nKernel #0\nKernelBinaryHeader:\n\t4 CheckSum 4294967295\n\t8 ShaderHashCode 18446744073709551615\n\t4 KernelNameSize 14\n\t4 PatchListSize 12\n\t4 KernelHeapSize 0\n\t4 GeneralStateHeapSize 0\n\t4 DynamicStateHeapSize 0\n\t4 SurfaceStateHeapSize 0\n\t4 KernelUnpaddedSize 0\n\tKernelName ExampleKernel\nPATCH_TOKEN_MEDIA_INTERFACE_DESCRIPTOR_LOAD:\n\t4 Token 19\n\t4 Size 12\n\t4 InterfaceDescriptorDataOffset 0\n";
EXPECT_EQ(expectedOutput, ptmFile.str());
EXPECT_TRUE(decoder.getMockIga()->disasmWasCalled);
EXPECT_FALSE(decoder.getMockIga()->asmWasCalled);
}
} // namespace NEO

View File

@ -239,14 +239,14 @@ TEST(EncoderTests, WhenProcessingDeviceBinaryThenProperChecksumIsCalculated) {
MockEncoder encoder;
std::string kernelName = "kernel";
encoder.filesMap["kernel_DynamicStateHeap.bin"] = std::string(16, 2);
encoder.filesMap["kernel_KernelHeap.bin"] = std::string(16, 4);
encoder.filesMap["kernel_KernelHeap.dat"] = std::string(16, 4);
encoder.filesMap["kernel_SurfaceStateHeap.bin"] = std::string(16, 8);
std::stringstream kernelBlob;
kernelBlob << kernelName;
kernelBlob.write(encoder.filesMap["kernel_KernelHeap.bin"].data(), encoder.filesMap["kernel_KernelHeap.bin"].size());
kernelBlob.write(encoder.filesMap["kernel_KernelHeap.dat"].data(), encoder.filesMap["kernel_KernelHeap.dat"].size());
encoder.addPadding(kernelBlob, 128); // isa prefetch padding
encoder.addPadding(kernelBlob, 64 - (encoder.filesMap["kernel_KernelHeap.bin"].size() + 128) % 64); // isa alignment
size_t kernelHeapSize = encoder.filesMap["kernel_KernelHeap.bin"].size();
encoder.addPadding(kernelBlob, 64 - (encoder.filesMap["kernel_KernelHeap.dat"].size() + 128) % 64); // isa alignment
size_t kernelHeapSize = encoder.filesMap["kernel_KernelHeap.dat"].size();
kernelHeapSize = alignUp(kernelHeapSize + 128, 64);
kernelBlob.write(encoder.filesMap["kernel_DynamicStateHeap.bin"].data(), encoder.filesMap["kernel_DynamicStateHeap.bin"].size());
kernelBlob.write(encoder.filesMap["kernel_SurfaceStateHeap.bin"].data(), encoder.filesMap["kernel_SurfaceStateHeap.bin"].size());
@ -295,9 +295,10 @@ TEST(EncoderTests, WhenProcessingDeviceBinaryThenProperChecksumIsCalculated) {
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 16;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = static_cast<uint32_t>(encoder.filesMap["kernel_KernelHeap.bin"].size());
byte4 = static_cast<uint32_t>(encoder.filesMap["kernel_KernelHeap.dat"].size());
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
expectedBinary.write(kernelName.c_str(), kernelName.length());
expectedBinary.write(encoder.filesMap["kernel_KernelHeap.dat"].data(), encoder.filesMap["kernel_KernelHeap.dat"].size());
std::vector<std::string> ptmFile;
ptmFile.push_back("ProgramBinaryHeader:");
@ -316,7 +317,7 @@ TEST(EncoderTests, WhenProcessingDeviceBinaryThenProperChecksumIsCalculated) {
ptmFile.push_back("\tHex 48 65");
ptmFile.push_back("Kernel #0");
ptmFile.push_back("KernelBinaryHeader:");
ptmFile.push_back("\t4 CheckSum " + std::to_string(checksum));
ptmFile.push_back("\t4 CheckSum 0");
ptmFile.push_back("\t8 ShaderHashCode 4988534869940066475");
ptmFile.push_back("\t4 KernelNameSize " + std::to_string(kernelName.size()));
ptmFile.push_back("\t4 PatchListSize 0");
@ -333,6 +334,119 @@ TEST(EncoderTests, WhenProcessingDeviceBinaryThenProperChecksumIsCalculated) {
auto expectedBinaryAsString = expectedBinary.str();
resultAsString.resize(expectedBinaryAsString.size()); // don't test beyond kernel header
EXPECT_EQ(expectedBinaryAsString, resultAsString);
EXPECT_FALSE(encoder.getMockIga()->disasmWasCalled);
EXPECT_FALSE(encoder.getMockIga()->asmWasCalled);
}
TEST(EncoderTests, WhenProcessingDeviceBinaryAndAsmIsAvailableThenAseembleItWithIga) {
std::stringstream expectedBinary;
uint8_t byte;
uint32_t byte4;
uint64_t byte8;
MockEncoder encoder;
encoder.getMockIga()->binaryToReturn = std::string(32, 13);
std::string kernelName = "kernel";
encoder.filesMap["kernel_DynamicStateHeap.bin"] = std::string(16, 2);
encoder.filesMap["kernel_KernelHeap.dat"] = std::string(16, 4);
encoder.filesMap["kernel_KernelHeap.asm"] = std::string(16, 7);
encoder.filesMap["kernel_SurfaceStateHeap.bin"] = std::string(16, 8);
std::stringstream kernelBlob;
kernelBlob << kernelName;
kernelBlob.write(encoder.getMockIga()->binaryToReturn.c_str(), encoder.getMockIga()->binaryToReturn.size());
encoder.addPadding(kernelBlob, 128); // isa prefetch padding
encoder.addPadding(kernelBlob, 64 - (encoder.getMockIga()->binaryToReturn.size() + 128) % 64); // isa alignment
size_t kernelHeapSize = encoder.getMockIga()->binaryToReturn.size();
kernelHeapSize = alignUp(kernelHeapSize + 128, 64);
kernelBlob.write(encoder.filesMap["kernel_DynamicStateHeap.bin"].data(), encoder.filesMap["kernel_DynamicStateHeap.bin"].size());
kernelBlob.write(encoder.filesMap["kernel_SurfaceStateHeap.bin"].data(), encoder.filesMap["kernel_SurfaceStateHeap.bin"].size());
auto kernelBlobData = kernelBlob.str();
uint64_t hashValue = NEO::Hash::hash(reinterpret_cast<const char *>(kernelBlobData.data()), kernelBlobData.size());
uint32_t checksum = hashValue & 0xFFFFFFFF;
byte4 = 1229870147;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 1042;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 12;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 4;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 1;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 2;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 18;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 42;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 16;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 0;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 2;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte = 0x48;
expectedBinary.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
byte = 0x65;
expectedBinary.write(reinterpret_cast<char *>(&byte), sizeof(uint8_t));
byte4 = checksum;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte8 = 4988534869940066475;
expectedBinary.write(reinterpret_cast<char *>(&byte8), sizeof(uint64_t));
byte4 = static_cast<uint32_t>(kernelName.size());
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 0;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = static_cast<uint32_t>(kernelHeapSize);
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = 0;
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = static_cast<uint32_t>(16);
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
byte4 = static_cast<uint32_t>(encoder.getMockIga()->binaryToReturn.size());
expectedBinary.write(reinterpret_cast<char *>(&byte4), sizeof(uint32_t));
expectedBinary.write(kernelName.c_str(), kernelName.length());
expectedBinary.write(encoder.getMockIga()->binaryToReturn.data(), encoder.getMockIga()->binaryToReturn.size());
std::vector<std::string> ptmFile;
ptmFile.push_back("ProgramBinaryHeader:");
ptmFile.push_back("\t4 Magic 1229870147");
ptmFile.push_back("\t4 Version 1042");
ptmFile.push_back("\t4 Device 12");
ptmFile.push_back("\t4 GPUPointerSizeInBytes 4");
ptmFile.push_back("\t4 NumberOfKernels 1");
ptmFile.push_back("\t4 SteppingId 2");
ptmFile.push_back("\t4 PatchListSize 18");
ptmFile.push_back("PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO:");
ptmFile.push_back("\t4 Token 42");
ptmFile.push_back("\t4 Size 16");
ptmFile.push_back("\t4 ConstantBufferIndex 0");
ptmFile.push_back("\t4 InlineDataSize 2");
ptmFile.push_back("\tHex 48 65");
ptmFile.push_back("Kernel #0");
ptmFile.push_back("KernelBinaryHeader:");
ptmFile.push_back("\t4 CheckSum 0");
ptmFile.push_back("\t8 ShaderHashCode 4988534869940066475");
ptmFile.push_back("\t4 KernelNameSize " + std::to_string(kernelName.size()));
ptmFile.push_back("\t4 PatchListSize 0");
ptmFile.push_back("\t4 KernelHeapSize 16");
ptmFile.push_back("\t4 GeneralStateHeapSize 0");
ptmFile.push_back("\t4 DynamicStateHeapSize 16");
ptmFile.push_back("\t4 KernelUnpaddedSize 16");
ptmFile.push_back("\tKernelName " + kernelName);
std::stringstream result;
auto ret = encoder.processBinary(ptmFile, result);
auto resultAsString = result.str();
EXPECT_EQ(0, ret);
auto expectedBinaryAsString = expectedBinary.str();
resultAsString.resize(expectedBinaryAsString.size()); // don't test beyond kernel header
EXPECT_EQ(expectedBinaryAsString, resultAsString);
EXPECT_FALSE(encoder.getMockIga()->disasmWasCalled);
EXPECT_TRUE(encoder.getMockIga()->asmWasCalled);
EXPECT_EQ(encoder.filesMap["kernel_KernelHeap.asm"], encoder.getMockIga()->receivedAsm);
}
} // namespace NEO

View File

@ -8,15 +8,20 @@
#pragma once
#include "offline_compiler/decoder/binary_decoder.h"
#include "mock_iga_wrapper.h"
struct MockDecoder : public BinaryDecoder {
MockDecoder() : MockDecoder("", "", ""){};
MockDecoder() : MockDecoder("", "", "") {
}
MockDecoder(const std::string &file, const std::string &patch, const std::string &dump)
: BinaryDecoder(file, patch, dump) {
this->iga.reset(new MockIgaWrapper);
setMessagePrinter(MessagePrinter{true});
};
using BinaryDecoder::binaryFile;
using BinaryDecoder::decode;
using BinaryDecoder::getSize;
using BinaryDecoder::iga;
using BinaryDecoder::kernelHeader;
using BinaryDecoder::parseTokens;
using BinaryDecoder::patchTokens;
@ -27,4 +32,8 @@ struct MockDecoder : public BinaryDecoder {
using BinaryDecoder::programHeader;
using BinaryDecoder::readPatchTokens;
using BinaryDecoder::readStructFields;
MockIgaWrapper *getMockIga() const {
return static_cast<MockIgaWrapper *>(iga.get());
}
};

View File

@ -9,6 +9,8 @@
#include "offline_compiler/decoder/binary_encoder.h"
#include "runtime/helpers/hash.h"
#include "mock_iga_wrapper.h"
#include <map>
#include <string>
@ -16,6 +18,7 @@ struct MockEncoder : public BinaryEncoder {
MockEncoder() : MockEncoder("", ""){};
MockEncoder(const std::string &dump, const std::string &elf)
: BinaryEncoder(dump, elf) {
this->iga.reset(new MockIgaWrapper);
setMessagePrinter(MessagePrinter{true});
};
@ -31,17 +34,31 @@ struct MockEncoder : public BinaryEncoder {
return true;
}
bool fileExists(const std::string &path) const override {
return filesMap.count(path) || BinaryEncoder::fileExists(path);
}
std::vector<char> readBinaryFile(const std::string &path) const override {
return filesMap.count(path) ? std::vector<char>(filesMap.at(path).c_str(), filesMap.at(path).c_str() + filesMap.at(path).size())
: BinaryEncoder::readBinaryFile(path);
}
using BinaryEncoder::addPadding;
using BinaryEncoder::calculatePatchListSizes;
using BinaryEncoder::copyBinaryToBinary;
using BinaryEncoder::createElf;
using BinaryEncoder::elfName;
using BinaryEncoder::encode;
using BinaryEncoder::iga;
using BinaryEncoder::pathToDump;
using BinaryEncoder::processBinary;
using BinaryEncoder::processKernel;
using BinaryEncoder::write;
using BinaryEncoder::writeDeviceBinary;
MockIgaWrapper *getMockIga() const {
return static_cast<MockIgaWrapper *>(iga.get());
}
std::map<std::string, std::string> filesMap;
};

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2018-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "offline_compiler/decoder/iga_wrapper.h"
#include <map>
#include <string>
struct MockIgaWrapper : public IgaWrapper {
bool tryDisassembleGenISA(const void *kernelPtr, uint32_t kernelSize, std::string &out) override {
out = asmToReturn;
disasmWasCalled = true;
receivedBinary.assign(reinterpret_cast<const char *>(kernelPtr), kernelSize);
return asmToReturn.size() != 0;
}
bool tryAssembleGenISA(const std::string &inAsm, std::string &outBinary) override {
outBinary = binaryToReturn;
asmWasCalled = true;
receivedAsm = inAsm;
return outBinary.size() != 0;
}
void setGfxCore(GFXCORE_FAMILY core) override {
}
void setProductFamily(PRODUCT_FAMILY product) override {
}
bool isKnownPlatform() const override {
return false;
}
bool tryLoadIga() override {
return true;
}
std::string asmToReturn;
std::string binaryToReturn;
std::string receivedAsm;
std::string receivedBinary;
bool disasmWasCalled = false;
bool asmWasCalled = false;
};