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

@ -292,6 +292,46 @@ else()
message(STATUS "IGC targets: ${IGDRCL__IGC_TARGETS}")
endif()
# VISA headers - always relative to IGC
if(IS_DIRECTORY "${IGC_DIR}/../visa")
get_filename_component(VISA_DIR "${IGC_DIR}/../visa" ABSOLUTE)
elseif(IS_DIRECTORY "${IGC_DIR}/visa")
set(VISA_DIR "${IGC_DIR}/visa")
elseif(IS_DIRECTORY "${IGC_DIR}/include/visa")
set(VISA_DIR "${IGC_DIR}/include/visa")
elseif(IS_DIRECTORY "${IGDRCL__IGC_INCLUDEDIR}/../visa")
get_filename_component(VISA_DIR "${IGDRCL__IGC_INCLUDEDIR}/../visa" ABSOLUTE)
endif()
message("VISA_DIR : ${VISA_DIR}")
if(IS_DIRECTORY "${VISA_DIR}/include")
set(VISA_INCLUDE_DIR "${VISA_DIR}/include")
else()
set(VISA_INCLUDE_DIR "${VISA_DIR}")
endif()
# IGA headers - always relative to VISA
if(IS_DIRECTORY "${VISA_DIR}/../iga")
get_filename_component(IGA_DIR "${VISA_DIR}/../iga" ABSOLUTE)
elseif(IS_DIRECTORY "${VISA_DIR}/iga")
set(IGA_DIR "${VISA_DIR}/iga")
endif()
if(IS_DIRECTORY "${IGA_DIR}/IGALibrary/api")
set(IGA_INCLUDE_DIR "${IGA_DIR}/IGALibrary/api")
else()
set(IGA_INCLUDE_DIR "${IGA_DIR}")
endif()
if(IS_DIRECTORY ${IGA_INCLUDE_DIR})
set(IGA_HEADERS_AVAILABLE TRUE)
set(IGA_LIBRARY_NAME "iga${NEO_BITS}")
else()
set(IGA_HEADERS_AVAILABLE FALSE)
endif()
message("IGA_INCLUDE_DIR : ${IGA_INCLUDE_DIR}")
if(WIN32)
set(IGC_LIBRARY_NAME "igc${NEO_BITS}")
set(FCL_LIBRARY_NAME "igdfcl${NEO_BITS}")

View File

@ -7,27 +7,40 @@
project(ocloc)
set(CLOC_SRCS_LIB
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_decoder.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_decoder.h
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_encoder.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_encoder.h
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/helper.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/helper.h
${IGDRCL_SOURCE_DIR}/offline_compiler/helper.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/offline_compiler.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/offline_compiler.h
${IGDRCL_SOURCE_DIR}/offline_compiler/multi_command.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/multi_command.h
${IGDRCL_SOURCE_DIR}/offline_compiler/options.cpp
${IGDRCL_SOURCE_DIR}/runtime/compiler_interface/create_main.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/abort.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/debug_helpers.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/file_io.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/hw_info.cpp
${IGDRCL_SOURCE_DIR}/runtime/platform/extensions.cpp
${IGDRCL_SOURCE_DIR}/runtime/platform/extensions.h
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_decoder.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_decoder.h
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_encoder.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_encoder.h
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/helper.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/helper.h
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/iga_wrapper.h
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/translate_platform_base.h
${IGDRCL_SOURCE_DIR}/offline_compiler/helper.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/offline_compiler.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/offline_compiler.h
${IGDRCL_SOURCE_DIR}/offline_compiler/multi_command.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/multi_command.h
${IGDRCL_SOURCE_DIR}/offline_compiler/options.cpp
${IGDRCL_SOURCE_DIR}/runtime/compiler_interface/create_main.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/abort.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/debug_helpers.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/file_io.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/hw_info.cpp
${IGDRCL_SOURCE_DIR}/runtime/platform/extensions.cpp
${IGDRCL_SOURCE_DIR}/runtime/platform/extensions.h
)
if(${IGA_HEADERS_AVAILABLE})
set(CLOC_SRCS_LIB ${CLOC_SRCS_LIB}
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/iga_wrapper.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder${BRANCH_DIR_SUFFIX}/translate_platform.cpp
)
else()
set(CLOC_SRCS_LIB ${CLOC_SRCS_LIB}
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/iga_stubs.cpp
)
endif()
if(WIN32)
list(APPEND CLOC_SRCS_LIB
${IGDRCL_SOURCE_DIR}/runtime/os_interface/windows/os_library.cpp
@ -96,8 +109,10 @@ set(CLOC_INCLUDES
)
target_include_directories(ocloc BEFORE PRIVATE ${CLOC_INCLUDES})
target_include_directories(ocloc BEFORE PRIVATE ${IGA_INCLUDE_DIR})
target_compile_definitions(ocloc PUBLIC ${CLOC_LIB_FLAGS_DEFINITIONS} ${SUPPORTED_GEN_FLAGS_DEFINITONS} DEFAULT_PLATFORM=${DEFAULT_SUPPORTED_PLATFORM})
target_compile_definitions(ocloc PUBLIC ${CLOC_LIB_FLAGS_DEFINITIONS} ${SUPPORTED_GEN_FLAGS_DEFINITONS} DEFAULT_PLATFORM=${DEFAULT_SUPPORTED_PLATFORM}
IGA_LIBRARY_NAME=${CMAKE_SHARED_LIBRARY_PREFIX}${IGA_LIBRARY_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
if(MSVC)
target_link_libraries(ocloc dbghelp)

View File

@ -9,6 +9,7 @@
#include "core/helpers/ptr_math.h"
#include "elf/reader.h"
#include "offline_compiler/offline_compiler.h"
#include "runtime/helpers/file_io.h"
#include "helper.h"
@ -242,18 +243,22 @@ void BinaryDecoder::parseTokens() {
}
void BinaryDecoder::printHelp() {
messagePrinter.printf("Usage:\n-file <Opencl elf binary file> -patch <path to folder containing patchlist> -dump <path to dumping folder>\n");
messagePrinter.printf("Usage:\n-file <Opencl elf binary file> -patch <path to folder containing patchlist> -dump <path to dumping folder> -device <device_type>\n");
messagePrinter.printf("e.g. -file C:/my_folder/my_binary.bin -patch C:/igc/inc -dump C:/my_folder/dump\n");
messagePrinter.printf(" -device <device_type> Indicates which device for which we will compile.\n");
messagePrinter.printf(" <device_type> can be: %s\n", NEO::getDevicesTypes().c_str());
}
int BinaryDecoder::processBinary(void *&ptr, std::ostream &ptmFile) {
ptmFile << "ProgramBinaryHeader:\n";
uint32_t numberOfKernels = 0, patchListSize = 0;
uint32_t numberOfKernels = 0, patchListSize = 0, device = 0;
for (const auto &v : programHeader.fields) {
if (v.name == "NumberOfKernels") {
numberOfKernels = readUnaligned<uint32_t>(ptr);
} else if (v.name == "PatchListSize") {
patchListSize = readUnaligned<uint32_t>(ptr);
} else if (v.name == "Device") {
device = readUnaligned<uint32_t>(ptr);
}
dumpField(ptr, v, ptmFile);
}
@ -262,6 +267,7 @@ int BinaryDecoder::processBinary(void *&ptr, std::ostream &ptmFile) {
}
readPatchTokens(ptr, patchListSize, ptmFile);
iga->setGfxCore(static_cast<GFXCORE_FAMILY>(device));
//Reading Kernels
for (uint32_t i = 0; i < numberOfKernels; ++i) {
@ -272,7 +278,7 @@ int BinaryDecoder::processBinary(void *&ptr, std::ostream &ptmFile) {
}
void BinaryDecoder::processKernel(void *&ptr, std::ostream &ptmFile) {
uint32_t KernelNameSize = 0, KernelPatchListSize = 0, KernelHeapSize = 0,
uint32_t KernelNameSize = 0, KernelPatchListSize = 0, KernelHeapSize = 0, KernelUnpaddedSize = 0,
GeneralStateHeapSize = 0, DynamicStateHeapSize = 0, SurfaceStateHeapSize = 0;
ptmFile << "KernelBinaryHeader:\n";
for (const auto &v : kernelHeader.fields) {
@ -282,6 +288,8 @@ void BinaryDecoder::processKernel(void *&ptr, std::ostream &ptmFile) {
KernelNameSize = readUnaligned<uint32_t>(ptr);
else if (v.name == "KernelHeapSize")
KernelHeapSize = readUnaligned<uint32_t>(ptr);
else if (v.name == "KernelUnpaddedSize")
KernelUnpaddedSize = readUnaligned<uint32_t>(ptr);
else if (v.name == "GeneralStateHeapSize")
GeneralStateHeapSize = readUnaligned<uint32_t>(ptr);
else if (v.name == "DynamicStateHeapSize")
@ -302,8 +310,14 @@ void BinaryDecoder::processKernel(void *&ptr, std::ostream &ptmFile) {
ptmFile << kernelName << '\n';
ptr = ptrOffset(ptr, KernelNameSize);
std::string fileName = pathToDump + kernelName + "_KernelHeap.bin";
writeDataToFile(fileName.c_str(), ptr, KernelHeapSize);
std::string fileName = pathToDump + kernelName + "_KernelHeap";
messagePrinter.printf("Trying to disassemble %s.krn\n", kernelName.c_str());
std::string disassembledKernel;
if (iga->tryDisassembleGenISA(ptr, KernelUnpaddedSize, disassembledKernel)) {
writeDataToFile((fileName + ".asm").c_str(), disassembledKernel.data(), disassembledKernel.size());
} else {
writeDataToFile((fileName + ".dat").c_str(), ptr, KernelHeapSize);
}
ptr = ptrOffset(ptr, KernelHeapSize);
if (GeneralStateHeapSize != 0) {
@ -411,6 +425,8 @@ int BinaryDecoder::validateInput(uint32_t argc, const char **argv) {
for (uint32_t i = 2; i < argc - 1; ++i) {
if (!strcmp(argv[i], "-file")) {
binaryFile = std::string(argv[++i]);
} else if (!strcmp(argv[i], "-device")) {
iga->setProductFamily(getProductFamilyFromDeviceName(argv[++i]));
} else if (!strcmp(argv[i], "-patch")) {
pathToPatch = std::string(argv[++i]);
addSlash(pathToPatch);
@ -427,10 +443,15 @@ int BinaryDecoder::validateInput(uint32_t argc, const char **argv) {
messagePrinter.printf(".bin extension is expected for binary file.\n");
printHelp();
return -1;
} else if (pathToDump.empty()) {
messagePrinter.printf("Path to dump folder can't be empty.\n");
printHelp();
return -1;
}
if (pathToDump.empty()) {
messagePrinter.printf("Warning : Path to dump folder not specificed - using ./dump as default.\n");
pathToDump = "dump";
addSlash(pathToDump);
}
if (false == iga->isKnownPlatform()) {
messagePrinter.printf("Warning : missing or invalid -device parameter - results may be inacurate\n");
}
}
return 0;

View File

@ -9,6 +9,7 @@
#include "elf/types.h"
#include "helper.h"
#include "iga_wrapper.h"
#include <memory>
#include <string>
@ -21,7 +22,7 @@ struct PTField {
};
struct BinaryHeader {
std::vector<PTField> fields; // (size, name)
std::vector<PTField> fields;
uint32_t size;
};
struct PatchToken : BinaryHeader {
@ -32,7 +33,9 @@ using PTMap = std::unordered_map<uint8_t, std::unique_ptr<PatchToken>>;
class BinaryDecoder {
public:
BinaryDecoder() = default;
BinaryDecoder() : iga(new IgaWrapper) {
iga->setMessagePrinter(messagePrinter);
}
BinaryDecoder(const std::string &file, const std::string &patch, const std::string &dump)
: binaryFile(file), pathToPatch(patch), pathToDump(dump){};
int decode();
@ -43,6 +46,7 @@ class BinaryDecoder {
protected:
BinaryHeader programHeader, kernelHeader;
CLElfLib::ElfBinaryStorage binary;
std::unique_ptr<IgaWrapper> iga;
PTMap patchTokens;
std::string binaryFile, pathToPatch, pathToDump;
MessagePrinter messagePrinter;

View File

@ -8,6 +8,7 @@
#include "binary_encoder.h"
#include "elf/writer.h"
#include "offline_compiler/offline_compiler.h"
#include "runtime/helpers/aligned_memory.h"
#include "runtime/helpers/file_io.h"
#include "runtime/helpers/hash.h"
@ -138,8 +139,10 @@ int BinaryEncoder::createElf() {
}
void BinaryEncoder::printHelp() {
messagePrinter.printf("Usage:\n-dump <path to dumping folder> -out <new elf file>\n");
messagePrinter.printf("Usage:\n-dump <path to dumping folder> -out <new elf file> -device <device_type>\n");
messagePrinter.printf("e.g. -dump C:/my_folder/dump -out C:/my_folder/new_binary.bin\n");
messagePrinter.printf(" -device <device_type> Indicates which device for which we will compile.\n");
messagePrinter.printf(" <device_type> can be: %s\n", NEO::getDevicesTypes().c_str());
}
int BinaryEncoder::encode() {
@ -161,15 +164,26 @@ int BinaryEncoder::encode() {
return createElf();
}
int BinaryEncoder::processBinary(const std::vector<std::string> &ptmFile, std::ostream &deviceBinary) {
int BinaryEncoder::processBinary(const std::vector<std::string> &ptmFileLines, std::ostream &deviceBinary) {
if (false == iga->isKnownPlatform()) {
auto deviceMarker = findPos(ptmFileLines, "Device");
if (deviceMarker != ptmFileLines.size()) {
std::stringstream ss(ptmFileLines[deviceMarker]);
ss.ignore(32, ' ');
ss.ignore(32, ' ');
uint32_t gfxCore = 0;
ss >> gfxCore;
iga->setGfxCore(static_cast<GFXCORE_FAMILY>(gfxCore));
}
}
size_t i = 0;
while (i < ptmFile.size()) {
if (ptmFile[i].find("Kernel #") != std::string::npos) {
if (processKernel(++i, ptmFile, deviceBinary)) {
while (i < ptmFileLines.size()) {
if (ptmFileLines[i].find("Kernel #") != std::string::npos) {
if (processKernel(++i, ptmFileLines, deviceBinary)) {
messagePrinter.printf("Warning while processing kernel!\n");
return -1;
}
} else if (writeDeviceBinary(ptmFile[i++], deviceBinary)) {
} else if (writeDeviceBinary(ptmFileLines[i++], deviceBinary)) {
messagePrinter.printf("Error while writing to binary!\n");
return -1;
}
@ -222,7 +236,22 @@ int BinaryEncoder::processKernel(size_t &line, const std::vector<std::string> &p
// Write KernelHeap and padding
uint32_t kernelSizeUnpadded = 0U;
bool heapsCopiedSuccesfully = copyBinaryToBinary(pathToDump + kernelName + "_KernelHeap.bin", kernelBlob, &kernelSizeUnpadded);
bool heapsCopiedSuccesfully = true;
// Use .asm if available, fallback to .dat
if (fileExists(pathToDump + kernelName + "_KernelHeap.asm")) {
auto kernelAsAsm = readBinaryFile(pathToDump + kernelName + "_KernelHeap.asm");
std::string kernelAsBinary;
messagePrinter.printf("Trying to assemble %s.asm\n", kernelName.c_str());
if (false == iga->tryAssembleGenISA(std::string(kernelAsAsm.begin(), kernelAsAsm.end()), kernelAsBinary)) {
messagePrinter.printf("Error : Could not assemble : %s\n", kernelName.c_str());
return -1;
}
kernelSizeUnpadded = static_cast<uint32_t>(kernelAsBinary.size());
kernelBlob.write(kernelAsBinary.data(), kernelAsBinary.size());
} else {
heapsCopiedSuccesfully = copyBinaryToBinary(pathToDump + kernelName + "_KernelHeap.dat", kernelBlob, &kernelSizeUnpadded);
}
// Adding padding and alignment
addPadding(kernelBlob, isaPaddingSizeInBytes);
@ -286,6 +315,8 @@ int BinaryEncoder::validateInput(uint32_t argc, const char **argv) {
if (!strcmp(argv[i], "-dump")) {
pathToDump = std::string(argv[++i]);
addSlash(pathToDump);
} else if (!strcmp(argv[i], "-device")) {
iga->setProductFamily(getProductFamilyFromDeviceName(argv[++i]));
} else if (!strcmp(argv[i], "-out")) {
elfName = std::string(argv[++i]);
} else {
@ -295,14 +326,19 @@ int BinaryEncoder::validateInput(uint32_t argc, const char **argv) {
}
}
if (pathToDump.empty()) {
messagePrinter.printf("Path to dump folder can't be empty.\n");
printHelp();
return -1;
} else if (elfName.find(".bin") == std::string::npos) {
messagePrinter.printf("Warning : Path to dump folder not specificed - using ./dump as default.\n");
pathToDump = "dump";
addSlash(pathToDump);
}
if (elfName.find(".bin") == std::string::npos) {
messagePrinter.printf(".bin extension is expected for binary file.\n");
printHelp();
return -1;
}
if (false == iga->isKnownPlatform()) {
messagePrinter.printf("Warning : missing or invalid -device parameter - results may be inacurate\n");
}
}
return 0;
}
@ -364,3 +400,11 @@ int BinaryEncoder::writeDeviceBinary(const std::string &line, std::ostream &devi
}
return 0;
}
bool BinaryEncoder::fileExists(const std::string &path) const {
return ::fileExists(path);
}
std::vector<char> BinaryEncoder::readBinaryFile(const std::string &path) const {
return ::readBinaryFile(path);
}

View File

@ -7,6 +7,7 @@
#pragma once
#include "helper.h"
#include "iga_wrapper.h"
#include <sstream>
#include <string>
@ -14,7 +15,9 @@
class BinaryEncoder {
public:
BinaryEncoder() = default;
BinaryEncoder() : iga(new IgaWrapper) {
iga->setMessagePrinter(messagePrinter);
}
BinaryEncoder(const std::string &dump, const std::string &elf)
: pathToDump(dump), elfName(elf){};
int encode();
@ -25,7 +28,7 @@ class BinaryEncoder {
protected:
std::string pathToDump, elfName;
MessagePrinter messagePrinter;
std::unique_ptr<IgaWrapper> iga;
void calculatePatchListSizes(std::vector<std::string> &ptmFile);
MOCKABLE_VIRTUAL bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary, uint32_t *binaryLength);
bool copyBinaryToBinary(const std::string &srcFileName, std::ostream &outBinary) {
@ -39,4 +42,6 @@ class BinaryEncoder {
void write(std::stringstream &in, std::ostream &deviceBinary);
int writeDeviceBinary(const std::string &line, std::ostream &deviceBinary);
void addPadding(std::ostream &out, size_t numBytes);
MOCKABLE_VIRTUAL bool fileExists(const std::string &path) const;
MOCKABLE_VIRTUAL std::vector<char> readBinaryFile(const std::string &path) const;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2018-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -7,6 +7,12 @@
#include "helper.h"
#include "runtime/helpers/hw_info.h"
#include "runtime/os_interface/os_inc_base.h"
#include "runtime/os_interface/os_library.h"
#include "igfxfmid.h"
#include <algorithm>
#include <fstream>
@ -66,3 +72,12 @@ size_t findPos(const std::vector<std::string> &lines, const std::string &whatToF
}
return lines.size();
}
PRODUCT_FAMILY getProductFamilyFromDeviceName(const std::string &deviceName) {
for (unsigned int productId = 0; productId < IGFX_MAX_PRODUCT; ++productId) {
if (deviceName == NEO::hardwarePrefix[productId]) {
return static_cast<PRODUCT_FAMILY>(productId);
}
}
return IGFX_UNKNOWN;
}

View File

@ -6,7 +6,12 @@
*/
#pragma once
#include "runtime/os_interface/os_library.h"
#include "igfxfmid.h"
#include <exception>
#include <memory>
#include <string>
#include <vector>
@ -18,6 +23,8 @@ void readFileToVectorOfStrings(std::vector<std::string> &lines, const std::strin
size_t findPos(const std::vector<std::string> &lines, const std::string &whatToFind);
PRODUCT_FAMILY getProductFamilyFromDeviceName(const std::string &deviceName);
class MessagePrinter {
public:
MessagePrinter() = default;

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2018-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "helper.h"
#include "iga_wrapper.h"
struct IgaWrapper::Impl {
};
IgaWrapper::IgaWrapper() = default;
IgaWrapper::~IgaWrapper() = default;
bool IgaWrapper::tryDisassembleGenISA(const void *kernelPtr, uint32_t kernelSize, std::string &out) {
messagePrinter->printf("Warning: ocloc built without support for IGA - kernel binaries won't be disassembled.\n");
return false;
}
bool IgaWrapper::tryAssembleGenISA(const std::string &inAsm, std::string &outBinary) {
messagePrinter->printf("Warning: ocloc built without support for IGA - kernel binaries won't be assembled.\n");
return false;
}
bool IgaWrapper::tryLoadIga() {
return false;
}
void IgaWrapper::setGfxCore(GFXCORE_FAMILY core) {
}
void IgaWrapper::setProductFamily(PRODUCT_FAMILY product) {
}
bool IgaWrapper::isKnownPlatform() const {
return false;
}

View File

@ -0,0 +1,192 @@
/*
* Copyright (C) 2018-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "iga_wrapper.h"
#include "runtime/helpers/hw_info.h"
#include "runtime/os_interface/os_inc_base.h"
#include "runtime/os_interface/os_library.h"
#include "helper.h"
#include "igfxfmid.h"
#include "translate_platform_base.h"
#include <memory>
struct IgaLibrary {
pIGAAssemble assemble = nullptr;
pIGAContextCreate contextCreate = nullptr;
pIGAContextGetErrors contextGetErrors = nullptr;
pIGAContextGetWarnings contextGetWarnings = nullptr;
pIGAContextRelease contextRelease = nullptr;
pIGADisassemble disassemble = nullptr;
pIGAStatusToString statusToString = nullptr;
iga_context_options_t OptsContext = {};
std::unique_ptr<NEO::OsLibrary> library;
bool isLoaded() {
return library != nullptr;
}
};
struct IgaWrapper::Impl {
iga_gen_t igaGen = IGA_GEN_INVALID;
IgaLibrary igaLib;
void loadIga() {
IgaLibrary iga;
iga.OptsContext.cb = sizeof(igaLib.OptsContext);
iga.OptsContext.gen = igaGen;
#define STR2(X) #X
#define STR(X) STR2(X)
iga.library.reset(NEO::OsLibrary::load(STR(IGA_LIBRARY_NAME)));
if (iga.library == nullptr) {
return;
}
#define LOAD_OR_ERROR(MEMBER, FUNC_NAME) \
if (nullptr == (iga.MEMBER = reinterpret_cast<decltype(iga.MEMBER)>(iga.library->getProcAddress(FUNC_NAME)))) { \
printf("Warning : Couldn't find %s in %s\n", FUNC_NAME, STR(IGA_LIBRARY_NAME)); \
return; \
}
LOAD_OR_ERROR(assemble, IGA_ASSEMBLE_STR);
LOAD_OR_ERROR(contextCreate, IGA_CONTEXT_CREATE_STR);
LOAD_OR_ERROR(contextGetErrors, IGA_CONTEXT_GET_ERRORS_STR);
LOAD_OR_ERROR(contextGetWarnings, IGA_CONTEXT_GET_WARNINGS_STR);
LOAD_OR_ERROR(contextRelease, IGA_CONTEXT_RELEASE_STR);
LOAD_OR_ERROR(disassemble, IGA_DISASSEMBLE_STR);
LOAD_OR_ERROR(statusToString, IGA_STATUS_TO_STRING_STR);
#undef LOAD_OR_ERROR
#undef STR
#undef STR2
this->igaLib = std::move(iga);
}
};
IgaWrapper::IgaWrapper()
: pimpl(new Impl()) {
}
IgaWrapper::~IgaWrapper() = default;
bool IgaWrapper::tryDisassembleGenISA(const void *kernelPtr, uint32_t kernelSize, std::string &out) {
if (false == tryLoadIga()) {
messagePrinter->printf("Warning: couldn't load iga - kernel binaries won't be disassembled.\n");
return false;
}
iga_context_t context;
iga_disassemble_options_t disassembleOptions = IGA_DISASSEMBLE_OPTIONS_INIT();
iga_status_t stat;
stat = pimpl->igaLib.contextCreate(&pimpl->igaLib.OptsContext, &context);
if (stat != 0) {
messagePrinter->printf("Error while creating IGA Context! Error msg: %s", pimpl->igaLib.statusToString(stat));
return false;
}
char kernelText = '\0';
char *pKernelText = &kernelText;
stat = pimpl->igaLib.disassemble(context, &disassembleOptions, kernelPtr, kernelSize, nullptr, nullptr, &pKernelText);
if (stat != 0) {
messagePrinter->printf("Error while disassembling with IGA!\nStatus msg: %s\n", pimpl->igaLib.statusToString(stat));
const iga_diagnostic_t *errors;
uint32_t size = 100;
pimpl->igaLib.contextGetErrors(context, &errors, &size);
if (errors != nullptr) {
messagePrinter->printf("Errors: %s\n", errors->message);
}
pimpl->igaLib.contextRelease(context);
return false;
}
const iga_diagnostic_t *warnings;
uint32_t warningsSize = 100;
pimpl->igaLib.contextGetWarnings(context, &warnings, &warningsSize);
if (warningsSize > 0 && warnings != nullptr) {
messagePrinter->printf("Warnings: %s\n", warnings->message);
}
out = pKernelText;
pimpl->igaLib.contextRelease(context);
return true;
}
bool IgaWrapper::tryAssembleGenISA(const std::string &inAsm, std::string &outBinary) {
if (false == tryLoadIga()) {
messagePrinter->printf("Warning: couldn't load iga - kernel binaries won't be assembled.\n");
return false;
}
iga_context_t context;
iga_status_t stat;
iga_assemble_options_t assembleOptions = IGA_ASSEMBLE_OPTIONS_INIT();
stat = pimpl->igaLib.contextCreate(&pimpl->igaLib.OptsContext, &context);
if (stat != 0) {
messagePrinter->printf("Error while creating IGA Context! Error msg: %s", pimpl->igaLib.statusToString(stat));
return false;
}
uint32_t size = 0;
void *pOutput = nullptr;
stat = pimpl->igaLib.assemble(context, &assembleOptions, inAsm.c_str(), &pOutput, &size);
if (stat != 0) {
messagePrinter->printf("Error while assembling with IGA!\nStatus msg: %s\n", pimpl->igaLib.statusToString(stat));
const iga_diagnostic_t *errors;
uint32_t size = 100;
pimpl->igaLib.contextGetErrors(context, &errors, &size);
if (errors != nullptr) {
messagePrinter->printf("Errors: %s\n", errors->message);
}
pimpl->igaLib.contextRelease(context);
return false;
}
const iga_diagnostic_t *warnings;
uint32_t context_size;
pimpl->igaLib.contextGetWarnings(context, &warnings, &context_size);
if (context_size > 0 && warnings != nullptr) {
messagePrinter->printf("Warnings: %s\n", warnings->message);
}
outBinary.assign(reinterpret_cast<char *>(pOutput), reinterpret_cast<char *>(pOutput) + size);
pimpl->igaLib.contextRelease(context);
return true;
}
bool IgaWrapper::tryLoadIga() {
if (false == pimpl->igaLib.isLoaded()) {
pimpl->loadIga();
}
return pimpl->igaLib.isLoaded();
}
void IgaWrapper::setGfxCore(GFXCORE_FAMILY core) {
if (pimpl->igaGen == IGA_GEN_INVALID) {
pimpl->igaGen = translateToIgaGen(core);
}
}
void IgaWrapper::setProductFamily(PRODUCT_FAMILY product) {
if (pimpl->igaGen == IGA_GEN_INVALID) {
pimpl->igaGen = translateToIgaGen(product);
}
}
bool IgaWrapper::isKnownPlatform() const {
return pimpl->igaGen != IGA_GEN_INVALID;
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2018-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "igfxfmid.h"
#include <memory>
#include <string>
class MessagePrinter;
struct IgaWrapper {
IgaWrapper();
MOCKABLE_VIRTUAL ~IgaWrapper();
IgaWrapper(IgaWrapper &) = delete;
IgaWrapper(const IgaWrapper &&) = delete;
IgaWrapper &operator=(IgaWrapper &) = delete;
IgaWrapper &operator=(const IgaWrapper &&) = delete;
MOCKABLE_VIRTUAL bool tryDisassembleGenISA(const void *kernelPtr, uint32_t kernelSize, std::string &out);
MOCKABLE_VIRTUAL bool tryAssembleGenISA(const std::string &inAsm, std::string &outBinary);
MOCKABLE_VIRTUAL void setGfxCore(GFXCORE_FAMILY core);
MOCKABLE_VIRTUAL void setProductFamily(PRODUCT_FAMILY product);
MOCKABLE_VIRTUAL bool isKnownPlatform() const;
void setMessagePrinter(MessagePrinter &messagePrinter) {
this->messagePrinter = &messagePrinter;
}
protected:
MOCKABLE_VIRTUAL bool tryLoadIga();
struct Impl;
std::unique_ptr<Impl> pimpl;
MessagePrinter *messagePrinter;
};

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "offline_compiler/decoder/translate_platform_base.h"
iga_gen_t translateToIgaGen(PRODUCT_FAMILY productFamily) {
return translateToIgaGenBase(productFamily);
}
iga_gen_t translateToIgaGen(GFXCORE_FAMILY coreFamily) {
return translateToIgaGenBase(coreFamily);
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "igad.h"
#include "igfxfmid.h"
inline iga_gen_t translateToIgaGenBase(PRODUCT_FAMILY productFamily) {
switch (productFamily) {
default:
return IGA_GEN_INVALID;
case IGFX_BROADWELL:
return IGA_GEN8;
case IGFX_CHERRYVIEW:
return IGA_GEN8lp;
case IGFX_SKYLAKE:
return IGA_GEN9;
case IGFX_BROXTON:
return IGA_GEN9lp;
case IGFX_KABYLAKE:
return IGA_GEN9p5;
case IGFX_COFFEELAKE:
return IGA_GEN9p5;
case IGFX_ICELAKE:
return IGA_GEN11;
case IGFX_ICELAKE_LP:
return IGA_GEN11;
}
}
inline iga_gen_t translateToIgaGenBase(GFXCORE_FAMILY coreFamily) {
switch (coreFamily) {
default:
return IGA_GEN_INVALID;
case IGFX_GEN8_CORE:
return IGA_GEN8;
case IGFX_GEN9_CORE:
return IGA_GEN9;
case IGFX_GEN11_CORE:
return IGA_GEN11;
case IGFX_GEN11LP_CORE:
return IGA_GEN11;
}
}
iga_gen_t translateToIgaGen(PRODUCT_FAMILY productFamily);
iga_gen_t translateToIgaGen(GFXCORE_FAMILY coreFamily);

View File

@ -20,7 +20,7 @@ using namespace NEO;
int main(int numArgs, const char *argv[]) {
try {
if (numArgs > 1 && !strcmp(argv[1], "disasm")) { // -file binary.bin -patch workspace/igc/inc -dump dump/folder
if (numArgs > 1 && !strcmp(argv[1], "disasm")) {
BinaryDecoder disasm;
int retVal = disasm.validateInput(numArgs, argv);
if (retVal == 0) {
@ -28,7 +28,7 @@ int main(int numArgs, const char *argv[]) {
} else {
return retVal;
}
} else if (numArgs > 1 && !strcmp(argv[1], "asm")) { // -dump dump/folder -out new_elf.bin
} else if (numArgs > 1 && !strcmp(argv[1], "asm")) {
BinaryEncoder assembler;
int retVal = assembler.validateInput(numArgs, argv);
if (retVal == 0) {

View File

@ -30,6 +30,7 @@ enum ErrorCode {
};
std::string generateFilePath(const std::string &directory, const std::string &fileNameBase, const char *extension);
std::string getDevicesTypes();
class OfflineCompiler {
public:

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;
};