diff --git a/level_zero/tools/source/metrics/metric_oa_enumeration_imp.cpp b/level_zero/tools/source/metrics/metric_oa_enumeration_imp.cpp index 8d10b0bc2e..1b81b90e37 100644 --- a/level_zero/tools/source/metrics/metric_oa_enumeration_imp.cpp +++ b/level_zero/tools/source/metrics/metric_oa_enumeration_imp.cpp @@ -669,11 +669,11 @@ ze_result_t OaMetricGroupImp::calculateMetricValues(const zet_metric_group_calcu } const bool calculateCountOnly = *pMetricValueCount == 0; - const bool result = calculateCountOnly - ? getCalculatedMetricCount(rawDataSize, *pMetricValueCount) - : getCalculatedMetricValues(type, rawDataSize, pRawData, *pMetricValueCount, pMetricValues); + const ze_result_t result = calculateCountOnly + ? getCalculatedMetricCount(rawDataSize, *pMetricValueCount) + : getCalculatedMetricValues(type, rawDataSize, pRawData, *pMetricValueCount, pMetricValues); - return result ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN; + return result; } ze_result_t OaMetricGroupImp::calculateMetricValuesExp(const zet_metric_group_calculation_type_t type, size_t rawDataSize, @@ -681,12 +681,13 @@ ze_result_t OaMetricGroupImp::calculateMetricValuesExp(const zet_metric_group_ca uint32_t *pTotalMetricValueCount, uint32_t *pMetricCounts, zet_typed_value_t *pMetricValues) { + ze_result_t result = ZE_RESULT_SUCCESS; const MetricGroupCalculateHeader *pRawHeader = reinterpret_cast(pRawData); if (pRawHeader->magic != MetricGroupCalculateHeader::magicValue) { const bool calculationCountOnly = *pTotalMetricValueCount == 0; - ze_result_t result = calculateMetricValues(type, rawDataSize, pRawData, pTotalMetricValueCount, pMetricValues); + result = calculateMetricValues(type, rawDataSize, pRawData, pTotalMetricValueCount, pMetricValues); if (result == ZE_RESULT_SUCCESS) { *pSetCount = 1; @@ -704,7 +705,6 @@ ze_result_t OaMetricGroupImp::calculateMetricValuesExp(const zet_metric_group_ca return result; } - bool result = true; const size_t metricGroupCount = metricGroups.size(); if (*pSetCount == 0 || *pTotalMetricValueCount == 0) { @@ -713,13 +713,9 @@ ze_result_t OaMetricGroupImp::calculateMetricValuesExp(const zet_metric_group_ca if (metricGroupCount == 0) { result = getCalculatedMetricCount(*pRawDataSizesUnpacked, *pTotalMetricValueCount); - - if (result) { - *pSetCount = 1; - } else { - *pSetCount = 0; - *pTotalMetricValueCount = 0; - } + *pSetCount = result == ZE_RESULT_SUCCESS + ? 1 + : 0; } else { *pSetCount = static_cast(metricGroupCount); *pTotalMetricValueCount = 0; @@ -729,7 +725,9 @@ ze_result_t OaMetricGroupImp::calculateMetricValuesExp(const zet_metric_group_ca auto &metricGroup = *static_cast(metricGroups[i]); result = metricGroup.getCalculatedMetricCount(pRawDataSizesUnpacked[i], metricCount); - if (!result) { + if (result == ZE_RESULT_NOT_READY) { + continue; + } else if (result != ZE_RESULT_SUCCESS) { *pSetCount = 0; *pTotalMetricValueCount = 0; break; @@ -737,6 +735,15 @@ ze_result_t OaMetricGroupImp::calculateMetricValuesExp(const zet_metric_group_ca *pTotalMetricValueCount += metricCount; } + + if (result == ZE_RESULT_NOT_READY) { + if (*pTotalMetricValueCount == 0) { + result = ZE_RESULT_ERROR_INVALID_SIZE; + *pSetCount = 0; + } else { + result = ZE_RESULT_SUCCESS; + } + } } } else { @@ -756,55 +763,77 @@ ze_result_t OaMetricGroupImp::calculateMetricValuesExp(const zet_metric_group_ca auto &metricGroup = *static_cast(metricGroups[i]); const uint32_t dataSize = pRawDataSizesUnpacked[i]; const uint8_t *pRawDataOffset = pRawDataOffsetUnpacked + pRawDataOffsetsUnpacked[i]; + pMetricCounts[i] = maxTotalMetricValueCount; result = metricGroup.getCalculatedMetricValues(type, dataSize, pRawDataOffset, pMetricCounts[i], pMetricValues); - if (!result) { - for (size_t j = 0; j <= i; j++) { + if (result == ZE_RESULT_NOT_READY) { + pMetricCounts[i] = 0; + continue; + } else if (result != ZE_RESULT_SUCCESS) { + for (size_t j = 0; j < *pSetCount; j++) { pMetricCounts[j] = 0; } + *pTotalMetricValueCount = 0; break; } *pTotalMetricValueCount += pMetricCounts[i]; pMetricValues += pMetricCounts[i]; } + + if (result == ZE_RESULT_NOT_READY) { + if (*pTotalMetricValueCount == 0) { + result = ZE_RESULT_ERROR_INVALID_SIZE; + for (size_t i = 0; i < *pSetCount; i++) { + pMetricCounts[i] = 0; + } + *pSetCount = 0; + } else { + result = ZE_RESULT_SUCCESS; + } + } } } - return result ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN; + return result; } -bool OaMetricGroupImp::getCalculatedMetricCount(const size_t rawDataSize, - uint32_t &metricValueCount) { - uint32_t rawReportSize = getRawReportSize(); +ze_result_t OaMetricGroupImp::getCalculatedMetricCount(const size_t rawDataSize, + uint32_t &metricValueCount) { + metricValueCount = 0; - if (rawReportSize == 0) { - return false; + if (rawDataSize == 0) { + return ZE_RESULT_NOT_READY; } - if ((rawDataSize % rawReportSize) != 0) { - return false; + const uint32_t rawReportSize = getRawReportSize(); + + if (rawReportSize == 0 || + (rawDataSize % rawReportSize) != 0) { + return ZE_RESULT_ERROR_INVALID_SIZE; } const uint32_t rawReportCount = static_cast(rawDataSize) / rawReportSize; metricValueCount = rawReportCount * properties.metricCount; - return true; + + return ZE_RESULT_SUCCESS; } -bool OaMetricGroupImp::getCalculatedMetricValues(const zet_metric_group_calculation_type_t type, const size_t rawDataSize, const uint8_t *pRawData, - uint32_t &metricValueCount, - zet_typed_value_t *pCalculatedData) { +ze_result_t OaMetricGroupImp::getCalculatedMetricValues(const zet_metric_group_calculation_type_t type, const size_t rawDataSize, const uint8_t *pRawData, + uint32_t &metricValueCount, + zet_typed_value_t *pCalculatedData) { uint32_t calculatedReportCount = 0; uint32_t expectedMetricValueCount = 0; if (pCalculatedData == nullptr) { - return false; + return ZE_RESULT_ERROR_INVALID_ARGUMENT; } - if (getCalculatedMetricCount(rawDataSize, expectedMetricValueCount) == false) { - return false; + ze_result_t result = getCalculatedMetricCount(rawDataSize, expectedMetricValueCount); + if (result != ZE_RESULT_SUCCESS) { + return result; } // Calculated metrics / maximum values container. @@ -816,13 +845,15 @@ bool OaMetricGroupImp::getCalculatedMetricValues(const zet_metric_group_calculat // Calculate metrics. const uint32_t outMetricsSize = static_cast(calculatedMetrics.size()) * sizeof(MetricsDiscovery::TTypedValue_1_0); - bool result = pReferenceMetricSet->CalculateMetrics( - reinterpret_cast(const_cast(pRawData)), static_cast(rawDataSize), - calculatedMetrics.data(), - outMetricsSize, - &calculatedReportCount, maximumValues.data(), outMetricsSize) == MetricsDiscovery::CC_OK; + result = pReferenceMetricSet->CalculateMetrics( + reinterpret_cast(const_cast(pRawData)), static_cast(rawDataSize), + calculatedMetrics.data(), + outMetricsSize, + &calculatedReportCount, maximumValues.data(), outMetricsSize) == MetricsDiscovery::CC_OK + ? ZE_RESULT_SUCCESS + : ZE_RESULT_ERROR_UNKNOWN; - if (result) { + if (result == ZE_RESULT_SUCCESS) { // Adjust copied reports to buffer provided by the user. metricValueCount = std::min(metricValueCount, calculatedReportCount * properties.metricCount); @@ -842,7 +873,7 @@ bool OaMetricGroupImp::getCalculatedMetricValues(const zet_metric_group_calculat break; default: - result = false; + result = ZE_RESULT_ERROR_UNKNOWN; break; } } diff --git a/level_zero/tools/source/metrics/metric_oa_enumeration_imp.h b/level_zero/tools/source/metrics/metric_oa_enumeration_imp.h index 8e513c8781..7bfdc4a0ae 100644 --- a/level_zero/tools/source/metrics/metric_oa_enumeration_imp.h +++ b/level_zero/tools/source/metrics/metric_oa_enumeration_imp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -133,12 +133,12 @@ struct OaMetricGroupImp : MetricGroup { void copyValue(const MetricsDiscovery::TTypedValue_1_0 &source, zet_typed_value_t &destination) const; - bool getCalculatedMetricCount(const size_t rawDataSize, - uint32_t &metricValueCount); + ze_result_t getCalculatedMetricCount(const size_t rawDataSize, + uint32_t &metricValueCount); - bool getCalculatedMetricValues(const zet_metric_group_calculation_type_t, const size_t rawDataSize, const uint8_t *pRawData, - uint32_t &metricValueCount, - zet_typed_value_t *pCalculatedData); + ze_result_t getCalculatedMetricValues(const zet_metric_group_calculation_type_t, const size_t rawDataSize, const uint8_t *pRawData, + uint32_t &metricValueCount, + zet_typed_value_t *pCalculatedData); // Cached metrics. std::vector metrics; diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_enumeration_1.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_enumeration_1.cpp index 5a42a77e6c..0ee94376b4 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_enumeration_1.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_enumeration_1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -1695,12 +1695,12 @@ TEST_F(MetricEnumerationTest, givenIncorrectRawReportSizeWhenZetMetricGroupCalcu // Invalid raw buffer size provided by the user. uint32_t calculatedResults = 0; EXPECT_NE(metricsSetParams.QueryReportSize, rawResultsSize); - EXPECT_EQ(zetMetricGroupCalculateMetricValues(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &calculatedResults, nullptr), ZE_RESULT_ERROR_UNKNOWN); + EXPECT_EQ(zetMetricGroupCalculateMetricValues(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &calculatedResults, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); // Invalid raw buffer size provided by the driver. metricsSetParams.QueryReportSize = 0; EXPECT_NE(metricsSetParams.QueryReportSize, rawResultsSize); - EXPECT_EQ(zetMetricGroupCalculateMetricValues(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &calculatedResults, nullptr), ZE_RESULT_ERROR_UNKNOWN); + EXPECT_EQ(zetMetricGroupCalculateMetricValues(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &calculatedResults, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); } TEST_F(MetricEnumerationTest, givenIncorrectRawReportSizeWhenZetMetricGroupCalculateMetricValuesExpIsCalledThenReturnsFail) { @@ -1760,13 +1760,13 @@ TEST_F(MetricEnumerationTest, givenIncorrectRawReportSizeWhenZetMetricGroupCalcu uint32_t dataCount = 0; uint32_t totalMetricCount = 0; EXPECT_NE(metricsSetParams.QueryReportSize, rawResultsSize); - EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_UNKNOWN); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); EXPECT_EQ(dataCount, 0u); EXPECT_EQ(totalMetricCount, 0u); // Invalid raw buffer size provided by the driver. EXPECT_NE(metricsSetParams.QueryReportSize, rawResultsSize); - EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_UNKNOWN); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); EXPECT_EQ(dataCount, 0u); EXPECT_EQ(totalMetricCount, 0u); } @@ -2003,7 +2003,7 @@ TEST_F(MetricEnumerationTest, givenInvalidQueryReportSizeWhenZetMetricGroupCalcu // Invalid raw buffer size provided by the driver. uint32_t dataCount = 0; uint32_t totalMetricCount = 0; - EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_UNKNOWN); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); EXPECT_EQ(dataCount, 0u); EXPECT_EQ(totalMetricCount, 0u); } diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_enumeration_2.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_enumeration_2.cpp index 9c5f90ad29..490ebfa186 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_enumeration_2.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_enumeration_2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Intel Corporation + * Copyright (C) 2021-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -729,7 +729,7 @@ TEST_F(MetricEnumerationMultiDeviceTest, givenInvalidQueryReportSizeWhenZetMetri uint32_t dataCount = 0; uint32_t totalMetricCount = 0; EXPECT_NE(metricsSetParams.QueryReportSize, rawResultsSize); - EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_UNKNOWN); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); EXPECT_EQ(dataCount, 0u); EXPECT_EQ(totalMetricCount, 0u); } @@ -915,5 +915,496 @@ TEST_F(MetricEnumerationMultiDeviceTest, givenCorrectRawDataHeaderWhenZetMetricG EXPECT_EQ(metricCount, 0u); } +TEST_F(MetricEnumerationMultiDeviceTest, givenCorrectRawDataHeaderWhenFirstSubDeviceHasNoReportsToCalculateThenZetMetricGroupCalculateMetricValuesExpReturnsPartialDataForSecondSubDeviceAndReturnsSuccess) { + + auto &deviceImp = *static_cast(devices[0]); + const uint32_t subDeviceCount = static_cast(deviceImp.subDevices.size()); + + metricsDeviceParams.ConcurrentGroupsCount = 1; + + Mock metricsConcurrentGroup; + TConcurrentGroupParams_1_0 metricsConcurrentGroupParams = {}; + metricsConcurrentGroupParams.MetricSetsCount = 1; + metricsConcurrentGroupParams.SymbolName = "OA"; + + Mock metricsSet; + MetricsDiscovery::TMetricSetParams_1_4 metricsSetParams = {}; + metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_IOSTREAM; + metricsSetParams.RawReportSize = 256; + metricsSetParams.MetricsCount = 11; + + Mock metric; + MetricsDiscovery::TMetricParams_1_0 metricParams = {}; + + zet_metric_group_handle_t metricGroupHandle = {}; + + uint32_t returnedMetricCount = 2; + + openMetricsAdapter(); + + EXPECT_CALL(metricsDevice, GetParams()) + .WillRepeatedly(Return(&metricsDeviceParams)); + + EXPECT_CALL(metricsDevice, GetConcurrentGroup(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroup)); + + EXPECT_CALL(metricsConcurrentGroup, GetParams()) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroupParams)); + + EXPECT_CALL(metricsConcurrentGroup, GetMetricSet(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsSet)); + + EXPECT_CALL(metricsSet, GetParams()) + .WillRepeatedly(Return(&metricsSetParams)); + + EXPECT_CALL(metricsSet, GetMetric(_)) + .Times(metricsSetParams.MetricsCount * subDeviceCount) + .WillRepeatedly(Return(&metric)); + + EXPECT_CALL(metricsSet, SetApiFiltering(_)) + .WillRepeatedly(Return(TCompletionCode::CC_OK)); + + EXPECT_CALL(metric, GetParams()) + .WillRepeatedly(Return(&metricParams)); + + EXPECT_CALL(metricsSet, CalculateMetrics(_, _, _, _, _, _, _)) + .Times(subDeviceCount - 1) + .WillRepeatedly(DoAll(::testing::SetArgPointee<4>(returnedMetricCount), Return(TCompletionCode::CC_OK))); + + // Metric group handles. + uint32_t metricGroupCount = 1; + EXPECT_EQ(zetMetricGroupGet(devices[0]->toHandle(), &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + EXPECT_NE(metricGroupHandle, nullptr); + + // Raw results. + constexpr size_t rawResultsSize = 512; // metricsSetParams.RawReportSize * returnedMetricCount + uint8_t rawResults[rawResultsSize] = {}; + MetricGroupCalculateHeader *pRawHeader = reinterpret_cast(rawResults); + + pRawHeader->magic = MetricGroupCalculateHeader::magicValue; + pRawHeader->dataCount = subDeviceCount; + pRawHeader->rawDataOffsets = sizeof(MetricGroupCalculateHeader); + pRawHeader->rawDataSizes = pRawHeader->rawDataOffsets + sizeof(uint32_t) * pRawHeader->dataCount; + pRawHeader->rawDataOffset = pRawHeader->rawDataSizes + sizeof(uint32_t) * pRawHeader->dataCount; + + // Sub device 0 has 0 reports to calculate. + uint32_t *pRawDataOffsets = reinterpret_cast(rawResults + pRawHeader->rawDataOffsets); + uint32_t *pRawDataSizes = reinterpret_cast(rawResults + pRawHeader->rawDataSizes); + pRawDataOffsets[0] = 0; + pRawDataOffsets[1] = 0; + pRawDataSizes[0] = 0; + pRawDataSizes[1] = metricsSetParams.RawReportSize * returnedMetricCount; + + // Valid raw buffer. + uint32_t dataCount = 0; + uint32_t totalMetricCount = 0; + EXPECT_NE(metricsSetParams.RawReportSize, rawResultsSize); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(dataCount, subDeviceCount); + EXPECT_EQ(totalMetricCount, returnedMetricCount * metricsSetParams.MetricsCount); + + // Copy calculated metrics. + std::vector metricCounts(dataCount); + std::vector caculatedRawResults(totalMetricCount); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, metricCounts.data(), caculatedRawResults.data()), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricCounts[0], 0u); + EXPECT_EQ(metricCounts[1], returnedMetricCount * metricsSetParams.MetricsCount); +} + +TEST_F(MetricEnumerationMultiDeviceTest, givenCorrectRawDataHeaderWhenSecondSubDeviceHasNoReportsToCalculateThenZetMetricGroupCalculateMetricValuesExpReturnsPartialDataForFirstSubDeviceAndReturnsSuccess) { + + auto &deviceImp = *static_cast(devices[0]); + const uint32_t subDeviceCount = static_cast(deviceImp.subDevices.size()); + + metricsDeviceParams.ConcurrentGroupsCount = 1; + + Mock metricsConcurrentGroup; + TConcurrentGroupParams_1_0 metricsConcurrentGroupParams = {}; + metricsConcurrentGroupParams.MetricSetsCount = 1; + metricsConcurrentGroupParams.SymbolName = "OA"; + + Mock metricsSet; + MetricsDiscovery::TMetricSetParams_1_4 metricsSetParams = {}; + metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_IOSTREAM; + metricsSetParams.RawReportSize = 256; + metricsSetParams.MetricsCount = 11; + + Mock metric; + MetricsDiscovery::TMetricParams_1_0 metricParams = {}; + + zet_metric_group_handle_t metricGroupHandle = {}; + + uint32_t returnedMetricCount = 2; + + openMetricsAdapter(); + + EXPECT_CALL(metricsDevice, GetParams()) + .WillRepeatedly(Return(&metricsDeviceParams)); + + EXPECT_CALL(metricsDevice, GetConcurrentGroup(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroup)); + + EXPECT_CALL(metricsConcurrentGroup, GetParams()) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroupParams)); + + EXPECT_CALL(metricsConcurrentGroup, GetMetricSet(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsSet)); + + EXPECT_CALL(metricsSet, GetParams()) + .WillRepeatedly(Return(&metricsSetParams)); + + EXPECT_CALL(metricsSet, GetMetric(_)) + .Times(metricsSetParams.MetricsCount * subDeviceCount) + .WillRepeatedly(Return(&metric)); + + EXPECT_CALL(metricsSet, SetApiFiltering(_)) + .WillRepeatedly(Return(TCompletionCode::CC_OK)); + + EXPECT_CALL(metric, GetParams()) + .WillRepeatedly(Return(&metricParams)); + + EXPECT_CALL(metricsSet, CalculateMetrics(_, _, _, _, _, _, _)) + .Times(subDeviceCount - 1) + .WillRepeatedly(DoAll(::testing::SetArgPointee<4>(returnedMetricCount), Return(TCompletionCode::CC_OK))); + + // Metric group handles. + uint32_t metricGroupCount = 1; + EXPECT_EQ(zetMetricGroupGet(devices[0]->toHandle(), &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + EXPECT_NE(metricGroupHandle, nullptr); + + // Raw results. + constexpr size_t rawResultsSize = 512; // metricsSetParams.RawReportSize * returnedMetricCount + uint8_t rawResults[rawResultsSize] = {}; + MetricGroupCalculateHeader *pRawHeader = reinterpret_cast(rawResults); + + pRawHeader->magic = MetricGroupCalculateHeader::magicValue; + pRawHeader->dataCount = subDeviceCount; + pRawHeader->rawDataOffsets = sizeof(MetricGroupCalculateHeader); + pRawHeader->rawDataSizes = pRawHeader->rawDataOffsets + sizeof(uint32_t) * pRawHeader->dataCount; + pRawHeader->rawDataOffset = pRawHeader->rawDataSizes + sizeof(uint32_t) * pRawHeader->dataCount; + + // Sub device 1 has 0 reports to calculate. + uint32_t *pRawDataOffsets = reinterpret_cast(rawResults + pRawHeader->rawDataOffsets); + uint32_t *pRawDataSizes = reinterpret_cast(rawResults + pRawHeader->rawDataSizes); + pRawDataOffsets[0] = 0; + pRawDataOffsets[1] = metricsSetParams.RawReportSize * returnedMetricCount; + pRawDataSizes[0] = metricsSetParams.RawReportSize * returnedMetricCount; + pRawDataSizes[1] = 0; + + // Valid raw buffer. + uint32_t dataCount = 0; + uint32_t totalMetricCount = 0; + EXPECT_NE(metricsSetParams.RawReportSize, rawResultsSize); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(dataCount, subDeviceCount); + EXPECT_EQ(totalMetricCount, returnedMetricCount * metricsSetParams.MetricsCount); + + // Copy calculated metrics. + std::vector metricCounts(dataCount); + std::vector caculatedRawResults(totalMetricCount); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, metricCounts.data(), caculatedRawResults.data()), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricCounts[0], returnedMetricCount * metricsSetParams.MetricsCount); + EXPECT_EQ(metricCounts[1], 0u); +} + +TEST_F(MetricEnumerationMultiDeviceTest, givenCorrectRawDataHeaderWhenBothSubDevicesHaveNoReportsToCalculateThenZetMetricGroupCalculateMetricValuesExpReturnsFail) { + + auto &deviceImp = *static_cast(devices[0]); + const uint32_t subDeviceCount = static_cast(deviceImp.subDevices.size()); + + metricsDeviceParams.ConcurrentGroupsCount = 1; + + Mock metricsConcurrentGroup; + TConcurrentGroupParams_1_0 metricsConcurrentGroupParams = {}; + metricsConcurrentGroupParams.MetricSetsCount = 1; + metricsConcurrentGroupParams.SymbolName = "OA"; + + Mock metricsSet; + MetricsDiscovery::TMetricSetParams_1_4 metricsSetParams = {}; + metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_IOSTREAM; + metricsSetParams.RawReportSize = 256; + metricsSetParams.MetricsCount = 11; + + Mock metric; + MetricsDiscovery::TMetricParams_1_0 metricParams = {}; + + zet_metric_group_handle_t metricGroupHandle = {}; + + openMetricsAdapter(); + + EXPECT_CALL(metricsDevice, GetParams()) + .WillRepeatedly(Return(&metricsDeviceParams)); + + EXPECT_CALL(metricsDevice, GetConcurrentGroup(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroup)); + + EXPECT_CALL(metricsConcurrentGroup, GetParams()) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroupParams)); + + EXPECT_CALL(metricsConcurrentGroup, GetMetricSet(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsSet)); + + EXPECT_CALL(metricsSet, GetParams()) + .WillRepeatedly(Return(&metricsSetParams)); + + EXPECT_CALL(metricsSet, GetMetric(_)) + .Times(metricsSetParams.MetricsCount * subDeviceCount) + .WillRepeatedly(Return(&metric)); + + EXPECT_CALL(metricsSet, SetApiFiltering(_)) + .WillRepeatedly(Return(TCompletionCode::CC_OK)); + + EXPECT_CALL(metric, GetParams()) + .WillRepeatedly(Return(&metricParams)); + + EXPECT_CALL(metricsSet, CalculateMetrics(_, _, _, _, _, _, _)) + .Times(0); + + // Metric group handles. + uint32_t metricGroupCount = 1; + EXPECT_EQ(zetMetricGroupGet(devices[0]->toHandle(), &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + EXPECT_NE(metricGroupHandle, nullptr); + + // Raw results. + constexpr size_t rawResultsSize = 512; // metricsSetParams.RawReportSize * returnedMetricCount + uint8_t rawResults[rawResultsSize] = {}; + MetricGroupCalculateHeader *pRawHeader = reinterpret_cast(rawResults); + + pRawHeader->magic = MetricGroupCalculateHeader::magicValue; + pRawHeader->dataCount = subDeviceCount; + pRawHeader->rawDataOffsets = sizeof(MetricGroupCalculateHeader); + pRawHeader->rawDataSizes = pRawHeader->rawDataOffsets + sizeof(uint32_t) * pRawHeader->dataCount; + pRawHeader->rawDataOffset = pRawHeader->rawDataSizes + sizeof(uint32_t) * pRawHeader->dataCount; + + // Sub device 0 and 1 have 0 reports to calculate. + uint32_t *pRawDataOffsets = reinterpret_cast(rawResults + pRawHeader->rawDataOffsets); + uint32_t *pRawDataSizes = reinterpret_cast(rawResults + pRawHeader->rawDataSizes); + pRawDataOffsets[0] = 0; + pRawDataOffsets[1] = 0; + pRawDataSizes[0] = 0; + pRawDataSizes[1] = 0; + + // Valid raw buffer. + uint32_t dataCount = 0; + uint32_t totalMetricCount = 0; + EXPECT_NE(metricsSetParams.RawReportSize, rawResultsSize); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); + EXPECT_EQ(dataCount, 0u); + EXPECT_EQ(totalMetricCount, 0u); +} + +TEST_F(MetricEnumerationMultiDeviceTest, givenCorrectRawDataHeaderWhenBothSubDevicesHaveNoReportsToCalculateAndPassInvalidArgumentsThatOneSubDeviceHasDataToCalculateToZetMetricGroupCalculateMetricValuesExpOnSecondCallReturnsFail) { + + auto &deviceImp = *static_cast(devices[0]); + const uint32_t subDeviceCount = static_cast(deviceImp.subDevices.size()); + + metricsDeviceParams.ConcurrentGroupsCount = 1; + + Mock metricsConcurrentGroup; + TConcurrentGroupParams_1_0 metricsConcurrentGroupParams = {}; + metricsConcurrentGroupParams.MetricSetsCount = 1; + metricsConcurrentGroupParams.SymbolName = "OA"; + + Mock metricsSet; + MetricsDiscovery::TMetricSetParams_1_4 metricsSetParams = {}; + metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_IOSTREAM; + metricsSetParams.RawReportSize = 256; + metricsSetParams.MetricsCount = 11; + + Mock metric; + MetricsDiscovery::TMetricParams_1_0 metricParams = {}; + + zet_metric_group_handle_t metricGroupHandle = {}; + + openMetricsAdapter(); + + EXPECT_CALL(metricsDevice, GetParams()) + .WillRepeatedly(Return(&metricsDeviceParams)); + + EXPECT_CALL(metricsDevice, GetConcurrentGroup(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroup)); + + EXPECT_CALL(metricsConcurrentGroup, GetParams()) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroupParams)); + + EXPECT_CALL(metricsConcurrentGroup, GetMetricSet(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsSet)); + + EXPECT_CALL(metricsSet, GetParams()) + .WillRepeatedly(Return(&metricsSetParams)); + + EXPECT_CALL(metricsSet, GetMetric(_)) + .Times(metricsSetParams.MetricsCount * subDeviceCount) + .WillRepeatedly(Return(&metric)); + + EXPECT_CALL(metricsSet, SetApiFiltering(_)) + .WillRepeatedly(Return(TCompletionCode::CC_OK)); + + EXPECT_CALL(metric, GetParams()) + .WillRepeatedly(Return(&metricParams)); + + EXPECT_CALL(metricsSet, CalculateMetrics(_, _, _, _, _, _, _)) + .Times(0); + + // Metric group handles. + uint32_t metricGroupCount = 1; + EXPECT_EQ(zetMetricGroupGet(devices[0]->toHandle(), &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + EXPECT_NE(metricGroupHandle, nullptr); + + // Raw results. + constexpr size_t rawResultsSize = 512; // metricsSetParams.RawReportSize * returnedMetricCount + uint8_t rawResults[rawResultsSize] = {}; + MetricGroupCalculateHeader *pRawHeader = reinterpret_cast(rawResults); + + pRawHeader->magic = MetricGroupCalculateHeader::magicValue; + pRawHeader->dataCount = subDeviceCount; + pRawHeader->rawDataOffsets = sizeof(MetricGroupCalculateHeader); + pRawHeader->rawDataSizes = pRawHeader->rawDataOffsets + sizeof(uint32_t) * pRawHeader->dataCount; + pRawHeader->rawDataOffset = pRawHeader->rawDataSizes + sizeof(uint32_t) * pRawHeader->dataCount; + + // Sub device 0 and 1 have 0 reports to calculate. + uint32_t *pRawDataOffsets = reinterpret_cast(rawResults + pRawHeader->rawDataOffsets); + uint32_t *pRawDataSizes = reinterpret_cast(rawResults + pRawHeader->rawDataSizes); + pRawDataOffsets[0] = 0; + pRawDataOffsets[1] = 0; + pRawDataSizes[0] = 0; + pRawDataSizes[1] = 0; + + // Valid raw buffer. + uint32_t dataCount = 0; + uint32_t totalMetricCount = 0; + EXPECT_NE(metricsSetParams.RawReportSize, rawResultsSize); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); + EXPECT_EQ(dataCount, 0u); + EXPECT_EQ(totalMetricCount, 0u); + + // Pass invalid dataCount and totalMetricCount params. + dataCount = 1; + totalMetricCount = metricsSetParams.MetricsCount; + uint32_t metricCounts = 0; + std::vector caculatedRawResults(totalMetricCount); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, &metricCounts, caculatedRawResults.data()), ZE_RESULT_ERROR_INVALID_SIZE); + EXPECT_EQ(dataCount, 0u); + EXPECT_EQ(totalMetricCount, 0u); + EXPECT_EQ(metricCounts, 0u); +} + +TEST_F(MetricEnumerationMultiDeviceTest, givenCorrectRawDataHeaderWhenBothSubDevicesHasNoReportsToCalculateAndPassInvalidArgumentsThatTwoSubDevicesHaveDataToCalculateToZetMetricGroupCalculateMetricValuesExpOnSecondCallReturnsFail) { + + auto &deviceImp = *static_cast(devices[0]); + const uint32_t subDeviceCount = static_cast(deviceImp.subDevices.size()); + + metricsDeviceParams.ConcurrentGroupsCount = 1; + + Mock metricsConcurrentGroup; + TConcurrentGroupParams_1_0 metricsConcurrentGroupParams = {}; + metricsConcurrentGroupParams.MetricSetsCount = 1; + metricsConcurrentGroupParams.SymbolName = "OA"; + + Mock metricsSet; + MetricsDiscovery::TMetricSetParams_1_4 metricsSetParams = {}; + metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_IOSTREAM; + metricsSetParams.RawReportSize = 256; + metricsSetParams.MetricsCount = 11; + + Mock metric; + MetricsDiscovery::TMetricParams_1_0 metricParams = {}; + + zet_metric_group_handle_t metricGroupHandle = {}; + + openMetricsAdapter(); + + EXPECT_CALL(metricsDevice, GetParams()) + .WillRepeatedly(Return(&metricsDeviceParams)); + + EXPECT_CALL(metricsDevice, GetConcurrentGroup(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroup)); + + EXPECT_CALL(metricsConcurrentGroup, GetParams()) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsConcurrentGroupParams)); + + EXPECT_CALL(metricsConcurrentGroup, GetMetricSet(_)) + .Times(subDeviceCount) + .WillRepeatedly(Return(&metricsSet)); + + EXPECT_CALL(metricsSet, GetParams()) + .WillRepeatedly(Return(&metricsSetParams)); + + EXPECT_CALL(metricsSet, GetMetric(_)) + .Times(metricsSetParams.MetricsCount * subDeviceCount) + .WillRepeatedly(Return(&metric)); + + EXPECT_CALL(metricsSet, SetApiFiltering(_)) + .WillRepeatedly(Return(TCompletionCode::CC_OK)); + + EXPECT_CALL(metric, GetParams()) + .WillRepeatedly(Return(&metricParams)); + + EXPECT_CALL(metricsSet, CalculateMetrics(_, _, _, _, _, _, _)) + .Times(0); + + // Metric group handles. + uint32_t metricGroupCount = 1; + EXPECT_EQ(zetMetricGroupGet(devices[0]->toHandle(), &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + EXPECT_NE(metricGroupHandle, nullptr); + + // Raw results. + constexpr size_t rawResultsSize = 512; // metricsSetParams.RawReportSize * returnedMetricCount + uint8_t rawResults[rawResultsSize] = {}; + MetricGroupCalculateHeader *pRawHeader = reinterpret_cast(rawResults); + + pRawHeader->magic = MetricGroupCalculateHeader::magicValue; + pRawHeader->dataCount = subDeviceCount; + pRawHeader->rawDataOffsets = sizeof(MetricGroupCalculateHeader); + pRawHeader->rawDataSizes = pRawHeader->rawDataOffsets + sizeof(uint32_t) * pRawHeader->dataCount; + pRawHeader->rawDataOffset = pRawHeader->rawDataSizes + sizeof(uint32_t) * pRawHeader->dataCount; + + // Sub device 0 and 1 have 0 reports to calculate. + uint32_t *pRawDataOffsets = reinterpret_cast(rawResults + pRawHeader->rawDataOffsets); + uint32_t *pRawDataSizes = reinterpret_cast(rawResults + pRawHeader->rawDataSizes); + pRawDataOffsets[0] = 0; + pRawDataOffsets[1] = 0; + pRawDataSizes[0] = 0; + pRawDataSizes[1] = 0; + + // Valid raw buffer. + uint32_t dataCount = 0; + uint32_t totalMetricCount = 0; + EXPECT_NE(metricsSetParams.RawReportSize, rawResultsSize); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, nullptr, nullptr), ZE_RESULT_ERROR_INVALID_SIZE); + EXPECT_EQ(dataCount, 0u); + EXPECT_EQ(totalMetricCount, 0u); + + // Pass invalid dataCount and totalMetricCount params. + dataCount = 2; + totalMetricCount = dataCount * metricsSetParams.MetricsCount; + std::vector metricCounts(dataCount); + std::vector caculatedRawResults(totalMetricCount); + EXPECT_EQ(L0::zetMetricGroupCalculateMultipleMetricValuesExp(metricGroupHandle, ZET_METRIC_GROUP_CALCULATION_TYPE_METRIC_VALUES, rawResultsSize, rawResults, &dataCount, &totalMetricCount, metricCounts.data(), caculatedRawResults.data()), ZE_RESULT_ERROR_INVALID_SIZE); + EXPECT_EQ(dataCount, 0u); + EXPECT_EQ(totalMetricCount, 0u); + EXPECT_EQ(metricCounts[0], 0u); + EXPECT_EQ(metricCounts[1], 0u); +} + } // namespace ult } // namespace L0