Skip to content

Commit 4078022

Browse files
fix: configure ISA Pool params based on productHelper
When is2MBLocalMemAlignmentEnabled returns true, increase pool size for builtins from 64k to 2MB. Additionally, set appropriate alignment for kernel ISA heap allocations. Additionally, configure isaAllocationPageSize based on productHelper. Related-To: NEO-12287 Signed-off-by: Fabian Zwoliński <[email protected]>
1 parent 26f3f7a commit 4078022

File tree

9 files changed

+160
-18
lines changed

9 files changed

+160
-18
lines changed

level_zero/core/source/module/module_imp.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,11 +554,10 @@ NEO::GraphicsAllocation *ModuleTranslationUnit::getGlobalVarBufferGA() const {
554554
ModuleImp::ModuleImp(Device *device, ModuleBuildLog *moduleBuildLog, ModuleType type)
555555
: device(device), translationUnit(std::make_unique<ModuleTranslationUnit>(device)),
556556
moduleBuildLog(moduleBuildLog), type(type) {
557-
auto &gfxCoreHelper = device->getGfxCoreHelper();
558557
auto &hwInfo = device->getHwInfo();
559-
this->isaAllocationPageSize = gfxCoreHelper.useSystemMemoryPlacementForISA(hwInfo) ? MemoryConstants::pageSize : MemoryConstants::pageSize64k;
560558
this->productFamily = hwInfo.platform.eProductFamily;
561559
this->metadataGeneration = std::make_unique<NEO::MetadataGeneration>();
560+
this->isaAllocationPageSize = getIsaAllocationPageSize();
562561
}
563562

564563
ModuleImp::~ModuleImp() {
@@ -1790,4 +1789,19 @@ NEO::GraphicsAllocation *ModuleImp::getKernelsIsaParentAllocation() const {
17901789
return sharedIsaAllocation->getGraphicsAllocation();
17911790
}
17921791

1792+
size_t ModuleImp::getIsaAllocationPageSize() const {
1793+
auto &gfxCoreHelper = device->getGfxCoreHelper();
1794+
auto &hwInfo = device->getHwInfo();
1795+
1796+
if (gfxCoreHelper.useSystemMemoryPlacementForISA(hwInfo)) {
1797+
return MemoryConstants::pageSize;
1798+
}
1799+
1800+
if (device->getProductHelper().is2MBLocalMemAlignmentEnabled()) {
1801+
return MemoryConstants::pageSize2M;
1802+
} else {
1803+
return MemoryConstants::pageSize64k;
1804+
}
1805+
}
1806+
17931807
} // namespace L0

level_zero/core/source/module/module_imp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ struct ModuleImp : public Module {
201201
MOCKABLE_VIRTUAL size_t computeKernelIsaAllocationAlignedSizeWithPadding(size_t isaSize, bool lastKernel);
202202
MOCKABLE_VIRTUAL NEO::GraphicsAllocation *allocateKernelsIsaMemory(size_t size);
203203
StackVec<NEO::GraphicsAllocation *, 32> getModuleAllocations();
204+
size_t getIsaAllocationPageSize() const;
204205

205206
Device *device = nullptr;
206207
PRODUCT_FAMILY productFamily{};

level_zero/core/test/unit_tests/mocks/mock_module.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct WhiteBox<::L0::Module> : public ::L0::ModuleImp {
7373
using BaseClass::copyPatchedSegments;
7474
using BaseClass::device;
7575
using BaseClass::exportedFunctionsSurface;
76+
using BaseClass::getIsaAllocationPageSize;
7677
using BaseClass::importedSymbolAllocations;
7778
using BaseClass::isaSegmentsForPatching;
7879
using BaseClass::isFullyLinked;
@@ -126,6 +127,7 @@ struct MockModule : public L0::ModuleImp {
126127
using ModuleImp::allocateKernelsIsaMemory;
127128
using ModuleImp::computeKernelIsaAllocationAlignedSizeWithPadding;
128129
using ModuleImp::debugModuleHandle;
130+
using ModuleImp::getIsaAllocationPageSize;
129131
using ModuleImp::getModuleAllocations;
130132
using ModuleImp::initializeKernelImmutableData;
131133
using ModuleImp::isaAllocationPageSize;

level_zero/core/test/unit_tests/sources/module/test_module.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ HWTEST_F(ModuleTest, givenUserModuleWhenCreatedThenCorrectAllocationTypeIsUsedFo
182182

183183
template <bool localMemEnabled>
184184
struct ModuleKernelIsaAllocationsFixture : public ModuleFixture {
185-
static constexpr size_t isaAllocationPageSize = (localMemEnabled ? MemoryConstants::pageSize64k : MemoryConstants::pageSize);
186185
using Module = WhiteBox<::L0::Module>;
187186

188187
void setUp() {
@@ -217,7 +216,7 @@ struct ModuleKernelIsaAllocationsFixture : public ModuleFixture {
217216
void givenSeparateIsaMemoryRegionPerKernelWhenGraphicsAllocationFailsThenProperErrorReturned() {
218217
mockModule->allocateKernelsIsaMemoryCallBase = false;
219218
mockModule->computeKernelIsaAllocationAlignedSizeWithPaddingCallBase = false;
220-
mockModule->computeKernelIsaAllocationAlignedSizeWithPaddingResult = isaAllocationPageSize;
219+
mockModule->computeKernelIsaAllocationAlignedSizeWithPaddingResult = this->mockModule->getIsaAllocationPageSize();
221220

222221
auto result = module->initialize(&this->moduleDesc, device->getNEODevice());
223222
EXPECT_EQ(result, ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY);
@@ -806,6 +805,35 @@ HWTEST_F(ModuleTest, whenMultipleModulesCreatedThenModulesShareIsaAllocation) {
806805
}
807806
};
808807

808+
TEST_F(ModuleTest, GivenLocalMemoryEnabledOrDisabledAnd2MBAlignmentEnabledOrDisabledWhenGettingIsaAllocationPageSizeThenCorrectValueIsReturned) {
809+
DebugManagerStateRestore restorer;
810+
811+
auto mockProductHelper = new MockProductHelper;
812+
device->getNEODevice()->getRootDeviceEnvironmentRef().productHelper.reset(mockProductHelper);
813+
814+
MockModule mockModule{device, nullptr, ModuleType::user};
815+
EXPECT_EQ(mockModule.getIsaAllocationPageSize(), mockModule.isaAllocationPageSize);
816+
817+
{
818+
debugManager.flags.EnableLocalMemory.set(0);
819+
mockProductHelper->is2MBLocalMemAlignmentEnabledResult = true;
820+
821+
EXPECT_EQ(MemoryConstants::pageSize, mockModule.getIsaAllocationPageSize());
822+
}
823+
{
824+
debugManager.flags.EnableLocalMemory.set(1);
825+
mockProductHelper->is2MBLocalMemAlignmentEnabledResult = true;
826+
827+
EXPECT_EQ(MemoryConstants::pageSize2M, mockModule.getIsaAllocationPageSize());
828+
}
829+
{
830+
debugManager.flags.EnableLocalMemory.set(1);
831+
mockProductHelper->is2MBLocalMemAlignmentEnabledResult = false;
832+
833+
EXPECT_EQ(MemoryConstants::pageSize64k, mockModule.getIsaAllocationPageSize());
834+
}
835+
}
836+
809837
template <typename T1, typename T2>
810838
struct ModuleSpecConstantsFixture : public DeviceFixture {
811839
void setUp() {
@@ -4347,7 +4375,6 @@ TEST_F(ModuleTest, whenContainsStatefulAccessIsCalledThenResultIsCorrect) {
43474375

43484376
template <bool localMemEnabled>
43494377
struct ModuleIsaAllocationsFixture : public DeviceFixture {
4350-
static constexpr size_t isaAllocationPageSize = (localMemEnabled ? MemoryConstants::pageSize64k : MemoryConstants::pageSize);
43514378
static constexpr NEO::MemoryPool isaAllocationMemoryPool = (localMemEnabled ? NEO::MemoryPool::localMemory : NEO::MemoryPool::system4KBPagesWith32BitGpuAddressing);
43524379

43534380
void setUp() {
@@ -4363,6 +4390,7 @@ struct ModuleIsaAllocationsFixture : public DeviceFixture {
43634390
this->mockMemoryManager->localMemorySupported[this->neoDevice->getRootDeviceIndex()] = true;
43644391
this->mockModule.reset(new MockModule{this->device, nullptr, ModuleType::user});
43654392
this->mockModule->translationUnit.reset(new MockModuleTranslationUnit{this->device});
4393+
this->isaAllocationPageSize = this->mockModule->getIsaAllocationPageSize();
43664394
}
43674395

43684396
void tearDown() {
@@ -4418,8 +4446,8 @@ struct ModuleIsaAllocationsFixture : public DeviceFixture {
44184446
EXPECT_EQ(kernelImmData[1]->getIsaOffsetInParentAllocation(), 0lu);
44194447
EXPECT_EQ(kernelImmData[1]->getIsaSubAllocationSize(), 0lu);
44204448
if constexpr (localMemEnabled) {
4421-
EXPECT_EQ(isaAllocationPageSize, kernelImmData[0]->getIsaSize());
4422-
EXPECT_EQ(isaAllocationPageSize, kernelImmData[1]->getIsaSize());
4449+
EXPECT_EQ(alignUp<size_t>(maxAllocationSizeInPage, MemoryConstants::pageSize64k), kernelImmData[0]->getIsaSize());
4450+
EXPECT_EQ(alignUp<size_t>(tinyAllocationSize, MemoryConstants::pageSize64k), kernelImmData[1]->getIsaSize());
44234451
} else {
44244452
EXPECT_EQ(this->computeKernelIsaAllocationSizeWithPadding(maxAllocationSizeInPage), kernelImmData[0]->getIsaSize());
44254453
EXPECT_EQ(this->computeKernelIsaAllocationSizeWithPadding(tinyAllocationSize), kernelImmData[1]->getIsaSize());
@@ -4466,6 +4494,7 @@ struct ModuleIsaAllocationsFixture : public DeviceFixture {
44664494

44674495
size_t isaPadding;
44684496
size_t kernelStartPointerAlignment;
4497+
size_t isaAllocationPageSize;
44694498
NEO::Device *neoDevice = nullptr;
44704499
MockMemoryManager *mockMemoryManager = nullptr;
44714500
std::unique_ptr<MockModule> mockModule = nullptr;

shared/source/os_interface/linux/drm_memory_manager.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,11 +2046,10 @@ void fillGmmsInAllocation(GmmHelper *gmmHelper, DrmAllocation *allocation) {
20462046
}
20472047
}
20482048

2049-
inline uint64_t getCanonizedHeapAllocationAddress(HeapIndex heap, GmmHelper *gmmHelper, GfxPartition *gfxPartition, size_t &sizeAllocated, bool packed) {
2050-
size_t alignment = 0;
2051-
2052-
if (debugManager.flags.ExperimentalEnableCustomLocalMemoryAlignment.get() != -1) {
2053-
alignment = static_cast<size_t>(debugManager.flags.ExperimentalEnableCustomLocalMemoryAlignment.get());
2049+
inline uint64_t getCanonizedHeapAllocationAddress(HeapIndex heap, GmmHelper *gmmHelper, GfxPartition *gfxPartition, size_t &sizeAllocated, size_t alignment, bool packed) {
2050+
if (const size_t customAlignment = static_cast<size_t>(debugManager.flags.ExperimentalEnableCustomLocalMemoryAlignment.get());
2051+
customAlignment > 0) {
2052+
alignment = customAlignment;
20542053
}
20552054
auto address = gfxPartition->heapAllocateWithCustomAlignment(heap, sizeAllocated, alignment);
20562055
return gmmHelper->canonize(address);
@@ -2070,10 +2069,15 @@ AllocationStatus getGpuAddress(const AlignmentSelector &alignmentSelector, HeapA
20702069
case AllocationType::kernelIsa:
20712070
case AllocationType::kernelIsaInternal:
20722071
case AllocationType::internalHeap:
2073-
case AllocationType::debugModuleArea:
2072+
case AllocationType::debugModuleArea: {
2073+
size_t alignment = 0;
2074+
if (gmmHelper->getRootDeviceEnvironment().getHelper<ProductHelper>().is2MBLocalMemAlignmentEnabled()) {
2075+
alignment = MemoryConstants::pageSize2M;
2076+
}
20742077
gpuAddress = getCanonizedHeapAllocationAddress(heapAssigner.get32BitHeapIndex(allocType, true, hwInfo, allocationData.flags.use32BitFrontWindow),
2075-
gmmHelper, gfxPartition, sizeAllocated, false);
2078+
gmmHelper, gfxPartition, sizeAllocated, alignment, false);
20762079
break;
2080+
}
20772081
case AllocationType::writeCombined:
20782082
sizeAllocated = 0;
20792083
break;

shared/source/utilities/isa_pool_allocator.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "shared/source/utilities/isa_pool_allocator.h"
99

1010
#include "shared/source/device/device.h"
11+
#include "shared/source/helpers/aligned_memory.h"
1112
#include "shared/source/memory_manager/allocation_properties.h"
1213
#include "shared/source/memory_manager/memory_manager.h"
1314
#include "shared/source/utilities/buffer_pool_allocator.inl"
@@ -16,6 +17,9 @@ namespace NEO {
1617

1718
ISAPool::ISAPool(Device *device, bool isBuiltin, size_t storageSize)
1819
: BaseType(device->getMemoryManager(), nullptr), device(device), isBuiltin(isBuiltin) {
20+
DEBUG_BREAK_IF(device->getProductHelper().is2MBLocalMemAlignmentEnabled() &&
21+
!isAligned(storageSize, MemoryConstants::pageSize2M));
22+
1923
auto allocationType = isBuiltin ? NEO::AllocationType::kernelIsaInternal : NEO::AllocationType::kernelIsa;
2024
AllocationProperties allocProperties = {device->getRootDeviceIndex(),
2125
storageSize,
@@ -58,6 +62,7 @@ const StackVec<NEO::GraphicsAllocation *, 1> &ISAPool::getAllocationsVector() {
5862
}
5963

6064
ISAPoolAllocator::ISAPoolAllocator(Device *device) : device(device) {
65+
initAllocParams();
6166
}
6267

6368
/**
@@ -79,7 +84,7 @@ SharedIsaAllocation *ISAPoolAllocator::requestGraphicsAllocationForIsa(bool isBu
7984
auto maxAllocationSize = getAllocationSize(isBuiltin);
8085

8186
if (sizeWithPadding > maxAllocationSize) {
82-
addNewBufferPool(ISAPool(device, isBuiltin, sizeWithPadding));
87+
addNewBufferPool(ISAPool(device, isBuiltin, alignToPoolSize(sizeWithPadding)));
8388
}
8489

8590
auto sharedIsaAllocation = tryAllocateISA(isBuiltin, sizeWithPadding);
@@ -94,7 +99,7 @@ SharedIsaAllocation *ISAPoolAllocator::requestGraphicsAllocationForIsa(bool isBu
9499
return sharedIsaAllocation;
95100
}
96101

97-
addNewBufferPool(ISAPool(device, isBuiltin, getAllocationSize(isBuiltin)));
102+
addNewBufferPool(ISAPool(device, isBuiltin, alignToPoolSize(getAllocationSize(isBuiltin))));
98103
return tryAllocateISA(isBuiltin, sizeWithPadding);
99104
}
100105

@@ -133,4 +138,19 @@ SharedIsaAllocation *ISAPoolAllocator::tryAllocateISA(bool isBuiltin, size_t siz
133138
return nullptr;
134139
}
135140

141+
void ISAPoolAllocator::initAllocParams() {
142+
if (device->getProductHelper().is2MBLocalMemAlignmentEnabled()) {
143+
userAllocationSize = MemoryConstants::pageSize2M * 2;
144+
builtinAllocationSize = MemoryConstants::pageSize2M;
145+
poolAlignment = MemoryConstants::pageSize2M;
146+
} else {
147+
userAllocationSize = MemoryConstants::pageSize2M * 2;
148+
builtinAllocationSize = MemoryConstants::pageSize64k;
149+
}
150+
}
151+
152+
size_t ISAPoolAllocator::alignToPoolSize(size_t size) const {
153+
return alignUp(size, poolAlignment);
154+
}
155+
136156
} // namespace NEO

shared/source/utilities/isa_pool_allocator.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,18 @@ class ISAPoolAllocator : public AbstractBuffersAllocator<ISAPool, GraphicsAlloca
4848
void freeSharedIsaAllocation(SharedIsaAllocation *sharedIsaAllocation);
4949

5050
private:
51+
void initAllocParams();
5152
SharedIsaAllocation *tryAllocateISA(bool isBuiltin, size_t size);
5253

5354
size_t getAllocationSize(bool isBuiltin) const {
54-
return isBuiltin ? buitinAllocationSize : userAllocationSize;
55+
return isBuiltin ? builtinAllocationSize : userAllocationSize;
5556
}
57+
size_t alignToPoolSize(size_t size) const;
5658

5759
Device *device;
5860
size_t userAllocationSize = MemoryConstants::pageSize2M * 2;
59-
size_t buitinAllocationSize = MemoryConstants::pageSize64k;
61+
size_t builtinAllocationSize = MemoryConstants::pageSize64k;
62+
size_t poolAlignment = 1u;
6063
std::mutex allocatorMtx;
6164
};
6265

shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7961,6 +7961,39 @@ TEST_F(DrmMemoryManagerLocalMemoryAlignmentTest, givenEnabled2MBSizeAlignmentWhe
79617961
memoryManager->freeGraphicsMemory(allocation);
79627962
}
79637963

7964+
TEST_F(DrmMemoryManagerLocalMemoryAlignmentTest, givenEnabled2MBSizeAlignmentWhenAllocatingLargeKernelIsaThenAllocationIsAlignedTo2MB) {
7965+
auto mockProductHelper = new MockProductHelper;
7966+
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->productHelper.reset(mockProductHelper);
7967+
mockProductHelper->is2MBLocalMemAlignmentEnabledResult = true;
7968+
7969+
ASSERT_TRUE(executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->productHelper->is2MBLocalMemAlignmentEnabled());
7970+
7971+
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
7972+
AllocationData allocData;
7973+
allocData.allFlags = 0;
7974+
allocData.size = MemoryConstants::pageSize2M + 1;
7975+
allocData.flags.allocateMemory = true;
7976+
allocData.type = AllocationType::kernelIsa;
7977+
allocData.rootDeviceIndex = rootDeviceIndex;
7978+
7979+
auto memoryManager = createMemoryManager();
7980+
auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
7981+
ASSERT_NE(nullptr, allocation);
7982+
EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
7983+
EXPECT_EQ(MemoryPool::localMemory, allocation->getMemoryPool());
7984+
EXPECT_TRUE(isAligned(allocation->getGpuAddress(), MemoryConstants::pageSize2M));
7985+
EXPECT_TRUE(isAligned(allocation->getUnderlyingBufferSize(), MemoryConstants::pageSize2M));
7986+
7987+
auto drmAllocation = static_cast<DrmAllocation *>(allocation);
7988+
auto bo = drmAllocation->getBO();
7989+
EXPECT_NE(nullptr, bo);
7990+
EXPECT_EQ(allocation->getGpuAddress(), bo->peekAddress());
7991+
EXPECT_TRUE(isAligned(bo->peekAddress(), MemoryConstants::pageSize2M));
7992+
EXPECT_TRUE(isAligned(bo->peekSize(), MemoryConstants::pageSize2M));
7993+
7994+
memoryManager->freeGraphicsMemory(allocation);
7995+
}
7996+
79647997
TEST_F(DrmMemoryManagerLocalMemoryAlignmentTest, Given2MBLocalMemAlignmentEnabledWhenAllocating2MBPageTypeInDevicePoolThenAllocationIs2MBAligned) {
79657998
auto mockProductHelper = new MockProductHelper;
79667999
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->productHelper.reset(mockProductHelper);

shared/test/unit_test/utilities/isa_pool_allocator_tests.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,29 @@
55
*
66
*/
77

8+
#include "shared/source/helpers/aligned_memory.h"
9+
#include "shared/source/utilities/heap_allocator.h"
810
#include "shared/test/common/fixtures/device_fixture.h"
911
#include "shared/test/common/mocks/mock_device.h"
12+
#include "shared/test/common/mocks/mock_product_helper.h"
1013
#include "shared/test/common/test_macros/test.h"
1114

1215
#include "gtest/gtest.h"
1316

1417
using namespace NEO;
1518

19+
class MockISAPool : public ISAPool {
20+
public:
21+
using ISAPool::chunkAllocator;
22+
};
23+
24+
class MockISAPoolAllocator : public ISAPoolAllocator {
25+
public:
26+
using ISAPoolAllocator::bufferPools;
27+
28+
MockISAPoolAllocator(Device *device) : ISAPoolAllocator(device) {}
29+
};
30+
1631
using IsaPoolAllocatorTest = Test<DeviceFixture>;
1732

1833
void verifySharedIsaAllocation(const SharedIsaAllocation *sharedAllocation, size_t expectedOffset, size_t expectedSize) {
@@ -99,3 +114,24 @@ TEST_F(IsaPoolAllocatorTest, givenIsaPoolAllocatorWhenRequestForLargeAllocationT
99114
verifySharedIsaAllocation(allocation, 0, requestAllocationSize);
100115
isaAllocator.freeSharedIsaAllocation(allocation);
101116
}
117+
118+
TEST_F(IsaPoolAllocatorTest, Given2MBLocalMemAlignmentEnabledWhenAllocatingIsaThenISAPoolSizeIsAlignedTo2MB) {
119+
auto mockProductHelper = new MockProductHelper;
120+
pDevice->getRootDeviceEnvironmentRef().productHelper.reset(mockProductHelper);
121+
mockProductHelper->is2MBLocalMemAlignmentEnabledResult = true;
122+
123+
MockISAPoolAllocator mockIsaAllocator(pDevice);
124+
125+
constexpr size_t requestAllocationSize = MemoryConstants::pageSize + 1;
126+
auto allocation = mockIsaAllocator.requestGraphicsAllocationForIsa(true, requestAllocationSize);
127+
128+
EXPECT_NE(nullptr, allocation);
129+
ASSERT_GE(mockIsaAllocator.bufferPools.size(), 1u);
130+
131+
auto *bufferPool = static_cast<MockISAPool *>(&mockIsaAllocator.bufferPools[0]);
132+
auto chunkAllocatorSize = bufferPool->chunkAllocator->getLeftSize() + bufferPool->chunkAllocator->getUsedSize();
133+
134+
EXPECT_TRUE(isAligned(chunkAllocatorSize, MemoryConstants::pageSize2M));
135+
136+
mockIsaAllocator.freeSharedIsaAllocation(allocation);
137+
}

0 commit comments

Comments
 (0)