nvitop/nvitop/gui/screens/help.py
2023-03-15 09:26:07 +00:00

112 lines
4.5 KiB
Python

# This file is part of nvitop, the interactive NVIDIA-GPU process viewer.
# License: GNU GPL version 3.
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
from nvitop.gui.library import Device, Displayable, MouseEvent
from nvitop.version import __version__
HELP_TEMPLATE = """nvitop {} - (C) Xuehai Pan, 2021-2023.
Released under the GNU GPLv3 License.
GPU Process Type: C: Compute, G: Graphics, X: Mixed.
Device coloring rules by loading intensity:
- GPU utilization: light < {:2d}% <= moderate < {:2d}% <= heavy.
- GPU-MEM percent: light < {:2d}% <= moderate < {:2d}% <= heavy.
a f c: change display mode h ?: show this help screen
F5 r: force refresh window q: quit
Arrows: scroll process list Space: tag/untag current process
Home: select the first process Esc: clear process selection
End: select the last process Ctrl-C I: interrupt selected process
K: kill selected process
Ctrl-A ^: scroll to left most T: terminate selected process
Ctrl-E $: scroll to right most e: show process environment
PageUp [: scroll entire screen up t: toggle tree-view screen
PageDown ]: scroll entire screen down Enter: show process metrics
Wheel: scroll process list Shift-Wheel: scroll horizontally
Tab: scroll process list Ctrl-Wheel: fast scroll ({}x)
on oN: sort by GPU-INDEX os oS: sort by %SM
op oP: sort by PID oc oC: sort by %CPU
ou oU: sort by USER om oM: sort by %MEM
og oG: sort by GPU-MEM ot oT: sort by TIME
, .: select sort column /: invert sort order
Press any key to return.
"""
class HelpScreen(Displayable): # pylint: disable=too-many-instance-attributes
NAME = 'help'
def __init__(self, win, root):
super().__init__(win, root)
self.infos = (
HELP_TEMPLATE.format(
__version__,
*Device.GPU_UTILIZATION_THRESHOLDS,
*Device.MEMORY_UTILIZATION_THRESHOLDS,
MouseEvent.CTRL_SCROLLWHEEL_MULTIPLIER,
)
.strip()
.splitlines()
)
self.color_matrix = {
9: ('green', 'green'),
10: ('green', 'green'),
12: ('cyan', 'yellow'),
13: ('cyan', 'yellow'),
14: ('cyan', 'red'),
15: (None, 'red'),
16: ('cyan', 'red'),
**{dy: ('cyan', 'green') for dy in range(17, 20)},
**{dy: ('blue', 'blue') for dy in range(21, 23)},
**{dy: ('blue', 'blue') for dy in range(24, 28)},
28: ('magenta', 'magenta'),
}
self.x, self.y = root.x, root.y
self.width = max(map(len, self.infos))
self.height = len(self.infos)
def draw(self):
if not self.need_redraw:
return
self.color_reset()
for y, line in enumerate(self.infos, start=self.y):
self.addstr(y, self.x, line)
self.color_at(self.y, self.x, width=self.width, fg='cyan', attr='bold')
self.color_at(self.y + 1, self.x, width=self.width, fg='cyan', attr='bold')
self.color_at(self.y + self.height - 1, self.x, width=self.width, fg='cyan', attr='bold')
self.color_at(self.y + 3, self.x, width=17, attr='bold')
for dx in (18, 30, 43):
self.color_at(self.y + 3, self.x + dx, width=1, fg='magenta', attr='bold')
for dx in (21, 33, 48):
self.color_at(self.y + 3, self.x + dx, width=1, attr='underline')
self.color_at(self.y + 5, self.x, width=21, attr='bold')
for dy in (6, 7):
self.color_at(self.y + dy, self.x + 21, width=5, fg='green', attr='bold | italic')
self.color_at(self.y + dy, self.x + 36, width=8, fg='yellow', attr='bold | italic')
self.color_at(self.y + dy, self.x + 54, width=5, fg='red', attr='bold | italic')
for dy, (left, right) in self.color_matrix.items():
if left is not None:
self.color_at(self.y + dy, self.x, width=12, fg=left, attr='bold')
if right is not None:
self.color_at(self.y + dy, self.x + 39, width=13, fg=right, attr='bold')
def press(self, key):
self.root.keymaps.use_keymap('help')
self.root.press(key)