Add 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
2020-11-25 10:31:09 +01:00
committed by Compute-Runtime-Automation
parent 42b6dff2b4
commit 4602220e62
26 changed files with 759 additions and 22 deletions

View File

@@ -42,6 +42,8 @@ set(L0_RUNTIME_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/driver/driver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/driver/driver.h
${CMAKE_CURRENT_SOURCE_DIR}/driver/driver_imp.h
${CMAKE_CURRENT_SOURCE_DIR}/driver/host_pointer_manager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/driver/host_pointer_manager.h
${CMAKE_CURRENT_SOURCE_DIR}/event/event.cpp
${CMAKE_CURRENT_SOURCE_DIR}/event/event.h
${CMAKE_CURRENT_SOURCE_DIR}/fence/fence.cpp

View File

@@ -70,6 +70,13 @@ struct DriverHandle : _ze_driver_handle_t {
virtual NEO::SVMAllocsManager *getSvmAllocsManager() = 0;
virtual ze_result_t sysmanEventsListen(uint32_t timeout, uint32_t count, zes_device_handle_t *phDevices,
uint32_t *pNumDeviceEvents, zes_event_type_flags_t *pEvents) = 0;
virtual ze_result_t importExternalPointer(void *ptr, size_t size) = 0;
virtual ze_result_t releaseImportedPointer(void *ptr) = 0;
virtual ze_result_t getHostPointerBaseAddress(void *ptr, void **baseAddress) = 0;
virtual NEO::GraphicsAllocation *findHostPointerAllocation(void *ptr, size_t size, uint32_t rootDeviceIndex) = 0;
virtual NEO::GraphicsAllocation *getDriverSystemMemoryAllocation(void *ptr, size_t size, uint32_t rootDeviceIndex) = 0;
static DriverHandle *fromHandle(ze_driver_handle_t handle) { return static_cast<DriverHandle *>(handle); }
inline ze_driver_handle_t toHandle() { return this; }

View File

@@ -17,6 +17,7 @@
#include "level_zero/core/source/debugger/debugger_l0.h"
#include "level_zero/core/source/device/device_imp.h"
#include "level_zero/core/source/driver/driver_imp.h"
#include "level_zero/core/source/driver/host_pointer_manager.h"
#include "driver_version_l0.h"
@@ -275,6 +276,10 @@ ze_result_t DriverHandleImp::initialize(std::vector<std::unique_ptr<NEO::Device>
uuidTimestamp = static_cast<uint64_t>(std::chrono::system_clock::now().time_since_epoch().count());
if (NEO::DebugManager.flags.EnableHostPointerImport.get() == 1) {
createHostPointerManager();
}
return ZE_RESULT_SUCCESS;
}
@@ -294,7 +299,7 @@ DriverHandle *DriverHandle::create(std::vector<std::unique_ptr<NEO::Device>> dev
GlobalDriver = driverHandle;
driverHandle->memoryManager->setForceNonSvmForExternalHostPtr(true);
driverHandle->getMemoryManager()->setForceNonSvmForExternalHostPtr(true);
return driverHandle;
}
@@ -392,4 +397,67 @@ ze_result_t DriverHandleImp::openEventPoolIpcHandle(ze_ipc_event_pool_handle_t h
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
void DriverHandleImp::createHostPointerManager() {
hostPointerManager = std::make_unique<HostPointerManager>(getMemoryManager());
}
ze_result_t DriverHandleImp::importExternalPointer(void *ptr, size_t size) {
if (hostPointerManager.get() != nullptr) {
auto ret = hostPointerManager->createHostPointerMultiAllocation(this->devices,
ptr,
size);
return ret;
}
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t DriverHandleImp::releaseImportedPointer(void *ptr) {
if (hostPointerManager.get() != nullptr) {
bool ret = hostPointerManager->freeHostPointerAllocation(ptr);
return ret ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t DriverHandleImp::getHostPointerBaseAddress(void *ptr, void **baseAddress) {
if (hostPointerManager.get() != nullptr) {
auto hostPointerData = hostPointerManager->getHostPointerAllocation(ptr);
if (hostPointerData != nullptr) {
if (baseAddress != nullptr) {
*baseAddress = hostPointerData->basePtr;
}
return ZE_RESULT_SUCCESS;
}
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
NEO::GraphicsAllocation *DriverHandleImp::findHostPointerAllocation(void *ptr, size_t size, uint32_t rootDeviceIndex) {
if (hostPointerManager.get() != nullptr) {
HostPointerData *hostData = hostPointerManager->getHostPointerAllocation(ptr);
if (hostData != nullptr) {
size_t foundEndSize = reinterpret_cast<size_t>(hostData->basePtr) + hostData->size;
size_t inputEndSize = reinterpret_cast<size_t>(ptr) + size;
if (foundEndSize >= inputEndSize) {
return hostData->hostPtrAllocations.getGraphicsAllocation(rootDeviceIndex);
}
return nullptr;
}
return nullptr;
}
return nullptr;
}
NEO::GraphicsAllocation *DriverHandleImp::getDriverSystemMemoryAllocation(void *ptr, size_t size, uint32_t rootDeviceIndex) {
NEO::SvmAllocationData *allocData = nullptr;
bool allocFound = findAllocationDataForRange(ptr, size, &allocData);
if (allocFound) {
return allocData->gpuAllocations.getGraphicsAllocation(rootDeviceIndex);
}
return findHostPointerAllocation(ptr, size, rootDeviceIndex);
}
} // namespace L0

View File

@@ -14,6 +14,7 @@
#include "level_zero/extensions/public/ze_exp_ext.h"
namespace L0 {
class HostPointerManager;
struct DriverHandleImp : public DriverHandle {
~DriverHandleImp() override;
@@ -68,25 +69,35 @@ struct DriverHandleImp : public DriverHandle {
ze_result_t sysmanEventsListen(uint32_t timeout, uint32_t count, zes_device_handle_t *phDevices,
uint32_t *pNumDeviceEvents, zes_event_type_flags_t *pEvents) override;
ze_result_t importExternalPointer(void *ptr, size_t size) override;
ze_result_t releaseImportedPointer(void *ptr) override;
ze_result_t getHostPointerBaseAddress(void *ptr, void **baseAddress) override;
virtual NEO::GraphicsAllocation *findHostPointerAllocation(void *ptr, size_t size, uint32_t rootDeviceIndex) override;
virtual NEO::GraphicsAllocation *getDriverSystemMemoryAllocation(void *ptr, size_t size, uint32_t rootDeviceIndex) override;
uint32_t parseAffinityMask(std::vector<std::unique_ptr<NEO::Device>> &neoDevices);
void createHostPointerManager();
uint32_t numDevices = 0;
std::vector<Device *> devices;
NEO::MemoryManager *memoryManager = nullptr;
NEO::SVMAllocsManager *svmAllocsManager = nullptr;
uint64_t uuidTimestamp = 0u;
std::unique_ptr<HostPointerManager> hostPointerManager;
// Experimental functions
std::unordered_map<std::string, void *> extensionFunctionsLookupMap;
// Environment Variables
std::string affinityMaskString = "";
bool enableProgramDebugging = false;
bool enableSysman = false;
std::vector<Device *> devices;
// Spec extensions
const std::vector<std::pair<std::string, uint32_t>> extensionsSupported = {
{ZE_MODULE_PROGRAM_EXP_NAME, ZE_MODULE_PROGRAM_EXP_VERSION_CURRENT}};
// Experimental functions
std::unordered_map<std::string, void *> extensionFunctionsLookupMap;
uint64_t uuidTimestamp = 0u;
NEO::MemoryManager *memoryManager = nullptr;
NEO::SVMAllocsManager *svmAllocsManager = nullptr;
uint32_t numDevices = 0;
// Environment Variables
bool enableProgramDebugging = false;
bool enableSysman = false;
};
extern struct DriverHandleImp *GlobalDriver;

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/source/driver/host_pointer_manager.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/constants.h"
#include "shared/source/memory_manager/allocation_properties.h"
#include "shared/source/memory_manager/graphics_allocation.h"
#include "shared/source/memory_manager/memory_manager.h"
#include "shared/source/memory_manager/multi_graphics_allocation.h"
#include "level_zero/core/source/device/device_imp.h"
namespace L0 {
void HostPointerManager::MapBasedAllocationTracker::insert(HostPointerData allocationsData) {
allocations.insert(std::make_pair(reinterpret_cast<void *>(allocationsData.basePtr), allocationsData));
}
void HostPointerManager::MapBasedAllocationTracker::remove(const void *ptr) {
HostPointerContainer::iterator iter;
iter = allocations.find(ptr);
allocations.erase(iter);
}
HostPointerData *HostPointerManager::MapBasedAllocationTracker::get(const void *ptr) {
HostPointerContainer::iterator iter, end;
HostPointerData *hostPtrData;
if ((ptr == nullptr) || (allocations.size() == 0)) {
return nullptr;
}
end = allocations.end();
iter = allocations.lower_bound(ptr);
if (((iter != end) && (iter->first != ptr)) ||
(iter == end)) {
if (iter == allocations.begin()) {
iter = end;
} else {
iter--;
}
}
if (iter != end) {
hostPtrData = &iter->second;
char *charPtr = reinterpret_cast<char *>(hostPtrData->basePtr);
if (ptr < (charPtr + hostPtrData->size)) {
return hostPtrData;
}
}
return nullptr;
}
HostPointerManager::HostPointerManager(NEO::MemoryManager *memoryManager) : memoryManager(memoryManager) {
}
HostPointerManager::~HostPointerManager() {
}
ze_result_t HostPointerManager::createHostPointerMultiAllocation(std::vector<Device *> &devices, void *ptr, size_t size) {
if (size == 0) {
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 endingAllocation = hostPointerAllocations.get(reinterpret_cast<void *>(endAddress - 1));
if (baseAllocation != nullptr && baseAllocation == endingAllocation) {
return ZE_RESULT_SUCCESS;
}
if (baseAllocation != 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);
return ZE_RESULT_ERROR_INVALID_SIZE;
}
HostPointerData hostData(static_cast<uint32_t>(devices.size() - 1));
hostData.basePtr = basePtr;
hostData.size = totalSize;
for (auto device : devices) {
NEO::GraphicsAllocation *gfxAlloc = createHostPointerAllocation(device->getRootDeviceIndex(),
basePtr,
totalSize,
device->getNEODevice()->getDeviceBitfield());
if (gfxAlloc == nullptr) {
auto allocations = hostData.hostPtrAllocations.getGraphicsAllocations();
for (auto &allocation : allocations) {
memoryManager->freeGraphicsMemory(allocation);
}
return ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY;
}
hostData.hostPtrAllocations.addAllocation(gfxAlloc);
}
hostPointerAllocations.insert(hostData);
return ZE_RESULT_SUCCESS;
}
NEO::GraphicsAllocation *HostPointerManager::createHostPointerAllocation(uint32_t rootDeviceIndex,
void *ptr,
size_t size,
const NEO::DeviceBitfield &deviceBitfield) {
NEO::AllocationProperties properties = {rootDeviceIndex, false, size,
NEO::GraphicsAllocation::AllocationType::EXTERNAL_HOST_PTR,
false, deviceBitfield};
properties.flags.flushL3RequiredForRead = properties.flags.flushL3RequiredForWrite = true;
auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(properties,
ptr);
return allocation;
}
HostPointerData *HostPointerManager::getHostPointerAllocation(const void *ptr) {
std::unique_lock<NEO::SpinLock> lock(mtx);
return hostPointerAllocations.get(ptr);
}
bool HostPointerManager::freeHostPointerAllocation(void *ptr) {
std::unique_lock<NEO::SpinLock> lock(mtx);
HostPointerData *hostPtrData = hostPointerAllocations.get(ptr);
if (hostPtrData == nullptr) {
return false;
}
auto graphicsAllocations = hostPtrData->hostPtrAllocations.getGraphicsAllocations();
for (auto gpuAllocation : graphicsAllocations) {
memoryManager->freeGraphicsMemory(gpuAllocation);
}
hostPointerAllocations.remove(hostPtrData->basePtr);
return true;
}
} // namespace L0

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/common_types.h"
#include "shared/source/memory_manager/multi_graphics_allocation.h"
#include "shared/source/utilities/spinlock.h"
#include <level_zero/ze_api.h>
#include <cstdint>
#include <map>
#include <mutex>
#include <vector>
namespace NEO {
class GraphicsAllocation;
class MemoryManager;
} // namespace NEO
namespace L0 {
struct Device;
struct HostPointerData {
HostPointerData(uint32_t maxRootDeviceIndex)
: hostPtrAllocations(maxRootDeviceIndex),
maxRootDeviceIndex(maxRootDeviceIndex) {
}
HostPointerData(const HostPointerData &hostPtrData)
: HostPointerData(hostPtrData.maxRootDeviceIndex) {
basePtr = hostPtrData.basePtr;
size = hostPtrData.size;
for (auto allocation : hostPtrData.hostPtrAllocations.getGraphicsAllocations()) {
if (allocation) {
this->hostPtrAllocations.addAllocation(allocation);
}
}
}
NEO::MultiGraphicsAllocation hostPtrAllocations;
void *basePtr = nullptr;
size_t size = 0u;
protected:
const uint32_t maxRootDeviceIndex;
};
class HostPointerManager {
public:
class MapBasedAllocationTracker {
friend class HostPointerManager;
public:
using HostPointerContainer = std::map<const void *, HostPointerData>;
void insert(HostPointerData allocationsData);
void remove(const void *ptr);
HostPointerData *get(const void *ptr);
size_t getNumAllocs() const { return allocations.size(); };
protected:
HostPointerContainer allocations;
};
HostPointerManager(NEO::MemoryManager *memoryManager);
virtual ~HostPointerManager();
ze_result_t createHostPointerMultiAllocation(std::vector<Device *> &devices, void *ptr, size_t size);
HostPointerData *getHostPointerAllocation(const void *ptr);
bool freeHostPointerAllocation(void *ptr);
protected:
NEO::GraphicsAllocation *createHostPointerAllocation(uint32_t rootDeviceIndex,
void *ptr,
size_t size,
const NEO::DeviceBitfield &deviceBitfield);
MapBasedAllocationTracker hostPointerAllocations;
NEO::MemoryManager *memoryManager;
NEO::SpinLock mtx;
};
} // namespace L0

View File

@@ -11,6 +11,7 @@ set(L0_FIXTURES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/cmdlist_fixture.h
${CMAKE_CURRENT_SOURCE_DIR}/device_fixture.h
${CMAKE_CURRENT_SOURCE_DIR}/device_fixture.cpp
${CMAKE_CURRENT_SOURCE_DIR}/host_pointer_manager_fixture.h
${CMAKE_CURRENT_SOURCE_DIR}/module_fixture.h
)

View File

@@ -12,6 +12,7 @@
#include "shared/test/unit_test/helpers/default_hw_info.h"
#include "shared/test/unit_test/mocks/mock_device.h"
#include "level_zero/core/source/driver/host_pointer_manager.h"
#include "level_zero/core/test/unit_tests/mocks/mock_built_ins.h"
#include "level_zero/core/test/unit_tests/mocks/mock_context.h"
#include "level_zero/core/test/unit_tests/mocks/mock_device.h"

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/constants.h"
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
#include "shared/test/unit_test/helpers/default_hw_info.h"
#include "shared/test/unit_test/mocks/mock_device.h"
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
#include "level_zero/core/test/unit_tests/mocks/mock_driver_handle.h"
#include "level_zero/core/test/unit_tests/mocks/mock_host_pointer_manager.h"
namespace L0 {
namespace ult {
struct HostPointerManagerFixure {
void SetUp() {
NEO::DeviceVector devices;
neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get());
auto mockBuiltIns = new MockBuiltins();
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->builtins.reset(mockBuiltIns);
devices.push_back(std::unique_ptr<NEO::Device>(neoDevice));
DebugManager.flags.EnableHostPointerImport.set(1);
hostDriverHandle = std::make_unique<L0::ult::DriverHandle>();
hostDriverHandle->initialize(std::move(devices));
device = hostDriverHandle->devices[0];
EXPECT_NE(nullptr, hostDriverHandle->hostPointerManager.get());
openHostPointerManager = static_cast<L0::ult::HostPointerManager *>(hostDriverHandle->hostPointerManager.get());
heapPointer = hostDriverHandle->getMemoryManager()->allocateSystemMemory(4 * MemoryConstants::pageSize, MemoryConstants::pageSize);
ASSERT_NE(nullptr, heapPointer);
}
void TearDown() {
hostDriverHandle->getMemoryManager()->freeSystemMemory(heapPointer);
}
L0::ult::HostPointerManager *openHostPointerManager = nullptr;
std::unique_ptr<L0::ult::DriverHandle> hostDriverHandle;
void *heapPointer = nullptr;
NEO::MockDevice *neoDevice = nullptr;
L0::Device *device = nullptr;
};
} // namespace ult
} // namespace L0

View File

@@ -25,6 +25,7 @@ set(L0_MOCKS_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/mock_event.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_event.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_gmm_resource_info_l0.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_host_pointer_manager.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_kernel.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_l0_debugger.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_memory_manager.h

View File

@@ -5,9 +5,7 @@
*
*/
#include "mock_cmdlist.h"
#include "level_zero/core/test/unit_tests/mocks/mock_device.h"
#include "level_zero/core/test/unit_tests/mocks/mock_cmdlist.h"
namespace L0 {
namespace ult {

View File

@@ -5,7 +5,7 @@
*
*/
#include "mock_cmdqueue.h"
#include "level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h"
#include "shared/source/device/device.h"

View File

@@ -5,7 +5,7 @@
*
*/
#include "mock_device.h"
#include "level_zero/core/test/unit_tests/mocks/mock_device.h"
#include "shared/source/device/device.h"

View File

@@ -5,7 +5,7 @@
*
*/
#include "mock_driver.h"
#include "level_zero/core/test/unit_tests/mocks/mock_driver.h"
namespace L0 {
namespace ult {

View File

@@ -5,10 +5,12 @@
*
*/
#include "mock_driver_handle.h"
#include "level_zero/core/test/unit_tests/mocks/mock_driver_handle.h"
#include "shared/test/unit_test/mocks/mock_graphics_allocation.h"
#include "level_zero/core/source/driver/host_pointer_manager.h"
namespace L0 {
namespace ult {

View File

@@ -148,6 +148,29 @@ struct Mock<DriverHandle> : public DriverHandleImp {
size_t size,
size_t alignment,
void **ptr);
ze_result_t importExternalPointer(void *ptr, size_t size) override {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t releaseImportedPointer(void *ptr) override {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t getHostPointerBaseAddress(void *ptr, void **baseAddress) override {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
NEO::GraphicsAllocation *findHostPointerAllocation(void *ptr, size_t size, uint32_t rootDeviceIndex) override {
return nullptr;
}
NEO::GraphicsAllocation *getDriverSystemMemoryAllocation(void *ptr, size_t size, uint32_t rootDeviceIndex) override {
auto svmData = svmAllocsManager->getSVMAlloc(ptr);
if (svmData != nullptr) {
return svmData->gpuAllocations.getGraphicsAllocation(rootDeviceIndex);
}
return nullptr;
}
};
} // namespace ult

View File

@@ -5,7 +5,7 @@
*
*/
#include "mock_event.h"
#include "level_zero/core/test/unit_tests/mocks/mock_event.h"
#include <vector>

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/core/source/driver/host_pointer_manager.h"
#include "level_zero/core/test/unit_tests/white_box.h"
namespace L0 {
namespace ult {
template <>
struct WhiteBox<::L0::HostPointerManager> : public ::L0::HostPointerManager {
using ::L0::HostPointerManager::createHostPointerAllocation;
using ::L0::HostPointerManager::hostPointerAllocations;
using ::L0::HostPointerManager::memoryManager;
};
using HostPointerManager = WhiteBox<::L0::HostPointerManager>;
} // namespace ult
} // namespace L0

View File

@@ -5,7 +5,7 @@
*
*/
#include "mock_module.h"
#include "level_zero/core/test/unit_tests/mocks/mock_module.h"
using ::testing::Return;

View File

@@ -15,6 +15,7 @@
#include "test.h"
#include "level_zero/core/source/cmdqueue/cmdqueue_imp.h"
#include "level_zero/core/source/driver/host_pointer_manager.h"
#include "level_zero/core/test/unit_tests/mocks/mock_driver_handle.h"
#include "gtest/gtest.h"

View File

@@ -6,5 +6,6 @@
target_sources(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/host_pointer_manager_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_driver.cpp
)

View File

@@ -0,0 +1,317 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
#include "opencl/test/unit_test/mocks/mock_memory_manager.h"
#include "test.h"
#include "level_zero/core/source/driver/driver_handle_imp.h"
#include "level_zero/core/test/unit_tests/fixtures/host_pointer_manager_fixture.h"
#include "level_zero/core/test/unit_tests/mocks/mock_host_pointer_manager.h"
using ::testing::Return;
namespace L0 {
namespace ult {
using HostPointerManagerTest = Test<HostPointerManagerFixure>;
TEST_F(HostPointerManagerTest,
givenMultipleGraphicsAllocationWhenCopyingHostPointerDataThenCopyOnlyExistingAllocations) {
HostPointerData originData(4);
auto gfxAllocation = openHostPointerManager->createHostPointerAllocation(device->getRootDeviceIndex(),
heapPointer,
MemoryConstants::pageSize,
device->getNEODevice()->getDeviceBitfield());
originData.hostPtrAllocations.addAllocation(gfxAllocation);
HostPointerData copyData(originData);
for (auto allocation : copyData.hostPtrAllocations.getGraphicsAllocations()) {
if (allocation != nullptr) {
EXPECT_EQ(device->getRootDeviceIndex(), allocation->getRootDeviceIndex());
EXPECT_EQ(gfxAllocation, allocation);
}
}
hostDriverHandle->getMemoryManager()->freeGraphicsMemory(gfxAllocation);
}
TEST_F(HostPointerManagerTest, givenNoHeapManagerThenReturnFeatureUnsupported) {
hostDriverHandle->hostPointerManager.reset(nullptr);
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
result = hostDriverHandle->getHostPointerBaseAddress(testPtr, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
auto gfxAllocation = hostDriverHandle->getDriverSystemMemoryAllocation(testPtr, 1u, device->getRootDeviceIndex());
EXPECT_EQ(nullptr, gfxAllocation);
}
TEST_F(HostPointerManagerTest, givenPointerRegisteredWhenSvmAllocationExistsThenRetrieveSvmFirst) {
void *testPtr = heapPointer;
size_t usmSize = MemoryConstants::pageSize;
void *usmBuffer = hostDriverHandle->getMemoryManager()->allocateSystemMemory(usmSize, usmSize);
NEO::GraphicsAllocation *usmAllocation = hostDriverHandle->getMemoryManager()->allocateGraphicsMemoryWithProperties(
{device->getRootDeviceIndex(), false, usmSize, NEO::GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY, false, neoDevice->getDeviceBitfield()},
usmBuffer);
ASSERT_NE(nullptr, usmAllocation);
NEO::SvmAllocationData allocData(device->getRootDeviceIndex());
allocData.gpuAllocations.addAllocation(usmAllocation);
allocData.cpuAllocation = nullptr;
allocData.size = usmSize;
allocData.memoryType = InternalMemoryType::NOT_SPECIFIED;
allocData.device = nullptr;
hostDriverHandle->getSvmAllocsManager()->insertSVMAlloc(allocData);
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
auto gfxAllocation = hostDriverHandle->getDriverSystemMemoryAllocation(usmBuffer, 1u, device->getRootDeviceIndex());
ASSERT_NE(nullptr, gfxAllocation);
EXPECT_EQ(usmBuffer, gfxAllocation->getUnderlyingBuffer());
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
hostDriverHandle->getMemoryManager()->freeGraphicsMemory(usmAllocation);
hostDriverHandle->getMemoryManager()->freeSystemMemory(usmBuffer);
}
TEST_F(HostPointerManagerTest, WhenSizeIsZeroThenExpectInvalidArgument) {
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, 0u);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
}
TEST_F(HostPointerManagerTest, givenNoPointerWhenImportAddressThenRegisterNewHostData) {
void *testPtr = heapPointer;
void *baseAddress;
auto result = hostDriverHandle->getHostPointerBaseAddress(testPtr, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = hostDriverHandle->getHostPointerBaseAddress(testPtr, &baseAddress);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(heapPointer, baseAddress);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = hostDriverHandle->getHostPointerBaseAddress(testPtr, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
}
TEST_F(HostPointerManagerTest, givenNoPointerWhenImportMisalignedAddressThenRegisterNewHostData) {
void *testPtr = heapPointer;
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + 0x10);
size_t size = 0x10;
void *baseAddress;
auto result = hostDriverHandle->getHostPointerBaseAddress(testPtr, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
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);
auto hostPointerData = openHostPointerManager->hostPointerAllocations.get(testPtr);
ASSERT_NE(nullptr, hostPointerData);
EXPECT_EQ(MemoryConstants::pageSize, hostPointerData->size);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenBiggerAddressImportedWhenImportingWithinThenReturnSuccess) {
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + 0x10);
size_t size = 0x10;
result = hostDriverHandle->importExternalPointer(testPtr, size);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(1u, openHostPointerManager->hostPointerAllocations.getNumAllocs());
result = hostDriverHandle->getHostPointerBaseAddress(testPtr, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerRegisteredWhenUsingInvalidAddressThenReturnError) {
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = hostDriverHandle->getHostPointerBaseAddress(nullptr, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
result = hostDriverHandle->releaseImportedPointer(heapPointer);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerRegisteredWhenSizeEndsInNoAllocationThenExpectObjectInUseError) {
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + 0x10);
size_t size = MemoryConstants::pageSize + 0x10;
result = hostDriverHandle->importExternalPointer(testPtr, size);
EXPECT_EQ(ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE, result);
result = hostDriverHandle->releaseImportedPointer(heapPointer);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerRegisteredWhenSizeEndsInDifferentAllocationThenExpectOverlappingError) {
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + MemoryConstants::pageSize);
size_t size = MemoryConstants::pageSize;
result = hostDriverHandle->importExternalPointer(testPtr, size);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
void *errorPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(heapPointer) + 0x10);
result = hostDriverHandle->importExternalPointer(errorPtr, size);
EXPECT_EQ(ZE_RESULT_ERROR_OVERLAPPING_REGIONS, result);
result = hostDriverHandle->releaseImportedPointer(heapPointer);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerNotRegisteredWhenSizeEndsInDifferentAllocationThenExpectInvalidSizeError) {
void *testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(heapPointer) + MemoryConstants::pageSize);
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
void *errorPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(heapPointer) + 0x10);
size_t size = MemoryConstants::pageSize;
result = hostDriverHandle->importExternalPointer(errorPtr, size);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_SIZE, result);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerUsesTwoPagesThenBothPagesAreAvailableAndSizeIsCorrect) {
void *testPtr = heapPointer;
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + 0x10);
size_t size = MemoryConstants::pageSize;
void *baseAddress;
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);
auto hostPointerData = openHostPointerManager->hostPointerAllocations.get(testPtr);
ASSERT_NE(nullptr, hostPointerData);
EXPECT_EQ(2 * MemoryConstants::pageSize, hostPointerData->size);
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + MemoryConstants::pageSize);
size = 0x010;
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);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerRegisteredWhenSizeFitsThenReturnGraphicsAllocation) {
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
auto gfxAllocation = hostDriverHandle->findHostPointerAllocation(testPtr, 0x10u, device->getRootDeviceIndex());
EXPECT_NE(nullptr, gfxAllocation);
EXPECT_EQ(testPtr, gfxAllocation->getUnderlyingBuffer());
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerNotRegisteredThenReturnNullptrGraphicsAllocation) {
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
testPtr = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(testPtr) + MemoryConstants::pageSize);
auto gfxAllocation = hostDriverHandle->findHostPointerAllocation(testPtr, 0x10u, device->getRootDeviceIndex());
EXPECT_EQ(nullptr, gfxAllocation);
result = hostDriverHandle->releaseImportedPointer(heapPointer);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenPointerRegisteredWhenSizeExceedsAllocationThenReturnNullptrGraphicsAllocation) {
void *testPtr = heapPointer;
auto result = hostDriverHandle->importExternalPointer(testPtr, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
auto gfxAllocation = hostDriverHandle->findHostPointerAllocation(testPtr, MemoryConstants::pageSize + 0x10u, device->getRootDeviceIndex());
EXPECT_EQ(nullptr, gfxAllocation);
result = hostDriverHandle->releaseImportedPointer(testPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(HostPointerManagerTest, givenNoPointerRegisteredWhenAllocationCreationFailThenExpectOutOfMemoryError) {
std::unique_ptr<MemoryManager> failMemoryManager = std::make_unique<NEO::FailMemoryManager>(0, *neoDevice->executionEnvironment);
openHostPointerManager->memoryManager = failMemoryManager.get();
auto result = hostDriverHandle->importExternalPointer(heapPointer, MemoryConstants::pageSize);
EXPECT_EQ(ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY, result);
}
} // namespace ult
} // namespace L0

View File

@@ -654,6 +654,5 @@ TEST(zeDriverGetIpcProperties, whenZeDriverGetIpcPropertiesIsCalledThenGetIPCPro
result = zeDriverGetIpcProperties(driverHandle.toHandle(), &ipcProperties);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0

View File

@@ -8,6 +8,7 @@
#pragma once
#include "level_zero/core/source/device/device_imp.h"
#include "level_zero/core/source/driver/driver_handle_imp.h"
#include "level_zero/core/source/driver/host_pointer_manager.h"
#include "level_zero/core/test/unit_tests/mocks/mock_cmdlist.h"
#include "level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h"
#include "level_zero/core/test/unit_tests/mocks/mock_device.h"