Canvas block families
The Canvas keeps three signals apart so each stays readable as features grow:
| Signal | Meaning | Appearance |
|---|---|---|
| Block family | What an operation does | The card's line glyph in the family colour, on a lightly tinted tile in Ink |
| Selection or tracing | What you are inspecting | A pale sage outline or connection highlight |
| Execution status | What happened during a run | An explicit icon, label and outline |
Selecting a convolution keeps its convolution glyph. A failed normalization layer keeps its normalization glyph and shows the error as its own icon, label and red outline. A sage normalization glyph never means "passed", and a clay loss glyph never means "failed". The glyph tile is the only coloured part of a card.
Families
| Family | Ink colour | Glyph | Examples |
|---|---|---|---|
| Convolution | #A8B9C7 | grid | Conv1d/2d/3d, ConvTranspose2d, aten.convolution |
| Linear | #B5BACB | network | Linear, Bilinear, addmm, matmul |
| Normalization | #AABDAE | scale | BatchNorm2d, LayerNorm, GroupNorm, RMSNorm |
| Activation | #C6BDA4 | waveform | ReLU, GELU, SiLU, Sigmoid, Softmax |
| Pooling | #BAAFC5 | shrink | MaxPool2d, AdaptiveAvgPool2d |
| Dropout | #C2ADB5 | dashed circle | Dropout, Dropout2d |
| Recurrent | #B5A5C1 | repeat | LSTM, GRU and cells |
| Attention / Transformer | #ABA7C7 | focus | MultiheadAttention, TransformerEncoderLayer, scaled attention |
| Embedding / sparse | #BEAF96 | hash | Embedding, EmbeddingBag |
| Padding | #B6B8A5 | frame | ReflectionPad2d, ZeroPad2d, pad |
| Resampling | #A5BBB6 | scaling | Upsample, interpolate, bilinear resize |
| Shape / rearrangement | #AAB8BE | shuffle | Flatten, view/reshape, permute, slice, PixelShuffle |
| Distance / similarity | #B9A9AE | ruler | CosineSimilarity, PairwiseDistance |
| Loss | #C2AA9F | target | CrossEntropyLoss, MSELoss |
| Arithmetic / merge | #BFB1A4 | merge | add, multiply, concatenate, reductions |
In Ink the glyph's tile also takes 16% of the family colour so the hue reads at a glance; the glyph keeps at least 3.7:1 on it. Paper uses darker variants of the same hues on untinted tiles, since a tint would take the strokes below 3:1 on white. These colors are a tensorViz palette, not official PyTorch colors. Several are deliberately close: the glyph shape and the block's name identify it exactly.
Neutral blocks keep a neutral tile and a gray glyph (#848D85 in Ink, #83888F in Paper; input and output #C9CFC8 / #555A66): Input and Output (arrows), Container (Sequential, ModuleList, ModuleDict, and parallel wrappers labelled as such), Composite module (your own classes, custom code, fused modules) and Unclassified operations, which show their type name.
How a block is classified
Classification follows the block's identity, never its display name:
- Input and output boundaries are neutral.
- A captured module call uses its fully qualified class, such as
torch.nn.modules.conv.Conv2d. Onlytorch.nnclasses map to a family; a class of your own stays a composite even when it is calledLinearorLayerNorm. - A captured operation uses its ATen operator, such as
aten.convolution.default. - A source graph uses its catalog id (
conv2d) or itstorch/torch.nn.functionaltarget. - Anything else is unclassified.
Equivalent module, functional and ATen forms therefore share a family, while nn.Bilinear (Linear) and a bilinear resize (Resampling) stay apart. Lazy, quantized and QAT variants keep their family and add a modifier label. The same result drives cards, collapsed modules, expanded frames, the overview/export SVG, the inspector and the legend.
Inspecting a block
Selecting a block shows, in the selection panel (and the graph viewer's detail panel):
- the family glyph and name, with any modifier;
- the exact class or operator it was classified from;
- for a composite module or container, the families of its children recorded in the graph, in data-flow order, for example Convolution → Normalization → Activation. Nothing is inferred when no child is classified.
Expand a composite module to see its individually coloured children.
Legend, connections and readability
Blocks in the Canvas overlay is a collapsed legend that lists only the families present in the displayed graph, as coloured glyphs. The overview and exported SVG draw the same glyph tiles, so the family colour stays visible when cards are small.
Connections stay neutral: 1.4px gray at rest, slightly stronger for the selected node's own inputs and outputs, and pale sage for a traced path, with unrelated connections quieter. Family colors never reach connections, and nothing glows or animates. Rows with several tensors are numbered from zero (IN 0, IN 1, OUT); the full argument path is the row's tooltip and appears in captured details.
Accessibility
Every family colour is carried by a distinct glyph shape and named in the inspector and legend, so the family survives grayscale and color-vision differences. In forced-colors mode the glyphs use the system text color and selection uses the system highlight. Keyboard focus has its own ring, separate from the selection outline.
Themes are in Canvas.