diff --git a/level_zero/tools/source/metrics/metric_ip_sampling_source.cpp b/level_zero/tools/source/metrics/metric_ip_sampling_source.cpp index 7626637e93..6bab728e72 100644 --- a/level_zero/tools/source/metrics/metric_ip_sampling_source.cpp +++ b/level_zero/tools/source/metrics/metric_ip_sampling_source.cpp @@ -81,8 +81,23 @@ ze_result_t IpSamplingMetricSourceImp::cacheMetricGroup() { subDeviceMetricGroup.push_back(static_cast(MetricGroup::fromHandle(hMetricGroup))); } - IpSamplingMetricSourceImp &source = deviceImp->getMetricDeviceContext().getMetricSource(); - cachedMetricGroup = MultiDeviceIpSamplingMetricGroupImp::create(source, subDeviceMetricGroup); + UNRECOVERABLE_IF(subDeviceMetricGroup.size() == 0); + IpSamplingMetricSourceImp &rootDevSource = deviceImp->getMetricDeviceContext().getMetricSource(); + uint32_t pCount = 0; + subDeviceMetricGroup[0]->metricGet(&pCount, nullptr); + std::vector hMetrics(pCount); + subDeviceMetricGroup[0]->metricGet(&pCount, hMetrics.data()); + std::vector metrics = {}; + + // Root device metrics must have the root device source + for (const auto &hMetric : hMetrics) { + zet_metric_properties_t metricProperties = {ZET_STRUCTURE_TYPE_METRIC_PROPERTIES, nullptr}; + Metric::fromHandle(hMetric)->getProperties(&metricProperties); + std::vector scopes{}; + metrics.push_back(IpSamplingMetricImp(rootDevSource, metricProperties, scopes)); + } + + cachedMetricGroup = MultiDeviceIpSamplingMetricGroupImp::create(rootDevSource, subDeviceMetricGroup, metrics); return ZE_RESULT_SUCCESS; } @@ -323,7 +338,8 @@ ze_result_t IpSamplingMetricGroupImp::getProperties(zet_metric_group_properties_ return ZE_RESULT_SUCCESS; } -ze_result_t IpSamplingMetricGroupImp::metricGet(uint32_t *pCount, zet_metric_handle_t *phMetrics) { +ze_result_t IpSamplingMetricGroupBase::metricGet(uint32_t *pCount, + zet_metric_handle_t *phMetrics) { if (*pCount == 0) { *pCount = static_cast(metrics.size()); @@ -421,10 +437,6 @@ ze_result_t MultiDeviceIpSamplingMetricGroupImp::getProperties(zet_metric_group_ return subDeviceMetricGroup[0]->getProperties(pProperties); } -ze_result_t MultiDeviceIpSamplingMetricGroupImp::metricGet(uint32_t *pCount, zet_metric_handle_t *phMetrics) { - return subDeviceMetricGroup[0]->metricGet(pCount, phMetrics); -} - ze_result_t MultiDeviceIpSamplingMetricGroupImp::calculateMetricValues(const zet_metric_group_calculation_type_t type, size_t rawDataSize, const uint8_t *pRawData, uint32_t *pMetricValueCount, zet_typed_value_t *pMetricValues) { @@ -507,9 +519,22 @@ ze_result_t MultiDeviceIpSamplingMetricGroupImp::getMetricTimestampsExp(const ze std::unique_ptr MultiDeviceIpSamplingMetricGroupImp::create( MetricSource &metricSource, - std::vector &subDeviceMetricGroup) { + std::vector &subDeviceMetricGroup, + std::vector &ipSamplingMetrics) { UNRECOVERABLE_IF(subDeviceMetricGroup.size() == 0); - return std::unique_ptr(new (std::nothrow) MultiDeviceIpSamplingMetricGroupImp(metricSource, subDeviceMetricGroup)); + UNRECOVERABLE_IF(ipSamplingMetrics.size() == 0); + return std::unique_ptr(new (std::nothrow) MultiDeviceIpSamplingMetricGroupImp( + metricSource, subDeviceMetricGroup, ipSamplingMetrics)); +} + +MultiDeviceIpSamplingMetricGroupImp::MultiDeviceIpSamplingMetricGroupImp( + MetricSource &metricSource, + std::vector &subDeviceMetricGroup, + std::vector &ipSamplingMetrics) : IpSamplingMetricGroupBase(metricSource), subDeviceMetricGroup(subDeviceMetricGroup) { + isMultiDevice = true; + for (auto &metric : ipSamplingMetrics) { + this->metrics.push_back(std::make_unique(metric)); + } } IpSamplingMetricImp::IpSamplingMetricImp(MetricSource &metricSource, zet_metric_properties_t &properties, std::vector &scopes) diff --git a/level_zero/tools/source/metrics/metric_ip_sampling_source.h b/level_zero/tools/source/metrics/metric_ip_sampling_source.h index 0e512d9187..08f14be3ea 100644 --- a/level_zero/tools/source/metrics/metric_ip_sampling_source.h +++ b/level_zero/tools/source/metrics/metric_ip_sampling_source.h @@ -83,9 +83,11 @@ class IpSamplingMetricSourceImp : public MetricSource { struct IpSamplingMetricGroupBase : public MetricGroupImp { IpSamplingMetricGroupBase(MetricSource &metricSource) : MetricGroupImp(metricSource) {} + ~IpSamplingMetricGroupBase() override = default; bool activate() override { return true; } bool deactivate() override { return true; }; + ze_result_t metricGet(uint32_t *pCount, zet_metric_handle_t *phMetrics) override; ze_result_t metricQueryPoolCreate( zet_context_handle_t hContext, zet_device_handle_t hDevice, @@ -106,6 +108,9 @@ struct IpSamplingMetricGroupBase : public MetricGroupImp { } IpSamplingMetricSourceImp &getMetricSource() { return static_cast(metricSource); } + + protected: + std::vector> metrics = {}; }; struct IpSamplingMetricGroupImp : public IpSamplingMetricGroupBase { @@ -113,7 +118,6 @@ struct IpSamplingMetricGroupImp : public IpSamplingMetricGroupBase { ~IpSamplingMetricGroupImp() override = default; ze_result_t getProperties(zet_metric_group_properties_t *pProperties) override; - ze_result_t metricGet(uint32_t *pCount, zet_metric_handle_t *phMetrics) override; ze_result_t calculateMetricValues(const zet_metric_group_calculation_type_t type, size_t rawDataSize, const uint8_t *pRawData, uint32_t *pMetricValueCount, zet_typed_value_t *pMetricValues) override; @@ -135,18 +139,17 @@ struct IpSamplingMetricGroupImp : public IpSamplingMetricGroupBase { std::vector &ipSamplingMetrics); private: - std::vector> metrics = {}; zet_metric_group_properties_t properties = {ZET_STRUCTURE_TYPE_METRIC_GROUP_PROPERTIES, nullptr}; }; struct MultiDeviceIpSamplingMetricGroupImp : public IpSamplingMetricGroupBase { - MultiDeviceIpSamplingMetricGroupImp(MetricSource &metricSource, std::vector &subDeviceMetricGroup) : IpSamplingMetricGroupBase(metricSource), subDeviceMetricGroup(subDeviceMetricGroup) { - isMultiDevice = true; - }; + MultiDeviceIpSamplingMetricGroupImp(MetricSource &metricSource, + std::vector &subDeviceMetricGroup, + std::vector &ipSamplingMetrics); ~MultiDeviceIpSamplingMetricGroupImp() override = default; + ze_result_t getProperties(zet_metric_group_properties_t *pProperties) override; - ze_result_t metricGet(uint32_t *pCount, zet_metric_handle_t *phMetrics) override; ze_result_t calculateMetricValues(const zet_metric_group_calculation_type_t type, size_t rawDataSize, const uint8_t *pRawData, uint32_t *pMetricValueCount, zet_typed_value_t *pMetricValues) override; @@ -164,7 +167,9 @@ struct MultiDeviceIpSamplingMetricGroupImp : public IpSamplingMetricGroupBase { zet_metric_streamer_desc_t *desc, ze_event_handle_t hNotificationEvent, zet_metric_streamer_handle_t *phMetricStreamer) override; - static std::unique_ptr create(MetricSource &metricSource, std::vector &subDeviceMetricGroup); + static std::unique_ptr create(MetricSource &metricSource, + std::vector &subDeviceMetricGroup, + std::vector &ipSamplingMetrics); private: void closeSubDeviceStreamers(std::vector &subDeviceStreamers); diff --git a/level_zero/tools/test/unit_tests/sources/metrics/metric_ip_sampling_fixture.h b/level_zero/tools/test/unit_tests/sources/metrics/metric_ip_sampling_fixture.h index 994d4f197f..2679155fb4 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/metric_ip_sampling_fixture.h +++ b/level_zero/tools/test/unit_tests/sources/metrics/metric_ip_sampling_fixture.h @@ -163,6 +163,24 @@ class MetricIpSamplingCalculateBaseFixture { {ZET_VALUE_TYPE_UINT64, {210}}, {ZET_VALUE_TYPE_UINT64, {210}}}; + // Expected values when calculating only odd index metrics from all raw reports in rawReports + std::vector expectedMetricValuesOddMetrics{ + {ZET_VALUE_TYPE_UINT64, {11}}, + {ZET_VALUE_TYPE_UINT64, {11}}, + {ZET_VALUE_TYPE_UINT64, {11}}, + {ZET_VALUE_TYPE_UINT64, {11}}, + {ZET_VALUE_TYPE_UINT64, {11}}, + {ZET_VALUE_TYPE_UINT64, {110}}, + {ZET_VALUE_TYPE_UINT64, {110}}, + {ZET_VALUE_TYPE_UINT64, {110}}, + {ZET_VALUE_TYPE_UINT64, {110}}, + {ZET_VALUE_TYPE_UINT64, {110}}, + {ZET_VALUE_TYPE_UINT64, {210}}, + {ZET_VALUE_TYPE_UINT64, {210}}, + {ZET_VALUE_TYPE_UINT64, {210}}, + {ZET_VALUE_TYPE_UINT64, {210}}, + {ZET_VALUE_TYPE_UINT64, {210}}}; + std::vector rawDataElementsOverflow = { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1000, 0x01}, {1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1000, 0x02}, diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_streamer_1.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_streamer_1.cpp index ebac4740d9..f2e2fe880e 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_streamer_1.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_streamer_1.cpp @@ -1010,12 +1010,12 @@ HWTEST2_F(MetricIpSamplingCalcOpMultiDevTest, WhenReadingMetricGroupTimeCalculat metricGroupCalcProps.pNext = nullptr; metricGroupCalcProps.isTimeFilterSupported = true; - zet_metric_group_properties_t properties{}; - properties.pNext = &metricGroupCalcProps; + zet_metric_group_properties_t metricGroupProperties = {ZET_STRUCTURE_TYPE_METRIC_GROUP_PROPERTIES, nullptr}; + metricGroupProperties.pNext = &metricGroupCalcProps; - EXPECT_EQ(zetMetricGroupGetProperties(metricGroups[0], &properties), ZE_RESULT_SUCCESS); - EXPECT_EQ(strcmp(properties.description, "EU stall sampling"), 0); - EXPECT_EQ(strcmp(properties.name, "EuStallSampling"), 0); + EXPECT_EQ(zetMetricGroupGetProperties(metricGroups[0], &metricGroupProperties), ZE_RESULT_SUCCESS); + EXPECT_EQ(strcmp(metricGroupProperties.description, "EU stall sampling"), 0); + EXPECT_EQ(strcmp(metricGroupProperties.name, "EuStallSampling"), 0); EXPECT_EQ(metricGroupCalcProps.isTimeFilterSupported, false); } } @@ -1229,5 +1229,103 @@ HWTEST2_F(MetricIpSamplingCalcOpMultiDevTest, GivenMultipleScopesWhenAllAreUnsup delete mockMetricScope3; } +HWTEST2_F(MetricIpSamplingCalcOpMultiDevTest, GivenRootDeviceCreatingCalcOpWithOnlyMetricsHandlesOnlyThoseMetricsAreInResultReport, EustallSupportedPlatforms) { + + EXPECT_EQ(ZE_RESULT_SUCCESS, testDevices[0]->getMetricDeviceContext().enableMetricApi()); + auto rootDevice = testDevices[0]; + + uint32_t metricGroupCount = 1; + zet_metric_group_handle_t metricGroupHandle = nullptr; + + ASSERT_EQ(zetMetricGroupGet(rootDevice->toHandle(), &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + ASSERT_NE(metricGroupHandle, nullptr); + + uint32_t metricCount = 0; + EXPECT_EQ(zetMetricGet(metricGroupHandle, &metricCount, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricCount, 10u); + std::vector phMetrics(metricCount); + EXPECT_EQ(zetMetricGet(metricGroupHandle, &metricCount, phMetrics.data()), ZE_RESULT_SUCCESS); + + std::vector metricsToCalculate; + + // Select only odd index metrics. According to expectedMetricNamesInReport there are: + // "Active", "PipeStall" "DistStall", "SyncStall", "OtherStall" + for (uint32_t i = 0; i < metricCount; i++) { + if (i % 2) { + metricsToCalculate.push_back(phMetrics[i]); + } + } + + uint32_t metricsToCalculateCount = static_cast(metricsToCalculate.size()); + EXPECT_EQ(metricsToCalculateCount, 5u); + + calculationDesc.metricGroupCount = 0; + calculationDesc.phMetricGroups = nullptr; + calculationDesc.metricCount = metricsToCalculateCount; + calculationDesc.phMetrics = metricsToCalculate.data(); + + zet_intel_metric_calculation_operation_exp_handle_t hCalculationOperation; + + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricCalculationOperationCreateExp(context->toHandle(), + rootDevice->toHandle(), &calculationDesc, + &hCalculationOperation)); + uint32_t metricsInReportCount = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricCalculationOperationGetReportFormatExp(hCalculationOperation, &metricsInReportCount, nullptr, nullptr)); + EXPECT_EQ(metricsInReportCount, 5u); + std::vector metricsInReport(metricsInReportCount); + std::vector metricScopesInReport(metricsInReportCount); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricCalculationOperationGetReportFormatExp(hCalculationOperation, &metricsInReportCount, + metricsInReport.data(), metricScopesInReport.data())); + + EXPECT_EQ(metricsInReportCount, 5u); + // Expect only odd index metrics in the result report + zet_metric_properties_t ipSamplingMetricProperties = {}; + for (uint32_t i = 0; i < metricsInReportCount; i++) { + EXPECT_EQ(ZE_RESULT_SUCCESS, zetMetricGetProperties(metricsInReport[i], &ipSamplingMetricProperties)); + EXPECT_EQ(strcmp(ipSamplingMetricProperties.name, expectedMetricNamesInReport[i * 2 + 1].c_str()), 0); + EXPECT_EQ(static_cast(MetricScope::fromHandle(metricScopesInReport[i])), hMockScope); + } + + // Raw data for a single read with different data for sub-device 0 and 1 + size_t rawDataSize = sizeof(IpSamplingMultiDevDataHeader) + rawReportsBytesSize + sizeof(IpSamplingMultiDevDataHeader) + rawReportsBytesSize; + std::vector rawDataWithHeader(rawDataSize); + // sub device index 0 + MockRawDataHelper::addMultiSubDevHeader(rawDataWithHeader.data(), rawDataWithHeader.size(), reinterpret_cast(rawReports.data()), rawReportsBytesSize, 0); + // sub device index 1 + MockRawDataHelper::addMultiSubDevHeader(rawDataWithHeader.data() + rawReportsBytesSize + sizeof(IpSamplingMultiDevDataHeader), + rawDataWithHeader.size() - (rawReportsBytesSize + sizeof(IpSamplingMultiDevDataHeader)), + reinterpret_cast(rawReports.data()), rawReportsBytesSize, 1); + + uint32_t totalMetricReportCount = 0; + bool final = true; + size_t usedSize = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricCalculateValuesExp(rawDataSize, reinterpret_cast(rawDataWithHeader.data()), + hCalculationOperation, + final, &usedSize, + &totalMetricReportCount, nullptr)); + + EXPECT_EQ(totalMetricReportCount, 3U); // three IPs in rawReports + EXPECT_EQ(usedSize, 0U); // query only, no data processed + + std::vector metricResults(totalMetricReportCount * metricsInReportCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricCalculateValuesExp(rawDataSize, reinterpret_cast(rawDataWithHeader.data()), + hCalculationOperation, + final, &usedSize, + &totalMetricReportCount, metricResults.data())); + EXPECT_EQ(totalMetricReportCount, 3U); + EXPECT_EQ(usedSize, rawDataSize); + + for (uint32_t i = 0; i < totalMetricReportCount; i++) { + for (uint32_t j = 0; j < metricsInReportCount; j++) { + uint32_t resultIndex = i * metricsInReportCount + j; + EXPECT_TRUE(metricResults[resultIndex].value.ui64 == expectedMetricValuesOddMetrics[resultIndex].value.ui64); + } + } + + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricCalculationOperationDestroyExp(hCalculationOperation)); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_streamer_2.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_streamer_2.cpp index 6086bc48e1..68fc4720d0 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_streamer_2.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_streamer_2.cpp @@ -116,7 +116,7 @@ HWTEST2_F(MetricIpSamplingCalcOpSingleDeviceTest, GivenIpSamplingCalcOpCallingMe EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricCalculationOperationDestroyExp(hCalculationOperation)); } -HWTEST2_F(MetricIpSamplingCalcOpSingleDeviceTest, GivenIpSamplingCalcOpCallingMetricCalculateValuesOnSubDeviceFilterMetricsInReport, EustallSupportedPlatforms) { +HWTEST2_F(MetricIpSamplingCalcOpSingleDeviceTest, GivenSubDeviceCreatingCalcOpWithOnlyMetricsHandlesOnlyThoseMetricsAreInresultReport, EustallSupportedPlatforms) { uint32_t metricCount = 0; EXPECT_EQ(zetMetricGet(metricGroupHandle, &metricCount, nullptr), ZE_RESULT_SUCCESS);