Register ELF for every kernel allocation for zebin format

- every isa allocation will have ELF linked
- fix for debug elf from patchtoken binary:
pass relocated ELF when exists
- simplify code

Related-To: NEO-5571

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2022-02-07 17:26:34 +00:00
committed by Compute-Runtime-Automation
parent d49c5d6185
commit e1758a2206
5 changed files with 89 additions and 14 deletions

View File

@@ -110,6 +110,10 @@ void KernelImmutableData::initialize(NEO::KernelInfo *kernelInfo, Device *device
isaGraphicsAllocation.reset(allocation);
if (neoDevice->getDebugger() && kernelInfo->kernelDescriptor.external.debugData.get()) {
createRelocatedDebugData(globalConstBuffer, globalVarBuffer);
}
this->crossThreadDataSize = this->kernelDescriptor->kernelAttributes.crossThreadDataSize;
ArrayRef<uint8_t> crossThredDataArrayRef;
@@ -193,6 +197,8 @@ void KernelImmutableData::createRelocatedDebugData(NEO::GraphicsAllocation *glob
outErrReason, outWarning);
if (decodedElf.getDebugInfoRelocations().size() > 1) {
UNRECOVERABLE_IF(kernelInfo->kernelDescriptor.external.relocatedDebugData.get() != nullptr);
auto size = kernelInfo->kernelDescriptor.external.debugData->vIsaSize;
kernelInfo->kernelDescriptor.external.relocatedDebugData = std::make_unique<uint8_t[]>(size);

View File

@@ -536,7 +536,7 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
kernelImmDatas.push_back(std::move(kernelImmData));
}
registerElfInDebuggerL0(neoDevice);
registerElfInDebuggerL0();
this->maxGroupSize = static_cast<uint32_t>(this->translationUnit->device->getNEODevice()->getDeviceInfo().maxWorkGroupSize);
checkIfPrivateMemoryPerDispatchIsNeeded();
@@ -992,8 +992,8 @@ ze_result_t ModuleImp::performDynamicLink(uint32_t numModules,
return ZE_RESULT_SUCCESS;
}
void ModuleImp::registerElfInDebuggerL0(NEO::Device *neoDevice) {
if (neoDevice->getDebugger() == nullptr) {
void ModuleImp::registerElfInDebuggerL0() {
if (device->getL0Debugger() == nullptr) {
return;
}
@@ -1001,19 +1001,27 @@ void ModuleImp::registerElfInDebuggerL0(NEO::Device *neoDevice) {
if (NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(refBin)) {
size_t debugDataSize = 0;
getDebugInfo(&debugDataSize, nullptr);
if (device->getL0Debugger()) {
NEO::DebugData debugData; // pass debug zebin in vIsa field
debugData.vIsa = reinterpret_cast<const char *>(translationUnit->debugData.get());
debugData.vIsaSize = static_cast<uint32_t>(translationUnit->debugDataSize);
device->getL0Debugger()->registerElf(&debugData, kernelImmDatas[0]->getIsaGraphicsAllocation());
NEO::DebugData debugData; // pass debug zebin in vIsa field
debugData.vIsa = reinterpret_cast<const char *>(translationUnit->debugData.get());
debugData.vIsaSize = static_cast<uint32_t>(translationUnit->debugDataSize);
for (auto &kernImmData : kernelImmDatas) {
device->getL0Debugger()->registerElf(&debugData, kernImmData->getIsaGraphicsAllocation());
}
} else {
for (auto &kernImmData : kernelImmDatas) {
if (kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get()) {
kernImmData->createRelocatedDebugData(translationUnit->globalConstBuffer, translationUnit->globalVarBuffer);
if (device->getL0Debugger()) {
device->getL0Debugger()->registerElf(kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get(), kernImmData->getIsaGraphicsAllocation());
NEO::DebugData *notifyDebugData = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get();
NEO::DebugData relocatedDebugData;
if (kernImmData->getKernelInfo()->kernelDescriptor.external.relocatedDebugData.get()) {
relocatedDebugData.genIsa = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->genIsa;
relocatedDebugData.genIsaSize = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->genIsaSize;
relocatedDebugData.vIsa = reinterpret_cast<char *>(kernImmData->getKernelInfo()->kernelDescriptor.external.relocatedDebugData.get());
relocatedDebugData.vIsaSize = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->vIsaSize;
notifyDebugData = &relocatedDebugData;
}
device->getL0Debugger()->registerElf(notifyDebugData, kernImmData->getIsaGraphicsAllocation());
}
}
}

View File

@@ -141,7 +141,7 @@ struct ModuleImp : public Module {
NEO::Debug::Segments getZebinSegments();
void passDebugData();
void createDebugZebin();
void registerElfInDebuggerL0(NEO::Device *neoDevice);
void registerElfInDebuggerL0();
Device *device = nullptr;
PRODUCT_FAMILY productFamily{};

View File

@@ -6,6 +6,8 @@
*/
#pragma once
#include "shared/source/kernel/debug_data.h"
#include "level_zero/core/source/debugger/debugger_l0.h"
#include "level_zero/core/test/unit_tests/white_box.h"
@@ -43,6 +45,7 @@ class MockDebuggerL0Hw : public L0::DebuggerL0Hw<GfxFamily> {
void registerElf(NEO::DebugData *debugData, NEO::GraphicsAllocation *isaAllocation) override {
registerElfCount++;
lastReceivedElf = debugData->vIsa;
L0::DebuggerL0Hw<GfxFamily>::registerElf(debugData, isaAllocation);
}
@@ -50,6 +53,7 @@ class MockDebuggerL0Hw : public L0::DebuggerL0Hw<GfxFamily> {
uint32_t programSbaTrackingCommandsCount = 0;
uint32_t getSbaTrackingCommandsSizeCount = 0;
uint32_t registerElfCount = 0;
const char *lastReceivedElf = nullptr;
};
template <uint32_t productFamily, typename GfxFamily>

View File

@@ -416,7 +416,7 @@ TEST_F(KernelInitializeTest, givenDebuggingEnabledWhenKernelsAreInitializedThenA
EXPECT_THAT(isa, testing::Not(MemCompare(&kernelHeap, sizeof(kernelHeap))));
};
HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWhenInitializingModuleThenRegisterElf) {
HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWithRelocationsWhenInitializingModuleThenRegisterElfWithRelocatedElf) {
NEO::MockCompilerEnableGuard mock(true);
auto cip = new NEO::MockCompilerInterfaceCaptureBuildOptions();
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface.reset(cip);
@@ -455,6 +455,59 @@ HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWhenInitializingModuleThenRegis
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
EXPECT_NE(nullptr, kernelInfo->kernelDescriptor.external.relocatedDebugData.get());
EXPECT_EQ(reinterpret_cast<char *>(kernelInfo->kernelDescriptor.external.relocatedDebugData.get()), getMockDebuggerL0Hw<FamilyType>()->lastReceivedElf);
}
HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWithoutRelocationsWhenInitializingModuleThenRegisterElfWithUnrelocatedElf) {
NEO::MockCompilerEnableGuard mock(true);
auto cip = new NEO::MockCompilerInterfaceCaptureBuildOptions();
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface.reset(cip);
uint8_t binary[10];
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = binary;
moduleDesc.inputSize = 10;
ModuleBuildLog *moduleBuildLog = nullptr;
std::unique_ptr<MockModule> moduleMock = std::make_unique<MockModule>(device, moduleBuildLog, ModuleType::User);
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
uint32_t kernelHeap = 0;
auto kernelInfo = new KernelInfo();
kernelInfo->heapInfo.KernelHeapSize = 1;
kernelInfo->heapInfo.pKernelHeap = &kernelHeap;
Mock<::L0::Kernel> kernelMock;
kernelMock.module = moduleMock.get();
kernelMock.immutableData.kernelInfo = kernelInfo;
kernelInfo->kernelDescriptor.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful = 0;
moduleMock->kernelImmData = &kernelMock.immutableData;
moduleMock->translationUnit->programInfo.kernelInfos.push_back(kernelInfo);
kernelInfo->kernelDescriptor.external.debugData = std::make_unique<NEO::DebugData>();
std::vector<uint8_t> data;
data.resize(4);
NEO::Elf::ElfEncoder<> elfEncoder;
elfEncoder.getElfFileHeader().type = NEO::Elf::SHT_PROGBITS;
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix, data);
auto elfBinary = elfEncoder.encode();
kernelInfo->kernelDescriptor.external.debugData->vIsaSize = static_cast<uint32_t>(elfBinary.size());
kernelInfo->kernelDescriptor.external.debugData->vIsa = reinterpret_cast<char *>(elfBinary.data());
kernelInfo->kernelDescriptor.external.debugData->genIsa = nullptr;
kernelInfo->kernelDescriptor.external.debugData->genIsaSize = 0;
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
EXPECT_EQ(nullptr, kernelInfo->kernelDescriptor.external.relocatedDebugData.get());
EXPECT_EQ(kernelInfo->kernelDescriptor.external.debugData->vIsa, getMockDebuggerL0Hw<FamilyType>()->lastReceivedElf);
}
HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenInitializingModuleThenDoNotRegisterElf) {
@@ -513,6 +566,10 @@ HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenZebinDebugDataWhenInitializingMo
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
moduleMock->kernelImmDatas.push_back(std::move(kernelImmutableData));
kernelImmutableData = ::std::make_unique<KernelImmutableData>(device);
kernelImmutableData->initialize(kernelInfo.get(), device, 0, nullptr, nullptr, false);
moduleMock->kernelImmDatas.push_back(std::move(kernelImmutableData));
auto zebin = ZebinTestData::ValidEmptyProgram();
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
moduleMock->translationUnit->unpackedDeviceBinarySize = zebin.storage.size();
@@ -521,7 +578,7 @@ HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenZebinDebugDataWhenInitializingMo
zebin.storage.data(), zebin.storage.size());
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
EXPECT_EQ(2u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
}
HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenZebinNoDebugDataWhenInitializingModuleThenDoNotRegisterElf) {