Data types — the command and its formats
VMAC’s data layer has two halves, both in
examples/vmac/vmac_datatypes.py: the
command the host enqueues (VmacCmd) and the dependent types
(VmacFormats) that a command implies for the datapath. This page is about those
types; the numeric behaviour they describe — how precision grows and is requantized
— is the arithmetic page.
The command — VmacCmd
A VmacCmd is the instruction the accelerator dequeues. It is a
ParamSchema specialized on the accelerator’s address
and component widths (VmacCmd.specialize(mem_awidth=…, data_bw=…)), so its fields
are sized to the design. Its fields:
| field | type | role |
|---|---|---|
op |
EnumField(OpCode) |
which element-wise op — scalar_mult / inner_prod / sum / end |
reduce |
BooleanField |
sum each result down its rows to one output row |
n_rows, n_cols |
UInt16 |
the operand matrix shape |
a, b, y |
Region |
operand A, operand B, destination Y descriptors |
alpha |
Alpha |
the scaling operand for scalar_mult |
Region descriptors
The operands are not inlined in the command — they are pointers into shared
memory, described by a Region:
| field | type | meaning |
|---|---|---|
addr |
IntField (width mem_awidth) |
base element offset of the region |
row_stride |
IntField, signed |
outer pitch in elements between rows |
A region addresses a row-major matrix as M[i, j] = mem[addr + i·row_stride + j].
Addresses and strides are in element units, not bytes or words — the
width-agnostic coordinate system the kernel and the SimPy
Region both use. a is always read;
b is read for inner_prod / sum; y is the destination (collapsed to a single
row when reduce is set).
The scalar — Alpha
scalar_mult needs a per-row complex scalar, and it can come two ways, captured by
the Alpha schema’s direct flag:
- direct (immediate) —
direct == True: the scalar travels in the command itself (imm, a complex value built from the operand’s integer component type). - indirect (per-row) —
direct == False:addr/stridepoint at a column of scalars in memory, one per row, read like any other operand.
This is the small but real bit of ISA design in VMAC: an immediate for the common case, an indirect for a per-row vector, selected by one boolean.
The dependent types — VmacFormats
VMAC’s fixed-point formats are not stored per element. Nowhere does a matrix
carry a scale or a width with each value. Instead the formats are a pure function of
the design’s structural widths and the command, computed by VmacFormats — a frozen
dataclass over data_bw, int_bits, acc_bw, out_bw, and the rounding/overflow
modes q_rnd / o_sat. This is the page’s signature idea: the types are
derived, not declared.
VmacFormats answers, for a given command:
operand_elem()— the shared-memory element type: aComplexFieldwhose real and imaginary parts are aFixedField(data_bw, int_bits). This is the typeA,B, and the indirectαare stored in.accumulator_format(cmd)— the wide intermediate format the op accumulates in, which depends on the op (a product op widens differently from a sum) and onreduce(a row sum adds⌈log₂ n_rows⌉integer bits).output_format(cmd)— theFixedFieldthe resultYis written back in, at widthout_bwwith the command’s rounding/overflow modes.derived_shift(cmd)— the single requantize shift from accumulator to output.lane_capacity(word_bw)— how many complex columns pack into one memory word, which sets the kernel’s packing factor.
Because these are derived, the golden model and the synthesizable kernel cannot
disagree about a format: both read it off the same VmacFormats. The arithmetic
those formats encode — what “widens differently” means, how the single requantize is
sized — is the next page.
The complex element
A, B, and Y are matrices of complex fixed-point values, modeled with the
framework’s ComplexField over a
FixedField component. VMAC does not
re-teach complex or fixed-point typing — it uses them: operand_elem() above is
just ComplexField.specialize(FixedField(...)). See those schema pages for how a
complex field serializes (real low, imaginary high) and how a fixed-point field’s
(W, I, F) works.
Next
- Fixed-point arithmetic — what the derived formats mean
numerically: the operand / accumulator / output formats, how precision grows
through
cmult→ reduce → requantize, and the single requantize.