diff --git a/level_zero/api/driver_experimental/public/zex_metric.cpp b/level_zero/api/driver_experimental/public/zex_metric.cpp index e6e08f1740..7d98f80263 100644 --- a/level_zero/api/driver_experimental/public/zex_metric.cpp +++ b/level_zero/api/driver_experimental/public/zex_metric.cpp @@ -119,6 +119,14 @@ ze_result_t ZE_APICALL zetIntelMetricDecodeCalculateMultipleValuesExp(zet_intel_ pSetCount, pMetricReportCountPerSet, pTotalMetricReportCount, pMetricResults); } +ze_result_t ZE_APICALL zetIntelMetricScopesGetExp(zet_context_handle_t hContext, zet_device_handle_t hDevice, uint32_t *pMetricScopesCount, zet_intel_metric_scope_exp_handle_t *phMetricScopes) { + return L0::metricScopesGet(hContext, hDevice, pMetricScopesCount, phMetricScopes); +} + +ze_result_t ZE_APICALL zetIntelMetricScopeGetPropertiesExp(zet_intel_metric_scope_exp_handle_t hMetricScope, zet_intel_metric_scope_properties_exp_t *pMetricScopeProperties) { + return L0::metricScopeGetProperties(hMetricScope, pMetricScopeProperties); +} + } // namespace L0 extern "C" { @@ -251,4 +259,12 @@ ze_result_t ZE_APICALL zetIntelMetricDecodeCalculateMultipleValuesExp(zet_metric pMetricReportCountPerSet, pTotalMetricReportCount, pMetricResults); } +ze_result_t ZE_APICALL zetIntelMetricScopesGetExp(zet_context_handle_t hContext, zet_device_handle_t hDevice, uint32_t *pMetricScopesCount, zet_intel_metric_scope_exp_handle_t *phMetricScopes) { + return L0::zetIntelMetricScopesGetExp(hContext, hDevice, pMetricScopesCount, phMetricScopes); +} + +ze_result_t ZE_APICALL zetIntelMetricScopeGetPropertiesExp(zet_intel_metric_scope_exp_handle_t hMetricScope, zet_intel_metric_scope_properties_exp_t *pMetricScopeProperties) { + return L0::zetIntelMetricScopeGetPropertiesExp(hMetricScope, pMetricScopeProperties); +} + } // extern "C" diff --git a/level_zero/core/source/driver/driver_handle_imp_helper.cpp b/level_zero/core/source/driver/driver_handle_imp_helper.cpp index 560e23f909..693e210ccc 100644 --- a/level_zero/core/source/driver/driver_handle_imp_helper.cpp +++ b/level_zero/core/source/driver/driver_handle_imp_helper.cpp @@ -60,6 +60,7 @@ const std::vector> DriverHandleImp::extensionsS {ZET_INTEL_METRIC_SOURCE_ID_EXP_NAME, ZET_INTEL_METRIC_SOURCE_ID_EXP_VERSION_CURRENT}, {ZET_INTEL_METRIC_CALCULATE_EXP_NAME, ZET_INTEL_METRIC_CALCULATE_EXP_VERSION_CURRENT}, {ZET_METRICS_RUNTIME_ENABLE_DISABLE_EXP_NAME, ZET_METRICS_RUNTIME_ENABLE_DISABLE_EXP_VERSION_CURRENT}, + {ZET_INTEL_METRIC_SCOPES_EXP_NAME, ZET_INTEL_METRIC_SCOPES_EXP_VERSION_CURRENT}, #include "additional_extensions_support.inl" }; diff --git a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h index 05070671e9..9eae9da432 100644 --- a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h +++ b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h @@ -117,6 +117,8 @@ class L0GfxCoreHelper : public NEO::ApiGfxCoreHelper { virtual CopyOffloadMode getDefaultCopyOffloadMode(bool additionalBlitPropertiesSupported) const = 0; virtual bool isDefaultCmdListWithCopyOffloadSupported(bool additionalBlitPropertiesSupported) const = 0; + virtual bool supportMetricsAggregation() const = 0; + protected: L0GfxCoreHelper() = default; }; @@ -175,6 +177,8 @@ class L0GfxCoreHelperHw : public L0GfxCoreHelper { CopyOffloadMode getDefaultCopyOffloadMode(bool additionalBlitPropertiesSupported) const override; bool isDefaultCmdListWithCopyOffloadSupported(bool additionalBlitPropertiesSupported) const override; + bool supportMetricsAggregation() const override; + protected: L0GfxCoreHelperHw() = default; }; diff --git a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_tgllp_to_dg2.inl b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_tgllp_to_dg2.inl index c179664c0b..7f932ea592 100644 --- a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_tgllp_to_dg2.inl +++ b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_tgllp_to_dg2.inl @@ -149,4 +149,9 @@ uint64_t L0GfxCoreHelperHw::getIpSamplingIpMask() const { return 0; } +template +bool L0GfxCoreHelperHw::supportMetricsAggregation() const { + return false; +} + } // namespace L0 diff --git a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_xe2_hpg_and_later.inl b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_xe2_hpg_and_later.inl index 1ffa5c1257..0132b4078e 100644 --- a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_xe2_hpg_and_later.inl +++ b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_xe2_hpg_and_later.inl @@ -222,4 +222,9 @@ uint64_t L0GfxCoreHelperHw::getOaTimestampValidBits() const { return oaTimestampValidBits; }; +template +bool L0GfxCoreHelperHw::supportMetricsAggregation() const { + return false; +} + } // namespace L0 diff --git a/level_zero/core/source/xe_hpc_core/l0_gfx_core_helper_xe_hpc_core.cpp b/level_zero/core/source/xe_hpc_core/l0_gfx_core_helper_xe_hpc_core.cpp index 584e5d0ec6..408420e21b 100644 --- a/level_zero/core/source/xe_hpc_core/l0_gfx_core_helper_xe_hpc_core.cpp +++ b/level_zero/core/source/xe_hpc_core/l0_gfx_core_helper_xe_hpc_core.cpp @@ -215,6 +215,11 @@ uint64_t L0GfxCoreHelperHw::getIpSamplingIpMask() const { return ipSamplingIpMaskXe; } +template <> +bool L0GfxCoreHelperHw::supportMetricsAggregation() const { + return false; +} + template class L0GfxCoreHelperHw; } // namespace L0 diff --git a/level_zero/core/test/unit_tests/gen12lp/test_l0_gfx_core_helper_gen12lp.cpp b/level_zero/core/test/unit_tests/gen12lp/test_l0_gfx_core_helper_gen12lp.cpp index b69914e4e3..636bfde263 100644 --- a/level_zero/core/test/unit_tests/gen12lp/test_l0_gfx_core_helper_gen12lp.cpp +++ b/level_zero/core/test/unit_tests/gen12lp/test_l0_gfx_core_helper_gen12lp.cpp @@ -115,5 +115,13 @@ GEN12LPTEST_F(L0GfxCoreHelperTestGen12Lp, GivenGen12LpWhenGetIpSamplingIpMaskIsC EXPECT_EQ(0u, l0GfxCoreHelper.getIpSamplingIpMask()); } +GEN12LPTEST_F(L0GfxCoreHelperTestGen12Lp, GivenL0GfxCoreHelperWhenCheckingMetricsAggregationSupportThenReturnFalse) { + MockExecutionEnvironment executionEnvironment; + auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0].get(); + auto &l0GfxCoreHelper = rootDeviceEnvironment.getHelper(); + + EXPECT_FALSE(l0GfxCoreHelper.supportMetricsAggregation()); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/core/test/unit_tests/xe2_hpg_core/test_l0_gfx_core_helper_xe2_hpg_core.cpp b/level_zero/core/test/unit_tests/xe2_hpg_core/test_l0_gfx_core_helper_xe2_hpg_core.cpp index 94b9bbe7b9..19e0ae8f8c 100644 --- a/level_zero/core/test/unit_tests/xe2_hpg_core/test_l0_gfx_core_helper_xe2_hpg_core.cpp +++ b/level_zero/core/test/unit_tests/xe2_hpg_core/test_l0_gfx_core_helper_xe2_hpg_core.cpp @@ -155,5 +155,13 @@ XE2_HPG_CORETEST_F(L0GfxCoreHelperTestXe2Hpg, GivenXe2HpgWhenCheckingL0HelperFor EXPECT_EQ(56u, l0GfxCoreHelper.getOaTimestampValidBits()); } +XE2_HPG_CORETEST_F(L0GfxCoreHelperTestXe2Hpg, GivenL0GfxCoreHelperWhenCheckingMetricsAggregationSupportThenReturnFalse) { + MockExecutionEnvironment executionEnvironment; + auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0].get(); + auto &l0GfxCoreHelper = rootDeviceEnvironment.getHelper(); + + EXPECT_FALSE(l0GfxCoreHelper.supportMetricsAggregation()); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/core/test/unit_tests/xe_hpc_core/test_l0_gfx_core_helper_xe_hpc_core.cpp b/level_zero/core/test/unit_tests/xe_hpc_core/test_l0_gfx_core_helper_xe_hpc_core.cpp index 76ab33bf27..0a07cfa502 100644 --- a/level_zero/core/test/unit_tests/xe_hpc_core/test_l0_gfx_core_helper_xe_hpc_core.cpp +++ b/level_zero/core/test/unit_tests/xe_hpc_core/test_l0_gfx_core_helper_xe_hpc_core.cpp @@ -96,5 +96,10 @@ XE_HPC_CORETEST_F(L0GfxCoreHelperTestXeHpc, GivenXeHpcWhenCheckingL0HelperForGet EXPECT_EQ(32u, l0GfxCoreHelper.getOaTimestampValidBits()); } +XE_HPC_CORETEST_F(L0GfxCoreHelperTestXeHpc, GivenL0GfxCoreHelperWhenCheckingMetricsAggregationSupportThenReturnFalse) { + auto &l0GfxCoreHelper = getHelper(); + EXPECT_FALSE(l0GfxCoreHelper.supportMetricsAggregation()); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/core/test/unit_tests/xe_hpg_core/test_l0_gfx_core_helper_xe_hpg_core.cpp b/level_zero/core/test/unit_tests/xe_hpg_core/test_l0_gfx_core_helper_xe_hpg_core.cpp index 20c541e0c9..8b000b48c7 100644 --- a/level_zero/core/test/unit_tests/xe_hpg_core/test_l0_gfx_core_helper_xe_hpg_core.cpp +++ b/level_zero/core/test/unit_tests/xe_hpg_core/test_l0_gfx_core_helper_xe_hpg_core.cpp @@ -118,5 +118,13 @@ XE_HPG_CORETEST_F(L0GfxCoreHelperTestXeHpg, GivenXeHpgWhenGetIpSamplingIpMaskIsC EXPECT_EQ(0u, l0GfxCoreHelper.getIpSamplingIpMask()); } +XE_HPG_CORETEST_F(L0GfxCoreHelperTestXeHpg, GivenL0GfxCoreHelperWhenCheckingMetricsAggregationSupportThenReturnFalse) { + MockExecutionEnvironment executionEnvironment; + auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0].get(); + auto &l0GfxCoreHelper = rootDeviceEnvironment.getHelper(); + + EXPECT_FALSE(l0GfxCoreHelper.supportMetricsAggregation()); +} + } // namespace ult } // namespace L0 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 5a0a1721d4..eabff2bf2e 100644 --- a/level_zero/include/level_zero/zet_intel_gpu_metric.h +++ b/level_zero/include/level_zero/zet_intel_gpu_metric.h @@ -203,6 +203,10 @@ typedef enum _zet_intel_metric_calculate_exp_version_t { ZET_INTEL_METRIC_CALCULATE_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } zet_intel_metric_calculate_exp_version_t; +#ifndef ZET_STRUCTURE_TYPE_INTEL_METRIC_CALCULATE_PROPERTIES_EXP +#define ZET_STRUCTURE_TYPE_INTEL_METRIC_CALCULATE_PROPERTIES_EXP 0x7fffffff +#endif // ZET_STRUCTURE_TYPE_INTEL_METRIC_CALCULATE_PROPERTIES_EXP + /////////////////////////////////////////////////////////////////////////////// /// @brief Query an metric group calculate properties /// This structure can be passed in the 'pNext' of zet_metric_group_properties_t @@ -432,8 +436,60 @@ ze_result_t ZE_APICALL zetIntelDeviceEnableMetricsExp(zet_device_handle_t hDevic /// is returned. ze_result_t ZE_APICALL zetIntelDeviceDisableMetricsExp(zet_device_handle_t hDevice); +#ifndef ZET_INTEL_METRIC_SCOPES_EXP_NAME +/// @brief Extension name to query Intel Metric Scopes operations +#define ZET_INTEL_METRIC_SCOPES_EXP_NAME "ZET_intel_metric_scopes" +#endif // ZET_INTEL_METRIC_SCOPES_EXP_NAME +typedef enum _zet_intel_metric_scopes_exp_version_t { + ZET_INTEL_METRIC_SCOPES_EXP_VERSION_1_0 = ZE_MAKE_VERSION(1, 0), ///< version 1.0 + ZET_INTEL_METRIC_SCOPES_EXP_VERSION_CURRENT = ZET_INTEL_METRIC_SCOPES_EXP_VERSION_1_0, ///< latest known version + ZET_INTEL_METRIC_SCOPES_EXP_VERSION_FORCE_UINT32 = 0x7fffffff +} zet_intel_metric_scopes_exp_version_t; + +/// @brief Handle of metric scope +struct _zet_intel_metric_scope_exp_handle_t {}; +typedef struct _zet_intel_metric_scope_exp_handle_t *zet_intel_metric_scope_exp_handle_t; + +#define ZET_INTEL_MAX_METRIC_SCOPE_NAME_EXP 64u +#define ZET_INTEL_MAX_METRIC_SCOPE_DESCRIPTION_EXP 128u + +#ifndef ZET_STRUCTURE_TYPE_INTEL_METRIC_SCOPE_PROPERTIES_EXP +#define ZET_STRUCTURE_TYPE_INTEL_METRIC_SCOPE_PROPERTIES_EXP 0x7fffffff +#endif // ZET_STRUCTURE_TYPE_INTEL_METRIC_SCOPE_PROPERTIES_EXP + +/// @brief Query an metric scope properties +typedef struct _zet_intel_metric_scope_properties_exp_t { + zet_structure_type_ext_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). + uint16_t iD; ///< [out ]ID will be equal to the index of the metric scope in the + ///> array returned by zetMetricScopesGet() + char name[ZET_INTEL_MAX_METRIC_SCOPE_NAME_EXP]; ///< [out] name of the metric scope, which is unique for the device. + ///< The name is expected to be a human readable string. + ///< The name can be used to identify the metric scope in the UI. + char description[ZET_INTEL_MAX_METRIC_SCOPE_DESCRIPTION_EXP]; ///< [out] description of the metric scope, which is unique for the device. + ///< The description is expected to be a human readable string. + ///< The description can be used to provide additional information about + ///< the metric scope in the UI. +} zet_intel_metric_scope_properties_exp_t; + +ze_result_t ZE_APICALL zetIntelMetricScopesGetExp( + zet_context_handle_t hContext, ///< [in] handle of the context object + zet_device_handle_t hDevice, ///< [in] handle of the device + uint32_t *pMetricScopesCount, ///< [in,out] pointer to the number of metric scopes available for the device. + ///< If set to zero, then the driver shall update the value with the total + ///< number of metric scopes available for the device. + zet_intel_metric_scope_exp_handle_t *phMetricScopes); ///< [out][optional] [range(0, *pMetricScopesCount)] array of metric scopes handles + ///< available for the device. If pMetricScopesCount is greater than zero but + ///< less than the total number of metric scopes available for the device, + ///< then driver shall only return that number of metric scopes. + +ze_result_t ZE_APICALL zetIntelMetricScopeGetPropertiesExp( + zet_intel_metric_scope_exp_handle_t hMetricScope, ///< [in] handle of the metric scope + zet_intel_metric_scope_properties_exp_t *pMetricScopeProperties); ///< [out] pointer to the metric scope properties structure + #if defined(__cplusplus) } // extern "C" #endif -#endif +#endif //_ZET_INTEL_GPU_METRIC_H diff --git a/level_zero/tools/source/metrics/metric.cpp b/level_zero/tools/source/metrics/metric.cpp index 3d27226a0e..06304f5b51 100644 --- a/level_zero/tools/source/metrics/metric.cpp +++ b/level_zero/tools/source/metrics/metric.cpp @@ -9,11 +9,15 @@ #include "shared/source/device/sub_device.h" #include "shared/source/execution_environment/execution_environment.h" +#include "shared/source/execution_environment/root_device_environment.h" +#include "shared/source/helpers/gfx_core_helper.h" +#include "shared/source/helpers/hw_info.h" #include "level_zero/core/source/device/device.h" #include "level_zero/core/source/device/device_imp.h" #include "level_zero/core/source/driver/driver.h" #include "level_zero/core/source/driver/driver_handle_imp.h" +#include "level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h" #include "level_zero/tools/source/metrics/metric_ip_sampling_source.h" #include "level_zero/tools/source/metrics/metric_oa_source.h" @@ -28,6 +32,48 @@ void MetricSource::getMetricGroupSourceIdProperty(zet_base_properties_t *propert groupProperty->sourceId = type; } +void MetricSource::initComputeMetricScopes(MetricDeviceContext &metricDeviceContext) { + + auto createScope = [&metricDeviceContext](const std::string &name, const std::string &desc, uint32_t id) { + zet_intel_metric_scope_properties_exp_t scopeProperties = {ZET_STRUCTURE_TYPE_INTEL_METRIC_SCOPE_PROPERTIES_EXP, nullptr}; + scopeProperties.iD = id; + snprintf(scopeProperties.name, ZET_INTEL_MAX_METRIC_SCOPE_NAME_EXP, "%s", name.c_str()); + snprintf(scopeProperties.description, ZET_INTEL_MAX_METRIC_SCOPE_NAME_EXP, "%s", desc.c_str()); + + auto metricScopeImp = MetricScopeImp::create(scopeProperties); + DEBUG_BREAK_IF(metricScopeImp == nullptr); + metricDeviceContext.addMetricScope(std::move(metricScopeImp)); + }; + + if (metricDeviceContext.isMultiDeviceCapable()) { + + auto deviceImp = static_cast(&metricDeviceContext.getDevice()); + uint32_t subDeviceCount = deviceImp->numSubDevices; + for (uint32_t i = 0; i < subDeviceCount; i++) { + std::string scopeName = "COMPUTE_TILE_" + std::to_string(i); + std::string scopeDesc = "Metrics results for tile " + std::to_string(i); + + createScope(scopeName, scopeDesc, i); + } + + auto &l0GfxCoreHelper = metricDeviceContext.getDevice().getNEODevice()->getRootDeviceEnvironment().getHelper(); + if (l0GfxCoreHelper.supportMetricsAggregation()) { + std::string scopeName = "DEVICE_AGGREGATED"; + std::string scopeDesc = "Metrics results aggregated at device level"; + + createScope(scopeName, scopeDesc, subDeviceCount); + } + } else { + auto subDeviceIndex = metricDeviceContext.getSubDeviceIndex(); + std::string scopeName = "COMPUTE_TILE_" + std::to_string(subDeviceIndex); + std::string scopeDesc = "Metrics results for tile " + std::to_string(subDeviceIndex); + + createScope(scopeName, scopeDesc, subDeviceIndex); + } + + metricDeviceContext.setComputeMetricScopeInitialized(); +} + MetricDeviceContext::MetricDeviceContext(Device &inputDevice) : device(inputDevice) { auto deviceNeo = device.getNEODevice(); std::tuple subDeviceMap; @@ -93,6 +139,11 @@ ze_result_t MetricDeviceContext::metricGroupGet(uint32_t *pCount, zet_metric_gro ze_result_t result = ZE_RESULT_SUCCESS; uint32_t availableCount = 0; uint32_t requestCount = *pCount; + + if (!metricScopesInitialized) { + initMetricScopes(); + } + for (auto const &entry : metricSources) { auto const &metricSource = entry.second; @@ -198,14 +249,6 @@ ze_result_t MetricDeviceContext::activateMetricGroups() { return ZE_RESULT_SUCCESS; } -uint32_t MetricDeviceContext::getSubDeviceIndex() const { - return subDeviceIndex; -} - -Device &MetricDeviceContext::getDevice() const { - return device; -} - void MetricDeviceContext::enableMetricApiForDevice(zet_device_handle_t hDevice, bool &isFailed) { auto deviceImp = static_cast(L0::Device::fromHandle(hDevice)); @@ -602,6 +645,53 @@ ze_result_t MetricDeviceContext::calcOperationCreate(zet_context_handle_t hConte return metricSource.calcOperationCreate(*this, pCalculateDesc, pExcludedMetricCount, phExcludedMetrics, phCalculateOperation); } +std::unique_ptr MetricScopeImp::create(zet_intel_metric_scope_properties_exp_t &scopeProperties) { + return std::make_unique(scopeProperties); +} + +void MetricDeviceContext::initMetricScopes() { + + for (auto const &entry : metricSources) { + auto const &metricSource = entry.second; + + if (!metricSource->isAvailable()) { + continue; + } + metricSource->initMetricScopes(*this); + } + + metricScopesInitialized = true; +} + +ze_result_t MetricDeviceContext::metricScopesGet(zet_context_handle_t hContext, uint32_t *pMetricScopesCount, + zet_intel_metric_scope_exp_handle_t *phMetricScopes) { + + if (!metricScopesInitialized) { + initMetricScopes(); + } + + if (*pMetricScopesCount == 0) { + *pMetricScopesCount = static_cast(metricScopes.size()); + return ZE_RESULT_SUCCESS; + } + + // User is expected to allocate space. + DEBUG_BREAK_IF(phMetricScopes == nullptr); + + *pMetricScopesCount = std::min(*pMetricScopesCount, static_cast(metricScopes.size())); + + for (uint32_t i = 0; i < *pMetricScopesCount; i++) { + phMetricScopes[i] = metricScopes[i]->toHandle(); + } + + return ZE_RESULT_SUCCESS; +} + +ze_result_t MetricScopeImp::getProperties(zet_intel_metric_scope_properties_exp_t *pProperties) { + *pProperties = properties; + return ZE_RESULT_SUCCESS; +} + ze_result_t MultiDeviceMetricImp::getProperties(zet_metric_properties_t *pProperties) { return subDeviceMetrics[0]->getProperties(pProperties); } @@ -970,4 +1060,21 @@ ze_result_t metricsDisable(zet_device_handle_t hDevice) { return MetricDeviceContext::disableMetricApiForDevice(hDevice); } +ze_result_t metricScopesGet( + zet_context_handle_t hContext, + zet_device_handle_t hDevice, + uint32_t *pMetricScopesCount, + zet_intel_metric_scope_exp_handle_t *phMetricScopes) { + + DeviceImp *deviceImp = static_cast(L0::Device::fromHandle(hDevice)); + return deviceImp->getMetricDeviceContext().metricScopesGet(hContext, pMetricScopesCount, phMetricScopes); +} + +ze_result_t metricScopeGetProperties( + zet_intel_metric_scope_exp_handle_t hMetricScope, + zet_intel_metric_scope_properties_exp_t *pMetricScopeProperties) { + + return static_cast(MetricScopeImp::fromHandle(hMetricScope))->getProperties(pMetricScopeProperties); +} + } // namespace L0 diff --git a/level_zero/tools/source/metrics/metric.h b/level_zero/tools/source/metrics/metric.h index 8b6afa588a..4787bf4f6d 100644 --- a/level_zero/tools/source/metrics/metric.h +++ b/level_zero/tools/source/metrics/metric.h @@ -68,6 +68,7 @@ struct CommandList; struct MetricStreamer; struct MetricProgrammable; class MetricDeviceContext; +struct MetricScopeImp; class MetricSource { public: static constexpr uint32_t metricSourceTypeUndefined = 0u; @@ -109,10 +110,12 @@ class MetricSource { zet_metric_handle_t *phExcludedMetrics, zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) = 0; virtual bool canDisable() = 0; + virtual void initMetricScopes(MetricDeviceContext &metricDeviceContext) = 0; protected: uint32_t type = MetricSource::metricSourceTypeUndefined; void getMetricGroupSourceIdProperty(zet_base_properties_t *property); + void initComputeMetricScopes(MetricDeviceContext &metricDeviceContext); }; class MultiDomainDeferredActivationTracker { @@ -137,7 +140,7 @@ class MetricDeviceContext { public: MetricDeviceContext(Device &device); - virtual ~MetricDeviceContext() {} + ~MetricDeviceContext() {} ze_result_t metricGroupGet(uint32_t *pCount, zet_metric_group_handle_t *phMetricGroups); ze_result_t activateMetricGroupsPreferDeferred(uint32_t count, zet_metric_group_handle_t *phMetricGroups); ze_result_t activateMetricGroups(); @@ -148,8 +151,13 @@ class MetricDeviceContext { zet_metric_group_sampling_type_flag_t samplingType, zet_metric_group_handle_t *pMetricGroupHandle); bool isImplicitScalingCapable() const; - Device &getDevice() const; - uint32_t getSubDeviceIndex() const; + Device &getDevice() const { + return device; + } + uint32_t getSubDeviceIndex() const { + return subDeviceIndex; + } + template T &getMetricSource() const; void setSubDeviceIndex(uint32_t subDeviceIndex) { this->subDeviceIndex = subDeviceIndex; } @@ -172,8 +180,25 @@ class MetricDeviceContext { uint32_t *pExcludedMetricCount, zet_metric_handle_t *phExcludedMetrics, zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation); + ze_result_t metricScopesGet(zet_context_handle_t hContext, + uint32_t *pMetricScopesCount, + zet_intel_metric_scope_exp_handle_t *phMetricScopes); bool areMetricGroupsFromSameDeviceHierarchy(uint32_t count, zet_metric_group_handle_t *phMetricGroups); void setMetricsCollectionAllowed(bool status) { isMetricsCollectionAllowed = status; } + bool isMultiDeviceCapable() const { + return multiDeviceCapable; + } + void addMetricScope(std::unique_ptr metricScope) { + metricScopes.push_back(std::move(metricScope)); + } + + void setComputeMetricScopeInitialized() { + computeMetricScopesInitialized = true; + } + + bool isComputeMetricScopesInitialized() const { + return computeMetricScopesInitialized; + } protected: bool areMetricGroupsFromSameSource(uint32_t count, zet_metric_group_handle_t *phMetricGroups, uint32_t *sourceType); @@ -181,17 +206,22 @@ class MetricDeviceContext { bool areMetricsFromSameDeviceHierarchy(uint32_t count, zet_metric_handle_t *phMetrics); std::map> metricSources; + bool multiDeviceCapable = false; private: bool enable(); bool canDisable(); void disable(); + void initMetricScopes(); + struct Device &device; - bool multiDeviceCapable = false; uint32_t subDeviceIndex = 0; bool isMetricsCollectionAllowed = false; bool isEnableChecked = false; std::mutex enableMetricsMutex; + std::vector> metricScopes{}; + bool metricScopesInitialized = false; + bool computeMetricScopesInitialized = false; }; struct Metric : _zet_metric_handle_t { @@ -458,6 +488,27 @@ struct MetricCalcOpImp : public MetricCalcOp { bool isMultiDevice = false; }; +struct MetricScope : _zet_intel_metric_scope_exp_handle_t { + virtual ~MetricScope() = default; + MetricScope() {} + + static MetricScope *fromHandle(zet_intel_metric_scope_exp_handle_t handle) { + return static_cast(handle); + } + inline zet_intel_metric_scope_exp_handle_t toHandle() { return this; } +}; + +struct MetricScopeImp : public MetricScope { + ~MetricScopeImp() override = default; + MetricScopeImp(zet_intel_metric_scope_properties_exp_t &properties) : properties(properties){}; + + virtual ze_result_t getProperties(zet_intel_metric_scope_properties_exp_t *pProperties); + static std::unique_ptr create(zet_intel_metric_scope_properties_exp_t &scopeProperties); + + private: + zet_intel_metric_scope_properties_exp_t properties; +}; + // MetricGroup. ze_result_t metricGroupGet(zet_device_handle_t hDevice, uint32_t *pCount, zet_metric_group_handle_t *phMetricGroups); @@ -535,5 +586,8 @@ ze_result_t metricDecodeCalculateMultipleValues(zet_intel_metric_decoder_exp_han ze_result_t metricsEnable(zet_device_handle_t hDevice); ze_result_t metricsDisable(zet_device_handle_t hDevice); +ze_result_t metricScopesGet(zet_context_handle_t hContext, zet_device_handle_t hDevice, uint32_t *pMetricScopesCount, + zet_intel_metric_scope_exp_handle_t *phMetricScopes); +ze_result_t metricScopeGetProperties(zet_intel_metric_scope_exp_handle_t hMetricScope, zet_intel_metric_scope_properties_exp_t *pMetricScopeProperties); } // namespace L0 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 beda2bdcc5..d037e920d5 100644 --- a/level_zero/tools/source/metrics/metric_ip_sampling_source.cpp +++ b/level_zero/tools/source/metrics/metric_ip_sampling_source.cpp @@ -284,6 +284,12 @@ bool IpSamplingMetricSourceImp::canDisable() { return !activationTracker->isAnyMetricGroupActivated(); } +void IpSamplingMetricSourceImp::initMetricScopes(MetricDeviceContext &metricDeviceContext) { + if (!metricDeviceContext.isComputeMetricScopesInitialized()) { + initComputeMetricScopes(metricDeviceContext); + } +} + IpSamplingMetricGroupImp::IpSamplingMetricGroupImp(IpSamplingMetricSourceImp &metricSource, std::vector &metrics) : IpSamplingMetricGroupBase(metricSource) { this->metrics.reserve(metrics.size()); 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 e6cff44afb..628c3d1214 100644 --- a/level_zero/tools/source/metrics/metric_ip_sampling_source.h +++ b/level_zero/tools/source/metrics/metric_ip_sampling_source.h @@ -65,6 +65,7 @@ class IpSamplingMetricSourceImp : public MetricSource { uint32_t metricSourceCount = 0; bool canDisable() override; + void initMetricScopes(MetricDeviceContext &metricDeviceContext) override; protected: ze_result_t cacheMetricGroup(); diff --git a/level_zero/tools/source/metrics/metric_oa_source.cpp b/level_zero/tools/source/metrics/metric_oa_source.cpp index cb3b3944af..2129e1c78f 100644 --- a/level_zero/tools/source/metrics/metric_oa_source.cpp +++ b/level_zero/tools/source/metrics/metric_oa_source.cpp @@ -116,6 +116,12 @@ bool OaMetricSourceImp::canDisable() { return !activationTracker->isAnyMetricGroupActivated(); } +void OaMetricSourceImp::initMetricScopes(MetricDeviceContext &metricDeviceContext) { + if (!metricDeviceContext.isComputeMetricScopesInitialized()) { + initComputeMetricScopes(metricDeviceContext); + } +} + MetricsLibrary &OaMetricSourceImp::getMetricsLibrary() { return *metricsLibrary; } diff --git a/level_zero/tools/source/metrics/metric_oa_source.h b/level_zero/tools/source/metrics/metric_oa_source.h index 58526a3605..389dd96f18 100644 --- a/level_zero/tools/source/metrics/metric_oa_source.h +++ b/level_zero/tools/source/metrics/metric_oa_source.h @@ -72,6 +72,7 @@ class OaMetricSourceImp : public MetricSource { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } bool canDisable() override; + void initMetricScopes(MetricDeviceContext &metricDeviceContext) override; 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 ae39828a21..356a73ebf8 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 @@ -57,6 +57,11 @@ class MockMetricSource : public L0::MetricSource { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } bool canDisable() override { return false; } + void initMetricScopes(MetricDeviceContext &metricDeviceContext) override { + if (!metricDeviceContext.isComputeMetricScopesInitialized()) { + initComputeMetricScopes(metricDeviceContext); + } + }; ~MockMetricSource() override = default; }; @@ -189,6 +194,23 @@ class MockMetricDeviceContext : public MetricDeviceContext { void setMockMetricSource(MockMetricSource *metricSource) { metricSources[MetricSource::metricSourceTypeOa] = std::unique_ptr(metricSource); } + void setMockMetricSourceAtIndex(uint32_t index, MockMetricSource *metricSource) { + metricSources[index] = std::unique_ptr(metricSource); + } + + void setMultiDeviceCapable(bool capable) { + multiDeviceCapable = capable; + } +}; + +class MockMetricScope : public MetricScopeImp { + public: + ~MockMetricScope() override = default; + MockMetricScope(zet_intel_metric_scope_properties_exp_t &properties) + : MetricScopeImp(properties) {} + ze_result_t getProperties(zet_intel_metric_scope_properties_exp_t *pProperties) override { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } }; } // namespace ult 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 bdb19ac9df..b62ffc6270 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 @@ -283,5 +283,100 @@ TEST_F(MetricRuntimeFixture, WhenRunTimeEnableIsDoneAndNoSourcesAreAvailableThen deviceImp->metricContext.reset(); } +using MetricScopesFixture = Test; + +TEST_F(MetricScopesFixture, WhenGettingMetricScopeForSingleDeviceTheyAreCorrectlyEnumerated) { + + auto mockDeviceContext = new MockMetricDeviceContext(*device); + mockDeviceContext->clearAllSources(); + auto metricSource = new MockMetricSource(); + metricSource->isAvailableReturn = true; + mockDeviceContext->setMockMetricSource(metricSource); + auto deviceImp = static_cast(device); + deviceImp->metricContext.reset(mockDeviceContext); + + uint32_t metricScopesCount = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricScopesGetExp(context->toHandle(), + device->toHandle(), + &metricScopesCount, + nullptr)); + + EXPECT_EQ(metricScopesCount, 1u); + std::vector metricScopes(metricScopesCount); + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricScopesGetExp(context->toHandle(), + device->toHandle(), + &metricScopesCount, + metricScopes.data())); + EXPECT_EQ(metricScopesCount, 1u); + EXPECT_EQ(metricScopes.size(), 1u); +} + +TEST_F(MetricScopesFixture, WhenMultipleSourcesAreAvailableComputeMetricScopesAreEnumeratedOnlyOnce) { + + auto mockDeviceContext = new MockMetricDeviceContext(*device); + mockDeviceContext->clearAllSources(); + auto metricSource = new MockMetricSource(); + metricSource->isAvailableReturn = true; + mockDeviceContext->setMockMetricSource(metricSource); + + auto metricSource2 = new MockMetricSource(); + metricSource2->isAvailableReturn = true; + mockDeviceContext->setMockMetricSourceAtIndex(100, metricSource2); + + auto deviceImp = static_cast(device); + deviceImp->metricContext.reset(mockDeviceContext); + + uint32_t metricScopesCount = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricScopesGetExp(context->toHandle(), + device->toHandle(), + &metricScopesCount, + nullptr)); + EXPECT_EQ(metricScopesCount, 1u); +} + +TEST_F(MetricScopesFixture, GettingMetricsScopesPropertiesReturnsExpectedValues) { + + auto mockDeviceContext = new MockMetricDeviceContext(*device); + mockDeviceContext->clearAllSources(); + auto metricSource = new MockMetricSource(); + metricSource->isAvailableReturn = true; + mockDeviceContext->setMockMetricSource(metricSource); + auto deviceImp = static_cast(device); + deviceImp->metricContext.reset(mockDeviceContext); + + uint32_t metricScopesCount = 1; + zet_intel_metric_scope_exp_handle_t metricScope; + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricScopesGetExp(context->toHandle(), + device->toHandle(), + &metricScopesCount, + &metricScope)); + EXPECT_EQ(metricScopesCount, 1u); + zet_intel_metric_scope_properties_exp_t scopeProperties{}; + scopeProperties.stype = ZET_STRUCTURE_TYPE_INTEL_METRIC_SCOPE_PROPERTIES_EXP; + scopeProperties.pNext = nullptr; + + EXPECT_EQ(ZE_RESULT_SUCCESS, zetIntelMetricScopeGetPropertiesExp(metricScope, + &scopeProperties)); + + EXPECT_EQ(scopeProperties.iD, 0u); + EXPECT_STREQ(scopeProperties.name, "COMPUTE_TILE_0"); + EXPECT_STREQ(scopeProperties.description, "Metrics results for tile 0"); +} + +TEST_F(MetricScopesFixture, MetricScopeObjectToAndFromHandleBaseClassWorkAsExpected) { + + zet_intel_metric_scope_properties_exp_t scopeProperties{}; + scopeProperties.stype = ZET_STRUCTURE_TYPE_INTEL_METRIC_SCOPE_PROPERTIES_EXP; + scopeProperties.pNext = nullptr; + + MockMetricScope mockMetricScope(scopeProperties); + auto hMockScope = mockMetricScope.toHandle(); + + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zetIntelMetricScopeGetPropertiesExp(hMockScope, + &scopeProperties)); + auto mockScope = MetricScope::fromHandle(hMockScope); + EXPECT_NE(nullptr, mockScope); +} + } // 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 ad5418b2e2..79545255d0 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 @@ -1332,5 +1332,20 @@ HWTEST2_F(MetricIpSamplingEnumerationTest, GivenEnumerationIsSuccessfulWhenUnsup } } +HWTEST2_F(MetricIpSamplingEnumerationTest, GivenValidIpSamplingSourceComputeMetricScopesAreEnumeratedOnce, EustallSupportedPlatforms) { + + MetricDeviceContext &metricsDevContext = testDevices[0]->getMetricDeviceContext(); + EXPECT_EQ(ZE_RESULT_SUCCESS, metricsDevContext.enableMetricApi()); + + metricsDevContext.setComputeMetricScopeInitialized(); + + auto &metricSource = metricsDevContext.getMetricSource(); + EXPECT_EQ(metricSource.isAvailable(), true); + + uint32_t metricScopesCount = 0; + metricsDevContext.metricScopesGet(context->toHandle(), &metricScopesCount, nullptr); + EXPECT_EQ(metricScopesCount, 0u); +} + } // namespace ult } // namespace L0 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 a5d79c79d1..e23361d496 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-2024 Intel Corporation + * Copyright (C) 2021-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -104,6 +104,20 @@ TEST_F(MetricEnumerationTest, givenTTypedValueWhenCopyValueIsCalledReturnsFilled } } +TEST_F(MetricEnumerationTest, GivenValidOASourceComputeMetricScopesAreEnumeratedOnce) { + MetricDeviceContext &metricsDevContext = device->getMetricDeviceContext(); + EXPECT_EQ(ZE_RESULT_SUCCESS, metricsDevContext.enableMetricApi()); + + metricsDevContext.setComputeMetricScopeInitialized(); + + auto &metricSource = metricsDevContext.getMetricSource(); + EXPECT_EQ(metricSource.isAvailable(), true); + + uint32_t metricScopesCount = 0; + metricsDevContext.metricScopesGet(context->toHandle(), &metricScopesCount, nullptr); + EXPECT_EQ(metricScopesCount, 0u); +} + using MetricEnumerationMultiDeviceTest = Test; TEST_F(MetricEnumerationMultiDeviceTest, givenRootDeviceWhenLoadDependenciesIsCalledThenOpenMetricsSubDeviceWillBeCalled) {