File: zebin_builder.hpp

package info (click to toggle)
intel-graphics-compiler2 2.18.5-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 107,080 kB
  • sloc: cpp: 807,289; lisp: 287,855; ansic: 16,414; python: 4,004; yacc: 2,588; lex: 1,666; pascal: 313; sh: 186; makefile: 35
file content (242 lines) | stat: -rw-r--r-- 10,233 bytes parent folder | download
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