1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
/*
* Copyright (C) 2018-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "iga_wrapper.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/os_interface/os_library.h"
#include "opencl/source/os_interface/os_inc_base.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(std::make_unique<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;
}
|