Add zeMemGetAllocProperties extension for sub-allocations

Signed-off-by: John Falkowski <john.falkowski@intel.com>
This commit is contained in:
John Falkowski 2023-03-16 18:55:02 +00:00 committed by Compute-Runtime-Automation
parent a65de57e33
commit a1e2eca9e8
6 changed files with 203 additions and 0 deletions

View File

@ -678,6 +678,26 @@ ze_result_t ContextImp::handleAllocationExtensions(NEO::GraphicsAllocation *allo
return ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY;
}
exportStructure->handle = reinterpret_cast<void *>(handle);
} else if (extendedProperties->stype == ZE_STRUCTURE_TYPE_MEMORY_SUB_ALLOCATIONS_EXP_PROPERTIES) {
if (alloc->isSubAllocSet) {
ze_memory_sub_allocations_exp_properties_t *extendedSubAllocProperties =
reinterpret_cast<ze_memory_sub_allocations_exp_properties_t *>(extendedProperties);
if (extendedSubAllocProperties->pCount) {
*extendedSubAllocProperties->pCount = alloc->getNumHandles();
} else {
// pCount cannot be nullptr
return ZE_RESULT_ERROR_INVALID_NULL_POINTER;
}
if (extendedSubAllocProperties->pSubAllocations) {
for (uint32_t i = 0; i < *extendedSubAllocProperties->pCount; i++) {
extendedSubAllocProperties->pSubAllocations[i].base = reinterpret_cast<void *>(alloc->subAllocBase[i]);
extendedSubAllocProperties->pSubAllocations[i].size = alloc->subAllocSize[i];
}
// If pSubAllocations nullptr, then user getting Count first and calling second time
}
return ZE_RESULT_SUCCESS;
}
return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
} else {
return ZE_RESULT_ERROR_INVALID_ENUMERATION;
}

View File

@ -2558,6 +2558,147 @@ TEST_F(MemoryExportImportTest,
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
struct SingleSubAllocMockGraphicsAllocation : public NEO::MockGraphicsAllocation {
using NEO::MockGraphicsAllocation::MockGraphicsAllocation;
uint32_t getNumHandles() override {
return 1;
}
};
TEST_F(MemoryExportImportTest,
givenCallToMemAllocPropertiesWithExtendedExportPropertiesAndGetSingleSubAllocation) {
char buffer[256];
auto alloc = new SingleSubAllocMockGraphicsAllocation(&buffer, sizeof(buffer));
ze_memory_allocation_properties_t memoryProperties = {};
ze_memory_sub_allocations_exp_properties_t subAllocationDesc{};
uint32_t numberOfSubAllocations = 0;
subAllocationDesc.stype = ZE_STRUCTURE_TYPE_MEMORY_SUB_ALLOCATIONS_EXP_PROPERTIES;
subAllocationDesc.pCount = &numberOfSubAllocations;
memoryProperties.pNext = &subAllocationDesc;
alloc->subAllocSize[0] = MemoryConstants::pageSize64k;
alloc->subAllocBase[0] = 0;
alloc->isSubAllocSet = true;
ze_memory_type_t type = ZE_MEMORY_TYPE_DEVICE;
ze_result_t result = context->handleAllocationExtensions(alloc, type, &subAllocationDesc, driverHandle.get());
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(1u, numberOfSubAllocations);
std::vector<ze_sub_allocation_t> subAllocationMemAllocProperties(1);
subAllocationDesc.pSubAllocations = subAllocationMemAllocProperties.data();
result = context->handleAllocationExtensions(alloc, type, &subAllocationDesc, driverHandle.get());
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(1u, numberOfSubAllocations);
EXPECT_EQ(alloc->subAllocSize[0], subAllocationMemAllocProperties[0].size);
EXPECT_EQ(alloc->subAllocBase[0], reinterpret_cast<uint64_t>(subAllocationMemAllocProperties[0].base));
delete alloc;
}
struct SubAllocMockGraphicsAllocation : public NEO::MockGraphicsAllocation {
using NEO::MockGraphicsAllocation::MockGraphicsAllocation;
uint32_t getNumHandles() override {
return 4;
}
};
TEST_F(MemoryExportImportTest,
givenCallToMemAllocPropertiesWithExtendedExportPropertiesAndGetSubAllocations) {
char buffer[256];
auto alloc = new SubAllocMockGraphicsAllocation(&buffer, sizeof(buffer));
ze_memory_allocation_properties_t memoryProperties = {};
ze_memory_sub_allocations_exp_properties_t subAllocationDesc{};
uint32_t numberOfSubAllocations = 0;
subAllocationDesc.stype = ZE_STRUCTURE_TYPE_MEMORY_SUB_ALLOCATIONS_EXP_PROPERTIES;
subAllocationDesc.pCount = &numberOfSubAllocations;
memoryProperties.pNext = &subAllocationDesc;
uint64_t baseAddress = 0;
size_t size = MemoryConstants::pageSize64k;
for (uint32_t i = 0; i < alloc->getNumHandles(); i++) {
alloc->subAllocSize[i] = size;
alloc->subAllocBase[i] = baseAddress;
baseAddress += size;
}
alloc->isSubAllocSet = true;
ze_memory_type_t type = ZE_MEMORY_TYPE_DEVICE;
ze_result_t result = context->handleAllocationExtensions(alloc, type, &subAllocationDesc, driverHandle.get());
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(4u, numberOfSubAllocations);
std::vector<ze_sub_allocation_t> subAllocationMemAllocProperties(4);
subAllocationDesc.pSubAllocations = subAllocationMemAllocProperties.data();
result = context->handleAllocationExtensions(alloc, type, &subAllocationDesc, driverHandle.get());
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(4u, numberOfSubAllocations);
for (uint32_t i = 0; i < numberOfSubAllocations; i++) {
EXPECT_EQ(alloc->subAllocSize[i], subAllocationMemAllocProperties[i].size);
EXPECT_EQ(alloc->subAllocBase[i], reinterpret_cast<uint64_t>(subAllocationMemAllocProperties[i].base));
}
delete alloc;
}
TEST_F(MemoryExportImportTest,
givenCallToMemAllocPropertiesWithExtendedExportPropertiesAndUnsetFlagAndGetReturnError) {
char buffer[256];
auto alloc = new SubAllocMockGraphicsAllocation(&buffer, sizeof(buffer));
ze_memory_allocation_properties_t memoryProperties = {};
ze_memory_sub_allocations_exp_properties_t subAllocationDesc{};
uint32_t numberOfSubAllocations = 0;
subAllocationDesc.stype = ZE_STRUCTURE_TYPE_MEMORY_SUB_ALLOCATIONS_EXP_PROPERTIES;
subAllocationDesc.pCount = &numberOfSubAllocations;
memoryProperties.pNext = &subAllocationDesc;
uint64_t baseAddress = 0;
size_t size = MemoryConstants::pageSize64k;
for (uint32_t i = 0; i < alloc->getNumHandles(); i++) {
alloc->subAllocSize[i] = size;
alloc->subAllocBase[i] = baseAddress;
baseAddress += size;
}
alloc->isSubAllocSet = false;
ze_memory_type_t type = ZE_MEMORY_TYPE_DEVICE;
ze_result_t result = context->handleAllocationExtensions(alloc, type, &subAllocationDesc, driverHandle.get());
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION, result);
delete alloc;
}
TEST_F(MemoryExportImportTest,
givenCallToMemAllocPropertiesWithExtendedExportPropertiesAndNullPCountAndGetReturnError) {
char buffer[256];
auto alloc = new SubAllocMockGraphicsAllocation(&buffer, sizeof(buffer));
ze_memory_allocation_properties_t memoryProperties = {};
ze_memory_sub_allocations_exp_properties_t subAllocationDesc{};
subAllocationDesc.stype = ZE_STRUCTURE_TYPE_MEMORY_SUB_ALLOCATIONS_EXP_PROPERTIES;
memoryProperties.pNext = &subAllocationDesc;
uint64_t baseAddress = 0;
size_t size = MemoryConstants::pageSize64k;
for (uint32_t i = 0; i < alloc->getNumHandles(); i++) {
alloc->subAllocSize[i] = size;
alloc->subAllocBase[i] = baseAddress;
baseAddress += size;
}
alloc->isSubAllocSet = true;
ze_memory_type_t type = ZE_MEMORY_TYPE_DEVICE;
ze_result_t result = context->handleAllocationExtensions(alloc, type, &subAllocationDesc, driverHandle.get());
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_NULL_POINTER, result);
delete alloc;
}
TEST_F(MemoryExportImportTest,
givenCallToDeviceAllocWithExtendedImportDescriptorAndNonSupportedFlagThenUnsupportedEnumerationIsReturned) {
size_t size = 10;

View File

@ -280,6 +280,9 @@ class GraphicsAllocation : public IDNode<GraphicsAllocation> {
constexpr static TaskCountType objectAlwaysResident = std::numeric_limits<TaskCountType>::max() - 1;
std::atomic<uint32_t> hostPtrTaskCountAssignment{0};
bool isShareableHostMemory = false;
bool isSubAllocSet = false;
StackVec<size_t, EngineLimits::maxHandleCount> subAllocSize;
StackVec<uint64_t, EngineLimits::maxHandleCount> subAllocBase;
protected:
struct UsageInfo {

View File

@ -1845,6 +1845,9 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation,
return false;
}
allocation->getBufferObjectToModify(currentBank + iterationOffset) = bos[handleId];
allocation->isSubAllocSet = true;
allocation->subAllocSize[handleId] = static_cast<size_t>(boSize);
allocation->subAllocBase[handleId] = static_cast<uint64_t>(boAddress);
if (storageInfo.multiStorage) {
boAddress += boSize;
}

View File

@ -23,11 +23,14 @@ class MockGraphicsAllocation : public MemoryAllocation {
using MemoryAllocation::aubInfo;
using MemoryAllocation::cpuPtr;
using MemoryAllocation::gpuAddress;
using MemoryAllocation::isSubAllocSet;
using MemoryAllocation::MemoryAllocation;
using MemoryAllocation::memoryPool;
using MemoryAllocation::objectNotResident;
using MemoryAllocation::objectNotUsed;
using MemoryAllocation::size;
using MemoryAllocation::subAllocBase;
using MemoryAllocation::subAllocSize;
using MemoryAllocation::usageInfos;
MockGraphicsAllocation()

View File

@ -5164,6 +5164,39 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenAllocati
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenMultipleHandlesUpdateSubAllocationInformation) {
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
AllocationData allocData;
allocData.allFlags = 0;
allocData.size = 18 * MemoryConstants::pageSize64k;
allocData.flags.allocateMemory = true;
allocData.type = AllocationType::BUFFER;
allocData.storageInfo.memoryBanks = maxNBitValue(MemoryBanks::getBankForLocalMemory(3));
allocData.storageInfo.multiStorage = true;
allocData.rootDeviceIndex = rootDeviceIndex;
auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
ASSERT_NE(nullptr, allocation);
EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
EXPECT_EQ(MemoryPool::LocalMemory, allocation->getMemoryPool());
EXPECT_NE(0u, allocation->getGpuAddress());
EXPECT_EQ(EngineLimits::maxHandleCount, allocation->getNumGmms());
auto drmAllocation = static_cast<DrmAllocation *>(allocation);
auto &bos = drmAllocation->getBOs();
EXPECT_TRUE(allocation->isSubAllocSet);
auto boAddress = drmAllocation->getGpuAddress();
for (auto handleId = 0u; handleId < EngineLimits::maxHandleCount; handleId++) {
auto bo = bos[handleId];
ASSERT_NE(nullptr, bo);
auto boSize = allocation->getGmm(handleId)->gmmResourceInfo->getSizeAllocation();
EXPECT_EQ(boAddress, allocation->subAllocBase[handleId]);
EXPECT_EQ(boSize, allocation->subAllocSize[handleId]);
boAddress += boSize;
}
memoryManager->freeGraphicsMemory(allocation);
}
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenAllocationWithKernelIsaWhenAllocationInDevicePoolAndDeviceBitfieldWithHolesThenCorrectAllocationCreated) {
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
AllocationData allocData;