Add Support for sysman Performance factor on windows

Related-To: LOCI-3342

Signed-off-by: Mayank Raghuwanshi <mayank.raghuwanshi@intel.com>
This commit is contained in:
Mayank Raghuwanshi
2022-12-28 08:07:26 +00:00
committed by Compute-Runtime-Automation
parent 76c3b4ad53
commit d7292a6b0d
8 changed files with 440 additions and 16 deletions

View File

@@ -0,0 +1,14 @@
#
# Copyright (C) 2023 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
if(WIN32)
target_sources(${TARGET_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/test_zes_performance.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_performance.h
)
endif()

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/core/test/unit_tests/mock.h"
#include "level_zero/tools/source/sysman/performance/windows/os_performance_imp.h"
#include "level_zero/tools/test/unit_tests/sources/sysman/windows/mock_kmd_sys_manager.h"
namespace L0 {
namespace ult {
class PerformanceKmdSysManager : public Mock<MockKmdSysManager> {};
template <>
struct Mock<PerformanceKmdSysManager> : public PerformanceKmdSysManager {
uint32_t mockNumberOfDomains = 1;
uint32_t mockPerformanceFactor = 0;
void getPerformanceProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) override {
uint8_t *pBuffer = reinterpret_cast<uint8_t *>(pResponse);
pBuffer += sizeof(KmdSysman::GfxSysmanReqHeaderOut);
KmdSysman::ActivityDomainsType domain = static_cast<KmdSysman::ActivityDomainsType>(pRequest->inCommandParam);
if (domain != KmdSysman::ActivityDomainsType::ActivityDomainMedia) {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
return;
}
switch (pRequest->inRequestId) {
case KmdSysman::Requests::Performance::NumPerformanceDomains: {
uint32_t *pValue = reinterpret_cast<uint32_t *>(pBuffer);
*pValue = mockNumberOfDomains;
pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess;
pResponse->outDataSize = sizeof(uint32_t);
} break;
case KmdSysman::Requests::Performance::Factor: {
uint32_t *pValue = reinterpret_cast<uint32_t *>(pBuffer);
*pValue = mockPerformanceFactor;
pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess;
pResponse->outDataSize = sizeof(uint32_t);
} break;
default: {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
} break;
}
}
void setPerformanceProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) override {
uint8_t *pBuffer = reinterpret_cast<uint8_t *>(pRequest);
pBuffer += sizeof(KmdSysman::GfxSysmanReqHeaderIn);
KmdSysman::ActivityDomainsType domain = static_cast<KmdSysman::ActivityDomainsType>(pRequest->inCommandParam);
if (domain != KmdSysman::ActivityDomainsType::ActivityDomainMedia) {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
return;
}
switch (pRequest->inRequestId) {
case KmdSysman::Requests::Performance::Factor: {
uint32_t *pValue = reinterpret_cast<uint32_t *>(pBuffer);
mockPerformanceFactor = *pValue;
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanSuccess;
} break;
default: {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
} break;
}
}
Mock() = default;
~Mock() override = default;
};
class PublicWddmPerformanceImp : public L0::WddmPerformanceImp {
public:
PublicWddmPerformanceImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_engine_type_flag_t domain) : WddmPerformanceImp(pOsSysman, onSubdevice, subdeviceId, domain) {}
using WddmPerformanceImp::domain;
using WddmPerformanceImp::pKmdSysManager;
};
} // namespace ult
} // namespace L0

View File

@@ -0,0 +1,188 @@
/*
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/tools/source/sysman/performance/windows/os_performance_imp.h"
#include "level_zero/tools/test/unit_tests/sources/sysman/performance/windows/mock_performance.h"
#include "level_zero/tools/test/unit_tests/sources/sysman/windows/mock_sysman_fixture.h"
extern bool sysmanUltsEnable;
namespace L0 {
namespace ult {
constexpr uint32_t mockHandleCount = 1u;
constexpr double maxPerformanceFactor = 100;
constexpr double halfOfMaxPerformanceFactor = 50;
constexpr double minPerformanceFactor = 0;
class SysmanDevicePerformanceFixture : public SysmanDeviceFixture {
protected:
std::unique_ptr<Mock<PerformanceKmdSysManager>> pKmdSysManager;
KmdSysManager *pOriginalKmdSysManager = nullptr;
void SetUp() override {
if (!sysmanUltsEnable) {
GTEST_SKIP();
}
SysmanDeviceFixture::SetUp();
pKmdSysManager.reset(new Mock<PerformanceKmdSysManager>);
pKmdSysManager->allowSetCalls = true;
pOriginalKmdSysManager = pWddmSysmanImp->pKmdSysManager;
pWddmSysmanImp->pKmdSysManager = pKmdSysManager.get();
for (auto handle : pSysmanDeviceImp->pPerformanceHandleContext->handleList) {
delete handle;
}
pSysmanDeviceImp->pPerformanceHandleContext->handleList.clear();
uint32_t subDeviceCount = 0;
std::vector<ze_device_handle_t> deviceHandles;
// We received a device handle. Check for subdevices in this device
Device::fromHandle(device->toHandle())->getSubDevices(&subDeviceCount, nullptr);
if (subDeviceCount == 0) {
deviceHandles.resize(1, device->toHandle());
} else {
deviceHandles.resize(subDeviceCount, nullptr);
Device::fromHandle(device->toHandle())->getSubDevices(&subDeviceCount, deviceHandles.data());
}
}
void TearDown() override {
if (!sysmanUltsEnable) {
GTEST_SKIP();
}
pWddmSysmanImp->pKmdSysManager = pOriginalKmdSysManager;
SysmanDeviceFixture::TearDown();
}
std::vector<zes_perf_handle_t> getPerfHandles(uint32_t count) {
std::vector<zes_perf_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumPerformanceFactorDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
return handles;
}
};
TEST_F(SysmanDevicePerformanceFixture, GivenValidSysmanHandleWhenRetrievingPerfThenValidHandlesReturned) {
uint32_t count = 0;
ze_result_t result = zesDeviceEnumPerformanceFactorDomains(device->toHandle(), &count, NULL);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(count, mockHandleCount);
uint32_t testcount = count + 1;
result = zesDeviceEnumPerformanceFactorDomains(device->toHandle(), &testcount, NULL);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(testcount, mockHandleCount);
count = 0;
std::vector<zes_perf_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumPerformanceFactorDomains(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
EXPECT_EQ(count, mockHandleCount);
}
TEST_F(SysmanDevicePerformanceFixture, GivenValidSysmanHandleWhenRetrievingPerfAndRequestSingleFailsThenFailuresAreReturned) {
pKmdSysManager->mockRequestSingle = true;
pKmdSysManager->mockRequestSingleResult = ZE_RESULT_ERROR_UNKNOWN;
uint32_t count = 0;
ze_result_t result = zesDeviceEnumPerformanceFactorDomains(device->toHandle(), &count, NULL);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(count, 0u);
}
TEST_F(SysmanDevicePerformanceFixture, GivenValidPerfHandleWhenGettingPerformancePropertiesThenValidPropertiesReturned) {
auto handles = getPerfHandles(mockHandleCount);
for (const auto &handle : handles) {
zes_perf_properties_t properties = {};
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorGetProperties(handle, &properties));
EXPECT_FALSE(properties.onSubdevice);
EXPECT_EQ(properties.engines, ZES_ENGINE_TYPE_FLAG_MEDIA);
EXPECT_EQ(properties.subdeviceId, 0u);
}
}
TEST_F(SysmanDevicePerformanceFixture, GivenValidPerfHandleWhenSettingMediaConfigAndGettingMediaConfigThenSuccessIsReturned) {
pKmdSysManager->allowSetCalls = true;
auto handles = getPerfHandles(mockHandleCount);
for (const auto &handle : handles) {
zes_perf_properties_t properties = {};
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorGetProperties(handle, &properties));
if (properties.engines == ZES_ENGINE_TYPE_FLAG_MEDIA) {
double setFactor = 49;
double getFactor = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorSetConfig(handle, setFactor));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorGetConfig(handle, &getFactor));
EXPECT_DOUBLE_EQ(std::round(getFactor), halfOfMaxPerformanceFactor);
setFactor = 50;
getFactor = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorSetConfig(handle, setFactor));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorGetConfig(handle, &getFactor));
EXPECT_DOUBLE_EQ(std::round(getFactor), halfOfMaxPerformanceFactor);
setFactor = 60;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorSetConfig(handle, setFactor));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorGetConfig(handle, &getFactor));
EXPECT_DOUBLE_EQ(std::round(getFactor), maxPerformanceFactor);
setFactor = 100;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorSetConfig(handle, setFactor));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorGetConfig(handle, &getFactor));
EXPECT_DOUBLE_EQ(std::round(getFactor), maxPerformanceFactor);
setFactor = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorSetConfig(handle, setFactor));
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorGetConfig(handle, &getFactor));
EXPECT_DOUBLE_EQ(std::round(getFactor), minPerformanceFactor);
}
}
}
TEST_F(SysmanDevicePerformanceFixture, GivenValidPerfHandlesWhenRetrievingPerformanceFactorAndKmdReturnsInvalidValueThenUnknownErrorIsReturned) {
pKmdSysManager->mockPerformanceFactor = 512;
auto handles = getPerfHandles(mockHandleCount);
for (const auto &handle : handles) {
double factor = 0;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesPerformanceFactorGetConfig(handle, &factor));
}
}
TEST_F(SysmanDevicePerformanceFixture, GivenValidPerfHandleWhenRetrievingPerformanceFactorAndOsPerformanceGetConfigFailsThenFailureIsReturned) {
pKmdSysManager->mockRequestSingle = true;
pKmdSysManager->mockRequestSingleResult = ZE_RESULT_ERROR_UNKNOWN;
PublicWddmPerformanceImp *pWddmPerformanceImp = new PublicWddmPerformanceImp(pOsSysman, 0, 0u, ZES_ENGINE_TYPE_FLAG_MEDIA);
double pFactor = 0;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, pWddmPerformanceImp->osPerformanceGetConfig(&pFactor));
delete pWddmPerformanceImp;
}
TEST_F(SysmanDevicePerformanceFixture, GivenValidPerfHandleWhenRetrievingPerformanceFactorAndOsPerformanceSetConfigFailsThenFailureIsReturned) {
pKmdSysManager->allowSetCalls = true;
pKmdSysManager->mockRequestSingle = true;
pKmdSysManager->mockRequestSingleResult = ZE_RESULT_ERROR_UNKNOWN;
PublicWddmPerformanceImp *pWddmPerformanceImp = new PublicWddmPerformanceImp(pOsSysman, 0, 0u, ZES_ENGINE_TYPE_FLAG_MEDIA);
double pFactor = halfOfMaxPerformanceFactor;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, pWddmPerformanceImp->osPerformanceSetConfig(pFactor));
delete pWddmPerformanceImp;
}
TEST_F(SysmanDevicePerformanceFixture, GivenValidPerfHandleWhenSettingPerformanceFactorWithInvalidValuesThenInvalidArgumentErrorIsReturned) {
pKmdSysManager->allowSetCalls = true;
auto handles = getPerfHandles(mockHandleCount);
for (const auto &handle : handles) {
zes_perf_properties_t properties = {};
EXPECT_EQ(ZE_RESULT_SUCCESS, zesPerformanceFactorGetProperties(handle, &properties));
if (properties.engines == ZES_ENGINE_TYPE_FLAG_MEDIA) {
double setFactor = -1;
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zesPerformanceFactorSetConfig(handle, setFactor));
setFactor = 110;
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, zesPerformanceFactorSetConfig(handle, setFactor));
}
}
}
} // namespace ult
} // namespace L0

View File

@@ -98,6 +98,11 @@ struct Mock<MockKmdSysManager> : public MockKmdSysManager {
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
}
MOCKABLE_VIRTUAL void getPerformanceProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
}
MOCKABLE_VIRTUAL void setActivityProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
@@ -123,6 +128,11 @@ struct Mock<MockKmdSysManager> : public MockKmdSysManager {
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
}
MOCKABLE_VIRTUAL void setPerformanceProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
}
MOCKABLE_VIRTUAL void getFpsProperty(KmdSysman::GfxSysmanReqHeaderIn *pRequest, KmdSysman::GfxSysmanReqHeaderOut *pResponse) {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
@@ -358,6 +368,9 @@ struct Mock<MockKmdSysManager> : public MockKmdSysManager {
case KmdSysman::Component::GlobalOperationsComponent: {
setGlobalOperationsProperty(pRequest, pResponse);
} break;
case KmdSysman::Component::PerformanceComponent: {
setPerformanceProperty(pRequest, pResponse);
} break;
default: {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;
@@ -400,6 +413,9 @@ struct Mock<MockKmdSysManager> : public MockKmdSysManager {
case KmdSysman::Component::GlobalOperationsComponent: {
getGlobalOperationsProperty(pRequest, pResponse);
} break;
case KmdSysman::Component::PerformanceComponent: {
getPerformanceProperty(pRequest, pResponse);
} break;
default: {
pResponse->outDataSize = 0;
pResponse->outReturnCode = KmdSysman::KmdSysmanFail;