skip to content
==> include/mesh/abi/placement.h <==
1/* @ajax/mesh-abi-placement: Placement across machines: capabilities, modes, split parts and the show region (SH_*).
2 *
3 * Part of alpha-c-mesh, a C port of alpha-rust-mesh (README.md says from where). */
4#ifndef MESH_ABI_PLACEMENT_H
5#define MESH_ABI_PLACEMENT_H
6
7#include <stdbool.h>
8#include <stddef.h>
9#include <stdint.h>
10
11/* ---------------------------------------------------------------- placement */
12/* Where a program runs on a cluster of N machines (control `place <name>
13 * local|pin <k>|split [spec]`).  Only a program whose manifest declares `place`
14 * can be placed; meshd moves its state and frames, generically:
15 * place_state  view regions of the shared state (doom: pose, frame, map)
16 * place_frame  the u32 frame number (inside a state region)
17 * place_out    view regions a frame writes; task arg b writes the b-th of
18 * `fanout` equal parts of each (doom: 4 x 32 columns)
19 * place_show   SH_* below: meshd's frame-matched copy of the output
20 * - local: each machine runs its own copy (the default; nothing mirrored).
21 * - pin k: only system k runs it; every other machine's kernel is stopped, its
22 * view gets k's state and whole frames (F_FRAME) and its input is forwarded
23 * to k (F_INPUT).
24 * - split: an *assignment* maps each part b (0..fanout) to a system.  The
25 * owner, the system of part 0, owns the state and runs its parts with
26 * OP_TASK (part 0 applies the input); every other assigned system (a
27 * follower) runs its parts with OP_FOLLOW on the state the owner sent with
28 * that frame.  Each sends its parts to every other machine; systems without
29 * parts mirror.  Every machine shows a frame only once it holds every part of
30 * the SAME frame number.  Input goes to the owner.  Specs: `split` (every
31 * system, parts dealt in order, earlier systems take the remainder: N = 3,
32 * fanout 4 -> 0 0 1 2), `split a,b,..` (those systems, the same way; the
33 * first owns), `split a:n,b:m,..` (n parts to a, ...; they sum to fanout),
34 * a list of fanout systems (one per part, repeats allowed: `split 0,0,1,2`),
35 * or `split auto` (every system, parts weighted by each machine's measured
36 * time per part, the fastest owning: a slower GPU gets fewer columns).
37 *
38 * A change pauses every copy, drains them, moves the state from the machine
39 * whose state continues (pin k: k; split: its owner; from local: the new
40 * runner/owner) and resumes; the fleet's leader coordinates it among the up
41 * members, re-plans when one of them drops (the state from a survivor's copy)
42 * and when one returns; without a leader, a member that lost a placement peer goes local. */
43#define MESH_PLACE_CAP_NONE 0u
44#define MESH_PLACE_CAP_PIN 1u
45#define MESH_PLACE_CAP_SPLIT 2u
46#define MESH_PLACE_CAPS_LEN 3
47extern const char *const MESH_PLACE_CAPS[3];
48#define MESH_PLACE_LOCAL 0u
49#define MESH_PLACE_PIN 1u
50#define MESH_PLACE_SPLIT 2u
51#define MESH_PLACES_LEN 3
52extern const char *const MESH_PLACES[3];
53/* Parts a split can assign (task args 0..fanout; part masks are one u32). */
54#define MESH_PLACE_PARTS_MAX 32
55/* PX_PLACE_ASSIGN's entry for a part beyond fanout (and every part when not split). */
56#define MESH_PART_NONE 0xff
57/* The show region (manifest `place_show`, view offset S), written by meshd
58 * in pin and split: two buffers, the output regions concatenated in each.
59 * S + SH_SEQ     u32 frames shown; the current buffer is SH_SEQ & 1
60 * (its data, then its SHB_*, then SH_SEQ: release)
61 * S + SH_MODE    u32 PLACE_* (local: readers use the program's own output)
62 * S + SH_SYS     u32 the pinned system / the split owner
63 * S + SH_LAT_US  u32 split: the last frame's added latency, its first part
64 * here to its last (us); pin: 0
65 * S + SH_BUF + SH_BUF_BYTES k: buffer k's SHB_FRAME (frame number) and
66 * SHB_SYS (4 bits per part b < 8: the system that rendered it)
67 * S + SH_DATA + k * out_bytes: buffer k's data */
68#define MESH_SH_SEQ 0x0
69#define MESH_SH_MODE 0x4
70#define MESH_SH_SYS 0x8
71#define MESH_SH_LAT_US 0xc
72#define MESH_SH_BUF 0x10
73#define MESH_SH_BUF_BYTES 0x10
74#define MESH_SHB_FRAME 0x0
75#define MESH_SHB_SYS 0x4
76#define MESH_SH_DATA 0x100
77
78/* The show region's bytes for out_bytes of output. */
79static inline uint32_t mesh_show_bytes(uint32_t out_bytes) { return (uint32_t)MESH_SH_DATA + 2 * out_bytes; }
80
81/* The Rust const asserts that only involve this package. */
82_Static_assert(MESH_SH_BUF + MESH_SH_BUF_BYTES * 2 <= MESH_SH_DATA, "SH_BUF + SH_BUF_BYTES * 2 <= SH_DATA");
83_Static_assert(MESH_SHB_SYS + 4 <= MESH_SH_BUF_BYTES, "SHB_SYS + 4 <= SH_BUF_BYTES");
84_Static_assert(MESH_PLACE_PARTS_MAX == 32, "PLACE_PARTS_MAX == 32");
85
86#endif