Files
bluflame/ruins64k/tools/NvPerfUtility/include/NvPerfMetricsConfigBuilder.h
2026-04-18 22:31:51 +02:00

300 lines
13 KiB
C++

/*
* Copyright 2014-2021 NVIDIA Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <utility>
#include "NvPerfMetricsEvaluator.h"
namespace nv { namespace perf {
class MetricsConfigBuilder
{
protected:
NVPW_MetricsEvaluator* m_pMetricsEvaluator; // not owned
NVPA_RawMetricsConfig* m_pRawMetricsConfig; // owned
NVPA_CounterDataBuilder* m_pCounterDataBuilder; // owned
bool m_configuring;
protected:
void MoveAssign(MetricsConfigBuilder&& rhs)
{
Reset();
m_pMetricsEvaluator = rhs.m_pMetricsEvaluator;
m_pRawMetricsConfig = rhs.m_pRawMetricsConfig;
m_pCounterDataBuilder = rhs.m_pCounterDataBuilder;
m_configuring = rhs.m_configuring;
rhs.m_pMetricsEvaluator = nullptr;
rhs.m_pRawMetricsConfig = nullptr;
rhs.m_pCounterDataBuilder = nullptr;
}
public:
~MetricsConfigBuilder()
{
Reset();
}
MetricsConfigBuilder() : m_pMetricsEvaluator(nullptr), m_pRawMetricsConfig(nullptr), m_pCounterDataBuilder(nullptr), m_configuring(false)
{
}
MetricsConfigBuilder(MetricsConfigBuilder&& rhs) : m_pMetricsEvaluator(nullptr), m_pRawMetricsConfig(nullptr), m_pCounterDataBuilder(nullptr), m_configuring(false)
{
MoveAssign(std::forward<MetricsConfigBuilder>(rhs));
}
MetricsConfigBuilder& operator=(MetricsConfigBuilder&& rhs)
{
MoveAssign(std::forward<MetricsConfigBuilder>(rhs));
return *this;
}
void Reset()
{
NVPW_RawMetricsConfig_Destroy_Params rawMetricsConfigParams = { NVPW_RawMetricsConfig_Destroy_Params_STRUCT_SIZE };
rawMetricsConfigParams.pRawMetricsConfig = m_pRawMetricsConfig;
NVPW_RawMetricsConfig_Destroy(&rawMetricsConfigParams);
NVPW_CounterDataBuilder_Destroy_Params counterDataBuilderParams = { NVPW_CounterDataBuilder_Destroy_Params_STRUCT_SIZE };
counterDataBuilderParams.pCounterDataBuilder = m_pCounterDataBuilder;
NVPW_CounterDataBuilder_Destroy(&counterDataBuilderParams);
m_pMetricsEvaluator = nullptr;
m_pRawMetricsConfig = nullptr;
m_pCounterDataBuilder = nullptr;
}
bool Initialize(NVPW_MetricsEvaluator* pMetricsEvaluator, NVPA_RawMetricsConfig* pRawMetricsConfig, const char* chipName)
{
NVPA_Status nvpaStatus;
Reset(); // destroy any existing objects
m_pMetricsEvaluator = pMetricsEvaluator;
m_pRawMetricsConfig = pRawMetricsConfig;
NVPW_CounterDataBuilder_Create_Params counterDataBuilderParams = { NVPW_CounterDataBuilder_Create_Params_STRUCT_SIZE };
counterDataBuilderParams.pChipName = chipName;
nvpaStatus = NVPW_CounterDataBuilder_Create(&counterDataBuilderParams);
if (nvpaStatus)
{
return false;
}
m_pCounterDataBuilder = counterDataBuilderParams.pCounterDataBuilder;
NVPW_RawMetricsConfig_BeginPassGroup_Params beginPassGroupParams = { NVPW_RawMetricsConfig_BeginPassGroup_Params_STRUCT_SIZE };
beginPassGroupParams.pRawMetricsConfig = m_pRawMetricsConfig;
nvpaStatus = NVPW_RawMetricsConfig_BeginPassGroup(&beginPassGroupParams);
if (nvpaStatus)
{
return false;
}
m_configuring = true;
return true;
}
bool AddMetrics(const NVPW_MetricEvalRequest* pMetricEvalRequests, size_t numMetricEvalRequests)
{
NVPA_Status nvpaStatus;
NVPW_MetricsEvaluator_GetMetricRawDependencies_Params getMetricRawDependenciesParams = { NVPW_MetricsEvaluator_GetMetricRawDependencies_Params_STRUCT_SIZE };
getMetricRawDependenciesParams.pMetricsEvaluator = m_pMetricsEvaluator;
getMetricRawDependenciesParams.pMetricEvalRequests = pMetricEvalRequests;
getMetricRawDependenciesParams.numMetricEvalRequests = numMetricEvalRequests;
getMetricRawDependenciesParams.metricEvalRequestStructSize = NVPW_MetricEvalRequest_STRUCT_SIZE;
getMetricRawDependenciesParams.metricEvalRequestStrideSize = sizeof(NVPW_MetricEvalRequest);
nvpaStatus = NVPW_MetricsEvaluator_GetMetricRawDependencies(&getMetricRawDependenciesParams);
if (nvpaStatus)
{
NV_PERF_LOG_ERR(50, "NVPW_MetricsEvaluator_GetMetricRawDependencies failed\n");
return false;
}
std::vector<const char*> rawDependencies(getMetricRawDependenciesParams.numRawDependencies);
getMetricRawDependenciesParams.ppRawDependencies = rawDependencies.data();
nvpaStatus = NVPW_MetricsEvaluator_GetMetricRawDependencies(&getMetricRawDependenciesParams);
if (nvpaStatus)
{
NV_PERF_LOG_ERR(50, "NVPW_MetricsEvaluator_GetMetricRawDependencies failed\n");
return false;
}
for (const char* const pRawMetricName : rawDependencies)
{
NVPA_RawMetricRequest rawMetricRequest = { NVPA_RAW_METRIC_REQUEST_STRUCT_SIZE };
rawMetricRequest.pMetricName = pRawMetricName;
rawMetricRequest.isolated = true;
rawMetricRequest.keepInstances = true;
NVPW_CounterDataBuilder_AddMetrics_Params addMetricParams = { NVPW_CounterDataBuilder_AddMetrics_Params_STRUCT_SIZE };
addMetricParams.numMetricRequests = 1;
addMetricParams.pCounterDataBuilder = m_pCounterDataBuilder;
addMetricParams.pRawMetricRequests = &rawMetricRequest;
nvpaStatus = NVPW_CounterDataBuilder_AddMetrics(&addMetricParams);
if (nvpaStatus)
{
NV_PERF_LOG_ERR(50, "NVPW_CounterDataBuilder_AddMetrics failed\n");
return false;
}
NVPW_RawMetricsConfig_AddMetrics_Params configAddMetricParams = { NVPW_RawMetricsConfig_AddMetrics_Params_STRUCT_SIZE };
configAddMetricParams.numMetricRequests = 1;
configAddMetricParams.pRawMetricRequests = &rawMetricRequest;
configAddMetricParams.pRawMetricsConfig = m_pRawMetricsConfig;
nvpaStatus = NVPW_RawMetricsConfig_AddMetrics(&configAddMetricParams);
if (nvpaStatus)
{
NV_PERF_LOG_ERR(50, "NVPW_RawMetricsConfig_AddMetrics failed\n");
return false;
}
}
return true;
}
bool AddMetric(const char* pMetricName)
{
NVPW_MetricEvalRequest metricEvalRequest{};
bool success = ToMetricEvalRequest(m_pMetricsEvaluator, pMetricName, metricEvalRequest);
if (!success)
{
NV_PERF_LOG_ERR(50, "ToMetricEvalRequest failed for metric: %s\n", pMetricName);
return false;
}
success = AddMetrics(&metricEvalRequest, 1);
if (!success)
{
NV_PERF_LOG_ERR(50, "AddMetrics failed for metric: %s\n", pMetricName);
return false;
}
return true;
}
bool AddMetrics(const char* const pMetricNames[], size_t numMetrics)
{
bool success = true;
for (size_t metricIdx = 0; metricIdx < numMetrics; ++metricIdx)
{
const bool addMetricSuccess = AddMetric(pMetricNames[metricIdx]);
if (!addMetricSuccess)
{
success = false;
}
}
if (!success)
{
return false;
}
return true;
}
bool PrepareConfigImage()
{
NVPA_Status nvpaStatus;
m_configuring = false;
NVPW_RawMetricsConfig_EndPassGroup_Params endPassGroupParam = { NVPW_RawMetricsConfig_EndPassGroup_Params_STRUCT_SIZE };
endPassGroupParam.pRawMetricsConfig = m_pRawMetricsConfig;
nvpaStatus = NVPW_RawMetricsConfig_EndPassGroup(&endPassGroupParam);
if (nvpaStatus)
{
return false;
}
NVPW_RawMetricsConfig_GenerateConfigImage_Params generateConfigImageParam = { NVPW_RawMetricsConfig_GenerateConfigImage_Params_STRUCT_SIZE };
generateConfigImageParam.pRawMetricsConfig = m_pRawMetricsConfig;
nvpaStatus = NVPW_RawMetricsConfig_GenerateConfigImage(&generateConfigImageParam);
if (nvpaStatus)
{
return false;
}
// Start a new PassGroup so that subsequent AddMetrics() calls will succeed.
// This will not result in optimal scheduling, but it obeys the principle of least surprise.
NVPW_RawMetricsConfig_BeginPassGroup_Params beginPassGroupParams = { NVPW_RawMetricsConfig_BeginPassGroup_Params_STRUCT_SIZE };
beginPassGroupParams.pRawMetricsConfig = m_pRawMetricsConfig;
nvpaStatus = NVPW_RawMetricsConfig_BeginPassGroup(&beginPassGroupParams);
if (nvpaStatus)
{
return false;
}
m_configuring = true;
return true;
}
// Returns the buffer size needed for the ConfigImage, or zero on error.
size_t GetConfigImageSize() const
{
NVPW_RawMetricsConfig_GetConfigImage_Params getConfigImageParam = { NVPW_RawMetricsConfig_GetConfigImage_Params_STRUCT_SIZE };
getConfigImageParam.pBuffer = nullptr;
getConfigImageParam.bytesAllocated = 0;
getConfigImageParam.pRawMetricsConfig = m_pRawMetricsConfig;
NVPA_Status nvpaStatus = NVPW_RawMetricsConfig_GetConfigImage(&getConfigImageParam);
if (nvpaStatus)
{
return 0;
}
return getConfigImageParam.bytesCopied;
}
// Copies the generated ConfigImage into pBuffer.
bool GetConfigImage(size_t bufferSize, uint8_t* pBuffer) const
{
NVPW_RawMetricsConfig_GetConfigImage_Params getConfigImageParam = { NVPW_RawMetricsConfig_GetConfigImage_Params_STRUCT_SIZE };
getConfigImageParam.pRawMetricsConfig = m_pRawMetricsConfig;
getConfigImageParam.bytesAllocated = bufferSize;
getConfigImageParam.pBuffer = pBuffer;
NVPA_Status nvpaStatus = NVPW_RawMetricsConfig_GetConfigImage(&getConfigImageParam);
if (nvpaStatus)
{
return false;
}
return true;
}
// Returns the buffer size needed for the CounterDataPrefix, or zero on error.
size_t GetCounterDataPrefixSize() const
{
NVPW_CounterDataBuilder_GetCounterDataPrefix_Params getCounterDataPrefixParams = { NVPW_CounterDataBuilder_GetCounterDataPrefix_Params_STRUCT_SIZE };
getCounterDataPrefixParams.bytesAllocated = 0;
getCounterDataPrefixParams.pBuffer = nullptr;
getCounterDataPrefixParams.pCounterDataBuilder = m_pCounterDataBuilder;
NVPA_Status nvpaStatus = NVPW_CounterDataBuilder_GetCounterDataPrefix(&getCounterDataPrefixParams);
if (nvpaStatus)
{
return 0;
}
return getCounterDataPrefixParams.bytesCopied;
}
// Copies the generated CounterDataPrefix into pBuffer.
bool GetCounterDataPrefix(size_t bufferSize, uint8_t* pBuffer) const
{
NVPW_CounterDataBuilder_GetCounterDataPrefix_Params getCounterDataPrefixParams = { NVPW_CounterDataBuilder_GetCounterDataPrefix_Params_STRUCT_SIZE };
getCounterDataPrefixParams.bytesAllocated = bufferSize;
getCounterDataPrefixParams.pBuffer = pBuffer;
getCounterDataPrefixParams.pCounterDataBuilder = m_pCounterDataBuilder;
NVPA_Status nvpaStatus = NVPW_CounterDataBuilder_GetCounterDataPrefix(&getCounterDataPrefixParams);
if (nvpaStatus)
{
return false;
}
return true;
}
};
}}