skip to content
==> src/infer.c <==
1/* infer: the trained cubic over a 64-point grid. It reads train's params
2 * through mesh_ctx_peer_view (manifest `reads = ["train"]`, so the runtime
3 * refuses any other view). Layout: @ajax/mesh-abi-view-infer. The loops
4 * mirror mesh-kcheck's CPU reference index by index (bitwise checks).
5 * Ported from alpha-rust-mesh programs/infer/src/lib.rs. */
6#include "mesh/rt.h"
7
8static float infer_cubic(const float p[4], float x) {
9    float x2 = x * x;
10    float x3 = x2 * x;
11    return p[0] + p[1] * x + p[2] * x2 + p[3] * x3;
12}
13
14/* The grid: x_i = -1 + 2 i / (POINTS - 1); lane l writes points l and l + 32. */
15static void infer_init(const mesh_ctx *ctx) {
16    uint32_t l = mesh_ctx_lane(ctx);
17    uint32_t is[2] = {l, l + 32};
18    for (int k = 0; k < 2; k++) {
19        uint32_t i = is[k];
20        mesh_ctx_set_f32(ctx, MESH_INFER_I_X + 4 * i, -1.0f + 2.0f * (float)i / (float)(MESH_INFER_POINTS - 1));
21    }
22}
23
24/* Returns POINTS, or R_NO_TRAIN when no train is loaded. */
25static uint32_t infer_run(const mesh_ctx *ctx) {
26    uint32_t s;
27    mesh_view tv;
28    if (!mesh_ctx_find(ctx, "train", 5, &s) || !mesh_ctx_peer_view(ctx, s, &tv)) return MESH_INFER_R_NO_TRAIN;
29    float p[4] = {mesh_view_f32(tv, MESH_TRAIN_T_PARAMS), mesh_view_f32(tv, MESH_TRAIN_T_PARAMS + 4),
30                  mesh_view_f32(tv, MESH_TRAIN_T_PARAMS + 8), mesh_view_f32(tv, MESH_TRAIN_T_PARAMS + 12)};
31    uint32_t l = mesh_ctx_lane(ctx);
32    uint32_t is[2] = {l, l + 32};
33    for (int k = 0; k < 2; k++) {
34        uint32_t i = is[k];
35        mesh_ctx_set_f32(ctx, MESH_INFER_I_Y + 4 * i, infer_cubic(p, mesh_ctx_view_f32(ctx, MESH_INFER_I_X + 4 * i)));
36    }
37    if (mesh_ctx_leader(ctx)) {
38        for (uint32_t k = 0; k < 4; k++) mesh_ctx_set_f32(ctx, MESH_INFER_I_PARAMS + 4 * k, p[k]);
39        mesh_ctx_set_u32(ctx, MESH_INFER_I_RUNS, mesh_ctx_view_u32(ctx, MESH_INFER_I_RUNS) + 1);
40        mesh_ctx_set_u32(ctx, MESH_INFER_I_TRAIN_STEP, mesh_view_u32(tv, MESH_TRAIN_T_NEXT_STEP));
41        mesh_ctx_count(ctx, 0, 1);
42    }
43    return MESH_INFER_POINTS;
44}
45
46static uint32_t infer_task(const mesh_ctx *ctx, uint32_t op, uint32_t arg) {
47    if (op == MESH_OP_TASK) return infer_run(ctx);
48    if (op == MESH_INFER_OP_PROBE_READ) {
49        mesh_view v;
50        return mesh_ctx_peer_view(ctx, arg, &v) ? mesh_view_len(v) : MESH_INFER_R_NO_VIEW;
51    }
52    return MESH_R_BAD_OP;
53}
54
55MESH_PROGRAM(infer_init, infer_task);