From f17500a9771fc43b922fedd7dd9d840f4a15109d Mon Sep 17 00:00:00 2001 From: Matias Cabral Date: Fri, 28 Feb 2025 19:18:05 +0000 Subject: [PATCH] feature: source independent entry for calc op create Resolves: NEO-13996 Signed-off-by: Matias Cabral --- .../driver_experimental/public/zex_metric.cpp | 26 +++ level_zero/include/level_zero/ze_stypes.h | 4 +- .../include/level_zero/zet_intel_gpu_metric.h | 184 +++++++++++++++++ level_zero/tools/source/metrics/metric.cpp | 120 ++++++++++- level_zero/tools/source/metrics/metric.h | 47 ++++- .../metrics/metric_ip_sampling_source.h | 7 + .../tools/source/metrics/metric_oa_source.h | 7 + .../sources/metrics/mock_metric_source.h | 24 +++ .../sources/metrics/test_metric.cpp | 191 +++++++++++++++++- .../test_metric_ip_sampling_enumeration.cpp | 32 +++ .../metrics/test_metric_oa_enumeration_1.cpp | 71 +++++++ 11 files changed, 709 insertions(+), 4 deletions(-) diff --git a/level_zero/api/driver_experimental/public/zex_metric.cpp b/level_zero/api/driver_experimental/public/zex_metric.cpp index 8c1e3404c9..4b4ec781af 100644 --- a/level_zero/api/driver_experimental/public/zex_metric.cpp +++ b/level_zero/api/driver_experimental/public/zex_metric.cpp @@ -70,6 +70,17 @@ ze_result_t ZE_APICALL zetIntelMetricTracerDecodeExp(zet_intel_metric_decoder_ex pSetCount, pMetricEntriesCountPerSet, pMetricEntriesCount, pMetricEntries); } +ze_result_t ZE_APICALL zetIntelMetricCalculateOperationCreateExp(zet_context_handle_t hContext, zet_device_handle_t hDevice, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) { + return L0::metricCalculateOperationCreate(hContext, hDevice, pCalculateDesc, pCount, phExcludedMetrics, phCalculateOperation); +} + +ze_result_t zetIntelMetricCalculateOperationDestroyExp(zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation) { + return L0::metricCalculateOperationDestroy(hCalculateOperation); +} + } // namespace L0 extern "C" { @@ -148,4 +159,19 @@ ze_result_t ZE_APICALL zetIntelMetricTracerDecodeExp( return L0::zetIntelMetricTracerDecodeExp(phMetricDecoder, pRawDataSize, pRawData, metricsCount, phMetrics, pSetCount, pMetricEntriesCountPerSet, pMetricEntriesCount, pMetricEntries); } + +ze_result_t zetIntelMetricCalculateOperationCreateExp( + zet_context_handle_t hContext, + zet_device_handle_t hDevice, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, + zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) { + return L0::zetIntelMetricCalculateOperationCreateExp(hContext, hDevice, pCalculateDesc, pCount, phExcludedMetrics, phCalculateOperation); +} + +ze_result_t zetIntelMetricCalculateOperationDestroyExp( + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation) { + return L0::zetIntelMetricCalculateOperationDestroyExp(hCalculateOperation); +} } diff --git a/level_zero/include/level_zero/ze_stypes.h b/level_zero/include/level_zero/ze_stypes.h index 71f3f38cbd..a9adee19a8 100644 --- a/level_zero/include/level_zero/ze_stypes.h +++ b/level_zero/include/level_zero/ze_stypes.h @@ -37,5 +37,7 @@ #define ZEX_STRUCTURE_COUNTER_BASED_EVENT_EXTERNAL_STORAGE_ALLOC_PROPERTIES (ze_structure_type_t)0x00030027 // Metric structure types -#define ZET_INTEL_STRUCTURE_TYPE_METRIC_SOURCE_ID_EXP (zet_structure_type_t)0x0001000a // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange), NEO-12901 +#define ZET_INTEL_STRUCTURE_TYPE_METRIC_SOURCE_ID_EXP (zet_structure_type_t)0x0001000a // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange), NEO-12901 +#define ZET_INTEL_STRUCTURE_TYPE_METRIC_CALCULATE_DESC_EXP (zet_structure_type_t)0x00010009 // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange), NEO-12901 + #endif diff --git a/level_zero/include/level_zero/zet_intel_gpu_metric.h b/level_zero/include/level_zero/zet_intel_gpu_metric.h index a43a9acb5c..dc7e1b548a 100644 --- a/level_zero/include/level_zero/zet_intel_gpu_metric.h +++ b/level_zero/include/level_zero/zet_intel_gpu_metric.h @@ -190,6 +190,190 @@ ze_result_t ZE_APICALL zetIntelMetricTracerDecodeExp( ///< decoded metric entries ); +#ifndef ZET_INTEL_METRIC_CALCULATE_EXP_NAME +/// @brief Extension name to query and read the Intel Level Zero Driver Version String +#define ZET_INTEL_METRIC_CALCULATE_EXP_NAME "ZET_intel_metric_calculate" +#endif // ZET_INTEL_METRIC_CALCULATE_EXP_NAME +/////////////////////////////////////////////////////////////////////////////// +/// @brief Metric Calculate extension Version(s) +typedef enum _zet_intel_metric_calculate_exp_version_t { + ZET_INTEL_METRIC_CALCULATE_EXP_VERSION_1_0 = ZE_MAKE_VERSION(1, 0), ///< version 1.0 + ZET_INTEL_METRIC_CALCULATE_EXP_VERSION_2_0 = ZE_MAKE_VERSION(2, 0), + ZET_INTEL_METRIC_CALCULATE_EXP_VERSION_CURRENT = ZET_INTEL_METRIC_CALCULATE_EXP_VERSION_2_0, ///< latest known version + ZET_INTEL_METRIC_CALCULATE_EXP_VERSION_FORCE_UINT32 = 0x7fffffff +} zet_intel_metric_calculate_exp_version_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of metric calculate operation +typedef struct _zet_intel_metric_calculate_operation_exp_handle_t *zet_intel_metric_calculate_operation_exp_handle_t; + +typedef struct _zet_intel_metric_calculate_time_window_exp_t { + uint64_t windowStart; ///< [in] starting time in nanoseconds of the raw data to where WindowSize + ///< is selected. If WindowStart + WindowSize is bigger than the total + ///< time of the raw data collected, only a fraction of the window will be used. + uint64_t windowSize; ///< [in] size in nanoseconds of the faction of the raw data used for calculation. +} zet_intel_metric_calculate_time_window_exp_t; + +typedef struct _zet_intel_metric_calculate_exp_desc_t { + zet_structure_type_t stype; ///< [in] type of this structure + const void *pNext; ///< [in][optional] must be null or a pointer to an extension-specific + ///< structure (i.e. contains stype and pNext). + uint32_t metricGroupCount; ///< [in] [in] count for metric group handles in metric hMetricGroups array. + ///< If set to 0, then phMetricGroups must be null + zet_metric_group_handle_t *phMetricGroups; ///< [in] [optional][range(0, metricGroupCount)] array of metric group + ///< handles to filter metric groups to be calculated. + uint32_t metricCount; ///< [in] number of metrics handles in the phMetrics array. If set to 0, then + ///< phMetrics must be null. + zet_metric_handle_t *phMetrics; ///< [in][optional] [range(0, metricsCount)] array of metrics handles to filter + ///< metrics to be calculated. phMetrics are additionally calculated even if repeated + ///< in phMetricGroups. + uint32_t timeWindowsCount; ///< [in] number of time windows in pCalculateTimeWindows. Must be 0 if disabled. + ///< If set to 0, then pCalculateTimeWindows must be null + zet_intel_metric_calculate_time_window_exp_t *pCalculateTimeWindows; ///< [in][optional][range(0,timeWindowsCount)] array containing the list of time windows + ///< to filter metrics data + ///< to be used for metrics calculation. Must be null if disabled. + uint64_t timeAggregationWindow; ///< [in] size in nanoseconds used to divide the raw data and calculate a result for + ///< each metric. When enabled, the API will return one report per aggregation + ///< window. Must not be 0. When set to uint64_t_MAX will include all rawdata + ///< in a single window. If the timeAggregationWindow is bigger than the total + ///< time of the raw data collected, will be same as uint64_t_MAX. When + ///< timeAggregationWindow is not a perfect divisor of the total time, + ///< the last window is expected to be smaller. When CalculateTimeWindows + ///< are used, the API will limit the maximum timeAggregationWindow to + ///< the size of each CalculateTimeWindow individually. When timeAggregationWindow + ///< is smaller than a given CalculateTimeWindow, the CalculateTimeWindow will + ///< be divided into timeAggregationWindow sections for aggregation, with the + ///< last fraction being smaller when there is no perfect division. +} zet_intel_metric_calculate_exp_desc_t; +typedef enum _zet_intel_metric_calculate_result_status_exp_t { + ZET_INTEL_METRIC_CALCULATE_EXP_RESULT_VALID = 0, + ZET_INTEL_METRIC_CALCULATE_EXP_RESULT_INVALID, + ZET_INTEL_METRIC_CALCULATE_EXP_RESULT_FORCE_UINT32 = 0x7fffffff +} zet_intel_metric_calculate_result_status_exp_t; + +typedef struct _zet_intel_metric_result_exp_t { + zet_value_t value; ///< [out] metric result calculated metric value + zet_intel_metric_calculate_result_status_exp_t resultStatus; ///< [out] type of the result for the filters applied to the calculation. +} zet_intel_metric_result_exp_t; +typedef struct _zet_intel_metric_decoded_buffer_exp_properties_t { + zet_structure_type_t stype; ///< [in] type of this structure + void *pNext; ///< [in][optional] must be null or a pointer to an extension-specific + ///< structure (i.e. contains stype and pNext). + uint64_t minTimeStamp; ///< [out] minimum timestamp contained in the raw data buffer + uint64_t maxTimeStamp; ///< [out] maximum timestamp contained in the raw data buffer +} zet_intel_metric_decoded_buffer_exp_properties_t; + +ze_result_t ZE_APICALL +zetIntelMetricCalculateOperationCreateExp( + zet_context_handle_t hContext, ///< [in] handle of the context object + zet_device_handle_t hDevice, ///< [in] handle of the device + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, ///< [in] pointer to structure with filters and operations to perform + ///< at calculation time. + uint32_t *pCount, ///< [out] pointer to number of excluded metrics. These are metrics in the + ///< input list in pcalculateDesc that do not allow calculation + zet_metric_handle_t *phExcludedMetrics, ///< [in,out] [range(0, *pCount)] array of handles of excluded metrics + ///< from the phCalculateOperation handle. + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation); ///< [out] Calculate operation handle + +ze_result_t ZE_APICALL +zetIntelMetricCalculateOperationDestroyExp( + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation); ///< [in] Calculate operation handle + +ze_result_t ZE_APICALL zetIntelMetricCalculateGetReportFormatExp( + zet_intel_metric_calculate_operation_exp_handle_t phCalculateOperation, ///< [in] Calculate operation handle + uint32_t *pCount, ///< [in,out] pointer to the number of metrics in the output report from + ///< calculate operations. If set to zero, then the driver shall update + ///< the value with the total number of metrics to be included in the + ///< calculate results report. If count is greater than the total number + ///< of metrics to be included in the calculate results report, then the + ///< driver shall update the value with the actual number. If count is + ///< smaller than the total number of metrics to be included in the + ///< calculate results report, then ZE_RESULT_ERROR_INVALID_ARGUMENT + ///< will be returned since this parameter is not intended for + ///< filtering metrics. + zet_metric_handle_t *phMetrics); ///< [out][optional] [range(0, pMetricsCount)] array of metrics handles + ///< with the order in which results will be found in output report of + ///< calculate operations + +ze_result_t ZE_APICALL +zetIntelMetricDecodeCalculateMultipleValuesExp( + zet_metric_decoder_exp_handle_t hMetricDecoder, ///< [in] handle of the metric decoder object + size_t rawDataSize, ///< [in] size in bytes of raw data buffer. + size_t *offset, ///< [in,out] On input, the offset from the beginning of the data to decode. On output, + ///< the number raw bytes processed + const uint8_t *pRawData, ///< [in,out][range(0, *rawDataSize)] buffer containing tracer + ///< data in raw format + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation, ///< [in] Calculate operation handle + uint32_t *pSetCount, ///< [in,out] pointer to number of metric sets. if count is zero, then the + ///< driver shall update the value with the total number of metric sets to + ///< be decoded and calculated. If count is greater than the number available + ///< in the raw data buffer, then the driver shall update the value with the + ///< actual number of metric sets to be decoded and calculated. There is a + ///< 1:1 relationship between the number of sets and the number sub-devices + ///< metrics results that can be calculated from the provided data + uint32_t *pMetricReportCountPerSet, ///< [in,out][optional][range(0, *pSetCount)] buffer of metric reports counts + ///< per metric set, one value per set + uint32_t *pTotalMetricReportCount, ///< [in,out] [optional] pointer to the total number of metric reports decoded and + ///< calculated, for all metric sets. If count is zero, then the driver shall update + ///< the value with the total number of metric reports to be decoded and calculated. + ///< If count is greater than zero but less than the total number of reports available + ///< in the raw data, then only that number of reports will be decoded and calculated. + ///< If count is greater than the number of reports available in the raw data buffer, + ///< then the driver shall update the value with the actual number of metric reports + ///< decoded and calculated. If set to null, then driver will only update the value + ///< of pSetCount + zet_intel_metric_result_exp_t *pMetricResults); ///< [in,out][optional][range(0, *pTotalMetricResultsCount)] buffer of decoded and + ///< calculated metrics results. + +ze_result_t ZE_APICALL +zetIntelMetricDecodeToBinaryBufferExp( + zet_metric_decoder_exp_handle_t hMetricDecoder, ///< [in] handle of the metric decoder object + size_t *pRawDataSize, ///< [in,out] size in bytes of raw data buffer. If pDecodedBufferSize is greater + ///< than 0 but smaller than the total number of bytes required for decoding + ///< the entire input raw data, then driver shall update this value with + ///< actual number of raw data bytes processed + const uint8_t *pRawData, ///< [in,out][range(0, *pRawDataSize)] buffer containing tracer + ///< data in raw format + zet_intel_metric_calculate_operation_exp_handle_t phCalculateOperation, ///< [in] Calculate operation handle, to filter metrics to decode + zet_intel_metric_decoded_buffer_exp_properties_t *pProperties, ///< [in] Properties of the decoded buffer. + size_t *pDecodedBufferSize, ///< [in] Pointer to the size of the decoded binary buffer. If set to 0, + ///< [in,out] Then driver shall update this value with total size in bytes required + ///< for the decoded binary buffer. If size is greater than 0 but smaller + ///< than the total number of bytes required for decoding entire input + ///< raw data, then driver shall only decode an approximate to that number + ///< of bytes. If size is greater than the total number of bytes required + ///< for decoding entire input raw data, then the driver shall update the + ///< value with the actual number of bytes decoded. + uint8_t *pDecodedBuffer); ///< [in,out][optional] binary buffer containing decoded raw data. + +ze_result_t ZE_APICALL +zetIntelMetricCalculateMultipleValuesExp( + size_t rawDataSize, ///< [in] size in bytes of raw data buffer. + size_t *offset, ///< [in,out] On input, the offset from the beginning of the data to decode. On output, + ///< the number raw bytes processed + const uint8_t *pRawData, ///< [in,out][range(0, *rawDataSize)] buffer containing tracer + ///< data in raw format + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation, ///< [in] Calculate operation handle + uint32_t *pSetCount, ///< [in,out] pointer to number of metric sets. if count is zero, then the + ///< driver shall update the value with the total number of metric sets to + ///< be calculated. If count is greater than the number available in the raw + ///< data buffer, then the driver shall update the value with the actual number + ///< of metric sets to be calculated. There is a 1:1 relationship between the + ///< number of sets and the number sub-devices metrics results that can be + ///< calculated from the provided data. + uint32_t *pMetricReportCountPerSet, ///< [in,out][optional][range(0, *pSetCount)] buffer of metric reports counts + ///< per metric set, one value per set + uint32_t *pTotalMetricReportCount, ///< [in,out] [optional] pointer to the total number of metric reports calculated, + ///< for all metric sets. If count is zero, then the driver shall update the value + ///< with the total number of metric reports to be calculated. If count is greater + ///< than zero but less than the total number of reports available in the raw data, + ///< then only that number of reports will be calculated. If count is greater than + ///< the number of reports available in the raw data buffer, then the driver shall + ///< update the value with the actual number of metric reports calculated. If set + ///< to null, then driver will only update the value of pSetCount + zet_intel_metric_result_exp_t *pMetricResults); ///< [in,out][optional][range(0, *pTotalMetricResultsCount)] buffer of calculated + ///< metrics results. + #if defined(__cplusplus) } // extern "C" #endif diff --git a/level_zero/tools/source/metrics/metric.cpp b/level_zero/tools/source/metrics/metric.cpp index 27f4e8ee02..5f03b69af4 100644 --- a/level_zero/tools/source/metrics/metric.cpp +++ b/level_zero/tools/source/metrics/metric.cpp @@ -424,7 +424,7 @@ ze_result_t MetricDeviceContext::createMetricGroupsFromMetrics(uint32_t metricCo bool MetricDeviceContext::areMetricGroupsFromSameDeviceHierarchy(uint32_t count, zet_metric_group_handle_t *phMetricGroups) { bool isRootDevice = isImplicitScalingCapable(); - // Verify whether all metricgroups have the same device heirarchy + // Verify whether metricGroups belong to the device heirarchy for (uint32_t index = 0; index < count; index++) { auto metricGroupImp = static_cast(MetricGroup::fromHandle(phMetricGroups[index])); if (isRootDevice != metricGroupImp->isRootDevice()) { @@ -434,6 +434,19 @@ bool MetricDeviceContext::areMetricGroupsFromSameDeviceHierarchy(uint32_t count, return true; } +bool MetricDeviceContext::areMetricsFromSameDeviceHierarchy(uint32_t count, zet_metric_handle_t *phMetrics) { + bool isRootDevice = isImplicitScalingCapable(); + + // Verify whether metricGroups belong to the device heirarchy + for (uint32_t index = 0; index < count; index++) { + auto metricImp = static_cast(Metric::fromHandle(phMetrics[index])); + if (isRootDevice != metricImp->isRootDevice()) { + return false; + } + } + return true; +} + ze_result_t MetricDeviceContext::metricGroupCreate(const char name[ZET_MAX_METRIC_GROUP_NAME], const char description[ZET_MAX_METRIC_GROUP_DESCRIPTION], zet_metric_group_sampling_type_flag_t samplingType, @@ -441,6 +454,94 @@ ze_result_t MetricDeviceContext::metricGroupCreate(const char name[ZET_MAX_METRI return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } +bool MetricDeviceContext::areMetricGroupsFromSameSource(uint32_t count, zet_metric_group_handle_t *phMetricGroups, uint32_t *sourceType) { + DEBUG_BREAK_IF(count == 0); + auto metricGroupImp = static_cast(MetricGroup::fromHandle(phMetricGroups[0])); + *sourceType = metricGroupImp->getMetricSource().getType(); + + // Verify whether all metric groups have the same source type + for (uint32_t index = 1; index < count; index++) { + metricGroupImp = static_cast(MetricGroup::fromHandle(phMetricGroups[index])); + if (*sourceType != metricGroupImp->getMetricSource().getType()) { + *sourceType = MetricSource::metricSourceTypeUndefined; + return false; + } + } + return true; +} + +bool MetricDeviceContext::areMetricsFromSameSource(uint32_t count, zet_metric_handle_t *phMetrics, uint32_t *sourceType) { + + DEBUG_BREAK_IF(count == 0); + auto metricImp = static_cast(Metric::fromHandle(phMetrics[0])); + *sourceType = metricImp->getMetricSource().getType(); + + // Verify whether all metrics have the same source type + for (uint32_t index = 1; index < count; index++) { + auto metricImp = static_cast(Metric::fromHandle(phMetrics[index])); + if (*sourceType != metricImp->getMetricSource().getType()) { + *sourceType = MetricSource::metricSourceTypeUndefined; + return false; + } + } + return true; +} + +ze_result_t MetricDeviceContext::calcOperationCreate(zet_context_handle_t hContext, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, + zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) { + + if (pCalculateDesc->timeAggregationWindow == 0) { + METRICS_LOG_ERR("%s", "Must define an aggregation window"); + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + + uint32_t metricGroupsSourceType = MetricSource::metricSourceTypeUndefined; + MetricGroupImp *metricGroupImp = nullptr; + if (pCalculateDesc->metricGroupCount > 0) { + if (!areMetricGroupsFromSameSource(pCalculateDesc->metricGroupCount, pCalculateDesc->phMetricGroups, &metricGroupsSourceType)) { + METRICS_LOG_ERR("%s", "Metric groups must be from the same domain"); + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + if (!areMetricGroupsFromSameDeviceHierarchy(pCalculateDesc->metricGroupCount, pCalculateDesc->phMetricGroups)) { + METRICS_LOG_ERR("%s", "Mix of root device and sub-device metric group handle is not allowed"); + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + + metricGroupImp = static_cast(MetricGroup::fromHandle(pCalculateDesc->phMetricGroups[0])); + } + + uint32_t metricsSourceType = MetricSource::metricSourceTypeUndefined; + MetricImp *metricImp = nullptr; + if (pCalculateDesc->metricCount > 0) { + if (!areMetricsFromSameSource(pCalculateDesc->metricCount, pCalculateDesc->phMetrics, &metricsSourceType)) { + METRICS_LOG_ERR("%s", "Metrics must be from the same domain"); + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + if (!areMetricsFromSameDeviceHierarchy(pCalculateDesc->metricCount, pCalculateDesc->phMetrics)) { + METRICS_LOG_ERR("%s", "Mix of root device and sub-device metric handle is not allowed"); + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + + metricImp = static_cast(Metric::fromHandle(pCalculateDesc->phMetrics[0])); + } + + if (pCalculateDesc->metricGroupCount > 0) { + if ((pCalculateDesc->metricCount > 0) && (metricGroupsSourceType != metricsSourceType)) { + METRICS_LOG_ERR("%s", "Metric groups and metrics must be from the same domain"); + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + } else if (pCalculateDesc->metricCount == 0) { + METRICS_LOG_ERR("%s", "Must define at least one metric group or metric"); + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + + MetricSource &metricSource = (metricGroupImp) ? metricGroupImp->getMetricSource() : metricImp->getMetricSource(); // NOLINT(clang-analyzer-core.CallAndMessage) + return metricSource.calcOperationCreate(*this, pCalculateDesc, pCount, phExcludedMetrics, phCalculateOperation); +} + ze_result_t MultiDeviceMetricImp::getProperties(zet_metric_properties_t *pProperties) { return subDeviceMetrics[0]->getProperties(pProperties); } @@ -752,4 +853,21 @@ ze_result_t metricCreateFromProgrammable( return L0::MetricProgrammable::fromHandle(hMetricProgrammable)->createMetric(pParameterValues, parameterCount, name, description, pMetricHandleCount, phMetricHandles); } +ze_result_t metricCalculateOperationCreate( + zet_context_handle_t hContext, + zet_device_handle_t hDevice, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, + zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) { + + DeviceImp *deviceImp = static_cast(L0::Device::fromHandle(hDevice)); + return deviceImp->getMetricDeviceContext().calcOperationCreate(hContext, pCalculateDesc, pCount, phExcludedMetrics, phCalculateOperation); +} + +ze_result_t metricCalculateOperationDestroy( + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation) { + return MetricCalcOp::fromHandle(hCalculateOperation)->destroy(); +} + } // namespace L0 diff --git a/level_zero/tools/source/metrics/metric.h b/level_zero/tools/source/metrics/metric.h index f7c9746b0d..f301bf064b 100644 --- a/level_zero/tools/source/metrics/metric.h +++ b/level_zero/tools/source/metrics/metric.h @@ -25,6 +25,8 @@ struct _zet_metric_query_pool_handle_t {}; struct _zet_metric_query_handle_t {}; struct _zet_metric_programmable_exp_handle_t {}; +struct _zet_intel_metric_calculate_operation_exp_handle_t {}; + namespace L0 { struct METRICS_LOG_BITMASK { // NOLINT(readability-identifier-naming) @@ -56,7 +58,7 @@ struct METRICS_LOG_BITMASK { // NOLINT(readability-identifier struct CommandList; struct MetricStreamer; struct MetricProgrammable; - +class MetricDeviceContext; class MetricSource { public: static constexpr uint32_t metricSourceTypeUndefined = 0u; @@ -90,6 +92,11 @@ class MetricSource { uint32_t *maxMetricGroupCount, std::vector &metricGroupList) = 0; virtual ze_result_t appendMarker(zet_command_list_handle_t hCommandList, zet_metric_group_handle_t hMetricGroup, uint32_t value) = 0; + virtual ze_result_t calcOperationCreate(MetricDeviceContext &metricDeviceContext, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, + zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) = 0; protected: uint32_t type = MetricSource::metricSourceTypeUndefined; @@ -145,9 +152,18 @@ class MetricDeviceContext { const char description[ZET_MAX_METRIC_GROUP_DESCRIPTION], uint32_t *pMetricGroupCount, zet_metric_group_handle_t *phMetricGroups); + ze_result_t calcOperationCreate(zet_context_handle_t hContext, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, + zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation); bool areMetricGroupsFromSameDeviceHierarchy(uint32_t count, zet_metric_group_handle_t *phMetricGroups); protected: + bool areMetricGroupsFromSameSource(uint32_t count, zet_metric_group_handle_t *phMetricGroups, uint32_t *sourceType); + bool areMetricsFromSameSource(uint32_t count, zet_metric_handle_t *phMetrics, uint32_t *sourceType); + bool areMetricsFromSameDeviceHierarchy(uint32_t count, zet_metric_handle_t *phMetrics); + std::map> metricSources; private: @@ -393,6 +409,30 @@ struct HomogeneousMultiDeviceMetricCreated : public MultiDeviceMetricImp { static MetricImp *create(MetricSource &metricSource, std::vector &subDeviceMetrics); }; +struct MetricCalcOp : _zet_intel_metric_calculate_operation_exp_handle_t { + virtual ~MetricCalcOp() = default; + MetricCalcOp() {} + virtual ze_result_t destroy() = 0; + virtual ze_result_t getReportFormat(uint32_t *pCount, zet_metric_handle_t *phMetrics) = 0; + static MetricCalcOp *fromHandle(zet_intel_metric_calculate_operation_exp_handle_t handle) { + return static_cast(handle); + } + inline zet_intel_metric_calculate_operation_exp_handle_t toHandle() { return this; } + virtual ze_result_t metricCalculateMultipleValues(size_t rawDataSize, size_t *offset, const uint8_t *pRawData, + uint32_t *pSetCount, uint32_t *pMetricsReportCountPerSet, + uint32_t *pTotalMetricReportCount, + zet_intel_metric_result_exp_t *pMetricResults) = 0; +}; + +struct MetricCalcOpImp : public MetricCalcOp { + ~MetricCalcOpImp() override = default; + MetricCalcOpImp(bool multiDevice) : isMultiDevice(multiDevice) {} + bool isRootDevice() { return isMultiDevice; } + + protected: + bool isMultiDevice = false; +}; + // MetricGroup. ze_result_t metricGroupGet(zet_device_handle_t hDevice, uint32_t *pCount, zet_metric_group_handle_t *phMetricGroups); @@ -445,4 +485,9 @@ ze_result_t metricTracerDecode(zet_metric_decoder_exp_handle_t hMetricDecoder, s uint32_t metricsCount, zet_metric_handle_t *phMetrics, uint32_t *pSetCount, uint32_t *pMetricEntriesCountPerSet, uint32_t *pMetricEntriesCount, zet_metric_entry_exp_t *pMetricEntries); +ze_result_t metricCalculateOperationCreate(zet_context_handle_t hContext, zet_device_handle_t hDevice, zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, zet_metric_handle_t *phExcludedMetrics, zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation); + +ze_result_t metricCalculateOperationDestroy(zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation); + } // namespace L0 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 91eb71212c..54a7c606fa 100644 --- a/level_zero/tools/source/metrics/metric_ip_sampling_source.h +++ b/level_zero/tools/source/metrics/metric_ip_sampling_source.h @@ -55,6 +55,13 @@ class IpSamplingMetricSourceImp : public MetricSource { void setActivationTracker(MultiDomainDeferredActivationTracker *inputActivationTracker) { activationTracker.reset(inputActivationTracker); } + ze_result_t calcOperationCreate(MetricDeviceContext &metricDeviceContext, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, + zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) override { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } uint32_t metricSourceCount = 0; diff --git a/level_zero/tools/source/metrics/metric_oa_source.h b/level_zero/tools/source/metrics/metric_oa_source.h index 5442271564..92f4da817d 100644 --- a/level_zero/tools/source/metrics/metric_oa_source.h +++ b/level_zero/tools/source/metrics/metric_oa_source.h @@ -64,6 +64,13 @@ class OaMetricSourceImp : public MetricSource { const char description[ZET_MAX_METRIC_GROUP_DESCRIPTION], zet_metric_group_sampling_type_flag_t samplingType, zet_metric_group_handle_t *pMetricGroupHandle); + ze_result_t calcOperationCreate(MetricDeviceContext &metricDeviceContext, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, + zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) override { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } protected: ze_result_t initializationState = ZE_RESULT_ERROR_UNINITIALIZED; diff --git a/level_zero/tools/test/unit_tests/sources/metrics/mock_metric_source.h b/level_zero/tools/test/unit_tests/sources/metrics/mock_metric_source.h index ddbd9458c0..c3d0c9bee0 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/mock_metric_source.h +++ b/level_zero/tools/test/unit_tests/sources/metrics/mock_metric_source.h @@ -46,6 +46,14 @@ class MockMetricSource : public L0::MetricSource { this->type = type; } + ze_result_t calcOperationCreate(MetricDeviceContext &metricDeviceContext, + zet_intel_metric_calculate_exp_desc_t *pCalculateDesc, + uint32_t *pCount, + zet_metric_handle_t *phExcludedMetrics, + zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) override { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + ~MockMetricSource() override = default; }; @@ -143,5 +151,21 @@ class MockMetric : public L0::MetricImp { } }; +class MockMetricCalcOp : public MetricCalcOpImp { + public: + ~MockMetricCalcOp() override = default; + MockMetricCalcOp() : MetricCalcOpImp(false){}; + ze_result_t destroy() override { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + }; + ze_result_t getReportFormat(uint32_t *pCount, zet_metric_handle_t *phMetrics) override { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + }; + ze_result_t metricCalculateMultipleValues(size_t rawDataSize, size_t *offset, const uint8_t *pRawData, + uint32_t *pSetCount, uint32_t *pMetricReportCountPerSet, + uint32_t *pTotalMetricReportCount, + zet_intel_metric_result_exp_t *pMetricResults) override { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; }; +}; + } // namespace ult } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric.cpp index 36e6032dac..8436248134 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -41,5 +41,194 @@ TEST(MultidevMetric, GivenMultideviceMetricCreatedThenReferenceIsUpdatedSuccessf delete multiDevMetric; } +class CalcOperationFixture : public DeviceFixture, + public ::testing::Test { + protected: + void SetUp() override; + void TearDown() override; + MockMetricSource mockMetricSource{}; + MockMetricGroup *mockMetricGroup; + zet_metric_group_handle_t phMetricGroup = nullptr; + uint32_t excludedMetricsCount = 0; + zet_metric_handle_t *phExcludedMetrics = nullptr; + + DebugManagerStateRestore restorer; +}; + +void CalcOperationFixture::SetUp() { + DeviceFixture::setUp(); + mockMetricGroup = new MockMetricGroup(mockMetricSource); + phMetricGroup = mockMetricGroup->toHandle(); +} + +void CalcOperationFixture::TearDown() { + DeviceFixture::tearDown(); + delete mockMetricGroup; +} + +TEST_F(CalcOperationFixture, WhenCreatingCalcOpAndInvalidParamsPassedThenErrorIsHandled) { + + // Aggregation window is zero + zet_intel_metric_calculate_exp_desc_t calculateDesc{ + ZET_INTEL_STRUCTURE_TYPE_METRIC_CALCULATE_DESC_EXP, + nullptr, // pNext + 1, // metricGroupCount + &phMetricGroup, // phMetricGroups + 0, // metricCount + nullptr, // phMetrics + 0, // timeWindowsCount + nullptr, // pCalculateTimeWindows + 0, // timeAggregationWindow, zero is not accepted + }; + + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation; + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zetIntelMetricCalculateOperationCreateExp(context->toHandle(), + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); + + // No metric groups or metrics + calculateDesc.timeAggregationWindow = 100; + calculateDesc.metricGroupCount = 0; + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zetIntelMetricCalculateOperationCreateExp(context->toHandle(), + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); +} + +TEST_F(CalcOperationFixture, WhenCreatingCalcOpWithMixedSourcesThenErrorIsReturned) { + + MockMetricSource mockMetricSource2{}; + mockMetricSource2.setType(UINT32_MAX); + MockMetricGroup mockMetricGroup2(mockMetricSource2); + + // metric groups from different source + std::vector metricGroups{phMetricGroup, mockMetricGroup2.toHandle()}; + zet_intel_metric_calculate_exp_desc_t calculateDesc{ + ZET_INTEL_STRUCTURE_TYPE_METRIC_CALCULATE_DESC_EXP, + nullptr, // pNext + 2, // metricGroupCount + metricGroups.data(), // phMetricGroups + 0, // metricCount + nullptr, // phMetrics + 0, // timeWindowsCount + nullptr, // pCalculateTimeWindows + 1000, // timeAggregationWindow + }; + + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation; + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zetIntelMetricCalculateOperationCreateExp(context, + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); + + // metrics from different source + MockMetric mockMetric(mockMetricSource); + MockMetric mockMetric2(mockMetricSource2); + std::vector metrics{mockMetric.toHandle(), mockMetric2.toHandle()}; + + calculateDesc.metricGroupCount = 1; + calculateDesc.phMetricGroups = &phMetricGroup; + calculateDesc.metricCount = 2; + calculateDesc.phMetrics = metrics.data(); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zetIntelMetricCalculateOperationCreateExp(context, + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); + + // metrics and metric group from different source + calculateDesc.metricCount = 1; + calculateDesc.phMetrics = &metrics[1]; + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zetIntelMetricCalculateOperationCreateExp(context, + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); +} + +TEST_F(CalcOperationFixture, WhenCreatingCalcOpWithMixedHierarchiesThenErrorIsReturned) { + MockMetricGroup mockMetricGroup2(mockMetricSource); + mockMetricGroup2.isMultiDevice = true; + + // metric groups from different hierarchy + std::vector metricGroups{phMetricGroup, mockMetricGroup2.toHandle()}; + zet_intel_metric_calculate_exp_desc_t calculateDesc{ + ZET_INTEL_STRUCTURE_TYPE_METRIC_CALCULATE_DESC_EXP, + nullptr, // pNext + 2, // metricGroupCount + metricGroups.data(), // phMetricGroups + 0, // metricCount + nullptr, // phMetrics + 0, // timeWindowsCount + nullptr, // pCalculateTimeWindows + 1000, // timeAggregationWindow + }; + + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation; + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zetIntelMetricCalculateOperationCreateExp(context, + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); + + MockMetric mockMetric(mockMetricSource), mockMetric2(mockMetricSource); + mockMetric2.setMultiDevice(true); + + std::vector metrics{mockMetric.toHandle(), mockMetric2.toHandle()}; + + calculateDesc.metricGroupCount = 1; + calculateDesc.phMetricGroups = &phMetricGroup; + calculateDesc.metricCount = 2; + calculateDesc.phMetrics = metrics.data(); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zetIntelMetricCalculateOperationCreateExp(context, + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); +} + +TEST_F(CalcOperationFixture, WhenCreatingCalcOpUseTheSourceFromMetricGroupOrMetricWhenAvailable) { + + MockMetricGroup mockMetricGroup2(mockMetricSource); + + std::vector metricGroups{phMetricGroup, mockMetricGroup2.toHandle()}; + zet_intel_metric_calculate_exp_desc_t calculateDesc{ + ZET_INTEL_STRUCTURE_TYPE_METRIC_CALCULATE_DESC_EXP, + nullptr, // pNext + 2, // metricGroupCount + metricGroups.data(), // phMetricGroups + 0, // metricCount + nullptr, // phMetrics + 0, // timeWindowsCount + nullptr, // pCalculateTimeWindows + 1000, // timeAggregationWindow + }; + + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zetIntelMetricCalculateOperationCreateExp(context, + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); + + MockMetric mockMetric(mockMetricSource), mockMetric2(mockMetricSource); + std::vector metrics{mockMetric.toHandle(), mockMetric.toHandle()}; + + calculateDesc.metricGroupCount = 0; + calculateDesc.phMetricGroups = nullptr; + calculateDesc.metricCount = 2; + calculateDesc.phMetrics = metrics.data(); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zetIntelMetricCalculateOperationCreateExp(context, + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); +} + +TEST_F(CalcOperationFixture, WhenCreatingCalcOpObjectToAndFromHandleBaseClassWorkAsExpected) { + MockMetricCalcOp mockMetricCalcOp{}; + auto hMockCalcOp = mockMetricCalcOp.toHandle(); + + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zetIntelMetricCalculateOperationDestroyExp(hMockCalcOp)); + EXPECT_EQ(false, mockMetricCalcOp.isRootDevice()); + auto mockCalcOp = MetricCalcOp::fromHandle(hMockCalcOp); + EXPECT_NE(nullptr, mockCalcOp); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_enumeration.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_enumeration.cpp index 9e5fc82a89..caf1f75a96 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_enumeration.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_ip_sampling_enumeration.cpp @@ -1297,5 +1297,37 @@ HWTEST2_F(MetricIpSamplingEnumerationTest, GivenEnumerationIsSuccessfulWhenUnsup } } +HWTEST2_F(MetricIpSamplingEnumerationTest, givenValidIPSamplingMetricGroupThenOASourceCalcOperationIsCalled, EustallSupportedPlatforms) { + + EXPECT_EQ(ZE_RESULT_SUCCESS, testDevices[0]->getMetricDeviceContext().enableMetricApi()); + + uint32_t metricGroupCount = 1; + zet_metric_group_handle_t metricGroupHandle = nullptr; + EXPECT_EQ(zetMetricGroupGet(testDevices[0]->toHandle(), &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + EXPECT_NE(metricGroupHandle, nullptr); + + // metric groups from different source + zet_intel_metric_calculate_exp_desc_t calculateDesc{ + ZET_INTEL_STRUCTURE_TYPE_METRIC_CALCULATE_DESC_EXP, + nullptr, // pNext + 1, // metricGroupCount + &metricGroupHandle, // phMetricGroups + 0, // metricCount + nullptr, // phMetrics + 0, // timeWindowsCount + nullptr, // pCalculateTimeWindows + 1000, // timeAggregationWindow + }; + + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation; + uint32_t excludedMetricsCount = 0; + zet_metric_handle_t *phExcludedMetrics = nullptr; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zetIntelMetricCalculateOperationCreateExp(context->toHandle(), + testDevices[0]->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); +} + } // namespace ult } // namespace L0 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 40b78805d5..a0b10862c9 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 @@ -3489,6 +3489,77 @@ TEST_F(MetricEnumerationTest, givenValidArgumentsWhenAppendMarkerIsCalledThenRet EXPECT_EQ(zetIntelCommandListAppendMarkerExp(commandList->toHandle(), metricGroupHandle, 0), ZE_RESULT_SUCCESS); } +TEST_F(MetricEnumerationTest, givenValidOAMetricGroupThenOASourceCalcOperationIsCalled) { + + // Metrics Discovery device. + metricsDeviceParams.ConcurrentGroupsCount = 1; + + // Metrics Discovery concurrent group. + Mock metricsConcurrentGroup; + TConcurrentGroupParams_1_13 metricsConcurrentGroupParams = {}; + metricsConcurrentGroupParams.SymbolName = "OA"; + metricsConcurrentGroupParams.MetricSetsCount = 1; + metricsConcurrentGroupParams.IoMeasurementInformationCount = 1; + + Mock ioReadEquation; + MetricsDiscovery::TEquationElement_1_0 ioEquationElement = {}; + ioEquationElement.Type = MetricsDiscovery::EQUATION_ELEM_IMM_UINT64; + ioEquationElement.ImmediateUInt64 = 0; + + ioReadEquation.getEquationElement.push_back(&ioEquationElement); + + Mock ioMeasurement; + MetricsDiscovery::TInformationParams_1_0 oaInformation = {}; + oaInformation.SymbolName = "BufferOverflow"; + oaInformation.IoReadEquation = &ioReadEquation; + metricsConcurrentGroup.GetIoMeasurementInformationResult = &ioMeasurement; + ioMeasurement.GetParamsResult = &oaInformation; + + // Metrics Discovery:: metric set. + Mock metricsSet; + MetricsDiscovery::TMetricSetParams_1_11 metricsSetParams = {}; + metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_OCL; + + openMetricsAdapter(); + + setupDefaultMocksForMetricDevice(metricsDevice); + + metricsDevice.getConcurrentGroupResults.push_back(&metricsConcurrentGroup); + + metricsConcurrentGroup.GetParamsResult = &metricsConcurrentGroupParams; + metricsConcurrentGroup.getMetricSetResult = &metricsSet; + + metricsSet.GetParamsResult = &metricsSetParams; + + // Metric group handle. + uint32_t metricGroupCount = 1; + zet_metric_group_handle_t metricGroupHandle = {}; + EXPECT_EQ(zetMetricGroupGet(device->toHandle(), &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + EXPECT_NE(metricGroupHandle, nullptr); + + // metric groups from different source + zet_intel_metric_calculate_exp_desc_t calculateDesc{ + ZET_INTEL_STRUCTURE_TYPE_METRIC_CALCULATE_DESC_EXP, + nullptr, // pNext + 1, // metricGroupCount + &metricGroupHandle, // phMetricGroups + 0, // metricCount + nullptr, // phMetrics + 0, // timeWindowsCount + nullptr, // pCalculateTimeWindows + 1000, // timeAggregationWindow + }; + + zet_intel_metric_calculate_operation_exp_handle_t hCalculateOperation; + uint32_t excludedMetricsCount = 0; + zet_metric_handle_t *phExcludedMetrics = nullptr; + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zetIntelMetricCalculateOperationCreateExp(context->toHandle(), + device->toHandle(), &calculateDesc, + &excludedMetricsCount, phExcludedMetrics, + &hCalculateOperation)); +} + using AppendMarkerDriverVersionTest = Test; TEST_F(AppendMarkerDriverVersionTest, givenSupportedExtensionsWhenCheckIfAppendMarkerIsSupportedThenCorrectResultsAreReturned) {