1 /*
2  * Copyright (C) 2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/command_stream/command_stream_receiver.h"
9 #include "shared/source/command_stream/linear_stream.h"
10 #include "shared/source/device/root_device.h"
11 #include "shared/source/device/sub_device.h"
12 #include "shared/test/common/helpers/debug_manager_state_restore.h"
13 #include "shared/test/common/helpers/ult_hw_config.h"
14 #include "shared/test/common/helpers/variable_backup.h"
15 #include "shared/test/common/libult/ult_command_stream_receiver.h"
16 #include "shared/test/common/mocks/mock_device.h"
17 #include "shared/test/common/mocks/mock_graphics_allocation.h"
18 #include "shared/test/common/mocks/mock_memory_manager.h"
19 #include "shared/test/common/mocks/ult_device_factory.h"
20 #include "shared/test/common/test_macros/test.h"
21 
22 #include "opencl/source/cl_device/cl_device.h"
23 
24 using namespace NEO;
25 
26 struct MultiDeviceStorageInfoTest : public ::testing::Test {
SetUpMultiDeviceStorageInfoTest27     void SetUp() override {
28         ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
29         DebugManager.flags.CreateMultipleSubDevices.set(numDevices);
30         DebugManager.flags.EnableLocalMemory.set(true);
31         memoryManager = static_cast<MockMemoryManager *>(factory.rootDevices[0]->getMemoryManager());
32     }
33     const uint32_t numDevices = 4u;
34     const DeviceBitfield allTilesMask{maxNBitValue(4u)};
35     const uint32_t tileIndex = 2u;
36     const DeviceBitfield singleTileMask{static_cast<uint32_t>(1u << tileIndex)};
37     DebugManagerStateRestore restorer;
38     UltDeviceFactory factory{1, numDevices};
39     VariableBackup<UltHwConfig> backup{&ultHwConfig};
40     MockMemoryManager *memoryManager;
41 };
42 
TEST_F(MultiDeviceStorageInfoTest,givenEnabledFlagForMultiTileIsaPlacementWhenCreatingStorageInfoForKernelIsaThenAllMemoryBanksAreOnAndPageTableClonningIsNotRequired)43 TEST_F(MultiDeviceStorageInfoTest, givenEnabledFlagForMultiTileIsaPlacementWhenCreatingStorageInfoForKernelIsaThenAllMemoryBanksAreOnAndPageTableClonningIsNotRequired) {
44     DebugManagerStateRestore restorer;
45     DebugManager.flags.MultiTileIsaPlacement.set(1);
46 
47     GraphicsAllocation::AllocationType isaTypes[] = {GraphicsAllocation::AllocationType::KERNEL_ISA, GraphicsAllocation::AllocationType::KERNEL_ISA_INTERNAL};
48 
49     for (uint32_t i = 0; i < 2; i++) {
50         AllocationProperties properties{mockRootDeviceIndex, false, 0u, isaTypes[i], false, false, singleTileMask};
51         auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
52         EXPECT_FALSE(storageInfo.cloningOfPageTables);
53         EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
54         EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
55         EXPECT_TRUE(storageInfo.tileInstanced);
56 
57         properties.flags.multiOsContextCapable = true;
58         auto storageInfo2 = memoryManager->createStorageInfoFromProperties(properties);
59         EXPECT_FALSE(storageInfo2.cloningOfPageTables);
60         EXPECT_EQ(allTilesMask, storageInfo2.memoryBanks);
61         EXPECT_EQ(allTilesMask, storageInfo2.pageTablesVisibility);
62         EXPECT_TRUE(storageInfo2.tileInstanced);
63     }
64 }
65 
TEST_F(MultiDeviceStorageInfoTest,givenDefaultFlagForMultiTileIsaPlacementWhenCreatingStorageInfoForKernelIsaThenSingleMemoryBanksIsOnAndPageTableClonningIsRequired)66 TEST_F(MultiDeviceStorageInfoTest, givenDefaultFlagForMultiTileIsaPlacementWhenCreatingStorageInfoForKernelIsaThenSingleMemoryBanksIsOnAndPageTableClonningIsRequired) {
67 
68     GraphicsAllocation::AllocationType isaTypes[] = {GraphicsAllocation::AllocationType::KERNEL_ISA, GraphicsAllocation::AllocationType::KERNEL_ISA_INTERNAL};
69 
70     for (uint32_t i = 0; i < 2; i++) {
71         AllocationProperties properties{mockRootDeviceIndex, false, 0u, isaTypes[i], false, false, singleTileMask};
72 
73         auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
74         EXPECT_TRUE(storageInfo.cloningOfPageTables);
75         EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
76         EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
77         EXPECT_FALSE(storageInfo.tileInstanced);
78 
79         properties.flags.multiOsContextCapable = true;
80         auto storageInfo2 = memoryManager->createStorageInfoFromProperties(properties);
81         EXPECT_TRUE(storageInfo2.cloningOfPageTables);
82         EXPECT_EQ(singleTileMask, storageInfo2.memoryBanks);
83         EXPECT_EQ(allTilesMask, storageInfo2.pageTablesVisibility);
84         EXPECT_FALSE(storageInfo2.tileInstanced);
85     }
86 }
87 
TEST_F(MultiDeviceStorageInfoTest,givenDisabledFlagForMultiTileIsaPlacementWhenCreatingStorageInfoForKernelIsaThenSingleMemoryBanksIsOnAndPageTableClonningIsRequired)88 TEST_F(MultiDeviceStorageInfoTest, givenDisabledFlagForMultiTileIsaPlacementWhenCreatingStorageInfoForKernelIsaThenSingleMemoryBanksIsOnAndPageTableClonningIsRequired) {
89     DebugManagerStateRestore restorer;
90     DebugManager.flags.MultiTileIsaPlacement.set(0);
91 
92     GraphicsAllocation::AllocationType isaTypes[] = {GraphicsAllocation::AllocationType::KERNEL_ISA, GraphicsAllocation::AllocationType::KERNEL_ISA_INTERNAL};
93 
94     for (uint32_t i = 0; i < 2; i++) {
95         AllocationProperties properties{mockRootDeviceIndex, false, 0u, isaTypes[i], false, false, singleTileMask};
96         auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
97         EXPECT_TRUE(storageInfo.cloningOfPageTables);
98         EXPECT_EQ(singleTileMask, storageInfo.memoryBanks.to_ulong());
99         EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
100         EXPECT_FALSE(storageInfo.tileInstanced);
101 
102         properties.flags.multiOsContextCapable = true;
103         auto storageInfo2 = memoryManager->createStorageInfoFromProperties(properties);
104         EXPECT_TRUE(storageInfo2.cloningOfPageTables);
105         EXPECT_EQ(singleTileMask, storageInfo2.memoryBanks.to_ulong());
106         EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
107         EXPECT_FALSE(storageInfo2.tileInstanced);
108     }
109 }
110 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForPrivateSurfaceWithOneTileThenOnlySingleBankIsUsed)111 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForPrivateSurfaceWithOneTileThenOnlySingleBankIsUsed) {
112     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::PRIVATE_SURFACE, false, false, singleTileMask};
113     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
114     EXPECT_FALSE(storageInfo.cloningOfPageTables);
115     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
116     EXPECT_EQ(singleTileMask, storageInfo.pageTablesVisibility);
117     EXPECT_FALSE(storageInfo.tileInstanced);
118     EXPECT_EQ(1u, storageInfo.getNumBanks());
119 }
120 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForPrivateSurfaceThenAllMemoryBanksAreOnAndPageTableClonningIsNotRequired)121 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForPrivateSurfaceThenAllMemoryBanksAreOnAndPageTableClonningIsNotRequired) {
122     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::PRIVATE_SURFACE, false, false, allTilesMask};
123     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
124     EXPECT_FALSE(storageInfo.cloningOfPageTables);
125     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
126     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
127     EXPECT_TRUE(storageInfo.tileInstanced);
128     EXPECT_EQ(4u, storageInfo.getNumBanks());
129 }
130 
TEST_F(MultiDeviceStorageInfoTest,givenMultiTileCsrWhenCreatingStorageInfoForInternalHeapThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)131 TEST_F(MultiDeviceStorageInfoTest, givenMultiTileCsrWhenCreatingStorageInfoForInternalHeapThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
132     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::INTERNAL_HEAP, true, false, singleTileMask};
133     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
134     EXPECT_TRUE(storageInfo.cloningOfPageTables);
135     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
136     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
137 }
138 
TEST_F(MultiDeviceStorageInfoTest,givenSingleTileCsrWhenCreatingStorageInfoForInternalHeapThenSingleMemoryBankIsOnAndPageTableClonningIsNotRequired)139 TEST_F(MultiDeviceStorageInfoTest, givenSingleTileCsrWhenCreatingStorageInfoForInternalHeapThenSingleMemoryBankIsOnAndPageTableClonningIsNotRequired) {
140     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::INTERNAL_HEAP, false, false, singleTileMask};
141     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
142     EXPECT_FALSE(storageInfo.cloningOfPageTables);
143     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
144     EXPECT_EQ(singleTileMask, storageInfo.pageTablesVisibility);
145     EXPECT_FALSE(storageInfo.tileInstanced);
146 }
147 
TEST_F(MultiDeviceStorageInfoTest,givenMultiTileCsrWhenCreatingStorageInfoForLinearStreamThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)148 TEST_F(MultiDeviceStorageInfoTest, givenMultiTileCsrWhenCreatingStorageInfoForLinearStreamThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
149     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::LINEAR_STREAM, true, false, singleTileMask};
150     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
151     EXPECT_TRUE(storageInfo.cloningOfPageTables);
152     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
153     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
154 }
155 
TEST_F(MultiDeviceStorageInfoTest,givenSingleTileCsrWhenCreatingStorageInfoForLinearStreamThenSingleMemoryBankIsOnAndPageTableClonningIsNotRequired)156 TEST_F(MultiDeviceStorageInfoTest, givenSingleTileCsrWhenCreatingStorageInfoForLinearStreamThenSingleMemoryBankIsOnAndPageTableClonningIsNotRequired) {
157     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::LINEAR_STREAM, false, false, singleTileMask};
158     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
159     EXPECT_FALSE(storageInfo.cloningOfPageTables);
160     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
161     EXPECT_EQ(singleTileMask, storageInfo.pageTablesVisibility);
162     EXPECT_FALSE(storageInfo.tileInstanced);
163 }
164 
TEST_F(MultiDeviceStorageInfoTest,givenMultiTileCsrWhenCreatingStorageInfoForCommandBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)165 TEST_F(MultiDeviceStorageInfoTest, givenMultiTileCsrWhenCreatingStorageInfoForCommandBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
166     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::COMMAND_BUFFER, true, false, singleTileMask};
167     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
168     EXPECT_TRUE(storageInfo.cloningOfPageTables);
169     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
170     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
171 }
172 
TEST_F(MultiDeviceStorageInfoTest,givenSingleTileCsrWhenCreatingStorageInfoForCommandBufferThenSingleMemoryBankIsOnAndPageTableClonningIsNotRequired)173 TEST_F(MultiDeviceStorageInfoTest, givenSingleTileCsrWhenCreatingStorageInfoForCommandBufferThenSingleMemoryBankIsOnAndPageTableClonningIsNotRequired) {
174     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::COMMAND_BUFFER, false, false, singleTileMask};
175     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
176     EXPECT_FALSE(storageInfo.cloningOfPageTables);
177     EXPECT_FALSE(storageInfo.tileInstanced);
178     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
179     EXPECT_EQ(singleTileMask, storageInfo.pageTablesVisibility);
180 }
181 
TEST_F(MultiDeviceStorageInfoTest,givenMultiTileCsrWhenCreatingStorageInfoForScratchSpaceThenAllMemoryBankAreOnAndPageTableClonningIsNotRequired)182 TEST_F(MultiDeviceStorageInfoTest, givenMultiTileCsrWhenCreatingStorageInfoForScratchSpaceThenAllMemoryBankAreOnAndPageTableClonningIsNotRequired) {
183     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::SCRATCH_SURFACE, true, false, singleTileMask};
184     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
185     EXPECT_FALSE(storageInfo.cloningOfPageTables);
186     EXPECT_TRUE(storageInfo.tileInstanced);
187     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
188     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
189 }
190 
TEST_F(MultiDeviceStorageInfoTest,givenSingleTileCsrWhenCreatingStorageInfoForScratchSpaceThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)191 TEST_F(MultiDeviceStorageInfoTest, givenSingleTileCsrWhenCreatingStorageInfoForScratchSpaceThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
192     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::SCRATCH_SURFACE, false, false, singleTileMask};
193     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
194     EXPECT_TRUE(storageInfo.cloningOfPageTables);
195     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
196     EXPECT_EQ(singleTileMask, storageInfo.pageTablesVisibility);
197 }
198 
TEST_F(MultiDeviceStorageInfoTest,givenMultiTileCsrWhenCreatingStorageInfoForPreemptionAllocationThenAllMemoryBankAreOnAndPageTableClonningIsNotRequired)199 TEST_F(MultiDeviceStorageInfoTest, givenMultiTileCsrWhenCreatingStorageInfoForPreemptionAllocationThenAllMemoryBankAreOnAndPageTableClonningIsNotRequired) {
200     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::PREEMPTION, true, false, singleTileMask};
201     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
202     EXPECT_FALSE(storageInfo.cloningOfPageTables);
203     EXPECT_TRUE(storageInfo.tileInstanced);
204     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
205     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
206 }
207 
TEST_F(MultiDeviceStorageInfoTest,givenSingleTileCsrWhenCreatingStorageInfoForPreemptionAllocationThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)208 TEST_F(MultiDeviceStorageInfoTest, givenSingleTileCsrWhenCreatingStorageInfoForPreemptionAllocationThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
209     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::PREEMPTION, false, false, singleTileMask};
210     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
211     EXPECT_TRUE(storageInfo.cloningOfPageTables);
212     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
213     EXPECT_EQ(singleTileMask, storageInfo.pageTablesVisibility);
214 }
215 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForWorkPartitionSurfaceThenAllMemoryBankAreOnAndPageTableClonningIsNotRequired)216 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForWorkPartitionSurfaceThenAllMemoryBankAreOnAndPageTableClonningIsNotRequired) {
217     AllocationProperties properties{mockRootDeviceIndex, false, 0u, GraphicsAllocation::AllocationType::WORK_PARTITION_SURFACE, true, false, singleTileMask};
218     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
219     EXPECT_FALSE(storageInfo.cloningOfPageTables);
220     EXPECT_TRUE(storageInfo.tileInstanced);
221     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
222     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
223 }
224 
HWTEST_F(MultiDeviceStorageInfoTest,givenSingleTileCsrWhenAllocatingCsrSpecificAllocationsThenStoreThemInSystemMemory)225 HWTEST_F(MultiDeviceStorageInfoTest, givenSingleTileCsrWhenAllocatingCsrSpecificAllocationsThenStoreThemInSystemMemory) {
226     auto commandStreamReceiver = static_cast<UltCommandStreamReceiver<FamilyType> *>(factory.rootDevices[0]->getSubDevice(tileIndex)->getDefaultEngine().commandStreamReceiver);
227     auto &heap = commandStreamReceiver->getIndirectHeap(IndirectHeap::INDIRECT_OBJECT, MemoryConstants::pageSize64k);
228     auto heapAllocation = heap.getGraphicsAllocation();
229     if (commandStreamReceiver->canUse4GbHeaps) {
230         EXPECT_EQ(GraphicsAllocation::AllocationType::INTERNAL_HEAP, heapAllocation->getAllocationType());
231     } else {
232         EXPECT_EQ(GraphicsAllocation::AllocationType::LINEAR_STREAM, heapAllocation->getAllocationType());
233     }
234 
235     commandStreamReceiver->ensureCommandBufferAllocation(heap, heap.getAvailableSpace() + 1, 0u);
236     auto commandBufferAllocation = heap.getGraphicsAllocation();
237     EXPECT_EQ(GraphicsAllocation::AllocationType::COMMAND_BUFFER, commandBufferAllocation->getAllocationType());
238     EXPECT_NE(heapAllocation, commandBufferAllocation);
239     EXPECT_NE(commandBufferAllocation->getMemoryPool(), MemoryPool::LocalMemory);
240 }
241 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForBufferCompressedThenAllMemoryBanksAreOnAndPageTableClonningIsRequired)242 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForBufferCompressedThenAllMemoryBanksAreOnAndPageTableClonningIsRequired) {
243     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::BUFFER, true, allTilesMask};
244     properties.flags.preferCompressed = true;
245     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
246     EXPECT_TRUE(storageInfo.cloningOfPageTables);
247     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
248     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
249     EXPECT_TRUE(storageInfo.multiStorage);
250     EXPECT_EQ(storageInfo.colouringGranularity, MemoryConstants::pageSize64k);
251     EXPECT_EQ(storageInfo.colouringPolicy, ColouringPolicy::DeviceCountBased);
252 }
253 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForBufferThenAllMemoryBanksAreOnAndPageTableClonningIsRequired)254 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForBufferThenAllMemoryBanksAreOnAndPageTableClonningIsRequired) {
255     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::BUFFER, true, allTilesMask};
256     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
257     EXPECT_TRUE(storageInfo.cloningOfPageTables);
258     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
259     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
260     EXPECT_TRUE(storageInfo.multiStorage);
261     EXPECT_EQ(storageInfo.colouringGranularity, MemoryConstants::pageSize64k);
262     EXPECT_EQ(storageInfo.colouringPolicy, ColouringPolicy::DeviceCountBased);
263 }
264 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForSVMGPUThenAllMemoryBanksAreOnAndPageTableClonningIsRequired)265 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForSVMGPUThenAllMemoryBanksAreOnAndPageTableClonningIsRequired) {
266     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::SVM_GPU, true, allTilesMask};
267     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
268     EXPECT_TRUE(storageInfo.cloningOfPageTables);
269     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
270     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
271     EXPECT_TRUE(storageInfo.multiStorage);
272     EXPECT_EQ(storageInfo.colouringGranularity, MemoryConstants::pageSize64k);
273     EXPECT_EQ(storageInfo.colouringPolicy, ColouringPolicy::DeviceCountBased);
274 }
275 
TEST_F(MultiDeviceStorageInfoTest,givenMultiStorageGranularityWhenCreatingStorageInfoThenProperGranularityIsSet)276 TEST_F(MultiDeviceStorageInfoTest, givenMultiStorageGranularityWhenCreatingStorageInfoThenProperGranularityIsSet) {
277     DebugManagerStateRestore restorer;
278     DebugManager.flags.MultiStorageGranularity.set(128);
279     DebugManager.flags.MultiStoragePolicy.set(1);
280 
281     AllocationProperties properties{mockRootDeviceIndex, false, 10 * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::SVM_GPU, true, allTilesMask};
282     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
283     EXPECT_TRUE(storageInfo.cloningOfPageTables);
284     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
285     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
286     EXPECT_TRUE(storageInfo.multiStorage);
287     EXPECT_EQ(storageInfo.colouringGranularity, MemoryConstants::kiloByte * 128);
288     EXPECT_EQ(storageInfo.colouringPolicy, ColouringPolicy::ChunkSizeBased);
289 }
290 
TEST_F(MultiDeviceStorageInfoTest,givenTwoPagesAllocationSizeWhenCreatingStorageInfoForBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)291 TEST_F(MultiDeviceStorageInfoTest, givenTwoPagesAllocationSizeWhenCreatingStorageInfoForBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
292     AllocationProperties properties{mockRootDeviceIndex, false, 2 * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::BUFFER, true, allTilesMask};
293     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
294     EXPECT_TRUE(storageInfo.cloningOfPageTables);
295     EXPECT_EQ(1lu, storageInfo.memoryBanks.to_ulong());
296     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
297     EXPECT_FALSE(storageInfo.multiStorage);
298 }
299 
TEST_F(MultiDeviceStorageInfoTest,givenSpecifiedDeviceIndexWhenCreatingStorageInfoForBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)300 TEST_F(MultiDeviceStorageInfoTest, givenSpecifiedDeviceIndexWhenCreatingStorageInfoForBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
301     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::BUFFER, true, false, singleTileMask};
302     properties.multiStorageResource = true;
303     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
304     EXPECT_TRUE(storageInfo.cloningOfPageTables);
305     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
306     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
307     EXPECT_FALSE(storageInfo.multiStorage);
308 }
309 
TEST_F(MultiDeviceStorageInfoTest,givenResourceColouringNotSupportedWhenCreatingStorageInfoForBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)310 TEST_F(MultiDeviceStorageInfoTest, givenResourceColouringNotSupportedWhenCreatingStorageInfoForBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
311     memoryManager->supportsMultiStorageResources = false;
312     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::BUFFER, true, singleTileMask};
313     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
314     EXPECT_TRUE(storageInfo.cloningOfPageTables);
315     EXPECT_EQ(1lu, storageInfo.memoryBanks.count());
316     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
317     EXPECT_FALSE(storageInfo.multiStorage);
318 }
319 
TEST_F(MultiDeviceStorageInfoTest,givenNonMultiStorageResourceWhenCreatingStorageInfoForBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired)320 TEST_F(MultiDeviceStorageInfoTest, givenNonMultiStorageResourceWhenCreatingStorageInfoForBufferThenSingleMemoryBankIsOnAndPageTableClonningIsRequired) {
321     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::BUFFER, false, singleTileMask};
322     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
323     EXPECT_TRUE(storageInfo.cloningOfPageTables);
324     EXPECT_EQ(1lu, storageInfo.memoryBanks.count());
325     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
326     EXPECT_FALSE(storageInfo.multiStorage);
327 }
328 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForBufferThenLocalOnlyFlagIsRequired)329 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForBufferThenLocalOnlyFlagIsRequired) {
330     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::BUFFER, false, singleTileMask};
331     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
332     EXPECT_TRUE(storageInfo.localOnlyRequired);
333 }
334 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForBufferCompressedThenLocalOnlyFlagIsRequired)335 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForBufferCompressedThenLocalOnlyFlagIsRequired) {
336     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::BUFFER, false, singleTileMask};
337     properties.flags.preferCompressed = true;
338     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
339     EXPECT_TRUE(storageInfo.localOnlyRequired);
340 }
341 
TEST_F(MultiDeviceStorageInfoTest,whenCreatingStorageInfoForSvmGpuThenLocalOnlyFlagIsRequired)342 TEST_F(MultiDeviceStorageInfoTest, whenCreatingStorageInfoForSvmGpuThenLocalOnlyFlagIsRequired) {
343     AllocationProperties properties{mockRootDeviceIndex, false, numDevices * MemoryConstants::pageSize64k, GraphicsAllocation::AllocationType::SVM_GPU, false, singleTileMask};
344     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
345     EXPECT_TRUE(storageInfo.localOnlyRequired);
346 }
347 
TEST_F(MultiDeviceStorageInfoTest,givenReadOnlyBufferToBeCopiedAcrossTilesWhenCreatingStorageInfoThenCorrectValuesAreSet)348 TEST_F(MultiDeviceStorageInfoTest, givenReadOnlyBufferToBeCopiedAcrossTilesWhenCreatingStorageInfoThenCorrectValuesAreSet) {
349     AllocationProperties properties{mockRootDeviceIndex, false, 1u, GraphicsAllocation::AllocationType::BUFFER, false, singleTileMask};
350     properties.flags.readOnlyMultiStorage = true;
351     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
352     EXPECT_EQ(allTilesMask, storageInfo.memoryBanks);
353     EXPECT_FALSE(storageInfo.cloningOfPageTables);
354     EXPECT_TRUE(storageInfo.readOnlyMultiStorage);
355     EXPECT_TRUE(storageInfo.tileInstanced);
356 }
357 
TEST_F(MultiDeviceStorageInfoTest,givenReadOnlyBufferToBeCopiedAcrossTilesWhenDebugVariableIsSetThenOnlyCertainBanksAreUsed)358 TEST_F(MultiDeviceStorageInfoTest, givenReadOnlyBufferToBeCopiedAcrossTilesWhenDebugVariableIsSetThenOnlyCertainBanksAreUsed) {
359     DebugManagerStateRestore restorer;
360     auto proposedTiles = allTilesMask;
361     proposedTiles[1] = 0;
362 
363     DebugManager.flags.OverrideMultiStoragePlacement.set(proposedTiles.to_ulong());
364 
365     AllocationProperties properties{mockRootDeviceIndex, false, 64 * KB * 40, GraphicsAllocation::AllocationType::BUFFER, true, allTilesMask};
366 
367     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
368     EXPECT_EQ(proposedTiles, storageInfo.memoryBanks);
369     EXPECT_TRUE(storageInfo.cloningOfPageTables);
370     EXPECT_FALSE(storageInfo.tileInstanced);
371     EXPECT_EQ(3u, storageInfo.getNumBanks());
372 }
373 
TEST_F(MultiDeviceStorageInfoTest,givenLeastOccupiedBankAndOtherBitsEnabledInSubDeviceBitfieldWhenCreateStorageInfoThenTakeLeastOccupiedBankAsMemoryBank)374 TEST_F(MultiDeviceStorageInfoTest, givenLeastOccupiedBankAndOtherBitsEnabledInSubDeviceBitfieldWhenCreateStorageInfoThenTakeLeastOccupiedBankAsMemoryBank) {
375     AllocationProperties properties{mockRootDeviceIndex, false, 1u, GraphicsAllocation::AllocationType::UNKNOWN, false, singleTileMask};
376     auto leastOccupiedBank = memoryManager->getLocalMemoryUsageBankSelector(properties.allocationType, properties.rootDeviceIndex)->getLeastOccupiedBank(properties.subDevicesBitfield);
377     properties.subDevicesBitfield.set(leastOccupiedBank);
378     properties.subDevicesBitfield.set(leastOccupiedBank + 1);
379     EXPECT_EQ(2u, properties.subDevicesBitfield.count());
380     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
381     EXPECT_EQ(1u, storageInfo.memoryBanks.count());
382     EXPECT_TRUE(storageInfo.memoryBanks.test(leastOccupiedBank));
383 }
384 
TEST_F(MultiDeviceStorageInfoTest,givenNoSubdeviceBitfieldWhenCreateStorageInfoThenReturnEmptyStorageInfo)385 TEST_F(MultiDeviceStorageInfoTest, givenNoSubdeviceBitfieldWhenCreateStorageInfoThenReturnEmptyStorageInfo) {
386     AllocationProperties properties{mockRootDeviceIndex, false, 1u, GraphicsAllocation::AllocationType::UNKNOWN, false, {}};
387     StorageInfo emptyInfo{};
388     EXPECT_EQ(memoryManager->createStorageInfoFromProperties(properties).getMemoryBanks(), emptyInfo.getMemoryBanks());
389 }
390 
TEST_F(MultiDeviceStorageInfoTest,givenGraphicsAllocationWithCpuAccessRequiredWhenCreatingStorageInfoThenSetCpuVisibleSegmentIsRequiredAndIsLockableFlagIsEnabled)391 TEST_F(MultiDeviceStorageInfoTest, givenGraphicsAllocationWithCpuAccessRequiredWhenCreatingStorageInfoThenSetCpuVisibleSegmentIsRequiredAndIsLockableFlagIsEnabled) {
392     auto firstAllocationIdx = static_cast<int>(GraphicsAllocation::AllocationType::UNKNOWN);
393     auto lastAllocationIdx = static_cast<int>(GraphicsAllocation::AllocationType::COUNT);
394 
395     for (int allocationIdx = firstAllocationIdx; allocationIdx != lastAllocationIdx; allocationIdx++) {
396         auto allocationType = static_cast<GraphicsAllocation::AllocationType>(allocationIdx);
397         AllocationProperties properties{mockRootDeviceIndex, false, 1u, allocationType, false, singleTileMask};
398         auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
399         if (GraphicsAllocation::isCpuAccessRequired(properties.allocationType)) {
400             EXPECT_TRUE(storageInfo.cpuVisibleSegment);
401             EXPECT_TRUE(storageInfo.isLockable);
402         } else {
403             EXPECT_FALSE(storageInfo.cpuVisibleSegment);
404         }
405     }
406 }
407 
TEST_F(MultiDeviceStorageInfoTest,givenGraphicsAllocationThatIsLockableWhenCreatingStorageInfoThenIsLockableFlagIsEnabled)408 TEST_F(MultiDeviceStorageInfoTest, givenGraphicsAllocationThatIsLockableWhenCreatingStorageInfoThenIsLockableFlagIsEnabled) {
409     auto firstAllocationIdx = static_cast<int>(GraphicsAllocation::AllocationType::UNKNOWN);
410     auto lastAllocationIdx = static_cast<int>(GraphicsAllocation::AllocationType::COUNT);
411 
412     for (int allocationIdx = firstAllocationIdx; allocationIdx != lastAllocationIdx; allocationIdx++) {
413         auto allocationType = static_cast<GraphicsAllocation::AllocationType>(allocationIdx);
414         AllocationProperties properties{mockRootDeviceIndex, false, 1u, allocationType, false, singleTileMask};
415         auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
416         if (GraphicsAllocation::isLockable(properties.allocationType)) {
417             EXPECT_TRUE(storageInfo.isLockable);
418         } else {
419             EXPECT_FALSE(storageInfo.isLockable);
420         }
421     }
422 }
423 
TEST_F(MultiDeviceStorageInfoTest,givenGpuTimestampAllocationWhenUsingSingleTileDeviceThenExpectRegularAllocationStorageInfo)424 TEST_F(MultiDeviceStorageInfoTest, givenGpuTimestampAllocationWhenUsingSingleTileDeviceThenExpectRegularAllocationStorageInfo) {
425     AllocationProperties properties{mockRootDeviceIndex,
426                                     false,
427                                     1u,
428                                     GraphicsAllocation::AllocationType::GPU_TIMESTAMP_DEVICE_BUFFER,
429                                     singleTileMask.count() > 1u,
430                                     false,
431                                     singleTileMask};
432     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
433     EXPECT_EQ(singleTileMask, storageInfo.memoryBanks);
434     EXPECT_FALSE(storageInfo.cloningOfPageTables);
435     EXPECT_FALSE(storageInfo.tileInstanced);
436     EXPECT_EQ(singleTileMask, storageInfo.pageTablesVisibility);
437 }
438 
TEST_F(MultiDeviceStorageInfoTest,givenGpuTimestampAllocationWhenUsingMultiTileDeviceThenExpectColoringAndCloningPagesAllocationStorageInfo)439 TEST_F(MultiDeviceStorageInfoTest,
440        givenGpuTimestampAllocationWhenUsingMultiTileDeviceThenExpectColoringAndCloningPagesAllocationStorageInfo) {
441     AllocationProperties properties{mockRootDeviceIndex,
442                                     false,
443                                     1u,
444                                     GraphicsAllocation::AllocationType::GPU_TIMESTAMP_DEVICE_BUFFER,
445                                     allTilesMask.count() > 1u,
446                                     false,
447                                     allTilesMask};
448     auto storageInfo = memoryManager->createStorageInfoFromProperties(properties);
449 
450     auto leastOccupiedBank = memoryManager->getLocalMemoryUsageBankSelector(properties.allocationType, properties.rootDeviceIndex)->getLeastOccupiedBank(properties.subDevicesBitfield);
451     DeviceBitfield allocationMask;
452     allocationMask.set(leastOccupiedBank);
453 
454     EXPECT_EQ(allocationMask, storageInfo.memoryBanks);
455     EXPECT_TRUE(storageInfo.cloningOfPageTables);
456     EXPECT_FALSE(storageInfo.tileInstanced);
457     EXPECT_EQ(allTilesMask, storageInfo.pageTablesVisibility);
458 }
459