1 /*
2  * Copyright (C) 2020-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #pragma once
9 
10 #include "shared/source/compiler_interface/compiler_interface.h"
11 #include "shared/source/compiler_interface/linker.h"
12 #include "shared/source/program/program_info.h"
13 #include "shared/source/utilities/const_stringref.h"
14 
15 #include "level_zero/core/source/device/device.h"
16 #include "level_zero/core/source/module/module.h"
17 
18 #include "igfxfmid.h"
19 
20 #include <memory>
21 #include <string>
22 
23 namespace NEO {
24 namespace Debug {
25 struct Segments;
26 }
27 } // namespace NEO
28 namespace L0 {
29 
30 namespace BuildOptions {
31 extern NEO::ConstStringRef optDisable;
32 extern NEO::ConstStringRef optLevel;
33 extern NEO::ConstStringRef greaterThan4GbRequired;
34 extern NEO::ConstStringRef hasBufferOffsetArg;
35 extern NEO::ConstStringRef debugKernelEnable;
36 } // namespace BuildOptions
37 
38 struct ModuleTranslationUnit {
39     ModuleTranslationUnit(L0::Device *device);
40     virtual ~ModuleTranslationUnit();
41     MOCKABLE_VIRTUAL bool buildFromSpirV(const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions,
42                                          const ze_module_constants_t *pConstants);
43     MOCKABLE_VIRTUAL bool staticLinkSpirV(std::vector<const char *> inputSpirVs, std::vector<uint32_t> inputModuleSizes, const char *buildOptions, const char *internalBuildOptions,
44                                           std::vector<const ze_module_constants_t *> specConstants);
45     MOCKABLE_VIRTUAL bool createFromNativeBinary(const char *input, size_t inputSize);
46     MOCKABLE_VIRTUAL bool processUnpackedBinary();
47     std::vector<uint8_t> generateElfFromSpirV(std::vector<const char *> inputSpirVs, std::vector<uint32_t> inputModuleSizes);
48     bool processSpecConstantInfo(NEO::CompilerInterface *compilerInterface, const ze_module_constants_t *pConstants, const char *input, uint32_t inputSize);
49     std::string generateCompilerOptions(const char *buildOptions, const char *internalBuildOptions);
50     bool compileGenBinary(NEO::TranslationInput inputArgs, bool staticLink);
51     void updateBuildLog(const std::string &newLogEntry);
52     void processDebugData();
53     L0::Device *device = nullptr;
54 
55     NEO::GraphicsAllocation *globalConstBuffer = nullptr;
56     NEO::GraphicsAllocation *globalVarBuffer = nullptr;
57     NEO::ProgramInfo programInfo;
58 
59     std::string options;
60     bool shouldSuppressRebuildWarning{false};
61 
62     std::string buildLog;
63 
64     std::unique_ptr<char[]> irBinary;
65     size_t irBinarySize = 0U;
66 
67     std::unique_ptr<char[]> unpackedDeviceBinary;
68     size_t unpackedDeviceBinarySize = 0U;
69 
70     std::unique_ptr<char[]> packedDeviceBinary;
71     size_t packedDeviceBinarySize = 0U;
72 
73     std::unique_ptr<char[]> debugData;
74     size_t debugDataSize = 0U;
75     std::vector<char *> alignedvIsas;
76 
77     NEO::specConstValuesMap specConstantsValues;
78 };
79 
80 struct ModuleImp : public Module {
81     ModuleImp() = delete;
82 
83     ModuleImp(Device *device, ModuleBuildLog *moduleBuildLog, ModuleType type);
84 
85     ~ModuleImp() override;
86 
destroyModuleImp87     ze_result_t destroy() override {
88         delete this;
89         return ZE_RESULT_SUCCESS;
90     }
91 
92     ze_result_t createKernel(const ze_kernel_desc_t *desc,
93                              ze_kernel_handle_t *phFunction) override;
94 
95     ze_result_t getNativeBinary(size_t *pSize, uint8_t *pModuleNativeBinary) override;
96 
97     ze_result_t getFunctionPointer(const char *pFunctionName, void **pfnFunction) override;
98 
99     ze_result_t getGlobalPointer(const char *pGlobalName, size_t *pSize, void **pPtr) override;
100 
101     ze_result_t getKernelNames(uint32_t *pCount, const char **pNames) override;
102 
103     ze_result_t getProperties(ze_module_properties_t *pModuleProperties) override;
104 
105     ze_result_t performDynamicLink(uint32_t numModules,
106                                    ze_module_handle_t *phModules,
107                                    ze_module_build_log_handle_t *phLinkLog) override;
108 
109     ze_result_t getDebugInfo(size_t *pDebugDataSize, uint8_t *pDebugData) override;
110 
111     const KernelImmutableData *getKernelImmutableData(const char *functionName) const override;
112 
getKernelImmutableDataVectorModuleImp113     const std::vector<std::unique_ptr<KernelImmutableData>> &getKernelImmutableDataVector() const override { return kernelImmDatas; }
114 
getMaxGroupSizeModuleImp115     uint32_t getMaxGroupSize() const override { return maxGroupSize; }
116 
117     void createBuildOptions(const char *pBuildFlags, std::string &buildOptions, std::string &internalBuildOptions);
118     void createBuildExtraOptions(std::string &buildOptions, std::string &internalBuildOptions);
119     void updateBuildLog(NEO::Device *neoDevice);
120 
getDeviceModuleImp121     Device *getDevice() const override { return device; }
122 
123     bool linkBinary();
124 
125     bool initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice);
126 
127     bool isDebugEnabled() const override;
128 
shouldAllocatePrivateMemoryPerDispatchModuleImp129     bool shouldAllocatePrivateMemoryPerDispatch() const override {
130         return allocatePrivateMemoryPerDispatch;
131     }
132 
getTranslationUnitModuleImp133     ModuleTranslationUnit *getTranslationUnit() {
134         return this->translationUnit.get();
135     }
136 
137   protected:
138     void copyPatchedSegments(const NEO::Linker::PatchableSegments &isaSegmentsForPatching);
139     void verifyDebugCapabilities();
140     void checkIfPrivateMemoryPerDispatchIsNeeded() override;
141     NEO::Debug::Segments getZebinSegments();
142     void passDebugData();
143     void createDebugZebin();
144 
145     Device *device = nullptr;
146     PRODUCT_FAMILY productFamily{};
147     std::unique_ptr<ModuleTranslationUnit> translationUnit;
148     ModuleBuildLog *moduleBuildLog = nullptr;
149     NEO::GraphicsAllocation *exportedFunctionsSurface = nullptr;
150     uint32_t maxGroupSize = 0U;
151     std::vector<std::unique_ptr<KernelImmutableData>> kernelImmDatas;
152     NEO::Linker::RelocatedSymbolsMap symbols;
153     bool debugEnabled = false;
154     bool isFullyLinked = false;
155     bool allocatePrivateMemoryPerDispatch = true;
156     ModuleType type;
157     NEO::Linker::UnresolvedExternals unresolvedExternalsInfo{};
158     std::set<NEO::GraphicsAllocation *> importedSymbolAllocations{};
159 };
160 
161 bool moveBuildOption(std::string &dstOptionsSet, std::string &srcOptionSet, NEO::ConstStringRef dstOptionName, NEO::ConstStringRef srcOptionName);
162 
163 } // namespace L0
164