/** One JSONL record = one benchmark run on a given date/host/hardware. */ export interface BenchmarkRecord { /** ISO date string, e.g. "2025-10-01" (required). */ date: string /** Machine / environment name, e.g. "aws-g5-xlarge" (required). */ host: string /** Hardware description, e.g. "NVIDIA A10G 24GB" (required). */ hardware: string /** Any other string fields (backend, quantization, ...) are kept as tags. */ tags: Record /** Numeric metric values from the record's "metrics" object (or top-level numbers). */ metrics: Record } export interface Dataset { /** File name without extension, used as the benchmark display name. */ name: string /** Benchmark category, from its data/ subfolder ("models", "kernels", ...). */ category: string records: BenchmarkRecord[] } export interface Filters { /** Inclusive lower date bound; EMPTY = unbounded (never pins out new runs). */ dateFrom: string /** Inclusive upper date bound; EMPTY = unbounded (never pins out new runs). */ dateTo: string hosts: string[] hardware: string[] /** Dynamic per-tag filtering: tag key -> selected values (empty = all). */ tags: Record } /** Sentinel facet value for records that lack a tag entirely. */ export const NONE_VALUE = '(none)' /** One selectable facet value with its count under the current selections. */ export interface FacetValue { /** Raw value used in Filters.tags selections, or NONE_VALUE. */ value: string /** Display label (commit hashes abbreviated, etc.). */ label: string /** Records matching the OTHER filter groups' current selections. */ count: number /** Whether this value is currently selected in its group. */ selected: boolean } /** One chip group (hosts / hardware / a tag key) with facet counts. */ export interface FacetGroup { /** "hosts" | "hardware" | "tag:" — matches FilterScope. */ key: string /** Display label for the group ("Host", "quantization", ...). */ label: string values: FacetValue[] /** Number of selected values in this group (0 = group cleared = All). */ selectedCount: number /** Records matching all OTHER groups (count shown on the 'All' chip). */ allCount: number } /** Addressable filter constraint groups. */ export type FilterScope = 'dates' | 'hosts' | 'hardware' | `tag:${string}` /** A constraint that is (partly) responsible for a zero-match filter result. */ export interface FilterBlocker { /** FilterScope, or 'all' when only the combination blocks. */ key: string /** Short group name used on recovery buttons ("dates", "hosts", ...). */ label: string /** Human-readable reason, e.g. "date range 2026-10-29..2026-10-30 has no data". */ detail: string } export const METRIC_LABELS: Record = { throughput_tps: 'Throughput (tokens/s)', latency_ms: 'Latency (ms)', ttft_ms: 'Time to first token (ms)', memory_mb: 'Memory (MB)', duration_ms: 'Kernel duration (ms)', bandwidth_gbs: 'Bandwidth (GB/s)', tflops: 'Compute (TFLOPS)', } /** Lower-is-better metrics get inverted delta colors. */ export const LOWER_IS_BETTER = new Set(['latency_ms', 'ttft_ms', 'memory_mb', 'duration_ms']) export function metricLabel(key: string): string { // Shape dimensions (shape.seq) display under their short name ("seq"). return METRIC_LABELS[key] ?? key.replace(/^shape\./, '').replace(/_/g, ' ') } export function formatMetric(key: string, value: number): string { if (key.endsWith('_mb') && value >= 1024) return `${(value / 1024).toFixed(1)} GB` return value >= 100 ? value.toFixed(0) : value.toFixed(1) }