Extracted from the tensor-formula-viz skill and rebuilt around the idea that the geometry rules should be enforced by construction rather than restated as prose an agent has to remember. - assets/supertensor.sty: faces, stacks, index faces, shared caption lanes, meaning box, signature. Macros take a declared axis and a declared role, so equal shapes get equal edges, a x a is square, a transpose swaps the face, and contracted axes share an edge length -- without any manual alignment. - scripts/preflight.sh: decide the TikZ/CJK path before drawing. - scripts/build.sh: compile and fail on silent corruption (missing CJK glyphs, overfull boxes, undeclared roles), then export pdf/svg/png/thumb. - scripts/test.sh: build every figure as a regression test for the package. - examples/: three golden figures (TP-FFN, causal MHA, MoE top-k gather) plus an anti-pattern gallery of figures that compile cleanly and still lie. - SKILL.md + references/: lean entry point, details loaded on demand.
104 lines
3.7 KiB
Markdown
104 lines
3.7 KiB
Markdown
# supertensor.sty API
|
||
|
||
```tex
|
||
\documentclass[border=10pt]{standalone}
|
||
\usepackage[cjk]{supertensor} % cjk: ctex + fandol (XeLaTeX). en: English rail labels.
|
||
```
|
||
|
||
Build with `./scripts/build.sh fig.tex` — it puts `assets/` on `TEXINPUTS`, so the package
|
||
does not need to be installed into your texmf tree.
|
||
|
||
## Ledgers
|
||
|
||
```tex
|
||
\stsetrole{q}{stTeal} % role -> color. Macros take a ROLE, never a color.
|
||
\stdim{T}{6} % symbolic axis -> physical edge length in cells
|
||
\stsetauthor{...} % default 五道口纳什
|
||
\stsetlabels{A}{O}{M} % override the three meaning-box rail labels
|
||
\stsetrail{3.2em} % width of the bold label rail
|
||
```
|
||
|
||
Colors: `stTeal stOrange stCoral stViolet stGray stInk`. An unknown role falls back to gray
|
||
**and emits a package warning**, which `build.sh` turns into a failed build.
|
||
|
||
Lengths: `\stunit` (one cell, 4.6 mm) and `\sttilegap` (white gutter, 0.5 mm).
|
||
|
||
## Faces
|
||
|
||
```tex
|
||
\stface[keys]{name}{(coord)}{rows}{cols}
|
||
\ststack[keys]{name}{(coord)}{rows}{cols}{sheets}
|
||
\stindexface[keys]{name}{(coord)}{rows}{cols}{entries}
|
||
```
|
||
|
||
`rows`/`cols` accept a declared axis name or a raw integer. `(coord)` must include its own
|
||
parentheses — `{(0,0)}`, `{($(A.east)+(1.5,0)$)}`. `name` becomes a TikZ node you can
|
||
anchor against; `\ststack` also defines `name-front`.
|
||
|
||
Keys:
|
||
|
||
| key | default | meaning |
|
||
|---|---|---|
|
||
| `role=` | `neutral` | hue, via `\stsetrole` |
|
||
| `pattern=` | `dense` | `solid dense diag band lower upper causal empty data` |
|
||
| `data=` | — | with `pattern=data`: comma-separated rows, one digit per cell, `0`–`3` = level |
|
||
| `level=` | `2` | level for `pattern=solid` and the flat level of a mask |
|
||
| `bracket=` | `false` | thin neutral matrix brackets |
|
||
| `border=` | `true` | outer `black!60` border |
|
||
| `tiles=` | `true` | `false` = one flat filled rectangle |
|
||
|
||
`\stindexface` entries are row-major, `rows*cols` of them; `.` leaves a cell blank.
|
||
It deliberately has no lightness ramp — see `semantics.md`.
|
||
|
||
```tex
|
||
\stface[role=w, pattern=data, level=3,
|
||
data={3300,0330,0033,3003,3030,0303}]{D}{(0,0)}{T}{E}
|
||
\stindexface[role=idx]{I}{(b)}{T}{k}{0,1, 1,2, 2,3, 3,0, 0,2, 1,3}
|
||
```
|
||
|
||
## Captions
|
||
|
||
```tex
|
||
\node[inner sep=0pt, fit=(A)(B)(C)] (rowA) {};
|
||
\stlane{rowA}
|
||
\stcaption{A}{$\mathbf A$}{$T\times d$} % symbol lane, shape lane
|
||
\stnolane
|
||
\stcaptiontop{A}{\stshapefont{token}} % occasional label above a face
|
||
```
|
||
|
||
`\stcaption` defines `name-sym` and `name-shape` nodes; anchor the next stage heading
|
||
against `name-shape.south`.
|
||
|
||
## Operators, connectors, nodes
|
||
|
||
```tex
|
||
\node[st op, right=6mm of A] (m) {$\times$};
|
||
\node[st comm, right=9mm of P] (ar) {All-Reduce};
|
||
\starrow{P.east}{ar.west}
|
||
\starrowlabel{M.east}{A.west}{softmax}
|
||
```
|
||
|
||
Styles: `st sym st shape st stage st op st note st arrow st comm st brace`.
|
||
Text helpers: `\stformula \ststagelabel \stoperator \stsymfont \stshapefont \stprose`.
|
||
Connectors route on the background layer automatically.
|
||
|
||
## Bottom
|
||
|
||
```tex
|
||
\node[inner sep=0pt, fit=(F)(rowA)(rowB)(Y-shape)] (all) {};
|
||
\stmeaningbox{mb}{16.6cm}{all}{axes text}{objects text}{mechanism text}
|
||
\stsignature{因果多头注意力(掩码 + 拼接投影)}{mb}
|
||
```
|
||
|
||
Arg 2 is the total box width; arg 3 is the node it hangs below — include every caption and
|
||
top label in that `fit` or the box will overlap them. An empty `{}` row is dropped.
|
||
|
||
## Gotchas
|
||
|
||
- `\ststack` never re-enters `\stface`; if you extend the package, do not pass
|
||
`role=\st@role` back through pgfkeys — it defines the macro in terms of itself and hangs.
|
||
- A coordinate expression inside `fit=` needs braces: `fit={(a) ($(b)+(1,0)$)}`.
|
||
- `\foreach {\macro,...,1}` cannot infer its direction from an unexpanded macro.
|
||
- `\strole` is expandable on purpose (it is used inside `\edef`); the warning lives in
|
||
`\stcheckrole`.
|