-
Notifications
You must be signed in to change notification settings - Fork 68
(sysman): Enabled multi process power get/set test #264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,13 +6,22 @@ | |||||||||||
| * | ||||||||||||
| */ | ||||||||||||
|
|
||||||||||||
| #include <boost/process.hpp> | ||||||||||||
| #include <boost/filesystem.hpp> | ||||||||||||
| #include <boost/interprocess/shared_memory_object.hpp> | ||||||||||||
| #include <boost/interprocess/mapped_region.hpp> | ||||||||||||
|
|
||||||||||||
| #include "gtest/gtest.h" | ||||||||||||
| #include <thread> | ||||||||||||
| #include "logging/logging.hpp" | ||||||||||||
| #include "utils/utils.hpp" | ||||||||||||
| #include "test_harness/test_harness.hpp" | ||||||||||||
| #include <chrono> | ||||||||||||
|
|
||||||||||||
| namespace lzt = level_zero_tests; | ||||||||||||
| namespace bp = boost::process; | ||||||||||||
| namespace fs = boost::filesystem; | ||||||||||||
| namespace bi = boost::interprocess; | ||||||||||||
|
|
||||||||||||
| #include <level_zero/zes_api.h> | ||||||||||||
|
|
||||||||||||
|
|
@@ -183,6 +192,130 @@ LZT_TEST_F( | |||||||||||
| } | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| struct powerInfo { | ||||||||||||
| uint32_t interval; | ||||||||||||
| uint32_t limit; | ||||||||||||
| bool limitValueLocked; | ||||||||||||
| }; | ||||||||||||
| struct powerDomains { | ||||||||||||
| zes_uuid_t uuid; | ||||||||||||
| std::vector<powerInfo> power_info_list; | ||||||||||||
| }; | ||||||||||||
| LZT_TEST_F( | ||||||||||||
| POWER_TEST, | ||||||||||||
| MultiProcessTestSetValidPowerLimitInParentProcessAndReadInChildProcess) { | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please follow a Given..When..Then.. way of naming a test case? |
||||||||||||
| // run test for all available devices | ||||||||||||
| std::vector<powerDomains> pd(devices.size()); | ||||||||||||
| for (size_t d = 0; d < devices.size(); ++d) { | ||||||||||||
| uint32_t count = 0; | ||||||||||||
| auto p_power_handles = lzt::get_power_handles(devices[d], count); | ||||||||||||
| if (count == 0) { | ||||||||||||
| FAIL() << "No handles found: " | ||||||||||||
| << _ze_result_t(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // loop through all power domains and set the power limit | ||||||||||||
|
|
||||||||||||
| //step 1: i) Preserve initial power limit descriptors for restoration later | ||||||||||||
| // ii) Set the power limit and verify the setting | ||||||||||||
| std::vector<std::vector<zes_power_limit_ext_desc_t>> power_limits_descriptors_initial(p_power_handles.size()); | ||||||||||||
| for (size_t p = 0; p < p_power_handles.size(); ++p) { | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless you're modifying the elements of the vector |
||||||||||||
| EXPECT_NE(nullptr, p_power_handles[p]); | ||||||||||||
|
|
||||||||||||
| uint32_t count_power = 0; | ||||||||||||
| std::vector<zes_power_limit_ext_desc_t> power_limits_descriptors; | ||||||||||||
| auto status = lzt::get_power_limits_ext( | ||||||||||||
| p_power_handles[p], &count_power, | ||||||||||||
| power_limits_descriptors); | ||||||||||||
| if (status == ZE_RESULT_ERROR_UNSUPPORTED_FEATURE) { | ||||||||||||
| continue; | ||||||||||||
| } | ||||||||||||
| EXPECT_ZE_RESULT_SUCCESS(status); | ||||||||||||
| // set power limit | ||||||||||||
| zes_power_limit_ext_desc_t power_peak_set = {}; | ||||||||||||
| for (auto &power_limits_descriptor : power_limits_descriptors) { | ||||||||||||
| power_limits_descriptors_initial[p].push_back(power_limits_descriptor); | ||||||||||||
| if (power_limits_descriptor.level == ZES_POWER_LEVEL_PEAK) { | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason you're implementing this test only for PEAK power limit? |
||||||||||||
| power_peak_set = power_limits_descriptor; | ||||||||||||
| power_peak_set.limit = power_limits_descriptor.limit - 1000; | ||||||||||||
| power_limits_descriptor.limit = power_peak_set.limit; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if (power_peak_set.limitValueLocked == false) { | ||||||||||||
| // store power info into the list for sharing it with child process | ||||||||||||
| powerInfo p_info; | ||||||||||||
| p_info.limit = power_peak_set.limit; | ||||||||||||
| p_info.interval = power_peak_set.interval; | ||||||||||||
| p_info.limitValueLocked = power_peak_set.limitValueLocked; | ||||||||||||
| pd[d].power_info_list.push_back(p_info); | ||||||||||||
|
|
||||||||||||
| status = lzt::set_power_limits_ext(p_power_handles[p], &count_power, | ||||||||||||
| power_limits_descriptors.data()); | ||||||||||||
| if (status == ZE_RESULT_ERROR_UNSUPPORTED_FEATURE) { | ||||||||||||
| continue; | ||||||||||||
| } | ||||||||||||
| EXPECT_ZE_RESULT_SUCCESS(status); | ||||||||||||
|
|
||||||||||||
| // Read power limits to confirm power limit is set | ||||||||||||
| zes_power_limit_ext_desc_t power_peak_get = {}; | ||||||||||||
| std::vector<zes_power_limit_ext_desc_t> power_limits_descriptors_get; | ||||||||||||
| status = lzt::get_power_limits_ext(p_power_handles[p], &count_power, | ||||||||||||
| power_limits_descriptors_get); | ||||||||||||
| if (status == ZE_RESULT_ERROR_UNSUPPORTED_FEATURE) { | ||||||||||||
| continue; | ||||||||||||
| } | ||||||||||||
| EXPECT_ZE_RESULT_SUCCESS(status); | ||||||||||||
| for (const auto &p_power_limits_descriptor_get : | ||||||||||||
| power_limits_descriptors_get) { | ||||||||||||
| if (p_power_limits_descriptor_get.level == ZES_POWER_LEVEL_PEAK) { | ||||||||||||
| power_peak_get = p_power_limits_descriptor_get; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| EXPECT_EQ(power_peak_get.limitValueLocked, power_peak_set.limitValueLocked); | ||||||||||||
| EXPECT_EQ(power_peak_get.interval, power_peak_set.interval); | ||||||||||||
| EXPECT_EQ(power_peak_get.limit, power_peak_set.limit); | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // step 2: Launch child process and share power limits set | ||||||||||||
| // create named shared object and copy all power settings | ||||||||||||
| zes_uuid_t uuid = lzt::get_sysman_device_uuid(devices[d]); | ||||||||||||
|
|
||||||||||||
| bi::shared_memory_object::remove("MultiProcPowerLimitSharedMemory"); | ||||||||||||
| bi::shared_memory_object power_limit_shm(bi::create_only, "MultiProcPowerLimitSharedMemory", bi::read_write); | ||||||||||||
|
||||||||||||
| bi::shared_memory_object power_limit_shm(bi::create_only, "MultiProcPowerLimitSharedMemory", bi::read_write); | |
| bi::shared_memory_object::remove(MULTI_PROC_POWER_LIMIT_SHARED_MEMORY_NAME); | |
| bi::shared_memory_object power_limit_shm(bi::create_only, MULTI_PROC_POWER_LIMIT_SHARED_MEMORY_NAME, bi::read_write); |
Copilot
AI
Aug 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The pointer arithmetic and casting make this line complex and hard to read. Consider using a more explicit approach with offset variables or helper functions.
| std::memcpy(((char*)mapped_region.get_address())+ZES_MAX_UUID_SIZE, pd[d].power_info_list.data(), pd[d].power_info_list.size()*sizeof(powerInfo)); | |
| size_t power_info_offset = ZES_MAX_UUID_SIZE; | |
| std::memcpy(static_cast<char*>(mapped_region.get_address()) + power_info_offset, | |
| pd[d].power_info_list.data(), | |
| pd[d].power_info_list.size() * sizeof(powerInfo)); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,108 @@ | ||||||
| /* | ||||||
| * | ||||||
| * Copyright (C) 2020-2025 Intel Corporation | ||||||
| * | ||||||
| * SPDX-License-Identifier: MIT | ||||||
| * | ||||||
| */ | ||||||
|
|
||||||
| #include <boost/interprocess/shared_memory_object.hpp> | ||||||
| #include <boost/interprocess/mapped_region.hpp> | ||||||
|
|
||||||
| #include "utils/utils.hpp" | ||||||
| #include "test_harness/test_harness.hpp" | ||||||
| #include "logging/logging.hpp" | ||||||
|
|
||||||
| namespace lzt = level_zero_tests; | ||||||
| namespace bp = boost::process; | ||||||
| namespace bi = boost::interprocess; | ||||||
|
|
||||||
| struct powerInfo { | ||||||
|
||||||
| uint32_t interval; | ||||||
| uint32_t limit; | ||||||
| bool limitValueLocked; | ||||||
| }; | ||||||
|
|
||||||
| void GetPowerLimitsSetByParentProcess(uint32_t power_handle_size, bool &test_result) { | ||||||
| //1. read shared object | ||||||
| bi::shared_memory_object power_limit_shm(bi::open_only, "MultiProcPowerLimitSharedMemory", bi::read_only); | ||||||
| bi::mapped_region region(power_limit_shm, bi::read_only); | ||||||
| char* data = static_cast<char*>(region.get_address()); | ||||||
| std::vector<powerInfo> power_limits_set; | ||||||
| power_limits_set.resize(power_handle_size); | ||||||
| zes_uuid_t uuid; | ||||||
| memcpy(uuid.id, data, ZES_MAX_UUID_SIZE); | ||||||
| memcpy(power_limits_set.data(), data+ZES_MAX_UUID_SIZE, power_handle_size*sizeof(powerInfo)); | ||||||
|
|
||||||
| //2. read power limits set for the device | ||||||
| auto driver = lzt::get_default_zes_driver(); | ||||||
| auto dev_count = lzt::get_zes_device_count(driver); | ||||||
| auto devices = lzt::get_zes_devices(dev_count, driver); | ||||||
| for (auto device : devices) { | ||||||
| zes_uuid_t id = lzt::get_sysman_device_uuid(device); | ||||||
| if (lzt::is_uuid_pair_equal(id.id, uuid.id)) { | ||||||
| uint32_t count = 0; | ||||||
| auto p_power_handles = lzt::get_power_handles(device, count); | ||||||
| if (count == 0) { | ||||||
| FAIL() << "No handles found: " | ||||||
| << _ze_result_t(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE); | ||||||
| test_result = false; | ||||||
| } | ||||||
|
|
||||||
| for (size_t p = 0; p < p_power_handles.size(); ++p) { | ||||||
| EXPECT_NE(nullptr, p_power_handles[p]); | ||||||
| uint32_t count_power = 0; | ||||||
| zes_power_limit_ext_desc_t power_peak_get = {}; | ||||||
| std::vector<zes_power_limit_ext_desc_t> power_limits_descriptors; | ||||||
| auto status = lzt::get_power_limits_ext( | ||||||
| p_power_handles[p], &count_power, | ||||||
| power_limits_descriptors); // get power limits for all descriptors | ||||||
| if (status == ZE_RESULT_ERROR_UNSUPPORTED_FEATURE) { | ||||||
| continue; | ||||||
| } | ||||||
| EXPECT_ZE_RESULT_SUCCESS(status); | ||||||
| for (const auto &p_power_limits_descriptor : power_limits_descriptors) { | ||||||
| if (p_power_limits_descriptor.level == ZES_POWER_LEVEL_PEAK) { | ||||||
| power_peak_get = p_power_limits_descriptor; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| EXPECT_EQ(power_peak_get.limitValueLocked, | ||||||
| power_limits_set[p].limitValueLocked); | ||||||
| EXPECT_EQ(power_peak_get.interval, | ||||||
| power_limits_set[p].interval); | ||||||
| EXPECT_EQ(power_peak_get.limit, power_limits_set[p].limit); | ||||||
|
|
||||||
| // Need to notify parent process about failure | ||||||
| if (power_peak_get.limitValueLocked != power_limits_set[p].limitValueLocked || | ||||||
| power_peak_get.interval != power_limits_set[p].interval || | ||||||
| power_peak_get.limit != (power_limits_set[p].limit)) { | ||||||
| test_result = false; | ||||||
| return; | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| int main(int argc, char **argv) { | ||||||
| if (argc != 2) { | ||||||
| LOG_INFO << "Insufficient argument count " <<argc; | ||||||
|
||||||
| LOG_INFO << "Insufficient argument count " <<argc; | |
| LOG_INFO << "Insufficient argument count " << argc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'powerInfo' struct is duplicated between files. Consider defining it in a shared header file to avoid code duplication and ensure consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems valid comment. @Sarbojit2019 Could you please address this?