From ed6b30af12cf46b70ef3f3d61b77a88d6986917d Mon Sep 17 00:00:00 2001 From: Joshua Santosh Ranjan Date: Thu, 18 Nov 2021 14:19:56 +0000 Subject: [PATCH] Metrics Library Release For Query Case Release Metrics Library after Query related objects are released Related-To: LOCI-2656 Signed-off-by: Joshua Santosh Ranjan --- level_zero/tools/source/metrics/metric.cpp | 39 +++- level_zero/tools/source/metrics/metric.h | 1 + .../tools/source/metrics/metric_query_imp.cpp | 7 + .../metrics/test_metric_query_pool_1.cpp | 218 ++++++++++++++++++ .../metrics/test_metric_query_pool_3.cpp | 2 + .../metrics/test_metric_streamer_1.cpp | 2 + 6 files changed, 257 insertions(+), 12 deletions(-) diff --git a/level_zero/tools/source/metrics/metric.cpp b/level_zero/tools/source/metrics/metric.cpp index 89d087b147..7a2933792b 100644 --- a/level_zero/tools/source/metrics/metric.cpp +++ b/level_zero/tools/source/metrics/metric.cpp @@ -29,6 +29,7 @@ struct MetricGroupDomains { ze_result_t activate(); ze_result_t deactivate(); bool isActivated(const zet_metric_group_handle_t hMetricGroup); + uint32_t getActivatedCount(); protected: bool activateMetricGroupDeferred(const zet_metric_group_handle_t hMetricGroup); @@ -62,6 +63,7 @@ struct MetricContextImp : public MetricContext { ze_result_t activateMetricGroupsDeferred(const uint32_t count, zet_metric_group_handle_t *phMetricGroups) override; bool isMetricGroupActivated(const zet_metric_group_handle_t hMetricGroup) override; + bool isMetricGroupActivated() override; void setUseCompute(const bool useCompute) override; bool isComputeUsed() override; @@ -185,6 +187,10 @@ bool MetricContextImp::isMetricGroupActivated(const zet_metric_group_handle_t hM return metricGroupDomains.isActivated(hMetricGroup); } +bool MetricContextImp::isMetricGroupActivated() { + return metricGroupDomains.getActivatedCount() > 0; +} + ze_result_t MetricContextImp::activateMetricGroups() { return metricGroupDomains.activate(); } ze_result_t MetricContext::enableMetricApi() { @@ -355,25 +361,26 @@ ze_result_t MetricGroupDomains::deactivate() { for (auto &domain : domains) { auto hMetricGroup = domain.second.first; - auto metricGroup = MetricGroup::fromHandle(hMetricGroup); - bool metricGroupActivated = domain.second.second; - auto metricGroupEventBased = (metricGroup != nullptr) - ? MetricGroup::getProperties(hMetricGroup).samplingType == ZET_METRIC_GROUP_SAMPLING_TYPE_FLAG_EVENT_BASED - : false; - auto hConfigurationEmpty = ConfigurationHandle_1_0{}; - auto hConfiguration = metricGroupEventBased - ? metricContext.getMetricsLibrary().getConfiguration(hMetricGroup) - : hConfigurationEmpty; + bool metricGroupActivatedOnGpu = domain.second.second; - // Deactivate metric group configuration using metrics library. - if (hConfiguration.IsValid() && metricGroupActivated) { + if (metricGroupActivatedOnGpu) { + // Only event based metric groups are activated on Gpu. + DEBUG_BREAK_IF(MetricGroup::getProperties(hMetricGroup).samplingType != ZET_METRIC_GROUP_SAMPLING_TYPE_FLAG_EVENT_BASED); + auto hConfiguration = metricContext.getMetricsLibrary().getConfiguration(hMetricGroup); + // Deactivate metric group configuration using metrics library. metricContext.getMetricsLibrary().deactivateConfiguration(hConfiguration); } - // Mark domain as free. domain.second = {}; } + // Check any open queries. + if (metricContext.getMetricsLibrary().getMetricQueryCount() == 0) { + if (metricContext.getMetricsLibrary().getInitializationState() != ZE_RESULT_ERROR_UNINITIALIZED) { + metricContext.getMetricsLibrary().release(); + } + } + return ZE_RESULT_SUCCESS; } @@ -390,6 +397,14 @@ bool MetricGroupDomains::isActivated(const zet_metric_group_handle_t hMetricGrou return domain->second.first == hMetricGroup; } +uint32_t MetricGroupDomains::getActivatedCount() { + uint32_t count = 0; + for (const auto &domain : domains) { + count += domain.second.second ? 1 : 0; + } + return count; +} + ze_result_t metricGroupGet(zet_device_handle_t hDevice, uint32_t *pCount, zet_metric_group_handle_t *phMetricGroups) { auto device = Device::fromHandle(hDevice); return device->getMetricContext().getMetricEnumeration().metricGroupGet(*pCount, diff --git a/level_zero/tools/source/metrics/metric.h b/level_zero/tools/source/metrics/metric.h index 6379f3c884..fcd8ea559c 100644 --- a/level_zero/tools/source/metrics/metric.h +++ b/level_zero/tools/source/metrics/metric.h @@ -51,6 +51,7 @@ struct MetricContext { virtual ze_result_t activateMetricGroupsDeferred(const uint32_t count, zet_metric_group_handle_t *phMetricGroups) = 0; virtual bool isMetricGroupActivated(const zet_metric_group_handle_t hMetricGroup) = 0; + virtual bool isMetricGroupActivated() = 0; virtual void setUseCompute(const bool useCompute) = 0; virtual bool isComputeUsed() = 0; diff --git a/level_zero/tools/source/metrics/metric_query_imp.cpp b/level_zero/tools/source/metrics/metric_query_imp.cpp index df4bdeb3ac..876ab703fd 100644 --- a/level_zero/tools/source/metrics/metric_query_imp.cpp +++ b/level_zero/tools/source/metrics/metric_query_imp.cpp @@ -540,6 +540,13 @@ ze_result_t MetricQueryPoolImp::destroy() { break; } + // Check open queries. + if (metricContext.getMetricsLibrary().getMetricQueryCount() == 0) { + if (!metricContext.isMetricGroupActivated()) { + metricContext.getMetricsLibrary().release(); + } + } + delete this; return ZE_RESULT_SUCCESS; diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_query_pool_1.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_query_pool_1.cpp index 865289fb83..772be8fc38 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_query_pool_1.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_query_pool_1.cpp @@ -1418,5 +1418,223 @@ TEST_F(MetricQueryPoolTest, givenCorrectArgumentsWhenZetMetricQueryGetDataIsCall EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle), ZE_RESULT_SUCCESS); } +TEST_F(MetricQueryPoolTest, givenMetricQueryIsActiveWhenMetricQueryPoolDestroyIsCalledThenMetricLibraryIsNotReleased) { + + zet_device_handle_t metricDevice = device->toHandle(); + + Mock metricGroup; + zet_metric_group_properties_t metricGroupProperties = {}; + metricGroupProperties.samplingType = ZET_METRIC_GROUP_SAMPLING_TYPE_FLAG_EVENT_BASED; + + zet_metric_query_handle_t queryHandle[2] = {}; + zet_metric_query_pool_handle_t poolHandle[2] = {}; + zet_metric_query_pool_desc_t poolDesc = {}; + poolDesc.stype = ZET_STRUCTURE_TYPE_METRIC_QUERY_POOL_DESC; + poolDesc.count = 1; + poolDesc.type = ZET_METRIC_QUERY_POOL_TYPE_PERFORMANCE; + + TypedValue_1_0 value = {}; + value.Type = ValueType::Uint32; + value.ValueUInt32 = 64; + + QueryHandle_1_0 metricsLibraryQueryHandle = {&value}; + ContextHandle_1_0 metricsLibraryContextHandle = {&value}; + + CommandBufferSize_1_0 commandBufferSize = {}; + commandBufferSize.GpuMemorySize = 100; + + EXPECT_CALL(*mockMetricEnumeration, isInitialized()) + .Times(1) + .WillOnce(Return(true)); + + EXPECT_CALL(*mockMetricsLibrary, getContextData(_, _)) + .Times(1) + .WillOnce(Return(true)); + + EXPECT_CALL(*mockMetricsLibrary, load()) + .Times(0); + + EXPECT_CALL(metricGroup, getProperties(_)) + .Times(2) + .WillRepeatedly(DoAll(::testing::SetArgPointee<0>(metricGroupProperties), Return(ZE_RESULT_SUCCESS))); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockQueryCreate(_, _)) + .Times(2) + .WillRepeatedly(DoAll(::testing::SetArgPointee<1>(metricsLibraryQueryHandle), Return(StatusCode::Success))); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockQueryDelete(_)) + .Times(2) + .WillRepeatedly(Return(StatusCode::Success)); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockGetParameter(_, _, _)) + .Times(2) + .WillRepeatedly(DoAll(::testing::SetArgPointee<2>(value), Return(StatusCode::Success))); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextCreate(_, _, _)) + .Times(1) + .WillOnce(DoAll(::testing::SetArgPointee<2>(metricsLibraryContextHandle), Return(StatusCode::Success))); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextDelete(_)) + .Times(1) + .WillOnce(Return(StatusCode::Success)); + + EXPECT_EQ(zetMetricQueryPoolCreate(context->toHandle(), metricDevice, metricGroup.toHandle(), &poolDesc, &poolHandle[0]), ZE_RESULT_SUCCESS); + EXPECT_NE(poolHandle[0], nullptr); + + EXPECT_EQ(zetMetricQueryPoolCreate(context->toHandle(), metricDevice, metricGroup.toHandle(), &poolDesc, &poolHandle[1]), ZE_RESULT_SUCCESS); + EXPECT_NE(poolHandle[1], nullptr); + + EXPECT_EQ(zetMetricQueryCreate(poolHandle[0], 0, &queryHandle[0]), ZE_RESULT_SUCCESS); + EXPECT_NE(queryHandle[0], nullptr); + + EXPECT_EQ(zetMetricQueryCreate(poolHandle[1], 0, &queryHandle[1]), ZE_RESULT_SUCCESS); + EXPECT_NE(queryHandle[1], nullptr); + + EXPECT_EQ(zetMetricQueryDestroy(queryHandle[0]), ZE_RESULT_SUCCESS); + EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle[0]), ZE_RESULT_SUCCESS); + + EXPECT_EQ(mockMetricsLibrary->getInitializationState(), ZE_RESULT_SUCCESS); + + EXPECT_EQ(zetMetricQueryDestroy(queryHandle[1]), ZE_RESULT_SUCCESS); + EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle[1]), ZE_RESULT_SUCCESS); + + EXPECT_NE(mockMetricsLibrary->getInitializationState(), ZE_RESULT_SUCCESS); +} + +TEST_F(MetricQueryPoolTest, givenMetricQueryIsActiveWhenMetricGroupDeactivateIsCalledThenMetricLibraryIsNotReleased) { + + zet_device_handle_t metricDevice = device->toHandle(); + + metricsDeviceParams.ConcurrentGroupsCount = 1; + + Mock metricsConcurrentGroup; + TConcurrentGroupParams_1_0 metricsConcurrentGroupParams = {}; + metricsConcurrentGroupParams.MetricSetsCount = 1; + metricsConcurrentGroupParams.SymbolName = "OA"; + metricsConcurrentGroupParams.Description = "OA description"; + + Mock metricsSet; + MetricsDiscovery::TMetricSetParams_1_4 metricsSetParams = {}; + metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_OCL; + metricsSetParams.MetricsCount = 0; + metricsSetParams.SymbolName = "Metric set name"; + metricsSetParams.ShortName = "Metric set description"; + metricsSetParams.MetricsCount = 1; + + Mock metric; + TMetricParams_1_0 metricParams = {}; + metricParams.SymbolName = "Metric symbol name"; + metricParams.ShortName = "Metric short name"; + metricParams.LongName = "Metric long name"; + metricParams.ResultType = MetricsDiscovery::TMetricResultType::RESULT_UINT64; + metricParams.MetricType = MetricsDiscovery::TMetricType::METRIC_TYPE_RATIO; + + zet_metric_group_handle_t metricGroupHandle = {}; + + zet_metric_group_properties_t metricGroupProperties = {}; + metricGroupProperties.samplingType = ZET_METRIC_GROUP_SAMPLING_TYPE_FLAG_EVENT_BASED; + + zet_metric_query_handle_t queryHandle = {}; + zet_metric_query_pool_handle_t poolHandle = {}; + zet_metric_query_pool_desc_t poolDesc = {}; + poolDesc.stype = ZET_STRUCTURE_TYPE_METRIC_QUERY_POOL_DESC; + poolDesc.count = 1; + poolDesc.type = ZET_METRIC_QUERY_POOL_TYPE_PERFORMANCE; + + TypedValue_1_0 value = {}; + value.Type = ValueType::Uint32; + value.ValueUInt32 = 64; + + QueryHandle_1_0 metricsLibraryQueryHandle = {&value}; + ContextHandle_1_0 metricsLibraryContextHandle = {&value}; + ConfigurationHandle_1_0 metricsLibraryConfigurationHandle = {&value}; + + openMetricsAdapter(); + + EXPECT_CALL(metricsDevice, GetParams()) + .WillRepeatedly(Return(&metricsDeviceParams)); + + EXPECT_CALL(metricsDevice, GetConcurrentGroup(_)) + .Times(1) + .WillRepeatedly(Return(&metricsConcurrentGroup)); + + EXPECT_CALL(metricsConcurrentGroup, GetParams()) + .Times(1) + .WillRepeatedly(Return(&metricsConcurrentGroupParams)); + + EXPECT_CALL(metricsConcurrentGroup, GetMetricSet(_)) + .WillRepeatedly(Return(&metricsSet)); + + EXPECT_CALL(metricsSet, GetParams()) + .WillRepeatedly(Return(&metricsSetParams)); + + EXPECT_CALL(metricsSet, GetMetric(_)) + .Times(1) + .WillRepeatedly(Return(&metric)); + + EXPECT_CALL(metric, GetParams()) + .Times(1) + .WillRepeatedly(Return(&metricParams)); + + EXPECT_CALL(metricsSet, SetApiFiltering(_)) + .WillRepeatedly(Return(TCompletionCode::CC_OK)); + + EXPECT_CALL(*mockMetricEnumeration, isInitialized()) + .Times(1) + .WillOnce(Return(true)); + + EXPECT_CALL(*mockMetricsLibrary, getContextData(_, _)) + .Times(1) + .WillOnce(Return(true)); + + EXPECT_CALL(*mockMetricsLibrary, load()) + .Times(0); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockQueryCreate(_, _)) + .Times(1) + .WillRepeatedly(DoAll(::testing::SetArgPointee<1>(metricsLibraryQueryHandle), Return(StatusCode::Success))); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockQueryDelete(_)) + .Times(1) + .WillRepeatedly(Return(StatusCode::Success)); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockGetParameter(_, _, _)) + .Times(1) + .WillOnce(DoAll(::testing::SetArgPointee<2>(value), Return(StatusCode::Success))); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextCreate(_, _, _)) + .Times(1) + .WillRepeatedly(DoAll(::testing::SetArgPointee<2>(metricsLibraryContextHandle), Return(StatusCode::Success))); + + EXPECT_CALL(*mockMetricsLibrary->g_mockApi, MockContextDelete(_)) + .Times(1) + .WillRepeatedly(Return(StatusCode::Success)); + + uint32_t metricGroupCount = 0; + EXPECT_EQ(zetMetricGroupGet(metricDevice, &metricGroupCount, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + + EXPECT_EQ(zetMetricGroupGet(metricDevice, &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(metricGroupCount, 1u); + EXPECT_NE(metricGroupHandle, nullptr); + + EXPECT_EQ(zetContextActivateMetricGroups(context->toHandle(), metricDevice, 1, &metricGroupHandle), ZE_RESULT_SUCCESS); + + EXPECT_EQ(zetMetricQueryPoolCreate(context->toHandle(), metricDevice, metricGroupHandle, &poolDesc, &poolHandle), ZE_RESULT_SUCCESS); + EXPECT_NE(poolHandle, nullptr); + + EXPECT_EQ(zetMetricQueryCreate(poolHandle, 0, &queryHandle), ZE_RESULT_SUCCESS); + EXPECT_NE(queryHandle, nullptr); + + EXPECT_EQ(zetContextActivateMetricGroups(context->toHandle(), metricDevice, 0, nullptr), ZE_RESULT_SUCCESS); + + EXPECT_EQ(mockMetricsLibrary->getInitializationState(), ZE_RESULT_SUCCESS); + + EXPECT_EQ(zetMetricQueryDestroy(queryHandle), ZE_RESULT_SUCCESS); + EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle), ZE_RESULT_SUCCESS); + + EXPECT_NE(mockMetricsLibrary->getInitializationState(), ZE_RESULT_SUCCESS); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_query_pool_3.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_query_pool_3.cpp index 01d7d68648..9173b1e3a2 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_query_pool_3.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_query_pool_3.cpp @@ -371,6 +371,8 @@ TEST_F(MultiDeviceMetricQueryPoolTest, givenEnableWalkerPartitionIsOnWhenZetComm EXPECT_EQ(zetMetricQueryCreate(poolHandle, 0, &queryHandle), ZE_RESULT_SUCCESS); EXPECT_NE(queryHandle, nullptr); + EXPECT_EQ(zetContextActivateMetricGroups(context->toHandle(), metricDeviceHandle, 0, nullptr), ZE_RESULT_SUCCESS); + EXPECT_EQ(zetMetricQueryDestroy(queryHandle), ZE_RESULT_SUCCESS); EXPECT_EQ(zetMetricQueryPoolDestroy(poolHandle), ZE_RESULT_SUCCESS); } diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_streamer_1.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_streamer_1.cpp index 17955d9086..6979f71144 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_streamer_1.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_streamer_1.cpp @@ -804,6 +804,8 @@ TEST_F(MetricStreamerTest, givenValidArgumentsWhenZetMetricStreamerReadDataIsCal EXPECT_EQ(zetMetricStreamerReadData(streamerHandle, reportCount, &rawSize, rawData.data()), ZE_RESULT_SUCCESS); EXPECT_EQ(zetMetricStreamerClose(streamerHandle), ZE_RESULT_SUCCESS); + + EXPECT_EQ(zetContextActivateMetricGroups(context->toHandle(), metricDeviceHandle, 0, nullptr), ZE_RESULT_SUCCESS); } TEST_F(MetricStreamerTest, givenInvalidArgumentsWhenZetCommandListAppendMetricStreamerMarkerIsCalledThenReturnsFail) {