diff --git a/docs/_extensions/isaaclab_docs.py b/docs/_extensions/isaaclab_docs.py index 0f6a61a92084..2de7ac4e2b63 100644 --- a/docs/_extensions/isaaclab_docs.py +++ b/docs/_extensions/isaaclab_docs.py @@ -7,6 +7,7 @@ from __future__ import annotations +import csv import inspect import json import posixpath @@ -84,6 +85,22 @@ def _parse_rst(directive: SphinxDirective, content: str) -> list[nodes.Node]: return container.children +class IsaacLabBenchmarkData(SphinxDirective): + """Embed benchmark snapshots so downloaded HTML works without an HTTP server.""" + + def run(self) -> list[nodes.Node]: + snapshots = {} + for channel in ("release", "develop"): + path = Path(self.env.srcdir) / "source/_static/benchmarks" / f"environment-performance-{channel}.csv" + self.env.note_dependency(str(path)) + with path.open(encoding="utf-8", newline="") as stream: + snapshots[channel] = list(csv.DictReader(stream)) + # Prevent CSV text from closing the script element, even inside a JSON string. + payload = json.dumps(snapshots).replace("<", "\\u003c") + html = f'' + return [nodes.raw("", html, format="html")] + + class IsaacLabCloneCommands(SphinxDirective): """Render SSH/HTTPS clone tabs using copy-friendly ``code-block`` directives.""" @@ -283,6 +300,7 @@ def setup(app): app.add_config_value("torchvision_version", "", "env") app.add_config_value("ovrtx_spec", "", "env") app.add_role("isaaclab-source", IsaacLabSourceLink()) + app.add_directive("isaaclab-benchmark-data", IsaacLabBenchmarkData) app.add_directive("isaaclab-clone-commands", IsaacLabCloneCommands) app.add_directive("isaaclab-clone-https", IsaacLabCloneHttps) app.add_directive("isaaclab-uv-isaacsim-wheel-install", IsaacLabUvIsaacSimWheelInstall) diff --git a/docs/source/_static/css/environment-browser.js b/docs/source/_static/css/environment-browser.js index 567d87999296..fdbdb2a292ee 100644 --- a/docs/source/_static/css/environment-browser.js +++ b/docs/source/_static/css/environment-browser.js @@ -642,32 +642,6 @@ updateSelection(); }; - const parseCsv = (contents) => { - const parseLine = (line) => { - const values = []; - let value = ""; - let quoted = false; - for (let index = 0; index < line.length; index += 1) { - const character = line[index]; - if (character === '"' && quoted && line[index + 1] === '"') { - value += '"'; - index += 1; - } else if (character === '"') { - quoted = !quoted; - } else if (character === "," && !quoted) { - values.push(value); - value = ""; - } else { - value += character; - } - } - values.push(value); - return values; - }; - const [header, ...lines] = contents.trim().split(/\r?\n/).map(parseLine); - return lines.map((line) => Object.fromEntries(header.map((name, index) => [name, line[index]]))); - }; - const formatFps = (value) => { if (value >= 1_000_000) { return `${Number((value / 1_000_000).toFixed(2))}M`; @@ -931,18 +905,14 @@ chart.replaceChildren(...(rows.length ? [renderBenchmarkChart(rows, maximum)] : [])); }; - const renderBenchmarks = async () => { + const renderBenchmarks = () => { if (!benchmarks) { return; } - benchmarkRows = (await Promise.all(["release", "develop"].map(async (channel) => { + const snapshots = JSON.parse(document.querySelector("[data-environment-benchmark-rows]").textContent); + benchmarkRows = ["release", "develop"].flatMap((channel) => { try { - const source = new URL(benchmarks.getAttribute(`data-benchmark-${channel}-source`), window.location.href); - const response = await fetch(source); - if (!response.ok) { - throw new Error(`Benchmark request failed with ${response.status}`); - } - return parseCsv(await response.text()) + return snapshots[channel] .filter((row) => row.data_origin === "measured" && row.workload === "training") .filter((row) => [row.collection_fps_mean, row.total_fps_mean] .every((value) => Number.isFinite(Number(value)) && Number(value) > 0)) @@ -955,7 +925,7 @@ console.error(error); return []; } - }))).flat(); + }); updatePreview(); }; diff --git a/docs/source/setup/environments.rst b/docs/source/setup/environments.rst index c19f7f280062..400287c4ef9b 100644 --- a/docs/source/setup/environments.rst +++ b/docs/source/setup/environments.rst @@ -102,11 +102,11 @@ Task Preview Benchmarks ---------- +.. isaaclab-benchmark-data:: + .. raw:: html