Refactor manager of imported host pointers

Related-To: NEO-5126

Signed-off-by: Zbigniew Zdanowicz <zbigniew.zdanowicz@intel.com>
This commit is contained in:
Zbigniew Zdanowicz
2021-05-13 01:08:51 +00:00
committed by Compute-Runtime-Automation
parent b7c7bc0a24
commit fa683b5e81
4 changed files with 88 additions and 40 deletions

View File

@@ -1469,8 +1469,11 @@ inline AlignedAllocationData CommandListCoreFamily<gfxCoreFamily>::getAlignedAll
if (srcAllocFound == false) {
alloc = device->getDriverHandle()->findHostPointerAllocation(ptr, static_cast<size_t>(bufferSize), device->getRootDeviceIndex());
if (alloc != nullptr) {
alignedPtr = static_cast<uintptr_t>(alloc->getGpuAddress());
offset = reinterpret_cast<size_t>(ptr) - reinterpret_cast<size_t>(alloc->getUnderlyingBuffer());
alignedPtr = static_cast<size_t>(alignDown(alloc->getGpuAddress(), NEO::EncodeSurfaceState<GfxFamily>::getSurfaceBaseAddressAlignment()));
//get offset from GPUVA of allocation to align down GPU address
offset = static_cast<size_t>(alloc->getGpuAddress()) - alignedPtr;
//get offset from base of allocation to arg address
offset += reinterpret_cast<size_t>(ptr) - reinterpret_cast<size_t>(alloc->getUnderlyingBuffer());
} else {
alloc = getHostPtrAlloc(buffer, bufferSize);
alignedPtr = static_cast<uintptr_t>(alignDown(alloc->getGpuAddress(), NEO::EncodeSurfaceState<GfxFamily>::getSurfaceBaseAddressAlignment()));

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -61,39 +61,36 @@ HostPointerManager::~HostPointerManager() {
}
ze_result_t HostPointerManager::createHostPointerMultiAllocation(std::vector<Device *> &devices, void *ptr, size_t size) {
if (size == 0) {
if (size == 0 || ptr == nullptr) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
void *basePtr = alignDown(ptr, MemoryConstants::pageSize);
size_t endAddress = reinterpret_cast<size_t>(ptr) + size;
endAddress = alignUp(endAddress, MemoryConstants::pageSize);
size_t totalSize = endAddress - reinterpret_cast<size_t>(basePtr);
std::unique_lock<NEO::SpinLock> lock(this->mtx);
auto baseAllocation = hostPointerAllocations.get(basePtr);
auto beginAllocation = hostPointerAllocations.get(ptr);
auto endingAllocation = hostPointerAllocations.get(reinterpret_cast<void *>(endAddress - 1));
if (baseAllocation != nullptr && baseAllocation == endingAllocation) {
if (beginAllocation != nullptr && beginAllocation == endingAllocation) {
return ZE_RESULT_SUCCESS;
}
if (baseAllocation != nullptr) {
if (beginAllocation != nullptr) {
if (endingAllocation != nullptr) {
return ZE_RESULT_ERROR_OVERLAPPING_REGIONS;
}
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
}
if (endingAllocation != nullptr) {
UNRECOVERABLE_IF(endingAllocation->basePtr == basePtr);
UNRECOVERABLE_IF(endingAllocation->basePtr == ptr);
return ZE_RESULT_ERROR_INVALID_SIZE;
}
HostPointerData hostData(static_cast<uint32_t>(devices.size() - 1));
hostData.basePtr = basePtr;
hostData.size = totalSize;
hostData.basePtr = ptr;
hostData.size = size;
for (auto device : devices) {
NEO::GraphicsAllocation *gfxAlloc = createHostPointerAllocation(device->getRootDeviceIndex(),
basePtr,
totalSize,
ptr,
size,
device->getNEODevice()->getDeviceBitfield());
if (gfxAlloc == nullptr) {
auto allocations = hostData.hostPtrAllocations.getGraphicsAllocations();

View File

@@ -1141,31 +1141,37 @@ HWTEST2_F(HostPointerManagerCommandListTest,
auto commandList = std::make_unique<::L0::ult::CommandListCoreFamily<gfxCoreFamily>>();
commandList->initialize(device, NEO::EngineGroupType::RenderCompute);
size_t pointerSize = MemoryConstants::pageSize;
size_t offset = 100;
void *offsetPointer = ptrOffset(heapPointer, offset);
size_t mainOffset = 100;
size_t importSize = 100;
void *importPointer = ptrOffset(heapPointer, mainOffset);
auto ret = hostDriverHandle->importExternalPointer(offsetPointer, offset);
auto ret = hostDriverHandle->importExternalPointer(importPointer, importSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, ret);
auto hostAllocation = hostDriverHandle->findHostPointerAllocation(heapPointer, pointerSize, device->getRootDeviceIndex());
auto hostAllocation = hostDriverHandle->findHostPointerAllocation(importPointer, importSize, device->getRootDeviceIndex());
ASSERT_NE(nullptr, hostAllocation);
AlignedAllocationData outData = commandList->getAlignedAllocation(device, heapPointer, pointerSize);
auto expectedAlignedAddress = static_cast<uintptr_t>(hostAllocation->getGpuAddress());
EXPECT_EQ(heapPointer, hostAllocation->getUnderlyingBuffer());
size_t allocOffset = 10;
size_t offsetSize = 20;
void *offsetPointer = ptrOffset(importPointer, allocOffset);
AlignedAllocationData outData = commandList->getAlignedAllocation(device, importPointer, importSize);
auto gpuBaseAddress = static_cast<size_t>(hostAllocation->getGpuAddress());
auto expectedAlignedAddress = alignDown(gpuBaseAddress, NEO::EncodeSurfaceState<FamilyType>::getSurfaceBaseAddressAlignment());
size_t expectedOffset = gpuBaseAddress - expectedAlignedAddress;
EXPECT_EQ(importPointer, hostAllocation->getUnderlyingBuffer());
EXPECT_EQ(expectedAlignedAddress, outData.alignedAllocationPtr);
EXPECT_EQ(hostAllocation, outData.alloc);
EXPECT_EQ(0u, outData.offset);
EXPECT_EQ(expectedOffset, outData.offset);
outData = commandList->getAlignedAllocation(device, offsetPointer, 2u);
expectedAlignedAddress = static_cast<uintptr_t>(hostAllocation->getGpuAddress());
EXPECT_EQ(heapPointer, hostAllocation->getUnderlyingBuffer());
outData = commandList->getAlignedAllocation(device, offsetPointer, offsetSize);
expectedOffset += allocOffset;
EXPECT_EQ(importPointer, hostAllocation->getUnderlyingBuffer());
EXPECT_EQ(expectedAlignedAddress, outData.alignedAllocationPtr);
EXPECT_EQ(hostAllocation, outData.alloc);
EXPECT_EQ(offset, outData.offset);
EXPECT_EQ(expectedOffset, outData.offset);
ret = hostDriverHandle->releaseImportedPointer(heapPointer);
ret = hostDriverHandle->releaseImportedPointer(importPointer);
EXPECT_EQ(ZE_RESULT_SUCCESS, ret);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -164,6 +164,11 @@ TEST_F(HostPointerManagerTest, WhenSizeIsZeroThenExpectInvalidArgument) {
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
}
TEST_F(HostPointerManagerTest, WhenPointerIsNullThenExpectInvalidArgument) {
auto result = hostDriverHandle->importExternalPointer(nullptr, 0x10);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
}
TEST_F(HostPointerManagerTest, givenNoPointerWhenImportAddressThenRegisterNewHostData) {
void *testPtr = heapPointer;
void *baseAddress;
@@ -193,7 +198,7 @@ TEST_F(HostPointerManagerTest, givenNoPointerWhenImportMisalignedAddressThenRegi
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + 0x10);
size_t size = 0x10;
void *baseAddress;
void *baseAddress = nullptr;
auto result = hostDriverHandle->getHostPointerBaseAddress(testPtr, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
@@ -206,10 +211,10 @@ TEST_F(HostPointerManagerTest, givenNoPointerWhenImportMisalignedAddressThenRegi
result = hostDriverHandle->getHostPointerBaseAddress(testPtr, &baseAddress);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(heapPointer, baseAddress);
EXPECT_EQ(testPtr, baseAddress);
auto hostPointerData = openHostPointerManager->hostPointerAllocations.get(testPtr);
ASSERT_NE(nullptr, hostPointerData);
EXPECT_EQ(MemoryConstants::pageSize, hostPointerData->size);
EXPECT_EQ(size, hostPointerData->size);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
@@ -307,29 +312,41 @@ TEST_F(HostPointerManagerTest, givenPointerUsesTwoPagesThenBothPagesAreAvailable
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + 0x10);
size_t size = MemoryConstants::pageSize;
void *baseAddress;
void *baseAddress = nullptr;
auto result = hostDriverHandle->importExternalPointer(testPtr, size);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = hostDriverHandle->getHostPointerBaseAddress(testPtr, &baseAddress);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(heapPointer, baseAddress);
EXPECT_EQ(testPtr, baseAddress);
auto hostPointerData = openHostPointerManager->hostPointerAllocations.get(testPtr);
ASSERT_NE(nullptr, hostPointerData);
EXPECT_EQ(2 * MemoryConstants::pageSize, hostPointerData->size);
EXPECT_EQ(size, hostPointerData->size);
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + MemoryConstants::pageSize);
void *testPtr2 = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + MemoryConstants::pageSize);
size = 0x010;
result = hostDriverHandle->importExternalPointer(testPtr, size);
result = hostDriverHandle->importExternalPointer(testPtr2, size);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = hostDriverHandle->getHostPointerBaseAddress(testPtr, &baseAddress);
result = hostDriverHandle->getHostPointerBaseAddress(testPtr2, &baseAddress);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(heapPointer, baseAddress);
EXPECT_EQ(testPtr2, baseAddress);
auto hostPointerData2 = openHostPointerManager->hostPointerAllocations.get(testPtr2);
ASSERT_NE(nullptr, hostPointerData2);
EXPECT_EQ(size, hostPointerData2->size);
EXPECT_EQ(hostPointerData->hostPtrAllocations.getGraphicsAllocations().size(), hostPointerData2->hostPtrAllocations.getGraphicsAllocations().size());
for (uint32_t i = 0; i < hostPointerData->hostPtrAllocations.getGraphicsAllocations().size(); i++) {
auto hostPointerAllocation = hostPointerData->hostPtrAllocations.getGraphicsAllocation(i);
auto hostPointerAllocation2 = hostPointerData2->hostPtrAllocations.getGraphicsAllocation(i);
EXPECT_NE(hostPointerAllocation, hostPointerAllocation2);
}
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = hostDriverHandle->releaseImportedPointer(testPtr2);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerRegisteredWhenSizeFitsThenReturnGraphicsAllocation) {
@@ -410,5 +427,30 @@ TEST_F(HostPointerManagerTest, givenHostAllocationImportedWhenMakingResidentAddr
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
}
TEST_F(HostPointerManagerTest, givenMisalignedPointerRegisteredWhenGettingRelativeOffsetAddressThenRetrieveMisalignedPointerAsBaseAddress) {
size_t mainOffset = 0x10;
void *testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(heapPointer) + mainOffset);
size_t size = MemoryConstants::pageSize + 0x10;
auto result = hostDriverHandle->importExternalPointer(testPtr, size);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
size_t relativeOffset = 0x20;
void *relativeAddress = ptrOffset(testPtr, relativeOffset);
void *baseAddress = nullptr;
result = hostDriverHandle->getHostPointerBaseAddress(relativeAddress, &baseAddress);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(testPtr, baseAddress);
auto gfxAllocation = hostDriverHandle->findHostPointerAllocation(testPtr, 0x10u, device->getRootDeviceIndex());
ASSERT_NE(nullptr, gfxAllocation);
size_t gpuVA = static_cast<size_t>(gfxAllocation->getGpuAddress());
size_t gpuAddressOffset = gpuVA - alignDown(gpuVA, MemoryConstants::pageSize);
EXPECT_EQ(mainOffset, gpuAddressOffset);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0