1313import argparse
1414import os
1515import sys
16+ import time
1617from ctypes import *
1718
1819# Add the source directory to Python path so we can import pyzes
@@ -912,7 +913,7 @@ def test_memory_modules(device_handle, device_index):
912913
913914
914915def test_power_module (device_handle , device_index ):
915- """Test power domain enumeration, energy counter , and power limit extension operations"""
916+ """Test power domain enumeration, properties, energy-derived power , and power limit extension operations"""
916917 print (f"\n ---- Device { device_index } Power Domains Test ----" )
917918
918919 # Get power domain count
@@ -939,6 +940,33 @@ def test_power_module(device_handle, device_index):
939940 for i in range (power_count .value ):
940941 print_verbose (f"\n Power Domain { i } :" )
941942
943+ default_limit = pz .zes_power_limit_ext_desc_t ()
944+ ext_properties = pz .zes_power_ext_properties_t ()
945+ ext_properties .stype = pz .ZES_STRUCTURE_TYPE_POWER_EXT_PROPERTIES
946+ ext_properties .pNext = None
947+ ext_properties .defaultLimit = pointer (default_limit )
948+
949+ properties = pz .zes_power_properties_t ()
950+ properties .stype = pz .ZES_STRUCTURE_TYPE_POWER_PROPERTIES
951+ properties .pNext = cast (pointer (ext_properties ), c_void_p )
952+
953+ rc = pz .zesPowerGetProperties (power_handles [i ], byref (properties ))
954+ if not check_rc (f"zesPowerGetProperties(power { i } )" , rc ):
955+ continue
956+
957+ print_verbose (" Power Properties:" )
958+ print_verbose (f" On Subdevice: { bool (properties .onSubdevice )} " )
959+ if properties .onSubdevice :
960+ print_verbose (f" Subdevice ID: { properties .subdeviceId } " )
961+ print_verbose (f" Can Control: { bool (properties .canControl )} " )
962+ print_verbose (
963+ f" Energy Threshold Supported: { bool (properties .isEnergyThresholdSupported )} "
964+ )
965+ print_verbose (f" Default Limit: { properties .defaultLimit } " )
966+ print_verbose (f" Min Limit: { properties .minLimit } " )
967+ print_verbose (f" Max Limit: { properties .maxLimit } " )
968+ print_verbose (f" Domain: { get_power_domain_string (ext_properties .domain )} " )
969+
942970 limit_count = c_uint32 (0 )
943971 rc = pz .zesPowerGetLimitsExt (power_handles [i ], byref (limit_count ), None )
944972 if not check_rc (f"zesPowerGetLimitsExt(power { i } , count)" , rc ):
@@ -989,31 +1017,26 @@ def test_power_module(device_handle, device_index):
9891017 )
9901018 print_verbose (f" Limit: { limit_desc .limit } " )
9911019
992- # Test power energy counter
993- energy_counter = pz .zes_power_energy_counter_t ()
994-
995- rc = pz .zesPowerGetEnergyCounter (power_handles [i ], byref (energy_counter ))
996- if not check_rc (f"zesPowerGetEnergyCounter(power { i } )" , rc ):
1020+ energy_counter1 = pz .zes_power_energy_counter_t ()
1021+ rc = pz .zesPowerGetEnergyCounter (power_handles [i ], byref (energy_counter1 ))
1022+ if not check_rc (f"zesPowerGetEnergyCounter(power { i } , first)" , rc ):
9971023 continue
9981024
999- print_verbose (" Energy Counter:" )
1000- print_verbose (f" Energy: { energy_counter .energy } " )
1001- print_verbose (f" Timestamp: { energy_counter .timestamp } microseconds" )
1002-
1003- # Take a second reading after a small delay
1004- import time
1005-
1006- time .sleep (0.01 ) # 10ms delay
1025+ time .sleep (1 )
10071026
10081027 energy_counter2 = pz .zes_power_energy_counter_t ()
1009- ret2 = pz .zesPowerGetEnergyCounter (power_handles [i ], byref (energy_counter2 ))
1010- if ret2 == pz .ZE_RESULT_SUCCESS :
1011- energy_delta = energy_counter2 .energy - energy_counter .energy
1012- time_delta = energy_counter2 .timestamp - energy_counter .timestamp
1013- if time_delta > 0 :
1014- print_verbose (
1015- f" Energy Delta: { energy_delta } over { time_delta } microseconds"
1016- )
1028+ rc = pz .zesPowerGetEnergyCounter (power_handles [i ], byref (energy_counter2 ))
1029+ if not check_rc (f"zesPowerGetEnergyCounter(power { i } , second)" , rc ):
1030+ continue
1031+
1032+ energy_delta = energy_counter2 .energy - energy_counter1 .energy
1033+ time_delta = energy_counter2 .timestamp - energy_counter1 .timestamp
1034+ if time_delta > 0 :
1035+ power_watt = energy_delta / time_delta
1036+ device_scope = "subDevice" if properties .onSubdevice else "rootDevice"
1037+ print_verbose (f" Current Power: { power_watt :.6f} W for { device_scope } " )
1038+ else :
1039+ print_verbose (" Current Power: unavailable due to zero delta time" )
10171040
10181041 if limit_descs is None :
10191042 continue
@@ -1029,9 +1052,7 @@ def test_power_module(device_handle, device_index):
10291052 if not check_rc (f"zesPowerSetLimitsExt(power { i } )" , rc ):
10301053 return False
10311054
1032- print_verbose (
1033- f" Re-applied { set_count .value } power limit descriptor(s) successfully"
1034- )
1055+ print_verbose (f" Set power limit successfully" )
10351056
10361057 return True
10371058
@@ -1100,15 +1121,6 @@ def test_frequency_domains(device_handle, device_index):
11001121 print_verbose (f" Min: { freq_range .min :.1f} MHz" )
11011122 print_verbose (f" Max: { freq_range .max :.1f} MHz" )
11021123
1103- throttle_time = pz .zes_freq_throttle_time_t ()
1104- rc = pz .zesFrequencyGetThrottleTime (freq_handles [i ], byref (throttle_time ))
1105- if not check_rc (f"zesFrequencyGetThrottleTime(frequency { i } )" , rc ):
1106- continue
1107-
1108- print_verbose (" Throttle Time:" )
1109- print_verbose (f" Throttle Time: { throttle_time .throttleTime } " )
1110- print_verbose (f" Timestamp: { throttle_time .timestamp } microseconds" )
1111-
11121124 # Test frequency state
11131125 freq_state = pz .zes_freq_state_t ()
11141126 freq_state .stype = pz .ZES_STRUCTURE_TYPE_FREQ_STATE
0 commit comments