1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2020-2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#pragma once
#include <vector>
#include <ZEELFObjectBuilder.hpp>
#include "OCL/util/BinaryStream.h"
#include "OCL/CommandStream/SamplerTypes.h"
#include "OCL/Platform/cmd_media_caps_g8.h"
#include "ocl_igc_shared/executable_format/patch_list.h"
#include "llvm/BinaryFormat/ELF.h"
#include "CLElfLib/ElfReader.h"
namespace IGC {
struct SOpenCLKernelInfo;
struct SOpenCLKernelCostExpInfo;
struct SOpenCLProgramInfo;
class CBTILayout;
class OpenCLProgramContext;
} // namespace IGC
namespace vISA {
struct ZESymEntry;
struct ZEFuncAttribEntry;
} // namespace vISA
namespace iOpenCL {
class DisallowCopy {
public:
DisallowCopy() {};
virtual ~DisallowCopy() {};
private:
DisallowCopy(const DisallowCopy &);
DisallowCopy &operator=(const DisallowCopy &);
};
/// ZEBinaryBuilder - Provides services to create a ZE Binary from given
/// SProgramOutput information
class ZEBinaryBuilder : DisallowCopy {
public:
// Setup ZEBin platform, and ELF header information. The program scope information
// is also be parsed from SOpenCLProgramInfo in the constructor
ZEBinaryBuilder(const PLATFORM plat, bool is64BitPointer, const IGC::SOpenCLProgramInfo &programInfo,
const uint8_t *spvData, uint32_t spvSize, const uint8_t *metricsData, uint32_t metricsSize,
const uint8_t *buildOptions, uint32_t buildOptionsSize);
// Set the ProductFamily as the specified value.
void setProductFamily(PRODUCT_FAMILY value);
// Set the GfxCoreFamily as the specified value.
void setGfxCoreFamily(GFXCORE_FAMILY value);
// Set VISA ABI version used in generated code.
void setVISAABIVersion(unsigned int ver);
// Set the GmdId as the specified value.
void setGmdID(GFX_GMD_ID value);
// Pair of name for the section (1st elem) and VISA asm text (2nd elem).
using NamedVISAAsm = std::pair<std::string, std::string>;
/// add kernel information. Also create kernel metadata information for .ze_info
/// This function can be called several times for adding different kernel information
/// into this ZEObject
/// The given rawIsaBinary must be lived through the entire ZEBinaryBuilder life
void createKernel(const char *rawIsaBinary, unsigned int rawIsaBinarySize, const IGC::SOpenCLKernelInfo &annotations,
const IGC::SOpenCLKernelCostExpInfo &costExpAnnotation, const uint32_t grfSize,
const std::vector<NamedVISAAsm> &visaasm);
// getElfSymbol - find a symbol name in ELF binary and return a symbol entry
// that will later be transformed to ZE binary format
void getElfSymbol(CLElfLib::CElfReader *elfReader, const unsigned int symtabIdx, llvm::ELF::Elf64_Sym &symtabEntry,
char *&symName);
/// addElfSections - copy every section of ELF file (a buffer in memory) to zeBinary
void addElfSections(void *elfBin, size_t elfSize);
/// getBinaryObject - get the final ze object
void getBinaryObject(llvm::raw_pwrite_stream &os);
// getBinaryObject - write the final object into given Util::BinaryStream
// Avoid using this function, which has extra buffer copy
void getBinaryObject(Util::BinaryStream &outputStream);
void printBinaryObject(const std::string &filename);
// print .ze_info to given os
void printZEInfo(llvm::raw_ostream &os);
// print .ze_info into a file with given filename
void printZEInfo(const std::string &filename);
private:
/// ------------ program scope helper functions ------------
/// add program scope information. This function will be called in the ctor.
/// The program scope information include global buffers (data sections for
/// globals and global constants)
/// ProgramScopeInfo must be prepared before kernel information. For example,
/// Symbols are per-kernel information but they could possible refering to
/// program-scope sections such as global buffer.
void addProgramScopeInfo(const IGC::SOpenCLProgramInfo &programInfo);
/// add data section for global constants
void addGlobalConstants(const IGC::SOpenCLProgramInfo &annotations);
/// add data section for globals
void addGlobals(const IGC::SOpenCLProgramInfo &annotations);
/// add spir-v section
void addSPIRV(const uint8_t *data, uint32_t size);
/// add miscellaneous info section (section with SHT_ZEBIN_MISC type)
void addMiscInfoSection(std::string sectName, const uint8_t *data, uint32_t size);
/// add runtime symbols
void addRuntimeSymbols(const IGC::SOpenCLProgramInfo &annotations);
/// add note section for IGC metrics
void addMetrics(const uint8_t *data, uint32_t size);
/// add program scope symbols (e.g. symbols defined in global/const buffer)
void addProgramSymbols(const IGC::SOpenCLProgramInfo &annotations);
/// add program scope relocations (e.g. relocations for global/const buffer)
void addProgramRelocations(const IGC::SOpenCLProgramInfo &annotations);
/// ------------ kernel scope helper functions ------------
/// add gen binary
zebin::ZEELFObjectBuilder::SectionID addKernelBinary(const std::string &kernelName, const char *kernelBinary,
unsigned int kernelBinarySize);
/// add user attributes (kernel attributes)
void addUserAttributes(const IGC::SOpenCLKernelInfo &annotations, zebin::zeInfoKernel &zeinfoKernel);
/// add kernel execution environment
void addKernelExecEnv(const IGC::SOpenCLKernelInfo &annotations, zebin::zeInfoKernel &zeinfoKernel);
/// add execution environment for external function
void addFunctionExecEnv(const IGC::SOpenCLKernelInfo &annotations, const vISA::ZEFuncAttribEntry &zeFuncAttr,
zebin::zeInfoFunction &zeFunction);
/// add experimental properties
void addKernelExperimentalProperties(const IGC::SOpenCLKernelInfo &annotations, zebin::zeInfoKernel &zeinfoKernel);
/// add symbols of this kernel corresponding to kernel binary
/// added by addKernelBinary
void addKernelSymbols(zebin::ZEELFObjectBuilder::SectionID kernelSectId, const IGC::SOpenCLKernelInfo &annotations);
/// get symbol type
/// FIXME: this should be decided when symbol being created
uint8_t getSymbolElfType(const vISA::ZESymEntry &sym);
/// addSymbol - a helper function to add a symbol which is defined in targetSect
void addSymbol(const vISA::ZESymEntry &sym, uint8_t binding, zebin::ZEELFObjectBuilder::SectionID targetSect);
/// add relocations of this kernel corresponding to binary added by
/// addKernelBinary.
void addKernelRelocations(zebin::ZEELFObjectBuilder::SectionID targetId, const IGC::SOpenCLKernelInfo &annotations);
/// add local ids as per-thread payload argument
void addLocalIds(uint32_t simdSize, uint32_t grfSize, bool has_local_id_x, bool has_local_id_y, bool has_local_id_z,
zebin::zeInfoKernel &zeinfoKernel);
/// add payload arguments and BTI info from IGC::SOpenCLKernelInfo
/// payload arguments and BTI info have been added at
/// COpenCLKernel::CreateZEPayloadArguments
void addPayloadArgsAndBTI(const IGC::SOpenCLKernelInfo &annotations, zebin::zeInfoKernel &zeinfoKernel);
/// add inline samplers in IGC::SOpenCLKernelInfo created from
/// COpenCLKernel::CreateZEInlineSamplerPayloadArguments()
void addInlineSamplers(const IGC::SOpenCLKernelInfo &annotations, zebin::zeInfoKernel &zeinfoKernel);
/// add Memory buffer information
void addMemoryBuffer(const IGC::SOpenCLKernelInfo &annotations, zebin::zeInfoKernel &zeinfoKernel);
/// add gtpin_info section
/// Add everything used to be in patch token iOpenCL::PATCH_TOKEN_GTPIN_INFO
/// into gtpin_info section
void addGTPinInfo(const IGC::SOpenCLKernelInfo &annotations);
/// Add function attributes for external functions.
void addFunctionAttrs(const IGC::SOpenCLKernelInfo &annotations);
/// check if the kernel has misc info. The entry of this function in
/// kernels_misc_info should only be created when this function return
/// true
bool hasKernelMiscInfo(const IGC::SOpenCLKernelInfo &annotations) const;
/// check if the kernel has cost info. The kernels_cost_info entry
/// should only be created when this function return true
bool hasKernelCostInfo(const IGC::SOpenCLKernelCostExpInfo &annotations) const;
/// Add kernel arg info
void addKernelArgInfo(const IGC::SOpenCLKernelInfo &annotations, zebin::zeInfoKernelMiscInfo &zeinfoKernelMisc);
/// Add kernel cost info
void addKernelCostInfo(const IGC::SOpenCLKernelCostExpInfo &costExpAnnotation,
zebin::zeInfoKernelCostInfo &zeinfoKernelCost);
/// Calculate correct (pure) size of ELF binary, because m_debugDataSize in kernel output
/// contains something else.
size_t calcElfSize(void *elfBin, size_t elfSize);
/// add visasm of the kernel
void addKernelVISAAsm(const std::string &kernel, const std::string &visaasm);
/// add global_host_access_table section to .ze_info
void addGlobalHostAccessInfo(const IGC::SOpenCLProgramInfo &annotations);
private:
// mBuilder - Builder of a ZE ELF object
zebin::ZEELFObjectBuilder mBuilder;
// mZEInfoBuilder - Builder and holder of a zeInfoContainer, which will
// be added into ZEELFObjectBuilder as .ze_info section
zebin::ZEInfoBuilder mZEInfoBuilder;
const PLATFORM mPlatform;
G6HWC::SMediaHardwareCapabilities mHWCaps;
/// sectionID holder for program scope sections
/// There should be only one global, global constant buffer per program
zebin::ZEELFObjectBuilder::SectionID mGlobalConstSectID = -1;
zebin::ZEELFObjectBuilder::SectionID mConstStringSectID = -1;
zebin::ZEELFObjectBuilder::SectionID mGlobalSectID = -1;
};
// a helper function to get ZE image type from a OCL image type
zebin::PreDefinedAttrGetter::ArgImageType getZEImageType(iOpenCL::IMAGE_MEMORY_OBJECT_TYPE);
// a helper function to get ZE sampler type from a OCL sampler type
zebin::PreDefinedAttrGetter::ArgSamplerType getZESamplerType(iOpenCL::SAMPLER_OBJECT_TYPE);
} // namespace iOpenCL
|