REF centralize rate plot code

This commit is contained in:
Nathan Dwarshuis 2021-07-19 23:58:58 -04:00
parent 9759d07582
commit 193a9dd759
4 changed files with 219 additions and 225 deletions

View File

@ -282,6 +282,52 @@ M.annotated_scale_plot_set = function(asp, cr, value)
ScaledTimeseries.update(asp.plot, cr, value)
end
--------------------------------------------------------------------------------
-- rate timecourse plots
M.compute_derivative = function(x0, x1, update_frequency)
-- mask overflow
if x1 > x0 then
return (x1 - x0) * update_frequency
else
return 0
end
end
local build_differential = function(update_frequency)
return function(x0, x1)
-- mask overflow
if x1 > x0 then
return (x1 - x0) * update_frequency
else
return 0
end
end
end
M.build_rate_timeseries = function(x, y, w, h, format_fun, label_fun, spacing,
label, min_domain, update_freq, init)
return {
label = _left_text(F.make_point(x, y), label),
value = Text.build_formatted(
F.make_point(x + w, y),
0,
M.right_text_style,
format_fun
),
plot = M.initThemedScalePlot(x, y + spacing, w, h, label_fun, min_domain, update_freq),
prev_value = init,
derive = build_differential(update_freq),
}
end
M.update_rate_timeseries = function(obj, cr, value)
local rate = obj.derive(obj.prev_value, value)
Text.set(obj.value, cr, rate)
ScaledTimeseries.update(obj.plot, cr, rate)
obj.prev_value = value
end
--------------------------------------------------------------------------------
-- arc (TODO this is just a dummy now to make everything organized

View File

@ -17,52 +17,6 @@ return function(update_freq)
local INTERFACES = get_interfaces()
-----------------------------------------------------------------------------
-- header
local header = Common.Header(
Geometry.CENTER_RIGHT_X,
Geometry.TOP_Y,
Geometry.SECTION_WIDTH,
'NETWORK'
)
-----------------------------------------------------------------------------
-- download plot
local value_format_function = function(bits)
local unit, value = Util.convert_data_val(bits)
return Util.precision_round_to_string(value, 3)..' '..unit..'b/s'
end
local build_plot = function(y, label)
return Common.initLabeledScalePlot(
Geometry.CENTER_RIGHT_X,
y,
Geometry.SECTION_WIDTH,
PLOT_HEIGHT,
value_format_function,
Common.converted_y_label_format_generator('b'),
PLOT_SEC_BREAK,
label,
2,
update_freq
)
end
local dnload = build_plot(header.bottom_y, 'Download')
-----------------------------------------------------------------------------
-- upload plot
local upload = build_plot(
header.bottom_y + PLOT_HEIGHT + PLOT_SEC_BREAK * 2,
'Upload'
)
-----------------------------------------------------------------------------
-- update function
local INTERFACE_PATHS = {}
for i = 1, #INTERFACES do
local dir = string.format('/sys/class/net/%s/statistics/', INTERFACES[i])
@ -87,46 +41,69 @@ return function(update_freq)
return rx, tx
end
local compute_speed = function(x0, x1)
-- mask overflow
if x1 > x0 then
return (x1 - x0) * update_freq
else
return 0
end
local init_rx_bits, init_tx_bits = read_interfaces()
local value_format_function = function(bits)
local unit, value = Util.convert_data_val(bits)
return Util.precision_round_to_string(value, 3)..' '..unit..'b/s'
end
local prev_rx_bits, prev_tx_bits = read_interfaces()
local update = function(cr)
local rx_bits, tx_bits = read_interfaces()
Common.annotated_scale_plot_set(
dnload,
cr,
compute_speed(prev_rx_bits, rx_bits)
local build_plot = function(y, label, init)
return Common.build_rate_timeseries(
Geometry.CENTER_RIGHT_X,
y,
Geometry.SECTION_WIDTH,
PLOT_HEIGHT,
value_format_function,
Common.converted_y_label_format_generator('b'),
PLOT_SEC_BREAK,
label,
2,
update_freq,
init
)
Common.annotated_scale_plot_set(
upload,
cr,
compute_speed(prev_tx_bits, tx_bits)
)
prev_rx_bits = rx_bits
prev_tx_bits = tx_bits
end
-----------------------------------------------------------------------------
-- header
local header = Common.Header(
Geometry.CENTER_RIGHT_X,
Geometry.TOP_Y,
Geometry.SECTION_WIDTH,
'NETWORK'
)
-----------------------------------------------------------------------------
-- download plot
local rx = build_plot(header.bottom_y, 'Download', init_rx_bits)
-----------------------------------------------------------------------------
-- upload plot
local TX_Y = header.bottom_y + PLOT_HEIGHT + PLOT_SEC_BREAK * 2
local tx = build_plot(TX_Y, 'Upload', init_tx_bits)
-----------------------------------------------------------------------------
-- main drawing functions
local update = function(cr)
local rx_bits, tx_bits = read_interfaces()
Common.update_rate_timeseries(rx, cr, rx_bits)
Common.update_rate_timeseries(tx, cr, tx_bits)
end
local draw_static = function(cr)
Common.drawHeader(cr, header)
Common.annotated_scale_plot_draw_static(dnload, cr)
Common.annotated_scale_plot_draw_static(upload, cr)
Common.annotated_scale_plot_draw_static(rx, cr)
Common.annotated_scale_plot_draw_static(tx, cr)
end
local draw_dynamic = function(cr)
update(cr)
Common.annotated_scale_plot_draw_dynamic(dnload, cr)
Common.annotated_scale_plot_draw_dynamic(upload, cr)
Common.annotated_scale_plot_draw_dynamic(rx, cr)
Common.annotated_scale_plot_draw_dynamic(tx, cr)
end
return {static = draw_static, dynamic = draw_dynamic}

View File

@ -9,6 +9,61 @@ return function(update_freq)
local PLOT_HEIGHT = 56
local PKG0_PATH = '/sys/class/powercap/intel-rapl:0/energy_uj'
local DRAM_PATH = '/sys/class/powercap/intel-rapl:0:2/energy_uj'
local BAT_CURRENT_PATH = '/sys/class/power_supply/BAT0/current_now'
local BAT_VOLTAGE_PATH = '/sys/class/power_supply/BAT0/voltage_now'
local read_milli = function(path)
return Util.read_file(path, nil, '*n') * 0.000001
end
local read_pkg0_joules = function()
return read_milli(PKG0_PATH)
end
local read_dram_joules = function()
return read_milli(DRAM_PATH)
end
local read_battery_current = function()
return read_milli(BAT_CURRENT_PATH)
end
local read_battery_voltage = function()
return read_milli(BAT_VOLTAGE_PATH)
end
local read_battery_power = function(is_using_ac)
if is_using_ac then
return 0
else
return read_battery_current() * read_battery_voltage()
end
end
local power_label_function = function(plot_max)
local fmt = Common.y_label_format_string(plot_max, 'W')
return function(watts) return string.format(fmt, watts) end
end
local format_rapl = function(watts)
return Util.precision_round_to_string(watts, 3)..' W'
end
local build_rate_plot = function(y, label, init)
return Common.build_rate_timeseries(
Geometry.RIGHT_X,
y,
Geometry.SECTION_WIDTH,
PLOT_HEIGHT,
format_rapl,
power_label_function,
PLOT_SEC_BREAK,
label,
0,
update_freq,
init
)
end
-----------------------------------------------------------------------------
-- header
@ -23,114 +78,60 @@ return function(update_freq)
-----------------------------------------------------------------------------
-- package 0 power plot
local power_label_function = function(plot_max)
local fmt = Common.y_label_format_string(plot_max, 'W')
return function(watts) return string.format(fmt, watts) end
end
local power_format_function = function(watts)
return Util.precision_round_to_string(watts, 3)..' W'
end
local build_plot = function(y, label, format_fun)
return Common.initLabeledScalePlot(
Geometry.RIGHT_X,
y,
Geometry.SECTION_WIDTH,
PLOT_HEIGHT,
format_fun,
power_label_function,
PLOT_SEC_BREAK,
label,
0,
update_freq
)
end
local pkg0 = build_plot(header.bottom_y, 'PKG0', power_format_function)
local pkg0 = build_rate_plot(header.bottom_y, 'PKG0', read_pkg0_joules())
-----------------------------------------------------------------------------
-- DRAM power plot
local CORE_Y = header.bottom_y + TEXT_SPACING + PLOT_SEC_BREAK + PLOT_HEIGHT
local dram = build_plot(CORE_Y, 'DRAM', power_format_function)
local DRAM_Y = header.bottom_y + TEXT_SPACING + PLOT_SEC_BREAK + PLOT_HEIGHT
local dram = build_rate_plot(DRAM_Y, 'DRAM', read_dram_joules())
-----------------------------------------------------------------------------
-- battery power plot
local ac_format_function = function(watts)
local format_ac = function(watts)
if watts == 0 then
return "A/C"
else
return power_format_function(watts)
return format_rapl(watts)
end
end
local battery_draw = build_plot(
CORE_Y + PLOT_SEC_BREAK * 2 + PLOT_HEIGHT,
local BAT_Y = DRAM_Y + PLOT_SEC_BREAK * 2 + PLOT_HEIGHT
local bat = Common.initLabeledScalePlot(
Geometry.RIGHT_X,
BAT_Y,
Geometry.SECTION_WIDTH,
PLOT_HEIGHT,
format_ac,
power_label_function,
PLOT_SEC_BREAK,
'Battery Draw',
ac_format_function
0,
update_freq
)
-----------------------------------------------------------------------------
-- update functions
local read_uj = function(path)
return Util.read_file(path, nil, '*n')
end
local prev_pkg0_uj_cnt = read_uj(PKG0_PATH)
local prev_dram_uj_cnt = read_uj(DRAM_PATH)
local calculate_power = function(prev_cnt, cnt, update_frequency)
if cnt > prev_cnt then
return (cnt - prev_cnt) * update_frequency * 0.000001
else
return 0
end
end
-- main functions
local update = function(cr, is_using_ac)
local pkg0_uj_cnt = read_uj(PKG0_PATH)
local dram_uj_cnt = read_uj(DRAM_PATH)
local pkg0_power = calculate_power(prev_pkg0_uj_cnt, pkg0_uj_cnt, update_freq)
Common.annotated_scale_plot_set(pkg0, cr, pkg0_power)
local dram_power = calculate_power(prev_dram_uj_cnt, dram_uj_cnt, update_freq)
Common.annotated_scale_plot_set(dram, cr, dram_power)
prev_pkg0_uj_cnt = pkg0_uj_cnt
prev_dram_uj_cnt = dram_uj_cnt
if is_using_ac then
Common.annotated_scale_plot_set(battery_draw, cr, 0)
else
local current = Util.read_file('/sys/class/power_supply/BAT0/current_now', nil, '*n')
local voltage = Util.read_file('/sys/class/power_supply/BAT0/voltage_now', nil, '*n')
local power = current * voltage * 0.000000000001
Common.annotated_scale_plot_set(battery_draw, cr, power)
Common.update_rate_timeseries(pkg0, cr, read_pkg0_joules())
Common.update_rate_timeseries(dram, cr, read_dram_joules())
Common.annotated_scale_plot_set(bat, cr, read_battery_power(is_using_ac))
end
end
-----------------------------------------------------------------------------
-- main functions
local draw_static = function(cr)
Common.drawHeader(cr, header)
Common.annotated_scale_plot_draw_static(pkg0, cr)
Common.annotated_scale_plot_draw_static(dram, cr)
Common.annotated_scale_plot_draw_static(battery_draw, cr)
Common.annotated_scale_plot_draw_static(bat, cr)
end
local draw_dynamic = function(cr, is_using_ac)
update(cr, is_using_ac)
Common.annotated_scale_plot_draw_dynamic(pkg0, cr)
Common.annotated_scale_plot_draw_dynamic(dram, cr)
Common.annotated_scale_plot_draw_dynamic(battery_draw, cr)
Common.annotated_scale_plot_draw_dynamic(bat, cr)
end
return {static = draw_static, dynamic = draw_dynamic}

View File

@ -16,62 +16,6 @@ return function(update_freq)
local __tonumber = tonumber
local __string_match = string.match
local __math_floor = math.floor
-----------------------------------------------------------------------------
-- header
local header = Common.Header(
Geometry.CENTER_LEFT_X,
Geometry.TOP_Y,
Geometry.SECTION_WIDTH,
'INPUT / OUTPUT'
)
-----------------------------------------------------------------------------
-- reads
-- local io_label_format_fun_generator = function(plot_max)
-- local new_unit, new_max = Util.convert_data_val(plot_max)
-- local conversion_factor = plot_max / new_max
-- local fmt = Common.y_label_format_string(new_max, new_unit..'B/s')
-- return function(bytes)
-- return string.format(fmt, bytes / conversion_factor)
-- end
-- end
local format_value_function = function(bps)
local unit, value = Util.convert_data_val(bps)
return Util.precision_round_to_string(value, 3)..' '..unit..'B/s'
end
local build_plot = function(y, label)
return Common.initLabeledScalePlot(
Geometry.CENTER_LEFT_X,
y,
Geometry.SECTION_WIDTH,
PLOT_HEIGHT,
format_value_function,
Common.converted_y_label_format_generator('B'),
PLOT_SEC_BREAK,
label,
2,
update_freq
)
end
local reads = build_plot(header.bottom_y, 'Reads')
-----------------------------------------------------------------------------
-- writes
local writes = build_plot(
header.bottom_y + PLOT_HEIGHT + PLOT_SEC_BREAK * 2,
'Writes'
)
-----------------------------------------------------------------------------
-- update function
local DEVICE_PATHS = {}
for i = 1, #DEVICES do
@ -89,36 +33,62 @@ return function(update_freq)
return read_bytes * BLOCK_SIZE_BYTES, write_bytes * BLOCK_SIZE_BYTES
end
local prev_read_bytes, prev_write_bytes = read_devices()
local init_read_bytes, init_write_bytes = read_devices()
local compute_rate = function(x0, x1)
-- mask overflow
if x1 > x0 then
return (x1 - x0) * update_freq
else
return 0
end
local format_value_function = function(bps)
local unit, value = Util.convert_data_val(bps)
return Util.precision_round_to_string(value, 3)..' '..unit..'B/s'
end
local update = function(cr)
local read_bytes, write_bytes = read_devices()
Common.annotated_scale_plot_set(
reads,
cr,
compute_rate(prev_read_bytes, read_bytes)
local build_plot = function(y, label, init)
return Common.build_rate_timeseries(
Geometry.CENTER_LEFT_X,
y,
Geometry.SECTION_WIDTH,
PLOT_HEIGHT,
format_value_function,
Common.converted_y_label_format_generator('B'),
PLOT_SEC_BREAK,
label,
2,
update_freq,
init
)
Common.annotated_scale_plot_set(
writes,
cr,
compute_rate(prev_write_bytes, write_bytes)
)
prev_read_bytes = read_bytes
prev_write_bytes = write_bytes
end
-----------------------------------------------------------------------------
-- header
local header = Common.Header(
Geometry.CENTER_LEFT_X,
Geometry.TOP_Y,
Geometry.SECTION_WIDTH,
'INPUT / OUTPUT'
)
-----------------------------------------------------------------------------
-- reads
local reads = build_plot(header.bottom_y, 'Reads', init_read_bytes)
-----------------------------------------------------------------------------
-- writes
local writes = build_plot(
header.bottom_y + PLOT_HEIGHT + PLOT_SEC_BREAK * 2,
'Writes',
init_write_bytes
)
-----------------------------------------------------------------------------
-- main drawing functions
local update = function(cr)
local read_bytes, write_bytes = read_devices()
Common.update_rate_timeseries(reads, cr, read_bytes)
Common.update_rate_timeseries(writes, cr, write_bytes)
end
local draw_static = function(cr)
Common.drawHeader(cr, header)
Common.annotated_scale_plot_draw_static(reads, cr)