Add support to query PMU counters

This change adds support to get engine active time and timestamp
from PMU interface.

Change-Id: I486dcce9fef3c7dc3f73fb8c7ea4c0bd020a6807
Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
Jitendra Sharma
2020-08-26 15:32:23 +05:30
committed by sys_ocldev
parent ef2f9e9299
commit 38ecb25ee6
12 changed files with 435 additions and 28 deletions

View File

@@ -19,6 +19,12 @@ static const std::multimap<drm_i915_gem_engine_class, zes_engine_group_t> i915To
{I915_ENGINE_CLASS_VIDEO, ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE},
{I915_ENGINE_CLASS_COPY, ZES_ENGINE_GROUP_COPY_SINGLE}};
static const std::multimap<zes_engine_group_t, drm_i915_gem_engine_class> engineToI915Map = {
{ZES_ENGINE_GROUP_RENDER_SINGLE, I915_ENGINE_CLASS_RENDER},
{ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE, I915_ENGINE_CLASS_VIDEO},
{ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE, I915_ENGINE_CLASS_VIDEO},
{ZES_ENGINE_GROUP_COPY_SINGLE, I915_ENGINE_CLASS_COPY}};
ze_result_t OsEngine::getNumEngineTypeAndInstances(std::multimap<zes_engine_group_t, uint32_t> &engineGroupInstance, OsSysman *pOsSysman) {
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
NEO::Drm *pDrm = &pLinuxSysmanImp->getDrm();
@@ -39,9 +45,17 @@ ze_result_t OsEngine::getNumEngineTypeAndInstances(std::multimap<zes_engine_grou
}
ze_result_t LinuxEngineImp::getActivity(zes_engine_stats_t *pStats) {
pStats->timestamp = 0;
pStats->activeTime = 0;
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
if (fd < 0) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
uint64_t data[2] = {};
if (pPmuInterface->pmuReadSingle(static_cast<int>(fd), data, sizeof(data)) < 0) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
// In data[], First u64 is "active time", And second u64 is "timestamp". Both in nanoseconds
pStats->activeTime = data[0] / microSecondsToNanoSeconds;
pStats->timestamp = data[1] / microSecondsToNanoSeconds;
return ZE_RESULT_SUCCESS;
}
ze_result_t LinuxEngineImp::getProperties(zes_engine_properties_t &properties) {
@@ -51,9 +65,16 @@ ze_result_t LinuxEngineImp::getProperties(zes_engine_properties_t &properties) {
return ZE_RESULT_SUCCESS;
}
void LinuxEngineImp::init() {
auto i915EngineClass = engineToI915Map.find(engineGroup);
// I915_PMU_ENGINE_BUSY macro provides the perf type config which we want to listen to get the engine busyness.
fd = pPmuInterface->pmuInterfaceOpen(I915_PMU_ENGINE_BUSY(i915EngineClass->second, engineInstance), -1, PERF_FORMAT_TOTAL_TIME_ENABLED);
}
LinuxEngineImp::LinuxEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance) : engineGroup(type), engineInstance(engineInstance) {
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
pDrm = &pLinuxSysmanImp->getDrm();
pPmuInterface = pLinuxSysmanImp->getPmuInterface();
init();
}
OsEngine *OsEngine::create(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance) {

View File

@@ -11,18 +11,29 @@
#include "sysman/engine/os_engine.h"
namespace L0 {
class PmuInterface;
class LinuxEngineImp : public OsEngine, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getActivity(zes_engine_stats_t *pStats) override;
ze_result_t getProperties(zes_engine_properties_t &properties) override;
LinuxEngineImp() = default;
LinuxEngineImp(OsSysman *pOsSysman, zes_engine_group_t type, uint32_t engineInstance);
~LinuxEngineImp() override = default;
~LinuxEngineImp() override {
if (fd != -1) {
close(static_cast<int>(fd));
fd = -1;
}
}
protected:
zes_engine_group_t engineGroup = ZES_ENGINE_GROUP_ALL;
uint32_t engineInstance = 0;
NEO::Drm *pDrm = nullptr;
PmuInterface *pPmuInterface = nullptr;
private:
void init();
const uint32_t microSecondsToNanoSeconds = 1000u;
int64_t fd = -1;
};
} // namespace L0

View File

@@ -37,10 +37,16 @@ ze_result_t LinuxSysmanImp::init() {
pPmt = new PlatformMonitoringTech();
UNRECOVERABLE_IF(nullptr == pPmt);
pPmt->init(myDeviceName, pFsAccess);
pPmuInterface = PmuInterface::create(this);
UNRECOVERABLE_IF(nullptr == pPmuInterface);
return ZE_RESULT_SUCCESS;
}
PmuInterface *LinuxSysmanImp::getPmuInterface() {
return pPmuInterface;
}
XmlParser *LinuxSysmanImp::getXmlParser() {
return pXmlParser;
}
@@ -99,6 +105,10 @@ LinuxSysmanImp::~LinuxSysmanImp() {
delete pPmt;
pPmt = nullptr;
}
if (nullptr != pPmuInterface) {
delete pPmuInterface;
pPmuInterface = nullptr;
}
}
OsSysman *OsSysman::create(SysmanDeviceImp *pParentSysmanDeviceImp) {

View File

@@ -13,10 +13,12 @@
#include "level_zero/core/source/device/device.h"
#include "level_zero/tools/source/sysman/linux/fs_access.h"
#include "level_zero/tools/source/sysman/linux/pmt.h"
#include "level_zero/tools/source/sysman/linux/pmu/pmu_imp.h"
#include "level_zero/tools/source/sysman/linux/xml_parser/xml_parser.h"
#include "level_zero/tools/source/sysman/sysman_imp.h"
namespace L0 {
class PmuInterface;
class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
public:
@@ -26,6 +28,7 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
ze_result_t init() override;
XmlParser *getXmlParser();
PmuInterface *getPmuInterface();
FsAccess &getFsAccess();
ProcfsAccess &getProcfsAccess();
SysfsAccess &getSysfsAccess();
@@ -41,6 +44,7 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
PlatformMonitoringTech *pPmt = nullptr;
NEO::Drm *pDrm = nullptr;
Device *pDevice = nullptr;
PmuInterface *pPmuInterface = nullptr;
private:
LinuxSysmanImp() = delete;

View File

@@ -0,0 +1,19 @@
#
# Copyright (C) 2020 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
set(L0_SRCS_TOOLS_SYSMAN_LINUX_PMU
${CMAKE_CURRENT_SOURCE_DIR}/pmu_imp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/pmu_imp.h
${CMAKE_CURRENT_SOURCE_DIR}/pmu.h
)
if(UNIX)
target_sources(${L0_STATIC_LIB_NAME}
PRIVATE
${L0_SRCS_TOOLS_SYSMAN_LINUX_PMU}
)
endif()
# Make our source files visible to parent
set_property(GLOBAL PROPERTY L0_SRCS_TOOLS_SYSMAN_PMU_LINUX ${L0_SRCS_TOOLS_SYSMAN_PMU_LINUX})

View File

@@ -0,0 +1,21 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <cstdint>
namespace L0 {
class LinuxSysmanImp;
class PmuInterface {
public:
virtual ~PmuInterface() = default;
virtual int64_t pmuInterfaceOpen(uint64_t config, int group, uint64_t format) = 0;
virtual int pmuReadSingle(int fd, uint64_t *data, ssize_t sizeOfdata) = 0;
static PmuInterface *create(LinuxSysmanImp *pLinuxSysmanImp);
};
} // namespace L0

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/tools/source/sysman/linux/pmu/pmu_imp.h"
namespace L0 {
const std::string PmuInterfaceImp::deviceDir("device");
const std::string PmuInterfaceImp::sysDevicesDir("/sys/devices/");
static constexpr int64_t perfEventOpenSyscallNumber = 298;
// Get event id
uint32_t PmuInterfaceImp::getEventType() {
std::string i915DirName("i915");
bool isLmemSupported = pDevice->getDriverHandle()->getMemoryManager()->isLocalMemorySupported(pDevice->getRootDeviceIndex());
if (isLmemSupported) {
std::string bdfDir;
// ID or type of Pmu driver for discrete graphics is obtained by reading sysfs node as explained below:
// For instance DG1 in PCI slot 0000:03:00.0:
// $ cat /sys/devices/i915_0000_03_00.0/type
// 23
ze_result_t result = pSysfsAccess->readSymLink(deviceDir, bdfDir);
if (ZE_RESULT_SUCCESS != result) {
return 0;
}
const auto loc = bdfDir.find_last_of('/');
auto bdf = bdfDir.substr(loc + 1);
std::replace(bdf.begin(), bdf.end(), ':', '_');
i915DirName = "i915_" + bdf;
}
// For integrated graphics type of PMU driver is obtained by reading /sys/devices/i915/type node
// # cat /sys/devices/i915/type
// 18
const std::string eventTypeSysfsNode = sysDevicesDir + i915DirName + "/" + "type";
auto eventTypeVal = 0u;
if (ZE_RESULT_SUCCESS != pFsAccess->read(eventTypeSysfsNode, eventTypeVal)) {
return 0;
}
return eventTypeVal;
}
inline int64_t PmuInterfaceImp::perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) {
attr->size = sizeof(*attr);
return syscall(perfEventOpenSyscallNumber, attr, pid, cpu, groupFd, flags);
}
int64_t PmuInterfaceImp::pmuInterfaceOpen(uint64_t config, int group, uint64_t format) {
struct perf_event_attr attr = {};
int nrCpus = get_nprocs_conf();
int cpu = 0;
int64_t ret = 0;
attr.type = getEventType();
if (attr.type == 0) {
return -ENOENT;
}
if (group >= 0) {
format &= ~PERF_FORMAT_GROUP;
}
attr.read_format = format;
attr.config = config;
do {
ret = perfEventOpen(&attr, -1, cpu++, group, 0);
} while ((ret < 0 && errno == EINVAL) && (cpu < nrCpus));
return ret;
}
int PmuInterfaceImp::pmuReadSingle(int fd, uint64_t *data, ssize_t sizeOfdata) {
ssize_t len;
len = read(fd, data, sizeOfdata);
if (len != sizeOfdata) {
return -1;
}
return 0;
}
PmuInterfaceImp::PmuInterfaceImp(LinuxSysmanImp *pLinuxSysmanImp) {
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
pFsAccess = &pLinuxSysmanImp->getFsAccess();
pDevice = pLinuxSysmanImp->getDeviceHandle();
}
PmuInterface *PmuInterface::create(LinuxSysmanImp *pLinuxSysmanImp) {
PmuInterfaceImp *pPmuInterfaceImp = new PmuInterfaceImp(pLinuxSysmanImp);
UNRECOVERABLE_IF(nullptr == pPmuInterfaceImp);
return pPmuInterfaceImp;
}
} // namespace L0

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/tools/source/sysman/linux/os_sysman_imp.h"
#include "level_zero/tools/source/sysman/linux/pmu/pmu.h"
#include <linux/perf_event.h>
#include <string>
#include <sys/sysinfo.h>
namespace L0 {
class PmuInterfaceImp : public PmuInterface, NEO::NonCopyableOrMovableClass {
public:
PmuInterfaceImp() = delete;
PmuInterfaceImp(LinuxSysmanImp *pLinuxSysmanImp);
~PmuInterfaceImp() override = default;
int64_t pmuInterfaceOpen(uint64_t config, int group, uint64_t format) override;
MOCKABLE_VIRTUAL int pmuReadSingle(int fd, uint64_t *data, ssize_t sizeOfdata) override;
protected:
MOCKABLE_VIRTUAL int64_t perfEventOpen(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags);
private:
uint32_t getEventType();
FsAccess *pFsAccess = nullptr;
SysfsAccess *pSysfsAccess = nullptr;
Device *pDevice = nullptr;
static const std::string deviceDir;
static const std::string sysDevicesDir;
};
} // namespace L0

View File

@@ -9,7 +9,9 @@
#include "shared/source/os_interface/linux/engine_info_impl.h"
#include "level_zero/core/test/unit_tests/mock.h"
#include "level_zero/core/test/unit_tests/mocks/mock_memory_manager.h"
#include "level_zero/tools/source/sysman/engine/linux/os_engine_imp.h"
#include "level_zero/tools/source/sysman/linux/pmu/pmu_imp.h"
#include "sysman/engine/engine_imp.h"
#include "sysman/linux/os_sysman_imp.h"
@@ -17,7 +19,14 @@
using namespace NEO;
namespace L0 {
namespace ult {
constexpr int64_t mockPmuFd = 10;
constexpr uint64_t mockTimestamp = 87654321;
constexpr uint64_t mockActiveTime = 987654321;
const uint32_t microSecondsToNanoSeconds = 1000u;
const std::string deviceDir("device");
struct MockMemoryManagerInEngineSysman : public MemoryManagerMock {
MockMemoryManagerInEngineSysman(NEO::ExecutionEnvironment &executionEnvironment) : MemoryManagerMock(const_cast<NEO::ExecutionEnvironment &>(executionEnvironment)) {}
};
class EngineNeoDrm : public Drm {
public:
using Drm::engineInfo;
@@ -29,7 +38,7 @@ struct Mock<EngineNeoDrm> : public EngineNeoDrm {
Mock<EngineNeoDrm>(RootDeviceEnvironment &rootDeviceEnvironment) : EngineNeoDrm(rootDeviceEnvironment) {}
bool queryEngineInfoMockPositiveTest() {
drm_i915_engine_info i915engineInfo[4] = {};
drm_i915_engine_info i915engineInfo[5] = {};
i915engineInfo[0].engine.engine_class = I915_ENGINE_CLASS_RENDER;
i915engineInfo[0].engine.engine_instance = 0;
i915engineInfo[1].engine.engine_class = I915_ENGINE_CLASS_VIDEO;
@@ -38,8 +47,10 @@ struct Mock<EngineNeoDrm> : public EngineNeoDrm {
i915engineInfo[2].engine.engine_instance = 1;
i915engineInfo[3].engine.engine_class = I915_ENGINE_CLASS_COPY;
i915engineInfo[3].engine.engine_instance = 0;
i915engineInfo[4].engine.engine_class = I915_ENGINE_CLASS_VIDEO_ENHANCE;
i915engineInfo[4].engine.engine_instance = 0;
this->engineInfo.reset(new EngineInfoImpl(i915engineInfo, 4));
this->engineInfo.reset(new EngineInfoImpl(i915engineInfo, 5));
return true;
}
@@ -50,5 +61,65 @@ struct Mock<EngineNeoDrm> : public EngineNeoDrm {
MOCK_METHOD(bool, queryEngineInfo, (), (override));
};
class MockPmuInterfaceImp : public PmuInterfaceImp {
public:
using PmuInterfaceImp::perfEventOpen;
MockPmuInterfaceImp(LinuxSysmanImp *pLinuxSysmanImp) : PmuInterfaceImp(pLinuxSysmanImp) {}
};
template <>
struct Mock<MockPmuInterfaceImp> : public MockPmuInterfaceImp {
Mock<MockPmuInterfaceImp>(LinuxSysmanImp *pLinuxSysmanImp) : MockPmuInterfaceImp(pLinuxSysmanImp) {}
int64_t mockedPerfEventOpenAndSuccessReturn(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) {
return mockPmuFd;
}
int64_t mockedPerfEventOpenAndFailureReturn(perf_event_attr *attr, pid_t pid, int cpu, int groupFd, uint64_t flags) {
return -1;
}
int mockedPmuReadSingleAndSuccessReturn(int fd, uint64_t *data, ssize_t sizeOfdata) {
data[0] = mockActiveTime;
data[1] = mockTimestamp;
return 0;
}
int mockedPmuReadSingleAndFailureReturn(int fd, uint64_t *data, ssize_t sizeOfdata) {
return -1;
}
MOCK_METHOD(int64_t, perfEventOpen, (perf_event_attr * attr, pid_t pid, int cpu, int groupFd, uint64_t flags), (override));
MOCK_METHOD(int, pmuReadSingle, (int fd, uint64_t *data, ssize_t sizeOfdata), (override));
};
class EngineSysfsAccess : public SysfsAccess {};
class EngineFsAccess : public FsAccess {};
template <>
struct Mock<EngineFsAccess> : public EngineFsAccess {
MOCK_METHOD(ze_result_t, read, (const std::string file, uint32_t &val), (override));
ze_result_t readValSuccess(const std::string file, uint32_t &val) {
val = 23;
return ZE_RESULT_SUCCESS;
}
ze_result_t readValFailure(const std::string file, uint32_t &val) {
val = 0;
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
};
template <>
struct Mock<EngineSysfsAccess> : public EngineSysfsAccess {
MOCK_METHOD(ze_result_t, readSymLink, (const std::string file, std::string &buf), (override));
ze_result_t getValStringSymLinkSuccess(const std::string file, std::string &val) {
if (file.compare(deviceDir) == 0) {
val = "/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/0000:02:01.0/0000:03:00.0";
return ZE_RESULT_SUCCESS;
}
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
ze_result_t getValStringSymLinkFailure(const std::string file, std::string &val) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
Mock<EngineSysfsAccess>() = default;
};
} // namespace ult
} // namespace L0

View File

@@ -17,31 +17,65 @@ namespace ult {
constexpr uint32_t handleComponentCount = 4u;
class ZesEngineFixture : public SysmanDeviceFixture {
protected:
Mock<EngineNeoDrm> *pDrm = nullptr;
std::unique_ptr<Mock<EngineNeoDrm>> pDrm;
std::unique_ptr<Mock<MockPmuInterfaceImp>> pPmuInterface;
Drm *pOriginalDrm = nullptr;
PmuInterface *pOriginalPmuInterface = nullptr;
MemoryManager *pMemoryManagerOriginal = nullptr;
std::unique_ptr<MockMemoryManagerInEngineSysman> pMemoryManager;
std::unique_ptr<Mock<EngineSysfsAccess>> pSysfsAccess;
SysfsAccess *pSysfsAccessOriginal = nullptr;
std::unique_ptr<Mock<EngineFsAccess>> pFsAccess;
FsAccess *pFsAccessOriginal = nullptr;
void SetUp() override {
SysmanDeviceFixture::SetUp();
pMemoryManagerOriginal = device->getDriverHandle()->getMemoryManager();
pMemoryManager = std::make_unique<::testing::NiceMock<MockMemoryManagerInEngineSysman>>(*neoDevice->getExecutionEnvironment());
pMemoryManager->localMemorySupported[0] = false;
device->getDriverHandle()->setMemoryManager(pMemoryManager.get());
pSysfsAccessOriginal = pLinuxSysmanImp->pSysfsAccess;
pSysfsAccess = std::make_unique<NiceMock<Mock<EngineSysfsAccess>>>();
pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
pFsAccessOriginal = pLinuxSysmanImp->pFsAccess;
pFsAccess = std::make_unique<NiceMock<Mock<EngineFsAccess>>>();
pLinuxSysmanImp->pFsAccess = pFsAccess.get();
EngineHandleContext *pEngineHandleContext = pSysmanDeviceImp->pEngineHandleContext;
pDrm = new NiceMock<Mock<EngineNeoDrm>>(const_cast<NEO::RootDeviceEnvironment &>(neoDevice->getRootDeviceEnvironment()));
pDrm = std::make_unique<NiceMock<Mock<EngineNeoDrm>>>(const_cast<NEO::RootDeviceEnvironment &>(neoDevice->getRootDeviceEnvironment()));
pPmuInterface = std::make_unique<NiceMock<Mock<MockPmuInterfaceImp>>>(pLinuxSysmanImp);
pOriginalDrm = pLinuxSysmanImp->pDrm;
pLinuxSysmanImp->pDrm = pDrm;
ON_CALL(*pDrm, queryEngineInfo())
.WillByDefault(::testing::Invoke(pDrm, &Mock<EngineNeoDrm>::queryEngineInfoMockPositiveTest));
pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface;
pLinuxSysmanImp->pDrm = pDrm.get();
pLinuxSysmanImp->pPmuInterface = pPmuInterface.get();
ON_CALL(*pDrm.get(), queryEngineInfo())
.WillByDefault(::testing::Invoke(pDrm.get(), &Mock<EngineNeoDrm>::queryEngineInfoMockPositiveTest));
ON_CALL(*pPmuInterface.get(), perfEventOpen(_, _, _, _, _))
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImp>::mockedPerfEventOpenAndSuccessReturn));
ON_CALL(*pPmuInterface.get(), pmuReadSingle(_, _, _))
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImp>::mockedPmuReadSingleAndSuccessReturn));
ON_CALL(*pSysfsAccess.get(), readSymLink(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<EngineSysfsAccess>::getValStringSymLinkSuccess));
ON_CALL(*pFsAccess.get(), read(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EngineFsAccess>::readValSuccess));
pEngineHandleContext->init();
}
void TearDown() override {
SysmanDeviceFixture::TearDown();
device->getDriverHandle()->setMemoryManager(pMemoryManagerOriginal);
pLinuxSysmanImp->pDrm = pOriginalDrm;
if (pDrm != nullptr) {
delete pDrm;
pDrm = nullptr;
}
pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface;
pLinuxSysmanImp->pSysfsAccess = pSysfsAccessOriginal;
pLinuxSysmanImp->pFsAccess = pFsAccessOriginal;
}
std::vector<zes_engine_handle_t> get_engine_handles(uint32_t count) {
std::vector<zes_engine_handle_t> getEngineHandles(uint32_t count) {
std::vector<zes_engine_handle_t> handles(count, nullptr);
EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS);
return handles;
@@ -65,7 +99,7 @@ TEST_F(ZesEngineFixture, GivenComponentCountZeroWhenCallingzesDeviceEnumEngineGr
TEST_F(ZesEngineFixture, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenVerifyCallSucceeds) {
zes_engine_properties_t properties;
auto handle = get_engine_handles(handleComponentCount);
auto handle = getEngineHandles(handleComponentCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[0], &properties));
EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_SINGLE, properties.type);
@@ -84,15 +118,86 @@ TEST_F(ZesEngineFixture, GivenValidEngineHandlesWhenCallingZesEngineGetPropertie
EXPECT_FALSE(properties.onSubdevice);
}
TEST_F(ZesEngineFixture, GivenValidEngineHandleWhenCallingZesEngineGetActivityThenVerifyCallReturnsUnsupportedErrorStatus) {
zes_engine_stats_t Stats;
auto handle = get_engine_handles(handleComponentCount);
TEST_F(ZesEngineFixture, GivenValidEngineHandleAndIntegratedDeviceWhenCallingZesEngineGetActivityThenVerifyCallReturnsSuccess) {
zes_engine_stats_t stats = {};
auto handles = getEngineHandles(handleComponentCount);
EXPECT_EQ(handleComponentCount, handles.size());
for (uint32_t i = 0; i < handleComponentCount; i++) {
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesEngineGetActivity(handle[i], &Stats));
EXPECT_EQ(0u, Stats.activeTime);
EXPECT_EQ(0u, Stats.timestamp);
for (auto handle : handles) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats));
EXPECT_EQ(mockActiveTime / microSecondsToNanoSeconds, stats.activeTime);
EXPECT_EQ(mockTimestamp / microSecondsToNanoSeconds, stats.timestamp);
}
}
TEST_F(ZesEngineFixture, GivenValidEngineHandleAndDiscreteDeviceWhenCallingZesEngineGetActivityThenVerifyCallReturnsSuccess) {
auto pMemoryManagerTest = std::make_unique<::testing::NiceMock<MockMemoryManagerInEngineSysman>>(*neoDevice->getExecutionEnvironment());
pMemoryManagerTest->localMemorySupported[0] = true;
device->getDriverHandle()->setMemoryManager(pMemoryManagerTest.get());
zes_engine_stats_t stats = {};
auto handles = getEngineHandles(handleComponentCount);
EXPECT_EQ(handleComponentCount, handles.size());
for (auto handle : handles) {
EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats));
EXPECT_EQ(mockActiveTime / microSecondsToNanoSeconds, stats.activeTime);
EXPECT_EQ(mockTimestamp / microSecondsToNanoSeconds, stats.timestamp);
}
}
TEST_F(ZesEngineFixture, GivenTestDiscreteDevicesAndValidEngineHandleWhenCallingZesEngineGetActivityAndPMUGetEventTypeFailsThenVerifyEngineGetActivityReturnsFailure) {
auto pMemoryManagerTest = std::make_unique<::testing::NiceMock<MockMemoryManagerInEngineSysman>>(*neoDevice->getExecutionEnvironment());
pMemoryManagerTest->localMemorySupported[0] = true;
device->getDriverHandle()->setMemoryManager(pMemoryManagerTest.get());
ON_CALL(*pSysfsAccess.get(), readSymLink(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<EngineSysfsAccess>::getValStringSymLinkFailure));
auto pOsEngineTest1 = OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u);
zes_engine_stats_t stats = {};
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest1->getActivity(&stats));
ON_CALL(*pSysfsAccess.get(), readSymLink(_, _))
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<EngineSysfsAccess>::getValStringSymLinkSuccess));
ON_CALL(*pFsAccess.get(), read(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EngineFsAccess>::readValFailure));
auto pOsEngineTest2 = OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest2->getActivity(&stats));
delete pOsEngineTest1;
delete pOsEngineTest2;
}
TEST_F(ZesEngineFixture, GivenTestIntegratedDevicesAndValidEngineHandleWhenCallingZesEngineGetActivityAndPMUGetEventTypeFailsThenVerifyEngineGetActivityReturnsFailure) {
zes_engine_stats_t stats = {};
ON_CALL(*pFsAccess.get(), read(_, _))
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<EngineFsAccess>::readValFailure));
auto pOsEngineTest1 = OsEngine::create(pOsSysman, ZES_ENGINE_GROUP_RENDER_SINGLE, 0u);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsEngineTest1->getActivity(&stats));
delete pOsEngineTest1;
}
TEST_F(ZesEngineFixture, GivenValidEngineHandleWhenCallingZesEngineGetActivityAndPmuReadSingleFailsThenVerifyEngineGetActivityReturnsFailure) {
ON_CALL(*pPmuInterface.get(), pmuReadSingle(_, _, _))
.WillByDefault(::testing::Invoke(pPmuInterface.get(), &Mock<MockPmuInterfaceImp>::mockedPmuReadSingleAndFailureReturn));
zes_engine_stats_t stats = {};
auto handles = getEngineHandles(handleComponentCount);
EXPECT_EQ(handleComponentCount, handles.size());
for (auto handle : handles) {
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesEngineGetActivity(handle, &stats));
}
}
TEST_F(ZesEngineFixture, GivenValidOsSysmanPointerWhenRetrievingEngineTypeAndInstancesAndIfEngineInfoQueryFailsThenErrorIsReturned) {
std::multimap<zes_engine_group_t, uint32_t> engineGroupInstance;
ON_CALL(*pDrm.get(), queryEngineInfo())
.WillByDefault(::testing::Invoke(pDrm.get(), &Mock<EngineNeoDrm>::queryEngineInfoMockReturnFalse));
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, OsEngine::getNumEngineTypeAndInstances(engineGroupInstance, pOsSysman));
}
} // namespace ult
} // namespace L0
} // namespace L0

View File

@@ -34,6 +34,7 @@ class PublicLinuxSysmanImp : public L0::LinuxSysmanImp {
using LinuxSysmanImp::pDrm;
using LinuxSysmanImp::pFsAccess;
using LinuxSysmanImp::pPmt;
using LinuxSysmanImp::pPmuInterface;
using LinuxSysmanImp::pProcfsAccess;
using LinuxSysmanImp::pSysfsAccess;
};

View File

@@ -75,5 +75,15 @@ TEST_F(SysmanDeviceFixture, GivenValidDeviceHandleVerifyThatSameHandleIsRetrieve
EXPECT_EQ(pLinuxSysmanImp->getDeviceHandle(), device);
}
TEST_F(SysmanDeviceFixture, GivenPmuInterfaceHandleWhenCallinggetPmuInterfaceThenCreatedPmuInterfaceHandleWillBeRetrieved) {
if (pLinuxSysmanImp->pPmuInterface != nullptr) {
//delete previously allocated pPmuInterface
delete pLinuxSysmanImp->pPmuInterface;
pLinuxSysmanImp->pPmuInterface = nullptr;
}
pLinuxSysmanImp->pPmuInterface = PmuInterface::create(pLinuxSysmanImp);
EXPECT_EQ(pLinuxSysmanImp->getPmuInterface(), pLinuxSysmanImp->pPmuInterface);
}
} // namespace ult
} // namespace L0