Inference workloads pack their weights into one byte per entry — a quarter of an int32’s storage, an eighth of a float64’s — and compute their products in a wider accumulator. Mica’s tensors carry that world as two more element families:
var
w : matrix[2, 3] of int8;
x : vector of int8; { the dynamic families take them too }The example is examples/QuantizedTensors
in the tutorial repository.
Storage families, not computing families
A quantized tensor declares, indexes, resizes, copies, transposes, and spreads
like any other — those are movement, decided by element size alone. What it
does not do is ride the ordinary operators. An int8 + int8 inside an
elementwise loop would overflow silently at values a program meets on its
first day, so the compiler refuses the operators on these families and names
the road instead:
the operator 'addition' has no meaning on 'matrix[2, 3] of int8' and
'matrix[2, 3] of int8': the quantized element families store values and
convert them, and their one arithmetic is the widening product —
'WideningProduct(a, b)' accumulates the int8 or uint8 products in int32,
so the accumulation type never hides inside an operatorWideningProduct
logits := WideningProduct(w, x); { matrix[2,3] of int8 × vector of int8 }The matrix product with every one-byte product accumulated in int32 — the shape numpy and ONNX call the integer matmul, spelled as its own function so the accumulation type stands in the name. A one-byte product always fits int32 (the extremes are 127·127 and 255·255), so only the accumulation can leave the domain — and the checked build traps the first sum that does, at the call’s own source position.
Static, dynamic, and mixed shape worlds compose under the same dimension-wise
law every product follows: the example’s static-rows-times-dynamic-vector
answers the fully static vector[2] of int32.
The signed and unsigned families differ exactly by the loads’ extension, which values past 127 prove:
unsigned: 700, 25014What stays above the language
Scale and zero-point calibration — the mapping between a float world and its quantized image — is arithmetic over values, and it stays a library concern above this verb. The language’s contribution ends where it should: honest storage, refused footguns, and one product whose accumulator is never implicit.