document.addEventListener("DOMContentLoaded", async () => { const statsLine = document.getElementById("stats-line"); const table = document.getElementById("mtp-table"); const tbody = document.getElementById("mtp-tbody"); try { const res = await fetch("mtp-summary.json"); if (!res.ok) throw new Error("Network response was not ok"); const data = await res.json(); renderTable(data, tbody); table.classList.remove("hidden"); statsLine.textContent = `Showing ${data.length} benchmark runs`; } catch (err) { console.error("Failed to load mtp-summary.json", err); statsLine.textContent = "Failed to load mtp-summary.json. Ensure the file is present in the docs folder."; } }); function renderTable(runs, tbody) { // Group by model and toolbox const grouped = new Map(); runs.forEach(run => { const key = `${run.model}|${run.toolbox}`; if (!grouped.has(key)) { grouped.set(key, { model: run.model, toolbox: run.toolbox, baseline: null, mtp2: null, mtp3: null }); } const entry = grouped.get(key); if (run.mode === "baseline") entry.baseline = run; if (run.mode === "mtp-2") entry.mtp2 = run; if (run.mode === "mtp-3") entry.mtp3 = run; }); const rows = Array.from(grouped.values()).sort((a, b) => { if (a.model !== b.model) return a.model.localeCompare(b.model); return a.toolbox.localeCompare(b.toolbox); }); tbody.innerHTML = ""; rows.forEach(row => { const tr = document.createElement("tr"); tr.className = "main-row"; // Model const tdModel = document.createElement("td"); tdModel.className = "model"; const modelHead = document.createElement("div"); modelHead.className = "model-head"; const nameSpan = document.createElement("span"); nameSpan.className = "model-name"; nameSpan.textContent = row.model; modelHead.appendChild(nameSpan); tdModel.appendChild(modelHead); tr.appendChild(tdModel); // Toolbox const tdToolbox = document.createElement("td"); const tbPill = document.createElement("span"); tbPill.className = "toolbox-pill"; if (row.toolbox.includes("vulkan") || row.toolbox.includes("radv")) { tbPill.classList.add("radv"); } tbPill.textContent = row.toolbox; tdToolbox.appendChild(tbPill); tr.appendChild(tdToolbox); // Baseline const baseSpeed = row.baseline ? row.baseline.avg_tok_s : null; tr.appendChild(makeMetricCell(baseSpeed)); // MTP-2 const mtp2Speed = row.mtp2 ? row.mtp2.avg_tok_s : null; tr.appendChild(makeMetricCell(mtp2Speed)); tr.appendChild(makeSpeedupCell(baseSpeed, mtp2Speed)); // MTP-3 const mtp3Speed = row.mtp3 ? row.mtp3.avg_tok_s : null; tr.appendChild(makeMetricCell(mtp3Speed)); tr.appendChild(makeSpeedupCell(baseSpeed, mtp3Speed)); // Details row const detailsTr = document.createElement("tr"); detailsTr.className = "details-row hidden"; const detailsTd = document.createElement("td"); detailsTd.colSpan = 8; detailsTd.innerHTML = makeDetailsHTML(row); detailsTr.appendChild(detailsTd); tr.addEventListener("click", () => { tr.classList.toggle("expanded"); detailsTr.classList.toggle("hidden"); }); tbody.appendChild(tr); tbody.appendChild(detailsTr); }); } function makeMetricCell(val) { const td = document.createElement("td"); td.className = "metric-col"; if (val !== null && val !== undefined) { td.innerHTML = `${val.toFixed(1)}`; } else { td.innerHTML = ``; } return td; } function makeSpeedupCell(base, mtp) { const td = document.createElement("td"); td.className = "metric-col"; if (base && mtp && base > 0) { const ratio = mtp / base; const badge = document.createElement("span"); badge.className = "speedup-badge"; badge.textContent = `${ratio.toFixed(2)}×`; if (ratio >= 1.8) { badge.classList.add("speedup-high"); } else if (ratio >= 1.3) { badge.classList.add("speedup-med"); } else { badge.classList.add("speedup-low"); } td.appendChild(badge); } else { td.innerHTML = ``; } return td; } function makeDetailsHTML(row) { if (!row.baseline || !row.baseline.results || row.baseline.results.length === 0) { return `

Granular data not available for this run. Re-run benchmarks to capture prompt-level metrics.

`; } const tasks = new Map(); const modes = [ { key: "base", data: row.baseline }, { key: "mtp2", data: row.mtp2 }, { key: "mtp3", data: row.mtp3 } ]; modes.forEach(mode => { if (!mode.data || !mode.data.results) return; mode.data.results.forEach(res => { if (!tasks.has(res.name)) { tasks.set(res.name, { name: res.name }); } const t = tasks.get(res.name); t[`${mode.key}_prefill`] = res.prompt_per_second; t[`${mode.key}_toks`] = res.predicted_per_second; t[`${mode.key}_acc`] = res.accept_rate; }); }); let html = `
`; tasks.forEach(t => { const p_base_val = t.base_prefill; const p_mtp2_val = t.mtp2_prefill; const p_mtp3_val = t.mtp3_prefill; const p_base = p_base_val ? p_base_val.toFixed(1) : "—"; let p_mtp2 = p_mtp2_val ? p_mtp2_val.toFixed(1) : "—"; let p_mtp3 = p_mtp3_val ? p_mtp3_val.toFixed(1) : "—"; if (p_base_val && p_mtp2_val) { const pct = ((p_mtp2_val - p_base_val) / p_base_val) * 100; const color = pct >= 0 ? '#16a34a' : '#dc2626'; const sign = pct > 0 ? '+' : ''; p_mtp2 += ` ${sign}${pct.toFixed(1)}%`; } if (p_base_val && p_mtp3_val) { const pct = ((p_mtp3_val - p_base_val) / p_base_val) * 100; const color = pct >= 0 ? '#16a34a' : '#dc2626'; const sign = pct > 0 ? '+' : ''; p_mtp3 += ` ${sign}${pct.toFixed(1)}%`; } const g_base = t.base_toks ? t.base_toks.toFixed(1) : "—"; const g_mtp2 = t.mtp2_toks ? t.mtp2_toks.toFixed(1) : "—"; const a_mtp2 = t.mtp2_acc !== null && t.mtp2_acc !== undefined ? (t.mtp2_acc * 100).toFixed(1) + "%" : "—"; const g_mtp3 = t.mtp3_toks ? t.mtp3_toks.toFixed(1) : "—"; const a_mtp3 = t.mtp3_acc !== null && t.mtp3_acc !== undefined ? (t.mtp3_acc * 100).toFixed(1) + "%" : "—"; html += ` `; }); html += `
Prompt Task Prefill (Base) Prefill (MTP-2) Prefill (MTP-3) Base Gen MTP-2 Gen Acc% MTP-3 Gen Acc%
${t.name} ${p_base} ${p_mtp2} ${p_mtp3} ${g_base} ${g_mtp2} ${a_mtp2} ${g_mtp3} ${a_mtp3}
`; return html; }