Rework interface for gpu select option

This commit is contained in:
Maxime Schmitt
2022-10-16 16:46:29 +02:00
parent 1205659afb
commit 71fdefd225
8 changed files with 97 additions and 128 deletions

View File

@@ -14,7 +14,7 @@ struct window_position {
#define MAX_CHARTS 64
void compute_sizes_from_layout(unsigned devices_count, unsigned device_header_rows, unsigned device_header_cols,
unsigned rows, unsigned cols, const plot_info_to_draw *to_draw,
unsigned rows, unsigned cols, const nvtop_interface_gpu_opts *gpu_opts,
process_field_displayed process_field_displayed,
struct window_position *device_positions, unsigned *num_plots,
struct window_position plot_positions[MAX_CHARTS], unsigned *map_device_to_plot,

View File

@@ -27,25 +27,22 @@
#include <stdbool.h>
typedef struct {
plot_info_to_draw to_draw; // The set of metrics to draw for this gpu
} nvtop_interface_gpu_opts;
typedef struct nvtop_interface_option_struct {
bool plot_left_to_right; // true to reverse the plot refresh direction
// defines inactivity (0 use rate) before
// hiding it
bool temperature_in_fahrenheit; // Switch from celsius to fahrenheit
// temperature scale
bool use_color; // Name self explanatory
double encode_decode_hiding_timer; // Negative to always display, positive
plot_info_to_draw
*device_information_drawn; // Stores the information to drawn for each
// GPU (see enum plot_draw_information)
char *config_file_location; // Location of the config file
enum process_field
sort_processes_by; // Specify the field used to order the processes
bool sort_descending_order; // Sort in descenging order
int update_interval; // Interval between interface update in milliseconds
process_field_displayed
process_fields_displayed; // Which columns of the
// process list are displayed
bool plot_left_to_right; // true to reverse the plot refresh direction defines inactivity (0 use rate) before hiding it
bool temperature_in_fahrenheit; // Switch from celsius to fahrenheit temperature scale
bool use_color; // Name self explanatory
double encode_decode_hiding_timer; // Negative to always display, positive
nvtop_interface_gpu_opts *gpu_specific_opts; // GPU specific options
char *config_file_location; // Location of the config file
enum process_field sort_processes_by; // Specify the field used to order the processes
bool sort_descending_order; // Sort in descenging order
int update_interval; // Interval between interface update in milliseconds
process_field_displayed process_fields_displayed; // Which columns of the
// process list are displayed
} nvtop_interface_option;
inline bool plot_isset_draw_info(enum plot_information check_info,

View File

@@ -247,7 +247,7 @@ static void initialize_gpu_mem_plot(struct plot_window *plot, struct window_posi
unsigned column_divisor = 0;
for (unsigned i = 0; i < plot->num_devices_to_plot; ++i) {
unsigned dev_id = plot->devices_ids[i];
plot_info_to_draw to_draw = options->device_information_drawn[dev_id];
plot_info_to_draw to_draw = options->gpu_specific_opts[dev_id].to_draw;
column_divisor += plot_count_draw_info(to_draw);
}
assert(column_divisor > 0);
@@ -369,7 +369,7 @@ static void initialize_all_windows(struct nvtop_interface *dwin) {
struct window_position setup_position;
compute_sizes_from_layout(devices_count, 3, device_length(), rows - 1, cols,
dwin->options.device_information_drawn,
dwin->options.gpu_specific_opts,
dwin->options.process_fields_displayed,
device_positions, &dwin->num_plots, plot_positions,
map_device_to_plot, &process_position,
@@ -471,7 +471,7 @@ struct nvtop_interface *initialize_curses(unsigned devices_count,
void clean_ncurses(struct nvtop_interface *interface) {
endwin();
delete_all_windows(interface);
free(interface->options.device_information_drawn);
free(interface->options.gpu_specific_opts);
free(interface->options.config_file_location);
free(interface->devices_win);
interface_free_ring_buffer(&interface->saved_data_ring);
@@ -1660,8 +1660,7 @@ void save_current_data_to_ring(struct list_head *devices,
unsigned data_index = 0;
for (enum plot_information info = plot_gpu_rate;
info < plot_information_count; ++info) {
if (plot_isset_draw_info(
info, interface->options.device_information_drawn[dev_id])) {
if (plot_isset_draw_info(info, interface->options.gpu_specific_opts[dev_id].to_draw)) {
unsigned data_val = 0;
switch (info) {
case plot_gpu_rate:
@@ -1737,8 +1736,7 @@ static unsigned populate_plot_data_from_ring_buffer(
unsigned total_to_draw = 0;
for (unsigned i = 0; i < plot_win->num_devices_to_plot; ++i) {
unsigned dev_id = plot_win->devices_ids[i];
plot_info_to_draw to_draw =
interface->options.device_information_drawn[dev_id];
plot_info_to_draw to_draw = interface->options.gpu_specific_opts[dev_id].to_draw;
total_to_draw += plot_count_draw_info(to_draw);
}
@@ -1750,11 +1748,9 @@ static unsigned populate_plot_data_from_ring_buffer(
unsigned in_processing = 0;
for (unsigned i = 0; i < plot_win->num_devices_to_plot; ++i) {
unsigned dev_id = plot_win->devices_ids[i];
plot_info_to_draw to_draw =
interface->options.device_information_drawn[dev_id];
plot_info_to_draw to_draw = interface->options.gpu_specific_opts[dev_id].to_draw;
unsigned data_ring_index = 0;
for (enum plot_information info = plot_gpu_rate;
info < plot_information_count; ++info) {
for (enum plot_information info = plot_gpu_rate; info < plot_information_count; ++info) {
if (plot_isset_draw_info(info, to_draw)) {
// Populate the legend
switch (info) {

View File

@@ -71,13 +71,12 @@ static bool move_plot_to_stack(unsigned stack_max_cols, unsigned plot_id,
}
}
static unsigned info_in_plot(unsigned plot_id, unsigned devices_count,
const unsigned map_device_to_plot[devices_count],
const plot_info_to_draw to_draw[devices_count]) {
static unsigned info_in_plot(unsigned plot_id, unsigned devices_count, const unsigned map_device_to_plot[devices_count],
const nvtop_interface_gpu_opts gpuOpts[devices_count]) {
unsigned sum = 0;
for (unsigned dev_id = 0; dev_id < devices_count; ++dev_id) {
if (map_device_to_plot[dev_id] == plot_id)
sum += plot_count_draw_info(to_draw[dev_id]);
sum += plot_count_draw_info(gpuOpts[dev_id].to_draw);
}
assert(sum > 0);
return sum;
@@ -111,7 +110,7 @@ size_differences_between_stacks(unsigned plot_count, unsigned stack_count,
}
static void preliminary_plot_positioning(unsigned rows_for_plots, unsigned plot_total_cols, unsigned devices_count,
const plot_info_to_draw to_draw[devices_count],
const nvtop_interface_gpu_opts gpuOpts[devices_count],
unsigned map_device_to_plot[devices_count],
unsigned plot_in_stack[devices_count], unsigned *num_plots,
unsigned *plot_stack_count) {
@@ -121,7 +120,7 @@ static void preliminary_plot_positioning(unsigned rows_for_plots, unsigned plot_
bool plot_anything = false;
for (unsigned i = 0; i < devices_count; ++i) {
num_info_per_plot[i] = plot_count_draw_info(to_draw[i]);
num_info_per_plot[i] = plot_count_draw_info(gpuOpts[i].to_draw);
map_device_to_plot[i] = i;
if (num_info_per_plot[i])
plot_anything = true;
@@ -244,7 +243,7 @@ static void balance_info_on_stacks_preserving_plot_order(
}
void compute_sizes_from_layout(unsigned devices_count, unsigned device_header_rows, unsigned device_header_cols,
unsigned rows, unsigned cols, const plot_info_to_draw *to_draw,
unsigned rows, unsigned cols, const nvtop_interface_gpu_opts *gpuOpts,
process_field_displayed process_displayed, struct window_position *device_positions,
unsigned *num_plots, struct window_position plot_positions[MAX_CHARTS],
unsigned *map_device_to_plot, struct window_position *process_position,
@@ -278,9 +277,8 @@ void compute_sizes_from_layout(unsigned devices_count, unsigned device_header_ro
unsigned num_plot_stacks = 0;
unsigned plot_in_stack[MAX_CHARTS];
preliminary_plot_positioning(rows_for_plots, cols, devices_count, to_draw,
map_device_to_plot, plot_in_stack, num_plots,
&num_plot_stacks);
preliminary_plot_positioning(rows_for_plots, cols, devices_count, gpuOpts, map_device_to_plot, plot_in_stack,
num_plots, &num_plot_stacks);
// Transfer some lines to the header to separate the devices
unsigned transferable_lines =
@@ -304,8 +302,7 @@ void compute_sizes_from_layout(unsigned devices_count, unsigned device_header_ro
// Compute the cols used in each stacks to prepare balancing
unsigned num_info_per_plot[MAX_CHARTS];
for (unsigned i = 0; i < *num_plots; ++i) {
num_info_per_plot[i] =
info_in_plot(i, devices_count, map_device_to_plot, to_draw);
num_info_per_plot[i] = info_in_plot(i, devices_count, map_device_to_plot, gpuOpts);
}
unsigned cols_allocated_in_stacks[MAX_CHARTS];
for (unsigned i = 0; i < num_plot_stacks; ++i) {

View File

@@ -64,9 +64,8 @@ static const char *default_config_path(void) {
void alloc_interface_options_internals(char *config_location,
unsigned num_devices,
nvtop_interface_option *options) {
options->device_information_drawn =
calloc(num_devices, sizeof(*options->device_information_drawn));
if (!options->device_information_drawn) {
options->gpu_specific_opts = calloc(num_devices, sizeof(*options->gpu_specific_opts));
if (!options->gpu_specific_opts) {
perror("Cannot allocate memory: ");
exit(EXIT_FAILURE);
}
@@ -227,11 +226,10 @@ static int nvtop_option_ini_handler(void *user, const char *section,
for (enum plot_information j = plot_gpu_rate;
j < plot_information_count + 1; ++j) {
if (strcmp(value, device_draw_vals[j]) == 0) {
ini_data->options->device_information_drawn[i] = plot_add_draw_info(
j, ini_data->options->device_information_drawn[i]);
ini_data->options->device_information_drawn[i] = plot_add_draw_info(
plot_information_count,
ini_data->options->device_information_drawn[i]);
ini_data->options->gpu_specific_opts[i].to_draw =
plot_add_draw_info(j, ini_data->options->gpu_specific_opts[i].to_draw);
ini_data->options->gpu_specific_opts[i].to_draw =
plot_add_draw_info(plot_information_count, ini_data->options->gpu_specific_opts[i].to_draw);
}
}
}
@@ -354,7 +352,7 @@ bool save_interface_options_to_config_file(
bool draw_any = false;
for (enum plot_information j = plot_gpu_rate; j < plot_information_count;
++j) {
if (plot_isset_draw_info(j, options->device_information_drawn[i])) {
if (plot_isset_draw_info(j, options->gpu_specific_opts[i].to_draw)) {
fprintf(config_file, "%s = %s\n", device_shown_value,
device_draw_vals[j]);
draw_any = true;

View File

@@ -426,9 +426,8 @@ static void draw_setup_window_chart(unsigned devices_count, struct list_head *de
if (interface->setup_win.options_selected[0] == setup_chart_all_gpu) {
plot_info_to_draw draw_union = 0, draw_intersection = 0xffff;
for (unsigned j = 0; j < devices_count; ++j) {
draw_union |= interface->options.device_information_drawn[j];
draw_intersection = draw_intersection &
interface->options.device_information_drawn[j];
draw_union |= interface->options.gpu_specific_opts[j].to_draw;
draw_intersection = draw_intersection & interface->options.gpu_specific_opts[j].to_draw;
}
if (plot_isset_draw_info(i, draw_intersection)) {
option_state = option_on;
@@ -439,8 +438,7 @@ static void draw_setup_window_chart(unsigned devices_count, struct list_head *de
option_state = option_off;
}
} else {
option_state = plot_isset_draw_info(
i, interface->options.device_information_drawn[selected_gpu]);
option_state = plot_isset_draw_info(i, interface->options.gpu_specific_opts[selected_gpu].to_draw);
}
mvwprintw(value_list_win, i + 2, 0, "[%c] %s",
option_state_char(option_state),
@@ -785,47 +783,32 @@ void handle_setup_win_keypress(int keyId, struct nvtop_interface *interface) {
if (interface->setup_win.options_selected[0] == setup_chart_all_gpu) {
plot_info_to_draw draw_intersection = 0xffff;
for (unsigned j = 0; j < interface->devices_count; ++j) {
draw_intersection =
draw_intersection &
interface->options.device_information_drawn[j];
draw_intersection = draw_intersection & interface->options.gpu_specific_opts[j].to_draw;
}
if (plot_isset_draw_info(interface->setup_win.options_selected[1],
draw_intersection)) {
if (plot_isset_draw_info(interface->setup_win.options_selected[1], draw_intersection)) {
for (unsigned i = 0; i < interface->devices_count; ++i) {
interface->options.device_information_drawn[i] =
plot_remove_draw_info(
interface->setup_win.options_selected[1],
interface->options.device_information_drawn[i]);
interface->options.gpu_specific_opts[i].to_draw = plot_remove_draw_info(
interface->setup_win.options_selected[1], interface->options.gpu_specific_opts[i].to_draw);
interface_ring_buffer_empty(&interface->saved_data_ring, i);
}
} else {
for (unsigned i = 0; i < interface->devices_count; ++i) {
interface->options.device_information_drawn[i] =
plot_add_draw_info(
interface->setup_win.options_selected[1],
interface->options.device_information_drawn[i]);
interface->options.gpu_specific_opts[i].to_draw = plot_add_draw_info(
interface->setup_win.options_selected[1], interface->options.gpu_specific_opts[i].to_draw);
interface_ring_buffer_empty(&interface->saved_data_ring, i);
}
}
}
if (interface->setup_win.options_selected[0] > setup_chart_all_gpu) {
unsigned selected_gpu = interface->setup_win.options_selected[0] -
setup_chart_start_gpu_list;
if (plot_isset_draw_info(
interface->setup_win.options_selected[1],
interface->options.device_information_drawn[selected_gpu]))
interface->options.device_information_drawn[selected_gpu] =
plot_remove_draw_info(
interface->setup_win.options_selected[1],
interface->options
.device_information_drawn[selected_gpu]);
unsigned selected_gpu = interface->setup_win.options_selected[0] - setup_chart_start_gpu_list;
if (plot_isset_draw_info(interface->setup_win.options_selected[1],
interface->options.gpu_specific_opts[selected_gpu].to_draw))
interface->options.gpu_specific_opts[selected_gpu].to_draw = plot_remove_draw_info(
interface->setup_win.options_selected[1], interface->options.gpu_specific_opts[selected_gpu].to_draw);
else
interface->options
.device_information_drawn[selected_gpu] = plot_add_draw_info(
interface->setup_win.options_selected[1],
interface->options.device_information_drawn[selected_gpu]);
interface_ring_buffer_empty(&interface->saved_data_ring,
selected_gpu);
interface->options.gpu_specific_opts[selected_gpu].to_draw = plot_add_draw_info(
interface->setup_win.options_selected[1], interface->options.gpu_specific_opts[selected_gpu].to_draw);
interface_ring_buffer_empty(&interface->saved_data_ring, selected_gpu);
}
}
}

View File

@@ -192,63 +192,61 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
unsigned devices_count = 0;
LIST_HEAD(devices);
if (!gpuinfo_init_info_extraction(&devices_count, &devices))
unsigned allDevCount = 0;
LIST_HEAD(allDevices);
if (!gpuinfo_init_info_extraction(&allDevCount, &allDevices))
return EXIT_FAILURE;
if (devices_count == 0) {
if (allDevCount == 0) {
fprintf(stdout, "No GPU to monitor.\n");
return EXIT_SUCCESS;
}
nvtop_interface_option interface_options;
alloc_interface_options_internals(custom_config_file_path, devices_count,
&interface_options);
load_interface_options_from_config_file(devices_count, &interface_options);
for (unsigned i = 0; i < devices_count; ++i) {
nvtop_interface_option allDevicesOptions;
alloc_interface_options_internals(custom_config_file_path, allDevCount,
&allDevicesOptions);
load_interface_options_from_config_file(allDevCount, &allDevicesOptions);
for (unsigned i = 0; i < allDevCount; ++i) {
// Nothing specified in the file
if (!plot_isset_draw_info(plot_information_count,
interface_options.device_information_drawn[i])) {
interface_options.device_information_drawn[i] = plot_default_draw_info();
if (!plot_isset_draw_info(plot_information_count, allDevicesOptions.gpu_specific_opts[i].to_draw)) {
allDevicesOptions.gpu_specific_opts[i].to_draw = plot_default_draw_info();
} else {
interface_options.device_information_drawn[i] =
plot_remove_draw_info(plot_information_count,
interface_options.device_information_drawn[i]);
allDevicesOptions.gpu_specific_opts[i].to_draw =
plot_remove_draw_info(plot_information_count, allDevicesOptions.gpu_specific_opts[i].to_draw);
}
}
if (!process_is_field_displayed(process_field_count,
interface_options.process_fields_displayed)) {
interface_options.process_fields_displayed =
allDevicesOptions.process_fields_displayed)) {
allDevicesOptions.process_fields_displayed =
process_default_displayed_field();
} else {
interface_options.process_fields_displayed =
allDevicesOptions.process_fields_displayed =
process_remove_field_to_display(
process_field_count, interface_options.process_fields_displayed);
process_field_count, allDevicesOptions.process_fields_displayed);
}
if (no_color_option)
interface_options.use_color = false;
allDevicesOptions.use_color = false;
if (hide_plot_option) {
for (unsigned i = 0; i < devices_count; ++i) {
interface_options.device_information_drawn[i] = 0;
for (unsigned i = 0; i < allDevCount; ++i) {
allDevicesOptions.gpu_specific_opts[i].to_draw = 0;
}
}
if (encode_decode_timer_option_set) {
interface_options.encode_decode_hiding_timer = encode_decode_hide_time;
if (interface_options.encode_decode_hiding_timer < 0.)
interface_options.encode_decode_hiding_timer = 0.;
allDevicesOptions.encode_decode_hiding_timer = encode_decode_hide_time;
if (allDevicesOptions.encode_decode_hiding_timer < 0.)
allDevicesOptions.encode_decode_hiding_timer = 0.;
}
if (reverse_plot_direction_option)
interface_options.plot_left_to_right = true;
allDevicesOptions.plot_left_to_right = true;
if (use_fahrenheit_option)
interface_options.temperature_in_fahrenheit = true;
allDevicesOptions.temperature_in_fahrenheit = true;
if (update_interval_option_set)
interface_options.update_interval = update_interval_option;
allDevicesOptions.update_interval = update_interval_option;
gpuinfo_populate_static_infos(&devices);
gpuinfo_populate_static_infos(&allDevices);
size_t biggest_name = 0;
struct gpu_info *device;
list_for_each_entry(device, &devices, list) {
list_for_each_entry(device, &allDevices, list) {
size_t device_name_size;
if (IS_VALID(gpuinfo_device_name_valid, device->static_info.valid))
device_name_size = strlen(device->static_info.device_name);
@@ -259,7 +257,7 @@ int main(int argc, char **argv) {
}
}
struct nvtop_interface *interface =
initialize_curses(devices_count, biggest_name, interface_options);
initialize_curses(allDevCount, biggest_name, allDevicesOptions);
timeout(interface_update_interval(interface));
double time_slept = interface_update_interval(interface);
@@ -269,19 +267,19 @@ int main(int argc, char **argv) {
update_window_size_to_terminal_size(interface);
}
if (time_slept >= interface_update_interval(interface)) {
gpuinfo_refresh_dynamic_info(&devices);
gpuinfo_refresh_dynamic_info(&allDevices);
if (!interface_freeze_processes(interface)) {
gpuinfo_refresh_processes(&devices);
gpuinfo_fix_dynamic_info_from_process_info(&devices);
gpuinfo_refresh_processes(&allDevices);
gpuinfo_fix_dynamic_info_from_process_info(&allDevices);
}
save_current_data_to_ring(&devices, interface);
save_current_data_to_ring(&allDevices, interface);
timeout(interface_update_interval(interface));
time_slept = 0.;
} else {
int next_sleep = interface_update_interval(interface) - (int)time_slept;
timeout(next_sleep);
}
draw_gpu_info_ncurses(devices_count, &devices, interface);
draw_gpu_info_ncurses(allDevCount, &allDevices, interface);
nvtop_time time_before_sleep, time_after_sleep;
nvtop_get_current_time(&time_before_sleep);
@@ -331,7 +329,7 @@ int main(int argc, char **argv) {
}
clean_ncurses(interface);
gpuinfo_shutdown_info_extraction(&devices);
gpuinfo_shutdown_info_extraction(&allDevices);
return EXIT_SUCCESS;
}

View File

@@ -131,8 +131,8 @@ bool test_with_terminal_size(unsigned device_count, unsigned header_rows, unsign
unsigned cols) {
struct window_position screen = {.posX = 0, .posY = 0, .sizeX = cols, .sizeY = rows};
plot_info_to_draw to_draw_default = plot_default_draw_info();
std::vector<plot_info_to_draw> plot_display(device_count, to_draw_default);
nvtop_interface_gpu_opts to_draw_default = {.to_draw = plot_default_draw_info()};
std::vector<nvtop_interface_gpu_opts> plot_display(device_count, to_draw_default);
process_field_displayed proc_display = process_default_displayed_field();
@@ -158,8 +158,8 @@ TEST(InterfaceLayout, CheckEmptyProcessWindow) {
unsigned device_count = 3, header_rows = 3, header_cols = 55, rows = 4, cols = 120;
struct window_position screen = {.posX = 0, .posY = 0, .sizeX = cols, .sizeY = rows};
plot_info_to_draw to_draw_default = plot_default_draw_info();
std::vector<plot_info_to_draw> plot_display(device_count, to_draw_default);
nvtop_interface_gpu_opts to_draw_default = {.to_draw = plot_default_draw_info()};
std::vector<nvtop_interface_gpu_opts> plot_display(device_count, to_draw_default);
process_field_displayed proc_display = process_default_displayed_field();
@@ -181,8 +181,8 @@ TEST(InterfaceLayout, FixInfiniteLoop) {
unsigned device_count = 3, header_rows = 3, header_cols = 55, rows = 22, cols = 25;
struct window_position screen = {.posX = 0, .posY = 0, .sizeX = cols, .sizeY = rows};
plot_info_to_draw to_draw_default = plot_default_draw_info();
std::vector<plot_info_to_draw> plot_display(device_count, to_draw_default);
nvtop_interface_gpu_opts to_draw_default = {.to_draw = plot_default_draw_info()};
std::vector<nvtop_interface_gpu_opts> plot_display(device_count, to_draw_default);
process_field_displayed proc_display = process_default_displayed_field();