Skip to content

Commit c543c0e

Browse files
authored
Merge pull request #253 from microsoft:bruno-addgpuviewer
Add Console GPU Viewer for NVIDIA GPU diagnostics
2 parents 532b51f + 7f9f7d0 commit c543c0e

7 files changed

Lines changed: 1003 additions & 0 deletions

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# GitHub Copilot Prompt: Create a GPU-monitoring console app in C# (.NET 10)
2+
3+
Goal
4+
-----
5+
6+
Generate a .NET 10 C# console application that monitors local NVIDIA GPU usage and displays a live terminal UI with graphs and a table, similar to `nvsharptop.cs` in this repository.
7+
8+
Requirements / Acceptance Criteria
9+
---------------------------------
10+
11+
- Buildable with .NET 10 SDK (using top-level statements or Program.cs). The project must run with `dotnet run` and should also be publishable as a single-file executable.
12+
- Use the `Spectre.Console` package to render the terminal UI (graphs, table, colors, markup).
13+
- Query local NVIDIA GPUs using the `nvidia-smi` command with the same fields: `index,name,temperature.gpu,utilization.gpu,memory.used,memory.total`.
14+
- Parse `nvidia-smi` CSV output safely and handle no-GPU cases without crashing.
15+
- Continuously sample GPU stats at a configurable `--sample-interval` (default `1.0s`) and refresh the display at `--display-interval` (default `3s`).
16+
- Provide a `--cleanup-screen <true|false>` option (default true) to clear the console on exit.
17+
- Handle Ctrl+C gracefully and restore console state according to `--cleanup-screen`.
18+
- Maintain per-GPU history buffers and render utilization and memory percent graphs with configurable graph width based on the console size.
19+
- Provide a `--help` / `-h` option that prints usage and exits.
20+
- Include build and run instructions and a short README section in the generated code comments or project README.
21+
22+
Interactive start screen
23+
------------------------
24+
25+
- The program should display a welcome/start screen on launch that shows interactive controls and the current view mode and the current CLI-configurable options.
26+
- Controls on the start screen:
27+
- `S` or `Enter` to start monitoring, `Q` to quit
28+
- `H` to select Horizontal mode, `V` to select Vertical mode (Vertical is the default)
29+
- `C` to toggle `--compact` (compact dense layout)
30+
- `A` to toggle `--animate` (render at sample rate)
31+
- `B` to cycle `--bg-glyph` through `space``dot``shade`
32+
- `P` to toggle `--pixel` (pixel-graded fractional blocks)
33+
- Left / Right arrows to decrease / increase `--sample-interval` (step ~0.1s, minimum 0.01s)
34+
- Down / Up arrows to decrease / increase `--display-interval` (step ~0.5s, minimum 0.1s)
35+
36+
- The welcome screen should be shown once at startup (or when the user changes H/V or any of the start-screen options before starting) to avoid repeated clear/write cycles that cause flicker; it is also refreshed when the console is resized.
37+
- The start screen mirrors CLI options: any configuration available via command-line flags (for example `--bg-glyph` and `--pixel`) is visible on the welcome screen and may be changed interactively before starting. This makes the tool usable both via CLI args and via the interactive start screen.
38+
- Precedence: CLI arguments (if provided) initialize the values shown on the start screen. Any changes the user makes on the start screen before starting will override the CLI-provided values for that run.
39+
40+
Notes
41+
-----
42+
43+
- Default background glyph: the app defaults to `--bg-glyph shade` (uses a light shaded block for empty cells).
44+
- Start key: the welcome screen accepts `S` or `Enter` to start monitoring.
45+
46+
Additional runtime behavior
47+
--------------------------
48+
49+
- While the app is running the user should also be able to press `H` or `V` to toggle the view mode without restarting. `S` should act as pause/resume.
50+
- The vertical view should render a stacked utilization+memory history with a percentage axis, simple time axis, and a small details table per GPU. The rendering should adapt to console width/height and use color-coded blocks and background dots for readability. In the stacked layout memory is shown above utilization within the same timestamp column.
51+
- Add a fun optional "Star Wars Mode" toggled by `W` which renders GPU lines in an animated Star Wars-style intro crawl; this must not affect the existing Horizontal/Vertical/Compact modes and should be an independent rendering path.
52+
- The default sampling interval should be `1.0` second. The default display/refresh interval should be `0.5` seconds. The vertical view may alternatively render per-timestamp bar charts (one stacked column per sample) for Util and Mem when the console width is sufficient. The vertical view renders scrolling per-timestamp bar groups with newest on the right. The view supports additional options: `--compact`, `--animate`, `--bar-char`, `--util-high`, `--util-warn`, `--bg-glyph`, and `--pixel`.
53+
54+
Default vertical view settings (should be the app defaults):
55+
56+
- `sample-interval`: `1.0` seconds
57+
- `display-interval`: `0.5` seconds
58+
- `compact`: `false`
59+
- `animate`: `false`
60+
- `bar-char`: ``
61+
- `util-high`: `90`
62+
- `util-warn`: `70`
63+
- `bg-glyph`: `shade`
64+
- `pixel`: `false`
65+
66+
Project structure the prompt should ask the Copilot to create
67+
-----------------------------------------------------------
68+
69+
- `nvsharptop.cs` (single-file top-level program) or `Program.cs` + `nvsharptop` classes — choose top-level for .NET 10 convenience.
70+
- `nvsharptop.csproj` with target framework `net10.0` and a `PackageReference` for `Spectre.Console`.
71+
- A minimal `README.md` with run and publish commands.
72+
73+
Functional contract for main components (to include in the generated code)
74+
---------------------------------------------------------------------
75+
76+
- CliParameters
77+
- Inputs: `string[] args`
78+
- Outputs: `SampleInterval` (double), `DisplayInterval` (double), `CleanupScreen` (bool)
79+
- Error modes: invalid numeric args -> fallback to defaults; `--help` prints and exits
80+
- DeviceInfo / DeviceSample / DeviceHistory
81+
- DeviceInfo: Id, Name, Temp (int), Util (int), MemUsed (int), MemTotal (int), Type enum
82+
- DeviceSample: Util (int), MemPct (int)
83+
- DeviceHistory: fixed-length queue of DeviceSample with AddSample
84+
- DeviceCollector
85+
- Reads `nvidia-smi` using `ProcessStartInfo` and `RedirectStandardOutput`
86+
- Returns `IEnumerable<DeviceInfo>`; handles missing `nvidia-smi` by returning empty list and optionally showing a message
87+
- Should trim fields and guard against parse exceptions
88+
- Renderer
89+
- Maintains per-device sample buffers, converts to history at display time (averaging samples between displays)
90+
- Computes graph width from console window width and chosen layout
91+
- Renders a graph per GPU (utilization stacked with memory) and a table with current values
92+
93+
CLI details and examples (include exact usage lines Copilot should generate)
94+
-----------------------------------------------------------------
95+
96+
- Usage examples to include in generated README and `--help` text:
97+
- `dotnet run -- nvsharptop.cs --sample-interval 0.2 --display-interval 1 --cleanup-screen false`
98+
- `dotnet publish -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true -o out`
99+
- `.\out\nvsharptop.exe --sample-interval 0.1 --display-interval 3`
100+
101+
Edge cases to handle (explicitly instruct Copilot)
102+
-----------------------------------------------
103+
104+
- No `nvidia-smi` found: print a friendly message once and keep retrying or exit with non-zero code depending on a command-line flag.
105+
- `nvidia-smi` returns malformed CSV lines: skip those lines and continue.
106+
- Zero or negative console width/height: fallback to sensible defaults.
107+
- Very small graph width: ensure code doesn't divide by zero and shows at least a minimal placeholder.
108+
- When `--cleanup-screen false` ensure console is left where the app finished without clearing.
109+
110+
Testing and validation to include in the generated repo
111+
----------------------------------------------------
112+
113+
- Small self-check in `Main` that `nvidia-smi` can be executed; if not found print instructions.
114+
- Unit-test-friendly separations: parsing `nvidia-smi` output should be in a separate method/class so tests can be added later.
115+
116+
Implementation notes for the Copilot prompt
117+
---------------------------------------
118+
119+
- Use modern C# features: top-level statements, `record` types, target-typed new, pattern matching, `Queue<T>`, `IEnumerable<T>`.
120+
- Keep the code in a single file (`nvsharptop.cs`) unless necessary; otherwise produce a small set of files as above.
121+
- Use `Spectre.Console` primitives: `Table`, `Grid`, `Markup`, and colored Markup tags.
122+
- Use `Spectre.Console` primitives: `Table`, `Grid`, `Markup`, and colored Markup tags.
123+
- Implement a welcome/start screen (interactive) that displays the current mode and instructions to start or quit.
124+
- Avoid external network calls. Read only `nvidia-smi` output locally.
125+
- Depend on `Spectre.Console` version compatible with .NET 10 (latest stable available).
126+
127+
Prompt text (paste this into GitHub Copilot or GitHub Copilot Chat)
128+
----------------------------------------------------------------
129+
130+
"""
131+
Create a .NET 10 C# console application (single-file `nvsharptop.cs` and `nvsharptop.csproj`) that monitors NVIDIA GPUs using `nvidia-smi` and renders a live terminal UI using Spectre.Console. The app must:
132+
133+
- Target `net10.0` and include a `PackageReference` to `Spectre.Console`.
134+
- Be runnable with `dotnet run nvsharptop.cs -- [args]` and publishable with `dotnet publish` as a single-file executable.
135+
- Parse command-line options `--sample-interval <seconds>` (double, default `0.1`), `--display-interval <seconds>` (double, default `3`), `--cleanup-screen <true|false>` (bool, default `true`), and `--help`/`-h`.
136+
- Parse command-line options `--sample-interval <seconds>` (double, default `1.0`), `--display-interval <seconds>` (double, default `3`), `--cleanup-screen <true|false>` (bool, default `true`), and `--help`/`-h`. Also support `--compact`, `--animate`, `--bar-char`, `--util-high`, `--util-warn`, `--bg-glyph`, and `--pixel`.
137+
- Parse command-line options `--sample-interval <seconds>` (double, default `1.0`), `--display-interval <seconds>` (double, default `3`), `--cleanup-screen <true|false>` (bool, default `true`), and `--help`/`-h`. Include additional flags: `--compact`, `--animate`, `--bar-char`, `--util-high`, `--util-warn`, `--bg-glyph`, `--pixel`.
138+
- Use `ProcessStartInfo` to run `nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,memory.used,memory.total --format=csv,noheader,nounits` and parse CSV output safely into `DeviceInfo` records.
139+
- Maintain per-device rolling history buffers and sample at `--sample-interval`, averaging samples between displays and then rendering graphs and a table on each display refresh (`--display-interval`).
140+
- Use Spectre.Console to render a visually clear live UI: per-GPU graphs (utilization + memory stacked), a table of current metrics, and a header/footer showing timestamp and refresh rate.
141+
- Handle no `nvidia-smi` gracefully (print message and exit or keep retrying) and guard against malformed lines.
142+
- Handle Ctrl+C to exit cleanly and respect `--cleanup-screen`.
143+
144+
Interactive start-screen requirements for generated app:
145+
146+
- The generated program should include an interactive welcome/start screen that mirrors the CLI-configurable options and lets the user change them prior to starting. The welcome screen should display current values for `--sample-interval`, `--display-interval`, `--compact`, `--animate`, `--bg-glyph`, and `--pixel`.
147+
- The welcome screen should accept the following keys to change options:
148+
- `C` toggle `--compact`
149+
- `A` toggle `--animate`
150+
- `B` cycle `--bg-glyph` through `space``dot``shade`
151+
- `P` toggle `--pixel`
152+
- Left / Right to decrease / increase `--sample-interval`
153+
- Down / Up to decrease / increase `--display-interval`
154+
- `S` or `Enter` to start and `Q` to quit
155+
156+
This makes the generated code usable both via CLI arguments and via the interactive start screen.
157+
158+
Include helpful inline comments, a short README explanation, and usage examples. Make functions small and testable (parsing logic separated).
159+
"""
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<PropertyGroup>
11+
<!-- Enable single-file publish and trimming when publishing (can be overridden on CLI) -->
12+
<PublishSingleFile>true</PublishSingleFile>
13+
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
14+
<SelfContained>false</SelfContained>
15+
<PublishTrimmed>false</PublishTrimmed>
16+
</PropertyGroup>
17+
18+
<ItemGroup>
19+
<!-- Spectre.Console for terminal UI (stable available on NuGet) -->
20+
<PackageReference Include="Spectre.Console" Version="0.50.0" />
21+
<!-- System.CommandLine for robust CLI parsing -->
22+
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
23+
</ItemGroup>
24+
25+
</Project>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<Solution>
2+
<Project Path="ConsoleGpuViewer.csproj" />
3+
</Solution>

0 commit comments

Comments
 (0)