==> include/mesh/top_app.h <==1/* @ajax/mesh-top-app: mesh-top's viewer state and key handling (crates/mesh-top src/app.rs). One
2 * machine per endpoint (its latest snapshot and the history the dashboard derives rates from),
3 * the tab, focus and selection, the prompts and the HTTP input. Keys become actions the caller
4 * sends, so tests drive the app without sockets. Programs are bound by name ("doom", "train",
5 * "infer", "http"). */
6#ifndef MESH_TOP_APP_H
7#define MESH_TOP_APP_H
8
9#include "mesh/top_clock.h"
10#include "mesh/top_net.h"
11#include "mesh/top_snap.h"
12#include "mesh/top_views.h"
13#include "tui/input.h"
14
15#include <stdbool.h>
16#include <stddef.h>
17#include <stdint.h>
18
19enum {
20 MT_TAB_MESH,
21 MT_TAB_PROGRAMS,
22 MT_TAB_DOOM,
23 MT_TAB_TRAIN,
24 MT_TAB_INFER,
25 MT_TAB_HTTP,
26 MT_TAB_NET,
27 MT_TAB_LOAD,
28 MT_TAB_FLEET,
29 MT_TAB_JOBS,
30 MT_TAB_PIPES,
31 MT_TAB_RENDER,
32 MT_TABS
33};
34extern const char *const MT_TAB_NAMES[MT_TABS];
35extern const char MT_TAB_KEYS[MT_TABS];
36extern const char *const MT_VIEWS[3]; /* "fleet", "jobs", "pipes" */
37extern const char *const MT_RENDER_PROGRAMS[2];
38
39#define MT_VIEW_POLL MT_MS(1000)
40#define MT_RENDER_POLL MT_MS(400)
41#define MT_STALL MT_SECS(1)
42#define MT_AUX_POLL MT_MS(250)
43#define MT_LOG_LINES 200
44#define MT_HTTP_INPUT_MAX 224
45#define MT_SPARK_LEN 240
46#define MT_PARAM_HISTORY 1024
47#define MT_LOSS_POINTS 4096
48#define MT_RATE_WINDOW MT_SECS(1)
49#define MT_TRACE_STALE MT_MS(500)
50
51/* A value sampled at snapshots, and its rate over MT_RATE_WINDOW (on the viewer's clock). */
52typedef struct {
53 mt_instant *t;
54 uint64_t *v;
55 size_t n, cap;
56} mt_rate;
57void mt_rate_push(mt_rate *r, mt_instant now, uint64_t v);
58float mt_rate_per_s(const mt_rate *r);
59void mt_rate_free(mt_rate *r);
60
61typedef struct {
62 uint32_t slot, node;
63 uint32_t heartbeat;
64 mt_instant changed;
65 float util;
66} mt_node_track;
67
68typedef struct {
69 uint32_t slot;
70 char name[3 * MESH_NAME_BYTES + 1];
71 uint32_t loads;
72 mt_rate counters[MESH_COUNTERS];
73} mt_prog_track;
74
75typedef struct {
76 uint32_t slot, n;
77 mt_instant moved;
78 mt_rec *recs;
79 size_t nrecs;
80} mt_trace_track;
81
82typedef struct {
83 uint64_t step;
84 uint8_t view[32];
85} mt_param;
86
87typedef struct {
88 uint64_t step;
89 float loss;
90} mt_loss;
91
92/* A fleet-rendered image as a member assembles it (meshd `render <job> raw`). */
93typedef struct {
94 mt_kv *kv; /* the status's key value words */
95 size_t nkv;
96 struct {
97 uint32_t k;
98 uint64_t folded;
99 uint32_t tiles;
100 } *members;
101 size_t nmembers;
102 uint32_t (*tiles)[2]; /* (passes folded, member of the last) */
103 size_t ntiles;
104 uint8_t *px; /* tile-major 0xffBBGGRR */
105 size_t npx;
106 double msps;
107} mt_fleet_image;
108bool mt_fleet_image_parse(const uint8_t *b, size_t len, mt_fleet_image *out);
109void mt_fleet_image_free(mt_fleet_image *f);
110const char *mt_fleet_image_get(const mt_fleet_image *f, const char *k); /* "" when absent */
111uint64_t mt_fleet_image_num(const mt_fleet_image *f, const char *k);
112
113typedef struct {
114 char *endpoint;
115 bool online;
116 char *status;
117 bool has_snap;
118 mt_snapshot snap;
119 bool has_snap_at;
120 mt_instant snap_at;
121 mt_node_track *nodes; /* sorted by (slot, node) */
122 size_t nnodes;
123 mt_prog_track *progs; /* sorted by slot */
124 size_t nprogs;
125 uint64_t *tps; /* oldest first, at most MT_SPARK_LEN */
126 size_t ntps;
127 mt_param *params; /* sorted by step, at most MT_PARAM_HISTORY */
128 size_t nparams;
129 mt_loss *losses;
130 size_t nlosses, caplosses;
131 mt_rate train_steps, doom_shown;
132 bool has_http_resp;
133 uint8_t *http_resp;
134 size_t http_resp_len;
135 mt_trace_track *trace; /* sorted by slot */
136 size_t ntrace;
137 char *trace_err;
138 char **log;
139 size_t nlog;
140 char *log_err;
141 char **catalog;
142 size_t ncatalog;
143 mt_net_track net;
144 uint64_t (*load_hist)[2]; /* (GPU share %, CPU busy %), at most MT_SPARK_LEN */
145 size_t nload_hist;
146 uint32_t load_seen;
147 bool has_render;
148 char *render_name;
149 uint8_t *render_px;
150 size_t render_len;
151 char *render_err;
152 bool has_fleet;
153 mt_fleet_image fleet;
154 bool has_fleet_prev;
155 mt_instant fleet_prev_t;
156 uint64_t fleet_prev_n;
157} mt_machine;
158
159/* The machine's name: its hostname once a snapshot told it, else the endpoint. out: 97 + endpoint. */
160const char *mt_machine_name(const mt_machine *m, char *out, size_t cap);
161bool mt_machine_system(const mt_machine *m, uint32_t *k);
162const mt_section *mt_machine_program(const mt_machine *m, const char *name);
163float mt_machine_counter_rate(const mt_machine *m, uint32_t slot, size_t i);
164bool mt_machine_stalled(const mt_machine *m, uint32_t slot, uint32_t node, mt_instant now);
165const mt_node_track *mt_machine_node(const mt_machine *m, uint32_t slot, uint32_t node);
166
167typedef struct {
168 mt_rec rec;
169 uint32_t age;
170} mt_flame_rec;
171/* The flame chart's records with their end's age in ns within window_ns of the newest (malloc'd). */
172size_t mt_machine_flame(const mt_machine *m, mt_instant now, uint32_t window_ns, mt_flame_rec **out);
173/* Trace records of programs whose trace moved recently (malloc'd). */
174size_t mt_machine_fresh_trace(const mt_machine *m, mt_instant now, mt_rec **out);
175
176/* train's u64 next step, and its loss ring in step order (count written to out, at most 256). */
177uint64_t mt_train_next_step(const mt_section *s);
178size_t mt_train_losses(const mt_section *s, mt_loss out[256]);
179
180/* The lockstep programs' view prefixes compared at the latest step every machine reported. */
181typedef struct {
182 uint64_t step;
183 size_t n;
184 bool identical;
185 char differ[MESH_MAX_SYSTEMS * 4][64];
186 size_t ndiffer;
187} mt_identity;
188
189/* A program's placement (from its manifest extension). */
190typedef enum { MT_PLACE_LOCAL, MT_PLACE_PIN, MT_PLACE_SPLIT } mt_place_kind;
191typedef struct {
192 mt_place_kind kind;
193 uint32_t pin;
194 uint8_t assign[MESH_PLACE_PARTS_MAX];
195} mt_place;
196bool mt_place_of(const mt_section *s, mt_place *out); /* false: it declares no placement */
197void mt_place_label(mt_place p, char out[32]);
198uint32_t mt_place_input_to(mt_place p, uint32_t me);
199mt_place mt_place_next(mt_place p, uint32_t n);
200bool mt_place_eq(mt_place a, mt_place b);
201typedef struct {
202 uint32_t first, last, system;
203} mt_part_run;
204size_t mt_part_runs(const uint8_t assign[MESH_PLACE_PARTS_MAX], uint32_t fanout, mt_part_run *out);
205
206typedef enum { MT_ACTION_NONE, MT_ACTION_QUIT, MT_ACTION_SEND, MT_ACTION_POLL } mt_action_kind;
207typedef struct {
208 mt_action_kind kind;
209 size_t machine;
210 char *line; /* malloc'd for SEND and POLL; free with mt_action_free */
211} mt_action;
212void mt_action_free(mt_action *a);
213
214typedef enum { MT_PROMPT_NONE, MT_PROMPT_LOAD, MT_PROMPT_UNLOAD, MT_PROMPT_CONFIRM } mt_prompt_kind;
215typedef struct {
216 mt_prompt_kind kind;
217 char input[132]; /* Load */
218 bool has_pick;
219 size_t pick;
220 size_t machine; /* Unload, Confirm */
221 char *name; /* Unload */
222 char *line, *what; /* Confirm */
223} mt_prompt;
224
225typedef struct {
226 mt_machine *machines;
227 size_t nmachines;
228 int tab;
229 size_t focus, sel;
230 mt_prompt prompt;
231 char http_input[MT_HTTP_INPUT_MAX + 8];
232 uint16_t http_scroll;
233 char *last_reply;
234 bool has_aux_at;
235 mt_instant aux_at;
236 bool has_view[3];
237 mt_view views[3];
238 bool has_view_at;
239 mt_instant view_at;
240 size_t fsel[2];
241 bool has_jsel;
242 size_t jsel;
243 bool render_marks;
244 bool has_render_at;
245 mt_instant render_at;
246} mt_app;
247
248void mt_app_init(mt_app *app, const char *const *endpoints, size_t n);
249void mt_app_free(mt_app *app);
250
251typedef enum { MT_UPDATE_ONLINE, MT_UPDATE_OFFLINE, MT_UPDATE_SNAP, MT_UPDATE_SNAP_ERROR, MT_UPDATE_REPLY } mt_update_kind;
252typedef struct {
253 mt_update_kind kind;
254 size_t machine;
255 char *text; /* Offline: why; SnapError: the error; Reply: the request line */
256 mt_snapshot snap; /* Snap (moved into the app) */
257 bool bytes; /* Reply: framed bytes (else a text line) */
258 uint8_t *data; /* Reply: the bytes or the text */
259 size_t len;
260} mt_update;
261/* Applies an update; takes ownership of its allocations. */
262void mt_app_apply(mt_app *app, mt_update *u, mt_instant now);
263/* Background refreshes due now; returns the count (at most 2), into out. */
264size_t mt_app_tick(mt_app *app, mt_instant now, mt_action out[2]);
265mt_action mt_app_handle_key(mt_app *app, tui_key k);
266
267size_t mt_app_view_machine(const mt_app *app, size_t view);
268int mt_app_tab_view(const mt_app *app); /* -1: none */
269const mt_view *mt_app_view(const mt_app *app, size_t v);
270/* The Fleet tab's selection: program name (NULL: none; caller frees) and member id. */
271void mt_app_fleet_sel(const mt_app *app, char **prog, bool *has_member, uint32_t *member);
272char *mt_app_job_sel(const mt_app *app); /* caller frees; NULL: none */
273uint32_t mt_app_cluster_size(const mt_app *app);
274bool mt_app_render_program(const mt_app *app, char name[64], uint32_t *tiles);
275const mt_machine *mt_app_focused(const mt_app *app);
276const mt_section *mt_app_selected(const mt_app *app);
277bool mt_params_identity(const mt_app *app, mt_identity *out);
278
279/* Constructors for tests and the client. */
280mt_update mt_update_snap(size_t i, mt_snapshot s);
281mt_update mt_update_reply_bytes(size_t i, const char *line, const void *data, size_t len);
282mt_update mt_update_reply_text(size_t i, const char *line, const char *text);
283mt_update mt_update_offline(size_t i, const char *why);
284mt_update mt_update_online(size_t i);
285
286#endif