From d5dcdc169b0348b1910493b775c5b1469a0d0683 Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Tue, 16 Jul 2024 08:12:19 +0000 Subject: [PATCH] feature: add support for querying simd16 eu per dss Related-To: NEO-12012 Signed-off-by: Mateusz Jablonski --- .../os_interface/linux/xe/ioctl_helper_xe.cpp | 12 +++- .../linux/xe/ioctl_helper_xe_tests.cpp | 55 +++++++++++++++++++ third_party/uapi/xe/.version | 1 + third_party/uapi/xe/xe_drm.h | 10 +++- 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 third_party/uapi/xe/.version diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp index d3b508d9c28d8..78e9911214aa0 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -464,6 +464,7 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo StackVec>, 2> geomDss; StackVec>, 2> computeDss; StackVec>, 2> euDss; + StackVec>, 2> simd16EuDss; auto topologySize = queryGtTopology.size(); auto dataPtr = queryGtTopology.data(); @@ -472,8 +473,10 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo geomDss.resize(numTiles); computeDss.resize(numTiles); euDss.resize(numTiles); + simd16EuDss.resize(numTiles); bool receivedDssInfo = false; bool receivedEuPerDssInfo = false; + bool receivedSimd16EuPerDssInfo = false; while (topologySize >= sizeof(drm_xe_query_topology_mask)) { drm_xe_query_topology_mask *topo = reinterpret_cast(dataPtr); UNRECOVERABLE_IF(topo == nullptr); @@ -495,6 +498,10 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo fillMask(euDss[tileId], topo); receivedEuPerDssInfo = true; break; + case DRM_XE_TOPO_SIMD16_EU_PER_DSS: + fillMask(simd16EuDss[tileId], topo); + receivedSimd16EuPerDssInfo = true; + break; default: xeLog("Unhandle GT Topo type: %d\n", topo->type); } @@ -504,9 +511,10 @@ bool IoctlHelperXe::getTopologyDataAndMap(const HardwareInfo &hwInfo, DrmQueryTo topologySize -= itemSize; dataPtr = ptrOffset(dataPtr, itemSize); } - + receivedEuPerDssInfo |= receivedSimd16EuPerDssInfo; bool isComputeDssEmpty = false; - getTopologyData(numTiles, geomDss.begin(), computeDss.begin(), euDss.begin(), topologyData, isComputeDssEmpty); + std::vector> *euDssVector = receivedSimd16EuPerDssInfo ? simd16EuDss.begin() : euDss.begin(); + getTopologyData(numTiles, geomDss.begin(), computeDss.begin(), euDssVector, topologyData, isComputeDssEmpty); auto &dssInfo = isComputeDssEmpty ? geomDss : computeDss; getTopologyMap(numTiles, dssInfo.begin(), topologyMap); diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp index 0ac8c503e8d63..24f9f7e2573f6 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.cpp @@ -835,6 +835,61 @@ TEST(IoctlHelperXeTest, givenComputeDssWhenGetTopologyDataAndMapThenResultsAreCo } } +TEST(IoctlHelperXeTest, givenSimd16EuPerDssAndEuPerDssWhenGetTopologyDataAndMapThenPreferSimd16EuPerDss) { + + auto executionEnvironment = std::make_unique(); + auto drm = DrmMockXe::create(*executionEnvironment->rootDeviceEnvironments[0]); + auto xeIoctlHelper = static_cast(drm->getIoctlHelper()); + auto &hwInfo = *executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(); + xeIoctlHelper->initialize(); + + uint16_t tileId = 0; + for (auto gtId = 0u; gtId < 4u; gtId++) { + drm->addMockedQueryTopologyData(gtId, DRM_XE_TOPO_DSS_GEOMETRY, 8, {0, 0, 0, 0, 0, 0, 0, 0}); + drm->addMockedQueryTopologyData(gtId, DRM_XE_TOPO_DSS_COMPUTE, 8, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}); + drm->addMockedQueryTopologyData(gtId, DRM_XE_TOPO_EU_PER_DSS, 8, {0b1111'1111, 0, 0, 0, 0, 0, 0, 0}); + drm->addMockedQueryTopologyData(gtId, DRM_XE_TOPO_SIMD16_EU_PER_DSS, 8, {0b1111, 0, 0, 0, 0, 0, 0, 0}); + } + + DrmQueryTopologyData topologyData{}; + TopologyMap topologyMap{}; + + auto result = xeIoctlHelper->getTopologyDataAndMap(hwInfo, topologyData, topologyMap); + ASSERT_TRUE(result); + + // verify topology data + EXPECT_EQ(1, topologyData.sliceCount); + EXPECT_EQ(1, topologyData.maxSliceCount); + + EXPECT_EQ(64, topologyData.subSliceCount); + EXPECT_EQ(64, topologyData.maxSubSliceCount); + + EXPECT_EQ(256, topologyData.euCount); + EXPECT_EQ(4, topologyData.maxEuPerSubSlice); + + // verify topology map + std::vector expectedSliceIndices = {0}; + ASSERT_EQ(expectedSliceIndices.size(), topologyMap[tileId].sliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].sliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSliceIndices.size(); i++) { + EXPECT_EQ(expectedSliceIndices[i], topologyMap[tileId].sliceIndices[i]); + } + + std::vector expectedSubSliceIndices; + expectedSubSliceIndices.reserve(64u); + for (auto i = 0u; i < 64; i++) { + expectedSubSliceIndices.emplace_back(i); + } + + ASSERT_EQ(expectedSubSliceIndices.size(), topologyMap[tileId].subsliceIndices.size()); + ASSERT_TRUE(topologyMap[tileId].subsliceIndices.size() > 0); + + for (auto i = 0u; i < expectedSubSliceIndices.size(); i++) { + EXPECT_EQ(expectedSubSliceIndices[i], topologyMap[tileId].subsliceIndices[i]); + } +} + TEST(IoctlHelperXeTest, givenOnlyMediaTypeWhenGetTopologyDataAndMapThenSubsliceIndicesNotSet) { auto executionEnvironment = std::make_unique(); diff --git a/third_party/uapi/xe/.version b/third_party/uapi/xe/.version new file mode 100644 index 0000000000000..db7f727deafee --- /dev/null +++ b/third_party/uapi/xe/.version @@ -0,0 +1 @@ +patch: https://lore.kernel.org/intel-xe/20240710220446.2169797-1-lucas.demarchi@intel.com/ diff --git a/third_party/uapi/xe/xe_drm.h b/third_party/uapi/xe/xe_drm.h index 6c98c3dfa8909..e9126c5afa6a5 100644 --- a/third_party/uapi/xe/xe_drm.h +++ b/third_party/uapi/xe/xe_drm.h @@ -504,7 +504,14 @@ struct drm_xe_query_gt_list { * available per Dual Sub Slices (DSS). For example a query response * containing the following in mask: * ``EU_PER_DSS ff ff 00 00 00 00 00 00`` - * means each DSS has 16 EU. + * means each DSS has 16 SIMD8 EUs. This type may be omitted if device + * doesn't have SIMD8 EUs. + * - %DRM_XE_TOPO_SIMD16_EU_PER_DSS - To query the mask of SIMD16 Execution + * Units (EU) available per Dual Sub Slices (DSS). For example a query + * response containing the following in mask: + * ``SIMD16_EU_PER_DSS ff ff 00 00 00 00 00 00`` + * means each DSS has 16 SIMD16 EUs. This type may be omitted if device + * doesn't have SIMD16 EUs. */ struct drm_xe_query_topology_mask { /** @gt_id: GT ID the mask is associated with */ @@ -513,6 +520,7 @@ struct drm_xe_query_topology_mask { #define DRM_XE_TOPO_DSS_GEOMETRY (1 << 0) #define DRM_XE_TOPO_DSS_COMPUTE (1 << 1) #define DRM_XE_TOPO_EU_PER_DSS (1 << 2) +#define DRM_XE_TOPO_SIMD16_EU_PER_DSS 5 /** @type: type of mask */ __u16 type;