1/* @ajax/mesh-abi-base: Mailbox-wide constants of the mesh contract: magic, version, runtime ABI, warp and shared-memory sizes, slots, systems, names.
2 *
3 * Part of alpha-c-mesh, a C port of alpha-rust-mesh (README.md says from where). */
4#ifndef MESH_ABI_BASE_H
5#define MESH_ABI_BASE_H
67#include <stdbool.h>
8#include <stddef.h>
9#include <stdint.h>
1011#define MESH_MAGIC 0x4853454du /* "MESH" */
12/* Threads per warp (a CUDA warp, an Apple SIMD-group). A node -- one block
13 * (threadgroup) of a program's kernel -- is PT_WARPS such warps: 32 x warps
14 * threads (manifest `warps`, 1..=MAX_WARPS); a program's kernel has `nodes`
15 * such blocks. */
16#define MESH_NODE_THREADS 32u
17/* The most warps a node may have (1024 threads: CUDA's and Metal's block limit). */
18#define MESH_MAX_WARPS 32u
19/* The runtime's own shared (threadgroup) memory at the start of every node's
20 * block: the ticket descriptor thread 0 broadcasts and the block
21 * collectives' scratch (mesh-rt, mesh_rt.h). A program's `shared_bytes`
22 * follow it: the launch's dynamic shared memory is RT_SHARED_BYTES +
23 * shared_bytes, and `ctx.shared(off, ..)` offsets are relative to the
24 * program's part. */
25#define MESH_RT_SHARED_BYTES 0x200u
26/* The largest manifest `shared_bytes` (the device's own limit applies at load:
27 * CUDA's opt-in shared memory per block, Metal's maxThreadgroupMemoryLength). */
28#define MESH_MAX_SHARED_BYTES ((uint32_t)(0x38000 - MESH_RT_SHARED_BYTES))
29/* Shared memory sizes are multiples of this (Metal's threadgroup memory granule). */
30#define MESH_SHARED_ALIGN 16u
31/* H_PEER of a single machine. */
32#define MESH_PEER_NONE 0xffffffffu
33#define MESH_VERSION 2u
34/* The value of a program's `MESH_RT_ABI` global and its manifest's `abi`.
35 * 3: the node loop keeps a node load record (NL_*) and reads H_LOAD_WIN.
36 * 4: a lockstep program's exchange runs over its *group* (H_GROUP_RANK,
37 * H_GROUP_N: `ctx.group()`), not H_PEER / H_SYSTEMS.
38 * 5: pipes have two rings per inbox (GPU side and CPU side), the record sum
39 * folds in the position, pushes count themselves in PP_FLIGHT/PP_FLIGHT1 under
40 * H_PIPE_EPOCH and answer Busy under PP_IN_HOLD; Metal pops a copy (`pop()`).
41 * An image built against 4 would corrupt a 5 inbox, so it is refused at load.
42 * 6: multi-warp nodes. A node is a block of 32 x PT_WARPS threads with
43 * RT_SHARED_BYTES + PX_SHARED bytes of dynamic shared memory; the node loop
44 * runs at block scope (thread 0 claims and polls, the descriptor reaches the
45 * block through shared memory and a block barrier; the block finishes the
46 * task, a barrier, then thread 0 completes it). PT_SMS is gone (PT_WARPS). */
47#define MESH_RT_ABI 6u
48#define MESH_MAILBOX_BYTES 0x800000
49/* Every program's kernel entry (emitted by `mesh_program!`). */
50#define MESH_PROGRAM_ENTRY "mesh_main"
51/* The `#[no_mangle]` u32 global meshd reads with `cuModuleGetGlobal` at load. */
52#define MESH_RT_ABI_SYMBOL "MESH_RT_ABI"
53/* The largest cluster: system ids 0..MAX_SYSTEMS-1. */
54#define MESH_MAX_SYSTEMS 8u
55/* ---------------------------------------------------------------- program table */
56#define MESH_PROG_SLOTS 32
57#define MESH_NAME_BYTES 16
58#define MESH_NAME_MAX 15
5960/* The Rust const asserts that only involve this package. */
61_Static_assert(MESH_PROG_SLOTS <= 32, "PROG_SLOTS <= 32");
62_Static_assert(MESH_MAX_SYSTEMS <= 16, "MAX_SYSTEMS <= 16");
63_Static_assert((MESH_RT_SHARED_BYTES % MESH_SHARED_ALIGN == 0), "RT_SHARED_BYTES.is_multiple_of(SHARED_ALIGN)");
64_Static_assert((MESH_MAX_SHARED_BYTES % MESH_SHARED_ALIGN == 0), "MAX_SHARED_BYTES.is_multiple_of(SHARED_ALIGN)");
65_Static_assert(MESH_MAX_WARPS * MESH_NODE_THREADS == 1024, "MAX_WARPS * NODE_THREADS == 1024");
6667#endif