Program refactor

* Decouple binary program handling from Program object
* Add binary formats multiplexer
* Improve Elf format support

Change-Id: Ic22aff40173532e14825d70b82ec53fcc5fa9fdf
This commit is contained in:
Jaroslaw Chodor
2020-01-25 19:18:48 +01:00
parent cb964f9e72
commit a53e26342a
96 changed files with 3917 additions and 2023 deletions

View File

@@ -48,7 +48,6 @@ if(WIN32)
endif()
endif()
target_link_libraries(${NEO_STATIC_LIB_NAME} elflib)
if(DEFINED AUB_STREAM_DIR)
target_link_libraries(${NEO_STATIC_LIB_NAME} ${AUB_STREAM_PROJECT_NAME})
endif()

View File

@@ -30,7 +30,6 @@ set(RUNTIME_SRCS_DLL_BASE
${NEO_SOURCE_DIR}/runtime/api/api.cpp
${NEO_SOURCE_DIR}/runtime/compiler_interface/default_cache_config.cpp
${NEO_SOURCE_DIR}/runtime/helpers/built_ins_helper.cpp
${NEO_SOURCE_DIR}/runtime/program/evaluate_unhandled_token.cpp
${GTPIN_INIT_FILE}
${HW_SRC_LINK}

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2018-2019 Intel Corporation
# Copyright (C) 2018-2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
@@ -25,9 +25,8 @@ set(RUNTIME_SRCS_PROGRAM
${CMAKE_CURRENT_SOURCE_DIR}/patch_info.h
${CMAKE_CURRENT_SOURCE_DIR}/printf_handler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/printf_handler.h
${CMAKE_CURRENT_SOURCE_DIR}/process_elf_binary.cpp
${CMAKE_CURRENT_SOURCE_DIR}/process_gen_binary.cpp
${CMAKE_CURRENT_SOURCE_DIR}/process_spir_binary.cpp
${CMAKE_CURRENT_SOURCE_DIR}/process_device_binary.cpp
${CMAKE_CURRENT_SOURCE_DIR}/process_intermediate_binary.cpp
${CMAKE_CURRENT_SOURCE_DIR}/program.cpp
${CMAKE_CURRENT_SOURCE_DIR}/program.h
)

View File

@@ -7,6 +7,7 @@
#include "core/compiler_interface/compiler_interface.h"
#include "core/device/device.h"
#include "core/device_binary_format/device_binary_formats.h"
#include "core/execution_environment/execution_environment.h"
#include "core/utilities/time_measure_wrapper.h"
#include "runtime/device/cl_device.h"
@@ -125,8 +126,7 @@ cl_int Program::build(
this->irBinarySize = compilerOuput.intermediateRepresentation.size;
this->isSpirV = compilerOuput.intermediateCodeType == IGC::CodeType::spirV;
}
this->genBinary = std::move(compilerOuput.deviceBinary.mem);
this->genBinarySize = compilerOuput.deviceBinary.size;
this->replaceDeviceBinary(std::move(compilerOuput.deviceBinary.mem), compilerOuput.deviceBinary.size);
this->debugData = std::move(compilerOuput.debugData.mem);
this->debugDataSize = compilerOuput.debugData.size;
}

View File

@@ -6,7 +6,10 @@
*/
#include "core/compiler_interface/compiler_interface.h"
#include "core/elf/writer.h"
#include "core/device/device.h"
#include "core/device_binary_format/elf/elf.h"
#include "core/device_binary_format/elf/elf_encoder.h"
#include "core/device_binary_format/elf/ocl_elf.h"
#include "core/execution_environment/execution_environment.h"
#include "runtime/device/cl_device.h"
#include "runtime/helpers/validators.h"
@@ -30,9 +33,6 @@ cl_int Program::compile(
void(CL_CALLBACK *funcNotify)(cl_program program, void *userData),
void *userData) {
cl_int retVal = CL_SUCCESS;
cl_program program;
Program *pHeaderProgObj;
size_t compileDataSize;
do {
if (((deviceList == nullptr) && (numDevices != 0)) ||
@@ -89,43 +89,35 @@ cl_int Program::compile(
}
// create ELF writer to process all sources to be compiled
CLElfLib::CElfWriter elfWriter(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_SOURCE, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
CLElfLib::SSectionNode sectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_SOURCE, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "CLMain", sourceCode, static_cast<uint32_t>(sourceCode.size() + 1u));
// add main program's source
elfWriter.addSection(sectionNode);
NEO::Elf::ElfEncoder<> elfEncoder(true, true, 1U);
elfEncoder.getElfFileHeader().type = NEO::Elf::ET_OPENCL_SOURCE;
elfEncoder.appendSection(NEO::Elf::SHT_OPENCL_SOURCE, "CLMain", sourceCode);
for (cl_uint i = 0; i < numInputHeaders; i++) {
program = inputHeaders[i];
auto program = inputHeaders[i];
if (program == nullptr) {
retVal = CL_INVALID_PROGRAM;
break;
}
pHeaderProgObj = castToObject<Program>(program);
auto pHeaderProgObj = castToObject<Program>(program);
if (pHeaderProgObj == nullptr) {
retVal = CL_INVALID_PROGRAM;
break;
}
sectionNode.name = headerIncludeNames[i];
sectionNode.type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_HEADER;
sectionNode.flag = CLElfLib::E_SH_FLAG::SH_FLAG_NONE;
// collect required data from the header
retVal = pHeaderProgObj->getSource(sectionNode.data);
std::string includeHeaderSource;
retVal = pHeaderProgObj->getSource(includeHeaderSource);
if (retVal != CL_SUCCESS) {
break;
}
sectionNode.dataSize = static_cast<uint32_t>(sectionNode.data.size());
elfWriter.addSection(sectionNode);
elfEncoder.appendSection(NEO::Elf::SHT_OPENCL_HEADER, ConstStringRef(headerIncludeNames[i], strlen(headerIncludeNames[i])), includeHeaderSource);
}
if (retVal != CL_SUCCESS) {
break;
}
compileDataSize = elfWriter.getTotalBinarySize();
CLElfLib::ElfBinaryStorage compileData(compileDataSize);
elfWriter.resolveBinary(compileData);
std::vector<uint8_t> compileData = elfEncoder.encode();
CompilerInterface *pCompilerInterface = this->executionEnvironment.getCompilerInterface();
if (!pCompilerInterface) {
@@ -148,7 +140,7 @@ cl_int Program::compile(
}
}
inputArgs.src = ArrayRef<const char>(compileData.data(), compileDataSize);
inputArgs.src = ArrayRef<const char>(reinterpret_cast<const char *>(compileData.data()), compileData.size());
inputArgs.apiOptions = ArrayRef<const char>(options.c_str(), options.length());
inputArgs.internalOptions = ArrayRef<const char>(internalOptions.c_str(), internalOptions.length());

View File

@@ -144,11 +144,9 @@ T *Program::createFromGenBinary(
if (CL_SUCCESS == retVal) {
program = new T(executionEnvironment, context, isBuiltIn);
program->numDevices = 1;
program->genBinary = makeCopy(binary, size);
program->genBinarySize = size;
program->replaceDeviceBinary(makeCopy(binary, size), size);
program->isCreatedFromBinary = true;
program->programBinaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
program->isProgramBinaryResolved = true;
program->buildStatus = CL_BUILD_SUCCESS;
program->createdFrom = CreatedFrom::BINARY;
}

View File

@@ -1,16 +0,0 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "runtime/program/program.h"
namespace NEO {
bool Program::isSafeToSkipUnhandledToken(unsigned int token) const {
return false;
}
} // namespace NEO

View File

@@ -36,10 +36,10 @@ cl_int Program::getInfo(cl_program_info paramName, size_t paramValueSize,
break;
case CL_PROGRAM_BINARIES:
resolveProgramBinary();
pSrc = elfBinary.data();
packDeviceBinary();
pSrc = packedDeviceBinary.get();
retSize = sizeof(void **);
srcSize = elfBinarySize;
srcSize = packedDeviceBinarySize;
if (paramValue != nullptr) {
if (paramValueSize < retSize) {
retVal = CL_INVALID_VALUE;
@@ -51,8 +51,8 @@ cl_int Program::getInfo(cl_program_info paramName, size_t paramValueSize,
break;
case CL_PROGRAM_BINARY_SIZES:
resolveProgramBinary();
pSrc = &elfBinarySize;
packDeviceBinary();
pSrc = &packedDeviceBinarySize;
retSize = srcSize = sizeof(size_t *);
break;
@@ -116,13 +116,11 @@ cl_int Program::getInfo(cl_program_info paramName, size_t paramValueSize,
break;
case CL_PROGRAM_DEBUG_INFO_SIZES_INTEL:
resolveProgramBinary();
retSize = srcSize = sizeof(debugDataSize);
pSrc = &debugDataSize;
break;
case CL_PROGRAM_DEBUG_INFO_INTEL:
resolveProgramBinary();
pSrc = debugData.get();
retSize = numDevices * sizeof(void **);
srcSize = debugDataSize;

View File

@@ -425,6 +425,37 @@ bool KernelInfo::createKernelAllocation(uint32_t rootDeviceIndex, MemoryManager
return memoryManager->copyMemoryToAllocation(kernelAllocation, heapInfo.pKernelHeap, kernelIsaSize);
}
void KernelInfo::apply(const DeviceInfoKernelPayloadConstants &constants) {
if (nullptr == this->crossThreadData) {
return;
}
uint32_t privateMemoryStatelessSizeOffset = this->workloadInfo.privateMemoryStatelessSizeOffset;
uint32_t localMemoryStatelessWindowSizeOffset = this->workloadInfo.localMemoryStatelessWindowSizeOffset;
uint32_t localMemoryStatelessWindowStartAddressOffset = this->workloadInfo.localMemoryStatelessWindowStartAddressOffset;
if (localMemoryStatelessWindowStartAddressOffset != WorkloadInfo::undefinedOffset) {
*(uintptr_t *)&(this->crossThreadData[localMemoryStatelessWindowStartAddressOffset]) = reinterpret_cast<uintptr_t>(constants.slmWindow);
}
if (localMemoryStatelessWindowSizeOffset != WorkloadInfo::undefinedOffset) {
*(uint32_t *)&(this->crossThreadData[localMemoryStatelessWindowSizeOffset]) = constants.slmWindowSize;
}
uint32_t privateMemorySize = 0U;
if (this->patchInfo.pAllocateStatelessPrivateSurface) {
privateMemorySize = this->patchInfo.pAllocateStatelessPrivateSurface->PerThreadPrivateMemorySize * constants.computeUnitsUsedForScratch * this->getMaxSimdSize();
}
if (privateMemoryStatelessSizeOffset != WorkloadInfo::undefinedOffset) {
*(uint32_t *)&(this->crossThreadData[privateMemoryStatelessSizeOffset]) = privateMemorySize;
}
if (this->workloadInfo.maxWorkGroupSizeOffset != WorkloadInfo::undefinedOffset) {
*(uint32_t *)&(this->crossThreadData[this->workloadInfo.maxWorkGroupSizeOffset]) = constants.maxWorkGroupSize;
}
}
std::string concatenateKernelNames(ArrayRef<KernelInfo *> kernelInfos) {
std::string semiColonDelimitedKernelNameStr;

View File

@@ -188,6 +188,7 @@ struct KernelInfo {
}
bool createKernelAllocation(uint32_t rootDeviceIndex, MemoryManager *memoryManager);
void apply(const DeviceInfoKernelPayloadConstants &constants);
std::string name;
std::string attributes;

View File

@@ -141,8 +141,7 @@ void populateKernelInfoArg(KernelInfo &dstKernelInfo, KernelArgInfo &dstKernelIn
dstKernelInfoArg.offsetObjectId = getOffset(src.objectId);
}
void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatchtokens &src, uint32_t gpuPointerSizeInBytes,
const DeviceInfoKernelPayloadConstants &constants) {
void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatchtokens &src, uint32_t gpuPointerSizeInBytes) {
UNRECOVERABLE_IF(nullptr == src.header);
dst.heapInfo.pKernelHeader = src.header;
dst.name = std::string(src.name.begin(), src.name.end()).c_str();
@@ -220,31 +219,6 @@ void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatch
uint32_t crossThreadDataSize = dst.patchInfo.dataParameterStream->DataParameterStreamSize;
dst.crossThreadData = new char[crossThreadDataSize];
memset(dst.crossThreadData, 0x00, crossThreadDataSize);
uint32_t privateMemoryStatelessSizeOffset = dst.workloadInfo.privateMemoryStatelessSizeOffset;
uint32_t localMemoryStatelessWindowSizeOffset = dst.workloadInfo.localMemoryStatelessWindowSizeOffset;
uint32_t localMemoryStatelessWindowStartAddressOffset = dst.workloadInfo.localMemoryStatelessWindowStartAddressOffset;
if (localMemoryStatelessWindowStartAddressOffset != WorkloadInfo::undefinedOffset) {
*(uintptr_t *)&(dst.crossThreadData[localMemoryStatelessWindowStartAddressOffset]) = reinterpret_cast<uintptr_t>(constants.slmWindow);
}
if (localMemoryStatelessWindowSizeOffset != WorkloadInfo::undefinedOffset) {
*(uint32_t *)&(dst.crossThreadData[localMemoryStatelessWindowSizeOffset]) = constants.slmWindowSize;
}
uint32_t privateMemorySize = 0U;
if (dst.patchInfo.pAllocateStatelessPrivateSurface) {
privateMemorySize = dst.patchInfo.pAllocateStatelessPrivateSurface->PerThreadPrivateMemorySize * constants.computeUnitsUsedForScratch * dst.getMaxSimdSize();
}
if (privateMemoryStatelessSizeOffset != WorkloadInfo::undefinedOffset) {
*(uint32_t *)&(dst.crossThreadData[privateMemoryStatelessSizeOffset]) = privateMemorySize;
}
if (dst.workloadInfo.maxWorkGroupSizeOffset != WorkloadInfo::undefinedOffset) {
*(uint32_t *)&(dst.crossThreadData[dst.workloadInfo.maxWorkGroupSizeOffset]) = constants.maxWorkGroupSize;
}
}
}

View File

@@ -11,14 +11,12 @@
namespace NEO {
struct DeviceInfoKernelPayloadConstants;
struct KernelInfo;
namespace PatchTokenBinary {
struct KernelFromPatchtokens;
}
void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatchtokens &src, uint32_t gpuPointerSizeInBytes,
const DeviceInfoKernelPayloadConstants &constant);
void populateKernelInfo(KernelInfo &dst, const PatchTokenBinary::KernelFromPatchtokens &src, uint32_t gpuPointerSizeInBytes);
} // namespace NEO

View File

@@ -6,7 +6,9 @@
*/
#include "core/compiler_interface/compiler_interface.h"
#include "core/elf/writer.h"
#include "core/device_binary_format/elf/elf.h"
#include "core/device_binary_format/elf/elf_encoder.h"
#include "core/device_binary_format/elf/ocl_elf.h"
#include "core/execution_environment/execution_environment.h"
#include "core/utilities/stackvec.h"
#include "runtime/device/cl_device.h"
@@ -30,9 +32,6 @@ cl_int Program::link(
void(CL_CALLBACK *funcNotify)(cl_program program, void *userData),
void *userData) {
cl_int retVal = CL_SUCCESS;
cl_program program;
Program *pInputProgObj;
size_t dataSize;
bool isCreateLibrary;
do {
@@ -73,16 +72,17 @@ cl_int Program::link(
buildStatus = CL_BUILD_IN_PROGRESS;
CLElfLib::CElfWriter elfWriter(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
NEO::Elf::ElfEncoder<> elfEncoder(true, false, 1U);
elfEncoder.getElfFileHeader().type = NEO::Elf::ET_OPENCL_OBJECTS;
StackVec<const Program *, 16> inputProgramsInternal;
for (cl_uint i = 0; i < numInputPrograms; i++) {
program = inputPrograms[i];
auto program = inputPrograms[i];
if (program == nullptr) {
retVal = CL_INVALID_PROGRAM;
break;
}
pInputProgObj = castToObject<Program>(program);
auto pInputProgObj = castToObject<Program>(program);
if (pInputProgObj == nullptr) {
retVal = CL_INVALID_PROGRAM;
break;
@@ -93,16 +93,15 @@ cl_int Program::link(
break;
}
elfWriter.addSection(CLElfLib::SSectionNode(pInputProgObj->getIsSpirV() ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY,
CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "", std::string(pInputProgObj->irBinary.get(), pInputProgObj->irBinarySize), static_cast<uint32_t>(pInputProgObj->irBinarySize)));
auto sectionType = pInputProgObj->getIsSpirV() ? NEO::Elf::SHT_OPENCL_SPIRV : NEO::Elf::SHT_OPENCL_LLVM_BINARY;
ConstStringRef sectionName = pInputProgObj->getIsSpirV() ? NEO::Elf::SectionNamesOpenCl::spirvObject : NEO::Elf::SectionNamesOpenCl::llvmObject;
elfEncoder.appendSection(sectionType, sectionName, ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(pInputProgObj->irBinary.get()), pInputProgObj->irBinarySize));
}
if (retVal != CL_SUCCESS) {
break;
}
dataSize = elfWriter.getTotalBinarySize();
CLElfLib::ElfBinaryStorage data(dataSize);
elfWriter.resolveBinary(data);
auto clLinkInput = elfEncoder.encode();
CompilerInterface *pCompilerInterface = this->executionEnvironment.getCompilerInterface();
if (!pCompilerInterface) {
@@ -112,7 +111,7 @@ cl_int Program::link(
TranslationInput inputArgs = {IGC::CodeType::elf, IGC::CodeType::undefined};
inputArgs.src = ArrayRef<const char>(data.data(), dataSize);
inputArgs.src = ArrayRef<const char>(reinterpret_cast<const char *>(clLinkInput.data()), clLinkInput.size());
inputArgs.apiOptions = ArrayRef<const char>(options.c_str(), options.length());
inputArgs.internalOptions = ArrayRef<const char>(internalOptions.c_str(), internalOptions.length());
@@ -127,8 +126,7 @@ cl_int Program::link(
break;
}
this->genBinary = std::move(compilerOuput.deviceBinary.mem);
this->genBinarySize = compilerOuput.deviceBinary.size;
this->replaceDeviceBinary(std::move(compilerOuput.deviceBinary.mem), compilerOuput.deviceBinary.size);
this->debugData = std::move(compilerOuput.debugData.mem);
this->debugDataSize = compilerOuput.debugData.size;

View File

@@ -5,27 +5,21 @@
*
*/
#include "core/device_binary_format/patchtokens_decoder.h"
#include "core/device_binary_format/patchtokens_dumper.h"
#include "core/device_binary_format/patchtokens_validator.inl"
#include "core/device_binary_format/device_binary_formats.h"
#include "core/helpers/aligned_memory.h"
#include "core/helpers/debug_helpers.h"
#include "core/helpers/ptr_math.h"
#include "core/helpers/string.h"
#include "core/memory_manager/unified_memory_manager.h"
#include "core/program/program_info.h"
#include "core/program/program_info_from_patchtokens.h"
#include "core/program/program_initialization.h"
#include "runtime/context/context.h"
#include "runtime/device/cl_device.h"
#include "runtime/gtpin/gtpin_notify.h"
#include "runtime/memory_manager/memory_manager.h"
#include "runtime/program/kernel_info.h"
#include "runtime/program/kernel_info_from_patchtokens.h"
#include "runtime/program/program.h"
#include "patch_list.h"
#include "patch_shared.h"
#include "program_debug_data.h"
#include <algorithm>
@@ -56,26 +50,6 @@ const KernelInfo *Program::getKernelInfo(size_t ordinal) const {
return kernelInfoArray[ordinal];
}
cl_int Program::isHandled(const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram) const {
std::string validatorErrMessage;
std::string validatorWarnings;
auto availableSlm = this->pDevice ? static_cast<size_t>(this->pDevice->getDeviceInfo().localMemSize) : 0U;
auto validatorErr = PatchTokenBinary::validate(decodedProgram, availableSlm, *this, validatorErrMessage, validatorWarnings);
if (validatorWarnings.empty() == false) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", validatorWarnings.c_str());
}
if (validatorErr != PatchTokenBinary::ValidatorError::Success) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", validatorErrMessage.c_str());
switch (validatorErr) {
default:
return CL_INVALID_BINARY;
case PatchTokenBinary::ValidatorError::NotEnoughSlm:
return CL_OUT_OF_RESOURCES;
}
}
return CL_SUCCESS;
}
cl_int Program::linkBinary() {
if (linkerInput == nullptr) {
return CL_SUCCESS;
@@ -146,6 +120,10 @@ cl_int Program::linkBinary() {
}
cl_int Program::processGenBinary() {
if (nullptr == this->unpackedDeviceBinary) {
return CL_INVALID_BINARY;
}
cleanCurrentKernelInfo();
if (this->constantSurface || this->globalSurface) {
pDevice->getMemoryManager()->freeGraphicsMemory(this->constantSurface);
@@ -154,41 +132,45 @@ cl_int Program::processGenBinary() {
this->globalSurface = nullptr;
}
auto blob = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(genBinary.get()), genBinarySize);
ProgramInfo programInfo;
auto ret = this->processPatchTokensBinary(blob, programInfo);
if (CL_SUCCESS != ret) {
return ret;
auto blob = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(this->unpackedDeviceBinary.get()), this->unpackedDeviceBinarySize);
SingleDeviceBinary binary = {};
binary.deviceBinary = blob;
std::string decodeErrors;
std::string decodeWarnings;
DecodeError decodeError;
DeviceBinaryFormat singleDeviceBinaryFormat;
std::tie(decodeError, singleDeviceBinaryFormat) = NEO::decodeSingleDeviceBinary(programInfo, binary, decodeErrors, decodeWarnings);
if (decodeWarnings.empty() == false) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeWarnings.c_str());
}
if (DecodeError::Success != decodeError) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeErrors.c_str());
return CL_INVALID_BINARY;
}
return this->processProgramInfo(programInfo);
}
cl_int Program::processPatchTokensBinary(ArrayRef<const uint8_t> src, ProgramInfo &dst) {
NEO::PatchTokenBinary::ProgramFromPatchtokens decodedProgram = {};
NEO::PatchTokenBinary::decodeProgramFromPatchtokensBlob(src, decodedProgram);
DBG_LOG(LogPatchTokens, NEO::PatchTokenBinary::asString(decodedProgram).c_str());
cl_int retVal = this->isHandled(decodedProgram);
if (CL_SUCCESS != retVal) {
return retVal;
}
cl_int Program::processProgramInfo(ProgramInfo &src) {
size_t slmNeeded = getMaxInlineSlmNeeded(src);
size_t slmAvailable = 0U;
NEO::DeviceInfoKernelPayloadConstants deviceInfoConstants;
if (this->pDevice) {
slmAvailable = static_cast<size_t>(this->pDevice->getDeviceInfo().localMemSize);
deviceInfoConstants.maxWorkGroupSize = (uint32_t)this->pDevice->getDeviceInfo().maxWorkGroupSize;
deviceInfoConstants.computeUnitsUsedForScratch = this->pDevice->getDeviceInfo().computeUnitsUsedForScratch;
deviceInfoConstants.slmWindowSize = (uint32_t)this->pDevice->getDeviceInfo().localMemSize;
if (requiresLocalMemoryWindowVA(decodedProgram)) {
if (requiresLocalMemoryWindowVA(src)) {
deviceInfoConstants.slmWindow = this->executionEnvironment.memoryManager->getReservedMemory(MemoryConstants::slmWindowSize, MemoryConstants::slmWindowAlignment);
}
}
if (slmNeeded > slmAvailable) {
return CL_OUT_OF_RESOURCES;
}
NEO::populateProgramInfo(dst, decodedProgram, deviceInfoConstants);
return CL_SUCCESS;
}
cl_int Program::processProgramInfo(ProgramInfo &src) {
this->linkerInput = std::move(src.linkerInput);
this->kernelInfoArray = std::move(src.kernelInfos);
auto svmAllocsManager = context ? context->getSVMAllocsManager() : nullptr;
@@ -221,23 +203,13 @@ cl_int Program::processProgramInfo(ProgramInfo &src) {
if (kernelInfo->requiresSubgroupIndependentForwardProgress()) {
subgroupKernelInfoArray.push_back(kernelInfo);
}
kernelInfo->apply(deviceInfoConstants);
}
return linkBinary();
}
bool Program::validateGenBinaryDevice(GFXCORE_FAMILY device) const {
bool isValid = familyEnabled[device];
return isValid;
}
bool Program::validateGenBinaryHeader(const iOpenCL::SProgramBinaryHeader *pGenBinaryHeader) const {
return pGenBinaryHeader->Magic == MAGIC_CL &&
pGenBinaryHeader->Version == CURRENT_ICBE_VERSION &&
validateGenBinaryDevice(static_cast<GFXCORE_FAMILY>(pGenBinaryHeader->Device));
}
void Program::processDebugData() {
if (debugData != nullptr) {
SProgramDebugDataHeaderIGC *programDebugHeader = reinterpret_cast<SProgramDebugDataHeaderIGC *>(debugData.get());

View File

@@ -1,165 +0,0 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "common/compiler_support.h"
#include "core/device_binary_format/patchtokens_decoder.h"
#include "core/elf/reader.h"
#include "core/elf/writer.h"
#include "core/helpers/string.h"
#include "program.h"
namespace NEO {
cl_int Program::processElfBinary(
const void *pBinary,
size_t binarySize,
uint32_t &binaryVersion) {
const CLElfLib::SElf64Header *pElfHeader = nullptr;
binaryVersion = iOpenCL::CURRENT_ICBE_VERSION;
elfBinarySize = binarySize;
elfBinary = CLElfLib::ElfBinaryStorage(reinterpret_cast<const char *>(pBinary), reinterpret_cast<const char *>(reinterpret_cast<const char *>(pBinary) + binarySize));
try {
CLElfLib::CElfReader elfReader(elfBinary);
pElfHeader = elfReader.getElfHeader();
switch (pElfHeader->Type) {
case CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_EXECUTABLE:
programBinaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
break;
case CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY:
programBinaryType = CL_PROGRAM_BINARY_TYPE_LIBRARY;
break;
case CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS:
programBinaryType = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
break;
default:
return CL_INVALID_BINARY;
}
// section 0 is always null
for (size_t i = 1u; i < elfReader.getSectionHeaders().size(); ++i) {
const auto &sectionHeader = elfReader.getSectionHeaders()[i];
switch (sectionHeader.Type) {
case CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV:
this->isSpirV = true;
CPP_ATTRIBUTE_FALLTHROUGH;
case CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY:
if (sectionHeader.DataSize > 0) {
this->irBinary = makeCopy(elfReader.getSectionData(sectionHeader.DataOffset), static_cast<size_t>(sectionHeader.DataSize));
this->irBinarySize = static_cast<size_t>(sectionHeader.DataSize);
}
break;
case CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_BINARY:
if (sectionHeader.DataSize > 0 && validateGenBinaryHeader(reinterpret_cast<iOpenCL::SProgramBinaryHeader *>(elfReader.getSectionData(sectionHeader.DataOffset)))) {
this->genBinary = makeCopy(elfReader.getSectionData(sectionHeader.DataOffset), static_cast<size_t>(sectionHeader.DataSize));
this->genBinarySize = static_cast<size_t>(sectionHeader.DataSize);
isCreatedFromBinary = true;
} else {
binaryVersion = reinterpret_cast<iOpenCL::SProgramBinaryHeader *>(elfReader.getSectionData(sectionHeader.DataOffset))->Version;
return CL_INVALID_BINARY;
}
break;
case CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_OPTIONS:
if (sectionHeader.DataSize > 0) {
options = std::string(elfReader.getSectionData(sectionHeader.DataOffset), static_cast<size_t>(sectionHeader.DataSize));
}
break;
case CLElfLib::E_SH_TYPE::SH_TYPE_STR_TBL:
// We can skip the string table
break;
default:
return CL_INVALID_BINARY;
}
}
isProgramBinaryResolved = true;
// Create an empty build log since program is effectively built
updateBuildLog(pDevice, "", 1);
} catch (const CLElfLib::ElfException &) {
return CL_INVALID_BINARY;
}
return CL_SUCCESS;
}
cl_int Program::resolveProgramBinary() {
CLElfLib::E_EH_TYPE headerType;
if (isProgramBinaryResolved == false) {
elfBinary.clear();
elfBinarySize = 0;
switch (programBinaryType) {
case CL_PROGRAM_BINARY_TYPE_EXECUTABLE:
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_EXECUTABLE;
if (!genBinary || !genBinarySize) {
return CL_INVALID_BINARY;
}
break;
case CL_PROGRAM_BINARY_TYPE_LIBRARY:
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY;
if (!irBinary || !irBinarySize) {
return CL_INVALID_BINARY;
}
break;
case CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT:
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS;
if (!irBinary || !irBinarySize) {
return CL_INVALID_BINARY;
}
break;
default:
return CL_INVALID_BINARY;
}
CLElfLib::CElfWriter elfWriter(headerType, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
elfWriter.addSection(CLElfLib::SSectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_OPTIONS, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "BuildOptions", options, static_cast<uint32_t>(strlen(options.c_str()) + 1u)));
std::string irBinaryTemp = irBinary ? std::string(irBinary.get(), irBinarySize) : "";
// Add the LLVM component if available
elfWriter.addSection(CLElfLib::SSectionNode(getIsSpirV() ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY, CLElfLib::E_SH_FLAG::SH_FLAG_NONE,
headerType == CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY ? "Intel(R) OpenCL LLVM Archive" : "Intel(R) OpenCL LLVM Object", std::move(irBinaryTemp), static_cast<uint32_t>(irBinarySize)));
// Add the device binary if it exists
if (genBinary) {
std::string genBinaryTemp = genBinary ? std::string(genBinary.get(), genBinarySize) : "";
elfWriter.addSection(CLElfLib::SSectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_BINARY, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "Intel(R) OpenCL Device Binary", std::move(genBinaryTemp), static_cast<uint32_t>(genBinarySize)));
}
// Add the device debug data if it exists
if (debugData != nullptr) {
std::string debugDataTemp = debugData ? std::string(debugData.get(), debugDataSize) : "";
elfWriter.addSection(CLElfLib::SSectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_DEBUG, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "Intel(R) OpenCL Device Debug", std::move(debugDataTemp), static_cast<uint32_t>(debugDataSize)));
}
elfBinarySize = elfWriter.getTotalBinarySize();
elfBinary = CLElfLib::ElfBinaryStorage(elfBinarySize);
elfWriter.resolveBinary(elfBinary);
isProgramBinaryResolved = true;
} else {
return CL_OUT_OF_HOST_MEMORY;
}
return CL_SUCCESS;
}
} // namespace NEO

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "program.h"
namespace NEO {
cl_int Program::processSpirBinary(
const void *pBinary,
size_t binarySize,
bool isSpirV) {
programBinaryType = CL_PROGRAM_BINARY_TYPE_INTERMEDIATE;
this->irBinary = makeCopy(pBinary, binarySize);
this->irBinarySize = binarySize;
buildStatus = CL_BUILD_NONE;
this->isSpirV = isSpirV;
return CL_SUCCESS;
}
} // namespace NEO

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "program.h"
namespace NEO {
bool Program::isValidSpirvBinary(
const void *pBinary,
size_t binarySize) {
const uint32_t magicWord[2] = {0x03022307, 0x07230203};
bool retVal = false;
if (pBinary && (binarySize > sizeof(uint32_t))) {
if ((memcmp(pBinary, &magicWord[0], sizeof(uint32_t)) == 0) ||
(memcmp(pBinary, &magicWord[1], sizeof(uint32_t)) == 0)) {
retVal = true;
}
}
return retVal;
}
cl_int Program::processSpirBinary(
const void *pBinary,
size_t binarySize,
bool isSpirV) {
programBinaryType = CL_PROGRAM_BINARY_TYPE_INTERMEDIATE;
this->irBinary = makeCopy(pBinary, binarySize);
this->irBinarySize = binarySize;
buildStatus = CL_BUILD_NONE;
this->isSpirV = isSpirV;
return CL_SUCCESS;
}
} // namespace NEO

View File

@@ -8,7 +8,10 @@
#include "program.h"
#include "core/compiler_interface/compiler_interface.h"
#include "core/elf/writer.h"
#include "core/compiler_interface/intermediate_representations.h"
#include "core/device_binary_format/device_binary_formats.h"
#include "core/device_binary_format/elf/elf_encoder.h"
#include "core/device_binary_format/elf/ocl_elf.h"
#include "core/helpers/debug_helpers.h"
#include "core/helpers/hw_helper.h"
#include "core/helpers/string.h"
@@ -43,22 +46,6 @@ Program::Program(ExecutionEnvironment &executionEnvironment, Context *context, b
blockKernelManager = new BlockKernelManager();
pDevice = context ? context->getDevice(0) : nullptr;
numDevices = 1;
elfBinarySize = 0;
genBinary = nullptr;
genBinarySize = 0;
irBinary = nullptr;
irBinarySize = 0;
debugData = nullptr;
debugDataSize = 0;
buildStatus = CL_BUILD_NONE;
programBinaryType = CL_PROGRAM_BINARY_TYPE_NONE;
isCreatedFromBinary = false;
isProgramBinaryResolved = false;
constantSurface = nullptr;
globalSurface = nullptr;
globalVarTotalSize = 0;
programOptionVersion = 12u;
allowNonUniform = false;
char paramValue[32] = {};
bool force32BitAddressess = false;
@@ -111,8 +98,6 @@ Program::Program(ExecutionEnvironment &executionEnvironment, Context *context, b
}
Program::~Program() {
elfBinarySize = 0;
cleanCurrentKernelInfo();
freeBlockResources();
@@ -146,28 +131,68 @@ cl_int Program::createProgramFromBinary(
const void *pBinary,
size_t binarySize) {
cl_int retVal = CL_INVALID_PROGRAM;
uint32_t binaryVersion = iOpenCL::CURRENT_ICBE_VERSION;
cl_int retVal = CL_INVALID_BINARY;
if (Program::isValidLlvmBinary(pBinary, binarySize)) {
retVal = processSpirBinary(pBinary, binarySize, false);
} else if (Program::isValidSpirvBinary(pBinary, binarySize)) {
retVal = processSpirBinary(pBinary, binarySize, true);
} else {
bool rebuildRequired = DebugManager.flags.RebuildPrecompiledKernels.get();
retVal = processElfBinary(pBinary, binarySize, binaryVersion);
if (retVal == CL_SUCCESS) {
isCreatedFromBinary = true;
} else if (binaryVersion != iOpenCL::CURRENT_ICBE_VERSION) {
// Version of compiler used to create program binary is invalid,
// needs to recompile program binary from its IR (if available).
// if recompile fails propagate error retVal from previous function
rebuildRequired = true;
this->irBinary.reset();
this->irBinarySize = 0U;
this->isSpirV = false;
this->unpackedDeviceBinary.reset();
this->unpackedDeviceBinarySize = 0U;
this->packedDeviceBinary.reset();
this->packedDeviceBinarySize = 0U;
ArrayRef<const uint8_t> archive(reinterpret_cast<const uint8_t *>(pBinary), binarySize);
bool isSpirV = NEO::isSpirVBitcode(archive);
if (isSpirV || NEO::isLlvmBitcode(archive)) {
this->programBinaryType = CL_PROGRAM_BINARY_TYPE_INTERMEDIATE;
retVal = processSpirBinary(archive.begin(), archive.size(), isSpirV);
} else if (isAnyDeviceBinaryFormat(archive)) {
this->programBinaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
this->isCreatedFromBinary = true;
auto productAbbreviation = hardwarePrefix[pDevice->getHardwareInfo().platform.eProductFamily];
TargetDevice targetDevice = {};
targetDevice.coreFamily = pDevice->getHardwareInfo().platform.eRenderCoreFamily;
targetDevice.stepping = pDevice->getHardwareInfo().platform.usRevId;
targetDevice.maxPointerSizeInBytes = sizeof(uintptr_t);
std::string decodeErrors;
std::string decodeWarnings;
auto singleDeviceBinary = unpackSingleDeviceBinary(archive, ConstStringRef(productAbbreviation, strlen(productAbbreviation)), targetDevice,
decodeErrors, decodeWarnings);
if (decodeWarnings.empty() == false) {
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeWarnings.c_str());
}
if (rebuildRequired) {
if (rebuildProgramFromIr() == CL_SUCCESS) {
retVal = CL_SUCCESS;
if (singleDeviceBinary.intermediateRepresentation.empty() && singleDeviceBinary.deviceBinary.empty()) {
retVal = CL_INVALID_BINARY;
printDebugString(DebugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeErrors.c_str());
} else {
retVal = CL_SUCCESS;
this->irBinary = makeCopy(reinterpret_cast<const char *>(singleDeviceBinary.intermediateRepresentation.begin()), singleDeviceBinary.intermediateRepresentation.size());
this->irBinarySize = singleDeviceBinary.intermediateRepresentation.size();
this->isSpirV = NEO::isSpirVBitcode(ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(this->irBinary.get()), this->irBinarySize));
this->options = singleDeviceBinary.buildOptions.str();
if ((false == singleDeviceBinary.deviceBinary.empty()) && (false == DebugManager.flags.RebuildPrecompiledKernels.get())) {
this->unpackedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(singleDeviceBinary.deviceBinary.begin()), singleDeviceBinary.deviceBinary.size());
this->unpackedDeviceBinarySize = singleDeviceBinary.deviceBinary.size();
this->packedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(archive.begin()), archive.size());
this->packedDeviceBinarySize = archive.size();
} else {
this->isCreatedFromBinary = false;
}
switch (singleDeviceBinary.format) {
default:
break;
case DeviceBinaryFormat::OclLibrary:
this->programBinaryType = CL_PROGRAM_BINARY_TYPE_LIBRARY;
break;
case DeviceBinaryFormat::OclCompiledObject:
this->programBinaryType = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
break;
}
}
}
@@ -175,60 +200,6 @@ cl_int Program::createProgramFromBinary(
return retVal;
}
cl_int Program::rebuildProgramFromIr() {
size_t dataSize;
isSpirV = false;
if (Program::isValidSpirvBinary(irBinary.get(), irBinarySize)) {
isSpirV = true;
} else if (false == Program::isValidLlvmBinary(irBinary.get(), irBinarySize)) {
return CL_INVALID_PROGRAM;
}
CLElfLib::CElfWriter elfWriter(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
elfWriter.addSection(CLElfLib::SSectionNode(isSpirV ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY,
CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "", std::string(irBinary.get(), irBinarySize), static_cast<uint32_t>(irBinarySize)));
dataSize = elfWriter.getTotalBinarySize();
CLElfLib::ElfBinaryStorage data(dataSize);
elfWriter.resolveBinary(data);
CompilerInterface *pCompilerInterface = this->executionEnvironment.getCompilerInterface();
if (nullptr == pCompilerInterface) {
return CL_OUT_OF_HOST_MEMORY;
}
TranslationInput inputArgs = {IGC::CodeType::elf, IGC::CodeType::oclGenBin};
inputArgs.src = ArrayRef<const char>(data);
inputArgs.apiOptions = ArrayRef<const char>(options);
inputArgs.internalOptions = ArrayRef<const char>(internalOptions);
TranslationOutput compilerOuput = {};
auto err = pCompilerInterface->link(this->pDevice->getDevice(), inputArgs, compilerOuput);
this->updateBuildLog(this->pDevice, compilerOuput.frontendCompilerLog.c_str(), compilerOuput.frontendCompilerLog.size());
this->updateBuildLog(this->pDevice, compilerOuput.backendCompilerLog.c_str(), compilerOuput.backendCompilerLog.size());
if (TranslationOutput::ErrorCode::Success != err) {
return asClError(err);
}
this->genBinary = std::move(compilerOuput.deviceBinary.mem);
this->genBinarySize = compilerOuput.deviceBinary.size;
this->debugData = std::move(compilerOuput.debugData.mem);
this->debugDataSize = compilerOuput.debugData.size;
auto retVal = processGenBinary();
if (retVal != CL_SUCCESS) {
return retVal;
}
programBinaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
isCreatedFromBinary = true;
isProgramBinaryResolved = true;
return CL_SUCCESS;
}
cl_int Program::setProgramSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue) {
if (!isSpirV) {
return CL_INVALID_PROGRAM;
@@ -270,22 +241,6 @@ cl_int Program::updateSpecializationConstant(cl_uint specId, size_t specSize, co
return CL_INVALID_SPEC_ID;
}
bool Program::isValidLlvmBinary(
const void *pBinary,
size_t binarySize) {
const char *pLlvmMagic = "BC\xc0\xde";
bool retVal = false;
if (pBinary && (binarySize > (strlen(pLlvmMagic) + 1))) {
if (strstr((char *)pBinary, pLlvmMagic) != nullptr) {
retVal = true;
}
}
return retVal;
}
void Program::setDevice(Device *device) {
this->pDevice = device->getSpecializedDevice<ClDevice>();
}
@@ -456,4 +411,61 @@ void Program::updateNonUniformFlag(const Program **inputPrograms, size_t numInpu
this->allowNonUniform = allowNonUniform;
}
void Program::replaceDeviceBinary(std::unique_ptr<char[]> newBinary, size_t newBinarySize) {
if (isAnyPackedDeviceBinaryFormat(ArrayRef<const uint8_t>(reinterpret_cast<uint8_t *>(newBinary.get()), newBinarySize))) {
this->packedDeviceBinary = std::move(newBinary);
this->packedDeviceBinarySize = newBinarySize;
this->unpackedDeviceBinary.reset();
this->unpackedDeviceBinarySize = 0U;
} else {
this->packedDeviceBinary.reset();
this->packedDeviceBinarySize = 0U;
this->unpackedDeviceBinary = std::move(newBinary);
this->unpackedDeviceBinarySize = newBinarySize;
}
}
cl_int Program::packDeviceBinary() {
if (nullptr != packedDeviceBinary) {
return CL_SUCCESS;
}
auto gfxCore = pDevice->getHardwareInfo().platform.eRenderCoreFamily;
auto stepping = pDevice->getHardwareInfo().platform.usRevId;
if (nullptr != this->unpackedDeviceBinary.get()) {
SingleDeviceBinary singleDeviceBinary;
singleDeviceBinary.buildOptions = this->options;
singleDeviceBinary.targetDevice.coreFamily = gfxCore;
singleDeviceBinary.targetDevice.stepping = stepping;
singleDeviceBinary.deviceBinary = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(this->unpackedDeviceBinary.get()), this->unpackedDeviceBinarySize);
singleDeviceBinary.intermediateRepresentation = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(this->irBinary.get()), this->irBinarySize);
std::string packWarnings;
std::string packErrors;
auto packedDeviceBinary = NEO::packDeviceBinary(singleDeviceBinary, packErrors, packWarnings);
if (packedDeviceBinary.empty()) {
DEBUG_BREAK_IF(true);
return CL_OUT_OF_HOST_MEMORY;
}
this->packedDeviceBinary = makeCopy(packedDeviceBinary.data(), packedDeviceBinary.size());
this->packedDeviceBinarySize = packedDeviceBinary.size();
} else if (nullptr != this->irBinary.get()) {
NEO::Elf::ElfEncoder<> elfEncoder(true, true, 1U);
if (this->programBinaryType == CL_PROGRAM_BINARY_TYPE_LIBRARY) {
elfEncoder.getElfFileHeader().type = NEO::Elf::ET_OPENCL_LIBRARY;
} else {
elfEncoder.getElfFileHeader().type = NEO::Elf::ET_OPENCL_OBJECTS;
}
elfEncoder.appendSection(NEO::Elf::SHT_OPENCL_SPIRV, NEO::Elf::SectionNamesOpenCl::spirvObject, ArrayRef<const uint8_t>::fromAny(this->irBinary.get(), this->irBinarySize));
elfEncoder.appendSection(NEO::Elf::SHT_OPENCL_OPTIONS, NEO::Elf::SectionNamesOpenCl::buildOptions, this->options);
auto elfData = elfEncoder.encode();
this->packedDeviceBinary = makeCopy(elfData.data(), elfData.size());
this->packedDeviceBinarySize = elfData.size();
} else {
return CL_INVALID_PROGRAM;
}
return CL_SUCCESS;
}
} // namespace NEO

View File

@@ -8,7 +8,7 @@
#pragma once
#include "core/compiler_interface/compiler_interface.h"
#include "core/compiler_interface/linker.h"
#include "core/elf/writer.h"
#include "core/device_binary_format/elf/elf_encoder.h"
#include "core/program/program_info.h"
#include "core/utilities/const_stringref.h"
#include "runtime/api/cl_types.h"
@@ -132,7 +132,6 @@ class Program : public BaseObject<_cl_program> {
std::unordered_map<std::string, BuiltinDispatchInfoBuilder *> &builtinsMap);
MOCKABLE_VIRTUAL cl_int processGenBinary();
MOCKABLE_VIRTUAL cl_int processPatchTokensBinary(ArrayRef<const uint8_t> src, ProgramInfo &dst);
MOCKABLE_VIRTUAL cl_int processProgramInfo(ProgramInfo &dst);
cl_int compile(cl_uint numDevices, const cl_device_id *deviceList, const char *buildOptions,
@@ -181,7 +180,6 @@ class Program : public BaseObject<_cl_program> {
void setDevice(Device *device);
MOCKABLE_VIRTUAL cl_int processElfBinary(const void *pBinary, size_t binarySize, uint32_t &binaryVersion);
cl_int processSpirBinary(const void *pBinary, size_t binarySize, bool isSpirV);
cl_int getSource(std::string &binary) const;
@@ -238,8 +236,6 @@ class Program : public BaseObject<_cl_program> {
kernelDebugEnabled = true;
}
static bool isValidLlvmBinary(const void *pBinary, size_t binarySize);
static bool isValidSpirvBinary(const void *pBinary, size_t binarySize);
bool isKernelDebugEnabled() {
return kernelDebugEnabled;
}
@@ -260,24 +256,17 @@ class Program : public BaseObject<_cl_program> {
return this->linkerInput.get();
}
MOCKABLE_VIRTUAL bool isSafeToSkipUnhandledToken(unsigned int token) const;
MOCKABLE_VIRTUAL void replaceDeviceBinary(std::unique_ptr<char[]> newBinary, size_t newBinarySize);
protected:
Program(ExecutionEnvironment &executionEnvironment);
MOCKABLE_VIRTUAL cl_int createProgramFromBinary(const void *pBinary, size_t binarySize);
cl_int resolveProgramBinary();
cl_int packDeviceBinary();
MOCKABLE_VIRTUAL cl_int linkBinary();
MOCKABLE_VIRTUAL cl_int isHandled(const PatchTokenBinary::ProgramFromPatchtokens &decodedProgram) const;
MOCKABLE_VIRTUAL cl_int rebuildProgramFromIr();
bool validateGenBinaryDevice(GFXCORE_FAMILY device) const;
bool validateGenBinaryHeader(const iOpenCL::SProgramBinaryHeader *pGenBinaryHeader) const;
void separateBlockKernels();
void updateNonUniformFlag();
@@ -293,19 +282,20 @@ class Program : public BaseObject<_cl_program> {
static const std::string clOptNameClVer;
cl_program_binary_type programBinaryType;
cl_program_binary_type programBinaryType = CL_PROGRAM_BINARY_TYPE_NONE;
bool isSpirV = false;
CLElfLib::ElfBinaryStorage elfBinary;
size_t elfBinarySize;
std::unique_ptr<char[]> genBinary;
size_t genBinarySize;
std::unique_ptr<char[]> irBinary;
size_t irBinarySize;
size_t irBinarySize = 0U;
std::unique_ptr<char[]> unpackedDeviceBinary;
size_t unpackedDeviceBinarySize = 0U;
std::unique_ptr<char[]> packedDeviceBinary;
size_t packedDeviceBinarySize = 0U;
std::unique_ptr<char[]> debugData;
size_t debugDataSize;
size_t debugDataSize = 0U;
CreatedFrom createdFrom = CreatedFrom::UNKNOWN;
@@ -313,23 +303,22 @@ class Program : public BaseObject<_cl_program> {
std::vector<KernelInfo *> parentKernelInfoArray;
std::vector<KernelInfo *> subgroupKernelInfoArray;
GraphicsAllocation *constantSurface;
GraphicsAllocation *globalSurface;
GraphicsAllocation *constantSurface = nullptr;
GraphicsAllocation *globalSurface = nullptr;
GraphicsAllocation *exportedFunctionsSurface = nullptr;
size_t globalVarTotalSize;
size_t globalVarTotalSize = 0U;
cl_build_status buildStatus;
bool isCreatedFromBinary;
bool isProgramBinaryResolved;
cl_build_status buildStatus = CL_BUILD_NONE;
bool isCreatedFromBinary = false;
std::string sourceCode;
std::string options;
std::string internalOptions;
static const std::vector<ConstStringRef> internalOptionsToExtract;
uint32_t programOptionVersion;
bool allowNonUniform;
uint32_t programOptionVersion = 12U;
bool allowNonUniform = false;
std::unique_ptr<LinkerInput> linkerInput;
Linker::RelocatedSymbolsMap symbols;
@@ -341,13 +330,13 @@ class Program : public BaseObject<_cl_program> {
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsSizes;
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsValues;
BlockKernelManager *blockKernelManager;
BlockKernelManager *blockKernelManager = nullptr;
ExecutionEnvironment &executionEnvironment;
Context *context;
ClDevice *pDevice;
cl_uint numDevices;
Context *context = nullptr;
ClDevice *pDevice = nullptr;
cl_uint numDevices = 0U;
bool isBuiltIn;
bool isBuiltIn = false;
bool kernelDebugEnabled = false;
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 Intel Corporation
* Copyright (C) 2019-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -8,7 +8,18 @@
#pragma once
#include "core/debug_settings/debug_settings_manager.h"
#include <cinttypes>
#include <cstddef>
#include <iostream>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>
namespace NEO {
class Kernel;
struct MultiDispatchInfo;
template <DebugFunctionalityLevel DebugLevel>
class FileLogger {
public: