mirror of
https://github.com/brockar/NVML-GPU-Control.git
synced 2026-01-12 07:20:58 -03:00
Adding support for uuid and name targeting (this deprecates -t and --target option)
This commit is contained in:
@@ -352,7 +352,7 @@ WantedBy=multi-user.target
|
||||
|
||||
- [x] Control fan policy
|
||||
|
||||
- [ ] Select GPU by UUID (allows users to control more than 1 GPU individually that shares the same model - e.g. 2 RTXs 4080)
|
||||
- [x] Select GPU by UUID (allows users to control more than 1 GPU individually that shares the same model - e.g. 2 RTXs 4080)
|
||||
|
||||
- [ ] Run at startup with necessary permissions (Windows and Linux) - Windows already works
|
||||
|
||||
|
||||
@@ -49,12 +49,22 @@ def print_GPU_info(gpu_handle):
|
||||
log_helper(f"Fan controller count {pynvml.nvmlDeviceGetNumFans(gpu_handle)}")
|
||||
|
||||
def fan_control(configuration):
|
||||
gpu_handle = get_GPU_handle_by_name(configuration.target_gpu)
|
||||
gpu_handle = get_GPU_handle(configuration.gpu_name, configuration.gpu_uuid)
|
||||
print_GPU_info(gpu_handle)
|
||||
control_and_monitor(gpu_handle, configuration)
|
||||
|
||||
# Search for a GPU and return a handle
|
||||
# This will not work if the user has more than 2 GPUs with the same name/model, use UUID for this case
|
||||
|
||||
def get_GPU_handle(gpu_name, gpu_uuid):
|
||||
|
||||
if gpu_uuid != '':
|
||||
return pynvml.nvmlDeviceGetHandleByUUID(gpu_uuid)
|
||||
|
||||
else:
|
||||
return get_GPU_handle_by_name(gpu_name)
|
||||
|
||||
|
||||
# This will NOT work if the user has more than 2 GPUs with the same name/model, use UUID for this case
|
||||
def get_GPU_handle_by_name(gpu_name):
|
||||
deviceCount = pynvml.nvmlDeviceGetCount()
|
||||
|
||||
@@ -172,7 +182,7 @@ def fan_policy(configuration):
|
||||
|
||||
current_policy = ctypes.c_uint(0)
|
||||
target_fan_policy = configuration.fan_policy
|
||||
gpu_handle = get_GPU_handle_by_name(configuration.target_gpu)
|
||||
gpu_handle = get_GPU_handle(configuration.gpu_name, configuration.gpu_uuid)
|
||||
|
||||
# The library unfortunately still needs pointers
|
||||
pynvml.nvmlDeviceGetFanControlPolicy_v2(gpu_handle, 0, ctypes.byref(current_policy))
|
||||
@@ -219,7 +229,7 @@ def get_power_limit_constraints_watts(gpu_handle):
|
||||
|
||||
|
||||
def print_power_limit_info(configuration):
|
||||
gpu_handle = get_GPU_handle_by_name(configuration.target_gpu)
|
||||
gpu_handle = get_GPU_handle(configuration.gpu_name, configuration.gpu_uuid)
|
||||
|
||||
constraints = get_power_limit_constraints_watts(gpu_handle)
|
||||
current_pl = get_current_power_limit_watts(gpu_handle)
|
||||
@@ -281,7 +291,7 @@ def set_temperature_thresholds(gpu_handle, threshold_type, temperature_C, dry_ru
|
||||
|
||||
def print_thresholds_info(configuration):
|
||||
|
||||
gpu_handle = get_GPU_handle_by_name(configuration.target_gpu)
|
||||
gpu_handle = get_GPU_handle(configuration.gpu_name, configuration.gpu_uuid)
|
||||
|
||||
temperarure_thresholds = get_temperarure_thresholds(gpu_handle)
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ class Configuration:
|
||||
def __init__(self):
|
||||
# This only supports one target gpu, use a process for each GPU (erros become isolated to each other)
|
||||
self.target_gpu = ""
|
||||
self.name = ""
|
||||
self.uuid = ""
|
||||
self.gpu_name = ""
|
||||
self.gpu_uuid = ""
|
||||
self.action = ""
|
||||
self.temp_speed_pair = []
|
||||
self.curve_type = "fixed" # Currently for internal usage only (I want to later add calculation for lines and curves fuctions)
|
||||
@@ -31,6 +31,9 @@ class Configuration:
|
||||
self.time_interval = 1.0 # In seconds
|
||||
self.dry_run = False
|
||||
self.fan_policy = ''
|
||||
self.single_use = False
|
||||
self.acoustic_temp_limit = 0 # The user must set the value
|
||||
self.power_limit = 0 # The user must set the value
|
||||
|
||||
class TempSpeedPair:
|
||||
|
||||
@@ -58,7 +61,12 @@ class TempSpeedPair:
|
||||
# Some sane checks (in case the user makes a bad config by accident)
|
||||
def validate_config(config):
|
||||
|
||||
if config.target_gpu == '':
|
||||
# if config.target_gpu == '':
|
||||
# print("You did not select a target GPU")
|
||||
# raise InvalidConfig("No GPU was selected")
|
||||
|
||||
# At least one of the target setting must be configured
|
||||
if config.gpu_name == '' and config.gpu_uuid == '':
|
||||
print("You did not select a target GPU")
|
||||
raise InvalidConfig("No GPU was selected")
|
||||
|
||||
@@ -73,6 +81,18 @@ def validate_config(config):
|
||||
print("You did not select a fan policy: autmatic or manual")
|
||||
raise InvalidConfig("No fan policy was selected")
|
||||
|
||||
# power-control needs a power limit configuration
|
||||
if config.action == 'power-control':
|
||||
if config.power_limit == 0:
|
||||
print("You did not select a power limit")
|
||||
raise InvalidConfig("No power limit was selected")
|
||||
|
||||
# temp-control needs a power limit configuration
|
||||
if config.action == 'temp-control':
|
||||
if config.acoustic_temp_limit == 0:
|
||||
print("You did not select a temperature limit")
|
||||
raise InvalidConfig("No temperature limit was selected")
|
||||
|
||||
|
||||
def parse_cmd_args(args):
|
||||
|
||||
@@ -107,6 +127,12 @@ def parse_cmd_args(args):
|
||||
elif (action == 'get-thresholds-info'):
|
||||
configuration.action = 'get-thresholds-info'
|
||||
|
||||
elif (action == 'power-control'):
|
||||
configuration.action = 'power-control'
|
||||
|
||||
elif (action == 'temp-control'):
|
||||
configuration.action = 'temp-control'
|
||||
|
||||
else:
|
||||
print(f'Invalid action: {action}')
|
||||
raise InvalidAction("The action passed as argument is incorrect")
|
||||
@@ -118,8 +144,16 @@ def parse_cmd_args(args):
|
||||
|
||||
arg = args[i]
|
||||
|
||||
if (arg == '--target' or arg == '-t'):
|
||||
configuration.target_gpu = args[i+1]
|
||||
# if (arg == '--target' or arg == '-t'):
|
||||
# configuration.target_gpu = args[i+1]
|
||||
# i += 1 # Skip the next iteration
|
||||
|
||||
if (arg == '--name' or arg == '-n'):
|
||||
configuration.gpu_name = args[i+1]
|
||||
i += 1 # Skip the next iteration
|
||||
|
||||
elif (arg == '--uuid' or arg == '-id'):
|
||||
configuration.gpu_uuid = args[i+1]
|
||||
i += 1 # Skip the next iteration
|
||||
|
||||
elif (arg == '--speed-pair' or arg == '-sp'):
|
||||
@@ -168,6 +202,17 @@ def parse_cmd_args(args):
|
||||
elif (arg == '--manual'):
|
||||
configuration.fan_policy = 'manual'
|
||||
|
||||
elif (arg == '--single-use' or arg == '-su'):
|
||||
configuration.single_use = True
|
||||
|
||||
elif (arg == '--acoustic-temp-limit' or arg == '-tl'):
|
||||
configuration.acoustic_temp_limit = int(args[i+1])
|
||||
i += 1 # Skip the next iteration
|
||||
|
||||
elif (arg == '--power-limit' or arg == '-pl'):
|
||||
configuration.power_limit = int(args[i+1])
|
||||
i += 1 # Skip the next iteration
|
||||
|
||||
else:
|
||||
print(f'Invalid option: {arg}')
|
||||
raise InvalidOption('The option given was invalid')
|
||||
|
||||
Reference in New Issue
Block a user