// gpu-bench's results file: what gpu-bench writes, and what mcap's GPU Benchmark window reads to put // several machines side by side. Plain text, one fact a line: // // gpu-bench 1 // machine: NAME a header line: key, colon, value // ... // model: ocr/ppocr-v5-mobile 1a2b... the fingerprint of the files a task's model is made of // result: ocr/ppocr-v5-mobile CUDA ms_per_image=12.3 images_per_s=81.2 ... // // Two results are comparable only when their corpus line (the images) and each task's model line // match; the window marks them where they do not. BENCH_RESULTS_FORMAT :: "gpu-bench 1"; Bench_Pair :: struct { key, value: string; } Bench_Row :: struct { task: string; // ocr/ppocr-v5-mobile, labels/siglip2-base-patch16-384, segment/... provider: string; // CUDA or CPU fields: [..] Bench_Pair; } Bench_Report :: struct { path: string; header: [..] Bench_Pair; // in the file's order; model lines too, as "model ocr/x" -> hash rows: [..] Bench_Row; } bench_header :: (report: *Bench_Report, key: string) -> string { for report.header if it.key == key return it.value; return ""; } bench_field :: (row: *Bench_Row, key: string) -> string { for row.fields if it.key == key return it.value; return ""; } bench_row :: (report: *Bench_Report, task: string, provider: string) -> *Bench_Row { for * report.rows if it.task == task && it.provider == provider return it; return null; } // A results file, or ok false and why; from the context allocator. bench_parse :: (text: string, path := "") -> Bench_Report, ok: bool, error: string { report: Bench_Report; report.path = copy_string(path); lines := split(text, "\n",, temp); if !lines.count || trim(lines[0]) != BENCH_RESULTS_FORMAT return report, false, tprint("% is not a gpu-bench results file (no \"%\" on its first line).", path, BENCH_RESULTS_FORMAT); for raw: lines { if it_index == 0 continue; line := trim(raw); if !line.count || line[0] == #char "#" continue; colon := find_index_from_left(line, #char ":"); if colon < 0 continue; key := trim(slice(line, 0, colon)); value := trim(advance(line, colon + 1)); if key == "result" { parts := split(value, " ",, temp); if parts.count < 2 continue; row := array_add(*report.rows); row.* = .{task = copy_string(parts[0]), provider = copy_string(parts[1])}; for 2..parts.count - 1 { part := parts[it]; equals := find_index_from_left(part, #char "="); if equals < 0 continue; array_add(*row.fields, .{copy_string(slice(part, 0, equals)), copy_string(advance(part, equals + 1))}); } } else if key == "model" { space := find_index_from_left(value, #char " "); if space < 0 continue; array_add(*report.header, .{tprint("model %", slice(value, 0, space),, context.allocator), copy_string(trim(advance(value, space + 1)))}); } else { array_add(*report.header, .{copy_string(key), copy_string(value)}); } } return report, true, ""; } bench_report_free :: (report: *Bench_Report) { free(report.path); for report.header { free(it.key); free(it.value); } array_free(report.header); for * report.rows { free(it.task); free(it.provider); for it.fields { free(it.key); free(it.value); } array_free(it.fields); } array_free(report.rows); report.* = .{}; }