2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2019-01-24 17:00:27 +08:00
|
|
|
* Copyright (C) 2017-2019 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
2019-07-04 23:14:51 +08:00
|
|
|
#include "core/compiler_interface/linker.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "elf/reader.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
#include "elf/writer.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/api/cl_types.h"
|
|
|
|
#include "runtime/helpers/base_object.h"
|
|
|
|
#include "runtime/helpers/stdio.h"
|
|
|
|
#include "runtime/helpers/string_helpers.h"
|
2019-09-03 20:20:32 +08:00
|
|
|
#include "runtime/program/block_kernel_manager.h"
|
|
|
|
#include "runtime/program/kernel_info.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
#include "cif/builtins/memory/buffer/buffer.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "igfxfmid.h"
|
|
|
|
#include "patch_list.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <map>
|
2019-02-27 18:39:32 +08:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
#define OCLRT_ALIGN(a, b) ((((a) % (b)) != 0) ? ((a) - ((a) % (b)) + (b)) : (a))
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
namespace NEO {
|
2017-12-21 07:45:38 +08:00
|
|
|
class Context;
|
|
|
|
class CompilerInterface;
|
2018-08-06 15:46:57 +08:00
|
|
|
class ExecutionEnvironment;
|
2017-12-21 07:45:38 +08:00
|
|
|
template <>
|
|
|
|
struct OpenCLObjectMapper<_cl_program> {
|
|
|
|
typedef class Program DerivedType;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool isSafeToSkipUnhandledToken(unsigned int token);
|
|
|
|
|
|
|
|
class Program : public BaseObject<_cl_program> {
|
|
|
|
public:
|
|
|
|
static const cl_ulong objectMagic = 0x5651C89100AAACFELL;
|
|
|
|
|
2019-03-15 22:26:06 +08:00
|
|
|
enum class CreatedFrom {
|
|
|
|
SOURCE,
|
|
|
|
IL,
|
|
|
|
BINARY,
|
|
|
|
UNKNOWN
|
|
|
|
};
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
// Create program from binary
|
|
|
|
template <typename T = Program>
|
|
|
|
static T *create(
|
|
|
|
cl_context context,
|
|
|
|
cl_uint numDevices,
|
|
|
|
const cl_device_id *deviceList,
|
|
|
|
const size_t *lengths,
|
|
|
|
const unsigned char **binaries,
|
|
|
|
cl_int *binaryStatus,
|
|
|
|
cl_int &errcodeRet);
|
|
|
|
|
|
|
|
// Create program from source
|
|
|
|
template <typename T = Program>
|
|
|
|
static T *create(
|
|
|
|
cl_context context,
|
|
|
|
cl_uint count,
|
|
|
|
const char **strings,
|
|
|
|
const size_t *lengths,
|
|
|
|
cl_int &errcodeRet);
|
|
|
|
|
|
|
|
template <typename T = Program>
|
|
|
|
static T *create(
|
|
|
|
const char *nullTerminatedString,
|
|
|
|
Context *context,
|
|
|
|
Device &device,
|
2018-05-28 22:16:06 +08:00
|
|
|
bool isBuiltIn,
|
2017-12-21 07:45:38 +08:00
|
|
|
cl_int *errcodeRet);
|
|
|
|
|
|
|
|
template <typename T = Program>
|
|
|
|
static T *createFromGenBinary(
|
2018-08-14 16:56:42 +08:00
|
|
|
ExecutionEnvironment &executionEnvironment,
|
2017-12-21 07:45:38 +08:00
|
|
|
Context *context,
|
|
|
|
const void *binary,
|
|
|
|
size_t size,
|
2018-05-28 22:16:06 +08:00
|
|
|
bool isBuiltIn,
|
2018-08-08 19:05:16 +08:00
|
|
|
cl_int *errcodeRet);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
template <typename T = Program>
|
|
|
|
static T *createFromIL(Context *context,
|
|
|
|
const void *il,
|
|
|
|
size_t length,
|
|
|
|
cl_int &errcodeRet);
|
|
|
|
|
2018-08-06 15:46:57 +08:00
|
|
|
Program(ExecutionEnvironment &executionEnvironment, Context *context, bool isBuiltIn);
|
2017-12-21 07:45:38 +08:00
|
|
|
~Program() override;
|
|
|
|
|
|
|
|
Program(const Program &) = delete;
|
|
|
|
Program &operator=(const Program &) = delete;
|
|
|
|
|
|
|
|
cl_int build(cl_uint numDevices, const cl_device_id *deviceList, const char *buildOptions,
|
|
|
|
void(CL_CALLBACK *funcNotify)(cl_program program, void *userData),
|
|
|
|
void *userData, bool enableCaching);
|
|
|
|
|
|
|
|
cl_int build(const cl_device_id device, const char *buildOptions, bool enableCaching,
|
|
|
|
std::unordered_map<std::string, BuiltinDispatchInfoBuilder *> &builtinsMap);
|
|
|
|
|
|
|
|
cl_int build(const char *pKernelData, size_t kernelDataSize);
|
|
|
|
|
|
|
|
MOCKABLE_VIRTUAL cl_int processGenBinary();
|
|
|
|
|
|
|
|
cl_int compile(cl_uint numDevices, const cl_device_id *deviceList, const char *buildOptions,
|
|
|
|
cl_uint numInputHeaders, const cl_program *inputHeaders, const char **headerIncludeNames,
|
|
|
|
void(CL_CALLBACK *funcNotify)(cl_program program, void *userData),
|
|
|
|
void *userData);
|
|
|
|
|
|
|
|
cl_int link(cl_uint numDevices, const cl_device_id *deviceList, const char *buildOptions,
|
|
|
|
cl_uint numInputPrograms, const cl_program *inputPrograms,
|
|
|
|
void(CL_CALLBACK *funcNotify)(cl_program program, void *userData),
|
|
|
|
void *userData);
|
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
cl_int setProgramSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue);
|
|
|
|
MOCKABLE_VIRTUAL cl_int updateSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue);
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t getNumKernels() const;
|
|
|
|
const KernelInfo *getKernelInfo(const char *kernelName) const;
|
|
|
|
const KernelInfo *getKernelInfo(size_t ordinal) const;
|
|
|
|
|
|
|
|
cl_int getInfo(cl_program_info paramName, size_t paramValueSize,
|
|
|
|
void *paramValue, size_t *paramValueSizeRet);
|
|
|
|
|
|
|
|
cl_int getBuildInfo(cl_device_id device, cl_program_build_info paramName,
|
|
|
|
size_t paramValueSize, void *paramValue, size_t *paramValueSizeRet) const;
|
|
|
|
|
2018-08-10 14:26:09 +08:00
|
|
|
cl_build_status getBuildStatus() const {
|
|
|
|
return buildStatus;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
Context &getContext() const {
|
|
|
|
return *context;
|
|
|
|
}
|
|
|
|
|
|
|
|
Context *getContextPtr() const {
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
2018-08-06 15:46:57 +08:00
|
|
|
ExecutionEnvironment &peekExecutionEnvironment() const {
|
|
|
|
return executionEnvironment;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
const Device &getDevice(cl_uint deviceOrdinal) const {
|
2019-07-04 23:14:51 +08:00
|
|
|
UNRECOVERABLE_IF(pDevice == nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
return *pDevice;
|
|
|
|
}
|
|
|
|
|
2018-03-09 18:52:14 +08:00
|
|
|
void setDevice(Device *device) { this->pDevice = device; }
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
cl_uint getNumDevices() const {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2018-08-06 17:07:12 +08:00
|
|
|
void setSource(const char *pSourceString);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
cl_int getSource(char *&pBinary, unsigned int &dataSize) const;
|
|
|
|
|
2018-07-28 04:59:40 +08:00
|
|
|
cl_int getSource(std::string &binary) const;
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
void storeGenBinary(const void *pSrc, const size_t srcSize);
|
|
|
|
|
|
|
|
char *getGenBinary(size_t &genBinarySize) const {
|
|
|
|
genBinarySize = this->genBinarySize;
|
|
|
|
return this->genBinary;
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:36:23 +08:00
|
|
|
void storeIrBinary(const void *pSrc, const size_t srcSize, bool isSpirV);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
void storeDebugData(const void *pSrc, const size_t srcSize);
|
2018-05-02 20:27:55 +08:00
|
|
|
void processDebugData();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
void updateBuildLog(const Device *pDevice, const char *pErrorString, const size_t errorStringSize);
|
|
|
|
|
|
|
|
const char *getBuildLog(const Device *pDevice) const;
|
|
|
|
|
|
|
|
cl_uint getProgramBinaryType() const {
|
|
|
|
return programBinaryType;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool getIsSpirV() const {
|
|
|
|
return isSpirV;
|
|
|
|
}
|
|
|
|
|
2019-04-12 17:31:42 +08:00
|
|
|
bool isCreatedFromIL() const {
|
|
|
|
return createdFrom == CreatedFrom::IL;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
size_t getProgramScopePatchListSize() const {
|
|
|
|
return programScopePatchListSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
GraphicsAllocation *getConstantSurface() const {
|
|
|
|
return constantSurface;
|
|
|
|
}
|
|
|
|
|
|
|
|
GraphicsAllocation *getGlobalSurface() const {
|
|
|
|
return globalSurface;
|
|
|
|
}
|
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
GraphicsAllocation *getExportedFunctionsSurface() const {
|
|
|
|
return exportedFunctionsSurface;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
BlockKernelManager *getBlockKernelManager() const {
|
|
|
|
return blockKernelManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
void allocateBlockPrivateSurfaces();
|
2018-03-08 18:56:44 +08:00
|
|
|
void freeBlockResources();
|
|
|
|
void cleanCurrentKernelInfo();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
const std::string &getOptions() const { return options; }
|
|
|
|
|
|
|
|
const std::string &getInternalOptions() const { return internalOptions; }
|
|
|
|
|
|
|
|
bool getAllowNonUniform() const {
|
|
|
|
return allowNonUniform;
|
|
|
|
}
|
2018-05-28 22:16:06 +08:00
|
|
|
bool getIsBuiltIn() const {
|
|
|
|
return isBuiltIn;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
uint32_t getProgramOptionVersion() const {
|
|
|
|
return programOptionVersion;
|
|
|
|
}
|
|
|
|
|
2018-03-09 21:40:31 +08:00
|
|
|
void enableKernelDebug() {
|
|
|
|
kernelDebugEnabled = true;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
static bool isValidLlvmBinary(const void *pBinary, size_t binarySize);
|
|
|
|
static bool isValidSpirvBinary(const void *pBinary, size_t binarySize);
|
2018-03-21 19:58:30 +08:00
|
|
|
bool isKernelDebugEnabled() {
|
|
|
|
return kernelDebugEnabled;
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-08-06 19:19:32 +08:00
|
|
|
char *getDebugData() {
|
|
|
|
return debugData;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t getDebugDataSize() {
|
|
|
|
return debugDataSize;
|
|
|
|
}
|
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> &getSpecConstIdsBuffer() {
|
|
|
|
return this->specConstantsIds;
|
|
|
|
}
|
|
|
|
|
|
|
|
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> &getSpecConstValuesBuffer() {
|
|
|
|
return this->specConstantsValues;
|
|
|
|
}
|
|
|
|
|
|
|
|
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> &getSpecConstSizesBuffer() {
|
|
|
|
return this->specConstantsSizes;
|
|
|
|
}
|
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
const Linker::RelocatedSymbolsMap &getSymbols() const {
|
|
|
|
return this->symbols;
|
|
|
|
}
|
|
|
|
|
|
|
|
LinkerInput *getLinkerInput() const {
|
|
|
|
return this->linkerInput.get();
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
protected:
|
2018-08-06 15:46:57 +08:00
|
|
|
Program(ExecutionEnvironment &executionEnvironment);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
MOCKABLE_VIRTUAL bool isSafeToSkipUnhandledToken(unsigned int token) const;
|
|
|
|
|
|
|
|
MOCKABLE_VIRTUAL cl_int createProgramFromBinary(const void *pBinary, size_t binarySize);
|
|
|
|
|
|
|
|
bool optionsAreNew(const char *options) const;
|
|
|
|
|
|
|
|
cl_int processElfHeader(const CLElfLib::SElf64Header *pElfHeader,
|
|
|
|
cl_program_binary_type &binaryType, uint32_t &numSections);
|
|
|
|
|
|
|
|
void getProgramCompilerVersion(SProgramBinaryHeader *pSectionData, uint32_t &binaryVersion) const;
|
|
|
|
|
|
|
|
cl_int resolveProgramBinary();
|
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
MOCKABLE_VIRTUAL cl_int linkBinary();
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
cl_int parseProgramScopePatchList();
|
|
|
|
|
2018-06-18 20:36:23 +08:00
|
|
|
MOCKABLE_VIRTUAL cl_int rebuildProgramFromIr();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
cl_int parsePatchList(KernelInfo &pKernelInfo, uint32_t kernelNum);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
size_t processKernel(const void *pKernelBlob, uint32_t kernelNum, cl_int &retVal);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
void storeBinary(char *&pDst, size_t &dstSize, const void *pSrc, const size_t srcSize);
|
|
|
|
|
|
|
|
bool validateGenBinaryDevice(GFXCORE_FAMILY device) const;
|
|
|
|
bool validateGenBinaryHeader(const iOpenCL::SProgramBinaryHeader *pGenBinaryHeader) const;
|
|
|
|
|
|
|
|
std::string getKernelNamesString() const;
|
|
|
|
|
|
|
|
void separateBlockKernels();
|
|
|
|
|
|
|
|
void updateNonUniformFlag();
|
|
|
|
void updateNonUniformFlag(const Program **inputProgram, size_t numInputPrograms);
|
|
|
|
|
2018-10-02 21:08:23 +08:00
|
|
|
void extractInternalOptions(std::string &options);
|
2019-01-24 17:00:27 +08:00
|
|
|
MOCKABLE_VIRTUAL void applyAdditionalOptions();
|
2018-10-02 21:08:23 +08:00
|
|
|
|
2018-12-05 17:58:08 +08:00
|
|
|
MOCKABLE_VIRTUAL bool appendKernelDebugOptions();
|
|
|
|
void notifyDebuggerWithSourceCode(std::string &filename);
|
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
void prepareLinkerInputStorage();
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
static const std::string clOptNameClVer;
|
|
|
|
static const std::string clOptNameUniformWgs;
|
2019-04-25 18:46:43 +08:00
|
|
|
|
|
|
|
cl_program_binary_type programBinaryType;
|
|
|
|
bool isSpirV = false;
|
2018-07-28 04:59:40 +08:00
|
|
|
CLElfLib::ElfBinaryStorage elfBinary;
|
2019-04-25 18:46:43 +08:00
|
|
|
size_t elfBinarySize;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
char *genBinary;
|
|
|
|
size_t genBinarySize;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
char *irBinary;
|
|
|
|
size_t irBinarySize;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
char *debugData;
|
|
|
|
size_t debugDataSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
CreatedFrom createdFrom = CreatedFrom::UNKNOWN;
|
2019-03-15 22:26:06 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
std::vector<KernelInfo *> kernelInfoArray;
|
|
|
|
std::vector<KernelInfo *> parentKernelInfoArray;
|
|
|
|
std::vector<KernelInfo *> subgroupKernelInfoArray;
|
|
|
|
BlockKernelManager *blockKernelManager;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
const void *programScopePatchList;
|
|
|
|
size_t programScopePatchListSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
GraphicsAllocation *constantSurface;
|
|
|
|
GraphicsAllocation *globalSurface;
|
2019-07-04 23:14:51 +08:00
|
|
|
GraphicsAllocation *exportedFunctionsSurface = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
size_t globalVarTotalSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
cl_build_status buildStatus;
|
|
|
|
bool isCreatedFromBinary;
|
|
|
|
bool isProgramBinaryResolved;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
std::string sourceCode;
|
|
|
|
std::string options;
|
|
|
|
std::string internalOptions;
|
2018-10-02 21:08:23 +08:00
|
|
|
static const std::vector<std::string> internalOptionsToExtract;
|
2019-04-25 18:46:43 +08:00
|
|
|
std::string hashFileName;
|
|
|
|
std::string hashFilePath;
|
|
|
|
|
|
|
|
uint32_t programOptionVersion;
|
|
|
|
bool allowNonUniform;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
std::unique_ptr<LinkerInput> linkerInput;
|
|
|
|
Linker::RelocatedSymbolsMap symbols;
|
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
std::map<const Device *, std::string> buildLog;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
bool areSpecializationConstantsInitialized = false;
|
|
|
|
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsIds;
|
|
|
|
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsSizes;
|
|
|
|
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsValues;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
ExecutionEnvironment &executionEnvironment;
|
|
|
|
Context *context;
|
|
|
|
Device *pDevice;
|
|
|
|
cl_uint numDevices;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-25 18:46:43 +08:00
|
|
|
bool isBuiltIn;
|
|
|
|
bool kernelDebugEnabled = false;
|
2017-12-21 07:45:38 +08:00
|
|
|
friend class OfflineCompiler;
|
|
|
|
};
|
2019-03-26 18:59:46 +08:00
|
|
|
} // namespace NEO
|