1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #pragma once
9 
10 #include "shared/source/device/device.h"
11 #include "shared/source/helpers/string.h"
12 #include "shared/source/kernel/grf_config.h"
13 #include "shared/test/common/mocks/mock_graphics_allocation.h"
14 #include "shared/test/common/mocks/mock_kernel_info.h"
15 
16 #include "opencl/source/cl_device/cl_device.h"
17 #include "opencl/source/kernel/kernel.h"
18 #include "opencl/source/kernel/kernel_objects_for_aux_translation.h"
19 #include "opencl/source/kernel/multi_device_kernel.h"
20 #include "opencl/source/platform/platform.h"
21 #include "opencl/source/program/block_kernel_manager.h"
22 #include "opencl/source/scheduler/scheduler_kernel.h"
23 #include "opencl/test/unit_test/mocks/mock_buffer.h"
24 #include "opencl/test/unit_test/mocks/mock_context.h"
25 #include "opencl/test/unit_test/mocks/mock_program.h"
26 
27 #include <cassert>
28 
29 namespace NEO {
30 using namespace iOpenCL;
31 
32 void populateKernelDescriptor(KernelDescriptor &dst, const SPatchExecutionEnvironment &execEnv);
33 
34 struct MockKernelObjForAuxTranslation : public KernelObjForAuxTranslation {
MockKernelObjForAuxTranslationMockKernelObjForAuxTranslation35     MockKernelObjForAuxTranslation(Type type) : KernelObjForAuxTranslation(type, nullptr) {
36         if (type == KernelObjForAuxTranslation::Type::MEM_OBJ) {
37             mockBuffer.reset(new MockBuffer);
38             this->object = mockBuffer.get();
39         } else {
40             DEBUG_BREAK_IF(type != KernelObjForAuxTranslation::Type::GFX_ALLOC);
41             mockGraphicsAllocation.reset(new MockGraphicsAllocation(nullptr, 0x100));
42             this->object = mockGraphicsAllocation.get();
43         }
44     };
45 
MockKernelObjForAuxTranslationMockKernelObjForAuxTranslation46     MockKernelObjForAuxTranslation(Type type, size_t size) : MockKernelObjForAuxTranslation(type) {
47         if (type == KernelObjForAuxTranslation::Type::MEM_OBJ) {
48             mockBuffer->getGraphicsAllocation(0)->setSize(size);
49         } else {
50             DEBUG_BREAK_IF(type != KernelObjForAuxTranslation::Type::GFX_ALLOC);
51             mockGraphicsAllocation->setSize(size);
52         }
53     }
54 
55     std::unique_ptr<MockBuffer> mockBuffer = nullptr;
56     std::unique_ptr<MockGraphicsAllocation> mockGraphicsAllocation = nullptr;
57 };
58 
59 class MockMultiDeviceKernel : public MultiDeviceKernel {
60   public:
toKernelVector(Kernel * pKernel)61     static KernelVectorType toKernelVector(Kernel *pKernel) {
62         KernelVectorType kernelVector;
63         kernelVector.resize(pKernel->getProgram()->getMaxRootDeviceIndex() + 1);
64         kernelVector[pKernel->getProgram()->getDevices()[0]->getRootDeviceIndex()] = pKernel;
65         return kernelVector;
66     }
67     using MultiDeviceKernel::MultiDeviceKernel;
68     template <typename kernel_t = Kernel>
create(Program * programArg,const KernelInfoContainer & kernelInfoArg)69     static MockMultiDeviceKernel *create(Program *programArg, const KernelInfoContainer &kernelInfoArg) {
70         KernelVectorType kernelVector;
71         kernelVector.resize(programArg->getMaxRootDeviceIndex() + 1);
72         for (auto &pDevice : programArg->getDevices()) {
73             auto rootDeviceIndex = pDevice->getRootDeviceIndex();
74             if (kernelVector[rootDeviceIndex]) {
75                 continue;
76             }
77             kernelVector[rootDeviceIndex] = new kernel_t(programArg, *kernelInfoArg[rootDeviceIndex], *pDevice);
78         }
79         return new MockMultiDeviceKernel(std::move(kernelVector), kernelInfoArg);
80     }
takeOwnership()81     void takeOwnership() const override {
82         MultiDeviceKernel::takeOwnership();
83         takeOwnershipCalls++;
84     }
85 
releaseOwnership()86     void releaseOwnership() const override {
87         releaseOwnershipCalls++;
88         MultiDeviceKernel::releaseOwnership();
89     }
90 
91     mutable uint32_t takeOwnershipCalls = 0;
92     mutable uint32_t releaseOwnershipCalls = 0;
93 };
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 // Kernel - Core implementation
97 ////////////////////////////////////////////////////////////////////////////////
98 class MockKernel : public Kernel {
99   public:
100     using Kernel::addAllocationToCacheFlushVector;
101     using Kernel::allBufferArgsStateful;
102     using Kernel::auxTranslationRequired;
103     using Kernel::containsStatelessWrites;
104     using Kernel::dataParameterSimdSize;
105     using Kernel::executionType;
106     using Kernel::getDevice;
107     using Kernel::getHardwareInfo;
108     using Kernel::hasDirectStatelessAccessToHostMemory;
109     using Kernel::hasDirectStatelessAccessToSharedBuffer;
110     using Kernel::hasIndirectStatelessAccessToHostMemory;
111     using Kernel::isSchedulerKernel;
112     using Kernel::kernelArgHandlers;
113     using Kernel::kernelArgRequiresCacheFlush;
114     using Kernel::kernelArguments;
115     using Kernel::KernelConfig;
116     using Kernel::kernelHasIndirectAccess;
117     using Kernel::kernelSubmissionMap;
118     using Kernel::kernelSvmGfxAllocations;
119     using Kernel::kernelUnifiedMemoryGfxAllocations;
120     using Kernel::maxKernelWorkGroupSize;
121     using Kernel::maxWorkGroupSizeForCrossThreadData;
122     using Kernel::numberOfBindingTableStates;
123     using Kernel::parentEventOffset;
124     using Kernel::patchBufferOffset;
125     using Kernel::patchWithImplicitSurface;
126     using Kernel::pImplicitArgs;
127     using Kernel::preferredWkgMultipleOffset;
128     using Kernel::privateSurface;
129     using Kernel::singleSubdevicePreferredInCurrentEnqueue;
130     using Kernel::svmAllocationsRequireCacheFlush;
131     using Kernel::threadArbitrationPolicy;
132     using Kernel::unifiedMemoryControls;
133 
134     using Kernel::slmSizes;
135     using Kernel::slmTotalSize;
136 
137     struct BlockPatchValues {
138         uint64_t offset;
139         uint32_t size;
140         uint64_t address;
141     };
142 
143     class ReflectionSurfaceHelperPublic : public Kernel::ReflectionSurfaceHelper {
144       public:
145         static BlockPatchValues devQueue;
146         static BlockPatchValues defaultQueue;
147         static BlockPatchValues eventPool;
148         static BlockPatchValues printfBuffer;
149         static const uint64_t undefinedOffset = (uint64_t)-1;
150 
patchBlocksCurbeMock(void * reflectionSurface,uint32_t blockID,uint64_t defaultDeviceQueueCurbeOffset,uint32_t patchSizeDefaultQueue,uint64_t defaultDeviceQueueGpuAddress,uint64_t eventPoolCurbeOffset,uint32_t patchSizeEventPool,uint64_t eventPoolGpuAddress,uint64_t deviceQueueCurbeOffset,uint32_t patchSizeDeviceQueue,uint64_t deviceQueueGpuAddress,uint64_t printfBufferOffset,uint32_t patchSizePrintfBuffer,uint64_t printfBufferGpuAddress)151         static void patchBlocksCurbeMock(void *reflectionSurface, uint32_t blockID,
152                                          uint64_t defaultDeviceQueueCurbeOffset, uint32_t patchSizeDefaultQueue, uint64_t defaultDeviceQueueGpuAddress,
153                                          uint64_t eventPoolCurbeOffset, uint32_t patchSizeEventPool, uint64_t eventPoolGpuAddress,
154                                          uint64_t deviceQueueCurbeOffset, uint32_t patchSizeDeviceQueue, uint64_t deviceQueueGpuAddress,
155                                          uint64_t printfBufferOffset, uint32_t patchSizePrintfBuffer, uint64_t printfBufferGpuAddress) {
156             defaultQueue.address = defaultDeviceQueueGpuAddress;
157             defaultQueue.offset = defaultDeviceQueueCurbeOffset;
158             defaultQueue.size = patchSizeDefaultQueue;
159 
160             devQueue.address = deviceQueueGpuAddress;
161             devQueue.offset = deviceQueueCurbeOffset;
162             devQueue.size = patchSizeDeviceQueue;
163 
164             eventPool.address = eventPoolGpuAddress;
165             eventPool.offset = eventPoolCurbeOffset;
166             eventPool.size = patchSizeEventPool;
167 
168             printfBuffer.address = printfBufferGpuAddress;
169             printfBuffer.offset = printfBufferOffset;
170             printfBuffer.size = patchSizePrintfBuffer;
171         }
172 
getConstantBufferOffset(void * reflectionSurface,uint32_t blockID)173         static uint32_t getConstantBufferOffset(void *reflectionSurface, uint32_t blockID) {
174             IGIL_KernelDataHeader *pKernelHeader = reinterpret_cast<IGIL_KernelDataHeader *>(reflectionSurface);
175             assert(blockID < pKernelHeader->m_numberOfKernels);
176 
177             IGIL_KernelAddressData *addressData = pKernelHeader->m_data;
178             assert(addressData[blockID].m_ConstantBufferOffset != 0);
179 
180             return addressData[blockID].m_ConstantBufferOffset;
181         }
182     };
183 
184     MockKernel(Program *programArg, const KernelInfo &kernelInfoArg, ClDevice &clDeviceArg, bool scheduler = false)
Kernel(programArg,kernelInfoArg,clDeviceArg,scheduler)185         : Kernel(programArg, kernelInfoArg, clDeviceArg, scheduler) {
186     }
187 
~MockKernel()188     ~MockKernel() override {
189         // prevent double deletion
190         if (crossThreadData == mockCrossThreadData.data()) {
191             crossThreadData = nullptr;
192         }
193 
194         if (kernelInfoAllocated) {
195             delete kernelInfoAllocated;
196         }
197     }
198 
199     template <typename KernelType = MockKernel>
create(Device & device,Program * program)200     static KernelType *create(Device &device, Program *program) {
201         return create<KernelType>(device, program, GrfConfig::DefaultGrfNumber);
202     }
203 
204     template <typename KernelType = MockKernel>
create(Device & device,Program * program,uint32_t grfNumber)205     static KernelType *create(Device &device, Program *program, uint32_t grfNumber) {
206         auto info = new MockKernelInfo();
207         const size_t crossThreadSize = 160;
208 
209         info->setLocalIds({0, 0, 0});
210         info->kernelDescriptor.kernelAttributes.flags.usesDeviceSideEnqueue = false;
211         info->kernelDescriptor.kernelAttributes.numGrfRequired = grfNumber;
212         info->kernelDescriptor.kernelAttributes.simdSize = 32;
213 
214         info->crossThreadData = new char[crossThreadSize];
215 
216         auto kernel = new KernelType(program, *info, *device.getSpecializedDevice<ClDevice>());
217         kernel->crossThreadData = new char[crossThreadSize];
218         memset(kernel->crossThreadData, 0, crossThreadSize);
219         kernel->crossThreadDataSize = crossThreadSize;
220 
221         kernel->kernelInfoAllocated = info;
222 
223         return kernel;
224     }
225 
226     static const KernelInfoContainer toKernelInfoContainer(const KernelInfo &kernelInfo, uint32_t rootDeviceIndex);
227 
getPatchedArgumentsNum()228     uint32_t getPatchedArgumentsNum() const { return patchedArgumentsNum; }
229 
230     bool isPatched() const override;
231 
232     bool canTransformImages() const override;
233 
234     ////////////////////////////////////////////////////////////////////////////////
setCrossThreadData(const void * crossThreadDataPattern,uint32_t newCrossThreadDataSize)235     void setCrossThreadData(const void *crossThreadDataPattern, uint32_t newCrossThreadDataSize) {
236         if ((crossThreadData != nullptr) && (crossThreadData != mockCrossThreadData.data())) {
237             delete[] crossThreadData;
238             crossThreadData = nullptr;
239             crossThreadDataSize = 0;
240         }
241         if (crossThreadDataPattern && (newCrossThreadDataSize > 0)) {
242             mockCrossThreadData.clear();
243             mockCrossThreadData.insert(mockCrossThreadData.begin(), (char *)crossThreadDataPattern, ((char *)crossThreadDataPattern) + newCrossThreadDataSize);
244         } else {
245             mockCrossThreadData.resize(newCrossThreadDataSize, 0);
246         }
247 
248         if (newCrossThreadDataSize == 0) {
249             crossThreadData = nullptr;
250             crossThreadDataSize = 0;
251             return;
252         }
253         crossThreadData = mockCrossThreadData.data();
254         crossThreadDataSize = static_cast<uint32_t>(mockCrossThreadData.size());
255     }
256 
setSshLocal(const void * sshPattern,uint32_t newSshSize)257     void setSshLocal(const void *sshPattern, uint32_t newSshSize) {
258         sshLocalSize = newSshSize;
259 
260         if (newSshSize == 0) {
261             pSshLocal.reset(nullptr);
262         } else {
263             pSshLocal = std::make_unique<char[]>(newSshSize);
264             if (sshPattern) {
265                 memcpy_s(pSshLocal.get(), newSshSize, sshPattern, newSshSize);
266             }
267         }
268     }
269 
setPrivateSurface(GraphicsAllocation * gfxAllocation,uint32_t size)270     void setPrivateSurface(GraphicsAllocation *gfxAllocation, uint32_t size) {
271         privateSurface = gfxAllocation;
272         privateSurfaceSize = size;
273     }
274 
setTotalSLMSize(uint32_t size)275     void setTotalSLMSize(uint32_t size) {
276         slmTotalSize = size;
277     }
278 
setKernelArguments(std::vector<SimpleKernelArgInfo> kernelArguments)279     void setKernelArguments(std::vector<SimpleKernelArgInfo> kernelArguments) {
280         this->kernelArguments = kernelArguments;
281     }
282 
getAllocatedKernelInfo()283     KernelInfo *getAllocatedKernelInfo() {
284         return kernelInfoAllocated;
285     }
286 
287     std::vector<char> mockCrossThreadData;
288     std::vector<char> mockSshLocal;
289 
setUsingSharedArgs(bool usingSharedArgValue)290     void setUsingSharedArgs(bool usingSharedArgValue) { this->usingSharedObjArgs = usingSharedArgValue; }
291 
292     void makeResident(CommandStreamReceiver &commandStreamReceiver) override;
293     void getResidency(std::vector<Surface *> &dst) override;
294 
setSpecialPipelineSelectMode(bool value)295     void setSpecialPipelineSelectMode(bool value) { specialPipelineSelectMode = value; }
296 
297     bool requiresCacheFlushCommand(const CommandQueue &commandQueue) const override;
298 
299     uint32_t makeResidentCalls = 0;
300     uint32_t getResidencyCalls = 0;
301 
302     bool canKernelTransformImages = true;
303     bool isPatchedOverride = true;
304 
305   protected:
306     KernelInfo *kernelInfoAllocated = nullptr;
307 };
308 
309 //class below have enough internals to service Enqueue operation.
310 class MockKernelWithInternals {
311   public:
312     MockKernelWithInternals(const ClDeviceVector &deviceVector, Context *context = nullptr, bool addDefaultArg = false, SPatchExecutionEnvironment execEnv = {}) {
313         memset(&kernelHeader, 0, sizeof(SKernelBinaryHeaderCommon));
314 
315         kernelInfo.heapInfo.pKernelHeap = kernelIsa;
316         kernelInfo.heapInfo.KernelHeapSize = sizeof(kernelIsa);
317         kernelInfo.heapInfo.pSsh = sshLocal;
318         kernelInfo.heapInfo.SurfaceStateHeapSize = sizeof(sshLocal);
319         kernelInfo.heapInfo.pDsh = dshLocal;
320         kernelInfo.heapInfo.DynamicStateHeapSize = sizeof(dshLocal);
321 
322         populateKernelDescriptor(kernelInfo.kernelDescriptor, execEnv);
323         kernelInfo.kernelDescriptor.kernelAttributes.numGrfRequired = GrfConfig::DefaultGrfNumber;
324         kernelInfo.kernelDescriptor.kernelAttributes.simdSize = 32;
325         kernelInfo.setCrossThreadDataSize(sizeof(crossThreadData));
326         kernelInfo.setLocalIds({1, 1, 1});
327 
328         if (context == nullptr) {
329             mockContext = new MockContext(deviceVector);
330             context = mockContext;
331         } else {
332             context->incRefInternal();
333             mockContext = context;
334         }
335         auto maxRootDeviceIndex = 0u;
336 
337         for (const auto &pClDevice : deviceVector) {
338             if (pClDevice->getRootDeviceIndex() > maxRootDeviceIndex) {
339                 maxRootDeviceIndex = pClDevice->getRootDeviceIndex();
340             }
341         }
342 
343         kernelInfos.resize(maxRootDeviceIndex + 1);
344 
345         for (const auto &pClDevice : deviceVector) {
346             kernelInfos[pClDevice->getRootDeviceIndex()] = &kernelInfo;
347         }
348 
349         mockProgram = new MockProgram(context, false, deviceVector);
350         mockKernel = new MockKernel(mockProgram, kernelInfo, *deviceVector[0]);
351         mockKernel->setCrossThreadData(&crossThreadData, sizeof(crossThreadData));
352         KernelVectorType mockKernels;
353         mockKernels.resize(mockProgram->getMaxRootDeviceIndex() + 1);
354         for (const auto &pClDevice : deviceVector) {
355             auto rootDeviceIndex = pClDevice->getRootDeviceIndex();
356             if (mockKernels[rootDeviceIndex] == nullptr) {
357                 mockKernels[rootDeviceIndex] = mockKernel;
358             }
359         }
360         mockMultiDeviceKernel = new MockMultiDeviceKernel(std::move(mockKernels), kernelInfos);
361 
362         mockKernel->setSshLocal(&sshLocal, sizeof(sshLocal));
363 
364         if (addDefaultArg) {
365             defaultKernelArguments.resize(2);
366             defaultKernelArguments[0] = {};
367             defaultKernelArguments[1] = {};
368 
369             kernelInfo.addArgBuffer(0, 0, sizeof(uintptr_t), 64);
370             kernelInfo.setAddressQualifier(0, KernelArgMetadata::AddrGlobal);
371             kernelInfo.setAccessQualifier(0, KernelArgMetadata::AccessReadWrite);
372 
373             kernelInfo.addArgBuffer(1, 8, sizeof(uintptr_t), 72);
374             kernelInfo.setAddressQualifier(1, KernelArgMetadata::AddrGlobal);
375             kernelInfo.setAccessQualifier(1, KernelArgMetadata::AccessReadWrite);
376 
377             mockKernel->setKernelArguments(defaultKernelArguments);
378             mockKernel->kernelArgRequiresCacheFlush.resize(2);
379             mockKernel->kernelArgHandlers.resize(2);
380             mockKernel->kernelArgHandlers[0] = &Kernel::setArgBuffer;
381             mockKernel->kernelArgHandlers[1] = &Kernel::setArgBuffer;
382         }
383     }
384 
MockKernelWithInternals(toClDeviceVector (deviceArg),context,addDefaultArg,execEnv)385     MockKernelWithInternals(ClDevice &deviceArg, Context *context = nullptr, bool addDefaultArg = false, SPatchExecutionEnvironment execEnv = {}) : MockKernelWithInternals(toClDeviceVector(deviceArg), context, addDefaultArg, execEnv) {
386     }
MockKernelWithInternals(ClDevice & deviceArg,SPatchExecutionEnvironment execEnv)387     MockKernelWithInternals(ClDevice &deviceArg, SPatchExecutionEnvironment execEnv) : MockKernelWithInternals(deviceArg, nullptr, false, execEnv) {
388         mockKernel->initialize();
389     }
390 
~MockKernelWithInternals()391     ~MockKernelWithInternals() {
392         mockMultiDeviceKernel->decRefInternal();
393         mockProgram->decRefInternal();
394         mockContext->decRefInternal();
395     }
396 
397     operator MockKernel *() {
398         return mockKernel;
399     }
400 
401     MockMultiDeviceKernel *mockMultiDeviceKernel = nullptr;
402     MockKernel *mockKernel;
403     MockProgram *mockProgram;
404     Context *mockContext;
405     KernelInfoContainer kernelInfos;
406     MockKernelInfo kernelInfo;
407     SKernelBinaryHeaderCommon kernelHeader = {};
408     uint32_t kernelIsa[32];
409     char crossThreadData[256];
410     char sshLocal[128];
411     char dshLocal[128];
412     std::vector<Kernel::SimpleKernelArgInfo> defaultKernelArguments;
413 };
414 
415 class MockParentKernel : public Kernel {
416   public:
417     struct CreateParams {
418         bool addChildSimdSize = false;
419         bool addChildGlobalMemory = false;
420         bool addChildConstantMemory = false;
421         bool addPrintfForParent = false;
422         bool addPrintfForBlock = false;
423     };
424     using Kernel::auxTranslationRequired;
425     using Kernel::kernelInfo;
426     using Kernel::patchBlocksCurbeWithConstantValues;
427     using Kernel::pImplicitArgs;
428     using Kernel::pSshLocal;
429     using Kernel::sshLocalSize;
create(Context & context)430     static MockParentKernel *create(Context &context) {
431         CreateParams createParams{};
432         return create(context, createParams);
433     }
create(Context & context,const CreateParams & createParams)434     static MockParentKernel *create(Context &context, const CreateParams &createParams) {
435         auto clDevice = context.getDevice(0);
436 
437         auto info = new MockKernelInfo();
438         const size_t crossThreadSize = 160;
439         uint32_t crossThreadOffset = 0;
440         uint32_t crossThreadOffsetBlock = 0;
441 
442         info->setLocalIds({0, 0, 0});
443 
444         info->kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::Stateless;
445         info->kernelDescriptor.kernelAttributes.flags.usesDeviceSideEnqueue = true;
446         info->kernelDescriptor.kernelAttributes.numGrfRequired = GrfConfig::DefaultGrfNumber;
447         info->kernelDescriptor.kernelAttributes.simdSize = 32;
448 
449         info->setDeviceSideEnqueueDefaultQueueSurface(8, crossThreadOffset);
450         crossThreadOffset += 8;
451 
452         info->setDeviceSideEnqueueEventPoolSurface(8, crossThreadOffset);
453         crossThreadOffset += 8;
454 
455         if (createParams.addPrintfForParent) {
456             info->setPrintfSurface(8, crossThreadOffset);
457             crossThreadOffset += 8;
458         }
459 
460         ClDeviceVector deviceVector;
461         deviceVector.push_back(clDevice);
462         MockProgram *mockProgram = new MockProgram(&context, false, deviceVector);
463 
464         if (createParams.addChildSimdSize) {
465             info->childrenKernelsIdOffset.push_back({0, crossThreadOffset});
466         }
467 
468         UNRECOVERABLE_IF(crossThreadSize < crossThreadOffset + 8);
469         info->crossThreadData = new char[crossThreadSize];
470 
471         auto parent = new MockParentKernel(mockProgram, *info);
472         parent->crossThreadData = new char[crossThreadSize];
473         memset(parent->crossThreadData, 0, crossThreadSize);
474         parent->crossThreadDataSize = crossThreadSize;
475         parent->mockKernelInfo = info;
476 
477         auto infoBlock = new MockKernelInfo();
478 
479         infoBlock->kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::Stateless;
480 
481         infoBlock->setDeviceSideEnqueueDefaultQueueSurface(8, crossThreadOffsetBlock);
482         crossThreadOffsetBlock += 8;
483 
484         infoBlock->setDeviceSideEnqueueEventPoolSurface(8, crossThreadOffset);
485         crossThreadOffsetBlock += 8;
486 
487         if (createParams.addPrintfForBlock) {
488             infoBlock->setPrintfSurface(8, crossThreadOffsetBlock);
489             crossThreadOffsetBlock += 8;
490         }
491 
492         if (createParams.addChildGlobalMemory) {
493             infoBlock->setGlobalVariablesSurface(8, crossThreadOffsetBlock);
494             crossThreadOffsetBlock += 8;
495         }
496 
497         if (createParams.addChildConstantMemory) {
498             infoBlock->setGlobalConstantsSurface(8, crossThreadOffsetBlock);
499             crossThreadOffsetBlock += 8;
500         }
501 
502         infoBlock->setLocalIds({0, 0, 0});
503 
504         infoBlock->kernelDescriptor.kernelAttributes.flags.usesDeviceSideEnqueue = true;
505         infoBlock->kernelDescriptor.kernelAttributes.numGrfRequired = GrfConfig::DefaultGrfNumber;
506         infoBlock->kernelDescriptor.kernelAttributes.simdSize = 32;
507 
508         infoBlock->setDeviceSideEnqueueBlockInterfaceDescriptorOffset(0);
509 
510         infoBlock->heapInfo.pDsh = (void *)new uint64_t[64];
511         infoBlock->heapInfo.DynamicStateHeapSize = 64 * sizeof(uint64_t);
512 
513         size_t crossThreadDataSize = crossThreadOffsetBlock > crossThreadSize ? crossThreadOffsetBlock : crossThreadSize;
514         infoBlock->crossThreadData = new char[crossThreadDataSize];
515         infoBlock->setCrossThreadDataSize(static_cast<uint16_t>(crossThreadDataSize));
516 
517         mockProgram->blockKernelManager->addBlockKernelInfo(infoBlock);
518         parent->mockProgram = mockProgram;
519 
520         return parent;
521     }
522 
MockParentKernel(Program * programArg,const KernelInfo & kernelInfoArg)523     MockParentKernel(Program *programArg, const KernelInfo &kernelInfoArg) : Kernel(programArg, kernelInfoArg, *programArg->getDevices()[0], false) {
524     }
525 
~MockParentKernel()526     ~MockParentKernel() override {
527         delete &kernelInfo;
528         BlockKernelManager *blockManager = program->getBlockKernelManager();
529 
530         for (uint32_t i = 0; i < blockManager->getCount(); i++) {
531             const KernelInfo *blockInfo = blockManager->getBlockKernelInfo(i);
532             delete[](uint64_t *) blockInfo->heapInfo.pDsh;
533         }
534 
535         if (mockProgram) {
536             mockProgram->decRefInternal();
537         }
538     }
539 
getContext()540     Context *getContext() {
541         return &mockProgram->getContext();
542     }
543 
setReflectionSurface(GraphicsAllocation * reflectionSurface)544     void setReflectionSurface(GraphicsAllocation *reflectionSurface) {
545         kernelReflectionSurface = reflectionSurface;
546     }
547 
548     MockProgram *mockProgram;
549     KernelInfo *mockKernelInfo = nullptr;
550 };
551 
552 class MockSchedulerKernel : public SchedulerKernel {
553   public:
MockSchedulerKernel(Program * programArg,const KernelInfo & kernelInfoArg,ClDevice & clDeviceArg)554     MockSchedulerKernel(Program *programArg, const KernelInfo &kernelInfoArg, ClDevice &clDeviceArg) : SchedulerKernel(programArg, kernelInfoArg, clDeviceArg){};
555 };
556 
557 class MockDebugKernel : public MockKernel {
558   public:
MockDebugKernel(Program * program,const KernelInfo & kernelInfo,ClDevice & clDeviceArg)559     MockDebugKernel(Program *program, const KernelInfo &kernelInfo, ClDevice &clDeviceArg) : MockKernel(program, kernelInfo, clDeviceArg) {
560         if (!isValidOffset(kernelInfo.kernelDescriptor.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful)) {
561             auto &kd = const_cast<KernelDescriptor &>(kernelInfo.kernelDescriptor);
562             kd.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful = 0;
563             kd.kernelAttributes.perThreadSystemThreadSurfaceSize = MockDebugKernel::perThreadSystemThreadSurfaceSize;
564         }
565     }
566 
~MockDebugKernel()567     ~MockDebugKernel() override {}
568     static const uint32_t perThreadSystemThreadSurfaceSize;
569 };
570 
571 } // namespace NEO
572