1 /* 2 * Copyright (C) 2018-2021 Intel Corporation 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 */ 7 8 #pragma once 9 #include "shared/source/device/device.h" 10 #include "shared/source/helpers/hash.h" 11 #include "shared/source/helpers/string.h" 12 #include "shared/source/program/kernel_info.h" 13 14 #include "opencl/source/cl_device/cl_device.h" 15 #include "opencl/source/kernel/multi_device_kernel.h" 16 #include "opencl/source/program/program.h" 17 18 #include "gmock/gmock.h" 19 20 #include <string> 21 22 namespace NEO { 23 24 class GraphicsAllocation; 25 ClDeviceVector toClDeviceVector(ClDevice &clDevice); 26 //////////////////////////////////////////////////////////////////////////////// 27 // Program - Core implementation 28 //////////////////////////////////////////////////////////////////////////////// 29 class MockProgram : public Program { 30 public: 31 using Program::allowNonUniform; 32 using Program::applyAdditionalOptions; 33 using Program::areSpecializationConstantsInitialized; 34 using Program::blockKernelManager; 35 using Program::buildInfos; 36 using Program::context; 37 using Program::createdFrom; 38 using Program::createProgramFromBinary; 39 using Program::debugData; 40 using Program::debugDataSize; 41 using Program::deviceBuildInfos; 42 using Program::extractInternalOptions; 43 using Program::getKernelInfo; 44 using Program::internalOptionsToExtract; 45 using Program::irBinary; 46 using Program::irBinarySize; 47 using Program::isBuiltIn; 48 using Program::isSpirV; 49 using Program::kernelDebugEnabled; 50 using Program::linkBinary; 51 using Program::options; 52 using Program::packDeviceBinary; 53 using Program::Program; 54 using Program::separateBlockKernels; 55 using Program::setBuildStatus; 56 using Program::shouldWarnAboutRebuild; 57 using Program::sourceCode; 58 using Program::specConstantsIds; 59 using Program::specConstantsSizes; 60 using Program::specConstantsValues; 61 using Program::updateNonUniformFlag; 62 MockProgram(const ClDeviceVector & deviceVector)63 MockProgram(const ClDeviceVector &deviceVector) : Program(nullptr, false, deviceVector) { 64 } 65 ~MockProgram()66 ~MockProgram() override { 67 if (contextSet) 68 context = nullptr; 69 } 70 KernelInfo mockKernelInfo; setBuildOptions(const char * buildOptions)71 void setBuildOptions(const char *buildOptions) { 72 options = buildOptions != nullptr ? buildOptions : ""; 73 } getInitInternalOptions()74 std::string getInitInternalOptions() const { 75 std::string internalOptions; 76 initInternalOptions(internalOptions); 77 return internalOptions; 78 }; setConstantSurface(GraphicsAllocation * gfxAllocation)79 void setConstantSurface(GraphicsAllocation *gfxAllocation) { 80 if (gfxAllocation) { 81 buildInfos[gfxAllocation->getRootDeviceIndex()].constantSurface = gfxAllocation; 82 } else { 83 for (auto &buildInfo : buildInfos) { 84 buildInfo.constantSurface = nullptr; 85 } 86 } 87 } setGlobalSurface(GraphicsAllocation * gfxAllocation)88 void setGlobalSurface(GraphicsAllocation *gfxAllocation) { 89 if (gfxAllocation) { 90 buildInfos[gfxAllocation->getRootDeviceIndex()].globalSurface = gfxAllocation; 91 } else { 92 for (auto &buildInfo : buildInfos) { 93 buildInfo.globalSurface = nullptr; 94 } 95 } 96 } getKernelInfoArray(uint32_t rootDeviceIndex)97 std::vector<KernelInfo *> &getKernelInfoArray(uint32_t rootDeviceIndex) { 98 return buildInfos[rootDeviceIndex].kernelInfoArray; 99 } addKernelInfo(KernelInfo * inInfo,uint32_t rootDeviceIndex)100 void addKernelInfo(KernelInfo *inInfo, uint32_t rootDeviceIndex) { 101 buildInfos[rootDeviceIndex].kernelInfoArray.push_back(inInfo); 102 } getParentKernelInfoArray(uint32_t rootDeviceIndex)103 std::vector<KernelInfo *> &getParentKernelInfoArray(uint32_t rootDeviceIndex) { 104 return buildInfos[rootDeviceIndex].parentKernelInfoArray; 105 } getSubgroupKernelInfoArray(uint32_t rootDeviceIndex)106 std::vector<KernelInfo *> &getSubgroupKernelInfoArray(uint32_t rootDeviceIndex) { 107 return buildInfos[rootDeviceIndex].subgroupKernelInfoArray; 108 } setContext(Context * context)109 void setContext(Context *context) { 110 this->context = context; 111 contextSet = true; 112 } setSourceCode(const char * ptr)113 void setSourceCode(const char *ptr) { sourceCode = ptr; } clearOptions()114 void clearOptions() { options = ""; } setCreatedFromBinary(bool createdFromBin)115 void setCreatedFromBinary(bool createdFromBin) { isCreatedFromBinary = createdFromBin; } clearLog(uint32_t rootDeviceIndex)116 void clearLog(uint32_t rootDeviceIndex) { buildInfos[rootDeviceIndex].buildLog.clear(); } 117 setIrBinary(char * ptr,bool isSpirv)118 void setIrBinary(char *ptr, bool isSpirv) { 119 irBinary.reset(ptr); 120 this->isSpirV = isSpirV; 121 } setIrBinarySize(size_t bsz,bool isSpirv)122 void setIrBinarySize(size_t bsz, bool isSpirv) { 123 irBinarySize = bsz; 124 this->isSpirV = isSpirV; 125 } 126 127 std::string getCachedFileName() const; setAllowNonUniform(bool allow)128 void setAllowNonUniform(bool allow) { 129 allowNonUniform = allow; 130 } 131 isFlagOption(ConstStringRef option)132 bool isFlagOption(ConstStringRef option) override { 133 if (isFlagOptionOverride != -1) { 134 return (isFlagOptionOverride > 0); 135 } 136 return Program::isFlagOption(option); 137 } 138 isOptionValueValid(ConstStringRef option,ConstStringRef value)139 bool isOptionValueValid(ConstStringRef option, ConstStringRef value) override { 140 if (isOptionValueValidOverride != -1) { 141 return (isOptionValueValidOverride > 0); 142 } 143 return Program::isOptionValueValid(option, value); 144 } 145 rebuildProgramFromIr()146 cl_int rebuildProgramFromIr() { 147 this->isCreatedFromBinary = false; 148 this->shouldWarnAboutRebuild = true; 149 setBuildStatus(CL_BUILD_NONE); 150 std::unordered_map<std::string, BuiltinDispatchInfoBuilder *> builtins; 151 return this->build(getDevices(), this->options.c_str(), false, builtins); 152 } 153 recompile()154 cl_int recompile() { 155 this->isCreatedFromBinary = false; 156 this->shouldWarnAboutRebuild = true; 157 setBuildStatus(CL_BUILD_NONE); 158 return this->compile(getDevices(), this->options.c_str(), 0, nullptr, nullptr); 159 } 160 replaceDeviceBinary(std::unique_ptr<char[]> && newBinary,size_t newBinarySize,uint32_t rootDeviceIndex)161 void replaceDeviceBinary(std::unique_ptr<char[]> &&newBinary, size_t newBinarySize, uint32_t rootDeviceIndex) override { 162 if (replaceDeviceBinaryCalledPerRootDevice.find(rootDeviceIndex) == replaceDeviceBinaryCalledPerRootDevice.end()) { 163 replaceDeviceBinaryCalledPerRootDevice.insert({rootDeviceIndex, 1}); 164 } else { 165 replaceDeviceBinaryCalledPerRootDevice[rootDeviceIndex]++; 166 } 167 Program::replaceDeviceBinary(std::move(newBinary), newBinarySize, rootDeviceIndex); 168 } processGenBinary(const ClDevice & clDevice)169 cl_int processGenBinary(const ClDevice &clDevice) override { 170 auto rootDeviceIndex = clDevice.getRootDeviceIndex(); 171 if (processGenBinaryCalledPerRootDevice.find(rootDeviceIndex) == processGenBinaryCalledPerRootDevice.end()) { 172 processGenBinaryCalledPerRootDevice.insert({rootDeviceIndex, 1}); 173 } else { 174 processGenBinaryCalledPerRootDevice[rootDeviceIndex]++; 175 } 176 return Program::processGenBinary(clDevice); 177 } 178 initInternalOptions(std::string & internalOptions)179 void initInternalOptions(std::string &internalOptions) const override { 180 initInternalOptionsCalled++; 181 Program::initInternalOptions(internalOptions); 182 }; 183 getKernelInfoForKernel(const char * kernelName)184 const KernelInfo &getKernelInfoForKernel(const char *kernelName) const { 185 return *getKernelInfo(kernelName, getDevices()[0]->getRootDeviceIndex()); 186 } 187 getKernelInfosForKernel(const char * kernelName)188 const KernelInfoContainer getKernelInfosForKernel(const char *kernelName) const { 189 KernelInfoContainer kernelInfos; 190 kernelInfos.resize(getMaxRootDeviceIndex() + 1); 191 for (auto i = 0u; i < kernelInfos.size(); i++) { 192 kernelInfos[i] = getKernelInfo(kernelName, i); 193 } 194 return kernelInfos; 195 } 196 197 std::map<uint32_t, int> processGenBinaryCalledPerRootDevice; 198 std::map<uint32_t, int> replaceDeviceBinaryCalledPerRootDevice; 199 static int initInternalOptionsCalled; 200 bool contextSet = false; 201 int isFlagOptionOverride = -1; 202 int isOptionValueValidOverride = -1; 203 }; 204 205 class GMockProgram : public Program { 206 public: 207 using Program::Program; 208 MOCK_METHOD(bool, appendKernelDebugOptions, (ClDevice &, std::string &), (override)); 209 }; 210 211 } // namespace NEO 212