bin/gpu-bench times every GPU model (OCR mobile and server, the label image encoder, segmentation; optionally the CPU and the label text encoder) over a fixed 30-image corpus in tools/gpu_bench/corpus. Every corpus file is checked against corpus.txt's SHA-256 before anything runs; each model's files and models.config entry are fingerprinted; the GPU, driver, power limit, CUDA runtime, cuDNN and onnxruntime are recorded, and NVML samples memory, load, power and clocks during the timed passes. Results go to bin/gpu-bench-results as text files. The GPU Bench button opens a window that runs gpu-bench in its own process (no console) and lays results files from several machines side by side against a baseline, marking a different corpus or model.
130 lines
5.8 KiB
Plaintext
130 lines
5.8 KiB
Plaintext
// The app's own UI: the capture viewer (app/viewer.jai). Everything else in src/ is the shell
|
|
// around it: the window, the frame loop, the tray, hotkeys, settings, themes, logging and the
|
|
// debug panels.
|
|
|
|
APP_MAIN_WINDOW_LABEL :: "Main";
|
|
|
|
// Once, after ImGui, the fonts, the theme and the settings are up and before the first frame.
|
|
app_ui_startup :: () {
|
|
// View mode (app/open_file.jai): the file alone. The library is not listed, and no model, scan,
|
|
// watcher or recording starts.
|
|
if app.view_mode {
|
|
import_startup();
|
|
open_file_startup();
|
|
return;
|
|
}
|
|
viewer_startup();
|
|
import_startup();
|
|
ocr_ui_startup();
|
|
labels_ui_startup();
|
|
segment_ui_startup(); // the library folders' options: after the viewer, which knows the library
|
|
screen_record_startup(); // recordings a crash left behind, to offer
|
|
open_file_startup(); // mcap.exe FILE: after the viewer, which knows whether it is in the library
|
|
}
|
|
|
|
// Every frame, before input is handed to ImGui. Poll background work here.
|
|
app_ui_frame_start :: () {
|
|
if app.view_mode return;
|
|
screen_capture_frame(); // also while hidden in the tray, where the frame ends before the UI
|
|
ocr_ui_unload_idle_models(); // models unused for a while, also while in the tray
|
|
}
|
|
|
|
// Once, on the shutdown thread after the window is asked to close (exit_shutdown.jai): save and
|
|
// stop background work here. Must not touch ImGui, since the main thread is still drawing frames
|
|
// (the overlay; app_main_window_ui stops running the app's frames once shutdown starts).
|
|
app_ui_shutdown :: () {
|
|
if app.view_mode {
|
|
app_shutdown_step(.IMPORT);
|
|
import_shutdown();
|
|
open_file_shutdown();
|
|
return;
|
|
}
|
|
gpu_bench_ui_shutdown(); // ends a benchmark run still going
|
|
app_shutdown_step(.CAPTURE);
|
|
screen_capture_shutdown();
|
|
app_shutdown_step(.IMPORT);
|
|
import_shutdown(); // before the viewer: it hands the viewer what it writes
|
|
app_shutdown_step(.VIEWER);
|
|
viewer_shutdown();
|
|
app_shutdown_step(.OCR);
|
|
ocr_ui_shutdown();
|
|
app_shutdown_step(.SEGMENT);
|
|
segment_ui_shutdown(); // after the OCR thread, which runs its scans
|
|
app_shutdown_step(.LABELS);
|
|
labels_ui_shutdown(); // after the OCR thread and the background workers have stopped
|
|
app_shutdown_step(.STATS);
|
|
stats_ui_shutdown();
|
|
open_file_shutdown();
|
|
}
|
|
|
|
// Which step of app_ui_shutdown is running, and since when, for the overlay a slow shutdown shows.
|
|
App_Shutdown_Step :: enum s32 { NONE; CAPTURE; IMPORT; VIEWER; OCR; SEGMENT; LABELS; STATS; }
|
|
app_shutdown: struct {
|
|
step: App_Shutdown_Step;
|
|
step_started_ns: s64; // monotonic
|
|
}
|
|
|
|
app_shutdown_step :: (step: App_Shutdown_Step) {
|
|
atomic_write(*app_shutdown.step_started_ns, to_nanoseconds(current_time_monotonic()));
|
|
atomic_write(*app_shutdown.step, step);
|
|
}
|
|
|
|
// Main thread, while app_ui_shutdown runs: what it is waiting on, as a line or two for the overlay
|
|
// (temp); "" before it has started a step.
|
|
app_ui_shutdown_status :: () -> string {
|
|
step := atomic_read(*app_shutdown.step);
|
|
text: string;
|
|
if step == {
|
|
case .NONE; return "";
|
|
case .CAPTURE; text = "Saving a screen capture.";
|
|
case .IMPORT;
|
|
if importer.phase == .INDEXING text = "Stopping the import: it is indexing the library, and stops after the files it is on.";
|
|
else if importer.running text = "Stopping the import: finishing the files it is on (a large video takes a while to copy).";
|
|
else text = "Stopping the import.";
|
|
case .VIEWER;
|
|
text = "Stopping the thumbnail, catalog and search workers";
|
|
if viewer.open_started text = tprint("%, and writing out % to play", text, viewer.open_name);
|
|
text = tprint("%.", text);
|
|
case .OCR;
|
|
text = "Closing the OCR model.";
|
|
if ocr_ui.thread_busy if ocr_ui.task.kind == {
|
|
case .SCAN; text = "Stopping the OCR scan: finishing the text lines it is reading.";
|
|
case .ERASE; text = "Stopping the erase: finishing the capture it is on.";
|
|
case .READ; text = "Waiting for OCR to finish reading a capture.";
|
|
case .CREATE; text = "Waiting for the OCR model to finish loading.";
|
|
case .LABELS_CREATE; text = "Waiting for the label model to finish loading.";
|
|
case .LABEL_SET; text = "Waiting for the label list to finish.";
|
|
case .SEGMENT; text = "Stopping the segmentation scan: finishing the images it is segmenting.";
|
|
case .UNLOAD; text = "Waiting for the models unused for a while to unload.";
|
|
case; text = "Stopping OCR.";
|
|
}
|
|
case .SEGMENT; text = "Closing the segmentation model.";
|
|
case .LABELS; text = "Closing the label model.";
|
|
case .STATS; text = "Closing Stats.";
|
|
}
|
|
waited := cast(float64) (to_nanoseconds(current_time_monotonic()) - atomic_read(*app_shutdown.step_started_ns)) / 1_000_000_000.0;
|
|
if waited >= 2 text = tprint("%\n(this step: % s)", text, FormatFloat.{value = waited, trailing_width = 0, zero_removal = .NO});
|
|
return text;
|
|
}
|
|
|
|
app_main_window_ui :: () {
|
|
if app.view_mode {
|
|
if !app_exit_shutdown_started() open_file_view_mode_ui(); // the whole window (app/open_file.jai)
|
|
return;
|
|
}
|
|
push_imgui_window(APP_MAIN_WINDOW_LABEL);
|
|
// Once shutdown has started, its thread is stopping the threads these frames hand work to and take
|
|
// it from (the viewer's workers, the search group, the import, OCR), and freeing what they share:
|
|
// running them now would race it. The exit overlay says what it is waiting on.
|
|
if app_exit_shutdown_started() return;
|
|
viewer_ui();
|
|
ocr_ui_frame();
|
|
labels_ui_frame();
|
|
segment_ui_frame();
|
|
stats_ui_frame();
|
|
gpu_bench_ui_frame(); // app/gpu_bench_ui.jai
|
|
import_frame();
|
|
open_file_frame(); // after import_frame, which hands the grid what an import of it wrote
|
|
screen_record_leftovers_popup();
|
|
}
|