From 54885e16f002c9494a39212054901a0c0a04337a Mon Sep 17 00:00:00 2001 From: moosecrap Date: Sun, 2 Feb 2025 23:28:28 -0800 Subject: [PATCH] Added overwrite output mode for things like live monitoring. --- README.md | 3 ++- evga-card.h | 1 + evga-icx.c | 31 ++++++++++++++++++++++++++----- nvidia-sensors.c | 6 ++---- nvidia-sensors.h | 2 +- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 491c7c8..efa97c9 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Access to the `/dev/i2c` device files, which means either: ## Optional features ### NVML support -Add the make flag `USE_NVML=1` and the it will also display the main GPU temperature ("GPU1") as reported by the NVIDIA driver. It will also display the performance cap/clock reason. This requires NVML development files to be installed. +Add the make flag `USE_NVML=1` and the it will also display the main GPU temperature ("GPU1") as reported by the NVIDIA driver. It will also display the performance cap/clock reason. This requires the NVIDIA management library (NVML) to be installed. ## Usage Note that when controlling fans directly through iCX3 they will fall offline from the Nvidia driver and show as 0 RPM until you return them to automatic mode. @@ -46,6 +46,7 @@ Available options: --sensors : Print sensor readings even if setting a fan speed --compact : Print sensor reading in a compact one-line per card format --watch N : Keep printing output every N seconds +--overwrite : Overwrite previously displayed info with --watch and --compact instead of continuously logging ``` ### Examples: diff --git a/evga-card.h b/evga-card.h index 9347457..c4a8fe2 100644 --- a/evga-card.h +++ b/evga-card.h @@ -86,6 +86,7 @@ struct card_info { char *card_name; char *pci_id; + unsigned short pci_device_id; char *i2c_dev_path; int i2c_fd; int product_id; diff --git a/evga-icx.c b/evga-icx.c index 2b12a7d..077186a 100644 --- a/evga-icx.c +++ b/evga-icx.c @@ -25,7 +25,8 @@ static const char helpstring[] = "Available options:\n" "--reset : Reset all fans to their default mode\n" "--sensors : Print sensor readings even if setting a fan speed \n" "--compact : Print sensor reading in a compact one-line per card format\n" - "--watch N : Keep printing output every N seconds\n"; + "--watch N : Keep printing output every N seconds\n" + "--overwrite : Overwrite previously displayed info with --watch and --compact instead of continuously logging\n"; void print_gpu_info(int gpu_num, struct card_info gpus[], int compact); @@ -36,6 +37,7 @@ int main (int argc, char **argv) int print_info = 0; int compact = 0; int gpu_num = -1; /* Card to control */ + int overwrite = 0; unsigned int watch = 0; char *fan_speed[ICX3_MAX_FANS] = {NULL}; @@ -83,6 +85,8 @@ int main (int argc, char **argv) printf(helpstring); return -1; } + } else if (strcmp(argv[i], "--overwrite") == 0) { + overwrite = 1; } else { printf(helpstring); return 0; @@ -98,6 +102,10 @@ int main (int argc, char **argv) } } + /* Don't use overwrite mode unless set to compact (we can't tell how many lines the output will be per GPU) */ + if (overwrite && !compact) + overwrite = 0; + gpu_count = find_evga_gpu_i2cs(gpus, MAX_GPUS); if (gpu_count == -1) { @@ -131,20 +139,35 @@ int main (int argc, char **argv) /* NVML init */ #ifdef USE_NVML - int nvml_ok = init_nvml(); - nvmlDevice_t* device[MAX_GPUS]; + init_nvml(); #endif /* print sensor info */ if (print_info) { do { + printf("\x1b[K"); /* Clear current console line (really just for overwrite mode) */ + if (gpu_num == -1) { + /* No GPU specified on command line, loop over all supported GPUs */ for (int i = 0; i < gpu_count; i++){ + if (i > 0) + printf("\n"); print_gpu_info(i, &gpus[i], compact); } } else if (gpu_num <= gpu_count - 1) { print_gpu_info(gpu_num, &gpus[gpu_num], compact); } + + if (!overwrite) + printf("\n"); /* Print line break at the end for continuous output */ + + if (overwrite && compact) { + printf("\x1b[1G"); /* Move cursor back to column 1 */ + if (gpu_count > 1) + printf("\x1b[%dA", gpu_count-1); /* Move cursor back up to the top of gpu list */ + } + + fflush(stdout); sleep(watch); } while (watch > 0); } @@ -168,7 +191,6 @@ void print_gpu_info(int gpu_num, struct card_info *gpu, int compact) { #ifdef USE_NVML print_nvml_clock_reason(1, gpu); #endif - printf("\n"); } else { /* One line per GPU sensor */ printf("#%d: %s (%s) @ %s\n", gpu_num, gpu->card_name, gpu->i2c_dev_path, gpu->pci_id); @@ -180,7 +202,6 @@ void print_gpu_info(int gpu_num, struct card_info *gpu, int compact) { #ifdef USE_NVML print_nvml_clock_reason(0, gpu); #endif - printf("\n"); } } diff --git a/nvidia-sensors.c b/nvidia-sensors.c index c2d7f2a..b89e7fb 100644 --- a/nvidia-sensors.c +++ b/nvidia-sensors.c @@ -2,14 +2,12 @@ #include "nvidia-sensors.h" -int init_nvml() +void init_nvml() { nvmlReturn_t result; result = nvmlInit_v2(); - if (result != NVML_SUCCESS) { + if (result != NVML_SUCCESS) printf("Could not init NVML: %s\n", nvmlErrorString(result)); - return 0; - } } void print_nvml_temp(int compact, struct card_info *card) diff --git a/nvidia-sensors.h b/nvidia-sensors.h index 8d74a51..e607c5b 100644 --- a/nvidia-sensors.h +++ b/nvidia-sensors.h @@ -21,7 +21,7 @@ static struct clock_reason clock_reason_names[] = {nvmlClocksEventReasonDisplayClockSetting, "DispClk", "Display clock"} }; -int init_nvml(); +void init_nvml(); void print_nvml_temp(int compact, struct card_info *card); void print_nvml_clock_reason(int compact, struct card_info *card); unsigned int get_nvml_temp(struct card_info *card);