GitHub Actions commited on
Commit
ecef386
·
1 Parent(s): 48fe3e6

sync from abhijitramesh/webgpu-bench@0e0f399c06

Browse files
Files changed (4) hide show
  1. js/app.js +3 -2
  2. js/charts.js +8 -6
  3. js/data.js +23 -0
  4. js/tables.js +5 -1
js/app.js CHANGED
@@ -1,4 +1,4 @@
1
- import { loadData, filterResults, selectBestResults } from './data.js';
2
  import { initFilters, populateQuantOptions, getFilters, resetFilters } from './filters.js';
3
  import { renderDecodeChart, renderPrefillChart, renderSizeChart, renderMachineChart, renderCpuGpuChart, renderSpeedupChart } from './charts.js';
4
  import { renderResultsTable, renderErrorTable, renderMachineInfo, renderCpuGpuTable } from './tables.js';
@@ -148,7 +148,8 @@ function renderCpuGpuSection(filtered, metric) {
148
  const chartsGrid = document.querySelector('#performance-section .charts-grid:nth-of-type(2)');
149
  const table = document.getElementById('cpu-gpu-table');
150
  const passed = filtered.filter(r => r.status === 'done');
151
- const cpuResults = passed.filter(r => r.nGpuLayers === 0);
 
152
  const gpuResults = passed.filter(r => r.nGpuLayers !== 0);
153
 
154
  if (!chartsGrid || !table) {
 
1
+ import { loadData, filterResults, selectBestResults, expandCpuRows } from './data.js';
2
  import { initFilters, populateQuantOptions, getFilters, resetFilters } from './filters.js';
3
  import { renderDecodeChart, renderPrefillChart, renderSizeChart, renderMachineChart, renderCpuGpuChart, renderSpeedupChart } from './charts.js';
4
  import { renderResultsTable, renderErrorTable, renderMachineInfo, renderCpuGpuTable } from './tables.js';
 
148
  const chartsGrid = document.querySelector('#performance-section .charts-grid:nth-of-type(2)');
149
  const table = document.getElementById('cpu-gpu-table');
150
  const passed = filtered.filter(r => r.status === 'done');
151
+ // Same expansion the chart/table renderers do — see expandCpuRows().
152
+ const cpuResults = expandCpuRows(passed);
153
  const gpuResults = passed.filter(r => r.nGpuLayers !== 0);
154
 
155
  if (!chartsGrid || !table) {
js/charts.js CHANGED
@@ -1,4 +1,5 @@
1
  import { BROWSER_COLORS, quantSortKey, groupBy, formatTokS } from './utils.js';
 
2
 
3
  // Global Chart.js theme — uses the site's font tokens and a calm tooltip
4
  // silhouette. Colors are pulled from CSS variables at render time so the
@@ -255,9 +256,10 @@ export function renderCpuGpuChart(results, metric = 'decode_tok_s') {
255
  const canvas = document.getElementById(canvasId);
256
  if (!canvas) return;
257
 
258
- const passed = results.filter(r => r.status === 'done' && r[metric] != null);
259
- const cpuResults = passed.filter(r => r.nGpuLayers === 0);
260
- const gpuResults = passed.filter(r => r.nGpuLayers !== 0);
 
261
 
262
  if (cpuResults.length === 0 || gpuResults.length === 0) {
263
  showEmptyState(canvas, cpuResults.length === 0 ? 'No CPU baseline data in current filter' : 'No GPU data in current filter');
@@ -311,9 +313,9 @@ export function renderSpeedupChart(results, metric = 'decode_tok_s') {
311
  const canvas = document.getElementById(canvasId);
312
  if (!canvas) return;
313
 
314
- const passed = results.filter(r => r.status === 'done' && r[metric] != null);
315
- const cpuResults = passed.filter(r => r.nGpuLayers === 0);
316
- const gpuResults = passed.filter(r => r.nGpuLayers !== 0);
317
 
318
  if (cpuResults.length === 0 || gpuResults.length === 0) {
319
  showEmptyState(canvas, cpuResults.length === 0 ? 'No CPU baseline data in current filter' : 'No GPU data in current filter');
 
1
  import { BROWSER_COLORS, quantSortKey, groupBy, formatTokS } from './utils.js';
2
+ import { expandCpuRows } from './data.js';
3
 
4
  // Global Chart.js theme — uses the site's font tokens and a calm tooltip
5
  // silhouette. Colors are pulled from CSS variables at render time so the
 
256
  const canvas = document.getElementById(canvasId);
257
  if (!canvas) return;
258
 
259
+ const passed = results.filter(r => r.status === 'done');
260
+ // expandCpuRows folds in cpu_baseline_* from browser-flow GPU records.
261
+ const cpuResults = expandCpuRows(passed).filter(r => r[metric] != null);
262
+ const gpuResults = passed.filter(r => r.nGpuLayers !== 0 && r[metric] != null);
263
 
264
  if (cpuResults.length === 0 || gpuResults.length === 0) {
265
  showEmptyState(canvas, cpuResults.length === 0 ? 'No CPU baseline data in current filter' : 'No GPU data in current filter');
 
313
  const canvas = document.getElementById(canvasId);
314
  if (!canvas) return;
315
 
316
+ const passed = results.filter(r => r.status === 'done');
317
+ const cpuResults = expandCpuRows(passed).filter(r => r[metric] != null);
318
+ const gpuResults = passed.filter(r => r.nGpuLayers !== 0 && r[metric] != null);
319
 
320
  if (cpuResults.length === 0 || gpuResults.length === 0) {
321
  showEmptyState(canvas, cpuResults.length === 0 ? 'No CPU baseline data in current filter' : 'No GPU data in current filter');
js/data.js CHANGED
@@ -155,6 +155,29 @@ export function selectBestResults(records) {
155
  return [...bestByCell.values()];
156
  }
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  export function filterResults(results, filters) {
159
  return results.filter(r => {
160
  if (filters.machine && filters.machine !== 'all' && r.machineSlug !== filters.machine) return false;
 
155
  return [...bestByCell.values()];
156
  }
157
 
158
+ /* Synthesize "CPU only" rows for the CPU-vs-GPU views.
159
+ Two record sources contribute:
160
+ 1) Real CPU runs (nGpuLayers === 0) — produced by the CLI runner which
161
+ alternates CPU and GPU passes.
162
+ 2) The cpu_baseline_* fields on every browser-flow record — the in-page
163
+ bench measures one CPU pass per variant alongside the GPU iterations
164
+ and stamps the result on the same record. We turn each of those into
165
+ a synthetic CPU row so the comparison view sees both data shapes.
166
+ */
167
+ export function expandCpuRows(results) {
168
+ const real = results.filter(r => r.nGpuLayers === 0);
169
+ const synthetic = results
170
+ .filter(r => r.nGpuLayers !== 0
171
+ && (r.cpu_baseline_decode_tok_s != null || r.cpu_baseline_prefill_tok_s != null))
172
+ .map(r => ({
173
+ ...r,
174
+ decode_tok_s: r.cpu_baseline_decode_tok_s,
175
+ prefill_tok_s: r.cpu_baseline_prefill_tok_s,
176
+ nGpuLayers: 0,
177
+ }));
178
+ return [...real, ...synthetic];
179
+ }
180
+
181
  export function filterResults(results, filters) {
182
  return results.filter(r => {
183
  if (filters.machine && filters.machine !== 'all' && r.machineSlug !== filters.machine) return false;
js/tables.js CHANGED
@@ -1,4 +1,5 @@
1
  import { formatTokS, formatMs, categorizeError, groupBy, quantSortKey } from './utils.js';
 
2
 
3
  let lastResults = [];
4
  let sortState = { key: null, dir: 'asc' };
@@ -302,7 +303,10 @@ export function renderCpuGpuTable(results) {
302
  ];
303
 
304
  const passed = results.filter(r => r.status === 'done');
305
- const cpuResults = passed.filter(r => r.nGpuLayers === 0);
 
 
 
306
  const gpuResults = passed.filter(r => r.nGpuLayers !== 0);
307
 
308
  if (cpuResults.length === 0 || gpuResults.length === 0) {
 
1
  import { formatTokS, formatMs, categorizeError, groupBy, quantSortKey } from './utils.js';
2
+ import { expandCpuRows } from './data.js';
3
 
4
  let lastResults = [];
5
  let sortState = { key: null, dir: 'asc' };
 
303
  ];
304
 
305
  const passed = results.filter(r => r.status === 'done');
306
+ // CPU side aggregates standalone CPU runs (nGpuLayers === 0) plus
307
+ // synthetic rows derived from the cpu_baseline_* fields on browser-flow
308
+ // GPU records. See expandCpuRows() in data.js.
309
+ const cpuResults = expandCpuRows(passed);
310
  const gpuResults = passed.filter(r => r.nGpuLayers !== 0);
311
 
312
  if (cpuResults.length === 0 || gpuResults.length === 0) {