Files
SuperTensor/tests/flow.tex
T
dela 7b59c81d02 Add flow layout: cursor placement, left rail, declared band heights
Figures were positioned by hand-written offsets. Every gap was a magic
number tuned against the content that happened to be there, so a label
that grew two characters landed on the next tensor, and two stages
started from two different x shared no rail. Both failures compile
cleanly.

Replace it with a cursor. Objects placed with an empty coordinate
argument reserve their own width -- including a stack's offset sheets
and a bracket's overhang -- and gaps are declared once (\stgutter,
\strowgap, \stblockgap). The gap belongs to the object that follows it
and the first object in a band gets none, so every band starts flush on
a shared rail and gap=0pt states that two shards tile exactly.

\stlink makes a connector's label a flow object, which is what removes
the label-wider-than-its-arrow failure entirely. \stcol is a vertical
sub-flow for a split along the contracted axis. \strow declares its
height, so an object that does not fit -- or a column that does not add
up to what it declared, and is therefore drawn off-center -- becomes a
package warning, which build.sh fails on.

Absolute placement is unchanged: passing a coordinate takes the original
code path, and \sttrack folds a hand-placed node back into the cursor.

All three golden examples and the new tests/flow.tex are converted and
build clean.
2026-08-05 15:55:21 +08:00

72 lines
2.3 KiB
TeX

% Regression test for the flow layout: stage headings on a shared left rail,
% bands whose objects reserve their own width, connectors whose labels are flow
% objects. No absolute coordinate appears anywhere in this figure.
% ../scripts/build.sh flow.tex
\documentclass[border=10pt]{standalone}
\usepackage[cjk]{supertensor}
\stsetrole{act}{stTeal}
\stsetrole{w}{stOrange}
\stsetrole{o}{stViolet}
\stdim{T}{7}
\stdim{d}{5}
\stdim{r}{3}
\begin{document}
\begin{tikzpicture}
\ststage{S1}{一、面、算子、带标签的连接线都由游标排布}
\strow{R1}{T}
\stface[role=act, bracket=true]{X}{}{T}{d}
\stglyph{m1}{$\times$}
\stface[role=w, bracket=true]{W}{}{d}{r}
\stlink{l1}{一个很长的标签也不会压到下一个张量}
\stface[role=o, bracket=true]{Y}{}{T}{r}
\strowend
\stcaption{X}{$\mathbf X$}{$T\times d$}
\stcaption{W}{$\mathbf W$}{$d\times r$}
\stcaption{Y}{$\mathbf Y$}{$T\times r$}
\ststage{S2}{二、堆叠的偏移页也计入宽度,行首自动回到同一条左轨}
\strow{R2}{T}
\ststack[role=act]{Q}{}{T}{r}{3}
\stlink{l2}{}
\stcomm{c1}{All-Reduce}
\stlink{l3}{sum}
\stface[role=o, pattern=causal]{A}{}{T}{T}
\stgap{4mm}
\stface[role=w, pattern=diag]{D}{}{r}{r}
\strowend
\stcaption{Q}{$\mathbf Q$}{$3\times T\times r$}
\stcaption{A}{$\mathbf A$}{$T\times T$}
\stcaption{D}{$\mathbf D$}{$r\times r$}
\ststage{S3}{三、列子流:两片沿收缩维叠放,恰好铺满一格}
\strow{R3}{T}
\stface[role=act]{H}{}{T}{d}
\stglyph{m3}{$\times$}
\stcol{Wc}{d}
% d = 2 * (d/2)... here r=3 and d=5, so the two shards are 3 and 2 units.
\stface[role=w]{Wa}{}{r}{T}
\stface[role=o, gap=0pt]{Wb}{}{2}{T}
\stcolend
\stglyph{e3}{$=$}
\stface[role=o, bracket=true]{Z}{}{T}{T}
\strowend
\stcaption{H}{$\mathbf H$}{$T\times d$}
\stcaption{Wc}{$\mathbf W^{(r)}$}{$d\times T$}
\stcaption{Z}{$\mathbf Z$}{$T\times T$}
\stbbox{all}
\stmeaningbox{mb}{15cm}{all}
{$T$ 序列长,$d$ 模型维,$r$ 低秩维}
{}
{三行的左端都落在同一条左轨上,行内间距由 \texttt{\string\stgutter} 声明一次,
标签自己占位,所以任何一处变宽都只会把后面的东西推开,不会盖住它们;
第三行的列子流用 \texttt{gap=0pt} 声明两片相邻,声明高度与实际不符会直接报警}
\stsignature{流式排版自测}{mb}
\end{tikzpicture}
\end{document}