Move symbols and linkerInput from Program to BuildInfo

these members should be kept per root device

Related-To: NEO-5001
Change-Id: Ie5e06deed234706cc41943d3c5e932c7d877127b
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2020-09-08 18:23:10 +02:00
committed by sys_ocldev
parent 88ee48498b
commit b52aec07dd
8 changed files with 79 additions and 67 deletions

View File

@ -5320,14 +5320,15 @@ cl_int CL_API_CALL clGetDeviceGlobalVariablePointerINTEL(
DBG_LOG_INPUTS("device", device, "program", program,
"globalVariableName", globalVariableName,
"globalVariablePointerRet", globalVariablePointerRet);
retVal = validateObjects(device, program);
Program *pProgram = nullptr;
ClDevice *pDevice = nullptr;
retVal = validateObjects(WithCastToInternal(program, &pProgram), WithCastToInternal(device, &pDevice));
if (globalVariablePointerRet == nullptr) {
retVal = CL_INVALID_ARG_VALUE;
}
if (CL_SUCCESS == retVal) {
Program *pProgram = (Program *)(program);
const auto &symbols = pProgram->getSymbols();
const auto &symbols = pProgram->getSymbols(pDevice->getRootDeviceIndex());
auto symbolIt = symbols.find(globalVariableName);
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.segment == NEO::SegmentType::Instructions)) {
retVal = CL_INVALID_ARG_VALUE;
@ -5352,14 +5353,16 @@ cl_int CL_API_CALL clGetDeviceFunctionPointerINTEL(
DBG_LOG_INPUTS("device", device, "program", program,
"functionName", functionName,
"functionPointerRet", functionPointerRet);
retVal = validateObjects(device, program);
Program *pProgram = nullptr;
ClDevice *pDevice = nullptr;
retVal = validateObjects(WithCastToInternal(program, &pProgram), WithCastToInternal(device, &pDevice));
if ((CL_SUCCESS == retVal) && (functionPointerRet == nullptr)) {
retVal = CL_INVALID_ARG_VALUE;
}
if (CL_SUCCESS == retVal) {
Program *pProgram = (Program *)(program);
const auto &symbols = pProgram->getSymbols();
const auto &symbols = pProgram->getSymbols(pDevice->getRootDeviceIndex());
auto symbolIt = symbols.find(functionName);
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.segment != NEO::SegmentType::Instructions)) {
retVal = CL_INVALID_ARG_VALUE;

View File

@ -52,6 +52,7 @@ const KernelInfo *Program::getKernelInfo(size_t ordinal) const {
}
cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const void *variablesInitData) {
auto linkerInput = pDevice ? getLinkerInput(pDevice->getRootDeviceIndex()) : nullptr;
if (linkerInput == nullptr) {
return CL_SUCCESS;
}
@ -69,9 +70,9 @@ cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const
constants.gpuAddress = static_cast<uintptr_t>(constantsForPatching->getGpuAddress());
constants.segmentSize = constantsForPatching->getUnderlyingBufferSize();
}
if (this->linkerInput->getExportedFunctionsSegmentId() >= 0) {
if (linkerInput->getExportedFunctionsSegmentId() >= 0) {
// Exported functions reside in instruction heap of one of kernels
auto exportedFunctionHeapId = this->linkerInput->getExportedFunctionsSegmentId();
auto exportedFunctionHeapId = linkerInput->getExportedFunctionsSegmentId();
this->exportedFunctionsSurface = this->kernelInfoArray[exportedFunctionHeapId]->getGraphicsAllocation();
exportedFunctions.gpuAddress = static_cast<uintptr_t>(exportedFunctionsSurface->getGpuAddressToPatch());
exportedFunctions.segmentSize = exportedFunctionsSurface->getUnderlyingBufferSize();
@ -93,7 +94,7 @@ cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const
globalsForPatching, constantsForPatching,
isaSegmentsForPatching, unresolvedExternalsInfo,
pDevice, constantsInitData, variablesInitData);
this->symbols = linker.extractRelocatedSymbols();
setSymbols(pDevice->getRootDeviceIndex(), linker.extractRelocatedSymbols());
if (false == linkSuccess) {
std::vector<std::string> kernelNames;
for (const auto &kernelInfo : this->kernelInfoArray) {
@ -114,7 +115,7 @@ cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const
kernHeapInfo.KernelHeapSize);
}
}
DBG_LOG(PrintRelocations, NEO::constructRelocationsDebugMessage(this->symbols));
DBG_LOG(PrintRelocations, NEO::constructRelocationsDebugMessage(this->getSymbols(pDevice->getRootDeviceIndex())));
return CL_SUCCESS;
}
@ -157,6 +158,7 @@ cl_int Program::processProgramInfo(ProgramInfo &src) {
size_t slmNeeded = getMaxInlineSlmNeeded(src);
size_t slmAvailable = 0U;
NEO::DeviceInfoKernelPayloadConstants deviceInfoConstants;
LinkerInput *linkerInput = nullptr;
if (this->pDevice) {
slmAvailable = static_cast<size_t>(this->pDevice->getDeviceInfo().localMemSize);
deviceInfoConstants.maxWorkGroupSize = (uint32_t)this->pDevice->getDeviceInfo().maxWorkGroupSize;
@ -165,24 +167,25 @@ cl_int Program::processProgramInfo(ProgramInfo &src) {
if (requiresLocalMemoryWindowVA(src)) {
deviceInfoConstants.slmWindow = this->executionEnvironment.memoryManager->getReservedMemory(MemoryConstants::slmWindowSize, MemoryConstants::slmWindowAlignment);
}
linkerInput = src.linkerInput.get();
setLinkerInput(pDevice->getRootDeviceIndex(), std::move(src.linkerInput));
}
if (slmNeeded > slmAvailable) {
return CL_OUT_OF_RESOURCES;
}
this->linkerInput = std::move(src.linkerInput);
this->kernelInfoArray = std::move(src.kernelInfos);
auto svmAllocsManager = context ? context->getSVMAllocsManager() : nullptr;
if (src.globalConstants.size != 0) {
UNRECOVERABLE_IF(nullptr == pDevice);
this->constantSurface = allocateGlobalsSurface(svmAllocsManager, *pDevice, src.globalConstants.size, true, linkerInput.get(), src.globalConstants.initData);
this->constantSurface = allocateGlobalsSurface(svmAllocsManager, *pDevice, src.globalConstants.size, true, linkerInput, src.globalConstants.initData);
}
this->globalVarTotalSize = src.globalVariables.size;
if (src.globalVariables.size != 0) {
UNRECOVERABLE_IF(nullptr == pDevice);
this->globalSurface = allocateGlobalsSurface(svmAllocsManager, *pDevice, src.globalVariables.size, false, linkerInput.get(), src.globalVariables.initData);
this->globalSurface = allocateGlobalsSurface(svmAllocsManager, *pDevice, src.globalVariables.size, false, linkerInput, src.globalVariables.initData);
if (pDevice->getSpecializedDevice<ClDevice>()->areOcl21FeaturesEnabled() == false) {
this->globalVarTotalSize = 0u;
}

View File

@ -9,6 +9,7 @@
#include "shared/source/compiler_interface/compiler_interface.h"
#include "shared/source/compiler_interface/linker.h"
#include "shared/source/device_binary_format/elf/elf_encoder.h"
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "shared/source/program/program_info.h"
#include "shared/source/utilities/const_stringref.h"
@ -254,12 +255,19 @@ class Program : public BaseObject<_cl_program> {
return debugDataSize;
}
const Linker::RelocatedSymbolsMap &getSymbols() const {
return this->symbols;
const Linker::RelocatedSymbolsMap &getSymbols(uint32_t rootDeviceIndex) const {
return buildInfos[rootDeviceIndex].symbols;
}
LinkerInput *getLinkerInput() const {
return this->linkerInput.get();
void setSymbols(uint32_t rootDeviceIndex, Linker::RelocatedSymbolsMap &&symbols) {
buildInfos[rootDeviceIndex].symbols = std::move(symbols);
}
LinkerInput *getLinkerInput(uint32_t rootDeviceIndex) const {
return buildInfos[rootDeviceIndex].linkerInput.get();
}
void setLinkerInput(uint32_t rootDeviceIndex, std::unique_ptr<LinkerInput> &&linkerInput) {
buildInfos[rootDeviceIndex].linkerInput = std::move(linkerInput);
}
MOCKABLE_VIRTUAL void replaceDeviceBinary(std::unique_ptr<char[]> newBinary, size_t newBinarySize);
@ -324,14 +332,13 @@ class Program : public BaseObject<_cl_program> {
uint32_t programOptionVersion = 12U;
bool allowNonUniform = false;
std::unique_ptr<LinkerInput> linkerInput;
Linker::RelocatedSymbolsMap symbols;
struct BuildInfo {
struct BuildInfo : public NonCopyableClass {
std::unique_ptr<LinkerInput> linkerInput;
Linker::RelocatedSymbolsMap symbols{};
std::string buildLog{};
};
StackVec<BuildInfo, 1> buildInfos;
std::vector<BuildInfo> buildInfos;
bool areSpecializationConstantsInitialized = false;
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsIds;

View File

@ -15,9 +15,10 @@ using clGetDeviceGlobalVariablePointer = api_tests;
using clGetDeviceFunctionPointer = api_tests;
TEST_F(clGetDeviceGlobalVariablePointer, GivenNullMandatoryArgumentsThenReturnInvalidArgError) {
this->pProgram->symbols["A"].gpuAddress = 7U;
this->pProgram->symbols["A"].symbol.size = 64U;
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
auto &symbols = pProgram->buildInfos[testedRootDeviceIndex].symbols;
symbols["A"].gpuAddress = 7U;
symbols["A"].symbol.size = 64U;
symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
void *globalRet = 0;
auto ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr, &globalRet);
@ -35,9 +36,10 @@ TEST_F(clGetDeviceGlobalVariablePointer, GivenNullMandatoryArgumentsThenReturnIn
}
TEST_F(clGetDeviceGlobalVariablePointer, GivenValidSymbolNameThenReturnProperAddressAndSize) {
this->pProgram->symbols["A"].gpuAddress = 7U;
this->pProgram->symbols["A"].symbol.size = 64U;
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
auto &symbols = pProgram->buildInfos[testedRootDeviceIndex].symbols;
symbols["A"].gpuAddress = 7U;
symbols["A"].symbol.size = 64U;
symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
void *globalRet = 0;
size_t sizeRet = 0;
@ -48,9 +50,10 @@ TEST_F(clGetDeviceGlobalVariablePointer, GivenValidSymbolNameThenReturnProperAdd
}
TEST_F(clGetDeviceGlobalVariablePointer, GivenFunctionSymbolNameThenReturnInvalidArgError) {
this->pProgram->symbols["A"].gpuAddress = 7U;
this->pProgram->symbols["A"].symbol.size = 64U;
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
auto &symbols = pProgram->buildInfos[testedRootDeviceIndex].symbols;
symbols["A"].gpuAddress = 7U;
symbols["A"].symbol.size = 64U;
symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
void *globalRet = 0;
auto ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr, &globalRet);
@ -64,9 +67,10 @@ TEST_F(clGetDeviceGlobalVariablePointer, GivenUnknownSymbolNameThenReturnInvalid
}
TEST_F(clGetDeviceFunctionPointer, GivenNullMandatoryArgumentsThenReturnInvalidArgError) {
this->pProgram->symbols["A"].gpuAddress = 7U;
this->pProgram->symbols["A"].symbol.size = 64U;
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
auto &symbols = pProgram->buildInfos[testedRootDeviceIndex].symbols;
symbols["A"].gpuAddress = 7U;
symbols["A"].symbol.size = 64U;
symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
cl_ulong fptrRet = 0;
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
@ -84,9 +88,10 @@ TEST_F(clGetDeviceFunctionPointer, GivenNullMandatoryArgumentsThenReturnInvalidA
}
TEST_F(clGetDeviceFunctionPointer, GivenValidSymbolNameThenReturnProperAddress) {
this->pProgram->symbols["A"].gpuAddress = 7U;
this->pProgram->symbols["A"].symbol.size = 64U;
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
auto &symbols = pProgram->buildInfos[testedRootDeviceIndex].symbols;
symbols["A"].gpuAddress = 7U;
symbols["A"].symbol.size = 64U;
symbols["A"].symbol.segment = NEO::SegmentType::Instructions;
cl_ulong fptrRet = 0;
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
@ -95,12 +100,13 @@ TEST_F(clGetDeviceFunctionPointer, GivenValidSymbolNameThenReturnProperAddress)
}
TEST_F(clGetDeviceFunctionPointer, GivenGlobalSymbolNameThenReturnInvalidArgError) {
this->pProgram->symbols["A"].gpuAddress = 7U;
this->pProgram->symbols["A"].symbol.size = 64U;
this->pProgram->symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
this->pProgram->symbols["B"].gpuAddress = 7U;
this->pProgram->symbols["B"].symbol.size = 64U;
this->pProgram->symbols["B"].symbol.segment = NEO::SegmentType::GlobalConstants;
auto &symbols = pProgram->buildInfos[testedRootDeviceIndex].symbols;
symbols["A"].gpuAddress = 7U;
symbols["A"].symbol.size = 64U;
symbols["A"].symbol.segment = NEO::SegmentType::GlobalVariables;
symbols["B"].gpuAddress = 7U;
symbols["B"].symbol.size = 64U;
symbols["B"].symbol.segment = NEO::SegmentType::GlobalConstants;
cl_ulong fptrRet = 0;
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);

View File

@ -37,6 +37,7 @@ class MockProgram : public Program {
using Program::applyAdditionalOptions;
using Program::areSpecializationConstantsInitialized;
using Program::blockKernelManager;
using Program::buildInfos;
using Program::constantSurface;
using Program::context;
using Program::createdFrom;
@ -49,7 +50,6 @@ class MockProgram : public Program {
using Program::irBinary;
using Program::irBinarySize;
using Program::isSpirV;
using Program::linkerInput;
using Program::options;
using Program::packDeviceBinary;
using Program::packedDeviceBinary;
@ -61,7 +61,6 @@ class MockProgram : public Program {
using Program::specConstantsIds;
using Program::specConstantsSizes;
using Program::specConstantsValues;
using Program::symbols;
using Program::unpackedDeviceBinary;
using Program::unpackedDeviceBinarySize;

View File

@ -1461,7 +1461,7 @@ TEST_F(KernelDataTest, givenSymbolTablePatchTokenThenLinkerInputIsCreated) {
buildAndDecode();
EXPECT_NE(nullptr, program->linkerInput);
EXPECT_NE(nullptr, program->getLinkerInput(pContext->getDevice(0)->getRootDeviceIndex()));
}
TEST_F(KernelDataTest, givenRelocationTablePatchTokenThenLinkerInputIsCreated) {
@ -1475,5 +1475,5 @@ TEST_F(KernelDataTest, givenRelocationTablePatchTokenThenLinkerInputIsCreated) {
buildAndDecode();
EXPECT_NE(nullptr, program->linkerInput);
EXPECT_NE(nullptr, program->getLinkerInput(pContext->getDevice(0)->getRootDeviceIndex()));
}

View File

@ -469,7 +469,7 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeConstantB
constantSurfaceStorage[0] = 0U;
constantSurfaceStorage[1] = sentinel;
pProgram->linkerInput = std::move(programInfo.linkerInput);
pProgram->setLinkerInput(pProgram->getDevice().getRootDeviceIndex(), std::move(programInfo.linkerInput));
pProgram->linkBinary(pProgram->pDevice, programInfo.globalConstants.initData, programInfo.globalVariables.initData);
uint32_t expectedAddr = static_cast<uint32_t>(constantSurface.getGraphicsAllocation(pProgram->getDevice().getRootDeviceIndex())->getGpuAddressToPatch());
EXPECT_EQ(expectedAddr, constantSurfaceStorage[0]);
@ -507,7 +507,7 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeGlobalPoi
globalSurfaceStorage[0] = 0U;
globalSurfaceStorage[1] = sentinel;
pProgram->linkerInput = std::move(programInfo.linkerInput);
pProgram->setLinkerInput(pProgram->getDevice().getRootDeviceIndex(), std::move(programInfo.linkerInput));
pProgram->linkBinary(pProgram->pDevice, programInfo.globalConstants.initData, programInfo.globalVariables.initData);
uint32_t expectedAddr = static_cast<uint32_t>(globalSurface.getGraphicsAllocation(pProgram->getDevice().getRootDeviceIndex())->getGpuAddressToPatch());
EXPECT_EQ(expectedAddr, globalSurfaceStorage[0]);
@ -527,14 +527,14 @@ TEST_F(ProgramDataTest, givenSymbolTablePatchTokenThenLinkerInputIsCreated) {
buildAndDecodeProgramPatchList();
EXPECT_NE(nullptr, pProgram->getLinkerInput());
EXPECT_NE(nullptr, pProgram->getLinkerInput(pContext->getDevice(0)->getRootDeviceIndex()));
}
TEST(ProgramLinkBinaryTest, whenLinkerInputEmptyThenLinkSuccessful) {
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
NEO::ExecutionEnvironment env;
MockProgram program{env};
program.linkerInput = std::move(linkerInput);
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
MockProgram program{*device->getExecutionEnvironment(), nullptr, false, device.get()};
program.setLinkerInput(device->getRootDeviceIndex(), std::move(linkerInput));
auto ret = program.linkBinary(program.pDevice, nullptr, nullptr);
EXPECT_EQ(CL_SUCCESS, ret);
}
@ -555,7 +555,7 @@ TEST(ProgramLinkBinaryTest, whenLinkerUnresolvedExternalThenLinkFailedAndBuildLo
kernelInfo.heapInfo.pKernelHeap = kernelHeap.data();
kernelInfo.heapInfo.KernelHeapSize = static_cast<uint32_t>(kernelHeap.size());
program.getKernelInfoArray().push_back(&kernelInfo);
program.linkerInput = std::move(linkerInput);
program.setLinkerInput(device->getRootDeviceIndex(), std::move(linkerInput));
std::string buildLog = program.getBuildLog(device->getRootDeviceIndex());
EXPECT_TRUE(buildLog.empty());
@ -582,8 +582,8 @@ TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) {
NEO::LinkerInput::RelocationInfo{"C", 24U, relocationType}});
linkerInput->traits.requiresPatchingOfInstructionSegments = true;
linkerInput->exportedFunctionsSegmentId = 0;
NEO::ExecutionEnvironment env;
MockProgram program{env};
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
MockProgram program{*device->getExecutionEnvironment(), nullptr, false, device.get()};
KernelInfo kernelInfo = {};
kernelInfo.name = "onlyKernel";
std::vector<char> kernelHeap;
@ -593,7 +593,7 @@ TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) {
MockGraphicsAllocation kernelIsa(kernelHeap.data(), kernelHeap.size());
kernelInfo.kernelAllocation = &kernelIsa;
program.getKernelInfoArray().push_back(&kernelInfo);
program.linkerInput = std::move(linkerInput);
program.setLinkerInput(device->getRootDeviceIndex(), std::move(linkerInput));
program.exportedFunctionsSurface = kernelInfo.kernelAllocation;
std::vector<char> globalVariablesBuffer;
@ -610,7 +610,7 @@ TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) {
auto ret = program.linkBinary(pProgram->pDevice, globalConstantsInitData.data(), globalVariablesInitData.data());
EXPECT_EQ(CL_SUCCESS, ret);
linkerInput.reset(static_cast<WhiteBox<LinkerInput> *>(program.linkerInput.release()));
linkerInput.reset(static_cast<WhiteBox<LinkerInput> *>(program.buildInfos[program.pDevice->getRootDeviceIndex()].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;
@ -631,8 +631,8 @@ TEST_F(ProgramDataTest, whenRelocationsAreNotNeededThenIsaIsPreserved) {
linkerInput->symbols["A"] = NEO::SymbolInfo{4U, 4U, NEO::SegmentType::GlobalVariables};
linkerInput->symbols["B"] = NEO::SymbolInfo{8U, 4U, NEO::SegmentType::GlobalConstants};
NEO::ExecutionEnvironment env;
MockProgram program{env};
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
MockProgram program{*device->getExecutionEnvironment(), nullptr, false, device.get()};
KernelInfo kernelInfo = {};
kernelInfo.name = "onlyKernel";
std::vector<char> kernelHeapData;
@ -643,7 +643,7 @@ TEST_F(ProgramDataTest, whenRelocationsAreNotNeededThenIsaIsPreserved) {
MockGraphicsAllocation kernelIsa(kernelHeap.data(), kernelHeap.size());
kernelInfo.kernelAllocation = &kernelIsa;
program.getKernelInfoArray().push_back(&kernelInfo);
program.linkerInput = std::move(linkerInput);
program.setLinkerInput(device->getRootDeviceIndex(), std::move(linkerInput));
std::vector<char> globalVariablesBuffer;
globalVariablesBuffer.resize(32, 7);

View File

@ -2726,12 +2726,6 @@ TEST_F(ProgramTests, givenProgramWhenInternalOptionsArePassedWithInvalidValuesTh
EXPECT_EQ(expectedOutput, program.getInternalOptions());
}
TEST_F(ProgramTests, givenProgramWhenGetSymbolsIsCalledThenMapWithExportedSymbolsIsReturned) {
ExecutionEnvironment executionEnvironment;
MockProgram program(executionEnvironment);
EXPECT_EQ(&program.symbols, &program.getSymbols());
}
class AdditionalOptionsMockProgram : public MockProgram {
public:
AdditionalOptionsMockProgram() : MockProgram(executionEnvironment) {}