Zebin: Add support for querying device globals by host name

This commit adds support for querying global pointers via decorated
names passed in zeInfo.
Related-To: NEO-6734
Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:
Kacper Nowak
2022-02-23 11:48:31 +00:00
committed by Compute-Runtime-Automation
parent 999c6424a4
commit 38086029ed
11 changed files with 289 additions and 8 deletions

View File

@@ -543,6 +543,9 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
success = this->linkBinary();
success &= populateHostGlobalSymbolsMap(this->translationUnit->programInfo.globalsDeviceToHostNameMap);
this->updateBuildLog(neoDevice);
if (debugEnabled) {
passDebugData();
}
@@ -815,15 +818,25 @@ ze_result_t ModuleImp::getFunctionPointer(const char *pFunctionName, void **pfnF
}
ze_result_t ModuleImp::getGlobalPointer(const char *pGlobalName, size_t *pSize, void **pPtr) {
auto symbolIt = symbols.find(pGlobalName);
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.segment == NEO::SegmentType::Instructions)) {
uint64_t address;
size_t size;
if (hostGlobalSymbolsMap.count(pGlobalName) == 1) {
address = hostGlobalSymbolsMap[pGlobalName].address;
size = hostGlobalSymbolsMap[pGlobalName].size;
} else if (symbols.count(pGlobalName) == 1) {
if (symbols[pGlobalName].symbol.segment == NEO::SegmentType::Instructions) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
address = symbols[pGlobalName].gpuAddress;
size = symbols[pGlobalName].symbol.size;
} else {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
if (pPtr) {
*pPtr = reinterpret_cast<void *>(symbolIt->second.gpuAddress);
*pPtr = reinterpret_cast<void *>(address);
}
if (pSize) {
*pSize = symbolIt->second.symbol.size;
*pSize = size;
}
return ZE_RESULT_SUCCESS;
}
@@ -992,6 +1005,29 @@ ze_result_t ModuleImp::performDynamicLink(uint32_t numModules,
return ZE_RESULT_SUCCESS;
}
bool ModuleImp::populateHostGlobalSymbolsMap(std::unordered_map<std::string, std::string> &devToHostNameMapping) {
bool retVal = true;
for (auto &[devName, hostName] : devToHostNameMapping) {
auto findSymbolRes = symbols.find(devName);
if (findSymbolRes != symbols.end()) {
auto symbol = findSymbolRes->second;
if (isDataSegment(symbol.symbol.segment)) {
GlobalSymbol hostSymbol;
hostSymbol.address = symbol.gpuAddress;
hostSymbol.size = symbol.symbol.size;
hostGlobalSymbolsMap[hostName] = hostSymbol;
} else {
translationUnit->buildLog.append("Error: Symbol with given device name: " + devName + " is not in globals* segment.\n");
retVal = false;
}
} else {
translationUnit->buildLog.append("Error: No symbol found with given device name: " + devName + ".\n");
retVal = false;
}
}
return retVal;
}
void ModuleImp::registerElfInDebuggerL0() {
if (device->getL0Debugger() == nullptr) {
return;

View File

@@ -147,6 +147,7 @@ struct ModuleImp : public Module {
void passDebugData();
void createDebugZebin();
void registerElfInDebuggerL0();
bool populateHostGlobalSymbolsMap(std::unordered_map<std::string, std::string> &devToHostNameMapping);
Device *device = nullptr;
PRODUCT_FAMILY productFamily{};
@@ -156,6 +157,14 @@ struct ModuleImp : public Module {
uint32_t maxGroupSize = 0U;
std::vector<std::unique_ptr<KernelImmutableData>> kernelImmDatas;
NEO::Linker::RelocatedSymbolsMap symbols;
struct GlobalSymbol {
uintptr_t address = std::numeric_limits<uintptr_t>::max();
size_t size = 0U;
};
std::unordered_map<std::string, GlobalSymbol> hostGlobalSymbolsMap;
bool debugEnabled = false;
bool isFullyLinked = false;
bool allocatePrivateMemoryPerDispatch = true;

View File

@@ -76,6 +76,8 @@ struct MockModule : public L0::ModuleImp {
using ModuleImp::debugEnabled;
using ModuleImp::debugModuleHandle;
using ModuleImp::kernelImmDatas;
using ModuleImp::populateHostGlobalSymbolsMap;
using ModuleImp::symbols;
using ModuleImp::translationUnit;
MockModule(L0::Device *device,

View File

@@ -2095,6 +2095,75 @@ TEST_F(ModuleTest, givenModuleWithSymbolWhenGettingGlobalPointerWithNullptrInput
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(ModuleTest, givenModuleWithGlobalSymbolMapWhenGettingGlobalPointerByHostSymbolNameExistingInMapThenCorrectPointerAndSuccessIsReturned) {
std::unordered_map<std::string, std::string> mapping;
mapping["devSymbolOne"] = "hostSymbolOne";
mapping["devSymbolTwo"] = "hostSymbolTwo";
size_t symbolsSize = 1024u;
uint64_t globalVarGpuAddress = 0x12345000;
NEO::SymbolInfo globalVariablesSymbolInfo{0, static_cast<uint32_t>(symbolsSize), SegmentType::GlobalVariables};
NEO::Linker::RelocatedSymbol globalVariablesRelocatedSymbol{globalVariablesSymbolInfo, globalVarGpuAddress};
uint64_t globalConstGpuAddress = 0x12347000;
NEO::SymbolInfo globalConstantsSymbolInfo{0, static_cast<uint32_t>(symbolsSize), SegmentType::GlobalConstants};
NEO::Linker::RelocatedSymbol globalConstansRelocatedSymbol{globalConstantsSymbolInfo, globalConstGpuAddress};
auto module0 = std::make_unique<MockModule>(device, nullptr, ModuleType::User);
module0->symbols["devSymbolOne"] = globalVariablesRelocatedSymbol;
module0->symbols["devSymbolTwo"] = globalConstansRelocatedSymbol;
auto success = module0->populateHostGlobalSymbolsMap(mapping);
EXPECT_TRUE(success);
EXPECT_TRUE(module0->getTranslationUnit()->buildLog.empty());
size_t size = 0;
void *ptr = nullptr;
auto result = module0->getGlobalPointer("hostSymbolOne", &size, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(symbolsSize, size);
EXPECT_EQ(globalVarGpuAddress, reinterpret_cast<uint64_t>(ptr));
result = module0->getGlobalPointer("hostSymbolTwo", &size, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(symbolsSize, size);
EXPECT_EQ(globalConstGpuAddress, reinterpret_cast<uint64_t>(ptr));
}
TEST_F(ModuleTest, givenModuleWithGlobalSymbolsMapWhenPopulatingMapWithSymbolNotFoundInRelocatedSymbolsMapThenPrintErrorStringAndReturnFalse) {
std::unordered_map<std::string, std::string> mapping;
std::string notFoundDevSymbolName = "anotherDevSymbolOne";
mapping[notFoundDevSymbolName] = "anotherHostSymbolOne";
auto module0 = std::make_unique<MockModule>(device, nullptr, ModuleType::User);
EXPECT_EQ(0u, module0->symbols.count(notFoundDevSymbolName));
auto result = module0->populateHostGlobalSymbolsMap(mapping);
EXPECT_FALSE(result);
std::string expectedErrorOutput = "Error: No symbol found with given device name: " + notFoundDevSymbolName + ".\n";
EXPECT_STREQ(expectedErrorOutput.c_str(), module0->getTranslationUnit()->buildLog.c_str());
}
TEST_F(ModuleTest, givenModuleWithGlobalSymbolsMapWhenPopulatingMapWithSymbolFromIncorrectSegmentThenPrintErrorStringAndReturnFalse) {
std::unordered_map<std::string, std::string> mapping;
std::string incorrectDevSymbolName = "incorrectSegmentDevSymbolOne";
mapping[incorrectDevSymbolName] = "incorrectSegmentHostSymbolOne";
size_t symbolSize = 1024u;
uint64_t gpuAddress = 0x12345000;
NEO::SymbolInfo symbolInfo{0, static_cast<uint32_t>(symbolSize), SegmentType::Instructions};
NEO::Linker::RelocatedSymbol relocatedSymbol{symbolInfo, gpuAddress};
auto module0 = std::make_unique<MockModule>(device, nullptr, ModuleType::User);
module0->symbols[incorrectDevSymbolName] = relocatedSymbol;
auto result = module0->populateHostGlobalSymbolsMap(mapping);
EXPECT_FALSE(result);
std::string expectedErrorOutput = "Error: Symbol with given device name: " + incorrectDevSymbolName + " is not in globals* segment.\n";
EXPECT_STREQ(expectedErrorOutput.c_str(), module0->getTranslationUnit()->buildLog.c_str());
}
using ModuleTests = Test<DeviceFixture>;
TEST_F(ModuleTests, whenCopyingPatchedSegmentsThenAllocationsAreSetWritableForTbxAndAub) {
auto pModule = std::make_unique<Module>(device, nullptr, ModuleType::User);