mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-09 22:43:00 +08:00
Support for symbol/relocation tables
Change-Id: I87890f6dc36a3454ffdcab1fb9d070fdaf91e689
This commit is contained in:
committed by
sys_ocldev
parent
b6792ef049
commit
ce061a48ef
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2017-2018 Intel Corporation
|
||||
# Copyright (C) 2017-2019 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
@@ -9,4 +9,8 @@ set(IGDRCL_SRCS_tests_compiler_interface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/binary_cache_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compiler_interface_tests.cpp
|
||||
)
|
||||
|
||||
get_property(NEO_CORE_COMPILER_INTERFACE_TESTS GLOBAL PROPERTY NEO_CORE_COMPILER_INTERFACE_TESTS)
|
||||
list(APPEND IGDRCL_SRCS_tests_compiler_interface ${NEO_CORE_COMPILER_INTERFACE_TESTS})
|
||||
|
||||
target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_compiler_interface})
|
||||
|
||||
@@ -94,6 +94,11 @@ TEST_P(KernelArgInfoTest, Create_Simple) {
|
||||
// included in the setup of fixture
|
||||
}
|
||||
|
||||
TEST_P(KernelArgInfoTest, WhenQueryingWithNullptrKernelNameTheniReturnNullptr) {
|
||||
auto kernelInfo = this->pProgram->getKernelInfo(nullptr);
|
||||
EXPECT_EQ(nullptr, kernelInfo);
|
||||
}
|
||||
|
||||
TEST_P(KernelArgInfoTest, getKernelArgAcessQualifier) {
|
||||
cl_kernel_arg_access_qualifier param_value = 0;
|
||||
queryArgInfo<cl_kernel_arg_access_qualifier>(CL_KERNEL_ARG_ACCESS_QUALIFIER, param_value);
|
||||
|
||||
@@ -436,6 +436,8 @@ class CommandStreamReceiverMock : public CommandStreamReceiver {
|
||||
typedef CommandStreamReceiver BaseClass;
|
||||
|
||||
public:
|
||||
using CommandStreamReceiver::executionEnvironment;
|
||||
|
||||
using BaseClass::CommandStreamReceiver;
|
||||
CommandStreamReceiverMock() : BaseClass(*(new ExecutionEnvironment)) {
|
||||
this->mockExecutionEnvironment.reset(&this->executionEnvironment);
|
||||
@@ -443,12 +445,16 @@ class CommandStreamReceiverMock : public CommandStreamReceiver {
|
||||
|
||||
void makeResident(GraphicsAllocation &graphicsAllocation) override {
|
||||
residency[graphicsAllocation.getUnderlyingBuffer()] = graphicsAllocation.getUnderlyingBufferSize();
|
||||
CommandStreamReceiver::makeResident(graphicsAllocation);
|
||||
if (passResidencyCallToBaseClass) {
|
||||
CommandStreamReceiver::makeResident(graphicsAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
void makeNonResident(GraphicsAllocation &graphicsAllocation) override {
|
||||
residency.erase(graphicsAllocation.getUnderlyingBuffer());
|
||||
CommandStreamReceiver::makeNonResident(graphicsAllocation);
|
||||
if (passResidencyCallToBaseClass) {
|
||||
CommandStreamReceiver::makeNonResident(graphicsAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
FlushStamp flush(BatchBuffer &batchBuffer, ResidencyContainer &allocationsForResidency) override {
|
||||
@@ -479,6 +485,7 @@ class CommandStreamReceiverMock : public CommandStreamReceiver {
|
||||
}
|
||||
|
||||
std::map<const void *, size_t> residency;
|
||||
bool passResidencyCallToBaseClass = true;
|
||||
std::unique_ptr<ExecutionEnvironment> mockExecutionEnvironment;
|
||||
};
|
||||
|
||||
@@ -1616,6 +1623,76 @@ HWTEST_F(KernelResidencyTest, givenKernelWhenMakeResidentIsCalledThenKernelIsaIs
|
||||
memoryManager->freeGraphicsMemory(pKernelInfo->kernelAllocation);
|
||||
}
|
||||
|
||||
HWTEST_F(KernelResidencyTest, givenKernelWhenMakeResidentIsCalledThenExportedFunctionsIsaAllocationIsMadeResident) {
|
||||
auto pKernelInfo = std::make_unique<KernelInfo>();
|
||||
auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver<FamilyType>();
|
||||
commandStreamReceiver.storeMakeResidentAllocations = true;
|
||||
|
||||
auto memoryManager = commandStreamReceiver.getMemoryManager();
|
||||
pKernelInfo->kernelAllocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{MemoryConstants::pageSize});
|
||||
|
||||
MockProgram program(*pDevice->getExecutionEnvironment());
|
||||
auto exportedFunctionsSurface = std::make_unique<MockGraphicsAllocation>();
|
||||
program.exportedFunctionsSurface = exportedFunctionsSurface.get();
|
||||
std::unique_ptr<MockKernel> pKernel(new MockKernel(&program, *pKernelInfo, *pDevice));
|
||||
ASSERT_EQ(CL_SUCCESS, pKernel->initialize());
|
||||
|
||||
EXPECT_EQ(0u, commandStreamReceiver.makeResidentAllocations.size());
|
||||
pKernel->makeResident(pDevice->getCommandStreamReceiver());
|
||||
EXPECT_TRUE(commandStreamReceiver.isMadeResident(program.exportedFunctionsSurface));
|
||||
|
||||
// check getResidency as well
|
||||
std::vector<NEO::Surface *> residencySurfaces;
|
||||
pKernel->getResidency(residencySurfaces);
|
||||
std::unique_ptr<NEO::ExecutionEnvironment> mockCsrExecEnv;
|
||||
{
|
||||
CommandStreamReceiverMock csrMock;
|
||||
csrMock.passResidencyCallToBaseClass = false;
|
||||
for (const auto &s : residencySurfaces) {
|
||||
s->makeResident(csrMock);
|
||||
delete s;
|
||||
}
|
||||
EXPECT_EQ(1U, csrMock.residency.count(exportedFunctionsSurface->getUnderlyingBuffer()));
|
||||
mockCsrExecEnv = std::move(csrMock.mockExecutionEnvironment);
|
||||
}
|
||||
|
||||
memoryManager->freeGraphicsMemory(pKernelInfo->kernelAllocation);
|
||||
}
|
||||
|
||||
HWTEST_F(KernelResidencyTest, givenKernelWhenMakeResidentIsCalledThenGlobalBufferIsMadeResident) {
|
||||
auto pKernelInfo = std::make_unique<KernelInfo>();
|
||||
auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver<FamilyType>();
|
||||
commandStreamReceiver.storeMakeResidentAllocations = true;
|
||||
|
||||
auto memoryManager = commandStreamReceiver.getMemoryManager();
|
||||
pKernelInfo->kernelAllocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{MemoryConstants::pageSize});
|
||||
|
||||
MockProgram program(*pDevice->getExecutionEnvironment());
|
||||
program.globalSurface = new MockGraphicsAllocation();
|
||||
std::unique_ptr<MockKernel> pKernel(new MockKernel(&program, *pKernelInfo, *pDevice));
|
||||
ASSERT_EQ(CL_SUCCESS, pKernel->initialize());
|
||||
|
||||
EXPECT_EQ(0u, commandStreamReceiver.makeResidentAllocations.size());
|
||||
pKernel->makeResident(pDevice->getCommandStreamReceiver());
|
||||
EXPECT_TRUE(commandStreamReceiver.isMadeResident(program.globalSurface));
|
||||
|
||||
std::vector<NEO::Surface *> residencySurfaces;
|
||||
pKernel->getResidency(residencySurfaces);
|
||||
std::unique_ptr<NEO::ExecutionEnvironment> mockCsrExecEnv;
|
||||
{
|
||||
CommandStreamReceiverMock csrMock;
|
||||
csrMock.passResidencyCallToBaseClass = false;
|
||||
for (const auto &s : residencySurfaces) {
|
||||
s->makeResident(csrMock);
|
||||
delete s;
|
||||
}
|
||||
EXPECT_EQ(1U, csrMock.residency.count(program.globalSurface->getUnderlyingBuffer()));
|
||||
mockCsrExecEnv = std::move(csrMock.mockExecutionEnvironment);
|
||||
}
|
||||
|
||||
memoryManager->freeGraphicsMemory(pKernelInfo->kernelAllocation);
|
||||
}
|
||||
|
||||
HWTEST_F(KernelResidencyTest, givenKernelWhenItUsesIndirectUnifiedMemoryDeviceAllocationThenTheyAreMadeResident) {
|
||||
MockKernelWithInternals mockKernel(*this->pDevice);
|
||||
auto &commandStreamReceiver = this->pDevice->getUltCommandStreamReceiver<FamilyType>();
|
||||
|
||||
@@ -25,25 +25,35 @@ class GraphicsAllocation;
|
||||
class MockProgram : public Program {
|
||||
public:
|
||||
using Program::createProgramFromBinary;
|
||||
using Program::getKernelNamesString;
|
||||
using Program::getProgramCompilerVersion;
|
||||
using Program::isKernelDebugEnabled;
|
||||
using Program::linkBinary;
|
||||
using Program::prepareLinkerInputStorage;
|
||||
using Program::rebuildProgramFromIr;
|
||||
using Program::resolveProgramBinary;
|
||||
using Program::updateNonUniformFlag;
|
||||
|
||||
using Program::areSpecializationConstantsInitialized;
|
||||
using Program::constantSurface;
|
||||
using Program::context;
|
||||
using Program::elfBinary;
|
||||
using Program::elfBinarySize;
|
||||
using Program::exportedFunctionsSurface;
|
||||
using Program::genBinary;
|
||||
using Program::genBinarySize;
|
||||
using Program::globalSurface;
|
||||
using Program::irBinary;
|
||||
using Program::irBinarySize;
|
||||
using Program::isProgramBinaryResolved;
|
||||
using Program::isSpirV;
|
||||
using Program::linkerInput;
|
||||
using Program::pDevice;
|
||||
using Program::programBinaryType;
|
||||
using Program::specConstantsIds;
|
||||
using Program::specConstantsSizes;
|
||||
using Program::specConstantsValues;
|
||||
using Program::symbols;
|
||||
|
||||
using Program::sourceCode;
|
||||
|
||||
|
||||
@@ -108,18 +108,24 @@ TEST_F(KernelDataTest, PrintfString) {
|
||||
iOpenCL::SPatchString printfString;
|
||||
printfString.Token = PATCH_TOKEN_STRING;
|
||||
printfString.Size = static_cast<uint32_t>(sizeof(SPatchString) + strSize);
|
||||
|
||||
printfString.Index = 0;
|
||||
printfString.StringSize = static_cast<uint32_t>(strSize);
|
||||
|
||||
cl_char *pPrintfString = new cl_char[printfString.Size];
|
||||
iOpenCL::SPatchString emptyString;
|
||||
emptyString.Token = PATCH_TOKEN_STRING;
|
||||
emptyString.Size = static_cast<uint32_t>(sizeof(SPatchString));
|
||||
emptyString.Index = 1;
|
||||
emptyString.StringSize = 0;
|
||||
|
||||
cl_char *pPrintfString = new cl_char[printfString.Size + emptyString.Size];
|
||||
|
||||
memcpy_s(pPrintfString, sizeof(SPatchString), &printfString, sizeof(SPatchString));
|
||||
|
||||
memcpy_s((cl_char *)pPrintfString + sizeof(printfString), strSize, stringValue, strSize);
|
||||
|
||||
memcpy_s((cl_char *)pPrintfString + printfString.Size, emptyString.Size, &emptyString, emptyString.Size);
|
||||
|
||||
pPatchList = (void *)pPrintfString;
|
||||
patchListSize = printfString.Size;
|
||||
patchListSize = printfString.Size + emptyString.Size;
|
||||
|
||||
buildAndDecode();
|
||||
|
||||
@@ -1387,3 +1393,31 @@ TEST_F(KernelDataTest, PATCH_TOKEN_ALLOCATE_SIP_SURFACE) {
|
||||
EXPECT_EQ(token.Token, pKernelInfo->patchInfo.pAllocateSystemThreadSurface->Token);
|
||||
EXPECT_EQ(token.PerThreadSystemThreadSurfaceSize, pKernelInfo->patchInfo.pAllocateSystemThreadSurface->PerThreadSystemThreadSurfaceSize);
|
||||
}
|
||||
|
||||
TEST_F(KernelDataTest, givenSymbolTablePatchTokenThenLinkerInputIsCreated) {
|
||||
SPatchFunctionTableInfo token;
|
||||
token.Token = PATCH_TOKEN_PROGRAM_SYMBOL_TABLE;
|
||||
token.Size = static_cast<uint32_t>(sizeof(SPatchFunctionTableInfo));
|
||||
token.NumEntries = 0;
|
||||
|
||||
pPatchList = &token;
|
||||
patchListSize = token.Size;
|
||||
|
||||
buildAndDecode();
|
||||
|
||||
EXPECT_NE(nullptr, program->linkerInput);
|
||||
}
|
||||
|
||||
TEST_F(KernelDataTest, givenRelocationTablePatchTokenThenLinkerInputIsCreated) {
|
||||
SPatchFunctionTableInfo token;
|
||||
token.Token = PATCH_TOKEN_PROGRAM_RELOCATION_TABLE;
|
||||
token.Size = static_cast<uint32_t>(sizeof(SPatchFunctionTableInfo));
|
||||
token.NumEntries = 0;
|
||||
|
||||
pPatchList = &token;
|
||||
patchListSize = token.Size;
|
||||
|
||||
buildAndDecode();
|
||||
|
||||
EXPECT_NE(nullptr, program->linkerInput);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/unit_tests/compiler_interface/linker_mock.h"
|
||||
#include "runtime/helpers/string.h"
|
||||
#include "runtime/memory_manager/allocations_list.h"
|
||||
#include "runtime/memory_manager/graphics_allocation.h"
|
||||
#include "runtime/memory_manager/svm_memory_manager.h"
|
||||
#include "runtime/platform/platform.h"
|
||||
#include "runtime/program/program.h"
|
||||
#include "test.h"
|
||||
@@ -22,17 +24,17 @@ using namespace iOpenCL;
|
||||
static const char constValue[] = "11223344";
|
||||
static const char globalValue[] = "55667788";
|
||||
|
||||
class ProgramDataTest : public testing::Test,
|
||||
public ContextFixture,
|
||||
public PlatformFixture,
|
||||
public ProgramFixture {
|
||||
template <typename ProgramType>
|
||||
class ProgramDataTestBase : public testing::Test,
|
||||
public ContextFixture,
|
||||
public PlatformFixture,
|
||||
public ProgramFixture {
|
||||
|
||||
using ContextFixture::SetUp;
|
||||
using PlatformFixture::SetUp;
|
||||
|
||||
public:
|
||||
ProgramDataTest() {
|
||||
|
||||
ProgramDataTestBase() {
|
||||
memset(&programBinaryHeader, 0x00, sizeof(SProgramBinaryHeader));
|
||||
pCurPtr = nullptr;
|
||||
pProgramPatchList = nullptr;
|
||||
@@ -48,7 +50,7 @@ class ProgramDataTest : public testing::Test,
|
||||
ContextFixture::SetUp(1, &device);
|
||||
ProgramFixture::SetUp();
|
||||
|
||||
CreateProgramWithSource(
|
||||
CreateProgramWithSource<ProgramType>(
|
||||
pContext,
|
||||
&device,
|
||||
"CopyBuffer_simd8.cl");
|
||||
@@ -120,7 +122,8 @@ class ProgramDataTest : public testing::Test,
|
||||
uint32_t programPatchListSize;
|
||||
};
|
||||
|
||||
void ProgramDataTest::buildAndDecodeProgramPatchList() {
|
||||
template <typename ProgramType>
|
||||
void ProgramDataTestBase<ProgramType>::buildAndDecodeProgramPatchList() {
|
||||
size_t headerSize = sizeof(SProgramBinaryHeader);
|
||||
|
||||
cl_int error = CL_SUCCESS;
|
||||
@@ -154,6 +157,9 @@ void ProgramDataTest::buildAndDecodeProgramPatchList() {
|
||||
delete[] pProgramData;
|
||||
}
|
||||
|
||||
using ProgramDataTest = ProgramDataTestBase<NEO::Program>;
|
||||
using MockProgramDataTest = ProgramDataTestBase<MockProgram>;
|
||||
|
||||
TEST_F(ProgramDataTest, EmptyProgramBinaryHeader) {
|
||||
buildAndDecodeProgramPatchList();
|
||||
}
|
||||
@@ -168,6 +174,113 @@ TEST_F(ProgramDataTest, AllocateConstantMemorySurfaceProgramBinaryInfo) {
|
||||
EXPECT_EQ(0, memcmp(constValue, reinterpret_cast<char *>(pProgram->getConstantSurface()->getUnderlyingBuffer()), constSize));
|
||||
}
|
||||
|
||||
TEST_F(MockProgramDataTest, whenGlobalConstantsAreExportedThenAllocateSurfacesAsSvm) {
|
||||
if (this->pContext->getSVMAllocsManager() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
setupConstantAllocation();
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalConstants = true;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getConstantSurface());
|
||||
EXPECT_NE(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getConstantSurface()->getGpuAddress())));
|
||||
}
|
||||
|
||||
TEST_F(MockProgramDataTest, whenGlobalConstantsAreNotExportedThenAllocateSurfacesAsNonSvm) {
|
||||
if (this->pContext->getSVMAllocsManager() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
setupConstantAllocation();
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalConstants = false;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
static_cast<MockProgram *>(pProgram)->context = nullptr;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
static_cast<MockProgram *>(pProgram)->context = pContext;
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getConstantSurface());
|
||||
EXPECT_EQ(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getConstantSurface()->getGpuAddress())));
|
||||
}
|
||||
|
||||
TEST_F(MockProgramDataTest, whenGlobalConstantsAreExportedButContextUnavailableThenAllocateSurfacesAsNonSvm) {
|
||||
if (this->pContext->getSVMAllocsManager() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
setupConstantAllocation();
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalConstants = true;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
static_cast<MockProgram *>(pProgram)->context = nullptr;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
static_cast<MockProgram *>(pProgram)->context = pContext;
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getConstantSurface());
|
||||
EXPECT_EQ(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getConstantSurface()->getGpuAddress())));
|
||||
}
|
||||
|
||||
TEST_F(MockProgramDataTest, whenGlobalVariablesAreExportedThenAllocateSurfacesAsSvm) {
|
||||
if (this->pContext->getSVMAllocsManager() == nullptr) {
|
||||
return;
|
||||
}
|
||||
setupGlobalAllocation();
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalVariables = true;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getGlobalSurface());
|
||||
EXPECT_NE(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getGlobalSurface()->getGpuAddress())));
|
||||
}
|
||||
|
||||
TEST_F(MockProgramDataTest, whenGlobalVariablesAreExportedButContextUnavailableThenAllocateSurfacesAsNonSvm) {
|
||||
if (this->pContext->getSVMAllocsManager() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
setupGlobalAllocation();
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalVariables = true;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
static_cast<MockProgram *>(pProgram)->context = nullptr;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
static_cast<MockProgram *>(pProgram)->context = pContext;
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getGlobalSurface());
|
||||
EXPECT_EQ(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getGlobalSurface()->getGpuAddress())));
|
||||
}
|
||||
|
||||
TEST_F(MockProgramDataTest, whenGlobalVariablesAreNotExportedThenAllocateSurfacesAsNonSvm) {
|
||||
if (this->pContext->getSVMAllocsManager() == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
setupGlobalAllocation();
|
||||
std::unique_ptr<WhiteBox<NEO::LinkerInput>> mockLinkerInput = std::make_unique<WhiteBox<NEO::LinkerInput>>();
|
||||
mockLinkerInput->traits.exportsGlobalVariables = false;
|
||||
static_cast<MockProgram *>(pProgram)->linkerInput = std::move(mockLinkerInput);
|
||||
static_cast<MockProgram *>(pProgram)->context = nullptr;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
static_cast<MockProgram *>(pProgram)->context = pContext;
|
||||
|
||||
ASSERT_NE(nullptr, pProgram->getGlobalSurface());
|
||||
EXPECT_EQ(nullptr, this->pContext->getSVMAllocsManager()->getSVMAlloc(reinterpret_cast<const void *>(pProgram->getGlobalSurface()->getGpuAddress())));
|
||||
}
|
||||
|
||||
TEST_F(ProgramDataTest, givenConstantAllocationThatIsInUseByGpuWhenProgramIsBeingDestroyedThenItIsAddedToTemporaryAllocationList) {
|
||||
|
||||
setupConstantAllocation();
|
||||
@@ -676,3 +789,122 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeGlobalPoi
|
||||
globalSurface.mockGfxAllocation.set32BitAllocation(false);
|
||||
prog->setGlobalSurface(nullptr);
|
||||
}
|
||||
|
||||
TEST_F(ProgramDataTest, givenSymbolTablePatchTokenThenLinkerInputIsCreated) {
|
||||
SPatchFunctionTableInfo token;
|
||||
token.Token = PATCH_TOKEN_PROGRAM_SYMBOL_TABLE;
|
||||
token.Size = static_cast<uint32_t>(sizeof(SPatchFunctionTableInfo));
|
||||
token.NumEntries = 0;
|
||||
|
||||
pProgramPatchList = &token;
|
||||
programPatchListSize = token.Size;
|
||||
|
||||
buildAndDecodeProgramPatchList();
|
||||
|
||||
EXPECT_NE(nullptr, pProgram->getLinkerInput());
|
||||
}
|
||||
|
||||
TEST(ProgramLinkBinaryTest, whenLinkerInputEmptyThenLinkSuccessful) {
|
||||
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
|
||||
NEO::ExecutionEnvironment env;
|
||||
MockProgram program{env};
|
||||
program.linkerInput = std::move(linkerInput);
|
||||
auto ret = program.linkBinary();
|
||||
EXPECT_EQ(CL_SUCCESS, ret);
|
||||
}
|
||||
|
||||
TEST(ProgramLinkBinaryTest, whenLinkerUnresolvedExternalThenLinkFailedAndBuildLogAvailable) {
|
||||
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
|
||||
NEO::LinkerInput::RelocationInfo relocation = {};
|
||||
relocation.symbolName = "A";
|
||||
relocation.offset = 0;
|
||||
linkerInput->relocations.push_back(NEO::LinkerInput::Relocations{relocation});
|
||||
linkerInput->traits.requiresPatchingOfInstructionSegments = true;
|
||||
NEO::ExecutionEnvironment env;
|
||||
MockProgram program{env};
|
||||
KernelInfo kernelInfo = {};
|
||||
kernelInfo.name = "onlyKernel";
|
||||
std::vector<char> kernelHeap;
|
||||
kernelHeap.resize(32, 7);
|
||||
kernelInfo.heapInfo.pKernelHeap = kernelHeap.data();
|
||||
iOpenCL::SKernelBinaryHeaderCommon kernelHeader = {};
|
||||
kernelHeader.KernelHeapSize = static_cast<uint32_t>(kernelHeap.size());
|
||||
kernelInfo.heapInfo.pKernelHeader = &kernelHeader;
|
||||
program.getKernelInfoArray().push_back(&kernelInfo);
|
||||
program.linkerInput = std::move(linkerInput);
|
||||
|
||||
EXPECT_EQ(nullptr, program.getBuildLog(nullptr));
|
||||
auto ret = program.linkBinary();
|
||||
EXPECT_NE(CL_SUCCESS, ret);
|
||||
program.getKernelInfoArray().clear();
|
||||
auto buildLog = program.getBuildLog(nullptr);
|
||||
ASSERT_NE(nullptr, buildLog);
|
||||
Linker::UnresolvedExternals expectedUnresolvedExternals;
|
||||
expectedUnresolvedExternals.push_back(Linker::UnresolvedExternal{relocation, 0, false});
|
||||
auto expectedError = constructLinkerErrorMessage(expectedUnresolvedExternals, std::vector<std::string>{"kernel : " + kernelInfo.name});
|
||||
EXPECT_THAT(buildLog, ::testing::HasSubstr(expectedError));
|
||||
}
|
||||
|
||||
TEST(ProgramLinkBinaryTest, whenPrepareLinkerInputStorageGetsCalledTwiceThenLinkerInputStorageIsReused) {
|
||||
ExecutionEnvironment execEnv;
|
||||
MockProgram program{execEnv};
|
||||
EXPECT_EQ(nullptr, program.linkerInput);
|
||||
program.prepareLinkerInputStorage();
|
||||
EXPECT_NE(nullptr, program.linkerInput);
|
||||
auto prevLinkerInput = program.getLinkerInput();
|
||||
program.prepareLinkerInputStorage();
|
||||
EXPECT_EQ(prevLinkerInput, program.linkerInput.get());
|
||||
}
|
||||
|
||||
TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) {
|
||||
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
|
||||
linkerInput->symbols["A"] = NEO::SymbolInfo{4U, 4U, NEO::SymbolInfo::GlobalVariable};
|
||||
linkerInput->symbols["B"] = NEO::SymbolInfo{8U, 4U, NEO::SymbolInfo::GlobalConstant};
|
||||
linkerInput->symbols["C"] = NEO::SymbolInfo{16U, 4U, NEO::SymbolInfo::Function};
|
||||
|
||||
linkerInput->relocations.push_back({NEO::LinkerInput::RelocationInfo{"A", 8U}, NEO::LinkerInput::RelocationInfo{"B", 16U}, NEO::LinkerInput::RelocationInfo{"C", 24U}});
|
||||
linkerInput->traits.requiresPatchingOfInstructionSegments = true;
|
||||
linkerInput->exportedFunctionsSegmentId = 0;
|
||||
NEO::ExecutionEnvironment env;
|
||||
MockProgram program{env};
|
||||
KernelInfo kernelInfo = {};
|
||||
kernelInfo.name = "onlyKernel";
|
||||
std::vector<char> kernelHeap;
|
||||
kernelHeap.resize(32, 7);
|
||||
kernelInfo.heapInfo.pKernelHeap = kernelHeap.data();
|
||||
iOpenCL::SKernelBinaryHeaderCommon kernelHeader = {};
|
||||
kernelHeader.KernelHeapSize = static_cast<uint32_t>(kernelHeap.size());
|
||||
kernelInfo.heapInfo.pKernelHeader = &kernelHeader;
|
||||
MockGraphicsAllocation kernelIsa(kernelHeap.data(), kernelHeap.size());
|
||||
kernelInfo.kernelAllocation = &kernelIsa;
|
||||
program.getKernelInfoArray().push_back(&kernelInfo);
|
||||
program.linkerInput = std::move(linkerInput);
|
||||
|
||||
program.exportedFunctionsSurface = kernelInfo.kernelAllocation;
|
||||
std::vector<char> globalVariablesBuffer;
|
||||
globalVariablesBuffer.resize(32, 7);
|
||||
std::vector<char> globalConstantsBuffer;
|
||||
globalConstantsBuffer.resize(32, 7);
|
||||
program.globalSurface = new MockGraphicsAllocation(globalVariablesBuffer.data(), globalVariablesBuffer.size());
|
||||
program.constantSurface = new MockGraphicsAllocation(globalConstantsBuffer.data(), globalConstantsBuffer.size());
|
||||
|
||||
program.pDevice = this->pContext->getDevice(0);
|
||||
|
||||
auto ret = program.linkBinary();
|
||||
EXPECT_EQ(CL_SUCCESS, ret);
|
||||
|
||||
linkerInput.reset(static_cast<WhiteBox<LinkerInput> *>(program.linkerInput.release()));
|
||||
|
||||
for (size_t i = 0; i < linkerInput->relocations.size(); ++i) {
|
||||
auto expectedPatch = program.globalSurface->getGpuAddress() + linkerInput->symbols[linkerInput->relocations[0][0].symbolName].offset;
|
||||
auto relocationAddress = kernelHeap.data() + linkerInput->relocations[0][0].offset;
|
||||
|
||||
EXPECT_EQ(static_cast<uintptr_t>(expectedPatch), *reinterpret_cast<uintptr_t *>(relocationAddress)) << i;
|
||||
}
|
||||
|
||||
program.getKernelInfoArray().clear();
|
||||
delete program.globalSurface;
|
||||
program.globalSurface = nullptr;
|
||||
delete program.constantSurface;
|
||||
program.constantSurface = nullptr;
|
||||
}
|
||||
|
||||
@@ -2923,6 +2923,12 @@ TEST_F(ProgramTests, givenProgramWhenUnknownInternalOptionsArePassedThenTheyAreN
|
||||
EXPECT_TRUE(buildOptions == internalOption);
|
||||
}
|
||||
|
||||
TEST_F(ProgramTests, givenProgramWhenGetSymbolsIsCalledThenMapWithExportedSymbolsIsReturned) {
|
||||
ExecutionEnvironment executionEnvironment;
|
||||
MockProgram program(executionEnvironment);
|
||||
EXPECT_EQ(&program.symbols, &program.getSymbols());
|
||||
}
|
||||
|
||||
class AdditionalOptionsMockProgram : public MockProgram {
|
||||
public:
|
||||
AdditionalOptionsMockProgram() : MockProgram(executionEnvironment) {}
|
||||
@@ -3011,6 +3017,19 @@ TEST(RebuildProgramFromIrTests, givenBinaryProgramWhenKernelRebulildIsNotForcedT
|
||||
EXPECT_FALSE(pProgram->rebuildProgramFromIrCalled);
|
||||
}
|
||||
|
||||
TEST(Program, whenGetKernelNamesStringIsCalledThenNamesAreProperlyConcatenated) {
|
||||
ExecutionEnvironment execEnv;
|
||||
MockProgram program{execEnv};
|
||||
KernelInfo kernel1 = {};
|
||||
kernel1.name = "kern1";
|
||||
KernelInfo kernel2 = {};
|
||||
kernel2.name = "kern2";
|
||||
program.getKernelInfoArray().push_back(&kernel1);
|
||||
program.getKernelInfoArray().push_back(&kernel2);
|
||||
EXPECT_EQ("kern1;kern2", program.getKernelNamesString());
|
||||
program.getKernelInfoArray().clear();
|
||||
}
|
||||
|
||||
struct SpecializationConstantProgramMock : public MockProgram {
|
||||
using MockProgram::MockProgram;
|
||||
cl_int updateSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue) override {
|
||||
|
||||
Reference in New Issue
Block a user