From 1360ec917913500f6fb8e635a10908944b9ee611 Mon Sep 17 00:00:00 2001 From: "Spruit, Neil R" Date: Thu, 15 Dec 2022 08:15:18 -0800 Subject: [PATCH] Fix Device Allocated IPC Events - Given Device Allocated IPC Event Pool, the open IPC event pool process must allocate the event pool as a device buffer or usage of the memory will fail. - Pass deviceAlloc flag thru the IPC Event Pool Handle to enable the child processes to allocate the correct memory type. Related-To: LOCI-3764 Signed-off-by: Spruit, Neil R --- .../core/source/context/context_imp.cpp | 17 +++- level_zero/core/source/event/event.cpp | 10 +- level_zero/core/source/event/event.h | 1 + .../unit_tests/sources/event/test_event.cpp | 98 +++++++++++++++++++ 4 files changed, 119 insertions(+), 7 deletions(-) diff --git a/level_zero/core/source/context/context_imp.cpp b/level_zero/core/source/context/context_imp.cpp index 43c58fa17e..fd87336e96 100644 --- a/level_zero/core/source/context/context_imp.cpp +++ b/level_zero/core/source/context/context_imp.cpp @@ -560,6 +560,9 @@ ze_result_t EventPoolImp::getIpcHandle(ze_ipc_event_pool_handle_t *pIpcHandle) { memcpy_s(pIpcHandle->data + sizeof(int) + sizeof(this->numEvents), sizeof(rootDeviceIndex), &rootDeviceIndex, sizeof(rootDeviceIndex)); + memcpy_s(pIpcHandle->data + sizeof(int) + sizeof(this->numEvents) + sizeof(uint32_t), + sizeof(this->isDeviceEventPoolAllocation), &this->isDeviceEventPoolAllocation, sizeof(this->isDeviceEventPoolAllocation)); + return ZE_RESULT_SUCCESS; } @@ -579,15 +582,25 @@ ze_result_t ContextImp::openEventPoolIpcHandle(const ze_ipc_event_pool_handle_t memcpy_s(&rootDeviceIndex, sizeof(rootDeviceIndex), hIpc.data + sizeof(int) + sizeof(numEvents), sizeof(rootDeviceIndex)); + memcpy_s(&eventPool->isDeviceEventPoolAllocation, sizeof(eventPool->isDeviceEventPoolAllocation), + hIpc.data + sizeof(int) + sizeof(numEvents) + sizeof(rootDeviceIndex), sizeof(eventPool->isDeviceEventPoolAllocation)); + auto device = Device::fromHandle(this->devices.begin()->second); auto neoDevice = device->getNEODevice(); NEO::osHandle osHandle = static_cast(handle); eventPool->initializeSizeParameters(this->numDevices, this->deviceHandles.data(), *this->driverHandle, device->getHwInfo()); + NEO::AllocationType allocationType = NEO::AllocationType::BUFFER_HOST_MEMORY; + bool isHostUsmAllocation = true; + if (eventPool->isDeviceEventPoolAllocation) { + allocationType = NEO::AllocationType::GPU_TIMESTAMP_DEVICE_BUFFER; + isHostUsmAllocation = false; + } + NEO::AllocationProperties unifiedMemoryProperties{rootDeviceIndex, eventPool->getEventPoolSize(), - NEO::AllocationType::BUFFER_HOST_MEMORY, + allocationType, systemMemoryBitfield}; unifiedMemoryProperties.subDevicesBitfield = neoDevice->getDeviceBitfield(); @@ -595,7 +608,7 @@ ze_result_t ContextImp::openEventPoolIpcHandle(const ze_ipc_event_pool_handle_t NEO::GraphicsAllocation *alloc = memoryManager->createGraphicsAllocationFromSharedHandle(osHandle, unifiedMemoryProperties, false, - true, + isHostUsmAllocation, false); if (alloc == nullptr) { diff --git a/level_zero/core/source/event/event.cpp b/level_zero/core/source/event/event.cpp index cf515e390a..df11181544 100644 --- a/level_zero/core/source/event/event.cpp +++ b/level_zero/core/source/event/event.cpp @@ -48,7 +48,7 @@ ze_result_t EventPoolImp::initialize(DriverHandle *driver, Context *context, uin DriverHandleImp *driverHandleImp = static_cast(driver); bool useDevicesFromApi = true; - bool useDeviceAlloc = isEventPoolDeviceAllocationFlagSet(); + this->isDeviceEventPoolAllocation = isEventPoolDeviceAllocationFlagSet(); if (numDevices == 0) { currentNumDevices = static_cast(driverHandleImp->devices.size()); @@ -78,17 +78,17 @@ ze_result_t EventPoolImp::initialize(DriverHandle *driver, Context *context, uin auto &hwInfo = getDevice()->getHwInfo(); auto &l0GfxCoreHelper = getDevice()->getNEODevice()->getRootDeviceEnvironment().getHelper(); - useDeviceAlloc |= l0GfxCoreHelper.alwaysAllocateEventInLocalMem(); + this->isDeviceEventPoolAllocation |= l0GfxCoreHelper.alwaysAllocateEventInLocalMem(); initializeSizeParameters(numDevices, phDevices, *driverHandleImp, hwInfo); NEO::AllocationType allocationType = isEventPoolTimestampFlagSet() ? NEO::AllocationType::TIMESTAMP_PACKET_TAG_BUFFER : NEO::AllocationType::BUFFER_HOST_MEMORY; if (this->devices.size() > 1) { - useDeviceAlloc = false; + this->isDeviceEventPoolAllocation = false; } - if (useDeviceAlloc) { + if (this->isDeviceEventPoolAllocation) { allocationType = NEO::AllocationType::GPU_TIMESTAMP_DEVICE_BUFFER; } @@ -96,7 +96,7 @@ ze_result_t EventPoolImp::initialize(DriverHandle *driver, Context *context, uin bool allocatedMemory = false; - if (useDeviceAlloc) { + if (this->isDeviceEventPoolAllocation) { NEO::AllocationProperties allocationProperties{*rootDeviceIndices.begin(), this->eventPoolSize, allocationType, devices[0]->getNEODevice()->getDeviceBitfield()}; allocationProperties.alignment = eventAlignment; diff --git a/level_zero/core/source/event/event.h b/level_zero/core/source/event/event.h index 535af69f12..1092236b54 100644 --- a/level_zero/core/source/event/event.h +++ b/level_zero/core/source/event/event.h @@ -304,6 +304,7 @@ struct EventPool : _ze_event_pool_handle_t { std::unique_ptr eventPoolAllocations; ze_event_pool_flags_t eventPoolFlags; + bool isDeviceEventPoolAllocation = false; protected: EventPool() = default; diff --git a/level_zero/core/test/unit_tests/sources/event/test_event.cpp b/level_zero/core/test/unit_tests/sources/event/test_event.cpp index dea0adc8f1..7b558f057f 100644 --- a/level_zero/core/test/unit_tests/sources/event/test_event.cpp +++ b/level_zero/core/test/unit_tests/sources/event/test_event.cpp @@ -342,6 +342,55 @@ TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolThenHandleAndNum driverHandle->setMemoryManager(curMemoryManager); } +TEST_F(EventPoolIPCHandleTests, whenGettingIpcHandleForEventPoolWithDeviceAllocThenHandleAndDeviceAllocAreReturnedInHandle) { + uint32_t numEvents = 4; + ze_event_pool_desc_t eventPoolDesc = { + ZE_STRUCTURE_TYPE_EVENT_POOL_DESC, + nullptr, + ZE_EVENT_POOL_FLAG_IPC, + numEvents}; + + auto deviceHandle = device->toHandle(); + ze_result_t result = ZE_RESULT_SUCCESS; + auto curMemoryManager = driverHandle->getMemoryManager(); + MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment); + driverHandle->setMemoryManager(mockMemoryManager); + auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, eventPool); + + EXPECT_TRUE(eventPool->isDeviceEventPoolAllocation); + + auto allocation = &eventPool->getAllocation(); + + EXPECT_EQ(allocation->getAllocationType(), NEO::AllocationType::GPU_TIMESTAMP_DEVICE_BUFFER); + + ze_ipc_event_pool_handle_t ipcHandle = {}; + ze_result_t res = eventPool->getIpcHandle(&ipcHandle); + EXPECT_EQ(res, ZE_RESULT_SUCCESS); + + int handle = -1; + memcpy_s(&handle, sizeof(int), ipcHandle.data, sizeof(int)); + EXPECT_NE(handle, -1); + + uint32_t expectedNumEvents = 0; + memcpy_s(&expectedNumEvents, sizeof(expectedNumEvents), ipcHandle.data + sizeof(int), sizeof(expectedNumEvents)); + EXPECT_EQ(numEvents, expectedNumEvents); + + uint32_t rootDeviceIndex = 0; + memcpy_s(&rootDeviceIndex, sizeof(rootDeviceIndex), ipcHandle.data + sizeof(int) + sizeof(size_t), sizeof(rootDeviceIndex)); + EXPECT_EQ(0u, rootDeviceIndex); + + uint8_t deviceAlloc = 0; + memcpy_s(&deviceAlloc, sizeof(deviceAlloc), ipcHandle.data + sizeof(int) + sizeof(size_t) + sizeof(rootDeviceIndex), sizeof(deviceAlloc)); + EXPECT_EQ(1u, deviceAlloc); + + res = eventPool->destroy(); + EXPECT_EQ(res, ZE_RESULT_SUCCESS); + delete mockMemoryManager; + driverHandle->setMemoryManager(curMemoryManager); +} + using EventPoolCreateMultiDevice = Test; TEST_F(EventPoolCreateMultiDevice, whenGettingIpcHandleForEventPoolWhenHostShareableMemoryIsFalseThenUnsuportedIsReturned) { @@ -413,6 +462,55 @@ TEST_F(EventPoolIPCHandleTests, whenOpeningIpcHandleForEventPoolThenEventPoolIsC driverHandle->setMemoryManager(curMemoryManager); } +TEST_F(EventPoolIPCHandleTests, whenOpeningIpcHandleForEventPoolWithDeviceAllocThenEventPoolIsCreatedAsDeviceBufferAndDeviceAllocIsSet) { + uint32_t numEvents = 4; + ze_event_pool_desc_t eventPoolDesc = { + ZE_STRUCTURE_TYPE_EVENT_POOL_DESC, + nullptr, + ZE_EVENT_POOL_FLAG_IPC, + numEvents}; + + auto deviceHandle = device->toHandle(); + ze_result_t result = ZE_RESULT_SUCCESS; + auto curMemoryManager = driverHandle->getMemoryManager(); + MemoryManagerEventPoolIPCMock *mockMemoryManager = new MemoryManagerEventPoolIPCMock(*neoDevice->executionEnvironment); + driverHandle->setMemoryManager(mockMemoryManager); + auto eventPool = EventPool::create(driverHandle.get(), context, 1, &deviceHandle, &eventPoolDesc, result); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, eventPool); + + ze_ipc_event_pool_handle_t ipcHandle = {}; + ze_result_t res = eventPool->getIpcHandle(&ipcHandle); + EXPECT_EQ(res, ZE_RESULT_SUCCESS); + + ze_event_pool_handle_t ipcEventPoolHandle = {}; + res = context->openEventPoolIpcHandle(ipcHandle, &ipcEventPoolHandle); + EXPECT_EQ(res, ZE_RESULT_SUCCESS); + + uint8_t deviceAlloc = 0; + memcpy_s(&deviceAlloc, sizeof(deviceAlloc), ipcHandle.data + sizeof(int) + sizeof(size_t) + sizeof(uint32_t), sizeof(deviceAlloc)); + EXPECT_EQ(1u, deviceAlloc); + + auto ipcEventPool = static_cast(L0::EventPool::fromHandle(ipcEventPoolHandle)); + + EXPECT_TRUE(ipcEventPool->isDeviceEventPoolAllocation); + + auto allocation = &ipcEventPool->getAllocation(); + + EXPECT_EQ(allocation->getAllocationType(), NEO::AllocationType::GPU_TIMESTAMP_DEVICE_BUFFER); + + EXPECT_EQ(ipcEventPool->getEventSize(), eventPool->getEventSize()); + EXPECT_EQ(numEvents, static_cast(ipcEventPool->getNumEvents())); + + res = ipcEventPool->closeIpcHandle(); + EXPECT_EQ(res, ZE_RESULT_SUCCESS); + + res = eventPool->destroy(); + EXPECT_EQ(res, ZE_RESULT_SUCCESS); + delete mockMemoryManager; + driverHandle->setMemoryManager(curMemoryManager); +} + TEST_F(EventPoolIPCHandleTests, GivenEventPoolWithIPCEventFlagAndDeviceMemoryThenShareableEventMemoryIsTrue) { ze_event_pool_desc_t eventPoolDesc = { ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,