mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-19 06:24:51 +08:00
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:
committed by
sys_ocldev
parent
ef2f9e9299
commit
38ecb25ee6
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
19
level_zero/tools/source/sysman/linux/pmu/CMakeLists.txt
Normal file
19
level_zero/tools/source/sysman/linux/pmu/CMakeLists.txt
Normal 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})
|
||||
21
level_zero/tools/source/sysman/linux/pmu/pmu.h
Normal file
21
level_zero/tools/source/sysman/linux/pmu/pmu.h
Normal 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
|
||||
96
level_zero/tools/source/sysman/linux/pmu/pmu_imp.cpp
Normal file
96
level_zero/tools/source/sysman/linux/pmu/pmu_imp.cpp
Normal 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
|
||||
38
level_zero/tools/source/sysman/linux/pmu/pmu_imp.h
Normal file
38
level_zero/tools/source/sysman/linux/pmu/pmu_imp.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user