Skip to content

Commit 4e31f23

Browse files
fix: correct program header generation for shared isa allocation
- when kernels share single allocation, LOAD address in program headers should point to correct virtual address including kernel offset Related-To: NEO-7788, GSD-9836 Signed-off-by: Mateusz Hoppe <[email protected]> Source: 37b7caa
1 parent 5f8f005 commit 4e31f23

File tree

5 files changed

+81
-14
lines changed

5 files changed

+81
-14
lines changed

level_zero/core/source/module/module_imp.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,9 +523,16 @@ ModuleImp::~ModuleImp() {
523523
}
524524

525525
NEO::Zebin::Debug::Segments ModuleImp::getZebinSegments() {
526-
std::vector<std::pair<std::string_view, NEO::GraphicsAllocation *>> kernels;
527-
for (const auto &kernelImmData : kernelImmDatas)
528-
kernels.push_back({kernelImmData->getDescriptor().kernelMetadata.kernelName, kernelImmData->getIsaGraphicsAllocation()});
526+
std::vector<NEO::Zebin::Debug::Segments::KernelNameIsaTupleT> kernels;
527+
for (const auto &kernelImmData : kernelImmDatas) {
528+
NEO::Zebin::Debug::Segments::Segment segment = {kernelImmData->getIsaGraphicsAllocation()->getGpuAddress(), kernelImmData->getIsaGraphicsAllocation()->getUnderlyingBufferSize()};
529+
if (kernelImmData->getIsaParentAllocation()) {
530+
segment.address += kernelImmData->getIsaOffsetInParentAllocation();
531+
segment.size = kernelImmData->getIsaSubAllocationSize();
532+
}
533+
kernels.push_back({kernelImmData->getDescriptor().kernelMetadata.kernelName, segment});
534+
}
535+
529536
ArrayRef<const uint8_t> strings = {reinterpret_cast<const uint8_t *>(translationUnit->programInfo.globalStrings.initData),
530537
translationUnit->programInfo.globalStrings.size};
531538
return NEO::Zebin::Debug::Segments(translationUnit->globalVarBuffer, translationUnit->globalConstBuffer, strings, kernels);

level_zero/core/test/unit_tests/sources/module/test_module.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4834,6 +4834,65 @@ TEST_F(ModuleWithZebinTest, givenValidZebinWhenGettingDebugInfoThenDebugZebinIsC
48344834
EXPECT_EQ(retCode, ZE_RESULT_SUCCESS);
48354835
}
48364836

4837+
TEST_F(ModuleTranslationUnitTest, givenModuleWithMultipleKernelsWhenDebugInfoQueriedThenCorrectSegmentsAreDefined) {
4838+
std::string zeInfo = std::string("version :\'") + versionToString(NEO::Zebin::ZeInfo::zeInfoDecoderVersion) + R"===('
4839+
kernels:
4840+
- name : kernel1
4841+
execution_env :
4842+
simd_size : 8
4843+
- name : kernel2
4844+
execution_env :
4845+
simd_size : 8
4846+
)===";
4847+
MockElfEncoder<> elfEncoder;
4848+
elfEncoder.getElfFileHeader().type = NEO::Elf::ET_REL;
4849+
elfEncoder.getElfFileHeader().machine = productFamily;
4850+
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Zebin::Elf::SectionNames::textPrefix.str() + "kernel1", std::string{});
4851+
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Zebin::Elf::SectionNames::textPrefix.str() + "kernel2", std::string{});
4852+
elfEncoder.appendSection(NEO::Zebin::Elf::SHT_ZEBIN_ZEINFO, NEO::Zebin::Elf::SectionNames::zeInfo, zeInfo);
4853+
auto zebin = elfEncoder.encode();
4854+
4855+
auto module = new Module(device, nullptr, ModuleType::user);
4856+
4857+
ze_module_desc_t moduleDesc = {ZE_STRUCTURE_TYPE_MODULE_DESC};
4858+
moduleDesc.format = ZE_MODULE_FORMAT_NATIVE;
4859+
moduleDesc.inputSize = zebin.size();
4860+
moduleDesc.pInputModule = zebin.data();
4861+
moduleDesc.pNext = nullptr;
4862+
ze_result_t result = ZE_RESULT_SUCCESS;
4863+
result = module->initialize(&moduleDesc, neoDevice);
4864+
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
4865+
size_t debugDataSize;
4866+
module->getDebugInfo(&debugDataSize, nullptr);
4867+
auto debugData = std::make_unique<uint8_t[]>(debugDataSize);
4868+
result = module->getDebugInfo(&debugDataSize, debugData.get());
4869+
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
4870+
ASSERT_NE(nullptr, module->translationUnit->debugData.get());
4871+
4872+
std::string errors, warnings;
4873+
auto outElf = Elf::decodeElf<NEO::Elf::EI_CLASS_64>(ArrayRef<const uint8_t>(debugData.get(), debugDataSize), errors, warnings);
4874+
4875+
auto kernel1 = module->kernelImmDatas[0].get();
4876+
auto kernel2 = module->kernelImmDatas[1].get();
4877+
EXPECT_EQ(kernel1->getIsaGraphicsAllocation(), kernel2->getIsaGraphicsAllocation());
4878+
EXPECT_EQ(kernel1->getIsaGraphicsAllocation(), kernel2->getIsaGraphicsAllocation());
4879+
EXPECT_NE(nullptr, kernel1->getIsaParentAllocation());
4880+
4881+
auto kernel1Address = kernel1->getIsaGraphicsAllocation()->getGpuAddress() + kernel1->getIsaOffsetInParentAllocation();
4882+
auto kernel1Size = kernel1->getIsaSubAllocationSize();
4883+
4884+
EXPECT_EQ(kernel1Address, outElf.programHeaders[0].header->vAddr);
4885+
EXPECT_EQ(kernel1Size, outElf.programHeaders[0].header->memSz);
4886+
4887+
auto kernel2Address = kernel2->getIsaGraphicsAllocation()->getGpuAddress() + kernel2->getIsaOffsetInParentAllocation();
4888+
auto kernel2Size = kernel2->getIsaSubAllocationSize();
4889+
4890+
EXPECT_EQ(kernel2Address, outElf.programHeaders[1].header->vAddr);
4891+
EXPECT_EQ(kernel2Size, outElf.programHeaders[1].header->memSz);
4892+
4893+
module->destroy();
4894+
}
4895+
48374896
TEST_F(ModuleWithZebinTest, givenValidZebinAndPassedDataSmallerThanDebugDataThenErrorIsReturned) {
48384897
module->addEmptyZebin();
48394898
module->addSegments();

opencl/source/program/process_device_binary.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,12 @@ void Program::processDebugData(uint32_t rootDeviceIndex) {
353353
Zebin::Debug::Segments Program::getZebinSegments(uint32_t rootDeviceIndex) {
354354
ArrayRef<const uint8_t> strings = {reinterpret_cast<const uint8_t *>(buildInfos[rootDeviceIndex].constStringSectionData.initData),
355355
buildInfos[rootDeviceIndex].constStringSectionData.size};
356-
std::vector<std::pair<std::string_view, NEO::GraphicsAllocation *>> kernels;
357-
for (const auto &kernelInfo : buildInfos[rootDeviceIndex].kernelInfoArray)
358-
kernels.push_back({kernelInfo->kernelDescriptor.kernelMetadata.kernelName, kernelInfo->getGraphicsAllocation()});
356+
std::vector<NEO::Zebin::Debug::Segments::KernelNameIsaTupleT> kernels;
357+
for (const auto &kernelInfo : buildInfos[rootDeviceIndex].kernelInfoArray) {
359358

359+
NEO::Zebin::Debug::Segments::Segment segment = {static_cast<uintptr_t>(kernelInfo->getGraphicsAllocation()->getGpuAddress()), kernelInfo->getGraphicsAllocation()->getUnderlyingBufferSize()};
360+
kernels.push_back({kernelInfo->kernelDescriptor.kernelMetadata.kernelName, segment});
361+
}
360362
return Zebin::Debug::Segments(getGlobalSurface(rootDeviceIndex), getConstantSurface(rootDeviceIndex), strings, kernels);
361363
}
362364

shared/source/device_binary_format/zebin/debug_zebin.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2021-2023 Intel Corporation
2+
* Copyright (C) 2021-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -18,7 +18,7 @@ using namespace NEO::Zebin::Elf;
1818

1919
Segments::Segments() {}
2020

21-
Segments::Segments(const GraphicsAllocation *globalVarAlloc, const GraphicsAllocation *globalConstAlloc, ArrayRef<const uint8_t> &globalStrings, std::vector<KernelNameIsaPairT> &kernels) {
21+
Segments::Segments(const GraphicsAllocation *globalVarAlloc, const GraphicsAllocation *globalConstAlloc, ArrayRef<const uint8_t> &globalStrings, std::vector<KernelNameIsaTupleT> &kernels) {
2222
if (globalVarAlloc) {
2323
varData = {static_cast<uintptr_t>(globalVarAlloc->getGpuAddress()), globalVarAlloc->getUnderlyingBufferSize()};
2424
}
@@ -28,9 +28,8 @@ Segments::Segments(const GraphicsAllocation *globalVarAlloc, const GraphicsAlloc
2828
if (false == globalStrings.empty()) {
2929
stringData = {reinterpret_cast<uintptr_t>(globalStrings.begin()), globalStrings.size()};
3030
}
31-
for (auto &[kernelName, isa] : kernels) {
32-
Debug::Segments::Segment kernelSegment = {static_cast<uintptr_t>(isa->getGpuAddress()), isa->getUnderlyingBufferSize()};
33-
nameToSegMap.insert(std::pair(kernelName, kernelSegment));
31+
for (auto &[kernelName, isaSegment] : kernels) {
32+
nameToSegMap.insert(std::pair(kernelName, isaSegment));
3433
}
3534
}
3635

shared/source/device_binary_format/zebin/debug_zebin.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2021-2023 Intel Corporation
2+
* Copyright (C) 2021-2024 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -26,15 +26,15 @@ struct Segments {
2626
};
2727
using CPUSegment = Segment;
2828
using GPUSegment = Segment;
29-
using KernelNameIsaPairT = std::pair<std::string_view, GraphicsAllocation *>;
29+
using KernelNameIsaTupleT = std::tuple<std::string_view, Segment>;
3030
using KernelNameToSegmentMap = std::unordered_map<std::string, GPUSegment>;
3131

3232
GPUSegment varData;
3333
GPUSegment constData;
3434
CPUSegment stringData;
3535
KernelNameToSegmentMap nameToSegMap;
3636
Segments();
37-
Segments(const GraphicsAllocation *globalVarAlloc, const GraphicsAllocation *globalConstAlloc, ArrayRef<const uint8_t> &globalStrings, std::vector<KernelNameIsaPairT> &kernels);
37+
Segments(const GraphicsAllocation *globalVarAlloc, const GraphicsAllocation *globalConstAlloc, ArrayRef<const uint8_t> &globalStrings, std::vector<KernelNameIsaTupleT> &kernels);
3838
};
3939

4040
class DebugZebinCreator {

0 commit comments

Comments
 (0)