feature: add support to query metrics hw buffer size

Related-To: NEO-13439

Signed-off-by: Joshua Santosh Ranjan <joshua.santosh.ranjan@intel.com>
This commit is contained in:
Joshua Santosh Ranjan
2025-07-28 14:21:14 +00:00
committed by Compute-Runtime-Automation
parent 4410d59bfe
commit 280239ebec
12 changed files with 451 additions and 17 deletions

View File

@@ -63,7 +63,7 @@ const std::vector<std::pair<std::string, uint32_t>> DriverHandleImp::extensionsS
{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},
{ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_NAME, ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_VERSION_CURRENT},
#include "additional_extensions_support.inl"
};
} // namespace L0

View File

@@ -45,6 +45,7 @@ using zes_structure_type_ext_t = uint32_t;
#define ZET_INTEL_STRUCTURE_TYPE_METRIC_CALCULATE_DESC_EXP static_cast<zet_structure_type_ext_t>(0x00010009)
#define ZET_INTEL_STRUCTURE_TYPE_METRIC_SOURCE_ID_EXP static_cast<zet_structure_type_ext_t>(0x0001000a)
#define ZET_INTEL_STRUCTURE_TYPE_METRIC_DECODED_BUFFER_PROPERTIES_EXP static_cast<zet_structure_type_ext_t>(0x0001000b)
#define ZET_INTEL_STRUCTURE_TYPE_METRIC_HW_BUFFER_SIZE_EXP_DESC static_cast<zet_structure_type_ext_t>(0x00010007)
// Sysman structure types
#define ZES_INTEL_PCI_LINK_SPEED_DOWNGRADE_EXP_STATE static_cast<zes_structure_type_ext_t>(0x00040001)

View File

@@ -495,6 +495,35 @@ 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
#ifndef ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_NAME
/// @brief Extension name for query to read the Intel Level Zero Driver Version String
#define ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_NAME "ZET_intel_get_hw_buffer_size"
#endif // ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_NAME
///////////////////////////////////////////////////////////////////////////////
/// @brief Maximum Hw Buffer Size extension Version(s)
typedef enum _zet_intel_metric_hw_buffer_size_exp_version_t {
ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_VERSION_1_0 = ZE_MAKE_VERSION(1, 0), ///< version 1.0
ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_VERSION_CURRENT = ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_VERSION_1_0, ///< latest known version
ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_VERSION_FORCE_UINT32 = 0x7fffffff
} zet_intel_metric_hw_buffer_size_exp_version_t;
///////////////////////////////////////////////////////////////////////////////
/// @brief Metric hardware buffer size descriptor
/// This descriptor can be used as a "pNext" value to the zet_metric_streamer_desc_t and zet_metric_tracer_exp_desc_t.
/// This descriptor allow to request and query the allocated HW buffer size in bytes.
/// The sizeInBytes should not be used to estimate buffer overflow scenario (Use notifyNReports to detect it).
typedef struct _zet_intel_metric_hw_buffer_size_exp_desc_t {
zet_structure_type_ext_t stype; ///< [in] type of this structure
const void *pNext; ///< [in][optional] must be null or a pointer to an extension-specific
///< structure (i.e. contains stype and pNext).
size_t sizeInBytes; ///< [in,out] size of the hardware buffer size in bytes.
///< If the requested value cannot be supported,
///< then the driver may use a value that can be supported and shall update this member.
///< When hNotificationEvent is set as input has precedence over hw_buffer_size_exp_desc_t when setting HW buffer size.
///< The actual size used by the HW will be updated in "sizeInBytes" member by the implementation.
} zet_intel_metric_hw_buffer_size_exp_desc_t;
#if defined(__cplusplus)
} // extern "C"
#endif

View File

@@ -74,6 +74,18 @@ void MetricSource::initComputeMetricScopes(MetricDeviceContext &metricDeviceCont
metricDeviceContext.setComputeMetricScopeInitialized();
}
std::optional<zet_intel_metric_hw_buffer_size_exp_desc_t *> MetricSource::getHwBufferSizeDesc(zet_base_desc_t *baseDesc) {
while (baseDesc != nullptr) {
if (baseDesc->stype == ZET_INTEL_STRUCTURE_TYPE_METRIC_HW_BUFFER_SIZE_EXP_DESC) {
return reinterpret_cast<zet_intel_metric_hw_buffer_size_exp_desc_t *>(baseDesc);
}
baseDesc = static_cast<zet_base_desc_t *>(const_cast<void *>(baseDesc->pNext));
}
return std::nullopt;
}
MetricDeviceContext::MetricDeviceContext(Device &inputDevice) : device(inputDevice) {
auto deviceNeo = device.getNEODevice();
std::tuple<uint32_t, uint32_t, uint32_t> subDeviceMap;

View File

@@ -109,6 +109,7 @@ class MetricSource {
zet_intel_metric_calculate_operation_exp_handle_t *phCalculateOperation) = 0;
virtual bool canDisable() = 0;
virtual void initMetricScopes(MetricDeviceContext &metricDeviceContext) = 0;
static std::optional<zet_intel_metric_hw_buffer_size_exp_desc_t *> getHwBufferSizeDesc(zet_base_desc_t *baseDesc);
protected:
uint32_t type = MetricSource::metricSourceTypeUndefined;

View File

@@ -56,6 +56,12 @@ ze_result_t IpSamplingMetricGroupImp::streamerOpen(
}
*phMetricStreamer = pStreamerImp->toHandle();
auto hwBufferSizeDesc = MetricSource::getHwBufferSizeDesc(static_cast<zet_base_desc_t *>(const_cast<void *>(desc->pNext)));
if (hwBufferSizeDesc.has_value()) {
// EUSS uses fixed max hw buffer size
hwBufferSizeDesc.value()->sizeInBytes = source.getMetricOsInterface()->getRequiredBufferSize(UINT32_MAX);
}
return ZE_RESULT_SUCCESS;
}
@@ -290,7 +296,8 @@ ze_result_t MultiDeviceIpSamplingMetricGroupImp::streamerOpen(
ze_result_t result = ZE_RESULT_SUCCESS;
std::vector<IpSamplingMetricStreamerImp *> subDeviceStreamers = {};
subDeviceStreamers.reserve(subDeviceMetricGroup.size());
const auto numSubDevices = subDeviceMetricGroup.size();
subDeviceStreamers.reserve(numSubDevices);
// Open SubDevice Streamers
for (auto &metricGroup : subDeviceMetricGroup) {
@@ -309,6 +316,14 @@ ze_result_t MultiDeviceIpSamplingMetricGroupImp::streamerOpen(
pStreamerImp->attachEvent(hNotificationEvent);
*phMetricStreamer = pStreamerImp->toHandle();
auto hwBufferSizeDesc = MetricSource::getHwBufferSizeDesc(static_cast<zet_base_desc_t *>(const_cast<void *>(desc->pNext)));
if (hwBufferSizeDesc.has_value()) {
auto device = Device::fromHandle(hDevice);
IpSamplingMetricSourceImp &source = device->getMetricDeviceContext().getMetricSource<IpSamplingMetricSourceImp>();
// EUSS uses fixed max hw buffer size
hwBufferSizeDesc.value()->sizeInBytes = source.getMetricOsInterface()->getRequiredBufferSize(UINT32_MAX) * numSubDevices;
}
return result;
}

View File

@@ -250,6 +250,7 @@ struct OaMetricGroupImp : public MetricGroupImp {
private:
ze_result_t openForDevice(Device *pDevice, zet_metric_streamer_desc_t &desc,
const bool isNotificationEnabled,
zet_metric_streamer_handle_t *phMetricStreamer);
};

View File

@@ -152,23 +152,45 @@ ze_result_t OaMetricStreamerImp::initialize(ze_device_handle_t hDevice,
return ZE_RESULT_SUCCESS;
}
uint32_t OaMetricStreamerImp::getOaBufferSize(const uint32_t notifyEveryNReports) const {
uint32_t OaMetricStreamerImp::getOaBufferSizeForNotification(const uint32_t notifyEveryNReports) const {
// Notification is on half full buffer, hence multiplication by 2.
return notifyEveryNReports * rawReportSize * 2;
}
ze_result_t OaMetricStreamerImp::startMeasurements(uint32_t &notifyEveryNReports,
uint32_t &samplingPeriodNs) {
auto metricGroup = static_cast<OaMetricGroupImp *>(MetricGroup::fromHandle(hMetricGroup));
uint32_t requestedOaBufferSize = getOaBufferSize(notifyEveryNReports);
uint32_t OaMetricStreamerImp::getOaBufferSizeForReports(const uint32_t maxReportCount) const {
const ze_result_t result = metricGroup->openIoStream(samplingPeriodNs, requestedOaBufferSize);
return maxReportCount * rawReportSize;
}
ze_result_t OaMetricStreamerImp::updateStreamerDescriptionAndStartMeasurements(zet_metric_streamer_desc_t &streamerDesc, const bool isNotificationEnabled) {
auto metricGroup = static_cast<OaMetricGroupImp *>(MetricGroup::fromHandle(hMetricGroup));
uint32_t requestedOaBufferSize = 0;
bool useNotifyNReports = true;
auto hwBufferSizeDesc = MetricSource::getHwBufferSizeDesc(static_cast<zet_base_desc_t *>(const_cast<void *>(streamerDesc.pNext)));
if (hwBufferSizeDesc.has_value() && !isNotificationEnabled) {
// Use value inside hwBufferSizeDesc only if notification was not enabled
auto expectReportCount = static_cast<uint32_t>(hwBufferSizeDesc.value()->sizeInBytes / rawReportSize);
requestedOaBufferSize = getOaBufferSizeForReports(expectReportCount);
useNotifyNReports = false;
}
if (useNotifyNReports) {
requestedOaBufferSize = getOaBufferSizeForNotification(streamerDesc.notifyEveryNReports);
}
const ze_result_t result = metricGroup->openIoStream(streamerDesc.samplingPeriod, requestedOaBufferSize);
// Return oa buffer size and notification event aligned to gpu capabilities.
if (result == ZE_RESULT_SUCCESS) {
oaBufferSize = requestedOaBufferSize;
notifyEveryNReports = getNotifyEveryNReports(requestedOaBufferSize);
if (useNotifyNReports) {
streamerDesc.notifyEveryNReports = getNotifyEveryNReports(requestedOaBufferSize);
}
if (hwBufferSizeDesc != std::nullopt) {
hwBufferSizeDesc.value()->sizeInBytes = requestedOaBufferSize;
}
}
return result;
@@ -226,6 +248,7 @@ uint32_t OaMetricStreamerImp::getRequiredBufferSize(const uint32_t maxReportCoun
}
ze_result_t OaMetricGroupImp::openForDevice(Device *pDevice, zet_metric_streamer_desc_t &desc,
const bool isNotificationEnabled,
zet_metric_streamer_handle_t *phMetricStreamer) {
auto &metricSource = pDevice->getMetricDeviceContext().getMetricSource<OaMetricSourceImp>();
@@ -266,8 +289,7 @@ ze_result_t OaMetricGroupImp::openForDevice(Device *pDevice, zet_metric_streamer
UNRECOVERABLE_IF(pMetricStreamer == nullptr);
pMetricStreamer->initialize(pDevice->toHandle(), toHandle());
const ze_result_t result = pMetricStreamer->startMeasurements(
desc.notifyEveryNReports, desc.samplingPeriod);
const ze_result_t result = pMetricStreamer->updateStreamerDescriptionAndStartMeasurements(desc, isNotificationEnabled);
if (result == ZE_RESULT_SUCCESS) {
metricSource.setMetricStreamer(pMetricStreamer);
} else {
@@ -290,6 +312,7 @@ ze_result_t OaMetricGroupImp::streamerOpen(
ze_result_t result = ZE_RESULT_SUCCESS;
auto pDevice = Device::fromHandle(hDevice);
const auto pDeviceImp = static_cast<const DeviceImp *>(pDevice);
const auto isNotificationEnabled = hNotificationEvent != nullptr;
if (pDeviceImp->metricContext->isImplicitScalingCapable()) {
const uint32_t subDeviceCount = pDeviceImp->numSubDevices;
@@ -299,10 +322,19 @@ ze_result_t OaMetricGroupImp::streamerOpen(
auto &metricStreamers = pMetricStreamer->getMetricStreamers();
metricStreamers.resize(subDeviceCount);
// for a root-device handle, split the sizeInBytes request considering the sub-device count
auto isHwBufferSizeRequested = false;
auto hwBufferSizeDesc = MetricSource::getHwBufferSizeDesc(static_cast<zet_base_desc_t *>(const_cast<void *>(desc->pNext)));
if (hwBufferSizeDesc != std::nullopt) {
hwBufferSizeDesc.value()->sizeInBytes /= subDeviceCount;
isHwBufferSizeRequested = true;
}
for (uint32_t i = 0; i < subDeviceCount; i++) {
auto metricGroupsSubDevice = static_cast<OaMetricGroupImp *>(MetricGroup::fromHandle(getMetricGroups()[i]));
result = metricGroupsSubDevice->openForDevice(pDeviceImp->subDevices[i], *desc, &metricStreamers[i]);
result = metricGroupsSubDevice->openForDevice(pDeviceImp->subDevices[i], *desc, isNotificationEnabled, &metricStreamers[i]);
if (result != ZE_RESULT_SUCCESS) {
for (uint32_t j = 0; j < i; j++) {
auto metricStreamerSubDevice = MetricStreamer::fromHandle(metricStreamers[j]);
@@ -313,10 +345,15 @@ ze_result_t OaMetricGroupImp::streamerOpen(
}
}
// for a root-device handle, update the sizeInBytes considering the sub-device count
if (isHwBufferSizeRequested) {
hwBufferSizeDesc.value()->sizeInBytes *= subDeviceCount;
}
*phMetricStreamer = pMetricStreamer->toHandle();
} else {
result = openForDevice(pDevice, *desc, phMetricStreamer);
result = openForDevice(pDevice, *desc, isNotificationEnabled, phMetricStreamer);
}
if (result == ZE_RESULT_SUCCESS) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -20,7 +20,7 @@ struct OaMetricStreamerImp : MetricStreamer {
ze_result_t close() override;
ze_result_t initialize(ze_device_handle_t hDevice, zet_metric_group_handle_t hMetricGroup);
ze_result_t startMeasurements(uint32_t &notifyEveryNReports, uint32_t &samplingPeriodNs);
ze_result_t updateStreamerDescriptionAndStartMeasurements(zet_metric_streamer_desc_t &desc, const bool isNotificationEnabled);
Event::State getNotificationState() override;
ze_result_t appendStreamerMarker(CommandList &commandList, uint32_t value) override;
@@ -28,7 +28,8 @@ struct OaMetricStreamerImp : MetricStreamer {
protected:
ze_result_t stopMeasurements();
uint32_t getOaBufferSize(const uint32_t notifyEveryNReports) const;
uint32_t getOaBufferSizeForNotification(const uint32_t notifyEveryNReports) const;
uint32_t getOaBufferSizeForReports(const uint32_t maxReportCount) const;
uint32_t getNotifyEveryNReports(const uint32_t oaBufferSize) const;
uint32_t getRequiredBufferSize(const uint32_t maxReportCount) const;

View File

@@ -59,6 +59,39 @@ TEST_F(MetricIpSamplingStreamerTest, GivenAllInputsAreCorrectWhenStreamerOpenAnd
}
}
TEST_F(MetricIpSamplingStreamerTest, GivenAllInputsAreCorrectWhenStreamerOpenWithHwBufferSizeQueryIsCalledExpectedSizeIsReturned) {
EXPECT_EQ(ZE_RESULT_SUCCESS, testDevices[0]->getMetricDeviceContext().enableMetricApi());
for (auto device : testDevices) {
zet_metric_group_handle_t metricGroupHandle = MetricIpSamplingStreamerTest::getMetricGroup(device);
EXPECT_EQ(zetContextActivateMetricGroups(context->toHandle(), device, 1, &metricGroupHandle), ZE_RESULT_SUCCESS);
ze_event_handle_t eventHandle = {};
zet_metric_streamer_handle_t streamerHandle = {};
zet_metric_streamer_desc_t streamerDesc = {};
streamerDesc.stype = ZET_STRUCTURE_TYPE_METRIC_STREAMER_DESC;
streamerDesc.notifyEveryNReports = 32768;
streamerDesc.samplingPeriod = 1000;
zet_intel_metric_hw_buffer_size_exp_desc_t hwBufferSizeDesc{};
hwBufferSizeDesc.sizeInBytes = 128u;
hwBufferSizeDesc.stype = ZET_INTEL_STRUCTURE_TYPE_METRIC_HW_BUFFER_SIZE_EXP_DESC;
hwBufferSizeDesc.pNext = nullptr;
streamerDesc.pNext = &hwBufferSizeDesc;
EXPECT_EQ(zetMetricStreamerOpen(context->toHandle(), device, metricGroupHandle, &streamerDesc, eventHandle, &streamerHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(streamerHandle, nullptr);
const uint32_t reportSize = 64;
DeviceImp *deviceImp = static_cast<DeviceImp *>(device);
size_t expectedSize = reportSize * UINT32_MAX;
expectedSize *= (!deviceImp->isSubdevice && deviceImp->isImplicitScalingCapable()) ? deviceImp->numSubDevices : 1u;
EXPECT_EQ(hwBufferSizeDesc.sizeInBytes, expectedSize);
EXPECT_EQ(zetMetricStreamerClose(streamerHandle), ZE_RESULT_SUCCESS);
}
}
TEST_F(MetricIpSamplingStreamerTest, GivenEventHandleIsNullWhenStreamerOpenAndCloseAreCalledThenSuccessIsReturned) {
EXPECT_EQ(ZE_RESULT_SUCCESS, testDevices[0]->getMetricDeviceContext().enableMetricApi());

View File

@@ -10,6 +10,7 @@
#include "level_zero/core/test/unit_tests/mocks/mock_cmdlist.h"
#include "level_zero/core/test/unit_tests/mocks/mock_driver.h"
#include "level_zero/core/test/unit_tests/mocks/mock_event.h"
#include "level_zero/tools/source/metrics/metric_oa_source.h"
#include "level_zero/tools/test/unit_tests/sources/metrics/mock_metric_oa.h"
@@ -1503,5 +1504,217 @@ TEST_F(MetricStreamerTest, givenMultipleMarkerInsertionsWhenZetCommandListAppend
EXPECT_EQ(zetMetricStreamerClose(streamerHandle), ZE_RESULT_SUCCESS);
}
TEST_F(MetricStreamerTest, WhenStreamerOpenIsCalledWithNotificationEventThenNotifyReportsParameterIsUsedForHwBufferSize) {
zet_device_handle_t metricDeviceHandle = device->toHandle();
zet_metric_streamer_handle_t streamerHandle = {};
auto &metricOaSource = (static_cast<DeviceImp *>(device))->getMetricDeviceContext().getMetricSource<OaMetricSourceImp>();
Mock<MetricGroup> metricGroup(metricOaSource);
zet_metric_group_handle_t metricGroupHandle = metricGroup.toHandle();
metricsDeviceParams.ConcurrentGroupsCount = 1;
Mock<IConcurrentGroup_1_13> metricsConcurrentGroup;
TConcurrentGroupParams_1_13 metricsConcurrentGroupParams = {};
metricsConcurrentGroupParams.MetricSetsCount = 1;
metricsConcurrentGroupParams.SymbolName = "OA";
metricsConcurrentGroupParams.Description = "OA description";
metricsConcurrentGroupParams.IoMeasurementInformationCount = 1;
Mock<MetricsDiscovery::IEquation_1_0> ioReadEquation;
MetricsDiscovery::TEquationElement_1_0 ioEquationElement = {};
ioEquationElement.Type = MetricsDiscovery::EQUATION_ELEM_IMM_UINT64;
ioEquationElement.ImmediateUInt64 = 0;
ioReadEquation.getEquationElement.push_back(&ioEquationElement);
Mock<MetricsDiscovery::IInformation_1_0> ioMeasurement;
MetricsDiscovery::TInformationParams_1_0 oaInformation = {};
oaInformation.SymbolName = "BufferOverflow";
oaInformation.IoReadEquation = &ioReadEquation;
Mock<MetricsDiscovery::IMetricSet_1_13> metricsSet;
MetricsDiscovery::TMetricSetParams_1_11 metricsSetParams = {};
metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_IOSTREAM;
metricsSetParams.MetricsCount = 0;
metricsSetParams.SymbolName = "Metric set name";
metricsSetParams.ShortName = "Metric set description";
metricsSetParams.RawReportSize = 256;
openMetricsAdapter();
setupDefaultMocksForMetricDevice(metricsDevice);
metricsDevice.getConcurrentGroupResults.push_back(&metricsConcurrentGroup);
metricsConcurrentGroup.GetParamsResult = &metricsConcurrentGroupParams;
metricsConcurrentGroup.getMetricSetResult = &metricsSet;
metricsConcurrentGroup.GetIoMeasurementInformationResult = &ioMeasurement;
ioMeasurement.GetParamsResult = &oaInformation;
metricsSet.GetParamsResult = &metricsSetParams;
mockMetricsLibrary->initializationState = ZE_RESULT_SUCCESS;
auto &metricSource = device->getMetricDeviceContext().getMetricSource<OaMetricSourceImp>();
EXPECT_TRUE(metricSource.loadDependencies());
EXPECT_TRUE(metricSource.isInitialized());
uint32_t metricGroupCount = 0;
EXPECT_EQ(zetMetricGroupGet(metricDeviceHandle, &metricGroupCount, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(metricGroupCount, 1u);
EXPECT_EQ(zetMetricGroupGet(metricDeviceHandle, &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(metricGroupCount, 1u);
EXPECT_NE(metricGroupHandle, nullptr);
EXPECT_EQ(zetContextActivateMetricGroups(context->toHandle(), metricDeviceHandle, 1, &metricGroupHandle), ZE_RESULT_SUCCESS);
zet_intel_metric_hw_buffer_size_exp_desc_t hwBufferSizeDesc{};
const uint32_t rawReportSize = 256;
hwBufferSizeDesc.sizeInBytes = 100 * rawReportSize;
hwBufferSizeDesc.stype = ZET_INTEL_STRUCTURE_TYPE_METRIC_HW_BUFFER_SIZE_EXP_DESC;
hwBufferSizeDesc.pNext = nullptr;
zet_metric_streamer_desc_t streamerDesc = {};
streamerDesc.stype = ZET_STRUCTURE_TYPE_METRIC_STREAMER_DESC;
streamerDesc.notifyEveryNReports = 32768;
streamerDesc.samplingPeriod = 1000;
streamerDesc.pNext = &hwBufferSizeDesc;
const uint32_t expectedOaHWBufferSize = streamerDesc.notifyEveryNReports * 2;
MockEvent event{};
EXPECT_EQ(zetMetricStreamerOpen(context->toHandle(), metricDeviceHandle, metricGroupHandle, &streamerDesc, event.toHandle(), &streamerHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(streamerHandle, nullptr);
EXPECT_EQ(hwBufferSizeDesc.sizeInBytes, static_cast<size_t>(expectedOaHWBufferSize * rawReportSize));
EXPECT_EQ(zetMetricStreamerClose(streamerHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(streamerHandle, nullptr);
}
TEST_F(MetricStreamerTest, WhenStreamerOpenIsCalledWithoutNotificationEventThenMaximumhwBufferSizeDescriptorIsUsedForHwBufferSize) {
zet_device_handle_t metricDeviceHandle = device->toHandle();
zet_metric_streamer_handle_t streamerHandle = {};
auto &metricOaSource = (static_cast<DeviceImp *>(device))->getMetricDeviceContext().getMetricSource<OaMetricSourceImp>();
Mock<MetricGroup> metricGroup(metricOaSource);
zet_metric_group_handle_t metricGroupHandle = metricGroup.toHandle();
metricsDeviceParams.ConcurrentGroupsCount = 1;
Mock<IConcurrentGroup_1_13> metricsConcurrentGroup;
TConcurrentGroupParams_1_13 metricsConcurrentGroupParams = {};
metricsConcurrentGroupParams.MetricSetsCount = 1;
metricsConcurrentGroupParams.SymbolName = "OA";
metricsConcurrentGroupParams.Description = "OA description";
metricsConcurrentGroupParams.IoMeasurementInformationCount = 1;
Mock<MetricsDiscovery::IEquation_1_0> ioReadEquation;
MetricsDiscovery::TEquationElement_1_0 ioEquationElement = {};
ioEquationElement.Type = MetricsDiscovery::EQUATION_ELEM_IMM_UINT64;
ioEquationElement.ImmediateUInt64 = 0;
ioReadEquation.getEquationElement.push_back(&ioEquationElement);
Mock<MetricsDiscovery::IInformation_1_0> ioMeasurement;
MetricsDiscovery::TInformationParams_1_0 oaInformation = {};
oaInformation.SymbolName = "BufferOverflow";
oaInformation.IoReadEquation = &ioReadEquation;
Mock<MetricsDiscovery::IMetricSet_1_13> metricsSet;
MetricsDiscovery::TMetricSetParams_1_11 metricsSetParams = {};
metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_IOSTREAM;
metricsSetParams.MetricsCount = 0;
metricsSetParams.SymbolName = "Metric set name";
metricsSetParams.ShortName = "Metric set description";
metricsSetParams.RawReportSize = 256;
openMetricsAdapter();
setupDefaultMocksForMetricDevice(metricsDevice);
metricsDevice.getConcurrentGroupResults.push_back(&metricsConcurrentGroup);
metricsConcurrentGroup.GetParamsResult = &metricsConcurrentGroupParams;
metricsConcurrentGroup.getMetricSetResult = &metricsSet;
metricsConcurrentGroup.GetIoMeasurementInformationResult = &ioMeasurement;
ioMeasurement.GetParamsResult = &oaInformation;
metricsSet.GetParamsResult = &metricsSetParams;
mockMetricsLibrary->initializationState = ZE_RESULT_SUCCESS;
auto &metricSource = device->getMetricDeviceContext().getMetricSource<OaMetricSourceImp>();
EXPECT_TRUE(metricSource.loadDependencies());
EXPECT_TRUE(metricSource.isInitialized());
uint32_t metricGroupCount = 0;
EXPECT_EQ(zetMetricGroupGet(metricDeviceHandle, &metricGroupCount, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(metricGroupCount, 1u);
EXPECT_EQ(zetMetricGroupGet(metricDeviceHandle, &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(metricGroupCount, 1u);
EXPECT_NE(metricGroupHandle, nullptr);
EXPECT_EQ(zetContextActivateMetricGroups(context->toHandle(), metricDeviceHandle, 1, &metricGroupHandle), ZE_RESULT_SUCCESS);
const uint32_t expectedMaxReportCount = 100;
const uint32_t rawReportSize = 256;
// Create a chain of descriptors using pNext
// streamerDesc -> dummyhwBufferSizeDesc -> hwBufferSizeDesc -> nullptr
zet_intel_metric_hw_buffer_size_exp_desc_t hwBufferSizeDesc{};
hwBufferSizeDesc.sizeInBytes = expectedMaxReportCount * rawReportSize + (rawReportSize - 1);
hwBufferSizeDesc.stype = ZET_INTEL_STRUCTURE_TYPE_METRIC_HW_BUFFER_SIZE_EXP_DESC;
hwBufferSizeDesc.pNext = nullptr;
zet_intel_metric_hw_buffer_size_exp_desc_t dummyhwBufferSizeDesc{};
dummyhwBufferSizeDesc.sizeInBytes = 0;
auto dummyStructureType = ZET_INTEL_STRUCTURE_TYPE_METRIC_HW_BUFFER_SIZE_EXP_DESC + 1;
dummyhwBufferSizeDesc.stype = static_cast<zet_structure_type_ext_t>(dummyStructureType);
dummyhwBufferSizeDesc.pNext = &hwBufferSizeDesc;
zet_metric_streamer_desc_t streamerDesc = {};
streamerDesc.stype = ZET_STRUCTURE_TYPE_METRIC_STREAMER_DESC;
streamerDesc.notifyEveryNReports = 32768;
streamerDesc.samplingPeriod = 1000;
streamerDesc.pNext = &dummyhwBufferSizeDesc;
EXPECT_EQ(zetMetricStreamerOpen(context->toHandle(), metricDeviceHandle, metricGroupHandle, &streamerDesc, nullptr, &streamerHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(streamerHandle, nullptr);
EXPECT_EQ(hwBufferSizeDesc.sizeInBytes, expectedMaxReportCount * rawReportSize);
EXPECT_EQ(zetMetricStreamerClose(streamerHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(streamerHandle, nullptr);
}
using DriverVersionTest = Test<DeviceFixture>;
TEST_F(DriverVersionTest, givenSupportedExtensionsWhenCheckIfSizeInBytesIsSupportedThenCorrectResultsAreReturned) {
uint32_t count = 0;
ze_result_t res = driverHandle->getExtensionProperties(&count, nullptr);
EXPECT_NE(0u, count);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
std::vector<ze_driver_extension_properties_t> extensionProperties;
extensionProperties.resize(count);
res = driverHandle->getExtensionProperties(&count, extensionProperties.data());
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
auto it = std::find_if(extensionProperties.begin(), extensionProperties.end(), [](const auto &extension) { return (strcmp(extension.name, ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_NAME) == 0); });
EXPECT_NE(it, extensionProperties.end());
EXPECT_EQ((*it).version, ZET_INTEL_METRIC_HW_BUFFER_SIZE_EXP_VERSION_CURRENT);
}
} // namespace ult
} // namespace L0

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -224,6 +224,97 @@ TEST_F(MetricStreamerMultiDeviceTest, givenValidArgumentsWhenZetMetricGroupCalcu
EXPECT_EQ(zetMetricStreamerClose(streamerHandle), ZE_RESULT_SUCCESS);
}
TEST_F(MetricStreamerMultiDeviceTest, WhenStreamerOpenIsCalledWithoutNotificationEventThenNotifyReportsParameterIsUsedForHwBufferSize) {
zet_device_handle_t metricDeviceHandle = devices[0]->toHandle();
zet_metric_streamer_handle_t streamerHandle = {};
zet_metric_streamer_desc_t streamerDesc = {};
zet_intel_metric_hw_buffer_size_exp_desc_t hwBufferSizeDesc{};
const uint32_t rawReportSize = 256;
hwBufferSizeDesc.sizeInBytes = 100 * rawReportSize;
hwBufferSizeDesc.stype = ZET_INTEL_STRUCTURE_TYPE_METRIC_HW_BUFFER_SIZE_EXP_DESC;
hwBufferSizeDesc.pNext = nullptr;
streamerDesc.stype = ZET_STRUCTURE_TYPE_METRIC_STREAMER_DESC;
streamerDesc.notifyEveryNReports = 32768;
streamerDesc.samplingPeriod = 1000;
streamerDesc.pNext = &hwBufferSizeDesc;
auto &metricOaSource = (static_cast<DeviceImp *>(devices[0]))->getMetricDeviceContext().getMetricSource<OaMetricSourceImp>();
Mock<MetricGroup> metricGroup(metricOaSource);
zet_metric_group_handle_t metricGroupHandle = metricGroup.toHandle();
metricsDeviceParams.ConcurrentGroupsCount = 1;
Mock<IConcurrentGroup_1_13> metricsConcurrentGroup;
TConcurrentGroupParams_1_13 metricsConcurrentGroupParams = {};
metricsConcurrentGroupParams.MetricSetsCount = 1;
metricsConcurrentGroupParams.SymbolName = "OA";
metricsConcurrentGroupParams.Description = "OA description";
metricsConcurrentGroupParams.IoMeasurementInformationCount = 1;
Mock<MetricsDiscovery::IMetricSet_1_13> metricsSet;
MetricsDiscovery::TMetricSetParams_1_11 metricsSetParams = {};
metricsSetParams.ApiMask = MetricsDiscovery::API_TYPE_IOSTREAM;
metricsSetParams.SymbolName = "Metric set name";
metricsSetParams.ShortName = "Metric set description";
metricsSetParams.RawReportSize = 256;
metricsSetParams.MetricsCount = 11;
Mock<MetricsDiscovery::IEquation_1_0> ioReadEquation;
MetricsDiscovery::TEquationElement_1_0 ioEquationElement = {};
ioEquationElement.Type = MetricsDiscovery::EQUATION_ELEM_IMM_UINT64;
ioEquationElement.ImmediateUInt64 = 0;
ioReadEquation.getEquationElement.push_back(&ioEquationElement);
Mock<MetricsDiscovery::IInformation_1_0> ioMeasurement;
MetricsDiscovery::TInformationParams_1_0 oaInformation = {};
oaInformation.SymbolName = "BufferOverflow";
oaInformation.IoReadEquation = &ioReadEquation;
Mock<IMetric_1_13> metric;
MetricsDiscovery::TMetricParams_1_13 metricParams = {};
uint32_t returnedMetricCount = 1;
openMetricsAdapter();
setupDefaultMocksForMetricDevice(metricsDevice);
metricsDevice.getConcurrentGroupResults.push_back(&metricsConcurrentGroup);
metricsConcurrentGroup.GetParamsResult = &metricsConcurrentGroupParams;
metricsConcurrentGroup.getMetricSetResult = &metricsSet;
metricsConcurrentGroup.GetIoMeasurementInformationResult = &ioMeasurement;
metricsSet.GetParamsResult = &metricsSetParams;
metricsSet.GetMetricResult = &metric;
metricsSet.calculateMetricsOutReportCount = &returnedMetricCount;
metric.GetParamsResult = &metricParams;
ioMeasurement.GetParamsResult = &oaInformation;
uint32_t metricGroupCount = 0;
EXPECT_EQ(zetMetricGroupGet(metricDeviceHandle, &metricGroupCount, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(metricGroupCount, 1u);
EXPECT_EQ(zetMetricGroupGet(metricDeviceHandle, &metricGroupCount, &metricGroupHandle), ZE_RESULT_SUCCESS);
EXPECT_EQ(metricGroupCount, 1u);
EXPECT_NE(metricGroupHandle, nullptr);
EXPECT_EQ(zetContextActivateMetricGroups(context->toHandle(), metricDeviceHandle, 1, &metricGroupHandle), ZE_RESULT_SUCCESS);
const size_t expectedOaHWBufferSize = hwBufferSizeDesc.sizeInBytes;
EXPECT_EQ(zetMetricStreamerOpen(context->toHandle(), metricDeviceHandle, metricGroupHandle, &streamerDesc, nullptr, &streamerHandle), ZE_RESULT_SUCCESS);
EXPECT_NE(streamerHandle, nullptr);
EXPECT_EQ(hwBufferSizeDesc.sizeInBytes, expectedOaHWBufferSize);
EXPECT_EQ(zetMetricStreamerClose(streamerHandle), ZE_RESULT_SUCCESS);
}
using MetricStreamerTest = Test<MetricContextFixture>;
TEST_F(MetricStreamerTest, givenRawReportSizeIsNotAlignedToOaBufferSizeWhenZetMetricStreamerReadDataIsCalledThenReadSizeIsAlignedToRawReportSize) {