> ## Documentation Index
> Fetch the complete documentation index at: https://klyne-research.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Types

> All scalar types in Enigma with their Metal and numpy equivalents.

Enigma defines a fixed set of scalar types that map directly to Metal Shading Language types. Use them as kernel parameter type annotations and as arguments to casting functions.

## Scalar types

| Enigma type   | Metal type | Bits | Python/NumPy         |
| ------------- | ---------- | ---- | -------------------- |
| `enigma.f32`  | `float`    | 32   | `np.float32`         |
| `enigma.f16`  | `half`     | 16   | `np.float16`         |
| `enigma.bf16` | `bfloat`   | 16   | `ml_dtypes.bfloat16` |
| `enigma.i32`  | `int`      | 32   | `np.int32`           |
| `enigma.u32`  | `uint`     | 32   | `np.uint32`          |
| `enigma.i64`  | `long`     | 64   | `np.int64`           |
| `enigma.u64`  | `ulong`    | 64   | `np.uint64`          |
| `enigma.i16`  | `short`    | 16   | `np.int16`           |
| `enigma.u16`  | `ushort`   | 16   | `np.uint16`          |
| `enigma.i8`   | `char`     | 8    | `np.int8`            |
| `enigma.u8`   | `uchar`    | 8    | `np.uint8`           |
| `enigma.b1`   | `bool`     | 1    | —                    |

## Using types as kernel parameters

Type annotations on kernel parameters declare the buffer element type:

```python theme={null}
@enigma.kernel
def mixed(A: enigma.f16, B: enigma.i32, C: enigma.f32):
    tid = enigma.thread_position_in_grid
    val = enigma.metal_cast(A[tid], enigma.f32)
    idx = B[tid]
    C[idx] = val
```

## Type casting

### `enigma.metal_cast(value, target_type)`

Standard type conversion, equivalent to C-style casting in Metal:

```python theme={null}
x_f32 = enigma.metal_cast(x_f16, enigma.f32)   # half → float
x_i32 = enigma.metal_cast(x_f32, enigma.i32)   # float → int (truncate)
```

### `enigma.as_type(value, target_type)`

Bitwise reinterpret (no value conversion, same bit pattern):

```python theme={null}
bits = enigma.as_type(x_f32, enigma.u32)        # float bits as uint32
```

## Integer literals

Integer literals in kernel bodies are automatically promoted to `u32`:

```python theme={null}
idx = tid * 4 + 1   # 4 and 1 become u32 IRValues
```

Float literals become `f32`:

```python theme={null}
val = A[tid] * 2.0  # 2.0 is f32
```

## Scalar parameters

`enigma.Scalar(dtype)` declares a per-dispatch constant. It is lowered as a 1-element device buffer and auto-loaded at kernel entry:

```python theme={null}
@enigma.kernel
def add_scalar(A: enigma.f32, bias: enigma.Scalar(enigma.f32), C: enigma.f32):
    tid = enigma.thread_position_in_grid
    C[tid] = A[tid] + bias
```

Pass the scalar value as a 1-element numpy array at dispatch time:

```python theme={null}
rt.execute(compiled, inputs=[a, np.array([0.5], dtype=np.float32)], ...)
```

## Vector types

Enigma supports vector construction for geometric operations. Vector types are created from scalars:

```python theme={null}
v2 = enigma.make_float2(x, y)
v3 = enigma.make_float3(x, y, z)
v4 = enigma.make_float4(x, y, z, w)
```

Access components via `.x`, `.y`, `.z`, `.w`, or by lane index:

```python theme={null}
px = v3.x
lane1 = enigma.vec_extract(v3, 1)  # equivalent to .y
```

See [Operations](/programming-guide/operations) for geometric and vector math functions.
