Learn

Phase 0 Cheat Sheet: Dtypes and Primitives

A quick reference for the two most important practical questions:

  1. What data types exist in Phase 0?
  2. What primitive operations are available in core IR?

This is a companion document, not a normative spec. If this file and phase-0/ disagree, phase-0/ is authoritative.


1) Type building blocks

Phase 0 type grammar (simplified) includes:

Dtypes in Phase 0

Category Dtypes
Floating-point F32, F16, BF16, F8E4M3, F8E5M2
Integer I32, I16, I8, I4
Boolean Bool

Shape and refinement reminders


2) Ten core primitives

Phase 0 commits to ten core operations. reduce is one IR operation with two typing rules (reduce and reduce-keep).

# Primitive Typical shape effect
1 Elementwise unary preserves shape
2 Cast preserves shape, changes dtype
3 Elementwise binary combines two same-shape tensors
4 Matmul combines contraction dims
5 Reduce / reduce-keep removes or keeps reduced axis
6 Transpose permutes axes
7 Reshape rearranges shape with equal volume assumption
8 Broadcast (explicit) expands singleton/scalar style shapes
9 Slice takes sub-range along axes
10 Concat joins tensors along an axis

Grouped by shape behavior


3) Three tiny typed examples

A) cast: dtype change, shape unchanged

let to_bf16 [B, S, D]
    (x : Tensor[F32, [B, S, D]])
    : Tensor[BF16, [B, S, D]] =
  cast[BF16] x

B) matmul: shape-combining primitive

let proj [B, M, K, N]
    (a : Tensor[F32, [B, M, K]])
    (b : Tensor[F32, [B, K, N]])
    : Tensor[F32, [B, M, N]] =
  matmul a b

C) reduce_keep: same rank, collapsed axis size 1

let row_sum_keep [B, S, D]
    (x : Tensor[F32, [B, S, D]])
    : Tensor[F32, [B, S, 1]] =
  reduce_keep[sum, axis=2] x

4) Beginner pitfalls (and fixes)

Pitfall 1: assuming implicit broadcast

Wrong mental model: x + bias should just work if bias is [D].

Phase 0 fix: broadcast explicitly first.

let bias_b = broadcast bias [B, S, D] in
x + bias_b

Pitfall 2: assuming implicit dtype promotion

Wrong mental model: I32 + F32 auto-promotes.

Phase 0 fix: cast explicitly, then apply binary op.

let xi = cast[F32] x_i32 in
xi + y_f32

Pitfall 3: confusing value-level mul with shape arithmetic

Keep these domains separate when reading typing rules.


5) Quick decision guide

When writing a new line of code, ask in order:

  1. Did dtype change? Use cast.
  2. Did axis order change? Use transpose.
  3. Did total element count stay same but layout changed? Use reshape.
  4. Need dimension expansion? Use explicit broadcast.
  5. Need to aggregate an axis? Use reduce / reduce_keep.
  6. Need to combine two tensors by contraction? Use matmul.

6) References