cuda-viz — animated GPU/CUDA diagrams
This skill produces animated explainer diagrams in one specific, deliberate visual
style (v2 dark blueprint: dashed double-border boxes, translucent fills, a
single-stroke serpentine texture for activity, blue comet packets for data in
motion — red = working, green = at rest, blue = in flight, chalk Archivo text). The user's audience
recognizes this style across posts — consistency is the whole point. Do not
freestyle visuals, colors, or motion outside the system defined here.
Two colorways exist, same anatomy and rules in both: the default dark
blueprint and a light "paper" variant (white paper, ink text, pastel role
hues) for embedding in light pages. Dark is the default; use light only when the
user asks for it or the destination is a light-background page. See "Light
colorway" below.
Where this skill lives
This skill directory IS a git repo whose remote is https://github.com/maxxfuu/cudaviz-skill
(branch main). Push there and only there — never create a new repo for it, and
never commit it into the repo of whatever project a diagram was authored for.
Push the skill, never the product. What belongs in this repo is the reusable
craft: library primitives and fixes, design rules, API docs, scripts, and lessons
learned while making a diagram. What must NEVER be committed here is the output —
diagram HTML, dist/ builds, mp4s, stills. Those are deliverables and stay in the
user's working directory. After finishing a diagram, ask what the session actually
taught (a bug fixed in lib.js, a rule that was missing from design-rules.md,
a new primitive), commit THAT, and leave the artwork behind.
Files in this skill
assets/lib.js — the component library (global CV). Read it once per session; it's short. v0.2 adds the CUDA-glyph vocabulary: thread (squiggly-arrow), threadBlock (morphable block of threads), dataCell (value cell with texture + plate), ring (full-border sliding selector), chipLegs/edgeConnector (hardware icon trims).
assets/theme.css — palette variables (dark default + light "paper" colorway) + player controls styling.
assets/template.html — starting scaffold for every new diagram.
references/design-rules.md — the visual law: palette, box anatomy, hatching, connectors, typography. Read before drawing anything.
references/api.md — full API, timeline patterns, composition recipes, sizing norms. Read before writing code.
examples/kernel-launch.html — canonical finished diagram (kernel launch → block scheduling → SIMT execution). Study it when structuring a new piece; it demonstrates every pattern.
examples/grid-block-thread.html — canonical multi-act diagram (grid → blocks → threads → one-thread dot-product trace → parallel finale). Demonstrates the v0.2 vocabulary and the multi-act patterns in api.md: transform-group morphing, guarded late tracks, sliding ring highlights, deterministic churn, bounce emphasis. (Its thread/block/cell code predates the v0.2 factories and inlines them — new diagrams should call CV.thread/CV.threadBlock/CV.dataCell/CV.ring instead.)
scripts/capture.py — keyframe stills / frame sequences / --video out.mp4.
scripts/capture.js — Node port of capture.py (identical CLI); use where Python lacks Playwright. Node resolves modules from the SCRIPT's directory, not the cwd, so after npm i playwright in a scratch dir run it as NODE_PATH=$PWD/node_modules node …/capture.js diagram.html …. The browsers under ~/.cache/ms-playwright are shared, so only the language binding ever needs installing.
scripts/build.py — inline the assets into a self-contained deliverable HTML.
Workflow
Layout and animation are separate problems; mixing them wastes iterations. Work in
this order:
Plan the story. Decide the 3–6 phases the animation narrates (e.g. launch →
schedule → execute → complete) and which components each phase touches. A loop
is 8–15s. Decide component colors by role: red (compute) = work happening now +
accent annotations, green (memory) = data at rest, neutral gray = passive
structure, blue (traffic) = data in motion ONLY — when a packet lands, its
blue becomes the destination's green state (the phase-change rule).
Static composition first. Copy template.html, place every component with
the CV primitives at final coordinates, including connectors, hidden routing
paths, and elements that will start invisible. Leave ≥40px channels between
components — particles route through channels, never over boxes. Then capture
one frame and actually look at it:
python3 scripts/capture.py diagram.html --times 0.5 --out /tmp/check
Fix spacing, alignment, and label centering now, before any motion exists.
Animate on the timeline. Add tracks per phase. Every track is a pure
function of (p, t) — the patterns (and the three bugs this prevents) are in
references/api.md. Reuse the proven verbs: particle flights, hatch-on-active,
warp-row pulsing with per-component phase offsets, staged waves, windowed
annotations.
Verify like a reviewer. Capture stills at each phase boundary and inspect
them against design-rules.md. Common regressions: labels not centered in
their header band, particles crossing a component, two tracks fighting over one
attribute (symptom: element visible at t=0 that shouldn't be), all components
pulsing in lockstep.
Deliver. Build the self-contained HTML (interactive: play/pause/scrub) and,
if the user wants to post it, render the mp4:
python3 scripts/build.py diagram.html dist/diagram.html
python3 scripts/capture.py dist/diagram.html --video dist/diagram.mp4
Growing the library
When a new diagram needs a primitive that doesn't exist (memory-hierarchy stack,
bus with lanes, data-array tiles), compose it from box/miniBox/el following
the anatomy rules, and if it's plausibly reusable, add it to lib.js as a factory
function in the same style rather than leaving it inline. The library growing is
expected and good — one-off visual inventions are not.
Light colorway ("paper")
Opt in with one class — <body class="cv-light"> — nothing else changes: same
lib, same anatomy, same roles. The variables swap to:
| role |
main |
accent (pale wash) |
| bg |
#FFFFFF (pure white) |
— |
| fg (all text) |
#111111 ink |
— |
| work / compute (red) |
#FADFDB |
#FDF1EF |
| state / memory (green) |
#B6E6CF |
#D9F2E6 |
| in flight / traffic (blue) |
#D5E5FD |
#EFF5FF |
| neutral |
#949494 |
— |
Each role's main pastel is the component color (borders, serpentine, solid
fills, particles); its accent is the pale wash — the light-theme equivalent
of the dark theme's ~10% translucent fill — exposed as --cv-compute-accent /
--cv-memory-accent / --cv-traffic-accent. (The vars exist in dark mode too,
derived via color-mix, so components painted with them work in both themes.)
Use the accent vars for large flat washes — plates, level tints, highlight
bands — where an exact tone matters; the lib's opacity-based fills still work
and land close to these tones over white.
For data-dense light frames (matrices, dense grids, small cells) add
cv-vivid — <body class="cv-light cv-vivid"> — which keeps the paper, ink
and washes but saturates the three role hues (red #E8503C, green #12A06B,
blue #3480E8) so a lit row can actually separate from an unlit one. Pair it
with a ~0.09 base fill against a ~0.85 lit fill.
Light-mode checks when verifying stills: pastel strokes carry less contrast
than dark-mode strokes, so lean on fills and ink labels to carry structure;
code traces automatically switch to the light editor token palette defined in
theme.css. One exception to the dark-mode rules: accent-colored TEXT
annotations are unreadable in pastel on paper — in light mode set annotation
text in --cv-fg ink on a --cv-compute-accent wash plate instead (verified
against a captured still; pastel text on white fails).
Hard rules (violating these breaks the brand)
- Colors only via the CSS variables; text is always fg-on-plate, never colored.
- No rounded corners, gradients, shadows, glows, springs, or bounces.
- Only two stroke widths: 2px outer borders, 1px everything else.
- Component inner dash is
8 8; connector dash is 8 6; don't swap them.
- Connectors and particle routes are orthogonal (elbows), never diagonal.
- Packets ride VISIBLE dashed connectors whose arrowheads point where they go —
no hidden-only routes; window a visible connector in/out if it would clutter.
- The serpentine (one continuous line riding the inner border) means "active
right now", not decoration; it crossfades with the inner dashes automatically.
- State changes happen IN components: cylinder levels rise/drain, cells fill or
dim in place — never a symbolic dot drifting out of a component.
- Blue is only ever moving; data at rest is green; work is red (phase-change).
- Timelines are authored in story time;
CV.timeline plays them 1.25× slower.
- Render videos at 1920×1080 with
capture.py --scale 1.5.
- Everything is centered: a component or group (measured as ONE bounding box)
sits centered both horizontally and vertically in its section, with equal
breathing room on opposing sides.
- Titles get their own row: every title sits on its own row ABOVE its content,
never inline with it; parallel columns share one title baseline.
- Execution cursors (code-line bars, cell rings) ease in, SLIDE between
positions with ease.io, and ease out — never hard-switch. The code-line bar is
centered on the text's measured ink by
codeBlock — never add a fudge offset.
- Side-by-side comparisons are one color per SIDE, not per role: every cell,
texture, ring, thread and label of a half wears that half's color (see
design-rules.md). Neutral title/divider/connectors and blue packets excepted.
- Code traces use
CV.codeBlock and the fixed --cv-code-* palette — in dark:
strings #CE9178 salmon, functions #DCDCAA gold, types #4EC9B0 teal, keywords
#C586C0 purple, variables #9CDCFE light blue italic, comments #6A9955 green
italic. The light colorway swaps these to the light editor set in theme.css
automatically — never hardcode token hexes in a diagram.
- Titles between two edges are vertically centered in the gap (
contentTop).
1---2name: cuda-viz3description: Author animated technical diagrams about GPU architecture, CUDA, and parallel computing in a consistent blueprint visual style, using a reusable SVG+JS component library. Use this skill whenever the user asks to animate, visualize, diagram, or explain anything involving GPUs, CUDA, kernels, threads, warps, blocks, SMs, memory hierarchy (registers/shared/L2/HBM), host-device transfer, PCIe/NVLink, matmul/reduction/scan algorithms, LLM inference serving, batching, or KV cache — even if they don't say "animation" or "diagram" explicitly, and even for a "quick sketch" of these topics. Also use it when the user asks for a diagram "in my style" / "the usual style". Produces a self-contained interactive HTML file and, on request, an mp4 loop for social posts.4---56# cuda-viz — animated GPU/CUDA diagrams78This skill produces animated explainer diagrams in one specific, deliberate visual9style (v2 dark blueprint: dashed double-border boxes, translucent fills, a10single-stroke serpentine texture for activity, blue comet packets for data in11motion — red = working, green = at rest, blue = in flight, chalk Archivo text). The user's audience12recognizes this style across posts — consistency is the whole point. Do not13freestyle visuals, colors, or motion outside the system defined here.1415Two colorways exist, same anatomy and rules in both: the default **dark16blueprint** and a **light "paper"** variant (white paper, ink text, pastel role17hues) for embedding in light pages. Dark is the default; use light only when the18user asks for it or the destination is a light-background page. See "Light19colorway" below.2021## Where this skill lives2223This skill directory IS a git repo whose remote is **https://github.com/maxxfuu/cudaviz-skill**24(branch `main`). Push there and only there — never create a new repo for it, and25never commit it into the repo of whatever project a diagram was authored for.2627**Push the skill, never the product.** What belongs in this repo is the reusable28craft: library primitives and fixes, design rules, API docs, scripts, and lessons29learned while making a diagram. What must NEVER be committed here is the output —30diagram HTML, `dist/` builds, mp4s, stills. Those are deliverables and stay in the31user's working directory. After finishing a diagram, ask what the session actually32taught (a bug fixed in `lib.js`, a rule that was missing from `design-rules.md`,33a new primitive), commit THAT, and leave the artwork behind.3435## Files in this skill3637- `assets/lib.js` — the component library (global `CV`). Read it once per session; it's short. v0.2 adds the CUDA-glyph vocabulary: `thread` (squiggly-arrow), `threadBlock` (morphable block of threads), `dataCell` (value cell with texture + plate), `ring` (full-border sliding selector), `chipLegs`/`edgeConnector` (hardware icon trims).38- `assets/theme.css` — palette variables (dark default + light "paper" colorway) + player controls styling.39- `assets/template.html` — starting scaffold for every new diagram.40- `references/design-rules.md` — the visual law: palette, box anatomy, hatching, connectors, typography. **Read before drawing anything.**41- `references/api.md` — full API, timeline patterns, composition recipes, sizing norms. **Read before writing code.**42- `examples/kernel-launch.html` — canonical finished diagram (kernel launch → block scheduling → SIMT execution). Study it when structuring a new piece; it demonstrates every pattern.43- `examples/grid-block-thread.html` — canonical multi-act diagram (grid → blocks → threads → one-thread dot-product trace → parallel finale). Demonstrates the v0.2 vocabulary and the multi-act patterns in api.md: transform-group morphing, guarded late tracks, sliding ring highlights, deterministic churn, bounce emphasis. (Its thread/block/cell code predates the v0.2 factories and inlines them — new diagrams should call `CV.thread`/`CV.threadBlock`/`CV.dataCell`/`CV.ring` instead.)44- `scripts/capture.py` — keyframe stills / frame sequences / `--video out.mp4`.45- `scripts/capture.js` — Node port of `capture.py` (identical CLI); use where Python lacks Playwright. Node resolves modules from the SCRIPT's directory, not the cwd, so after `npm i playwright` in a scratch dir run it as `NODE_PATH=$PWD/node_modules node …/capture.js diagram.html …`. The browsers under `~/.cache/ms-playwright` are shared, so only the language binding ever needs installing.46- `scripts/build.py` — inline the assets into a self-contained deliverable HTML.4748## Workflow4950Layout and animation are separate problems; mixing them wastes iterations. Work in51this order:52531. **Plan the story.** Decide the 3–6 phases the animation narrates (e.g. launch →54 schedule → execute → complete) and which components each phase touches. A loop55 is 8–15s. Decide component colors by role: red (`compute`) = work happening now +56 accent annotations, green (`memory`) = data at rest, neutral gray = passive57 structure, blue (`traffic`) = data in motion ONLY — when a packet lands, its58 blue becomes the destination's green state (the phase-change rule).59602. **Static composition first.** Copy `template.html`, place every component with61 the `CV` primitives at final coordinates, including connectors, hidden routing62 paths, and elements that will start invisible. Leave ≥40px channels between63 components — particles route through channels, never over boxes. Then capture64 one frame and actually look at it:6566 ```bash67 python3 scripts/capture.py diagram.html --times 0.5 --out /tmp/check68 ```6970 Fix spacing, alignment, and label centering *now*, before any motion exists.71723. **Animate on the timeline.** Add tracks per phase. Every track is a pure73 function of `(p, t)` — the patterns (and the three bugs this prevents) are in74 `references/api.md`. Reuse the proven verbs: particle flights, hatch-on-active,75 warp-row pulsing with per-component phase offsets, staged waves, windowed76 annotations.77784. **Verify like a reviewer.** Capture stills at each phase boundary and inspect79 them against `design-rules.md`. Common regressions: labels not centered in80 their header band, particles crossing a component, two tracks fighting over one81 attribute (symptom: element visible at t=0 that shouldn't be), all components82 pulsing in lockstep.83845. **Deliver.** Build the self-contained HTML (interactive: play/pause/scrub) and,85 if the user wants to post it, render the mp4:8687 ```bash88 python3 scripts/build.py diagram.html dist/diagram.html89 python3 scripts/capture.py dist/diagram.html --video dist/diagram.mp490 ```9192## Growing the library9394When a new diagram needs a primitive that doesn't exist (memory-hierarchy stack,95bus with lanes, data-array tiles), compose it from `box`/`miniBox`/`el` following96the anatomy rules, and if it's plausibly reusable, add it to `lib.js` as a factory97function in the same style rather than leaving it inline. The library growing is98expected and good — one-off visual inventions are not.99100## Light colorway ("paper")101102Opt in with one class — `<body class="cv-light">` — nothing else changes: same103lib, same anatomy, same roles. The variables swap to:104105| role | main | accent (pale wash) |106|---|---|---|107| bg | `#FFFFFF` (pure white) | — |108| fg (all text) | `#111111` ink | — |109| work / compute (red) | `#FADFDB` | `#FDF1EF` |110| state / memory (green) | `#B6E6CF` | `#D9F2E6` |111| in flight / traffic (blue) | `#D5E5FD` | `#EFF5FF` |112| neutral | `#949494` | — |113114Each role's **main** pastel is the component color (borders, serpentine, solid115fills, particles); its **accent** is the pale wash — the light-theme equivalent116of the dark theme's ~10% translucent fill — exposed as `--cv-compute-accent` /117`--cv-memory-accent` / `--cv-traffic-accent`. (The vars exist in dark mode too,118derived via `color-mix`, so components painted with them work in both themes.)119Use the accent vars for large flat washes — plates, level tints, highlight120bands — where an exact tone matters; the lib's opacity-based fills still work121and land close to these tones over white.122123For data-dense light frames (matrices, dense grids, small cells) add124`cv-vivid` — `<body class="cv-light cv-vivid">` — which keeps the paper, ink125and washes but saturates the three role hues (red `#E8503C`, green `#12A06B`,126blue `#3480E8`) so a lit row can actually separate from an unlit one. Pair it127with a ~0.09 base fill against a ~0.85 lit fill.128129Light-mode checks when verifying stills: pastel strokes carry less contrast130than dark-mode strokes, so lean on fills and ink labels to carry structure;131code traces automatically switch to the light editor token palette defined in132`theme.css`. One exception to the dark-mode rules: accent-colored TEXT133annotations are unreadable in pastel on paper — in light mode set annotation134text in `--cv-fg` ink on a `--cv-compute-accent` wash plate instead (verified135against a captured still; pastel text on white fails).136137## Hard rules (violating these breaks the brand)138139- Colors only via the CSS variables; text is always fg-on-plate, never colored.140- No rounded corners, gradients, shadows, glows, springs, or bounces.141- Only two stroke widths: 2px outer borders, 1px everything else.142- Component inner dash is `8 8`; connector dash is `8 6`; don't swap them.143- Connectors and particle routes are orthogonal (elbows), never diagonal.144- Packets ride VISIBLE dashed connectors whose arrowheads point where they go —145 no hidden-only routes; window a visible connector in/out if it would clutter.146- The serpentine (one continuous line riding the inner border) means "active147 right now", not decoration; it crossfades with the inner dashes automatically.148- State changes happen IN components: cylinder levels rise/drain, cells fill or149 dim in place — never a symbolic dot drifting out of a component.150- Blue is only ever moving; data at rest is green; work is red (phase-change).151- Timelines are authored in story time; `CV.timeline` plays them 1.25× slower.152- Render videos at 1920×1080 with `capture.py --scale 1.5`.153- Everything is centered: a component or group (measured as ONE bounding box)154 sits centered both horizontally and vertically in its section, with equal155 breathing room on opposing sides.156- Titles get their own row: every title sits on its own row ABOVE its content,157 never inline with it; parallel columns share one title baseline.158- Execution cursors (code-line bars, cell rings) ease in, SLIDE between159 positions with ease.io, and ease out — never hard-switch. The code-line bar is160 centered on the text's measured ink by `codeBlock` — never add a fudge offset.161- Side-by-side comparisons are one color per SIDE, not per role: every cell,162 texture, ring, thread and label of a half wears that half's color (see163 design-rules.md). Neutral title/divider/connectors and blue packets excepted.164- Code traces use `CV.codeBlock` and the fixed `--cv-code-*` palette — in dark:165 strings #CE9178 salmon, functions #DCDCAA gold, types #4EC9B0 teal, keywords166 #C586C0 purple, variables #9CDCFE light blue italic, comments #6A9955 green167 italic. The light colorway swaps these to the light editor set in `theme.css`168 automatically — never hardcode token hexes in a diagram.169- Titles between two edges are vertically centered in the gap (`contentTop`).