736 lines
30 KiB
C++
736 lines
30 KiB
C++
![]() |
/*
|
||
|
* Copyright (C) 2019-2020 Intel Corporation
|
||
|
*
|
||
|
* SPDX-License-Identifier: MIT
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "level_zero/tools/source/metrics/metric_enumeration_imp.h"
|
||
|
|
||
|
#include "shared/source/helpers/debug_helpers.h"
|
||
|
#include "shared/source/helpers/string.h"
|
||
|
#include "shared/source/os_interface/os_library.h"
|
||
|
|
||
|
#include <algorithm>
|
||
|
|
||
|
namespace L0 {
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Static const field initialization.
|
||
|
const char *MetricEnumeration::oaConcurrentGroupName = "OA";
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Metric enumeration constructor.
|
||
|
MetricEnumeration::MetricEnumeration(MetricContext &metricContextInput)
|
||
|
: metricContext(metricContextInput) {}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Metric enumeration destructor.
|
||
|
MetricEnumeration::~MetricEnumeration() {
|
||
|
cleanupMetricsDiscovery();
|
||
|
initializationState = ZE_RESULT_ERROR_UNINITIALIZED;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Return metric group handles and their count.
|
||
|
ze_result_t MetricEnumeration::metricGroupGet(uint32_t &count,
|
||
|
zet_metric_group_handle_t *phMetricGroups) {
|
||
|
if (initialize() != ZE_RESULT_SUCCESS) {
|
||
|
return ZE_RESULT_ERROR_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
if (count == 0) {
|
||
|
count = static_cast<uint32_t>(metricGroups.size());
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
} else if (count > metricGroups.size()) {
|
||
|
count = static_cast<uint32_t>(metricGroups.size());
|
||
|
}
|
||
|
|
||
|
// User is expected to allocate space.
|
||
|
if (phMetricGroups == nullptr) {
|
||
|
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||
|
}
|
||
|
|
||
|
for (uint32_t i = 0; i < count; i++) {
|
||
|
phMetricGroups[i] = metricGroups[i]->toHandle();
|
||
|
}
|
||
|
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns enumeration object initialization state.
|
||
|
bool MetricEnumeration::isInitialized() { return initializationState == ZE_RESULT_SUCCESS; }
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Initializes metric enumeration object.
|
||
|
ze_result_t MetricEnumeration::initialize() {
|
||
|
if (initializationState == ZE_RESULT_ERROR_UNINITIALIZED) {
|
||
|
if (metricContext.isInitialized() &&
|
||
|
openMetricsDiscovery() == ZE_RESULT_SUCCESS &&
|
||
|
cacheMetricInformation() == ZE_RESULT_SUCCESS) {
|
||
|
initializationState = ZE_RESULT_SUCCESS;
|
||
|
} else {
|
||
|
initializationState = ZE_RESULT_ERROR_UNKNOWN;
|
||
|
cleanupMetricsDiscovery();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return initializationState;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Loads Metrics Discovery API library and its functions.
|
||
|
ze_result_t MetricEnumeration::loadMetricsDiscovery() {
|
||
|
// Load library.
|
||
|
hMetricsDiscovery.reset(NEO::OsLibrary::load(getMetricsDiscoveryFilename()));
|
||
|
|
||
|
// Load exported functions.
|
||
|
if (hMetricsDiscovery) {
|
||
|
openMetricsDevice = reinterpret_cast<MetricsDiscovery::OpenMetricsDevice_fn>(
|
||
|
hMetricsDiscovery->getProcAddress("OpenMetricsDevice"));
|
||
|
closeMetricsDevice = reinterpret_cast<MetricsDiscovery::CloseMetricsDevice_fn>(
|
||
|
hMetricsDiscovery->getProcAddress("CloseMetricsDevice"));
|
||
|
openMetricsDeviceFromFile =
|
||
|
reinterpret_cast<MetricsDiscovery::OpenMetricsDeviceFromFile_fn>(
|
||
|
hMetricsDiscovery->getProcAddress("OpenMetricsDeviceFromFile"));
|
||
|
}
|
||
|
|
||
|
if (openMetricsDevice == nullptr || closeMetricsDevice == nullptr ||
|
||
|
openMetricsDeviceFromFile == nullptr) {
|
||
|
cleanupMetricsDiscovery();
|
||
|
return ZE_RESULT_ERROR_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
// Return success if exported functions have been loaded.
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Opens Metrics Discovery APIs MetricDevice.
|
||
|
ze_result_t MetricEnumeration::openMetricsDiscovery() {
|
||
|
// #TODO_P1 reset MDAPI/instrumentation state - call close multiple times?
|
||
|
UNRECOVERABLE_IF(openMetricsDevice == nullptr);
|
||
|
UNRECOVERABLE_IF(closeMetricsDevice == nullptr);
|
||
|
|
||
|
auto openResult = openMetricsDevice(&pMetricsDevice);
|
||
|
if (openResult != MetricsDiscovery::CC_OK) {
|
||
|
return ZE_RESULT_ERROR_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Closes Metrics Discovery APIs MetricDevice and unloads its library.
|
||
|
ze_result_t MetricEnumeration::cleanupMetricsDiscovery() {
|
||
|
|
||
|
for (uint32_t i = 0; i < metricGroups.size(); ++i) {
|
||
|
delete metricGroups[i];
|
||
|
}
|
||
|
|
||
|
metricGroups.clear();
|
||
|
|
||
|
if (pMetricsDevice) {
|
||
|
closeMetricsDevice(pMetricsDevice);
|
||
|
pMetricsDevice = nullptr;
|
||
|
}
|
||
|
|
||
|
if (hMetricsDiscovery != nullptr) {
|
||
|
openMetricsDevice = nullptr;
|
||
|
closeMetricsDevice = nullptr;
|
||
|
openMetricsDeviceFromFile = nullptr;
|
||
|
|
||
|
hMetricsDiscovery.reset();
|
||
|
}
|
||
|
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Caches metric group / metric information for later use.
|
||
|
ze_result_t MetricEnumeration::cacheMetricInformation() {
|
||
|
// #TODO_val keep checks, e.g. metricsDevice, deviceParams?
|
||
|
UNRECOVERABLE_IF(pMetricsDevice == nullptr);
|
||
|
|
||
|
MetricsDiscovery::TMetricsDeviceParams_1_2 *pMetricsDeviceParams = pMetricsDevice->GetParams();
|
||
|
UNRECOVERABLE_IF(pMetricsDeviceParams == nullptr);
|
||
|
|
||
|
// Check required Metrics Discovery API version - should be at least 1.5.
|
||
|
const bool unsupportedMajorVersion =
|
||
|
pMetricsDeviceParams->Version.MajorNumber < requiredMetricsDiscoveryMajorVersion;
|
||
|
const bool unsupportedMinorVersion =
|
||
|
(pMetricsDeviceParams->Version.MajorNumber == requiredMetricsDiscoveryMajorVersion) &&
|
||
|
(pMetricsDeviceParams->Version.MinorNumber < requiredMetricsDiscoveryMinorVersion);
|
||
|
|
||
|
if (unsupportedMajorVersion || unsupportedMinorVersion) {
|
||
|
// Metrics Discovery API version too low
|
||
|
return ZE_RESULT_ERROR_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
// 1. Iterate over concurrent groups.
|
||
|
MetricsDiscovery::IConcurrentGroup_1_5 *pConcurrentGroup = nullptr;
|
||
|
for (uint32_t i = 0; i < pMetricsDeviceParams->ConcurrentGroupsCount; ++i) {
|
||
|
pConcurrentGroup = pMetricsDevice->GetConcurrentGroup(i);
|
||
|
UNRECOVERABLE_IF(pConcurrentGroup == nullptr);
|
||
|
|
||
|
MetricsDiscovery::TConcurrentGroupParams_1_0 *pConcurrentGroupParams =
|
||
|
pConcurrentGroup->GetParams();
|
||
|
UNRECOVERABLE_IF(pConcurrentGroupParams == nullptr);
|
||
|
|
||
|
// 2. Find "OA" concurrent group. // #TODO_P2 other groups than OA?
|
||
|
if (strcmp(pConcurrentGroupParams->SymbolName, oaConcurrentGroupName) == 0) {
|
||
|
// Reserve memory for metric groups
|
||
|
metricGroups.reserve(pConcurrentGroupParams->MetricSetsCount);
|
||
|
|
||
|
// 3. Iterate over metric sets.
|
||
|
for (uint32_t j = 0; j < pConcurrentGroupParams->MetricSetsCount; ++j) {
|
||
|
MetricsDiscovery::IMetricSet_1_5 *pMetricSet = pConcurrentGroup->GetMetricSet(j);
|
||
|
UNRECOVERABLE_IF(pMetricSet == nullptr);
|
||
|
|
||
|
cacheMetricGroup(*pMetricSet, *pConcurrentGroup, i,
|
||
|
ZET_METRIC_GROUP_SAMPLING_TYPE_TIME_BASED);
|
||
|
cacheMetricGroup(*pMetricSet, *pConcurrentGroup, i,
|
||
|
ZET_METRIC_GROUP_SAMPLING_TYPE_EVENT_BASED);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Creates and caches metric groups, mapping metric sets from Metrics Discovery.
|
||
|
ze_result_t
|
||
|
MetricEnumeration::cacheMetricGroup(MetricsDiscovery::IMetricSet_1_5 &metricSet,
|
||
|
MetricsDiscovery::IConcurrentGroup_1_5 &concurrentGroup,
|
||
|
const uint32_t domain,
|
||
|
const zet_metric_group_sampling_type_t samplingType) {
|
||
|
MetricsDiscovery::TMetricSetParams_1_4 *pMetricSetParams = metricSet.GetParams();
|
||
|
UNRECOVERABLE_IF(pMetricSetParams == nullptr);
|
||
|
|
||
|
const uint32_t sourceApiMask = MetricGroupImp::getApiMask(samplingType);
|
||
|
|
||
|
// Map metric groups to level zero format and cache them.
|
||
|
if (pMetricSetParams->ApiMask & sourceApiMask) {
|
||
|
metricSet.SetApiFiltering(sourceApiMask);
|
||
|
|
||
|
// Obtain params once again - updated after SetApiFiltering
|
||
|
pMetricSetParams = metricSet.GetParams();
|
||
|
|
||
|
zet_metric_group_properties_t properties = {};
|
||
|
properties.version = ZET_METRIC_GROUP_PROPERTIES_VERSION_CURRENT;
|
||
|
snprintf(properties.name, sizeof(properties.name), "%s",
|
||
|
pMetricSetParams->SymbolName); // To always have null-terminated string
|
||
|
snprintf(properties.description, sizeof(properties.description), "%s",
|
||
|
pMetricSetParams->ShortName);
|
||
|
properties.samplingType = samplingType;
|
||
|
properties.domain = domain; // Concurrent group number
|
||
|
properties.metricCount =
|
||
|
pMetricSetParams->MetricsCount + pMetricSetParams->InformationCount;
|
||
|
|
||
|
std::vector<Metric *> metrics;
|
||
|
createMetrics(metricSet, metrics);
|
||
|
|
||
|
auto pMetricGroup = MetricGroup::create(properties, metricSet, concurrentGroup, metrics);
|
||
|
UNRECOVERABLE_IF(pMetricGroup == nullptr);
|
||
|
|
||
|
metricGroups.push_back(pMetricGroup);
|
||
|
|
||
|
// Disable api filtering
|
||
|
metricSet.SetApiFiltering(MetricsDiscovery::API_TYPE_ALL);
|
||
|
}
|
||
|
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Creates metrics, mapping metrics from Metrics Discovery.
|
||
|
ze_result_t MetricEnumeration::createMetrics(MetricsDiscovery::IMetricSet_1_5 &metricSet,
|
||
|
std::vector<Metric *> &metrics) {
|
||
|
MetricsDiscovery::TMetricSetParams_1_4 *pMetricSetParams = metricSet.GetParams();
|
||
|
UNRECOVERABLE_IF(pMetricSetParams == nullptr);
|
||
|
|
||
|
metrics.reserve(pMetricSetParams->MetricsCount + pMetricSetParams->InformationCount);
|
||
|
|
||
|
// Map metrics to level zero format and add them to 'metrics' vector.
|
||
|
for (uint32_t i = 0; i < pMetricSetParams->MetricsCount; ++i) {
|
||
|
MetricsDiscovery::IMetric_1_0 *pSourceMetric = metricSet.GetMetric(i);
|
||
|
UNRECOVERABLE_IF(pSourceMetric == nullptr);
|
||
|
|
||
|
MetricsDiscovery::TMetricParams_1_0 *pSourceMetricParams = pSourceMetric->GetParams();
|
||
|
UNRECOVERABLE_IF(pSourceMetricParams == nullptr);
|
||
|
|
||
|
zet_metric_properties_t properties = {};
|
||
|
properties.version = ZET_METRIC_PROPERTIES_VERSION_CURRENT;
|
||
|
snprintf(properties.name, sizeof(properties.name), "%s",
|
||
|
pSourceMetricParams->SymbolName); // To always have a null-terminated string
|
||
|
snprintf(properties.description, sizeof(properties.description), "%s",
|
||
|
pSourceMetricParams->LongName);
|
||
|
snprintf(properties.component, sizeof(properties.component), "%s",
|
||
|
pSourceMetricParams->GroupName);
|
||
|
snprintf(properties.resultUnits, sizeof(properties.resultUnits), "%s",
|
||
|
pSourceMetricParams->MetricResultUnits);
|
||
|
properties.tierNumber = getMetricTierNumber(pSourceMetricParams->UsageFlagsMask);
|
||
|
properties.metricType = getMetricType(pSourceMetricParams->MetricType);
|
||
|
properties.resultType = getMetricResultType(pSourceMetricParams->ResultType);
|
||
|
|
||
|
auto pMetric = Metric::create(properties);
|
||
|
UNRECOVERABLE_IF(pMetric == nullptr);
|
||
|
|
||
|
metrics.push_back(pMetric);
|
||
|
}
|
||
|
|
||
|
// Map information to level zero format and add them to 'metrics' vector (as metrics).
|
||
|
for (uint32_t i = 0; i < pMetricSetParams->InformationCount; ++i) {
|
||
|
// #TODO_P1 not every information is needed? e.g. PTBR, reportCount, etc. shouldn't be
|
||
|
// available #TODO_P2 split e.g. report_reason to separate flags?
|
||
|
MetricsDiscovery::IInformation_1_0 *pSourceInformation = metricSet.GetInformation(i);
|
||
|
UNRECOVERABLE_IF(pSourceInformation == nullptr);
|
||
|
|
||
|
MetricsDiscovery::TInformationParams_1_0 *pSourceInformationParams =
|
||
|
pSourceInformation->GetParams();
|
||
|
UNRECOVERABLE_IF(pSourceInformationParams == nullptr);
|
||
|
|
||
|
zet_metric_properties_t properties;
|
||
|
properties.version = ZET_METRIC_PROPERTIES_VERSION_CURRENT;
|
||
|
snprintf(properties.name, sizeof(properties.name), "%s",
|
||
|
pSourceInformationParams->SymbolName); // To always have a null-terminated string
|
||
|
snprintf(properties.description, sizeof(properties.description), "%s",
|
||
|
pSourceInformationParams->LongName);
|
||
|
snprintf(properties.component, sizeof(properties.component), "%s",
|
||
|
pSourceInformationParams->GroupName);
|
||
|
snprintf(properties.resultUnits, sizeof(properties.resultUnits), "%s",
|
||
|
pSourceInformationParams->InfoUnits);
|
||
|
properties.tierNumber = 1; // #TODO_P2 default tier for information?
|
||
|
properties.metricType = getMetricType(pSourceInformationParams->InfoType);
|
||
|
properties.resultType =
|
||
|
ZET_VALUE_TYPE_UINT64; // MetricsDiscovery information are always UINT64
|
||
|
|
||
|
auto pMetric = Metric::create(properties);
|
||
|
UNRECOVERABLE_IF(pMetric == nullptr);
|
||
|
|
||
|
metrics.push_back(pMetric);
|
||
|
}
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Maps Metrics Discovery metric usage flags to level zero format (tier numbers).
|
||
|
uint32_t MetricEnumeration::getMetricTierNumber(const uint32_t sourceUsageFlagsMask) const {
|
||
|
uint32_t tierNumber = 0;
|
||
|
if (sourceUsageFlagsMask & MetricsDiscovery::USAGE_FLAG_TIER_1) {
|
||
|
tierNumber = 1;
|
||
|
} else if (sourceUsageFlagsMask & MetricsDiscovery::USAGE_FLAG_TIER_2) {
|
||
|
tierNumber = 2;
|
||
|
} else if (sourceUsageFlagsMask & MetricsDiscovery::USAGE_FLAG_TIER_3) {
|
||
|
tierNumber = 3;
|
||
|
} else if (sourceUsageFlagsMask & MetricsDiscovery::USAGE_FLAG_TIER_4) {
|
||
|
tierNumber = 4;
|
||
|
} else {
|
||
|
// No tier - some metrics may have this undefined
|
||
|
tierNumber = 0;
|
||
|
}
|
||
|
return tierNumber;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Maps Metrics Discovery metric types to level zero format.
|
||
|
zet_metric_type_t
|
||
|
MetricEnumeration::getMetricType(const MetricsDiscovery::TMetricType sourceMetricType) const {
|
||
|
switch (sourceMetricType) {
|
||
|
case MetricsDiscovery::METRIC_TYPE_DURATION:
|
||
|
return ZET_METRIC_TYPE_DURATION;
|
||
|
case MetricsDiscovery::METRIC_TYPE_EVENT:
|
||
|
return ZET_METRIC_TYPE_EVENT;
|
||
|
case MetricsDiscovery::METRIC_TYPE_EVENT_WITH_RANGE:
|
||
|
return ZET_METRIC_TYPE_EVENT_WITH_RANGE;
|
||
|
case MetricsDiscovery::METRIC_TYPE_THROUGHPUT:
|
||
|
return ZET_METRIC_TYPE_THROUGHPUT;
|
||
|
case MetricsDiscovery::METRIC_TYPE_TIMESTAMP:
|
||
|
return ZET_METRIC_TYPE_TIMESTAMP;
|
||
|
case MetricsDiscovery::METRIC_TYPE_FLAG:
|
||
|
return ZET_METRIC_TYPE_FLAG;
|
||
|
case MetricsDiscovery::METRIC_TYPE_RATIO:
|
||
|
return ZET_METRIC_TYPE_RATIO;
|
||
|
case MetricsDiscovery::METRIC_TYPE_RAW:
|
||
|
return ZET_METRIC_TYPE_RAW;
|
||
|
default:
|
||
|
UNRECOVERABLE_IF(!false);
|
||
|
return ZET_METRIC_TYPE_RAW;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Maps Metrics Discovery information types to level zero format.
|
||
|
zet_metric_type_t MetricEnumeration::getMetricType(
|
||
|
const MetricsDiscovery::TInformationType sourceInformationType) const {
|
||
|
|
||
|
switch (sourceInformationType) {
|
||
|
case MetricsDiscovery::INFORMATION_TYPE_REPORT_REASON:
|
||
|
return ZET_METRIC_TYPE_EVENT;
|
||
|
case MetricsDiscovery::INFORMATION_TYPE_VALUE:
|
||
|
case MetricsDiscovery::INFORMATION_TYPE_CONTEXT_ID_TAG:
|
||
|
case MetricsDiscovery::INFORMATION_TYPE_SAMPLE_PHASE:
|
||
|
case MetricsDiscovery::INFORMATION_TYPE_GPU_NODE:
|
||
|
return ZET_METRIC_TYPE_RAW;
|
||
|
case MetricsDiscovery::INFORMATION_TYPE_FLAG:
|
||
|
return ZET_METRIC_TYPE_FLAG;
|
||
|
case MetricsDiscovery::INFORMATION_TYPE_TIMESTAMP:
|
||
|
return ZET_METRIC_TYPE_TIMESTAMP;
|
||
|
default:
|
||
|
UNRECOVERABLE_IF(!false);
|
||
|
return ZET_METRIC_TYPE_RAW;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Maps Metrics Discovery metric result types to level zero format.
|
||
|
zet_value_type_t MetricEnumeration::getMetricResultType(
|
||
|
const MetricsDiscovery::TMetricResultType sourceMetricResultType) const {
|
||
|
|
||
|
switch (sourceMetricResultType) {
|
||
|
case MetricsDiscovery::RESULT_UINT32:
|
||
|
return ZET_VALUE_TYPE_UINT32;
|
||
|
case MetricsDiscovery::RESULT_UINT64:
|
||
|
return ZET_VALUE_TYPE_UINT64;
|
||
|
case MetricsDiscovery::RESULT_BOOL:
|
||
|
return ZET_VALUE_TYPE_BOOL8;
|
||
|
case MetricsDiscovery::RESULT_FLOAT:
|
||
|
return ZET_VALUE_TYPE_FLOAT32;
|
||
|
default:
|
||
|
UNRECOVERABLE_IF(!false);
|
||
|
return ZET_VALUE_TYPE_UINT64;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Metric group destructor.
|
||
|
MetricGroupImp ::~MetricGroupImp() {
|
||
|
|
||
|
for (uint32_t i = 0; i < metrics.size(); ++i) {
|
||
|
delete metrics[i];
|
||
|
}
|
||
|
|
||
|
metrics.clear();
|
||
|
};
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns metric group properties (copies data to user).
|
||
|
ze_result_t MetricGroupImp::getProperties(zet_metric_group_properties_t *pProperties) {
|
||
|
UNRECOVERABLE_IF(pProperties->version > ZET_METRIC_GROUP_PROPERTIES_VERSION_CURRENT);
|
||
|
copyProperties(properties, *pProperties);
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns metric group properties.
|
||
|
zet_metric_group_properties_t MetricGroup::getProperties(const zet_metric_group_handle_t handle) {
|
||
|
auto metricGroup = MetricGroup::fromHandle(handle);
|
||
|
UNRECOVERABLE_IF(!metricGroup);
|
||
|
|
||
|
zet_metric_group_properties_t properties = {ZET_METRIC_GROUP_PROPERTIES_VERSION_CURRENT};
|
||
|
metricGroup->getProperties(&properties);
|
||
|
|
||
|
return properties;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns metric handles and their count.
|
||
|
ze_result_t MetricGroupImp::getMetric(uint32_t *pCount, zet_metric_handle_t *phMetrics) {
|
||
|
if (*pCount == 0) {
|
||
|
*pCount = static_cast<uint32_t>(metrics.size());
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
} else if (*pCount > metrics.size()) {
|
||
|
*pCount = static_cast<uint32_t>(metrics.size());
|
||
|
}
|
||
|
|
||
|
// User is expected to allocate space.
|
||
|
if (phMetrics == nullptr) {
|
||
|
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||
|
}
|
||
|
|
||
|
for (uint32_t i = 0; i < *pCount; i++) {
|
||
|
phMetrics[i] = metrics[i]->toHandle();
|
||
|
}
|
||
|
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Activates metric group in the kernel.
|
||
|
bool MetricGroupImp::activate() {
|
||
|
UNRECOVERABLE_IF(pReferenceMetricSet == nullptr);
|
||
|
const bool result = pReferenceMetricSet->Activate() == MetricsDiscovery::CC_OK;
|
||
|
UNRECOVERABLE_IF(!result);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Deactivates metric group in the kernel.
|
||
|
bool MetricGroupImp::deactivate() {
|
||
|
UNRECOVERABLE_IF(pReferenceMetricSet == nullptr);
|
||
|
const bool result = pReferenceMetricSet->Deactivate() == MetricsDiscovery::CC_OK;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns metrics discovery api filtering type
|
||
|
/// for a given metric group sampling type.
|
||
|
uint32_t MetricGroupImp::getApiMask(const zet_metric_group_sampling_type_t samplingType) {
|
||
|
|
||
|
switch (samplingType) {
|
||
|
case ZET_METRIC_GROUP_SAMPLING_TYPE_TIME_BASED:
|
||
|
return MetricsDiscovery::API_TYPE_IOSTREAM;
|
||
|
case ZET_METRIC_GROUP_SAMPLING_TYPE_EVENT_BASED:
|
||
|
// #TODO Expose ocl metric sets from open source metrics discovery.
|
||
|
return MetricsDiscovery::API_TYPE_OCL | MetricsDiscovery::API_TYPE_OGL4_X;
|
||
|
default:
|
||
|
UNRECOVERABLE_IF(true);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Opens metrics discovery io stream.
|
||
|
ze_result_t MetricGroupImp::openIoStream(uint32_t &timerPeriodNs, uint32_t &oaBufferSize) {
|
||
|
const auto openResult = pReferenceConcurrentGroup->OpenIoStream(pReferenceMetricSet, 0,
|
||
|
&timerPeriodNs, &oaBufferSize);
|
||
|
return (openResult == MetricsDiscovery::CC_OK) ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Checks if metric tracer reports are available.
|
||
|
ze_result_t MetricGroupImp::waitForReports(const uint32_t timeoutMs) {
|
||
|
return (pReferenceConcurrentGroup->WaitForReports(timeoutMs) == MetricsDiscovery::TCompletionCode::CC_OK)
|
||
|
? ZE_RESULT_SUCCESS
|
||
|
: ZE_RESULT_NOT_READY;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Reads raw data from metrics discovery io stream.
|
||
|
ze_result_t MetricGroupImp::readIoStream(uint32_t &reportCount, uint8_t &reportData) {
|
||
|
char *castedReportData = reinterpret_cast<char *>(&reportData);
|
||
|
|
||
|
// #TODO_tracer_P2 use IO_READ_FLAG_DROP_OLD_REPORTS flag?
|
||
|
const auto readResult =
|
||
|
pReferenceConcurrentGroup->ReadIoStream(&reportCount, castedReportData, 0);
|
||
|
|
||
|
switch (readResult) {
|
||
|
case MetricsDiscovery::CC_OK:
|
||
|
case MetricsDiscovery::CC_READ_PENDING: // #TODO_tracer_P1 what about pending?
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
|
||
|
default:
|
||
|
return ZE_RESULT_ERROR_UNKNOWN;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Closes metrics discovery io stream.
|
||
|
ze_result_t MetricGroupImp::closeIoStream() {
|
||
|
const auto closeResult = pReferenceConcurrentGroup->CloseIoStream();
|
||
|
return (closeResult == MetricsDiscovery::CC_OK) ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Calculates raw data, returns metric values.
|
||
|
ze_result_t MetricGroupImp::calculateMetricValues(size_t rawDataSize,
|
||
|
const uint8_t *pRawData, uint32_t *pMetricValueCount,
|
||
|
zet_typed_value_t *pMetricValues) {
|
||
|
const bool calculateCountOnly = *pMetricValueCount == 0;
|
||
|
const bool result = calculateCountOnly
|
||
|
? getCalculatedMetricCount(rawDataSize, *pMetricValueCount)
|
||
|
: getCalculatedMetricValues(rawDataSize, pRawData, *pMetricValueCount, pMetricValues);
|
||
|
|
||
|
return result ? ZE_RESULT_SUCCESS : ZE_RESULT_ERROR_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns calculated metric value count for a given raw data.
|
||
|
bool MetricGroupImp::getCalculatedMetricCount(const size_t rawDataSize,
|
||
|
uint32_t &metricValueCount) {
|
||
|
uint32_t rawReportSize = getRawReportSize();
|
||
|
|
||
|
if (rawReportSize == 0) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ((rawDataSize % rawReportSize) != 0) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
const uint32_t rawReportCount = static_cast<uint32_t>(rawDataSize) / rawReportSize;
|
||
|
metricValueCount = rawReportCount * properties.metricCount;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns calculated metric values for a given raw data.
|
||
|
bool MetricGroupImp::getCalculatedMetricValues(const size_t rawDataSize, const uint8_t *pRawData,
|
||
|
uint32_t &metricValueCount,
|
||
|
zet_typed_value_t *pCalculatedData) {
|
||
|
|
||
|
uint32_t calculatedReportCount = 0;
|
||
|
uint32_t expectedMetricValueCount = 0;
|
||
|
|
||
|
if (pCalculatedData == nullptr) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (getCalculatedMetricCount(rawDataSize, expectedMetricValueCount) == false) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Calculated metrics container.
|
||
|
std::vector<MetricsDiscovery::TTypedValue_1_0> calculatedMetrics(expectedMetricValueCount);
|
||
|
|
||
|
// Set filtering type.
|
||
|
pReferenceMetricSet->SetApiFiltering(MetricGroupImp::getApiMask(properties.samplingType));
|
||
|
|
||
|
// Calculate metrics.
|
||
|
const bool result = pReferenceMetricSet->CalculateMetrics(
|
||
|
reinterpret_cast<unsigned char *>(const_cast<uint8_t *>(pRawData)), static_cast<uint32_t>(rawDataSize),
|
||
|
calculatedMetrics.data(),
|
||
|
static_cast<uint32_t>(calculatedMetrics.size()) * sizeof(MetricsDiscovery::TTypedValue_1_0),
|
||
|
&calculatedReportCount, nullptr, static_cast<uint32_t>(0)) == MetricsDiscovery::CC_OK;
|
||
|
|
||
|
if (result) {
|
||
|
|
||
|
// Adjust copied reports to buffer provided by the user.
|
||
|
metricValueCount = std::min<uint32_t>(metricValueCount, calculatedReportCount * properties.metricCount);
|
||
|
|
||
|
// Translate metrics from metrics discovery to one api format.
|
||
|
for (size_t i = 0; i < metricValueCount; ++i) {
|
||
|
copyValue(calculatedMetrics[i], pCalculatedData[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Initializes metric group object.
|
||
|
ze_result_t MetricGroupImp::initialize(const zet_metric_group_properties_t &sourceProperties,
|
||
|
MetricsDiscovery::IMetricSet_1_5 &metricSet,
|
||
|
MetricsDiscovery::IConcurrentGroup_1_5 &concurrentGroup,
|
||
|
const std::vector<Metric *> &groupMetrics) {
|
||
|
copyProperties(sourceProperties, properties);
|
||
|
pReferenceMetricSet = &metricSet;
|
||
|
pReferenceConcurrentGroup = &concurrentGroup;
|
||
|
metrics = groupMetrics;
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns size of raw reports produced by this metric group.
|
||
|
uint32_t MetricGroupImp::getRawReportSize() {
|
||
|
auto pMetricSetParams = pReferenceMetricSet->GetParams();
|
||
|
|
||
|
return (properties.samplingType == ZET_METRIC_GROUP_SAMPLING_TYPE_TIME_BASED)
|
||
|
? pMetricSetParams->RawReportSize
|
||
|
: pMetricSetParams->QueryReportSize;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Copies metric group properties from 'source' to 'destination'.
|
||
|
void MetricGroupImp::copyProperties(const zet_metric_group_properties_t &source,
|
||
|
zet_metric_group_properties_t &destination) {
|
||
|
UNRECOVERABLE_IF(source.version < destination.version);
|
||
|
destination = source;
|
||
|
memcpy_s(destination.name, sizeof(destination.name),
|
||
|
source.name, sizeof(destination.name));
|
||
|
memcpy_s(destination.description, sizeof(destination.description),
|
||
|
source.description, sizeof(destination.description));
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Translates metrics discovery typed value into one api format.
|
||
|
void MetricGroupImp::copyValue(const MetricsDiscovery::TTypedValue_1_0 &source,
|
||
|
zet_typed_value_t &destination) const {
|
||
|
|
||
|
destination = {};
|
||
|
|
||
|
switch (source.ValueType) {
|
||
|
case MetricsDiscovery::VALUE_TYPE_UINT32:
|
||
|
destination.type = ZET_VALUE_TYPE_UINT32;
|
||
|
destination.value.ui32 = source.ValueUInt32;
|
||
|
break;
|
||
|
|
||
|
case MetricsDiscovery::VALUE_TYPE_UINT64:
|
||
|
destination.type = ZET_VALUE_TYPE_UINT64;
|
||
|
destination.value.ui64 = source.ValueUInt64;
|
||
|
break;
|
||
|
|
||
|
case MetricsDiscovery::VALUE_TYPE_FLOAT:
|
||
|
destination.type = ZET_VALUE_TYPE_FLOAT32;
|
||
|
destination.value.fp32 = source.ValueFloat;
|
||
|
break;
|
||
|
|
||
|
case MetricsDiscovery::VALUE_TYPE_BOOL:
|
||
|
destination.type = ZET_VALUE_TYPE_BOOL8;
|
||
|
destination.value.b8 = source.ValueBool;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
destination.type = ZET_VALUE_TYPE_UINT64;
|
||
|
destination.value.ui64 = 0;
|
||
|
UNRECOVERABLE_IF(true);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Returns metric properties (copies data to user).
|
||
|
ze_result_t MetricImp::getProperties(zet_metric_properties_t *pProperties) {
|
||
|
UNRECOVERABLE_IF(pProperties->version > ZET_METRIC_PROPERTIES_VERSION_CURRENT);
|
||
|
copyProperties(properties, *pProperties);
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Initializes metric object.
|
||
|
ze_result_t MetricImp::initialize(const zet_metric_properties_t &sourceProperties) {
|
||
|
copyProperties(sourceProperties, properties);
|
||
|
return ZE_RESULT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Copies metric properties from 'source' to 'destination'.
|
||
|
void MetricImp::copyProperties(const zet_metric_properties_t &source,
|
||
|
zet_metric_properties_t &destination) {
|
||
|
UNRECOVERABLE_IF(source.version < destination.version);
|
||
|
destination = source;
|
||
|
memcpy_s(destination.name, sizeof(destination.name),
|
||
|
source.name, sizeof(destination.name));
|
||
|
memcpy_s(destination.description, sizeof(destination.description),
|
||
|
source.description, sizeof(destination.description));
|
||
|
memcpy_s(destination.component, sizeof(destination.component),
|
||
|
source.component, sizeof(destination.component));
|
||
|
memcpy_s(destination.resultUnits, sizeof(destination.resultUnits),
|
||
|
source.resultUnits, sizeof(destination.resultUnits));
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Creates metric group object.
|
||
|
MetricGroup *MetricGroup::create(zet_metric_group_properties_t &properties,
|
||
|
MetricsDiscovery::IMetricSet_1_5 &metricSet,
|
||
|
MetricsDiscovery::IConcurrentGroup_1_5 &concurrentGroup,
|
||
|
const std::vector<Metric *> &metrics) {
|
||
|
auto pMetricGroup = new MetricGroupImp();
|
||
|
UNRECOVERABLE_IF(pMetricGroup == nullptr);
|
||
|
pMetricGroup->initialize(properties, metricSet, concurrentGroup, metrics);
|
||
|
return pMetricGroup;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// @brief Creates metric object.
|
||
|
Metric *Metric::create(zet_metric_properties_t &properties) {
|
||
|
auto pMetric = new MetricImp();
|
||
|
UNRECOVERABLE_IF(pMetric == nullptr);
|
||
|
pMetric->initialize(properties);
|
||
|
return pMetric;
|
||
|
}
|
||
|
|
||
|
} // namespace L0
|