From 5446b9ca0d830c00de9001a1a5908010c0f1ba99 Mon Sep 17 00:00:00 2001 From: Jaime A Arteaga Molina Date: Tue, 25 Oct 2022 07:21:48 +0000 Subject: [PATCH] Update Fabric Latency to Edge Properties (2) - Only initialize vertexes when queried. - Return also bandwidth when calling PRELIM_DRM_I915_QUERY_FABRIC_INFO. Related-To: LOCI-3464 Signed-off-by: Jaime A Arteaga Molina --- level_zero/core/source/device/device.h | 2 +- level_zero/core/source/device/device_imp.cpp | 8 ++- level_zero/core/source/device/device_imp.h | 2 +- .../core/source/driver/driver_handle_imp.cpp | 31 +++++---- .../core/source/driver/driver_handle_imp.h | 1 + .../source/fabric/linux/fabric_device_iaf.cpp | 3 +- .../core/test/unit_tests/mocks/mock_device.h | 2 +- .../sources/cmdqueue/test_cmdqueue_3.cpp | 51 ++++++++++++++ .../linux/test_driver_handle_imp_linux.cpp | 67 +++++++++++++++++-- .../sources/fabric/linux/test_fabric_iaf.cpp | 29 ++++++-- .../unit_tests/sources/fabric/test_fabric.cpp | 56 ++++++++++++++-- .../source/os_interface/linux/ioctl_helper.h | 6 +- .../linux/ioctl_helper_prelim.cpp | 5 +- .../linux/ioctl_helper_upstream.cpp | 2 +- .../linux/ioctl_helper_tests_prelim.cpp | 30 +++++++-- .../linux/ioctl_helper_tests_upstream.cpp | 4 +- 16 files changed, 251 insertions(+), 48 deletions(-) diff --git a/level_zero/core/source/device/device.h b/level_zero/core/source/device/device.h index 094f140a0f..16b4ece696 100644 --- a/level_zero/core/source/device/device.h +++ b/level_zero/core/source/device/device.h @@ -135,7 +135,7 @@ struct Device : _ze_device_handle_t { virtual ze_result_t getCsrForLowPriority(NEO::CommandStreamReceiver **csr) = 0; virtual NEO::GraphicsAllocation *obtainReusableAllocation(size_t requiredSize, NEO::AllocationType type) = 0; virtual void storeReusableAllocation(NEO::GraphicsAllocation &alloc) = 0; - virtual ze_result_t getFabricVertex(ze_fabric_vertex_handle_t *phVertex) const = 0; + virtual ze_result_t getFabricVertex(ze_fabric_vertex_handle_t *phVertex) = 0; protected: NEO::Device *neoDevice = nullptr; diff --git a/level_zero/core/source/device/device_imp.cpp b/level_zero/core/source/device/device_imp.cpp index 107ed33105..15a9b114cf 100644 --- a/level_zero/core/source/device/device_imp.cpp +++ b/level_zero/core/source/device/device_imp.cpp @@ -1506,7 +1506,13 @@ NEO::EngineGroupType DeviceImp::getEngineGroupTypeForOrdinal(uint32_t ordinal) c return engineGroupType; } -ze_result_t DeviceImp::getFabricVertex(ze_fabric_vertex_handle_t *phVertex) const { +ze_result_t DeviceImp::getFabricVertex(ze_fabric_vertex_handle_t *phVertex) { + auto driverHandle = this->getDriverHandle(); + DriverHandleImp *driverHandleImp = static_cast(driverHandle); + if (driverHandleImp->fabricVertices.empty()) { + driverHandleImp->initializeVertexes(); + } + if (fabricVertex == nullptr) { return ZE_RESULT_EXP_ERROR_DEVICE_IS_NOT_VERTEX; } diff --git a/level_zero/core/source/device/device_imp.h b/level_zero/core/source/device/device_imp.h index a0ee5d6e5e..7bb44bf7a4 100644 --- a/level_zero/core/source/device/device_imp.h +++ b/level_zero/core/source/device/device_imp.h @@ -137,7 +137,7 @@ struct DeviceImp : public Device { using CmdListCreateFunPtrT = L0::CommandList *(*)(uint32_t, Device *, NEO::EngineGroupType, ze_command_list_flags_t, ze_result_t &); CmdListCreateFunPtrT getCmdListCreateFunc(const ze_command_list_desc_t *desc); - ze_result_t getFabricVertex(ze_fabric_vertex_handle_t *phVertex) const override; + ze_result_t getFabricVertex(ze_fabric_vertex_handle_t *phVertex) override; ze_result_t queryDeviceLuid(ze_device_luid_ext_properties_t *deviceLuidProperties); ze_result_t setDeviceLuid(ze_device_luid_ext_properties_t *deviceLuidProperties); diff --git a/level_zero/core/source/driver/driver_handle_imp.cpp b/level_zero/core/source/driver/driver_handle_imp.cpp index e431f423e4..381d62cc48 100644 --- a/level_zero/core/source/driver/driver_handle_imp.cpp +++ b/level_zero/core/source/driver/driver_handle_imp.cpp @@ -243,19 +243,6 @@ ze_result_t DriverHandleImp::initialize(std::vector createHostPointerManager(); } - for (auto &device : this->devices) { - - auto deviceImpl = static_cast(device); - auto fabricVertex = FabricVertex::createFromDevice(device); - if (fabricVertex == nullptr) { - continue; - } - deviceImpl->setFabricVertex(fabricVertex); - this->fabricVertices.push_back(fabricVertex); - } - - FabricEdge::createEdgesFromVertices(this->fabricVertices, this->fabricEdges); - return ZE_RESULT_SUCCESS; } @@ -643,8 +630,26 @@ ze_result_t DriverHandleImp::checkMemoryAccessFromDevice(Device *device, const v return ZE_RESULT_ERROR_INVALID_ARGUMENT; } +void DriverHandleImp::initializeVertexes() { + for (auto &device : this->devices) { + auto deviceImpl = static_cast(device); + auto fabricVertex = FabricVertex::createFromDevice(device); + if (fabricVertex == nullptr) { + continue; + } + deviceImpl->setFabricVertex(fabricVertex); + this->fabricVertices.push_back(fabricVertex); + } + + FabricEdge::createEdgesFromVertices(this->fabricVertices, this->fabricEdges); +} + ze_result_t DriverHandleImp::fabricVertexGetExp(uint32_t *pCount, ze_fabric_vertex_handle_t *phVertices) { + if (fabricVertices.empty()) { + this->initializeVertexes(); + } + uint32_t fabricVertexCount = static_cast(this->fabricVertices.size()); if (*pCount == 0) { *pCount = fabricVertexCount; diff --git a/level_zero/core/source/driver/driver_handle_imp.h b/level_zero/core/source/driver/driver_handle_imp.h index 18d28ea5c6..b52805af31 100644 --- a/level_zero/core/source/driver/driver_handle_imp.h +++ b/level_zero/core/source/driver/driver_handle_imp.h @@ -71,6 +71,7 @@ struct DriverHandleImp : public DriverHandle { NEO::SvmAllocationData *allocData, void *basePtr, uintptr_t *peerGpuAddress); + void initializeVertexes(); ze_result_t fabricVertexGetExp(uint32_t *pCount, ze_fabric_vertex_handle_t *phDevices) override; void createHostPointerManager(); void sortNeoDevices(std::vector> &neoDevices); diff --git a/level_zero/core/source/fabric/linux/fabric_device_iaf.cpp b/level_zero/core/source/fabric/linux/fabric_device_iaf.cpp index c7ab691e06..4f58426c6e 100644 --- a/level_zero/core/source/fabric/linux/fabric_device_iaf.cpp +++ b/level_zero/core/source/fabric/linux/fabric_device_iaf.cpp @@ -224,7 +224,8 @@ bool FabricSubDeviceIaf::getEdgeProperty(FabricSubDeviceIaf *pNeighbourInterface edgeProperty.latency = std::numeric_limits::max(); edgeProperty.latencyUnit = ZE_LATENCY_UNIT_UNKNOWN; - if (pDrm->getIoctlHelper()->getFabricLatency(neighbourFabricId, edgeProperty.latency) == true) { + uint32_t bandwidth = 0; + if (pDrm->getIoctlHelper()->getFabricLatency(neighbourFabricId, edgeProperty.latency, bandwidth) == true) { edgeProperty.latencyUnit = ZE_LATENCY_UNIT_HOP; } diff --git a/level_zero/core/test/unit_tests/mocks/mock_device.h b/level_zero/core/test/unit_tests/mocks/mock_device.h index 36dda7c1c6..7b1ce5bc42 100644 --- a/level_zero/core/test/unit_tests/mocks/mock_device.h +++ b/level_zero/core/test/unit_tests/mocks/mock_device.h @@ -82,7 +82,7 @@ struct Mock : public Device { ADDMETHOD_NOBASE_VOIDRETURN(removeDebugSession, ()); ADDMETHOD_NOBASE(obtainReusableAllocation, NEO::GraphicsAllocation *, nullptr, (size_t requiredSize, NEO::AllocationType type)) ADDMETHOD_NOBASE_VOIDRETURN(storeReusableAllocation, (NEO::GraphicsAllocation & alloc)); - ADDMETHOD_CONST_NOBASE(getFabricVertex, ze_result_t, ZE_RESULT_SUCCESS, (ze_fabric_vertex_handle_t * phVertex)); + ADDMETHOD_NOBASE(getFabricVertex, ze_result_t, ZE_RESULT_SUCCESS, (ze_fabric_vertex_handle_t * phVertex)); DebugSession *createDebugSession(const zet_debug_config_t &config, ze_result_t &result, bool isRootAttach) override { result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; diff --git a/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_3.cpp b/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_3.cpp index df31df8509..d6b0a3308e 100644 --- a/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_3.cpp +++ b/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_3.cpp @@ -712,6 +712,57 @@ HWTEST2_F(EngineInstancedDeviceExecuteTests, givenEngineInstancedDeviceWhenExecu commandQueue->destroy(); } +HWTEST2_F(EngineInstancedDeviceExecuteTests, givenEngineInstancedDeviceWithFabricEnumerationWhenExecutingThenEnableSingleSliceDispatch, IsAtLeastXeHpCore) { + using CFE_STATE = typename FamilyType::CFE_STATE; + + constexpr uint32_t genericDevicesCount = 1; + constexpr uint32_t ccsCount = 2; + + DebugManager.flags.AllowSingleTileEngineInstancedSubDevices.set(true); + + if (!createDevices(genericDevicesCount, ccsCount)) { + GTEST_SKIP(); + } + + auto subDevice = static_cast(rootDevice->getSubDevice(0)); + auto defaultEngine = subDevice->getDefaultEngine(); + EXPECT_TRUE(defaultEngine.osContext->isEngineInstanced()); + + std::vector> devices; + devices.push_back(std::unique_ptr(subDevice)); + + auto driverHandle = std::make_unique>(); + driverHandle->initialize(std::move(devices)); + + driverHandle->initializeVertexes(); + + auto l0Device = driverHandle->devices[0]; + + ze_command_queue_desc_t desc = {}; + NEO::CommandStreamReceiver *csr; + l0Device->getCsrForOrdinalAndIndex(&csr, 0u, 0u); + ze_result_t returnValue; + auto commandQueue = whiteboxCast(CommandQueue::create(productFamily, l0Device, csr, &desc, false, false, returnValue)); + auto commandList = std::unique_ptr(whiteboxCast(CommandList::create(productFamily, l0Device, NEO::EngineGroupType::Compute, 0u, returnValue))); + auto commandListHandle = commandList->toHandle(); + + commandQueue->executeCommandLists(1, &commandListHandle, nullptr, false); + + GenCmdList cmdList; + FamilyType::PARSE::parseCommandBuffer(cmdList, commandQueue->commandStream.getCpuBase(), commandQueue->commandStream.getUsed()); + + auto cfeStates = findAll(cmdList.begin(), cmdList.end()); + + EXPECT_NE(0u, cfeStates.size()); + + for (auto &cmd : cfeStates) { + auto cfeState = reinterpret_cast(*cmd); + EXPECT_TRUE(cfeState->getSingleSliceDispatchCcsMode()); + } + + commandQueue->destroy(); +} + template class MockCommandQueueHandleIndirectAllocs : public MockCommandQueueHw { public: diff --git a/level_zero/core/test/unit_tests/sources/driver/linux/test_driver_handle_imp_linux.cpp b/level_zero/core/test/unit_tests/sources/driver/linux/test_driver_handle_imp_linux.cpp index f19cb86fd3..af1dcdf473 100644 --- a/level_zero/core/test/unit_tests/sources/driver/linux/test_driver_handle_imp_linux.cpp +++ b/level_zero/core/test/unit_tests/sources/driver/linux/test_driver_handle_imp_linux.cpp @@ -129,7 +129,7 @@ TEST_F(DriverLinuxWithouthPciOrderTests, GivenNoEnvironmentVariableForDeviceOrde delete driverHandle; } -class DriverPciOrderWitSimilarBusLinuxFixture : public ::testing::Test { +class DriverPciOrderWithSimilarBusLinuxFixture : public ::testing::Test { public: void SetUp() override { DebugManagerStateRestore restorer; @@ -170,7 +170,7 @@ class DriverPciOrderWitSimilarBusLinuxFixture : public ::testing::Test { std::unique_ptr deviceFactory; }; -TEST_F(DriverPciOrderWitSimilarBusLinuxFixture, GivenEnvironmentVariableForDeviceOrderAccordingToPciSetWhenRetrievingNeoDevicesThenNeoDevicesAccordingToBusOrderRetrieved) { +TEST_F(DriverPciOrderWithSimilarBusLinuxFixture, GivenEnvironmentVariableForDeviceOrderAccordingToPciSetWhenRetrievingNeoDevicesThenNeoDevicesAccordingToBusOrderRetrieved) { DriverHandleImp *driverHandle = new DriverHandleImp; @@ -187,7 +187,27 @@ TEST_F(DriverPciOrderWitSimilarBusLinuxFixture, GivenEnvironmentVariableForDevic delete driverHandle; } -class DriverPciOrderWitDifferentDeviceLinuxFixture : public ::testing::Test { +TEST_F(DriverPciOrderWithSimilarBusLinuxFixture, + GivenEnvironmentVariableForDeviceOrderAccordingToPciSetWhenRetrievingNeoDevicesAndThenInitializingVertexesThenNeoDevicesAccordingToBusOrderRetrieved) { + + DriverHandleImp *driverHandle = new DriverHandleImp; + + EXPECT_EQ(ZE_RESULT_SUCCESS, driverHandle->initialize(std::move(devices))); + + driverHandle->initializeVertexes(); + + for (uint32_t i = 0; i < numRootDevices; i++) { + auto l0Device = driverHandle->devices[i]; + if (l0Device != nullptr) { + auto pDrm = l0Device->getNEODevice()->getExecutionEnvironment()->rootDeviceEnvironments[l0Device->getRootDeviceIndex()]->osInterface->getDriverModel()->as(); + EXPECT_NE(pDrm, nullptr); + EXPECT_TRUE(!pDrm->getPciPath().compare(sortedBdf[i])); + } + } + delete driverHandle; +} + +class DriverPciOrderWithDifferentDeviceLinuxFixture : public ::testing::Test { public: void SetUp() override { DebugManagerStateRestore restorer; @@ -228,7 +248,7 @@ class DriverPciOrderWitDifferentDeviceLinuxFixture : public ::testing::Test { std::unique_ptr deviceFactory; }; -TEST_F(DriverPciOrderWitDifferentDeviceLinuxFixture, GivenEnvironmentVariableForDeviceOrderAccordingToPciSetWhenRetrievingNeoDevicesThenNeoDevicesAccordingToBusOrderRetrieved) { +TEST_F(DriverPciOrderWithDifferentDeviceLinuxFixture, GivenEnvironmentVariableForDeviceOrderAccordingToPciSetWhenRetrievingNeoDevicesThenNeoDevicesAccordingToBusOrderRetrieved) { DriverHandleImp *driverHandle = new DriverHandleImp; @@ -245,7 +265,27 @@ TEST_F(DriverPciOrderWitDifferentDeviceLinuxFixture, GivenEnvironmentVariableFor delete driverHandle; } -class DriverPciOrderWitSimilarBusAndDeviceLinuxFixture : public ::testing::Test { +TEST_F(DriverPciOrderWithDifferentDeviceLinuxFixture, + GivenEnvironmentVariableForDeviceOrderAccordingToPciSetWhenRetrievingNeoDevicesAndThenInitializingVertexesThenNeoDevicesAccordingToBusOrderRetrieved) { + + DriverHandleImp *driverHandle = new DriverHandleImp; + + EXPECT_EQ(ZE_RESULT_SUCCESS, driverHandle->initialize(std::move(devices))); + + driverHandle->initializeVertexes(); + + for (uint32_t i = 0; i < numRootDevices; i++) { + auto l0Device = driverHandle->devices[i]; + if (l0Device != nullptr) { + auto pDrm = l0Device->getNEODevice()->getExecutionEnvironment()->rootDeviceEnvironments[l0Device->getRootDeviceIndex()]->osInterface->getDriverModel()->as(); + EXPECT_NE(pDrm, nullptr); + EXPECT_TRUE(!pDrm->getPciPath().compare(sortedBdf[i])); + } + } + delete driverHandle; +} + +class DriverPciOrderWithSimilarBusAndDeviceLinuxFixture : public ::testing::Test { public: void SetUp() override { DebugManagerStateRestore restorer; @@ -286,7 +326,7 @@ class DriverPciOrderWitSimilarBusAndDeviceLinuxFixture : public ::testing::Test std::unique_ptr deviceFactory; }; -TEST_F(DriverPciOrderWitSimilarBusAndDeviceLinuxFixture, GivenEnvironmentVariableForDeviceOrderAccordingToPciSetWhenRetrievingNeoDevicesThenNeoDevicesAccordingToBusOrderRetrieved) { +TEST_F(DriverPciOrderWithSimilarBusAndDeviceLinuxFixture, GivenEnvironmentVariableForDeviceOrderAccordingToPciSetWhenRetrievingNeoDevicesThenNeoDevicesAccordingToBusOrderRetrieved) { DriverHandleImp *driverHandle = new DriverHandleImp; @@ -453,5 +493,20 @@ TEST_F(DriverWDDMLinuxFixture, ClearPciSortFlagToVerifyCodeCoverageOnly) { delete driverHandle; } +TEST_F(DriverWDDMLinuxFixture, ClearPciSortFlagWithFabricEnumerationToVerifyCodeCoverageOnly) { + + DriverHandleImp *driverHandle = new DriverHandleImp; + EXPECT_EQ(ZE_RESULT_SUCCESS, driverHandle->initialize(std::move(devices))); + + driverHandle->initializeVertexes(); + + DebugManagerStateRestore restorer; + DebugManager.flags.ZE_ENABLE_PCI_ID_DEVICE_ORDER.set(0); + + executionEnvironment->sortNeoDevices(); + + delete driverHandle; +} + } // namespace ult } // namespace L0 diff --git a/level_zero/core/test/unit_tests/sources/fabric/linux/test_fabric_iaf.cpp b/level_zero/core/test/unit_tests/sources/fabric/linux/test_fabric_iaf.cpp index f3d5a4e6b7..95ff3a0607 100644 --- a/level_zero/core/test/unit_tests/sources/fabric/linux/test_fabric_iaf.cpp +++ b/level_zero/core/test/unit_tests/sources/fabric/linux/test_fabric_iaf.cpp @@ -234,8 +234,9 @@ TEST_F(TestFabricIaf, GivenIafFabricAvailableWhenGetPortsReturnsErrorThenReturnE class MockIoctlHelperIafTest : public NEO::IoctlHelperPrelim20 { public: using IoctlHelperPrelim20::IoctlHelperPrelim20; - bool getFabricLatency(uint32_t fabricId, uint32_t &latency) override { + bool getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) override { latency = 1; + bandwidth = 10; return mockFabricLatencyReturn; } @@ -253,9 +254,18 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT auto drmMock = new DrmMockResources(*rootDeviceEnvironment); drmMock->ioctlHelper.reset(new MockIoctlHelperIafTest(*drmMock)); rootDeviceEnvironment->osInterface.reset(osInterface); - executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr(drmMock)); + executionEnvironment->rootDeviceEnvironments[device->getRootDeviceIndex()]->osInterface->setDriverModel(std::unique_ptr(drmMock)); } + // initialize + uint32_t count = 0; + std::vector phVertices; + ze_result_t res = driverHandle->fabricVertexGetExp(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + phVertices.resize(count); + res = driverHandle->fabricVertexGetExp(&count, phVertices.data()); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + // IAF port connection configuration // Device | SubDevice | Port -- Connected to -- Device | SubDevice | Port // 0 0 1 1 0 2 @@ -417,7 +427,7 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenCreatingEdgesT EXPECT_EQ(static_cast(driverHandle->fabricEdges.size()), root2root + subDevice2root + subDevice2SubDevice); - uint32_t count = 0; + count = 0; std::vector edges(30); // Root to Root Connection @@ -537,9 +547,18 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenLatencyRequest mockIoctlHelper->mockFabricLatencyReturn = false; drmMock->ioctlHelper.reset(mockIoctlHelper); rootDeviceEnvironment->osInterface.reset(osInterface); - executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr(drmMock)); + executionEnvironment->rootDeviceEnvironments[device->getRootDeviceIndex()]->osInterface->setDriverModel(std::unique_ptr(drmMock)); } + // initialize + uint32_t count = 0; + std::vector phVertices; + ze_result_t res = driverHandle->fabricVertexGetExp(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + phVertices.resize(count); + res = driverHandle->fabricVertexGetExp(&count, phVertices.data()); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + // IAF port connection configuration // Device | SubDevice | Port -- Connected to -- Device | SubDevice | Port // 0 0 1 1 0 2 @@ -589,7 +608,7 @@ TEST_F(FabricIafEdgeFixture, GivenMultipleDevicesAndSubDevicesWhenLatencyRequest } driverHandle->fabricEdges.clear(); FabricEdge::createEdgesFromVertices(driverHandle->fabricVertices, driverHandle->fabricEdges); - uint32_t count = 0; + count = 0; std::vector edges(30); // Root to Root Connection diff --git a/level_zero/core/test/unit_tests/sources/fabric/test_fabric.cpp b/level_zero/core/test/unit_tests/sources/fabric/test_fabric.cpp index 54faa1777c..dd2cb975d6 100644 --- a/level_zero/core/test/unit_tests/sources/fabric/test_fabric.cpp +++ b/level_zero/core/test/unit_tests/sources/fabric/test_fabric.cpp @@ -171,8 +171,16 @@ TEST(FabricEngineInstanceTest, GivenEngineInstancedDeviceWhenFabricVerticesAreCr ze_result_t res = driverHandle->initialize(std::move(devices)); EXPECT_EQ(ZE_RESULT_SUCCESS, res); - EXPECT_EQ(driverHandle->fabricVertices.size(), 1u); uint32_t count = 0; + std::vector phVertices; + res = driverHandle->fabricVertexGetExp(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + phVertices.resize(count); + res = driverHandle->fabricVertexGetExp(&count, phVertices.data()); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + + EXPECT_EQ(driverHandle->fabricVertices.size(), 1u); + count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, driverHandle->fabricVertices[0]->getSubVertices(&count, nullptr)); EXPECT_EQ(count, 0u); } @@ -194,10 +202,15 @@ TEST_F(FabricVertexFixture, GivenDevicesAreCreatedWhenZeDeviceGetFabricVertexExp TEST_F(FabricVertexFixture, GivenDevicesAreCreatedWhenFabricVertexIsNotSetToDeviceThenZeDeviceGetFabricVertexExpReturnsError) { auto l0Device = driverHandle->devices[0]; + + ze_fabric_vertex_handle_t hVertex = nullptr; + EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeDeviceGetFabricVertexExp(l0Device->toHandle(), &hVertex)); + EXPECT_NE(hVertex, nullptr); + auto deviceImp = static_cast(l0Device); deviceImp->setFabricVertex(nullptr); - ze_fabric_vertex_handle_t hVertex = nullptr; + hVertex = nullptr; EXPECT_EQ(ZE_RESULT_EXP_ERROR_DEVICE_IS_NOT_VERTEX, L0::zeDeviceGetFabricVertexExp(l0Device->toHandle(), &hVertex)); EXPECT_EQ(hVertex, nullptr); } @@ -206,6 +219,15 @@ using FabricEdgeFixture = Test; TEST_F(FabricEdgeFixture, GivenFabricVerticesAreCreatedWhenZeFabricEdgeGetExpIsCalledThenReturnSuccess) { + // initialize + uint32_t count = 0; + std::vector phVertices; + ze_result_t res = driverHandle->fabricVertexGetExp(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + phVertices.resize(count); + res = driverHandle->fabricVertexGetExp(&count, phVertices.data()); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + // Delete existing fabric edges for (auto edge : driverHandle->fabricEdges) { delete edge; @@ -218,7 +240,7 @@ TEST_F(FabricEdgeFixture, GivenFabricVerticesAreCreatedWhenZeFabricEdgeGetExpIsC driverHandle->fabricEdges.push_back(FabricEdge::create(driverHandle->fabricVertices[0], driverHandle->fabricVertices[1], dummyProperties)); std::vector edgeHandles(10); - uint32_t count = 0; + count = 0; EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(driverHandle->fabricVertices[0]->toHandle(), driverHandle->fabricVertices[1]->toHandle(), &count, @@ -232,6 +254,14 @@ TEST_F(FabricEdgeFixture, GivenFabricVerticesAreCreatedWhenZeFabricEdgeGetExpIsC } TEST_F(FabricEdgeFixture, GivenFabricEdgesAreCreatedWhenZeFabricEdgeGetVerticesExpIsCalledThenReturnCorrectVertices) { + // initialize + uint32_t count = 0; + std::vector phVertices; + ze_result_t res = driverHandle->fabricVertexGetExp(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + phVertices.resize(count); + res = driverHandle->fabricVertexGetExp(&count, phVertices.data()); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); // Delete existing fabric edges for (auto edge : driverHandle->fabricEdges) { @@ -243,7 +273,7 @@ TEST_F(FabricEdgeFixture, GivenFabricEdgesAreCreatedWhenZeFabricEdgeGetVerticesE driverHandle->fabricEdges.push_back(FabricEdge::create(driverHandle->fabricVertices[0], driverHandle->fabricVertices[1], dummyProperties)); std::vector edgeHandles(10); - uint32_t count = 1; + count = 1; EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(driverHandle->fabricVertices[1]->toHandle(), driverHandle->fabricVertices[0]->toHandle(), &count, @@ -256,6 +286,14 @@ TEST_F(FabricEdgeFixture, GivenFabricEdgesAreCreatedWhenZeFabricEdgeGetVerticesE } TEST_F(FabricEdgeFixture, GivenFabricEdgesAreCreatedWhenZeFabricEdgeGetPropertiesExpIsCalledThenReturnCorrectProperties) { + // initialize + uint32_t count = 0; + std::vector phVertices; + ze_result_t res = driverHandle->fabricVertexGetExp(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + phVertices.resize(count); + res = driverHandle->fabricVertexGetExp(&count, phVertices.data()); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); // Delete existing fabric edges for (auto edge : driverHandle->fabricEdges) { @@ -269,7 +307,7 @@ TEST_F(FabricEdgeFixture, GivenFabricEdgesAreCreatedWhenZeFabricEdgeGetPropertie driverHandle->fabricEdges.push_back(FabricEdge::create(driverHandle->fabricVertices[0], driverHandle->fabricVertices[1], properties)); std::vector edgeHandles(10); - uint32_t count = 1; + count = 1; EXPECT_EQ(ZE_RESULT_SUCCESS, L0::zeFabricEdgeGetExp(driverHandle->fabricVertices[1]->toHandle(), driverHandle->fabricVertices[0]->toHandle(), &count, @@ -281,6 +319,14 @@ TEST_F(FabricEdgeFixture, GivenFabricEdgesAreCreatedWhenZeFabricEdgeGetPropertie } TEST_F(FabricEdgeFixture, GivenMdfiLinksAreAvailableWhenEdgesAreCreatedThenVerifyThatBiDirectionalEdgesAreNotCreated) { + // initialize + uint32_t count = 0; + std::vector phVertices; + ze_result_t res = driverHandle->fabricVertexGetExp(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + phVertices.resize(count); + res = driverHandle->fabricVertexGetExp(&count, phVertices.data()); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); auto &fabricSubVertex1 = driverHandle->fabricVertices[0]->subVertices[1]; auto fabricDeviceMdfi = static_cast(fabricSubVertex1->pFabricDeviceInterfaces[FabricDeviceInterface::Type::Mdfi].get()); diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index c6c71aa1b0..3439f9d95e 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -134,7 +134,7 @@ class IoctlHelper { virtual std::string getFileForMaxGpuFrequency() const; virtual std::string getFileForMaxGpuFrequencyOfSubDevice(int subDeviceId) const; virtual std::string getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId) const; - virtual bool getFabricLatency(uint32_t fabricId, uint32_t &latency) = 0; + virtual bool getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) = 0; uint32_t getFlagsForPrimeHandleToFd() const; @@ -191,7 +191,7 @@ class IoctlHelperUpstream : public IoctlHelper { int getDrmParamValue(DrmParam drmParam) const override; std::string getDrmParamString(DrmParam param) const override; std::string getIoctlString(DrmIoctl ioctlRequest) const override; - bool getFabricLatency(uint32_t fabricId, uint32_t &latency) override; + bool getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) override; }; template @@ -258,7 +258,7 @@ class IoctlHelperPrelim20 : public IoctlHelper { std::string getDrmParamString(DrmParam param) const override; std::string getIoctlString(DrmIoctl ioctlRequest) const override; bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const override; - bool getFabricLatency(uint32_t fabricId, uint32_t &latency) override; + bool getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) override; }; } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index f7c0c771b1..87338d02f3 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -655,7 +655,7 @@ bool IoctlHelperPrelim20::checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctl return IoctlHelper::checkIfIoctlReinvokeRequired(error, ioctlRequest); } -bool IoctlHelperPrelim20::getFabricLatency(uint32_t fabricId, uint32_t &latency) { +bool IoctlHelperPrelim20::getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) { Query query = {}; QueryItem queryItem = {}; PrelimI915::prelim_drm_i915_query_fabric_info info = {}; @@ -673,13 +673,14 @@ bool IoctlHelperPrelim20::getFabricLatency(uint32_t fabricId, uint32_t &latency) return false; } - if (info.latency < 10) { + if (info.latency < 10 || info.bandwidth == 0) { return false; } // Latency is in tenths of path length. 10 == 1 fabric link between src and dst // 1 link = zero hops latency = (info.latency / 10) - 1; + bandwidth = info.bandwidth; return true; } diff --git a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp index fb5dc37365..e5c2de5f9b 100644 --- a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp @@ -236,7 +236,7 @@ std::string IoctlHelperUpstream::getIoctlString(DrmIoctl ioctlRequest) const { } } -bool IoctlHelperUpstream::getFabricLatency(uint32_t fabricId, uint32_t &latency) { +bool IoctlHelperUpstream::getFabricLatency(uint32_t fabricId, uint32_t &latency, uint32_t &bandwidth) { return false; } } // namespace NEO diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp index 4c255c95f4..66b651791d 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_prelim.cpp @@ -364,12 +364,14 @@ class DrmMockIoctl : public DrmMock { reinterpret_cast(queryItem->dataPtr); info->latency = mockLatency; + info->bandwidth = mockBandwidth; return mockIoctlReturn; } return 0; } int mockIoctlReturn = 0; uint32_t mockLatency = 10; + uint32_t mockBandwidth = 100; }; TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyThenSuccessIsReturned) { @@ -378,8 +380,10 @@ TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyThen std::unique_ptr drm = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]); IoctlHelperPrelim20 ioctlHelper{*drm}; - uint32_t latency = 0, fabricId = 0; - EXPECT_TRUE(ioctlHelper.getFabricLatency(fabricId, latency)); + uint32_t latency = std::numeric_limits::max(), fabricId = 0, bandwidth = 0; + EXPECT_TRUE(ioctlHelper.getFabricLatency(fabricId, latency, bandwidth)); + EXPECT_NE(latency, std::numeric_limits::max()); + EXPECT_NE(bandwidth, 0u); } TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyAndIoctlFailsThenErrorIsReturned) { @@ -388,9 +392,9 @@ TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyAndI std::unique_ptr drm = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]); IoctlHelperPrelim20 ioctlHelper{*drm}; - uint32_t latency = 0, fabricId = 0; + uint32_t latency = 0, fabricId = 0, bandwidth = 0; drm->mockIoctlReturn = 1; - EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency)); + EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency, bandwidth)); } TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyAndIoctlSetsZeroForLatencyThenErrorIsReturned) { @@ -399,8 +403,22 @@ TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyAndI std::unique_ptr drm = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]); IoctlHelperPrelim20 ioctlHelper{*drm}; - uint32_t latency = 0, fabricId = 0; + uint32_t latency = 0, fabricId = 0, bandwidth = 0; drm->mockIoctlReturn = 0; drm->mockLatency = 0; - EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency)); + drm->mockBandwidth = 10; + EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency, bandwidth)); +} + +TEST(IoctlPrelimHelperFabricLatencyTest, givenPrelimWhenGettingFabricLatencyAndIoctlSetsZeroForBandwidthThenErrorIsReturned) { + + MockExecutionEnvironment executionEnvironment{}; + std::unique_ptr drm = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]); + IoctlHelperPrelim20 ioctlHelper{*drm}; + + uint32_t latency = 0, fabricId = 0, bandwidth = 0; + drm->mockIoctlReturn = 0; + drm->mockLatency = 10; + drm->mockBandwidth = 0; + EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency, bandwidth)); } diff --git a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp index cb42ed405e..a0f556db22 100644 --- a/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp +++ b/shared/test/unit_test/os_interface/linux/ioctl_helper_tests_upstream.cpp @@ -482,6 +482,6 @@ TEST(IoctlHelperTestsUpstream, givenUpstreamWhenGettingFabricLatencyThenFalseIsR auto executionEnvironment = std::make_unique(); auto drm = std::make_unique(*executionEnvironment->rootDeviceEnvironments[0]); IoctlHelperUpstream ioctlHelper{*drm}; - uint32_t fabricId = 0, latency = 0; - EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency)); + uint32_t fabricId = 0, latency = 0, bandwidth = 0; + EXPECT_FALSE(ioctlHelper.getFabricLatency(fabricId, latency, bandwidth)); }