2022-07-13 01:06:15 -04:00
|
|
|
local pure = require 'pure'
|
2021-08-08 15:58:53 -04:00
|
|
|
local i_o = require 'i_o'
|
2021-07-29 22:18:29 -04:00
|
|
|
local common = require 'common'
|
|
|
|
local geometry = require 'geometry'
|
2017-07-19 00:36:15 -04:00
|
|
|
|
2022-07-14 20:13:29 -04:00
|
|
|
return function(update_freq, point)
|
2021-07-17 23:28:59 -04:00
|
|
|
local SEPARATOR_SPACING = 20
|
|
|
|
local TEXT_SPACING = 20
|
|
|
|
local PLOT_SEC_BREAK = 20
|
|
|
|
local PLOT_HEIGHT = 56
|
|
|
|
local NA = 'N/A'
|
|
|
|
local __string_match = string.match
|
2021-11-10 16:55:10 -05:00
|
|
|
local __tonumber = tonumber
|
2017-07-19 00:36:15 -04:00
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- helper functions
|
|
|
|
|
|
|
|
local _from_state = function(def, f, set)
|
|
|
|
return function(s)
|
|
|
|
if s.error == false then
|
|
|
|
set(f(s))
|
|
|
|
else
|
|
|
|
set(def)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local _mk_plot = function(label, getter, y)
|
|
|
|
local obj = common.make_tagged_maybe_percent_timeseries(
|
2022-07-14 20:13:29 -04:00
|
|
|
point.x,
|
2022-07-13 01:06:15 -04:00
|
|
|
y,
|
|
|
|
geometry.SECTION_WIDTH,
|
|
|
|
PLOT_HEIGHT,
|
|
|
|
PLOT_SEC_BREAK,
|
|
|
|
label,
|
|
|
|
update_freq
|
|
|
|
)
|
|
|
|
local update = _from_state(
|
|
|
|
false,
|
|
|
|
getter,
|
|
|
|
pure.partial(common.tagged_maybe_percent_timeseries_set, obj)
|
|
|
|
)
|
|
|
|
local static = pure.partial(common.tagged_percent_timeseries_draw_static, obj)
|
|
|
|
local dynamic = pure.partial(common.tagged_percent_timeseries_draw_dynamic, obj)
|
|
|
|
return common.mk_acc(PLOT_HEIGHT + PLOT_SEC_BREAK, update, static, dynamic)
|
|
|
|
end
|
2021-07-13 00:14:04 -04:00
|
|
|
|
2021-07-17 23:28:59 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- header
|
2021-07-13 00:14:04 -04:00
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local mk_header = pure.partial(
|
|
|
|
common.mk_header,
|
|
|
|
'NVIDIA GRAPHICS',
|
2021-07-29 22:18:29 -04:00
|
|
|
geometry.SECTION_WIDTH,
|
2022-07-14 20:13:29 -04:00
|
|
|
point.x
|
2021-07-17 23:28:59 -04:00
|
|
|
)
|
2021-07-17 16:43:00 -04:00
|
|
|
|
2021-07-17 23:28:59 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- gpu status
|
2021-07-17 16:43:00 -04:00
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local mk_status = function(y)
|
|
|
|
local obj = common.make_text_row(
|
2022-07-14 20:13:29 -04:00
|
|
|
point.x,
|
2022-07-13 01:06:15 -04:00
|
|
|
y,
|
|
|
|
geometry.SECTION_WIDTH,
|
|
|
|
'Status'
|
|
|
|
)
|
|
|
|
local update = function(s)
|
|
|
|
if s.error == false then
|
|
|
|
common.text_row_set(obj, 'On')
|
|
|
|
else
|
|
|
|
common.text_row_set(obj, s.error)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local static = pure.partial(common.text_row_draw_static, obj)
|
|
|
|
local dynamic = pure.partial(common.text_row_draw_dynamic, obj)
|
|
|
|
return common.mk_acc(0, update, static, dynamic)
|
|
|
|
end
|
2021-07-17 23:28:59 -04:00
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local mk_sep = pure.partial(
|
|
|
|
common.mk_seperator,
|
|
|
|
geometry.SECTION_WIDTH,
|
2022-07-14 20:13:29 -04:00
|
|
|
point.x
|
2021-07-17 23:28:59 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- gpu temperature
|
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local mk_temp = function(y)
|
|
|
|
local obj = common.make_threshold_text_row(
|
2022-07-14 20:13:29 -04:00
|
|
|
point.x,
|
2022-07-13 01:06:15 -04:00
|
|
|
y,
|
|
|
|
geometry.SECTION_WIDTH,
|
|
|
|
'Internal Temperature',
|
|
|
|
function(s)
|
|
|
|
if s == -1 then return NA else return string.format('%s°C', s) end
|
|
|
|
end,
|
|
|
|
80
|
|
|
|
)
|
|
|
|
local update = _from_state(
|
|
|
|
-1,
|
|
|
|
function(s) return __tonumber(s.temp_reading) end,
|
|
|
|
pure.partial(common.threshold_text_row_set, obj)
|
|
|
|
)
|
|
|
|
local static = pure.partial(common.threshold_text_row_draw_static, obj)
|
|
|
|
local dynamic = pure.partial(common.threshold_text_row_draw_dynamic, obj)
|
|
|
|
return common.mk_acc(0, update, static, dynamic)
|
|
|
|
end
|
2021-07-17 23:28:59 -04:00
|
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- gpu clock speeds
|
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local mk_clock = function(y)
|
|
|
|
local obj = common.make_text_rows(
|
2022-07-14 20:13:29 -04:00
|
|
|
point.x,
|
2021-07-17 23:28:59 -04:00
|
|
|
y,
|
2021-07-29 22:18:29 -04:00
|
|
|
geometry.SECTION_WIDTH,
|
2022-07-13 01:06:15 -04:00
|
|
|
TEXT_SPACING,
|
|
|
|
{'GPU Clock Speed', 'memory Clock Speed'}
|
2021-07-17 23:28:59 -04:00
|
|
|
)
|
2022-07-13 01:06:15 -04:00
|
|
|
local update = function(s)
|
|
|
|
if s.error == false then
|
|
|
|
common.text_rows_set(obj, 1, s.gpu_frequency..' Mhz')
|
|
|
|
common.text_rows_set(obj, 2, s.memory_frequency..' Mhz')
|
|
|
|
else
|
|
|
|
common.text_rows_set(obj, 1, NA)
|
|
|
|
common.text_rows_set(obj, 2, NA)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local static = pure.partial(common.text_rows_draw_static, obj)
|
|
|
|
local dynamic = pure.partial(common.text_rows_draw_dynamic, obj)
|
|
|
|
return common.mk_acc(TEXT_SPACING, update, static, dynamic)
|
2021-07-17 23:28:59 -04:00
|
|
|
end
|
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- gpu utilization plot
|
|
|
|
|
|
|
|
local mk_gpu_util = pure.partial(
|
|
|
|
_mk_plot,
|
|
|
|
'GPU utilization',
|
|
|
|
function(s) return s.gpu_utilization end
|
|
|
|
)
|
2021-07-17 23:28:59 -04:00
|
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- gpu memory consumption plot
|
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local mk_mem_util = pure.partial(
|
|
|
|
_mk_plot,
|
|
|
|
'Memory utilization',
|
|
|
|
function(s) return s.used_memory / s.total_memory * 100 end
|
|
|
|
)
|
2021-07-17 23:28:59 -04:00
|
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- gpu video utilization plot
|
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local mk_vid_util = pure.partial(
|
|
|
|
_mk_plot,
|
|
|
|
'Video utilization',
|
|
|
|
function(s) return s.vid_utilization end
|
|
|
|
)
|
2021-07-17 23:28:59 -04:00
|
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
2022-07-13 01:06:15 -04:00
|
|
|
-- nvidia state
|
2021-07-17 23:28:59 -04:00
|
|
|
|
|
|
|
-- vars to process the nv settings glob
|
|
|
|
--
|
|
|
|
-- glob will be of the form:
|
|
|
|
-- <used_mem>
|
|
|
|
-- <total_mem>
|
|
|
|
-- <temp>
|
|
|
|
-- <gpu_freq>,<mem_freq>
|
|
|
|
-- graphics=<gpu_util>, memory=<mem_util>, video=<vid_util>, PCIe=<pci_util>
|
|
|
|
local NV_QUERY = 'nvidia-settings -t'..
|
2021-07-29 22:18:29 -04:00
|
|
|
' -q UsedDedicatedGPUmemory'..
|
|
|
|
' -q TotalDedicatedGPUmemory'..
|
2021-07-17 23:28:59 -04:00
|
|
|
' -q ThermalSensorReading'..
|
|
|
|
' -q [gpu:0]/GPUCurrentClockFreqs'..
|
2021-07-29 22:39:38 -04:00
|
|
|
' -q [gpu:0]/GPUutilization'
|
2021-07-17 23:28:59 -04:00
|
|
|
|
|
|
|
local NV_REGEX = '(%d+)\n'..
|
|
|
|
'(%d+)\n'..
|
|
|
|
'(%d+)\n'..
|
|
|
|
'(%d+),(%d+)\n'..
|
|
|
|
'graphics=(%d+), memory=%d+, video=(%d+), PCIe=%d+\n'
|
|
|
|
|
|
|
|
local GPU_BUS_CTRL = '/sys/bus/pci/devices/0000:01:00.0/power/control'
|
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local state = {
|
|
|
|
error = false,
|
|
|
|
used_memory = 0,
|
|
|
|
total_memory = 0,
|
|
|
|
temp_reading = 0,
|
|
|
|
gpu_frequency = 0,
|
|
|
|
memory_frequency = 0,
|
|
|
|
gpu_utilization = 0,
|
|
|
|
vid_utilization = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
local update_state = function()
|
2021-08-08 15:58:53 -04:00
|
|
|
if i_o.read_file(GPU_BUS_CTRL, nil, '*l') == 'on' then
|
|
|
|
local nvidia_settings_glob = i_o.execute_cmd(NV_QUERY)
|
2021-07-17 16:43:00 -04:00
|
|
|
if nvidia_settings_glob == '' then
|
2022-07-13 01:06:15 -04:00
|
|
|
state.error = 'Error'
|
2021-07-17 16:43:00 -04:00
|
|
|
else
|
2022-07-13 01:06:15 -04:00
|
|
|
state.used_memory,
|
|
|
|
state.total_memory,
|
|
|
|
state.temp_reading,
|
|
|
|
state.gpu_frequency,
|
|
|
|
state.memory_frequency,
|
|
|
|
state.gpu_utilization,
|
|
|
|
state.vid_utilization
|
2021-07-17 16:43:00 -04:00
|
|
|
= __string_match(nvidia_settings_glob, NV_REGEX)
|
2022-07-13 01:06:15 -04:00
|
|
|
state.error = false
|
2021-07-17 16:43:00 -04:00
|
|
|
end
|
2020-01-30 23:48:02 -05:00
|
|
|
else
|
2022-07-13 01:06:15 -04:00
|
|
|
state.error = 'Off'
|
2021-07-17 16:43:00 -04:00
|
|
|
end
|
2022-07-13 01:06:15 -04:00
|
|
|
return state
|
2021-07-17 16:43:00 -04:00
|
|
|
end
|
2020-01-30 23:48:02 -05:00
|
|
|
|
2021-07-17 23:28:59 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- main drawing functions
|
|
|
|
|
2022-07-13 01:06:15 -04:00
|
|
|
local rbs = common.reduce_blocks_(
|
2022-07-14 20:13:29 -04:00
|
|
|
point.y,
|
2022-07-13 01:06:15 -04:00
|
|
|
{
|
|
|
|
common.mk_block(mk_header, true, 0),
|
|
|
|
common.mk_block(mk_status, true, 0),
|
|
|
|
common.mk_block(mk_sep, true, SEPARATOR_SPACING),
|
|
|
|
common.mk_block(mk_temp, true, TEXT_SPACING),
|
|
|
|
common.mk_block(mk_sep, true, SEPARATOR_SPACING),
|
|
|
|
common.mk_block(mk_clock, true, SEPARATOR_SPACING),
|
|
|
|
common.mk_block(mk_sep, true, SEPARATOR_SPACING),
|
|
|
|
common.mk_block(mk_gpu_util, true, PLOT_SEC_BREAK),
|
|
|
|
common.mk_block(mk_mem_util, true, PLOT_SEC_BREAK),
|
|
|
|
common.mk_block(mk_vid_util, true, PLOT_SEC_BREAK)
|
|
|
|
}
|
|
|
|
)
|
2022-07-14 20:13:29 -04:00
|
|
|
return pure.map_at("update", function(f) return function() f(update_state()) end end, rbs)
|
2021-07-17 00:17:22 -04:00
|
|
|
end
|