diff --git a/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.cpp b/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.cpp index 57659dfb39..36e35fdb6d 100644 --- a/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.cpp +++ b/level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.cpp @@ -13,6 +13,7 @@ #include "level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h" #include "level_zero/sysman/source/shared/linux/pmu/sysman_pmu_imp.h" +#include "level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper.h" #include "level_zero/sysman/source/shared/linux/sysman_hw_device_id_linux.h" #include "level_zero/sysman/source/shared/linux/zes_os_sysman_imp.h" #include "level_zero/sysman/source/sysman_const.h" @@ -52,6 +53,7 @@ ze_result_t OsEngine::getNumEngineTypeAndInstances(std::set(pOsSysman); NEO::Drm *pDrm = pLinuxSysmanImp->getDrm(); auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface(); + auto pSysmanProductHelper = pLinuxSysmanImp->getSysmanProductHelper(); bool status = false; { @@ -74,9 +76,9 @@ ze_result_t OsEngine::getNumEngineTypeAndInstances(std::setsecond; engineGroupInstance.insert({l0EngineType, {static_cast(itr->second.engineInstance), gtId}}); - if (pSysmanKmdInterface->isGroupEngineInterfaceAvailable()) { + if (pSysmanKmdInterface->isGroupEngineInterfaceAvailable() || pSysmanProductHelper->isAggregationOfSingleEnginesSupported()) { engineGroupInstance.insert({LinuxEngineImp::getGroupFromEngineType(l0EngineType), {0u, gtId}}); - engineGroupInstance.insert({ZES_ENGINE_GROUP_ALL, {0u, gtId}}); + engineGroupInstance.insert({ZES_ENGINE_GROUP_ALL, {0u, pDrm->getIoctlHelper()->getTileIdFromGtId(gtId)}}); } } } @@ -84,7 +86,15 @@ ze_result_t OsEngine::getNumEngineTypeAndInstances(std::setreadBusynessFromGroupFd(pPmuInterface, fdList[0], pStats); + + auto pSysmanProductHelper = pLinuxSysmanImp->getSysmanProductHelper(); + if (!fdList.empty()) { + return pSysmanKmdInterface->readBusynessFromGroupFd(pPmuInterface, fdList[0], pStats); + } else if (pSysmanProductHelper->isAggregationOfSingleEnginesSupported()) { + return pSysmanProductHelper->getGroupEngineBusynessFromSingleEngines(pLinuxSysmanImp, pStats, engineGroup); + } else { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } } ze_result_t LinuxEngineImp::getProperties(zes_engine_properties_t &properties) { @@ -127,5 +137,122 @@ std::unique_ptr OsEngine::create(OsSysman *pOsSysman, zes_engine_group return pLinuxEngineImp; } +static int32_t getFdList(PmuInterface *const &pPmuInterface, std::vector &engineConfigs, std::vector &fdList) { + + for (auto &engineConfig : engineConfigs) { + int64_t fd = -1; + if (fdList.empty()) { + fd = pPmuInterface->pmuInterfaceOpen(engineConfig, -1, PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP); + if (fd < 0) { + return -1; + } + } else { + fd = pPmuInterface->pmuInterfaceOpen(engineConfig, static_cast(fdList[0]), PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP); + if (fd < 0) { + return -1; + } + } + fdList.push_back(fd); + } + + return 0; +} + +static void closeFds(std::vector &fdList) { + + if (!fdList.empty()) { + for (auto &fd : fdList) { + DEBUG_BREAK_IF(fd < 0); + close(static_cast(fd)); + } + fdList.clear(); + } +} + +void OsEngine::initGroupEngineHandleGroupFd(OsSysman *pOsSysman) { + + LinuxSysmanImp *pLinuxSysmanImp = static_cast(pOsSysman); + auto pSysmanProductHelper = pLinuxSysmanImp->getSysmanProductHelper(); + + if (!pSysmanProductHelper->isAggregationOfSingleEnginesSupported()) { + return; + } + + auto pPmuInterface = pLinuxSysmanImp->getPmuInterface(); + auto pSysmanDeviceImp = pLinuxSysmanImp->getSysmanDeviceImp(); + + std::vector mediaEngineConfigs{}; + std::vector computeEngineConfigs{}; + std::vector copyEngineConfigs{}; + std::vector renderEngineConfigs{}; + std::vector allEnginesConfigs{}; + + for (auto &engine : pSysmanDeviceImp->pEngineHandleContext->handleList) { + + zes_engine_properties_t engineProperties = {}; + engine->engineGetProperties(&engineProperties); + + if (engineProperties.type == ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE || engineProperties.type == ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE || engineProperties.type == ZES_ENGINE_GROUP_MEDIA_ENHANCEMENT_SINGLE) { + mediaEngineConfigs.push_back(engine->configPair.first); + mediaEngineConfigs.push_back(engine->configPair.second); + } else if (engineProperties.type == ZES_ENGINE_GROUP_COMPUTE_SINGLE) { + computeEngineConfigs.push_back(engine->configPair.first); + computeEngineConfigs.push_back(engine->configPair.second); + } else if (engineProperties.type == ZES_ENGINE_GROUP_COPY_SINGLE) { + copyEngineConfigs.push_back(engine->configPair.first); + copyEngineConfigs.push_back(engine->configPair.second); + } else if (engineProperties.type == ZES_ENGINE_GROUP_RENDER_SINGLE) { + renderEngineConfigs.push_back(engine->configPair.first); + renderEngineConfigs.push_back(engine->configPair.second); + } + } + + uint64_t allEngineGroupsSize = mediaEngineConfigs.size() + computeEngineConfigs.size() + copyEngineConfigs.size() + renderEngineConfigs.size(); + allEnginesConfigs.reserve(allEngineGroupsSize); + + allEnginesConfigs.insert(allEnginesConfigs.end(), mediaEngineConfigs.begin(), mediaEngineConfigs.end()); + allEnginesConfigs.insert(allEnginesConfigs.end(), computeEngineConfigs.begin(), computeEngineConfigs.end()); + allEnginesConfigs.insert(allEnginesConfigs.end(), copyEngineConfigs.begin(), copyEngineConfigs.end()); + allEnginesConfigs.insert(allEnginesConfigs.end(), renderEngineConfigs.begin(), renderEngineConfigs.end()); + + std::vector>::iterator it = pSysmanDeviceImp->pEngineHandleContext->handleList.begin(); + while (it != pSysmanDeviceImp->pEngineHandleContext->handleList.end()) { + + int32_t ret = 0; + zes_engine_properties_t engineProperties = {}; + (*it)->engineGetProperties(&engineProperties); + + if (engineProperties.type == ZES_ENGINE_GROUP_MEDIA_ALL) { + ret = getFdList(pPmuInterface, mediaEngineConfigs, (*it)->fdList); + } else if (engineProperties.type == ZES_ENGINE_GROUP_COMPUTE_ALL) { + ret = getFdList(pPmuInterface, computeEngineConfigs, (*it)->fdList); + } else if (engineProperties.type == ZES_ENGINE_GROUP_COPY_ALL) { + ret = getFdList(pPmuInterface, copyEngineConfigs, (*it)->fdList); + } else if (engineProperties.type == ZES_ENGINE_GROUP_RENDER_ALL) { + ret = getFdList(pPmuInterface, renderEngineConfigs, (*it)->fdList); + } else if (engineProperties.type == ZES_ENGINE_GROUP_ALL) { + ret = getFdList(pPmuInterface, allEnginesConfigs, (*it)->fdList); + } + + if (ret < 0) { + closeFds((*it)->fdList); + it = pSysmanDeviceImp->pEngineHandleContext->handleList.erase(it); + } else { + ++it; + } + } + + return; +} + +void OsEngine::closeFdsForGroupEngineHandles(OsSysman *pOsSysman) { + LinuxSysmanImp *pLinuxSysmanImp = static_cast(pOsSysman); + auto pSysmanDeviceImp = pLinuxSysmanImp->getSysmanDeviceImp(); + + for (auto &engine : pSysmanDeviceImp->pEngineHandleContext->handleList) { + closeFds(engine->fdList); + } +} + } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/source/api/engine/sysman_engine.cpp b/level_zero/sysman/source/api/engine/sysman_engine.cpp index 4e7948f4ab..a6699a9339 100644 --- a/level_zero/sysman/source/api/engine/sysman_engine.cpp +++ b/level_zero/sysman/source/api/engine/sysman_engine.cpp @@ -43,9 +43,12 @@ void EngineHandleContext::init(uint32_t subDeviceCount) { const auto isSubDevice = subDeviceCount > 0; createHandle(itr->first, itr->second.first, itr->second.second, isSubDevice); } + + OsEngine::initGroupEngineHandleGroupFd(pOsSysman); } void EngineHandleContext::releaseEngines() { + OsEngine::closeFdsForGroupEngineHandles(pOsSysman); handleList.clear(); } diff --git a/level_zero/sysman/source/api/engine/sysman_engine.h b/level_zero/sysman/source/api/engine/sysman_engine.h index ce568300e5..c846e00a2f 100644 --- a/level_zero/sysman/source/api/engine/sysman_engine.h +++ b/level_zero/sysman/source/api/engine/sysman_engine.h @@ -32,6 +32,7 @@ class Engine : _zes_engine_handle_t { inline zes_engine_handle_t toHandle() { return this; } bool initSuccess = false; std::pair configPair{}; + std::vector fdList{}; }; struct EngineHandleContext { diff --git a/level_zero/sysman/source/api/engine/sysman_os_engine.h b/level_zero/sysman/source/api/engine/sysman_os_engine.h index 342e295a0c..a6d7978e0a 100644 --- a/level_zero/sysman/source/api/engine/sysman_os_engine.h +++ b/level_zero/sysman/source/api/engine/sysman_os_engine.h @@ -26,6 +26,8 @@ class OsEngine { virtual bool isEngineModuleSupported() = 0; static std::unique_ptr create(OsSysman *pOsSysman, zes_engine_group_t engineType, uint32_t engineInstance, uint32_t subDeviceId, ze_bool_t onSubdevice); static ze_result_t getNumEngineTypeAndInstances(std::set> &engineGroupInstance, OsSysman *pOsSysman); + static void initGroupEngineHandleGroupFd(OsSysman *pOsSysman); + static void closeFdsForGroupEngineHandles(OsSysman *pOsSysman); virtual ~OsEngine() = default; }; diff --git a/level_zero/sysman/source/api/engine/windows/sysman_os_engine_imp.cpp b/level_zero/sysman/source/api/engine/windows/sysman_os_engine_imp.cpp index 2df1e8a235..73232bcb22 100644 --- a/level_zero/sysman/source/api/engine/windows/sysman_os_engine_imp.cpp +++ b/level_zero/sysman/source/api/engine/windows/sysman_os_engine_imp.cpp @@ -144,5 +144,13 @@ ze_result_t OsEngine::getNumEngineTypeAndInstances(std::set> *getGuidToKeyOffsetMap() = 0; diff --git a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h index 79ff87f322..e168311e63 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h +++ b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h @@ -75,6 +75,10 @@ class SysmanProductHelperHw : public SysmanProductHelper { ze_result_t getPciProperties(zes_pci_properties_t *pProperties) override; ze_result_t getPciStats(zes_pci_stats_t *pStats, LinuxSysmanImp *pLinuxSysmanImp) override; + // Engine + bool isAggregationOfSingleEnginesSupported() override; + ze_result_t getGroupEngineBusynessFromSingleEngines(LinuxSysmanImp *pLinuxSysmanImp, zes_engine_stats_t *pStats, zes_engine_group_t &engineGroup) override; + ~SysmanProductHelperHw() override = default; const std::map> *getGuidToKeyOffsetMap() override; diff --git a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl index 571025cc7a..352673e930 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl +++ b/level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl @@ -362,5 +362,15 @@ bool SysmanProductHelperHw::isZesInitSupported() { return false; } +template +bool SysmanProductHelperHw::isAggregationOfSingleEnginesSupported() { + return false; +} + +template +ze_result_t SysmanProductHelperHw::getGroupEngineBusynessFromSingleEngines(LinuxSysmanImp *pLinuxSysmanImp, zes_engine_stats_t *pStats, zes_engine_group_t &engineGroup) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/source/shared/linux/product_helper/xe2_hpg_core/bmg/sysman_product_helper_bmg.cpp b/level_zero/sysman/source/shared/linux/product_helper/xe2_hpg_core/bmg/sysman_product_helper_bmg.cpp index 35044db462..6f771110d2 100644 --- a/level_zero/sysman/source/shared/linux/product_helper/xe2_hpg_core/bmg/sysman_product_helper_bmg.cpp +++ b/level_zero/sysman/source/shared/linux/product_helper/xe2_hpg_core/bmg/sysman_product_helper_bmg.cpp @@ -7,6 +7,7 @@ #include "shared/source/os_interface/linux/pmt_util.h" +#include "level_zero/sysman/source/shared/linux/pmu/sysman_pmu.h" #include "level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.h" #include "level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper_hw.inl" @@ -918,6 +919,53 @@ bool SysmanProductHelperHw::isZesInitSupported() { return true; } +template <> +bool SysmanProductHelperHw::isAggregationOfSingleEnginesSupported() { + return true; +} + +template <> +ze_result_t SysmanProductHelperHw::getGroupEngineBusynessFromSingleEngines(LinuxSysmanImp *pLinuxSysmanImp, zes_engine_stats_t *pStats, zes_engine_group_t &engineGroup) { + + auto pSysmanDeviceImp = pLinuxSysmanImp->getSysmanDeviceImp(); + auto pPmuInterface = pLinuxSysmanImp->getPmuInterface(); + std::vector fdList{}; + for (auto &engine : pSysmanDeviceImp->pEngineHandleContext->handleList) { + zes_engine_properties_t engineProperties = {}; + engine->engineGetProperties(&engineProperties); + + if (engineGroup == engineProperties.type) { + fdList = engine->fdList; + break; + } + } + + if (fdList.empty()) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + uint64_t dataCount = fdList.size(); + std::vector readData(dataCount + 2, 0); + + auto ret = pPmuInterface->pmuRead(static_cast(fdList[0]), readData.data(), sizeof(uint64_t) * (dataCount + 2)); + if (ret < 0) { + return ZE_RESULT_ERROR_UNKNOWN; + } + + uint64_t activeTime = 0u; + uint64_t timeStamp = 0u; + + for (uint32_t i = 0u; i < dataCount; i++) { + i % 2 ? timeStamp += (readData[2 + i] ? readData[2 + i] : SysmanDevice::getSysmanTimestamp()) : activeTime += readData[2 + i]; + } + + uint64_t engineCount = fdList.size() / 2; + pStats->activeTime = activeTime / engineCount; + pStats->timestamp = timeStamp / engineCount; + + return ZE_RESULT_SUCCESS; +} + template class SysmanProductHelperHw; } // namespace Sysman diff --git a/level_zero/sysman/source/sysman_const.h b/level_zero/sysman/source/sysman_const.h index 8a39648877..92bf04a3d2 100644 --- a/level_zero/sysman/source/sysman_const.h +++ b/level_zero/sysman/source/sysman_const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -96,5 +96,9 @@ const std::map sysfsEngineMapToLevel0E {"vcs", ZES_ENGINE_TYPE_FLAG_MEDIA}, {"vecs", ZES_ENGINE_TYPE_FLAG_OTHER}}; +inline constexpr bool isGroupEngineHandle(zes_engine_group_t engineGroup) { + return (engineGroup == ZES_ENGINE_GROUP_ALL || engineGroup == ZES_ENGINE_GROUP_MEDIA_ALL || engineGroup == ZES_ENGINE_GROUP_COMPUTE_ALL || engineGroup == ZES_ENGINE_GROUP_RENDER_ALL || engineGroup == ZES_ENGINE_GROUP_COPY_ALL); +} + } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/engine/linux/CMakeLists.txt index 8434fa3fb0..3a3cf4172b 100644 --- a/level_zero/sysman/test/unit_tests/sources/engine/linux/CMakeLists.txt +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/CMakeLists.txt @@ -1,12 +1,11 @@ # -# Copyright (C) 2020-2024 Intel Corporation +# Copyright (C) 2020-2025 Intel Corporation # # SPDX-License-Identifier: MIT # set(L0_TESTS_SYSMAN_ENGINE_LINUX ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt - ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_engine_xe.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_engine_xe.h ${CMAKE_CURRENT_SOURCE_DIR}/test_zes_engine.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_engine.h diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine.cpp b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine.cpp index e0551538b2..76c2bcab3f 100644 --- a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine.cpp +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine.cpp @@ -81,51 +81,6 @@ class ZesEngineFixtureI915 : public ZesEngineFixture { } }; -TEST_F(ZesEngineFixtureI915, GivenComponentCountZeroWhenCallingzesDeviceEnumEngineGroupsThenNonZeroCountIsReturnedAndVerifyCallSucceeds) { - - uint32_t count = 0; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); - EXPECT_EQ(count, handleComponentCount); - - uint32_t testcount = count + 1; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &testcount, NULL)); - EXPECT_EQ(testcount, count); - - count = 0; - std::vector handles(count, nullptr); - EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); - EXPECT_EQ(count, handleComponentCount); -} - -TEST_F(ZesEngineFixtureI915, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenVerifyCallSucceeds) { - zes_engine_properties_t properties; - auto handle = getEngineHandles(handleComponentCount); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[0], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[1], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[2], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[3], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[4], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_COPY_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handle[5], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ENHANCEMENT_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); -} - TEST_F(ZesEngineFixtureI915, GivenValidEngineHandleAndIntegratedDeviceWhenCallingZesEngineGetActivityThenVerifyCallReturnsSuccess) { zes_engine_stats_t stats = {}; auto handles = getEngineHandles(handleComponentCount); diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_prelim.cpp b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_prelim.cpp index 7e2fd7e593..e7524b777f 100644 --- a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_prelim.cpp +++ b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_prelim.cpp @@ -17,7 +17,7 @@ namespace Sysman { namespace ult { constexpr uint32_t handleComponentCount = 13u; -constexpr uint32_t handleCountForMultiDeviceFixture = 7u; + class ZesEngineFixturePrelim : public SysmanDeviceFixture { protected: MockEngineNeoDrmPrelim *pDrm = nullptr; @@ -375,123 +375,6 @@ TEST_F(ZesEngineFixturePrelim, GivenValidEngineHandleAndHandleCountZeroWhenCalli EXPECT_EQ(count, handleComponentCount); } -class ZesEngineMultiFixturePrelim : public SysmanMultiDeviceFixture { - protected: - std::unique_ptr pPmuInterface; - L0::Sysman::PmuInterface *pOriginalPmuInterface = nullptr; - L0::Sysman::SysmanDevice *device = nullptr; - - void SetUp() override { - SysmanMultiDeviceFixture::SetUp(); - VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int { - std::string str = "../../devices/pci0000:37/0000:37:01.0/0000:38:00.0/0000:39:01.0/0000:3a:00.0/drm/renderD128"; - std::memcpy(buf, str.c_str(), str.size()); - return static_cast(str.size()); - }); - - MockEngineNeoDrmPrelim *pDrm = new MockEngineNeoDrmPrelim(const_cast(pSysmanDeviceImp->getRootDeviceEnvironment())); - pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily); - auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface; - osInterface->setDriverModel(std::unique_ptr(pDrm)); - - pLinuxSysmanImp->pSysmanKmdInterface.reset(new SysmanKmdInterfaceI915Prelim(pLinuxSysmanImp->getSysmanProductHelper())); - pLinuxSysmanImp->pSysmanKmdInterface->initFsAccessInterface(*pDrm); - - pPmuInterface = std::make_unique(pLinuxSysmanImp); - pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; - pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); - pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); - - pDrm->mockReadSysmanQueryEngineInfoMultiDevice = true; - - pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); - bool isIntegratedDevice = true; - pLinuxSysmanImp->pSysmanKmdInterface->setSysmanDeviceDirName(isIntegratedDevice); - device = pSysmanDevice; - getEngineHandles(0); - } - - void TearDown() override { - SysmanMultiDeviceFixture::TearDown(); - pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; - } - - std::vector getEngineHandles(uint32_t count) { - - VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { - std::ostringstream oStream; - oStream << 23; - std::string value = oStream.str(); - memcpy(buf, value.data(), count); - return count; - }); - - std::vector handles(count, nullptr); - EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); - return handles; - } -}; - -TEST_F(ZesEngineMultiFixturePrelim, GivenComponentCountZeroWhenCallingzesDeviceEnumEngineGroupsThenNonZeroCountIsReturnedAndVerifyCallSucceeds) { - uint32_t count = 0; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); - EXPECT_EQ(count, handleCountForMultiDeviceFixture); - - uint32_t testcount = count + 1; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &testcount, NULL)); - EXPECT_EQ(testcount, count); - - count = 0; - std::vector handles(count, nullptr); - EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); - EXPECT_EQ(count, handleCountForMultiDeviceFixture); -} - -TEST_F(ZesEngineMultiFixturePrelim, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenVerifyCallSucceeds) { - zes_engine_properties_t properties; - auto handles = getEngineHandles(handleCountForMultiDeviceFixture); - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - } - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[0], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_ALL, properties.type); - EXPECT_TRUE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[1], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_ALL, properties.type); - EXPECT_TRUE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[2], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ALL, properties.type); - EXPECT_TRUE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[3], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_SINGLE, properties.type); - EXPECT_TRUE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[4], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE, properties.type); - EXPECT_TRUE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[5], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE, properties.type); - EXPECT_TRUE(properties.onSubdevice); - - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[6], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_ALL, properties.type); - EXPECT_TRUE(properties.onSubdevice); -} - -TEST_F(ZesEngineMultiFixturePrelim, GivenHandleQueryItemCalledWhenPmuInterfaceOpenFailsThenzesDeviceEnumEngineGroupsSucceedsAndHandleCountIsZero) { - - pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); - pSysmanDeviceImp->pEngineHandleContext->init(pOsSysman->getSubDeviceCount()); - uint32_t count = 0; - uint32_t mockHandleCount = 0u; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); - EXPECT_EQ(count, mockHandleCount); -} - } // namespace ult } // namespace Sysman } // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_xe.cpp b/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_xe.cpp deleted file mode 100644 index d457ad4104..0000000000 --- a/level_zero/sysman/test/unit_tests/sources/engine/linux/test_zes_engine_xe.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2023-2025 Intel Corporation - * - * SPDX-License-Identifier: MIT - * - */ - -#include "shared/source/os_interface/linux/xe/ioctl_helper_xe.h" -#include "shared/test/common/helpers/variable_backup.h" - -#include "level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.h" -#include "level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine_xe.h" -#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" -#include "level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/mock_sysman_kmd_interface_xe.h" -#include "level_zero/sysman/test/unit_tests/sources/shared/linux/mock_pmu_interface.h" - -namespace L0 { -namespace Sysman { -namespace ult { - -constexpr uint32_t mockEngineHandleCount = 4u; - -class ZesEngineFixtureXe : public SysmanDeviceFixture { - protected: - L0::Sysman::SysmanDevice *device = nullptr; - std::unique_ptr pPmuInterface; - L0::Sysman::PmuInterface *pOriginalPmuInterface = nullptr; - MockSysmanKmdInterfaceXe *pSysmanKmdInterface = nullptr; - - void SetUp() override { - SysmanDeviceFixture::SetUp(); - VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int { - std::string str = "../../devices/pci0000:37/0000:37:01.0/0000:38:00.0/0000:39:01.0/0000:3a:00.0/drm/renderD128"; - std::memcpy(buf, str.c_str(), str.size()); - return static_cast(str.size()); - }); - device = pSysmanDevice; - MockNeoDrm *pDrm = new MockNeoDrm(const_cast(pSysmanDeviceImp->getRootDeviceEnvironment())); - pDrm->ioctlHelper = std::make_unique(*pDrm); - auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface; - osInterface->setDriverModel(std::unique_ptr(pDrm)); - - pSysmanKmdInterface = new MockSysmanKmdInterfaceXe(pLinuxSysmanImp->getSysmanProductHelper()); - pLinuxSysmanImp->pSysmanKmdInterface.reset(pSysmanKmdInterface); - pLinuxSysmanImp->pSysmanKmdInterface->initFsAccessInterface(*pDrm); - - pPmuInterface = std::make_unique(pLinuxSysmanImp); - pPmuInterface->mockPmuFd = 10; - pPmuInterface->mockActiveTime = 987654321; - pPmuInterface->mockTimestamp = 87654321; - pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); - pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; - pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); - - pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); - bool isIntegratedDevice = true; - pLinuxSysmanImp->pSysmanKmdInterface->setSysmanDeviceDirName(isIntegratedDevice); - getEngineHandles(0); - } - - void TearDown() override { - pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; - SysmanDeviceFixture::TearDown(); - } - - std::vector getEngineHandles(uint32_t count) { - - VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { - uint32_t mockReadVal = 23; - std::ostringstream oStream; - oStream << mockReadVal; - std::string value = oStream.str(); - memcpy(buf, value.data(), count); - return count; - }); - - std::vector handles(count, nullptr); - EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); - return handles; - } -}; - -TEST_F(ZesEngineFixtureXe, GivenComponentCountZeroWhenCallingZesDeviceEnumEngineGroupsThenCallSucceedsAndValidCountIsReturned) { - - uint32_t count = 0; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); - EXPECT_EQ(count, mockEngineHandleCount); - - uint32_t testcount = count + 1; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &testcount, NULL)); - EXPECT_EQ(testcount, mockEngineHandleCount); - - count = 0; - std::vector handles(count, nullptr); - EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); - EXPECT_EQ(count, mockEngineHandleCount); -} - -TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleWhenFetchingConfigPairThenProperValuesAreReturned) { - auto handles = getEngineHandles(mockEngineHandleCount); - EXPECT_EQ(mockEngineHandleCount, handles.size()); - - for (auto handle : handles) { - L0::Sysman::Engine *pEngine = L0::Sysman::Engine::fromHandle(handle); - EXPECT_EQ(pEngine->configPair.first, pPmuInterface->mockActiveTicksConfig); - EXPECT_EQ(pEngine->configPair.second, pPmuInterface->mockTotalTicksConfig); - } -} - -TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleWhenCallingZesEngineGetActivityThenCallSuccedsAndValidValuesAreReturned) { - - zes_engine_stats_t stats = {}; - auto handles = getEngineHandles(mockEngineHandleCount); - EXPECT_EQ(mockEngineHandleCount, handles.size()); - - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats)); - EXPECT_EQ(stats.activeTime, pPmuInterface->mockActiveTime); - EXPECT_EQ(stats.timestamp, pPmuInterface->mockTimestamp); - } -} - -TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleAndPmuTimeStampIsZeroWhenCallingZesEngineGetActivityThenValidTimeStampIsReturned) { - zes_engine_stats_t stats = {}; - pPmuInterface->mockTimestamp = 0u; - auto handles = getEngineHandles(mockEngineHandleCount); - EXPECT_EQ(mockEngineHandleCount, handles.size()); - - std::chrono::time_point ts = std::chrono::steady_clock::now(); - uint64_t timeBeforeApiCall = std::chrono::duration_cast(ts.time_since_epoch()).count(); - - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetActivity(handle, &stats)); - EXPECT_EQ(stats.activeTime, pPmuInterface->mockActiveTime); - EXPECT_GE(stats.timestamp, timeBeforeApiCall); - } -} - -TEST_F(ZesEngineFixtureXe, GivenValidEngineHandleAndPmuReadFailsWhenCallingZesEngineGetActivityThenErrorIsReturned) { - - zes_engine_stats_t stats = {}; - pPmuInterface->mockPmuReadFailureReturnValue = -1; - auto handles = getEngineHandles(mockEngineHandleCount); - EXPECT_EQ(mockEngineHandleCount, handles.size()); - - for (auto handle : handles) { - ASSERT_NE(nullptr, handle); - EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesEngineGetActivity(handle, &stats)); - } -} - -TEST_F(ZesEngineFixtureXe, GivenDeviceHandleAndPmuOpenFailsDueToFileTableOverFlowWhenCallingZesDeviceEnumEngineGroupsThenZeroHandlesReturned) { - - VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { - std::ostringstream oStream; - oStream << 23; - std::string value = oStream.str(); - memcpy(buf, value.data(), count); - return count; - }); - - pPmuInterface->mockPerfEventOpenReadFail = true; - pPmuInterface->mockPerfEventOpenFailAtCount = 3; - pPmuInterface->mockErrorNumber = ENFILE; - pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); - pSysmanDeviceImp->pEngineHandleContext->init(pOsSysman->getSubDeviceCount()); - - uint32_t handleCount = 0; - EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &handleCount, nullptr), ZE_RESULT_SUCCESS); - EXPECT_EQ(handleCount, 0u); -} - -} // namespace ult -} // namespace Sysman -} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_xe.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_xe.cpp index 0e61c8a611..f7f051f083 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_xe.cpp +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/kmd_interface/test_sysman_kmd_interface_xe.cpp @@ -197,11 +197,11 @@ TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceWhenGetEnergyCounterNodeFil EXPECT_EQ(expectedFilePath, pSysmanKmdInterface->getEnergyCounterNodeFile(ZES_POWER_DOMAIN_UNKNOWN)); } -TEST_F(SysmanFixtureDeviceXe, GivenGroupEngineTypeAndSysmanKmdInterfaceWhenCallingGetEngineActivityFdListThenErrorIsReturned) { +TEST_F(SysmanFixtureDeviceXe, Given3DSingleEngineTypeAndSysmanKmdInterfaceWhenCallingGetEngineActivityFdListThenErrorIsReturned) { auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); std::vector> fdList = {}; std::pair configPair = {}; - EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdListAndConfigPair(ZES_ENGINE_GROUP_ALL, 0, 0, pPmuInterface.get(), fdList, configPair), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); + EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdListAndConfigPair(ZES_ENGINE_GROUP_3D_SINGLE, 0, 0, pPmuInterface.get(), fdList, configPair), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); } TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndGettingConfigFromEventFileFailsForEngineActiveTicksWhenCallingGetEngineActivityFdListThenErrorIsReturned) { @@ -242,6 +242,37 @@ TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndGettingConfigAfterFormat EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdListAndConfigPair(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get(), fdList, configPair), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); } +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndPmuInterfaceOpenFailsForBusyTicksHandleWhenCallingGetEngineActivityFdListThenErrorIsReturned) { + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + + std::vector> fdList = {}; + std::pair configPair = {}; + + pPmuInterface->mockPerfEventOpenReadFail = true; + EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdListAndConfigPair(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get(), fdList, configPair), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); +} + +TEST_F(SysmanFixtureDeviceXe, GivenSysmanKmdInterfaceAndPmuInterfaceOpenFailsForTotalTicksHandleWhenCallingGetEngineActivityFdListThenErrorIsReturned) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 23; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + auto pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + + std::vector> fdList = {}; + std::pair configPair = {}; + + pPmuInterface->mockPerfEventOpenReadFail = true; + pPmuInterface->mockPerfEventOpenFailAtCount = 3; + pPmuInterface->mockPmuFd = 10; + EXPECT_EQ(pSysmanKmdInterface->getEngineActivityFdListAndConfigPair(ZES_ENGINE_GROUP_COMPUTE_SINGLE, 0, 0, pPmuInterface.get(), fdList, configPair), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); +} + } // namespace ult } // namespace Sysman } // namespace L0 \ No newline at end of file diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/mock_pmu_interface.h b/level_zero/sysman/test/unit_tests/sources/shared/linux/mock_pmu_interface.h index da17ac01a9..ff3bfd2666 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/mock_pmu_interface.h +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/mock_pmu_interface.h @@ -47,12 +47,17 @@ class MockPmuInterfaceImp : public L0::Sysman::PmuInterfaceImp { } int32_t pmuRead(int fd, uint64_t *data, ssize_t sizeOfdata) override { + if (mockPmuReadFailureReturnValue == -1) { return mockPmuReadFailureReturnValue; } - data[2] = mockActiveTime; - data[3] = mockTimestamp; + uint64_t dataCount = sizeOfdata / sizeof(uint64_t); + + for (uint32_t i = 2; i < dataCount; i++) { + i % 2 ? data[i] = mockTimestamp : data[i] = mockActiveTime; + } + return 0; } diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/CMakeLists.txt index 176133c100..0a32cfd540 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/CMakeLists.txt +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/CMakeLists.txt @@ -18,6 +18,7 @@ if(UNIX) ${CMAKE_CURRENT_SOURCE_DIR}/sysman_product_helper_device_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sysman_product_helper_pci_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sysman_product_helper_init_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_product_helper_engine_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sysman_product_helper_engine_tests_xe.cpp ) endif() diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_engine_tests.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_engine_tests.cpp new file mode 100644 index 0000000000..69e64d8c2d --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_engine_tests.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/common/libult/linux/drm_mock.h" + +#include "level_zero/sysman/source/shared/linux/kmd_interface/sysman_kmd_interface.h" +#include "level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper.h" +#include "level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine_prelim.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" +#include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_hw_device_id.h" + +namespace L0 { +namespace Sysman { +namespace ult { + +constexpr uint32_t handleCountForMultiDeviceFixture = 7u; + +class SysmanProductHelperEngineTestsFixture : public SysmanMultiDeviceFixture { + protected: + std::unique_ptr pPmuInterface; + L0::Sysman::PmuInterface *pOriginalPmuInterface = nullptr; + L0::Sysman::SysmanDevice *device = nullptr; + + void SetUp() override { + SysmanMultiDeviceFixture::SetUp(); + VariableBackup mockReadLink(&NEO::SysCalls::sysCallsReadlink, [](const char *path, char *buf, size_t bufsize) -> int { + std::string str = "../../devices/pci0000:37/0000:37:01.0/0000:38:00.0/0000:39:01.0/0000:3a:00.0/drm/renderD128"; + std::memcpy(buf, str.c_str(), str.size()); + return static_cast(str.size()); + }); + + MockEngineNeoDrmPrelim *pDrm = new MockEngineNeoDrmPrelim(const_cast(pSysmanDeviceImp->getRootDeviceEnvironment())); + pDrm->setupIoctlHelper(pSysmanDeviceImp->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily); + auto &osInterface = pSysmanDeviceImp->getRootDeviceEnvironment().osInterface; + osInterface->setDriverModel(std::unique_ptr(pDrm)); + + pLinuxSysmanImp->pSysmanKmdInterface.reset(new SysmanKmdInterfaceI915Prelim(pLinuxSysmanImp->getSysmanProductHelper())); + pLinuxSysmanImp->pSysmanKmdInterface->initFsAccessInterface(*pDrm); + + pPmuInterface = std::make_unique(pLinuxSysmanImp); + pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; + pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); + pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); + + pDrm->mockReadSysmanQueryEngineInfoMultiDevice = true; + + pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); + bool isIntegratedDevice = true; + pLinuxSysmanImp->pSysmanKmdInterface->setSysmanDeviceDirName(isIntegratedDevice); + device = pSysmanDevice; + getEngineHandles(0); + } + + void TearDown() override { + SysmanMultiDeviceFixture::TearDown(); + pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; + } + + std::vector getEngineHandles(uint32_t count) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + std::ostringstream oStream; + oStream << 23; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + return handles; + } +}; + +HWTEST2_F(SysmanProductHelperEngineTestsFixture, GivenComponentCountZeroWhenCallingZesDeviceEnumEngineGroupsThenSuccessAndNonZeroCountIsReturned, IsPVC) { + uint32_t count = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); + EXPECT_EQ(count, handleCountForMultiDeviceFixture); + + uint32_t testcount = count + 1; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &testcount, NULL)); + EXPECT_EQ(testcount, count); + + count = 0; + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, handleCountForMultiDeviceFixture); +} + +HWTEST2_F(SysmanProductHelperEngineTestsFixture, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenSuccessIsReturned, IsPVC) { + zes_engine_properties_t properties; + auto handles = getEngineHandles(handleCountForMultiDeviceFixture); + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + } + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[0], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_ALL, properties.type); + EXPECT_TRUE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[1], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_ALL, properties.type); + EXPECT_TRUE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[2], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ALL, properties.type); + EXPECT_TRUE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[3], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_SINGLE, properties.type); + EXPECT_TRUE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[4], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_DECODE_SINGLE, properties.type); + EXPECT_TRUE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[5], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ENCODE_SINGLE, properties.type); + EXPECT_TRUE(properties.onSubdevice); + + EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[6], &properties)); + EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_ALL, properties.type); + EXPECT_TRUE(properties.onSubdevice); +} + +HWTEST2_F(SysmanProductHelperEngineTestsFixture, GivenHandleQueryItemCalledAndPmuInterfaceOpenFailsWhenCallingZesDeviceEnumEngineGroupsThenSuccessAndZeroHandleCountIsReturned, IsPVC) { + + pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); + pSysmanDeviceImp->pEngineHandleContext->init(pOsSysman->getSubDeviceCount()); + uint32_t count = 0; + uint32_t mockHandleCount = 0u; + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, mockHandleCount); +} + +HWTEST2_F(SysmanProductHelperEngineTestsFixture, GivenValidEngineHandleWith3DSingleGroupEngineWhenCallingEngineGetActivityThenErrorIsReturned, IsPVC) { + zes_engine_group_t engineType = ZES_ENGINE_GROUP_3D_SINGLE; + zes_engine_stats_t stats = {}; + + auto pLinuxEngineImp = std::make_unique(pOsSysman, engineType, 0, 0, 0); + EXPECT_EQ(pLinuxEngineImp->getActivity(&stats), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); +} + +HWTEST2_F(SysmanProductHelperEngineTestsFixture, GivenSysmanProductHelperHandleWhenCheckingIsAggregationOfSingleEnginesSupportedThenFailureIsReturned, IsPVC) { + auto pSysmanProductHelper = L0::Sysman::SysmanProductHelper::create(defaultHwInfo->platform.eProductFamily); + EXPECT_FALSE(pSysmanProductHelper->isAggregationOfSingleEnginesSupported()); +} + +HWTEST2_F(SysmanProductHelperEngineTestsFixture, GivenSysmanProductHelperHandleWhenCallingGetGroupEngineBusynessFromSingleEnginesThenErrorIsReturned, IsPVC) { + auto pSysmanProductHelper = L0::Sysman::SysmanProductHelper::create(defaultHwInfo->platform.eProductFamily); + zes_engine_group_t engineType = ZES_ENGINE_GROUP_3D_SINGLE; + zes_engine_stats_t stats = {}; + EXPECT_EQ(pSysmanProductHelper->getGroupEngineBusynessFromSingleEngines(pLinuxSysmanImp, &stats, engineType), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); +} + +} // namespace ult +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_engine_tests_xe.cpp b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_engine_tests_xe.cpp index 5b757e37a4..f9909e4142 100644 --- a/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_engine_tests_xe.cpp +++ b/level_zero/sysman/test/unit_tests/sources/shared/linux/product_helper/sysman_product_helper_engine_tests_xe.cpp @@ -9,6 +9,7 @@ #include "shared/test/common/helpers/variable_backup.h" #include "level_zero/sysman/source/api/engine/linux/sysman_os_engine_imp.h" +#include "level_zero/sysman/source/api/engine/sysman_engine_imp.h" #include "level_zero/sysman/source/shared/linux/product_helper/sysman_product_helper.h" #include "level_zero/sysman/test/unit_tests/sources/engine/linux/mock_engine_xe.h" #include "level_zero/sysman/test/unit_tests/sources/linux/mock_sysman_fixture.h" @@ -19,7 +20,7 @@ namespace L0 { namespace Sysman { namespace ult { -constexpr uint32_t mockEngineHandleCount = 4u; +constexpr uint32_t mockEngineHandleCount = 9u; class SysmanProductHelperEngineXeTestFixture : public SysmanDeviceFixture { protected: @@ -47,6 +48,8 @@ class SysmanProductHelperEngineXeTestFixture : public SysmanDeviceFixture { pPmuInterface = std::make_unique(pLinuxSysmanImp); pPmuInterface->mockPmuFd = 10; + pPmuInterface->mockActiveTime = 98765432; + pPmuInterface->mockTimestamp = 8765432; pPmuInterface->pSysmanKmdInterface = pLinuxSysmanImp->pSysmanKmdInterface.get(); pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface; pLinuxSysmanImp->pPmuInterface = pPmuInterface.get(); @@ -60,9 +63,25 @@ class SysmanProductHelperEngineXeTestFixture : public SysmanDeviceFixture { pLinuxSysmanImp->pPmuInterface = pOriginalPmuInterface; SysmanDeviceFixture::TearDown(); } + + std::vector getEngineHandles(uint32_t count) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint32_t mockReadVal = 23; + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + return handles; + } }; -HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenValidEngineHandlesWhenCallingZesEngineGetPropertiesThenSuccessIsReturned, IsBMG) { +HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenComponentCountZeroWhenCallingZesDeviceEnumEngineGroupsThenCallSucceedsAndValidCountIsReturned, IsBMG) { VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { uint32_t mockReadVal = 23; @@ -73,35 +92,129 @@ HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenValidEngineHandlesWhenCal return count; }); - uint32_t count = 0u; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, nullptr)); + uint32_t count = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); EXPECT_EQ(count, mockEngineHandleCount); + + uint32_t testcount = count + 1; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &testcount, NULL)); + EXPECT_EQ(testcount, mockEngineHandleCount); + + count = 0; std::vector handles(count, nullptr); - EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data())); + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + EXPECT_EQ(count, mockEngineHandleCount); +} + +HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenValidEngineHandleWhenFetchingConfigPairThenProperValuesAreReturned, IsBMG) { + auto handles = getEngineHandles(mockEngineHandleCount); + EXPECT_EQ(mockEngineHandleCount, handles.size()); + + for (auto handle : handles) { + + zes_engine_properties_t properties = {}; + EXPECT_EQ(zesEngineGetProperties(handle, &properties), ZE_RESULT_SUCCESS); + + if (!isGroupEngineHandle(properties.type)) { + L0::Sysman::Engine *pEngine = L0::Sysman::Engine::fromHandle(handle); + EXPECT_EQ(pEngine->configPair.first, pPmuInterface->mockActiveTicksConfig); + EXPECT_EQ(pEngine->configPair.second, pPmuInterface->mockTotalTicksConfig); + } + } +} + +HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenValidEngineHandleWhenCallingZesEngineGetActivityThenCallSuccedsAndValidValuesAreReturned, IsBMG) { + + zes_engine_stats_t stats = {}; + auto handles = getEngineHandles(mockEngineHandleCount); + EXPECT_EQ(mockEngineHandleCount, handles.size()); + for (auto handle : handles) { ASSERT_NE(nullptr, handle); + EXPECT_EQ(zesEngineGetActivity(handle, &stats), ZE_RESULT_SUCCESS); + EXPECT_EQ(stats.activeTime, pPmuInterface->mockActiveTime); + EXPECT_EQ(stats.timestamp, pPmuInterface->mockTimestamp); } +} - zes_engine_properties_t properties = {}; - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[0], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_COMPUTE_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - EXPECT_EQ(properties.subdeviceId, 0u); +HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenValidEngineHandleAndPmuTimeStampIsZeroWhenCallingZesEngineGetActivityThenValidTimeStampIsReturned, IsBMG) { + zes_engine_stats_t stats = {}; + pPmuInterface->mockTimestamp = 0u; + auto handles = getEngineHandles(mockEngineHandleCount); + EXPECT_EQ(mockEngineHandleCount, handles.size()); - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[1], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_RENDER_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - EXPECT_EQ(properties.subdeviceId, 0u); + std::chrono::time_point ts = std::chrono::steady_clock::now(); + uint64_t timeBeforeApiCall = std::chrono::duration_cast(ts.time_since_epoch()).count(); - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[2], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_COPY_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - EXPECT_EQ(properties.subdeviceId, 0u); + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + EXPECT_EQ(zesEngineGetActivity(handle, &stats), ZE_RESULT_SUCCESS); + EXPECT_EQ(stats.activeTime, pPmuInterface->mockActiveTime); + EXPECT_GE(stats.timestamp, timeBeforeApiCall); + } +} - EXPECT_EQ(ZE_RESULT_SUCCESS, zesEngineGetProperties(handles[3], &properties)); - EXPECT_EQ(ZES_ENGINE_GROUP_MEDIA_ENHANCEMENT_SINGLE, properties.type); - EXPECT_FALSE(properties.onSubdevice); - EXPECT_EQ(properties.subdeviceId, 0u); +HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenValidEngineHandleAndPmuReadFailsWhenCallingZesEngineGetActivityThenErrorIsReturned, IsBMG) { + + zes_engine_stats_t stats = {}; + pPmuInterface->mockPmuReadFailureReturnValue = -1; + auto handles = getEngineHandles(mockEngineHandleCount); + EXPECT_EQ(mockEngineHandleCount, handles.size()); + + for (auto handle : handles) { + ASSERT_NE(nullptr, handle); + EXPECT_EQ(zesEngineGetActivity(handle, &stats), ZE_RESULT_ERROR_UNKNOWN); + } +} + +HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenEngineHandleWithGroupAllEngineTypeAndPmuInterfaceOpenFailsWhenCallingZesEngineGetActivityThenErrorIsReturned, IsBMG) { + + VariableBackup mockPread(&NEO::SysCalls::sysCallsPread, [](int fd, void *buf, size_t count, off_t offset) -> ssize_t { + uint32_t mockReadVal = 23; + std::ostringstream oStream; + oStream << mockReadVal; + std::string value = oStream.str(); + memcpy(buf, value.data(), count); + return count; + }); + + pPmuInterface->mockPerfEventOpenReadFail = true; + pPmuInterface->mockPerfEventOpenFailAtCount = 12; + + uint32_t count = 0; + EXPECT_EQ(ZE_RESULT_SUCCESS, zesDeviceEnumEngineGroups(device->toHandle(), &count, NULL)); + + std::vector handles(count, nullptr); + EXPECT_EQ(zesDeviceEnumEngineGroups(device->toHandle(), &count, handles.data()), ZE_RESULT_SUCCESS); + + for (auto handle : handles) { + zes_engine_properties_t properties = {}; + EXPECT_EQ(zesEngineGetProperties(handle, &properties), ZE_RESULT_SUCCESS); + + if (isGroupEngineHandle(properties.type)) { + zes_engine_stats_t stats = {}; + EXPECT_EQ(zesEngineGetActivity(handle, &stats), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); + } + } +} + +HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenSysmanProductHelperHandleWhenCheckingIsAggregationOfSingleEnginesSupportedThenSuccessIsReturned, IsBMG) { + auto pSysmanProductHelper = L0::Sysman::SysmanProductHelper::create(defaultHwInfo->platform.eProductFamily); + EXPECT_TRUE(pSysmanProductHelper->isAggregationOfSingleEnginesSupported()); +} + +HWTEST2_F(SysmanProductHelperEngineXeTestFixture, GivenSysmanProductHelperHandleAndFdListNotAvailableWhenCallingGetGroupEngineBusynessFromSingleEnginesThenErrorIsReturned, IsBMG) { + + zes_engine_group_t engineType = ZES_ENGINE_GROUP_COMPUTE_ALL; + std::unique_ptr pEngine = std::make_unique(pOsSysman, engineType, 0, 0, 0); + + pSysmanDeviceImp->pEngineHandleContext->handleList.clear(); + pSysmanDeviceImp->pEngineHandleContext->handleList.push_back(std::move(pEngine)); + + auto pSysmanProductHelper = L0::Sysman::SysmanProductHelper::create(defaultHwInfo->platform.eProductFamily); + + zes_engine_stats_t stats = {}; + EXPECT_EQ(pSysmanProductHelper->getGroupEngineBusynessFromSingleEngines(pLinuxSysmanImp, &stats, engineType), ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); } } // namespace ult