==> tests/model.c <==1/* Golden data from the Rust (mesh-ref gpt2.rs) on synthetic weights: the row operations on hashed data
2 * (layer norm, linear with each epilogue and a column range, attention over 1..600 keys, argmax, the
3 * digest), the synthetic weights, a greedy generation (prompt 11 7, one step), and gpt2.rs's
4 * decode_rows_equal_prefill_rows: three tokens one at a time give the KV and logits of the three at
5 * once, both the Rust's. */
6#include "mesh/ref/gpt2.h"
7
8#include "mesh/ftz.h"
9#include "mesh/ref/gpt2_attend.h"
10#include "mesh/ref/gpt2_linear.h"
11#include "mesh/ref/gpt2_logits.h"
12#include "mesh/ref/gpt2_norm.h"
13#include "mesh/ref/gpt2_weights.h"
14#include "mesh/ref/matmul.h"
15
16#include <stdio.h>
17#include <stdlib.h>
18
19static int failures;
20
21static void want(const char *what, uint64_t got, uint64_t want) {
22 if (got != want) {
23 fprintf(stderr, "%s: %#018llx, want %#018llx\n", what, (unsigned long long)got, (unsigned long long)want);
24 failures++;
25 }
26}
27
28static uint64_t fh(uint64_t h, uint64_t w) { return (h ^ w) * 0x100000001b3ull; }
29
30static float *mat(uint32_t seed, size_t n) {
31 float *m = malloc(n * sizeof *m);
32 mesh_matmul_matrix(seed, n, m);
33 return m;
34}
35
36static void rows(void) {
37 uint64_t h = 0xcbf29ce484222325ull;
38 float *x = mat(1, 768), *g = mat(2, 768), *b = mat(3, 768), out[768];
39 mesh_gpt2_normalize_row(x, g, b, out);
40 for (int i = 0; i < 768; i++) h = fh(h, mesh_ftz_bits(out[i]));
41 float *w = mat(4, 768 * 96), *bias = mat(5, 96);
42 const mesh_gpt2_epi epis[3] = {MESH_GPT2_EPI_BIAS, MESH_GPT2_EPI_BIAS_GELU, MESH_GPT2_EPI_BIAS_RESIDUAL};
43 for (int e = 0; e < 3; e++) {
44 float *o = mat(6, 96), *o2 = mat(6, 40);
45 mesh_gpt2_project_row(x, 768, w, bias, 96, epis[e], o);
46 for (int i = 0; i < 96; i++) h = fh(h, mesh_ftz_bits(o[i]));
47 mesh_gpt2_project_cols(x, 768, w, bias, 96, epis[e], 50, 40, o2);
48 for (int i = 0; i < 40; i++) h = fh(h, mesh_ftz_bits(o2[i]));
49 free(o), free(o2);
50 }
51 const size_t ns[6] = {1, 2, 7, 256, 257, 600};
52 for (int t = 0; t < 6; t++) {
53 float *q = mat(7, 64), *ks = mat(8, ns[t] * 64), *vs = mat(9, ns[t] * 64), o[64];
54 mesh_gpt2_attend_row(q, ns[t], ks, 64, vs, 64, o);
55 for (int i = 0; i < 64; i++) h = fh(h, mesh_ftz_bits(o[i]));
56 free(q), free(ks), free(vs);
57 }
58 float *lg = mat(10, 1000);
59 h = fh(h, mesh_gpt2_argmax(lg, 1000));
60 h = fh(h, mesh_gpt2_digest_extend(MESH_GPT2_DIGEST_SEED, lg, 1000));
61 free(x), free(g), free(b), free(w), free(bias), free(lg);
62 want("rows", h, 0x2212298fd900ec07ull);
63}
64
65int main(void) {
66 rows();
67 mesh_gpt2_layout lay;
68 mesh_gpt2_layout_init(&lay);
69 float *w = mesh_gpt2_synthetic(5);
70 if (!w) {
71 fprintf(stderr, "no memory for the weights\n");
72 return 1;
73 }
74 uint64_t h = 0xcbf29ce484222325ull;
75 for (size_t i = 0; i < lay.total; i += 997) h = fh(h, mesh_ftz_bits(w[i]));
76 want("synthetic", h, 0x86cd90d5c4c081b6ull);
77
78 const uint32_t prompt[2] = {11, 7};
79 uint32_t toks[2];
80 uint64_t digest;
81 mesh_gpt2_kv kv;
82 if (!mesh_gpt2_generate(w, &lay, prompt, 2, 1, 8, toks, &digest, &kv)) return 1;
83 if (toks[0] != 48384 || toks[1] != 48384) fprintf(stderr, "tokens %u %u\n", toks[0], toks[1]), failures++;
84 want("generate", digest, 0x9fc013029dba45d5ull);
85 want("generate kv", mesh_gpt2_kv_digest(&kv), 0xfc7a3e32394ce039ull);
86 mesh_gpt2_kv_free(&kv);
87
88 /* decode_rows_equal_prefill_rows, three tokens */
89 const uint32_t three[3] = {11, 7, 50256};
90 float *la = malloc(MESH_GPT2_VOCAB * sizeof *la), *lb = malloc(MESH_GPT2_VOCAB * sizeof *lb);
91 mesh_gpt2_kv a, b;
92 mesh_gpt2_kv_init(&a);
93 mesh_gpt2_kv_init(&b);
94 if (!mesh_gpt2_forward(w, &lay, three, 3, &a, 8, la)) return 1;
95 for (int t = 0; t < 3; t++)
96 if (!mesh_gpt2_forward(w, &lay, &three[t], 1, &b, 3, lb)) return 1;
97 want("prefill kv", mesh_gpt2_kv_digest(&a), 0xdddcc2e98df017bfull);
98 want("decode kv", mesh_gpt2_kv_digest(&b), 0xdddcc2e98df017bfull);
99 want("prefill logits", mesh_gpt2_digest_extend(MESH_GPT2_DIGEST_SEED, la, MESH_GPT2_VOCAB), 0xa7b4303cf98c5170ull);
100 want("decode logits", mesh_gpt2_digest_extend(MESH_GPT2_DIGEST_SEED, lb, MESH_GPT2_VOCAB), 0xa7b4303cf98c5170ull);
101 mesh_gpt2_kv_free(&a);
102 mesh_gpt2_kv_free(&b);
103 free(la), free(lb), free(w);
104 return failures != 0;
105}