1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #pragma once
9 #include "shared/source/execution_environment/execution_environment.h"
10 #include "shared/source/memory_manager/os_agnostic_memory_manager.h"
11 #include "shared/test/common/helpers/default_hw_info.h"
12 #include "shared/test/common/mocks/mock_execution_environment.h"
13 #include "shared/test/common/mocks/mock_host_ptr_manager.h"
14 
15 #include "gmock/gmock.h"
16 
17 namespace NEO {
18 
19 template <class T>
20 class MemoryManagerCreate : public T {
21   public:
22     using T::T;
23 
24     template <class... U>
MemoryManagerCreate(bool enable64kbPages,bool enableLocalMemory,U &&...args)25     MemoryManagerCreate(bool enable64kbPages, bool enableLocalMemory, U &&...args) : T(std::forward<U>(args)...) {
26         std::fill(this->enable64kbpages.begin(), this->enable64kbpages.end(), enable64kbPages);
27         std::fill(this->localMemorySupported.begin(), this->localMemorySupported.end(), enableLocalMemory);
28     }
29 };
30 
31 class MockMemoryManager : public MemoryManagerCreate<OsAgnosticMemoryManager> {
32   public:
33     using MemoryManager::allocateGraphicsMemoryInPreferredPool;
34     using MemoryManager::allocateGraphicsMemoryWithAlignment;
35     using MemoryManager::allocateGraphicsMemoryWithProperties;
36     using MemoryManager::createGraphicsAllocation;
37     using MemoryManager::createStorageInfoFromProperties;
38     using MemoryManager::defaultEngineIndex;
39     using MemoryManager::externalLocalMemoryUsageBankSelector;
40     using MemoryManager::getAllocationData;
41     using MemoryManager::gfxPartitions;
42     using MemoryManager::internalLocalMemoryUsageBankSelector;
43     using MemoryManager::isNonSvmBuffer;
44     using MemoryManager::multiContextResourceDestructor;
45     using MemoryManager::overrideAllocationData;
46     using MemoryManager::pageFaultManager;
47     using MemoryManager::registeredEngines;
48     using MemoryManager::supportsMultiStorageResources;
49     using MemoryManager::useNonSvmHostPtrAlloc;
50     using OsAgnosticMemoryManager::allocateGraphicsMemoryForImageFromHostPtr;
51     using MemoryManagerCreate<OsAgnosticMemoryManager>::MemoryManagerCreate;
52     using MemoryManager::enable64kbpages;
53     using MemoryManager::isaInLocalMemory;
54     using MemoryManager::isAllocationTypeToCapture;
55     using MemoryManager::isCopyRequired;
56     using MemoryManager::localMemorySupported;
57     using MemoryManager::reservedMemory;
58 
MockMemoryManager(ExecutionEnvironment & executionEnvironment)59     MockMemoryManager(ExecutionEnvironment &executionEnvironment) : MockMemoryManager(false, executionEnvironment) {}
60 
MockMemoryManager(bool enableLocalMemory,ExecutionEnvironment & executionEnvironment)61     MockMemoryManager(bool enableLocalMemory, ExecutionEnvironment &executionEnvironment) : MemoryManagerCreate(false, enableLocalMemory, executionEnvironment) {
62         hostPtrManager.reset(new MockHostPtrManager);
63     };
64 
MockMemoryManager()65     MockMemoryManager() : MockMemoryManager(*(new MockExecutionEnvironment(defaultHwInfo.get()))) {
66         mockExecutionEnvironment.reset(static_cast<MockExecutionEnvironment *>(&executionEnvironment));
67         mockExecutionEnvironment->initGmm();
68     };
MockMemoryManager(bool enable64pages,bool enableLocalMemory)69     MockMemoryManager(bool enable64pages, bool enableLocalMemory) : MemoryManagerCreate(enable64pages, enableLocalMemory, *(new MockExecutionEnvironment(defaultHwInfo.get()))) {
70         mockExecutionEnvironment.reset(static_cast<MockExecutionEnvironment *>(&executionEnvironment));
71     }
72     GraphicsAllocation *allocateGraphicsMemory64kb(const AllocationData &allocationData) override;
73     void setDeferredDeleter(DeferredDeleter *deleter);
74     void overrideAsyncDeleterFlag(bool newValue);
75     GraphicsAllocation *allocateGraphicsMemoryForImage(const AllocationData &allocationData) override;
76     GraphicsAllocation *allocateMemoryByKMD(const AllocationData &allocationData) override;
77     int redundancyRatio = 1;
78 
79     GraphicsAllocation *allocateGraphicsMemoryInDevicePool(const AllocationData &allocationData, AllocationStatus &status) override;
80     GraphicsAllocation *allocateGraphicsMemoryWithAlignment(const AllocationData &allocationData) override;
81     GraphicsAllocation *allocateGraphicsMemoryWithProperties(const AllocationProperties &properties) override;
82     GraphicsAllocation *allocateGraphicsMemoryWithProperties(const AllocationProperties &properties, const void *ptr) override;
83     GraphicsAllocation *createGraphicsAllocationFromExistingStorage(AllocationProperties &properties, void *ptr, MultiGraphicsAllocation &multiGraphicsAllocation) override;
84 
85     void *allocateSystemMemory(size_t size, size_t alignment) override;
86 
freeGraphicsMemoryImpl(GraphicsAllocation * gfxAllocation)87     void freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation) override {
88         freeGraphicsMemoryCalled++;
89         OsAgnosticMemoryManager::freeGraphicsMemoryImpl(gfxAllocation);
90     };
91 
lockResourceImpl(GraphicsAllocation & gfxAllocation)92     void *lockResourceImpl(GraphicsAllocation &gfxAllocation) override {
93         lockResourceCalled++;
94         auto pLockedMemory = OsAgnosticMemoryManager::lockResourceImpl(gfxAllocation);
95         lockResourcePointers.push_back(pLockedMemory);
96         return pLockedMemory;
97     }
98 
unlockResourceImpl(GraphicsAllocation & gfxAllocation)99     void unlockResourceImpl(GraphicsAllocation &gfxAllocation) override {
100         unlockResourceCalled++;
101         OsAgnosticMemoryManager::unlockResourceImpl(gfxAllocation);
102     }
103 
waitForEnginesCompletion(GraphicsAllocation & graphicsAllocation)104     void waitForEnginesCompletion(GraphicsAllocation &graphicsAllocation) override {
105         waitForEnginesCompletionCalled++;
106         if (waitAllocations.get()) {
107             waitAllocations.get()->addAllocation(&graphicsAllocation);
108         }
109         MemoryManager::waitForEnginesCompletion(graphicsAllocation);
110     }
111 
handleFenceCompletion(GraphicsAllocation * graphicsAllocation)112     void handleFenceCompletion(GraphicsAllocation *graphicsAllocation) override {
113         handleFenceCompletionCalled++;
114         OsAgnosticMemoryManager::handleFenceCompletion(graphicsAllocation);
115     }
116 
reserveCpuAddressRange(size_t size,uint32_t rootDeviceIndex)117     void *reserveCpuAddressRange(size_t size, uint32_t rootDeviceIndex) override {
118         if (failReserveAddress) {
119             return nullptr;
120         }
121         return OsAgnosticMemoryManager::reserveCpuAddressRange(size, rootDeviceIndex);
122     }
123 
createMultiGraphicsAllocationInSystemMemoryPool(std::vector<uint32_t> & rootDeviceIndices,AllocationProperties & properties,MultiGraphicsAllocation & multiGraphicsAllocation)124     void *createMultiGraphicsAllocationInSystemMemoryPool(std::vector<uint32_t> &rootDeviceIndices,
125                                                           AllocationProperties &properties,
126                                                           MultiGraphicsAllocation &multiGraphicsAllocation) override {
127         if (isMockEventPoolCreateMemoryManager) {
128             return nullptr;
129         }
130         return OsAgnosticMemoryManager::createMultiGraphicsAllocationInSystemMemoryPool(rootDeviceIndices, properties, multiGraphicsAllocation);
131     }
132 
isCpuCopyRequired(const void * ptr)133     bool isCpuCopyRequired(const void *ptr) override { return cpuCopyRequired; }
134 
135     GraphicsAllocation *allocate32BitGraphicsMemory(uint32_t rootDeviceIndex, size_t size, const void *ptr, GraphicsAllocation::AllocationType allocationType);
136     GraphicsAllocation *allocate32BitGraphicsMemoryImpl(const AllocationData &allocationData, bool useLocalMemory) override;
137     GraphicsAllocation *allocateGraphicsMemoryForNonSvmHostPtr(const AllocationData &allocationData) override;
138 
isLimitedGPU(uint32_t rootDeviceIndex)139     bool isLimitedGPU(uint32_t rootDeviceIndex) override {
140         return limitedGPU;
141     }
forceLimitedRangeAllocator(uint32_t rootDeviceIndex,uint64_t range)142     void forceLimitedRangeAllocator(uint32_t rootDeviceIndex, uint64_t range) { getGfxPartition(rootDeviceIndex)->init(range, 0, 0, gfxPartitions.size()); }
143 
setMemAdvise(GraphicsAllocation * gfxAllocation,MemAdviseFlags flags,uint32_t rootDeviceIndex)144     bool setMemAdvise(GraphicsAllocation *gfxAllocation, MemAdviseFlags flags, uint32_t rootDeviceIndex) override {
145         memAdviseFlags = flags;
146         if (failSetMemAdvise) {
147             return false;
148         }
149         return MemoryManager::setMemAdvise(gfxAllocation, flags, rootDeviceIndex);
150     }
151 
152     struct CopyMemoryToAllocationBanksParams {
153         GraphicsAllocation *graphicsAllocation = nullptr;
154         size_t destinationOffset = 0u;
155         const void *memoryToCopy = nullptr;
156         size_t sizeToCopy = 0u;
157         DeviceBitfield handleMask = {};
158     };
159 
160     StackVec<CopyMemoryToAllocationBanksParams, 2> copyMemoryToAllocationBanksParamsPassed{};
161     bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask) override;
162 
163     uint32_t copyMemoryToAllocationBanksCalled = 0u;
164     uint32_t freeGraphicsMemoryCalled = 0u;
165     uint32_t unlockResourceCalled = 0u;
166     uint32_t lockResourceCalled = 0u;
167     uint32_t createGraphicsAllocationFromExistingStorageCalled = 0u;
168     std::vector<GraphicsAllocation *> allocationsFromExistingStorage{};
169     AllocationData alignAllocationData;
170     uint32_t successAllocatedGraphicsMemoryIndex = 0u;
171     uint32_t maxSuccessAllocatedGraphicsMemoryIndex = std::numeric_limits<uint32_t>::max();
172     std::vector<void *> lockResourcePointers;
173     uint32_t handleFenceCompletionCalled = 0u;
174     uint32_t waitForEnginesCompletionCalled = 0u;
175     uint32_t allocateGraphicsMemoryWithPropertiesCount = 0;
176     bool allocationCreated = false;
177     bool allocation64kbPageCreated = false;
178     bool allocationInDevicePoolCreated = false;
179     bool failInDevicePool = false;
180     bool failInDevicePoolWithError = false;
181     bool failInAllocateWithSizeAndAlignment = false;
182     bool preferCompressedFlagPassed = false;
183     bool allocateForImageCalled = false;
184     bool allocate32BitGraphicsMemoryImplCalled = false;
185     bool allocateGraphicsMemoryForNonSvmHostPtrCalled = false;
186     bool allocateForShareableCalled = false;
187     bool failReserveAddress = false;
188     bool failAllocateSystemMemory = false;
189     bool failAllocate32Bit = false;
190     bool failSetMemAdvise = false;
191     bool cpuCopyRequired = false;
192     bool forceCompressed = false;
193     bool forceFailureInPrimaryAllocation = false;
194     bool forceFailureInAllocationWithHostPointer = false;
195     bool isMockHostMemoryManager = false;
196     bool isMockEventPoolCreateMemoryManager = false;
197     bool limitedGPU = false;
198     bool returnFakeAllocation = false;
199     std::unique_ptr<MockExecutionEnvironment> mockExecutionEnvironment;
200     DeviceBitfield recentlyPassedDeviceBitfield{};
201     std::unique_ptr<MultiGraphicsAllocation> waitAllocations = nullptr;
202     MemAdviseFlags memAdviseFlags{};
203 };
204 
205 class GMockMemoryManager : public MockMemoryManager {
206   public:
GMockMemoryManager(const ExecutionEnvironment & executionEnvironment)207     GMockMemoryManager(const ExecutionEnvironment &executionEnvironment) : MockMemoryManager(const_cast<ExecutionEnvironment &>(executionEnvironment)){};
208     MOCK_METHOD2(populateOsHandles, MemoryManager::AllocationStatus(OsHandleStorage &handleStorage, uint32_t rootDeviceIndex));
209     MOCK_METHOD1(allocateGraphicsMemoryForNonSvmHostPtr, GraphicsAllocation *(const AllocationData &));
210 
MemoryManagerPopulateOsHandles(OsHandleStorage & handleStorage,uint32_t rootDeviceIndex)211     MemoryManager::AllocationStatus MemoryManagerPopulateOsHandles(OsHandleStorage &handleStorage, uint32_t rootDeviceIndex) { return OsAgnosticMemoryManager::populateOsHandles(handleStorage, rootDeviceIndex); }
212 };
213 
214 class MockAllocSysMemAgnosticMemoryManager : public OsAgnosticMemoryManager {
215   public:
MockAllocSysMemAgnosticMemoryManager(ExecutionEnvironment & executionEnvironment)216     MockAllocSysMemAgnosticMemoryManager(ExecutionEnvironment &executionEnvironment) : OsAgnosticMemoryManager(executionEnvironment) {
217         ptrRestrictions = nullptr;
218         testRestrictions.minAddress = 0;
219     }
220 
getAlignedMallocRestrictions()221     AlignedMallocRestrictions *getAlignedMallocRestrictions() override {
222         return ptrRestrictions;
223     }
224 
allocateSystemMemory(size_t size,size_t alignment)225     void *allocateSystemMemory(size_t size, size_t alignment) override {
226         constexpr size_t minAlignment = 16;
227         alignment = std::max(alignment, minAlignment);
228         return alignedMalloc(size, alignment);
229     }
230 
231     AlignedMallocRestrictions testRestrictions;
232     AlignedMallocRestrictions *ptrRestrictions;
233 };
234 
235 class FailMemoryManager : public MockMemoryManager {
236   public:
237     using MemoryManager::allocateGraphicsMemoryWithProperties;
238     using MockMemoryManager::MockMemoryManager;
239     FailMemoryManager(int32_t failedAllocationsCount, ExecutionEnvironment &executionEnvironment);
240     FailMemoryManager(int32_t failedAllocationsCount, ExecutionEnvironment &executionEnvironment, bool localMemory);
241 
allocateGraphicsMemoryWithAlignment(const AllocationData & allocationData)242     GraphicsAllocation *allocateGraphicsMemoryWithAlignment(const AllocationData &allocationData) override {
243         if (failedAllocationsCount <= 0) {
244             return nullptr;
245         }
246         failedAllocationsCount--;
247         return OsAgnosticMemoryManager::allocateGraphicsMemoryWithAlignment(allocationData);
248     }
allocateGraphicsMemoryForNonSvmHostPtr(const AllocationData & allocationData)249     GraphicsAllocation *allocateGraphicsMemoryForNonSvmHostPtr(const AllocationData &allocationData) override {
250         return nullptr;
251     }
allocateGraphicsMemory64kb(const AllocationData & allocationData)252     GraphicsAllocation *allocateGraphicsMemory64kb(const AllocationData &allocationData) override {
253         return nullptr;
254     }
allocateGraphicsMemoryWithProperties(const AllocationProperties & properties,const void * ptr)255     GraphicsAllocation *allocateGraphicsMemoryWithProperties(const AllocationProperties &properties, const void *ptr) override {
256         return nullptr;
257     }
allocate32BitGraphicsMemoryImpl(const AllocationData & allocationData,bool useLocalMemory)258     GraphicsAllocation *allocate32BitGraphicsMemoryImpl(const AllocationData &allocationData, bool useLocalMemory) override {
259         return nullptr;
260     }
261 
createGraphicsAllocationFromSharedHandle(osHandle handle,const AllocationProperties & properties,bool requireSpecificBitness,bool isHostIpcAllocation)262     GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, bool requireSpecificBitness, bool isHostIpcAllocation) override {
263         return nullptr;
264     }
createGraphicsAllocationFromNTHandle(void * handle,uint32_t rootDeviceIndex,GraphicsAllocation::AllocationType allocType)265     GraphicsAllocation *createGraphicsAllocationFromNTHandle(void *handle, uint32_t rootDeviceIndex, GraphicsAllocation::AllocationType allocType) override {
266         return nullptr;
267     }
268 
lockResourceImpl(GraphicsAllocation & gfxAllocation)269     void *lockResourceImpl(GraphicsAllocation &gfxAllocation) override { return nullptr; };
unlockResourceImpl(GraphicsAllocation & gfxAllocation)270     void unlockResourceImpl(GraphicsAllocation &gfxAllocation) override{};
271 
populateOsHandles(OsHandleStorage & handleStorage,uint32_t rootDeviceIndex)272     MemoryManager::AllocationStatus populateOsHandles(OsHandleStorage &handleStorage, uint32_t rootDeviceIndex) override {
273         return AllocationStatus::Error;
274     };
cleanOsHandles(OsHandleStorage & handleStorage,uint32_t rootDeviceIndex)275     void cleanOsHandles(OsHandleStorage &handleStorage, uint32_t rootDeviceIndex) override{};
276 
getSystemSharedMemory(uint32_t rootDeviceIndex)277     uint64_t getSystemSharedMemory(uint32_t rootDeviceIndex) override {
278         return 0;
279     };
280 
createGraphicsAllocation(OsHandleStorage & handleStorage,const AllocationData & allocationData)281     GraphicsAllocation *createGraphicsAllocation(OsHandleStorage &handleStorage, const AllocationData &allocationData) override {
282         return nullptr;
283     };
allocateGraphicsMemoryForImage(const AllocationData & allocationData)284     GraphicsAllocation *allocateGraphicsMemoryForImage(const AllocationData &allocationData) override {
285         return nullptr;
286     }
allocateMemoryByKMD(const AllocationData & allocationData)287     GraphicsAllocation *allocateMemoryByKMD(const AllocationData &allocationData) override {
288         return nullptr;
289     }
290     int32_t failedAllocationsCount = 0;
291 };
292 
293 class GMockMemoryManagerFailFirstAllocation : public MockMemoryManager {
294   public:
GMockMemoryManagerFailFirstAllocation(bool enableLocalMemory,const ExecutionEnvironment & executionEnvironment)295     GMockMemoryManagerFailFirstAllocation(bool enableLocalMemory, const ExecutionEnvironment &executionEnvironment) : MockMemoryManager(enableLocalMemory, const_cast<ExecutionEnvironment &>(executionEnvironment)){};
GMockMemoryManagerFailFirstAllocation(const ExecutionEnvironment & executionEnvironment)296     GMockMemoryManagerFailFirstAllocation(const ExecutionEnvironment &executionEnvironment) : GMockMemoryManagerFailFirstAllocation(false, executionEnvironment){};
297 
298     MOCK_METHOD2(allocateGraphicsMemoryInDevicePool, GraphicsAllocation *(const AllocationData &, AllocationStatus &));
baseAllocateGraphicsMemoryInDevicePool(const AllocationData & allocationData,AllocationStatus & status)299     GraphicsAllocation *baseAllocateGraphicsMemoryInDevicePool(const AllocationData &allocationData, AllocationStatus &status) {
300         return OsAgnosticMemoryManager::allocateGraphicsMemoryInDevicePool(allocationData, status);
301     }
allocateNonSystemGraphicsMemoryInDevicePool(const AllocationData & allocationData,AllocationStatus & status)302     GraphicsAllocation *allocateNonSystemGraphicsMemoryInDevicePool(const AllocationData &allocationData, AllocationStatus &status) {
303         auto allocation = baseAllocateGraphicsMemoryInDevicePool(allocationData, status);
304         if (!allocation) {
305             allocation = allocateGraphicsMemory(allocationData);
306         }
307         static_cast<MemoryAllocation *>(allocation)->overrideMemoryPool(MemoryPool::SystemCpuInaccessible);
308         return allocation;
309     }
310 };
311 
312 } // namespace NEO
313