==> include/mesh/peer_codec.h <==1/* @ajax/mesh-peer-codec: the fleet's peer link frames (mesh-abi "peer frames v6", peer.rs), byte for
2 * byte: F_JOIN (ids, version, size, the GPU's capabilities) and its checks, the election and commit
3 * messages of mesh-fleet-core, F_BEAT (the core's beat plus this member's reconcile status and its move
4 * outcomes), and F_HELLO (a lockstep group member ready for an epoch and cycle). Frames are the type
5 * byte then the body. */
6#ifndef MESH_PEER_CODEC_H
7#define MESH_PEER_CODEC_H
8
9#include "mesh/abi/base.h"
10#include "mesh/fleet_core.h"
11#include "mesh/place_wire.h"
12#include "mesh/sched_tracker.h"
13
14#include <stdbool.h>
15#include <stdint.h>
16
17/* This machine's capabilities, sent in F_JOIN. */
18typedef struct {
19 uint32_t cc, sms, sms_total, blocks_per_sm;
20 char gpu[32], arch[16], host[32]; /* NUL terminated, as on the wire (at most 31 / 15 / 31 bytes) */
21 uint32_t backend; /* H_BACKEND: 0 CUDA; Metal: BACKEND_METAL | family << 8 */
22 uint32_t max_threads, max_shared; /* a node's limits on its GPU; 0: no GPU */
23} mpk_caps;
24
25typedef struct {
26 uint32_t system, version, systems;
27 mpk_caps caps;
28} mpk_join;
29
30mpw_bytes mpk_join_encode(const mpk_join *j);
31/* b: JOIN_BYTES after the type byte. */
32mpk_join mpk_join_decode(const uint8_t *b);
33/* Whether a JOIN may open a link here: version, size, and (has_expect) the system dialed, or (not)
34 * one of the systems that dial us. */
35bool mpk_join_check(const mpk_join *j, uint32_t me, uint32_t n, bool has_expect, uint32_t expect, char **err);
36bool mpk_caps_eq(const mpk_caps *a, const mpk_caps *b);
37
38/* A member's status as its F_BEAT says (beside the fleet core's part). */
39typedef struct {
40 bool has_leader;
41 uint32_t leader;
42 uint64_t applied;
43 uint32_t status, up, group_epoch, group_state;
44 char *reason;
45 mst_outcome *moves; /* what its reconciler did with programs moves placed on it */
46 size_t nmoves;
47} mpk_beat_status;
48
49void mpk_beat_status_free(mpk_beat_status *s);
50mpk_beat_status mpk_beat_status_clone(const mpk_beat_status *s);
51bool mpk_beat_status_eq(const mpk_beat_status *a, const mpk_beat_status *b);
52
53/* A core message as a frame (not a Beat: mpk_beat_frame). */
54mpw_bytes mpk_msg_frame(const mfc_msg *m);
55mpw_bytes mpk_beat_frame(const mfc_msg *beat, const mpk_beat_status *st);
56/* h: BEAT_HEAD bytes; reason; moves: the k outcomes' bytes after the count. */
57bool mpk_beat_decode(const uint8_t *h, const uint8_t *reason, size_t nreason, const uint8_t *moves, size_t nmoves, mfc_msg *msg, mpk_beat_status *st, char **err);
58/* The fixed-size core messages from their bodies (after the type byte). */
59mfc_msg mpk_vote_req_decode(const uint8_t *b);
60mfc_msg mpk_vote_decode(const uint8_t *b);
61mfc_msg mpk_ack_decode(uint8_t type, const uint8_t *b); /* F_STATE_ACK or F_COMMIT */
62
63/* A lockstep group member ready for (epoch, cycle) of its group. */
64typedef struct {
65 char group[MESH_NAME_BYTES + 1];
66 uint32_t epoch, cycle, mask;
67 uint8_t order[MESH_MAX_SYSTEMS]; /* rank order: system ids, 0xff past the end */
68 uint64_t hash;
69} mpk_hello;
70
71bool mpk_hello_rank(const mpk_hello *h, uint32_t k, uint32_t *rank);
72uint32_t mpk_hello_n(const mpk_hello *h);
73bool mpk_hello_eq(const mpk_hello *a, const mpk_hello *b);
74mpw_bytes mpk_hello_frame(uint32_t me, const mpk_hello *h);
75/* b: HELLO_BYTES after the type byte. */
76bool mpk_hello_decode(const uint8_t *b, uint32_t *system, uint32_t *version, mpk_hello *out, char **err);
77
78#endif