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/helpers/file_io.h" 11 #include "shared/source/memory_manager/allocation_properties.h" 12 #include "shared/source/program/kernel_info.h" 13 #include "shared/test/common/helpers/debug_manager_state_restore.h" 14 #include "shared/test/common/helpers/test_files.h" 15 #include "shared/test/common/mocks/mock_compilers.h" 16 #include "shared/test/common/mocks/mock_graphics_allocation.h" 17 #include "shared/test/common/mocks/mock_memory_manager.h" 18 #include "shared/test/unit_test/device_binary_format/zebin_tests.h" 19 20 #include "level_zero/core/source/module/module.h" 21 #include "level_zero/core/source/module/module_imp.h" 22 #include "level_zero/core/test/unit_tests/fixtures/device_fixture.h" 23 #include "level_zero/core/test/unit_tests/mocks/mock_built_ins.h" 24 #include "level_zero/core/test/unit_tests/mocks/mock_context.h" 25 #include "level_zero/core/test/unit_tests/mocks/mock_device.h" 26 #include "level_zero/core/test/unit_tests/mocks/mock_kernel.h" 27 28 namespace L0 { 29 namespace ult { 30 31 struct ModuleImmutableDataFixture : public DeviceFixture { 32 struct MockImmutableMemoryManager : public NEO::MockMemoryManager { MockImmutableMemoryManagerModuleImmutableDataFixture::MockImmutableMemoryManager33 MockImmutableMemoryManager(NEO::ExecutionEnvironment &executionEnvironment) : NEO::MockMemoryManager(const_cast<NEO::ExecutionEnvironment &>(executionEnvironment)) {} copyMemoryToAllocationModuleImmutableDataFixture::MockImmutableMemoryManager34 bool copyMemoryToAllocation(NEO::GraphicsAllocation *graphicsAllocation, 35 size_t destinationOffset, 36 const void *memoryToCopy, 37 size_t sizeToCopy) override { 38 copyMemoryToAllocationCalledTimes++; 39 return true; 40 } 41 uint32_t copyMemoryToAllocationCalledTimes = 0; 42 }; 43 44 struct MockImmutableData : KernelImmutableData { 45 using KernelImmutableData::crossThreadDataSize; 46 using KernelImmutableData::crossThreadDataTemplate; 47 using KernelImmutableData::kernelDescriptor; 48 using KernelImmutableData::kernelInfo; MockImmutableDataModuleImmutableDataFixture::MockImmutableData49 MockImmutableData(uint32_t perHwThreadPrivateMemorySize) { 50 mockKernelDescriptor = new NEO::KernelDescriptor; 51 mockKernelDescriptor->kernelAttributes.perHwThreadPrivateMemorySize = perHwThreadPrivateMemorySize; 52 kernelDescriptor = mockKernelDescriptor; 53 54 mockKernelInfo = new NEO::KernelInfo; 55 mockKernelInfo->heapInfo.pKernelHeap = kernelHeap; 56 mockKernelInfo->heapInfo.KernelHeapSize = MemoryConstants::pageSize; 57 kernelInfo = mockKernelInfo; 58 59 if (getIsaGraphicsAllocation() != nullptr) { 60 device->getNEODevice()->getMemoryManager()->freeGraphicsMemory(&*isaGraphicsAllocation); 61 isaGraphicsAllocation.release(); 62 } 63 isaGraphicsAllocation.reset(new NEO::MockGraphicsAllocation(0, 64 NEO::GraphicsAllocation::AllocationType::KERNEL_ISA, 65 reinterpret_cast<void *>(0x1234), 66 0x1000, 67 0, 68 sizeof(uint32_t), 69 MemoryPool::System4KBPages)); 70 } 71 setDeviceModuleImmutableDataFixture::MockImmutableData72 void setDevice(L0::Device *inDevice) { 73 device = inDevice; 74 } 75 ~MockImmutableDataModuleImmutableDataFixture::MockImmutableData76 ~MockImmutableData() override { 77 delete mockKernelInfo; 78 delete mockKernelDescriptor; 79 } resizeExplicitArgsModuleImmutableDataFixture::MockImmutableData80 void resizeExplicitArgs(size_t size) { 81 kernelDescriptor->payloadMappings.explicitArgs.resize(size); 82 } 83 NEO::KernelDescriptor *mockKernelDescriptor = nullptr; 84 char kernelHeap[MemoryConstants::pageSize] = {}; 85 NEO::KernelInfo *mockKernelInfo = nullptr; 86 }; 87 88 struct MockModule : public L0::ModuleImp { 89 using ModuleImp::getKernelImmutableDataVector; 90 using ModuleImp::kernelImmDatas; 91 using ModuleImp::maxGroupSize; 92 using ModuleImp::translationUnit; 93 using ModuleImp::type; 94 MockModuleModuleImmutableDataFixture::MockModule95 MockModule(L0::Device *device, 96 L0::ModuleBuildLog *moduleBuildLog, 97 L0::ModuleType type, 98 uint32_t perHwThreadPrivateMemorySize, 99 MockImmutableData *inMockKernelImmData) : ModuleImp(device, moduleBuildLog, type), mockKernelImmData(inMockKernelImmData) { 100 mockKernelImmData->setDevice(device); 101 } 102 ~MockModuleModuleImmutableDataFixture::MockModule103 ~MockModule() { 104 } 105 getKernelImmutableDataModuleImmutableDataFixture::MockModule106 const KernelImmutableData *getKernelImmutableData(const char *functionName) const override { 107 return mockKernelImmData; 108 } 109 checkIfPrivateMemoryPerDispatchIsNeededModuleImmutableDataFixture::MockModule110 void checkIfPrivateMemoryPerDispatchIsNeeded() override { 111 const_cast<KernelDescriptor &>(kernelImmDatas[0]->getDescriptor()).kernelAttributes.perHwThreadPrivateMemorySize = mockKernelImmData->getDescriptor().kernelAttributes.perHwThreadPrivateMemorySize; 112 ModuleImp::checkIfPrivateMemoryPerDispatchIsNeeded(); 113 } 114 115 MockImmutableData *mockKernelImmData = nullptr; 116 }; 117 118 class MockKernel : public WhiteBox<L0::KernelImp> { 119 public: 120 using KernelImp::crossThreadData; 121 using KernelImp::crossThreadDataSize; 122 using KernelImp::kernelArgHandlers; 123 using KernelImp::kernelHasIndirectAccess; 124 using KernelImp::privateMemoryGraphicsAllocation; 125 MockKernelModuleImmutableDataFixture126 MockKernel(MockModule *mockModule) : WhiteBox<L0::KernelImp>(mockModule) { 127 } setBufferSurfaceStateModuleImmutableDataFixture128 void setBufferSurfaceState(uint32_t argIndex, void *address, NEO::GraphicsAllocation *alloc) override { 129 return; 130 } evaluateIfRequiresGenerationOfLocalIdsByRuntimeModuleImmutableDataFixture131 void evaluateIfRequiresGenerationOfLocalIdsByRuntime(const NEO::KernelDescriptor &kernelDescriptor) override { 132 return; 133 } setCrossThreadDataModuleImmutableDataFixture134 void setCrossThreadData(uint32_t dataSize) { 135 crossThreadData.reset(new uint8_t[dataSize]); 136 crossThreadDataSize = dataSize; 137 memset(crossThreadData.get(), 0x00, crossThreadDataSize); 138 } ~MockKernelModuleImmutableDataFixture139 ~MockKernel() override { 140 } 141 }; 142 SetUpModuleImmutableDataFixture143 void SetUp() { 144 auto executionEnvironment = MockDevice::prepareExecutionEnvironment(NEO::defaultHwInfo.get(), 0u); 145 memoryManager = new MockImmutableMemoryManager(*executionEnvironment); 146 executionEnvironment->memoryManager.reset(memoryManager); 147 DeviceFixture::setupWithExecutionEnvironment(*executionEnvironment); 148 } 149 createModuleFromBinaryModuleImmutableDataFixture150 void createModuleFromBinary(uint32_t perHwThreadPrivateMemorySize, bool isInternal, MockImmutableData *mockKernelImmData) { 151 std::string testFile; 152 retrieveBinaryKernelFilenameNoRevision(testFile, binaryFilename + "_", ".bin"); 153 154 size_t size = 0; 155 auto src = loadDataFromFile( 156 testFile.c_str(), 157 size); 158 159 ASSERT_NE(0u, size); 160 ASSERT_NE(nullptr, src); 161 162 ze_module_desc_t moduleDesc = {}; 163 moduleDesc.format = ZE_MODULE_FORMAT_NATIVE; 164 moduleDesc.pInputModule = reinterpret_cast<const uint8_t *>(src.get()); 165 moduleDesc.inputSize = size; 166 167 ModuleBuildLog *moduleBuildLog = nullptr; 168 169 module = std::make_unique<MockModule>(device, 170 moduleBuildLog, 171 ModuleType::User, 172 perHwThreadPrivateMemorySize, 173 mockKernelImmData); 174 175 module->type = isInternal ? ModuleType::Builtin : ModuleType::User; 176 bool result = module->initialize(&moduleDesc, device->getNEODevice()); 177 EXPECT_TRUE(result); 178 } 179 createKernelModuleImmutableDataFixture180 void createKernel(MockKernel *kernel) { 181 ze_kernel_desc_t desc = {}; 182 desc.pKernelName = kernelName.c_str(); 183 kernel->initialize(&desc); 184 } 185 TearDownModuleImmutableDataFixture186 void TearDown() { 187 DeviceFixture::TearDown(); 188 } 189 190 const std::string binaryFilename = "test_kernel"; 191 const std::string kernelName = "test"; 192 const uint32_t numKernelArguments = 6; 193 std::unique_ptr<MockModule> module; 194 MockImmutableMemoryManager *memoryManager; 195 }; 196 197 struct ModuleFixture : public DeviceFixture { SetUpModuleFixture198 void SetUp() { 199 NEO::MockCompilerEnableGuard mock(true); 200 DeviceFixture::SetUp(); 201 createModuleFromBinary(); 202 } 203 204 void createModuleFromBinary(ModuleType type = ModuleType::User) { 205 std::string testFile; 206 retrieveBinaryKernelFilenameNoRevision(testFile, binaryFilename + "_", ".bin"); 207 208 size_t size = 0; 209 auto src = loadDataFromFile( 210 testFile.c_str(), 211 size); 212 213 ASSERT_NE(0u, size); 214 ASSERT_NE(nullptr, src); 215 216 ze_module_desc_t moduleDesc = {}; 217 moduleDesc.format = ZE_MODULE_FORMAT_NATIVE; 218 moduleDesc.pInputModule = reinterpret_cast<const uint8_t *>(src.get()); 219 moduleDesc.inputSize = size; 220 221 ModuleBuildLog *moduleBuildLog = nullptr; 222 223 module.reset(Module::create(device, &moduleDesc, moduleBuildLog, type)); 224 } 225 createKernelModuleFixture226 void createKernel() { 227 ze_kernel_desc_t desc = {}; 228 desc.pKernelName = kernelName.c_str(); 229 230 kernel = std::make_unique<WhiteBox<::L0::Kernel>>(); 231 kernel->module = module.get(); 232 kernel->initialize(&desc); 233 } 234 TearDownModuleFixture235 void TearDown() { 236 DeviceFixture::TearDown(); 237 } 238 239 const std::string binaryFilename = "test_kernel"; 240 const std::string kernelName = "test"; 241 const uint32_t numKernelArguments = 6; 242 std::unique_ptr<L0::Module> module; 243 std::unique_ptr<WhiteBox<::L0::Kernel>> kernel; 244 }; 245 246 struct MultiDeviceModuleFixture : public MultiDeviceFixture { SetUpMultiDeviceModuleFixture247 void SetUp() { 248 MultiDeviceFixture::SetUp(); 249 modules.resize(numRootDevices); 250 } 251 createModuleFromBinaryMultiDeviceModuleFixture252 void createModuleFromBinary(uint32_t rootDeviceIndex) { 253 std::string testFile; 254 retrieveBinaryKernelFilenameNoRevision(testFile, binaryFilename + "_", ".bin"); 255 256 size_t size = 0; 257 auto src = loadDataFromFile(testFile.c_str(), size); 258 259 ASSERT_NE(0u, size); 260 ASSERT_NE(nullptr, src); 261 262 ze_module_desc_t moduleDesc = {}; 263 moduleDesc.format = ZE_MODULE_FORMAT_NATIVE; 264 moduleDesc.pInputModule = reinterpret_cast<const uint8_t *>(src.get()); 265 moduleDesc.inputSize = size; 266 267 ModuleBuildLog *moduleBuildLog = nullptr; 268 269 auto device = driverHandle->devices[rootDeviceIndex]; 270 modules[rootDeviceIndex].reset(Module::create(device, 271 &moduleDesc, 272 moduleBuildLog, ModuleType::User)); 273 } 274 createKernelMultiDeviceModuleFixture275 void createKernel(uint32_t rootDeviceIndex) { 276 ze_kernel_desc_t desc = {}; 277 desc.pKernelName = kernelName.c_str(); 278 279 kernel = std::make_unique<WhiteBox<::L0::Kernel>>(); 280 kernel->module = modules[rootDeviceIndex].get(); 281 kernel->initialize(&desc); 282 } 283 TearDownMultiDeviceModuleFixture284 void TearDown() { 285 MultiDeviceFixture::TearDown(); 286 } 287 288 const std::string binaryFilename = "test_kernel"; 289 const std::string kernelName = "test"; 290 const uint32_t numKernelArguments = 6; 291 std::vector<std::unique_ptr<L0::Module>> modules; 292 std::unique_ptr<WhiteBox<::L0::Kernel>> kernel; 293 }; 294 295 struct ModuleWithZebinFixture : public DeviceFixture { 296 struct MockImmutableData : public KernelImmutableData { 297 using KernelImmutableData::device; 298 using KernelImmutableData::isaGraphicsAllocation; 299 using KernelImmutableData::kernelDescriptor; MockImmutableDataModuleWithZebinFixture::MockImmutableData300 MockImmutableData(L0::Device *device) { 301 302 auto mockKernelDescriptor = new NEO::KernelDescriptor; 303 mockKernelDescriptor->kernelMetadata.kernelName = "kernel"; 304 kernelDescriptor = mockKernelDescriptor; 305 this->device = device; 306 isaGraphicsAllocation.reset(new NEO::MockGraphicsAllocation(0, 307 NEO::GraphicsAllocation::AllocationType::KERNEL_ISA, 308 reinterpret_cast<void *>(0x1234), 309 0x1000, 310 0, 311 sizeof(uint32_t), 312 MemoryPool::System4KBPages)); 313 } 314 ~MockImmutableDataModuleWithZebinFixture::MockImmutableData315 ~MockImmutableData() { 316 delete kernelDescriptor; 317 } 318 }; 319 320 struct MockModuleWithZebin : public L0::ModuleImp { 321 using ModuleImp::getDebugInfo; 322 using ModuleImp::getZebinSegments; 323 using ModuleImp::kernelImmDatas; 324 using ModuleImp::passDebugData; 325 using ModuleImp::translationUnit; MockModuleWithZebinModuleWithZebinFixture::MockModuleWithZebin326 MockModuleWithZebin(L0::Device *device) : ModuleImp(device, nullptr, ModuleType::User) {} 327 addSegmentsModuleWithZebinFixture::MockModuleWithZebin328 void addSegments() { 329 kernelImmDatas.push_back(std::make_unique<MockImmutableData>(device)); 330 translationUnit->globalVarBuffer = new NEO::MockGraphicsAllocation(0, 331 NEO::GraphicsAllocation::AllocationType::GLOBAL_SURFACE, 332 reinterpret_cast<void *>(0x1234), 333 0x1000, 334 0, 335 sizeof(uint32_t), 336 MemoryPool::System4KBPages); 337 translationUnit->globalConstBuffer = new NEO::MockGraphicsAllocation(0, 338 NEO::GraphicsAllocation::AllocationType::GLOBAL_SURFACE, 339 reinterpret_cast<void *>(0x1234), 340 0x1000, 341 0, 342 sizeof(uint32_t), 343 MemoryPool::System4KBPages); 344 345 translationUnit->programInfo.globalStrings.initData = &strings; 346 translationUnit->programInfo.globalStrings.size = sizeof(strings); 347 } 348 addKernelSegmentModuleWithZebinFixture::MockModuleWithZebin349 void addKernelSegment() { 350 } 351 addEmptyZebinModuleWithZebinFixture::MockModuleWithZebin352 void addEmptyZebin() { 353 auto zebin = ZebinTestData::ValidEmptyProgram(); 354 355 translationUnit->unpackedDeviceBinarySize = zebin.storage.size(); 356 translationUnit->unpackedDeviceBinary.reset(new char[zebin.storage.size()]); 357 memcpy_s(translationUnit->unpackedDeviceBinary.get(), translationUnit->unpackedDeviceBinarySize, 358 zebin.storage.data(), zebin.storage.size()); 359 } 360 ~MockModuleWithZebinModuleWithZebinFixture::MockModuleWithZebin361 ~MockModuleWithZebin() { 362 } 363 364 const char strings[12] = "Hello olleH"; 365 }; SetUpModuleWithZebinFixture366 void SetUp() { 367 NEO::MockCompilerEnableGuard mock(true); 368 DeviceFixture::SetUp(); 369 module = std::make_unique<MockModuleWithZebin>(device); 370 } 371 TearDownModuleWithZebinFixture372 void TearDown() { 373 DeviceFixture::TearDown(); 374 } 375 std::unique_ptr<MockModuleWithZebin> module; 376 }; 377 378 struct ImportHostPointerModuleFixture : public ModuleFixture { SetUpImportHostPointerModuleFixture379 void SetUp() { 380 DebugManager.flags.EnableHostPointerImport.set(1); 381 ModuleFixture::SetUp(); 382 383 hostPointer = driverHandle->getMemoryManager()->allocateSystemMemory(MemoryConstants::pageSize, MemoryConstants::pageSize); 384 } 385 TearDownImportHostPointerModuleFixture386 void TearDown() { 387 driverHandle->getMemoryManager()->freeSystemMemory(hostPointer); 388 ModuleFixture::TearDown(); 389 } 390 391 DebugManagerStateRestore debugRestore; 392 void *hostPointer = nullptr; 393 }; 394 395 } // namespace ult 396 } // namespace L0 397