Make unified memory allocations multistorage resources

Related-To: NEO-2998

Change-Id: I61e831568a6bbf6e751d7a2ef9c7171c633a128a
Signed-off-by: Jobczyk, Lukasz <lukasz.jobczyk@intel.com>
This commit is contained in:
Jobczyk, Lukasz
2019-11-13 10:01:52 +01:00
committed by sys_ocldev
parent 2ad089a40b
commit bfa1164675
4 changed files with 118 additions and 7 deletions

View File

@ -88,7 +88,7 @@ void *SVMAllocsManager::createSVMAlloc(uint32_t rootDeviceIndex, size_t size, co
if (!memoryManager->isLocalMemorySupported()) {
return createZeroCopySvmAllocation(rootDeviceIndex, size, svmProperties);
} else {
return createUnifiedAllocationWithDeviceStorage(rootDeviceIndex, size, svmProperties);
return createUnifiedAllocationWithDeviceStorage(rootDeviceIndex, size, svmProperties, {});
}
}
@ -103,10 +103,14 @@ void *SVMAllocsManager::createUnifiedMemoryAllocation(uint32_t rootDeviceIndex,
allocationType = GraphicsAllocation::AllocationType::BUFFER;
}
}
AllocationProperties unifiedMemoryProperties{rootDeviceIndex, true,
AllocationProperties unifiedMemoryProperties{rootDeviceIndex,
true,
alignedSize,
allocationType,
false};
memoryProperties.subdeviceBitfield.count() > 1,
memoryProperties.subdeviceBitfield.count() > 1,
memoryProperties.subdeviceBitfield};
GraphicsAllocation *unifiedMemoryAllocation = memoryManager->allocateGraphicsMemoryWithProperties(unifiedMemoryProperties);
if (!unifiedMemoryAllocation) {
@ -134,7 +138,7 @@ void *SVMAllocsManager::createSharedUnifiedMemoryAllocation(uint32_t rootDeviceI
}
if (supportDualStorageSharedMemory) {
auto unifiedMemoryPointer = createUnifiedAllocationWithDeviceStorage(rootDeviceIndex, size, {});
auto unifiedMemoryPointer = createUnifiedAllocationWithDeviceStorage(rootDeviceIndex, size, {}, memoryProperties);
if (!unifiedMemoryPointer) {
return nullptr;
}
@ -192,7 +196,7 @@ void *SVMAllocsManager::createZeroCopySvmAllocation(uint32_t rootDeviceIndex, si
return allocation->getUnderlyingBuffer();
}
void *SVMAllocsManager::createUnifiedAllocationWithDeviceStorage(uint32_t rootDeviceIndex, size_t size, const SvmAllocationProperties &svmProperties) {
void *SVMAllocsManager::createUnifiedAllocationWithDeviceStorage(uint32_t rootDeviceIndex, size_t size, const SvmAllocationProperties &svmProperties, const UnifiedMemoryProperties &unifiedMemoryProperties) {
size_t alignedSize = alignUp<size_t>(size, 2 * MemoryConstants::megaByte);
AllocationProperties cpuProperties{rootDeviceIndex, true, alignedSize, GraphicsAllocation::AllocationType::SVM_CPU, false};
cpuProperties.alignment = 2 * MemoryConstants::megaByte;
@ -205,7 +209,14 @@ void *SVMAllocsManager::createUnifiedAllocationWithDeviceStorage(uint32_t rootDe
allocationCpu->setCoherent(svmProperties.coherent);
void *svmPtr = allocationCpu->getUnderlyingBuffer();
AllocationProperties gpuProperties{rootDeviceIndex, false, alignedSize, GraphicsAllocation::AllocationType::SVM_GPU, false};
AllocationProperties gpuProperties{rootDeviceIndex,
false,
alignedSize,
GraphicsAllocation::AllocationType::SVM_GPU,
unifiedMemoryProperties.subdeviceBitfield.count() > 1,
false,
unifiedMemoryProperties.subdeviceBitfield};
gpuProperties.alignment = 2 * MemoryConstants::megaByte;
MemoryPropertiesParser::fillCachePolicyInProperties(gpuProperties, false, svmProperties.readOnly, false);
GraphicsAllocation *allocationGpu = memoryManager->allocateGraphicsMemoryWithProperties(gpuProperties, svmPtr);

View File

@ -6,6 +6,7 @@
*/
#pragma once
#include "core/helpers/common_types.h"
#include "core/unified_memory/unified_memory.h"
#include "core/utilities/spinlock.h"
@ -76,6 +77,7 @@ class SVMAllocsManager {
InternalMemoryType memoryType = InternalMemoryType::NOT_SPECIFIED;
MemoryPropertiesFlags allocationFlags;
void *device = nullptr;
DeviceBitfield subdeviceBitfield;
};
SVMAllocsManager(MemoryManager *memoryManager);
@ -91,7 +93,7 @@ class SVMAllocsManager {
void removeSvmMapOperation(const void *regionSvmPtr);
SvmMapOperation *getSvmMapOperation(const void *regionPtr);
void makeInternalAllocationsResident(CommandStreamReceiver &commandStreamReceiver, uint32_t requestedTypesMask);
void *createUnifiedAllocationWithDeviceStorage(uint32_t rootDeviceIndex, size_t size, const SvmAllocationProperties &svmProperties);
void *createUnifiedAllocationWithDeviceStorage(uint32_t rootDeviceIndex, size_t size, const SvmAllocationProperties &svmProperties, const UnifiedMemoryProperties &unifiedMemoryProperties);
void freeSvmAllocationWithDeviceStorage(SvmAllocationData *svmData);
protected:

View File

@ -37,6 +37,7 @@
#include "runtime/mem_obj/image.h"
#include "runtime/mem_obj/mem_obj_helper.h"
#include "runtime/mem_obj/pipe.h"
#include "runtime/os_interface/os_context.h"
#include "runtime/platform/platform.h"
#include "runtime/program/program.h"
#include "runtime/sampler/sampler.h"
@ -3498,6 +3499,7 @@ void *clDeviceMemAllocINTEL(
return nullptr;
}
unifiedMemoryProperties.device = device;
unifiedMemoryProperties.subdeviceBitfield = neoDevice->getDefaultEngine().osContext->getDeviceBitfield();
return neoContext->getSVMAllocsManager()->createUnifiedMemoryAllocation(neoDevice->getRootDeviceIndex(), size, unifiedMemoryProperties);
}
@ -3535,6 +3537,7 @@ void *clSharedMemAllocINTEL(
return nullptr;
}
unifiedMemoryProperties.device = device;
unifiedMemoryProperties.subdeviceBitfield = neoDevice->getDefaultEngine().osContext->getDeviceBitfield();
if (isValueSet(unifiedMemoryProperties.allocationFlags.allAllocFlags, CL_MEM_ALLOC_WRITE_COMBINED_INTEL)) {
err.set(CL_INVALID_VALUE);

View File

@ -450,3 +450,98 @@ TEST_F(SVMLocalMemoryAllocatorTest, whenCouldNotReserveCpuAddressRangeInMemoryMa
EXPECT_EQ(nullptr, ptr);
EXPECT_EQ(0u, svmManager->SVMAllocs.getNumAllocs());
}
struct MemoryManagerPropertiesCheck : public MockMemoryManager {
using MockMemoryManager::MockMemoryManager;
GraphicsAllocation *allocateGraphicsMemoryWithProperties(const AllocationProperties &properties) override {
return this->allocateGraphicsMemoryWithProperties(properties, nullptr);
}
GraphicsAllocation *allocateGraphicsMemoryWithProperties(const AllocationProperties &properties, const void *ptr) override {
this->multiOsContextCapablePassed = properties.flags.multiOsContextCapable;
this->multiStorageResourcePassed = properties.multiStorageResource;
this->subDevicesBitfieldPassed = properties.subDevicesBitfield;
return MockMemoryManager::allocateGraphicsMemoryWithProperties(properties, ptr);
}
bool multiOsContextCapablePassed;
bool multiStorageResourcePassed;
DeviceBitfield subDevicesBitfieldPassed;
};
struct UnifiedMemoryManagerPropertiesTest : public ::testing::Test {
void SetUp() override {
bool svmSupported = executionEnvironment.getHardwareInfo()->capabilityTable.ftrSvm;
if (!svmSupported) {
GTEST_SKIP();
}
memoryManager = std::make_unique<MemoryManagerPropertiesCheck>(false, true, executionEnvironment);
svmManager = std::make_unique<MockSVMAllocsManager>(memoryManager.get());
memoryManager->pageFaultManager.reset(new MockPageFaultManager);
}
MockExecutionEnvironment executionEnvironment;
std::unique_ptr<MemoryManagerPropertiesCheck> memoryManager;
std::unique_ptr<MockSVMAllocsManager> svmManager;
};
TEST_F(UnifiedMemoryManagerPropertiesTest, givenDeviceBitfieldWithMultipleBitsSetWhenSharedUnifiedMemoryAllocationIsCreatedThenProperPropertiesArePassedToMemoryManager) {
MockCommandQueue cmdQ;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties;
unifiedMemoryProperties.memoryType = InternalMemoryType::SHARED_UNIFIED_MEMORY;
unifiedMemoryProperties.subdeviceBitfield = DeviceBitfield(0xf);
auto ptr = svmManager->createSharedUnifiedMemoryAllocation(0, 4096u, unifiedMemoryProperties, &cmdQ);
EXPECT_TRUE(memoryManager->multiOsContextCapablePassed);
EXPECT_FALSE(memoryManager->multiStorageResourcePassed);
EXPECT_EQ(unifiedMemoryProperties.subdeviceBitfield, memoryManager->subDevicesBitfieldPassed);
svmManager->freeSVMAlloc(ptr);
}
TEST_F(UnifiedMemoryManagerPropertiesTest, givenDeviceBitfieldWithSingleBitSetWhenSharedUnifiedMemoryAllocationIsCreatedThenProperPropertiesArePassedToMemoryManager) {
MockCommandQueue cmdQ;
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties;
unifiedMemoryProperties.memoryType = InternalMemoryType::SHARED_UNIFIED_MEMORY;
unifiedMemoryProperties.subdeviceBitfield = DeviceBitfield(0x8);
auto ptr = svmManager->createSharedUnifiedMemoryAllocation(0, 4096u, unifiedMemoryProperties, &cmdQ);
EXPECT_FALSE(memoryManager->multiOsContextCapablePassed);
EXPECT_FALSE(memoryManager->multiStorageResourcePassed);
EXPECT_EQ(unifiedMemoryProperties.subdeviceBitfield, memoryManager->subDevicesBitfieldPassed);
svmManager->freeSVMAlloc(ptr);
}
TEST_F(UnifiedMemoryManagerPropertiesTest, givenDeviceBitfieldWithMultipleBitsSetWhenDeviceUnifiedMemoryAllocationIsCreatedThenProperPropertiesArePassedToMemoryManager) {
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties;
unifiedMemoryProperties.memoryType = InternalMemoryType::SHARED_UNIFIED_MEMORY;
unifiedMemoryProperties.subdeviceBitfield = DeviceBitfield(0xf);
auto ptr = svmManager->createUnifiedMemoryAllocation(0, 4096u, unifiedMemoryProperties);
EXPECT_TRUE(memoryManager->multiOsContextCapablePassed);
EXPECT_TRUE(memoryManager->multiStorageResourcePassed);
EXPECT_EQ(unifiedMemoryProperties.subdeviceBitfield, memoryManager->subDevicesBitfieldPassed);
svmManager->freeSVMAlloc(ptr);
}
TEST_F(UnifiedMemoryManagerPropertiesTest, givenDeviceBitfieldWithSingleBitSetWhenDeviceUnifiedMemoryAllocationIsCreatedThenProperPropertiesArePassedToMemoryManager) {
SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties;
unifiedMemoryProperties.memoryType = InternalMemoryType::SHARED_UNIFIED_MEMORY;
unifiedMemoryProperties.subdeviceBitfield = DeviceBitfield(0x8);
auto ptr = svmManager->createUnifiedMemoryAllocation(0, 4096u, unifiedMemoryProperties);
EXPECT_FALSE(memoryManager->multiOsContextCapablePassed);
EXPECT_FALSE(memoryManager->multiStorageResourcePassed);
EXPECT_EQ(unifiedMemoryProperties.subdeviceBitfield, memoryManager->subDevicesBitfieldPassed);
svmManager->freeSVMAlloc(ptr);
}