# gizlang:machine

What this machine is: its CPU's instruction-set features, the CPUs this process may use, the caches they share and the memory nodes, detected at run time by the runtime, never inferred from a model name. Code that sizes its work to the hardware (a hash table to a cache, a kernel to its vector width, a pool to its CPUs) reads it here.

One cap rules every choice: GIZLANG_CPU sets the x86-64 level code runs at, and the features stop at that level, so a kernel or a compiled unit chosen from them never uses more. GIZLANG_THREADS lowers `threads` as it lowers Task.parallel's pool.

```gizlang
import * as Machine from "gizlang:machine";
```

## Types

### `Cache`

```gizlang
type Cache = { level: i64; bytes: i64; cpus: Vec<i64>; }
```

One cache that a set of CPUs share (data or unified; instruction caches are left out).

- `level`: `i64`
- `bytes`: `i64`
- `cpus`: `Vec<i64>`

### `Node`

```gizlang
type Node = { bytes: i64; cpus: Vec<i64>; }
```

One memory node and its CPUs. A node with no CPUs is memory far from every core (CXL memory, a device's).

- `bytes`: `i64`
- `cpus`: `Vec<i64>`

### `Machine`

```gizlang
type Machine = { arch: string; features: Vec<string>; level: i64; cpus: Vec<i64>; threads: i64; caches: Vec<Cache>; nodes: Vec<Node>; }
```

The CPU, caches and memory nodes of the machine that the program runs on.

- `arch`: `string` — "x86-64", "aarch64" or "generic".
- `features`: `Vec<string>` — As LLVM names them ("avx2", "avx512f", "sve2"), at most those of `level`.
- `level`: `i64` — The x86-64 level code runs at: 4 (AVX-512), 3 (AVX2), 2 (the baseline); 0 on another architecture.
- `cpus`: `Vec<i64>` — The CPUs this process may run on (its affinity).
- `threads`: `i64` — The threads Task.parallel runs on: affinity, the container's CPU quota and GIZLANG_THREADS.
- `caches`: `Vec<gizlang_machine.Cache>` — Each cache instance once, smallest level first as the kernel lists them.
- `nodes`: `Vec<gizlang_machine.Node>`

## Functions

### `machine`

```gizlang
function machine(): Machine
```

This machine. The runtime reads it once per process; each call parses that text again (microseconds).

Effects: fail, read.

### `cpuList`

```gizlang
function cpuList(text: string): Vec<i64>
```

"0-7,16-23" as its CPUs.

Effects: fail.

## Methods

### `Machine.has`

```gizlang
function Machine.has(self: Machine, feature: string): bool
```

Whether the CPU has FEATURE (an LLVM name), within the level code runs at.

Effects: fail.

### `Machine.cacheShare`

```gizlang
function Machine.cacheShare(self: Machine, level: i64): i64
```

The bytes of the cache of LEVEL that one core of this process may count on: over each instance, its bytes over the
usable cores that share it, the least of them; 0 when no cache of LEVEL is known. CPUs that share a first-level
cache (SMT siblings) are one core. A hash table or a partition sized to it stays in that cache while every core
works on its own.

Effects: fail.

### `Machine.lastLevel`

```gizlang
function Machine.lastLevel(self: Machine): i64
```

The highest cache level known (3 on most servers), or 0.

Effects: fail.

### `Machine.groups`

```gizlang
function Machine.groups(self: Machine): Vec<Vec<i64>>
```

The usable CPUs that share each last-level cache (an AMD CCD, an Intel socket), in the kernel's order. Threads of
one group share that cache; data that crosses groups goes through memory.

Effects: fail.

