test: add missing ult for checking patch address in heapless mode OCL

Signed-off-by: Kamil Kopryk <kamil.kopryk@intel.com>
This commit is contained in:
Kamil Kopryk
2024-05-20 13:26:09 +00:00
committed by Compute-Runtime-Automation
parent 49cc1a0ba0
commit 101c914b1f
4 changed files with 83 additions and 59 deletions

View File

@@ -25,6 +25,7 @@
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/mock_file_io.h"
#include "shared/test/common/libult/ult_command_stream_receiver.h"
#include "shared/test/common/mocks/mock_compiler_product_helper.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_elf.h"
#include "shared/test/common/mocks/mock_graphics_allocation.h"
@@ -1879,22 +1880,11 @@ TEST_F(ModuleDynamicLinkTests, givenModuleWithInternalRelocationAndUnresolvedExt
EXPECT_EQ(externalSymbolAddress, *reinterpret_cast<uint64_t *>(ptrOffset(isaPtr, externalRelocationOffset)));
}
template <PRODUCT_FAMILY productFamily>
class MockCompilerProductHelperHw : public CompilerProductHelperHw<productFamily> {
public:
bool isHeaplessModeEnabled() const override {
return heaplessModeEnabled;
}
MockCompilerProductHelperHw(bool heaplessModeEnabled) : CompilerProductHelperHw<productFamily>(), heaplessModeEnabled(heaplessModeEnabled) {}
bool heaplessModeEnabled = false;
};
HWTEST2_F(ModuleDynamicLinkTests, givenHeaplessAndModuleWithInternalRelocationAndUnresolvedExternalSymbolWhenLinkModuleThenPatchedAddressesAreCorrect, MatchAny) {
for (bool heaplessModeEnabled : {true, false}) {
auto backup = std::unique_ptr<CompilerProductHelper>(new MockCompilerProductHelperHw<productFamily>(heaplessModeEnabled));
auto backup = std::unique_ptr<CompilerProductHelper>(new MockCompilerProductHelperHeaplessHw<productFamily>(heaplessModeEnabled));
neoDevice->getRootDeviceEnvironmentRef().compilerProductHelper.swap(backup);
auto linkerInput = std::make_unique<::WhiteBox<NEO::LinkerInput>>();
@@ -1941,7 +1931,7 @@ HWTEST2_F(ModuleDynamicLinkTests, givenHeaplessAndModuleWithInternalRelocationAn
for (bool heaplessModeEnabled : {true, false}) {
auto backup = std::unique_ptr<CompilerProductHelper>(new MockCompilerProductHelperHw<productFamily>(heaplessModeEnabled));
auto backup = std::unique_ptr<CompilerProductHelper>(new MockCompilerProductHelperHeaplessHw<productFamily>(heaplessModeEnabled));
neoDevice->getRootDeviceEnvironmentRef().compilerProductHelper.swap(backup);
auto linkerInput = std::make_unique<::WhiteBox<NEO::LinkerInput>>();

View File

@@ -16,6 +16,7 @@
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/gtest_helpers.h"
#include "shared/test/common/mocks/mock_bindless_heaps_helper.h"
#include "shared/test/common/mocks/mock_compiler_product_helper.h"
#include "shared/test/common/mocks/mock_csr.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/mocks/mock_memory_manager.h"
@@ -705,59 +706,69 @@ TEST(ProgramLinkBinaryTest, whenLinkerUnresolvedExternalThenLinkFailedAndBuildLo
device->getMemoryManager()->freeGraphicsMemory(kernelInfo.getGraphicsAllocation());
}
TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) {
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
linkerInput->symbols["A"] = NEO::SymbolInfo{4U, 4U, NEO::SegmentType::globalVariables, std::numeric_limits<uint32_t>::max(), true};
linkerInput->symbols["B"] = NEO::SymbolInfo{8U, 4U, NEO::SegmentType::globalConstants, std::numeric_limits<uint32_t>::max(), true};
linkerInput->symbols["C"] = NEO::SymbolInfo{16U, 4U, NEO::SegmentType::instructions, std::numeric_limits<uint32_t>::max(), true};
HWTEST2_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched, MatchAny) {
auto relocationType = NEO::LinkerInput::RelocationInfo::Type::address;
linkerInput->textRelocations.push_back({NEO::LinkerInput::RelocationInfo{"A", 8U, relocationType},
NEO::LinkerInput::RelocationInfo{"B", 16U, relocationType},
NEO::LinkerInput::RelocationInfo{"C", 24U, relocationType}});
linkerInput->traits.requiresPatchingOfInstructionSegments = true;
linkerInput->exportedFunctionsSegmentId = 0;
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
MockProgram program{nullptr, false, toClDeviceVector(*device)};
auto &buildInfo = program.buildInfos[device->getRootDeviceIndex()];
KernelInfo kernelInfo = {};
kernelInfo.kernelDescriptor.kernelMetadata.kernelName = "onlyKernel";
std::vector<char> kernelHeap;
kernelHeap.resize(32, 7);
kernelInfo.heapInfo.pKernelHeap = kernelHeap.data();
kernelInfo.heapInfo.kernelHeapSize = static_cast<uint32_t>(kernelHeap.size());
MockGraphicsAllocation kernelIsa(kernelHeap.data(), kernelHeap.size());
kernelInfo.kernelAllocation = &kernelIsa;
program.getKernelInfoArray(rootDeviceIndex).push_back(&kernelInfo);
program.setLinkerInput(device->getRootDeviceIndex(), std::move(linkerInput));
for (bool heaplessModeEnabled : {false, true}) {
buildInfo.exportedFunctionsSurface = kernelInfo.kernelAllocation;
std::vector<char> globalVariablesBuffer;
globalVariablesBuffer.resize(32, 7);
std::vector<char> globalConstantsBuffer;
globalConstantsBuffer.resize(32, 7);
std::vector<char> globalVariablesInitData{32, 0};
std::vector<char> globalConstantsInitData{32, 0};
buildInfo.globalSurface = new MockGraphicsAllocation(globalVariablesBuffer.data(), globalVariablesBuffer.size());
buildInfo.constantSurface = new MockGraphicsAllocation(globalConstantsBuffer.data(), globalConstantsBuffer.size());
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
auto backup = std::unique_ptr<CompilerProductHelper>(new MockCompilerProductHelperHeaplessHw<productFamily>(heaplessModeEnabled));
device->device.getRootDeviceEnvironmentRef().compilerProductHelper.swap(backup);
auto ret = program.linkBinary(&pClDevice->getDevice(), globalConstantsInitData.data(), globalConstantsInitData.size(), globalVariablesInitData.data(), globalVariablesInitData.size(), {}, program.externalFunctions);
EXPECT_EQ(CL_SUCCESS, ret);
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
linkerInput->symbols["A"] = NEO::SymbolInfo{4U, 4U, NEO::SegmentType::globalVariables, std::numeric_limits<uint32_t>::max(), true};
linkerInput->symbols["B"] = NEO::SymbolInfo{8U, 4U, NEO::SegmentType::globalConstants, std::numeric_limits<uint32_t>::max(), true};
linkerInput->symbols["C"] = NEO::SymbolInfo{16U, 4U, NEO::SegmentType::instructions, std::numeric_limits<uint32_t>::max(), true};
linkerInput.reset(static_cast<WhiteBox<LinkerInput> *>(buildInfo.linkerInput.release()));
auto relocationType = NEO::LinkerInput::RelocationInfo::Type::address;
linkerInput->textRelocations.push_back({NEO::LinkerInput::RelocationInfo{"A", 8U, relocationType},
NEO::LinkerInput::RelocationInfo{"B", 16U, relocationType},
NEO::LinkerInput::RelocationInfo{"C", 24U, relocationType}});
linkerInput->traits.requiresPatchingOfInstructionSegments = true;
linkerInput->exportedFunctionsSegmentId = 0;
for (size_t i = 0; i < linkerInput->textRelocations.size(); ++i) {
auto expectedPatch = buildInfo.globalSurface->getGpuAddress() + linkerInput->symbols[linkerInput->textRelocations[0][0].symbolName].offset;
auto relocationAddress = kernelHeap.data() + linkerInput->textRelocations[0][0].offset;
MockProgram program{nullptr, false, toClDeviceVector(*device)};
auto &buildInfo = program.buildInfos[device->getRootDeviceIndex()];
KernelInfo kernelInfo = {};
kernelInfo.kernelDescriptor.kernelMetadata.kernelName = "onlyKernel";
std::vector<char> kernelHeap;
kernelHeap.resize(32, 7);
kernelInfo.heapInfo.pKernelHeap = kernelHeap.data();
kernelInfo.heapInfo.kernelHeapSize = static_cast<uint32_t>(kernelHeap.size());
MockGraphicsAllocation kernelIsa(kernelHeap.data(), kernelHeap.size());
kernelInfo.kernelAllocation = &kernelIsa;
program.getKernelInfoArray(rootDeviceIndex).push_back(&kernelInfo);
program.setLinkerInput(device->getRootDeviceIndex(), std::move(linkerInput));
EXPECT_EQ(static_cast<uintptr_t>(expectedPatch), *reinterpret_cast<uintptr_t *>(relocationAddress)) << i;
buildInfo.exportedFunctionsSurface = kernelInfo.kernelAllocation;
std::vector<char> globalVariablesBuffer;
globalVariablesBuffer.resize(32, 7);
std::vector<char> globalConstantsBuffer;
globalConstantsBuffer.resize(32, 7);
std::vector<char> globalVariablesInitData{32, 0};
std::vector<char> globalConstantsInitData{32, 0};
auto globalSurface = std::make_unique<MockGraphicsAllocation>(globalVariablesBuffer.data(), globalVariablesBuffer.size());
auto constantSurface = std::make_unique<MockGraphicsAllocation>(globalConstantsBuffer.data(), globalConstantsBuffer.size());
buildInfo.globalSurface = globalSurface.get();
buildInfo.constantSurface = constantSurface.get();
auto ret = program.linkBinary(&pClDevice->getDevice(), globalConstantsInitData.data(), globalConstantsInitData.size(), globalVariablesInitData.data(), globalVariablesInitData.size(), {}, program.externalFunctions);
EXPECT_EQ(CL_SUCCESS, ret);
linkerInput.reset(static_cast<WhiteBox<LinkerInput> *>(buildInfo.linkerInput.release()));
for (size_t i = 0; i < linkerInput->textRelocations.size(); ++i) {
auto expectedPatch = buildInfo.globalSurface->getGpuAddress() + linkerInput->symbols[linkerInput->textRelocations[0][0].symbolName].offset;
auto relocationAddress = kernelHeap.data() + linkerInput->textRelocations[0][0].offset;
EXPECT_EQ(static_cast<uintptr_t>(expectedPatch), *reinterpret_cast<uintptr_t *>(relocationAddress)) << i;
}
program.getKernelInfoArray(rootDeviceIndex).clear();
buildInfo.globalSurface = nullptr;
buildInfo.constantSurface = nullptr;
device->device.getRootDeviceEnvironmentRef().compilerProductHelper.swap(backup);
}
program.getKernelInfoArray(rootDeviceIndex).clear();
delete buildInfo.globalSurface;
buildInfo.globalSurface = nullptr;
delete buildInfo.constantSurface;
buildInfo.constantSurface = nullptr;
}
TEST_F(ProgramDataTest, whenRelocationsAreNotNeededThenIsaIsPreserved) {

View File

@@ -36,6 +36,7 @@ set(NEO_CORE_tests_mocks
${CMAKE_CURRENT_SOURCE_DIR}/mock_compiler_cache.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_compiler_interface_spirv.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_compiler_interface_spirv.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_compiler_product_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_compilers.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_compilers.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_cpu_page_fault_manager.h

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/compiler_product_helper.h"
namespace NEO {
template <PRODUCT_FAMILY productFamily>
class MockCompilerProductHelperHeaplessHw : public CompilerProductHelperHw<productFamily> {
public:
bool isHeaplessModeEnabled() const override {
return heaplessModeEnabled;
}
MockCompilerProductHelperHeaplessHw(bool heaplessModeEnabled) : CompilerProductHelperHw<productFamily>(), heaplessModeEnabled(heaplessModeEnabled) {}
bool heaplessModeEnabled = false;
};
} // namespace NEO