Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions docs/isa/vmi-isa/06-convert.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
4. **FpToUi** — `fp → unsigned int`. Supported pairs follow the contract
table `lookupVMIFpToUIContract`: currently `f16→u8`.

5. **SiToFp** — `int → fp` (e.g. `i32 → f32`, `i8 → f16`).
5. **SiToFp** — `signed int → fp`. The currently supported pairs are
`si32 → f32` and `si8 → f16` (see the support matrix below).

6. **IntWiden** — `int → int`, `|dst| > |src|`.

Expand Down Expand Up @@ -60,11 +61,40 @@
| `rounding` | `"R"` (nearest-even), `"A"` (away-from-zero), `"H"` (half-up), `"Z"` (toward-zero); for the `bf16x2→f4x2` contract pair the allowed set is `"R"`,`"A"`,`"F"` (floor), `"C"` (ceil), `"Z"` (toward-zero) — `"H"` is **rejected** | fp narrowing | Rounding mode |
| `saturate` | `"SAT"`, `"NOSAT"` | required for fp-narrow / int-narrow; for fp→si / fp→ui the requirement follows the vcvt contract's `requiresSat` (e.g. `f16→s8` required, `f16→s32` **forbidden** — no overflow possible; same-width `bf16→f16` required, same-width `f16→bf16` **forbidden**); the `bf16x2→f4x2` narrow has `requiresSat=false` — any `saturate` is **forbidden** | `SAT` clamps to ±max of the destination type; `NOSAT` performs a direct bit truncation of the result representation. |

- **datatypes:** Source and destination from `{f32, f16, bf16, fp8_e4m3, fp8_e5m2, i32, i16, i8, ui32, ui16, ui8}`; packed carrier types `{!pto.bf16x2, !pto.f4E1M2x2, !pto.f4E2M1x2}` for the bf16x2↔f4x2 fp-to-fp pair (see contract `lookupVMIFpToFpContract`). `bf16x2` is **conversion-only** — it may not appear as a compute element type (`vfadd`/`vfmul`/`vcmp`/...).
- **datatypes:** Floating-point source and destination types are
`{f32, f16, bf16, fp8_e4m3, fp8_e5m2}`. Integer types are
`{si32, si16, si8, i32, i16, i8, ui32, ui16, ui8}`. The explicitly signed
`si*` types are required when an integer is converted to floating point
(`SiToFp`). Signless `i*` and unsigned `ui*` types cannot be used as
`SiToFp` sources. Packed carrier types
`{!pto.bf16x2, !pto.f4E1M2x2, !pto.f4E2M1x2}` are valid only for the
bf16x2↔f4x2 fp-to-fp pair (see contract `lookupVMIFpToFpContract`).
`bf16x2` is **conversion-only** — it may not appear as a compute element
type (`vfadd`/`vfmul`/`vcmp`/...).

### SiToFp support matrix

`SiToFp` requires an explicitly signed integer source (`si*`). A signless
`i*` source is rejected even when it has the same bit width. The current VMI
contract exposes `si32 → f32` and `si8 → f16`.

The destination type is fixed by the source width: `si32` requires `f32`, and
`si8` requires `f16`. Other signed-integer widths and floating-point result
types are rejected by the current `vcvt` contract.

| Source | Destination | Current VMI support |
|---|---|---|
| `si32` | `f32` | **Supported** |
| `si8` | `f16` | **Supported** |

Neither supported pair accepts `rounding` or `saturate` attributes.

- **lowering to `pto.mi`:**

| Conversion | Physical lowering | `#mi` | `dep` |
|---|---|---|---|
| SiToFp (`si32→f32`, current) | same-width `vcvt`, no part | `K` | `1` |
| SiToFp (`si8→f16`, current) | widen `vcvt` EVEN/ODD | `2K` | `2` |
| 16↔32 (radix-2) | `2K × vcvt EVEN/ODD` + predicate `ppack`/`punpack` companion | `2K` | `2` |
| 8↔32 (radix-4) | widen: `UNPK_B8` + `vintlv` + `vcvt P0` + `punpack`; narrow: `PK4_B32` store (or `vselr` gather) + `ppack` | `2–3` | `2–3` |
| f32→fp8 quant | `1 cast` + `PK4_B32` | `K` | `1` |
Expand All @@ -75,6 +105,10 @@
| `bf16x2→f4x2` narrow (32→8) | source viewed as raw `bf16` lanes (2 bf16/bf16x2); `vcvt{P0}` 1:1, `rnd` set, **no sat**; reuse prior pairing `vbitcast` when present | `K` | `1` |
| `f4x2→bf16x2` widen (8→32) | `vcvt{P0}` produces `bf16` lanes; result-side `vbitcast` reinterprets them as `bf16x2`; no rnd, no sat | `K` | `1` |

The width-family rows above do not imply that every source/destination
signedness combination is exposed for `SiToFp`; use the support matrix as
the normative list for signed-integer-to-floating-point conversions.

- **example:**
```mlir
// fp16 → fp32 widen (radix-2, produces parity EVEN/ODD)
Expand Down Expand Up @@ -112,6 +146,14 @@
%u = pto.vmi.vcvt %x {saturate = "SAT"}
: !pto.vmi.vreg<128×f16> -> !pto.vmi.vreg<128×ui8>

// si32 → f32 signed-integer to floating-point
%sf = pto.vmi.vcvt %s
: !pto.vmi.vreg<64×si32> -> !pto.vmi.vreg<64×f32>

// si8 → f16 signed-integer to floating-point
%hf = pto.vmi.vcvt %b8
: !pto.vmi.vreg<128×si8> -> !pto.vmi.vreg<128×f16>

// bf16x2 → f4x2 quantized narrow (rounding required; saturate forbidden;
// bf16x2 arrives via a physical-noop vinterpret_cast pairing of 2 bf16 lanes)
%pair = pto.vmi.vinterpret_cast %b
Expand Down
Loading