1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #pragma once
9 
10 #include "shared/offline_compiler/source/ocloc_arg_helper.h"
11 #include "shared/source/helpers/hw_info.h"
12 #include "shared/source/os_interface/os_library.h"
13 #include "shared/source/utilities/arrayref.h"
14 #include "shared/source/utilities/const_stringref.h"
15 
16 #include "cif/common/cif_main.h"
17 #include "ocl_igc_interface/fcl_ocl_device_ctx.h"
18 #include "ocl_igc_interface/igc_ocl_device_ctx.h"
19 
20 #include <cstdint>
21 #include <memory>
22 #include <string>
23 
24 namespace NEO {
25 
26 struct HardwareInfo;
27 class OsLibrary;
28 
29 std::string convertToPascalCase(const std::string &inString);
30 
31 std::string generateFilePath(const std::string &directory, const std::string &fileNameBase, const char *extension);
32 std::string getDevicesTypes();
33 
34 class OfflineCompiler {
35   public:
36     enum ErrorCode {
37         SUCCESS = 0,
38         OUT_OF_HOST_MEMORY = -6,
39         BUILD_PROGRAM_FAILURE = -11,
40         INVALID_DEVICE = -33,
41         INVALID_PROGRAM = -44,
42         INVALID_COMMAND_LINE = -5150,
43         INVALID_FILE = -5151,
44     };
45 
46     static int query(size_t numArgs, const std::vector<std::string> &allArgs, OclocArgHelper *helper);
47 
48     static OfflineCompiler *create(size_t numArgs, const std::vector<std::string> &allArgs, bool dumpFiles, int &retVal, OclocArgHelper *helper);
49     int build();
50     std::string &getBuildLog();
51     void printUsage();
52     std::string getDevicesConfigs();
53 
54     static constexpr ConstStringRef queryHelp =
55         "Depending on <query_option> will generate file\n"
56         "(with a name adequate to <query_option>)\n"
57         "containing either driver version or NEO revision hash.\n\n"
58         "Usage: ocloc query <query_option>\n\n"
59         "Supported query options:\n"
60         "  OCL_DRIVER_VERSION  ; returns driver version\n"
61         "  NEO_REVISION        ; returns NEO revision hash\n\n"
62         "Examples:\n"
63         "  Extract driver version\n"
64         "    ocloc query OCL_DRIVER_VERSION\n";
65 
66     OfflineCompiler &operator=(const OfflineCompiler &) = delete;
67     OfflineCompiler(const OfflineCompiler &) = delete;
68     MOCKABLE_VIRTUAL ~OfflineCompiler();
69 
isQuiet()70     bool isQuiet() const {
71         return quiet;
72     }
73 
isOnlySpirV()74     bool isOnlySpirV() const {
75         return onlySpirV;
76     }
77 
78     std::string parseBinAsCharArray(uint8_t *binary, size_t size, std::string &fileName);
79 
80     static bool readOptionsFromFile(std::string &optionsOut, const std::string &file, OclocArgHelper *helper);
81 
getPackedDeviceBinaryOutput()82     ArrayRef<const uint8_t> getPackedDeviceBinaryOutput() {
83         return this->elfBinary;
84     }
85 
86     static std::string getFileNameTrunk(std::string &filePath);
getHardwareInfo()87     const HardwareInfo &getHardwareInfo() const {
88         return hwInfo;
89     }
90 
91   protected:
92     OfflineCompiler();
93 
94     void setFamilyType();
95     int initHardwareInfo(std::string deviceName);
96     std::string getStringWithinDelimiters(const std::string &src);
97     int initialize(size_t numArgs, const std::vector<std::string> &allArgs, bool dumpFiles);
98     int parseCommandLine(size_t numArgs, const std::vector<std::string> &allArgs);
99     void setStatelessToStatefullBufferOffsetFlag();
100     void appendExtraInternalOptions(const HardwareInfo &hwInfo, std::string &internalOptions);
101     void parseDebugSettings();
102     void storeBinary(char *&pDst, size_t &dstSize, const void *pSrc, const size_t srcSize);
103     MOCKABLE_VIRTUAL int buildSourceCode();
104     MOCKABLE_VIRTUAL std::string validateInputType(const std::string &input, bool isLlvm, bool isSpirv);
105     int buildIrBinary();
106     void updateBuildLog(const char *pErrorString, const size_t errorStringSize);
107     MOCKABLE_VIRTUAL bool generateElfBinary();
generateFilePathForIr(const std::string & fileNameBase)108     std::string generateFilePathForIr(const std::string &fileNameBase) {
109         const char *ext = (isSpirV) ? ".spv" : ".bc";
110         return generateFilePath(outputDirectory, fileNameBase, useLlvmText ? ".ll" : ext);
111     }
112 
generateOptsSuffix()113     std::string generateOptsSuffix() {
114         std::string suffix{useOptionsSuffix ? options : ""};
115         std::replace(suffix.begin(), suffix.end(), ' ', '_');
116         return suffix;
117     }
118     MOCKABLE_VIRTUAL void writeOutAllFiles();
119     void unifyExcludeIrFlags();
120     HardwareInfo hwInfo;
121 
122     PRODUCT_CONFIG deviceConfig = UNKNOWN_ISA;
123     std::string deviceName;
124     std::string familyNameWithType;
125     std::string inputFile;
126     std::string outputFile;
127     std::string outputDirectory;
128     std::string options;
129     std::string internalOptions;
130     std::string sourceCode;
131     std::string buildLog;
132 
133     bool dumpFiles = true;
134     bool useLlvmText = false;
135     bool useLlvmBc = false;
136     bool useCppFile = false;
137     bool useOptionsSuffix = false;
138     bool quiet = false;
139     bool onlySpirV = false;
140     bool inputFileLlvm = false;
141     bool inputFileSpirV = false;
142     bool outputNoSuffix = false;
143     bool forceStatelessToStatefulOptimization = false;
144     bool isSpirV = false;
145     bool showHelp = false;
146     bool excludeIr = false;
147 
148     std::vector<uint8_t> elfBinary;
149     char *genBinary = nullptr;
150     size_t genBinarySize = 0;
151     char *irBinary = nullptr;
152     size_t irBinarySize = 0;
153     char *debugDataBinary = nullptr;
154     size_t debugDataBinarySize = 0;
155     struct buildInfo;
156     std::unique_ptr<buildInfo> pBuildInfo;
157     std::unique_ptr<OsLibrary> igcLib = nullptr;
158     CIF::RAII::UPtr_t<CIF::CIFMain> igcMain = nullptr;
159     CIF::RAII::UPtr_t<IGC::IgcOclDeviceCtxTagOCL> igcDeviceCtx = nullptr;
160     int revisionId = -1;
161 
162     std::unique_ptr<OsLibrary> fclLib = nullptr;
163     CIF::RAII::UPtr_t<CIF::CIFMain> fclMain = nullptr;
164     CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> fclDeviceCtx = nullptr;
165     IGC::CodeType::CodeType_t preferredIntermediateRepresentation;
166 
167     OclocArgHelper *argHelper = nullptr;
168 };
169 } // namespace NEO
170