1/* @ajax/mesh-load-prog: one slot's load sampler (load.rs Prog).
2 *
3 * Each sample (about once a second) reads the program's node load records
4 * (NL_*: the GPU share its nodes obtained), node records (busy time, tasks),
5 * the trace records written since the last sample (task latencies) and P_DONE,
6 * and for a CPU executor (wasm, native) its CPU time and RSS (mesh-cpuuse),
7 * and writes the program's PLOAD record: the last second and a window of
8 * LOAD_WINDOW samples. Another image in the slot (PT_PTX_HASH, PT_LOADS)
9 * starts a fresh baseline. */
10#ifndef MESH_LOAD_PROG_H
11#define MESH_LOAD_PROG_H
1213#include "mesh/abi.h"
14#include "mesh/load_share.h"
15#include "mesh/mailbox.h"
1617#include <stdbool.h>
18#include <stdint.h>
1920/* One node load record (NL_*) now, its longest gap and its window number. */
21mesh_nl mesh_nl_read(mesh_mailbox mb, uint32_t s, uint32_t n, uint32_t *max_gap_ns, uint32_t *win);
2223typedef struct {
24 mesh_nl d;
25 uint32_t *lat; /* task durations (ns) */
26 size_t nlat;
27 uint64_t busy_ns, busy_tasks, tasks, cpu_d;
28} mesh_prog_window;
2930typedef struct {
31 uint64_t hash;
32 uint32_t loads; /* (PT_PTX_HASH, PT_LOADS): another image resets everything */
33 uint32_t nodes;
34 mesh_nl nl[MESH_PROG_MAX_NODES];
35 uint64_t busy_ns[MESH_PROG_MAX_NODES];
36 uint32_t busy_tasks[MESH_PROG_MAX_NODES];
37 uint32_t done, trace_n;
38 mesh_prog_window win[MESH_LOAD_WINDOW];
39 size_t nwin;
40 bool has_task_us;
41 float task_us;
42 uint64_t cpu_base, cpu_last;
43 bool started; /* a baseline exists */
44} mesh_prog_sampler;
4546void mesh_prog_sampler_reset(mesh_prog_sampler *p);
47/* One sample of slot s: its record and its GPU deltas (for the machine's sums) and the window's longest gap. */
48void mesh_prog_sample(mesh_prog_sampler *p, mesh_mailbox mb, uint32_t s, double dt, uint32_t win, uint8_t out[MESH_PLOAD_BYTES], mesh_nl *d,
49 uint32_t *max_gap);
5051#endif