skip to content
==> src/kv.c <==
1/* GPT-2's KV cache (mesh-ref gpt2.rs `Kv`). */
2#include "mesh/ref/gpt2_kv.h"
3
4#include "mesh/ref/gpt2_logits.h"
5
6#include <stdlib.h>
7
8void mesh_gpt2_kv_init(mesh_gpt2_kv *kv) {
9    for (int l = 0; l < MESH_GPT2_LAYERS; l++) kv->k[l] = kv->v[l] = NULL, kv->rows[l] = 0;
10    kv->cap = 0;
11}
12
13void mesh_gpt2_kv_free(mesh_gpt2_kv *kv) {
14    for (int l = 0; l < MESH_GPT2_LAYERS; l++) free(kv->k[l]), free(kv->v[l]);
15    mesh_gpt2_kv_init(kv);
16}
17
18bool mesh_gpt2_kv_reserve(mesh_gpt2_kv *kv, size_t positions) {
19    if (positions <= kv->cap) return true;
20    size_t cap = kv->cap ? kv->cap : 16;
21    while (cap < positions) cap *= 2;
22    for (int l = 0; l < MESH_GPT2_LAYERS; l++) {
23        float *k = realloc(kv->k[l], cap * MESH_GPT2_WIDTH * sizeof *k);
24        if (!k) return false;
25        kv->k[l] = k;
26        float *v = realloc(kv->v[l], cap * MESH_GPT2_WIDTH * sizeof *v);
27        if (!v) return false;
28        kv->v[l] = v;
29    }
30    kv->cap = cap;
31    return true;
32}
33
34uint64_t mesh_gpt2_kv_digest(const mesh_gpt2_kv *kv) {
35    uint64_t h = MESH_GPT2_DIGEST_SEED;
36    for (int l = 0; l < MESH_GPT2_LAYERS; l++) {
37        h = mesh_gpt2_digest_extend(h, kv->k[l], kv->rows[l] * MESH_GPT2_WIDTH);
38        h = mesh_gpt2_digest_extend(h, kv->v[l], kv->rows[l] * MESH_GPT2_WIDTH);
39    }
40    return h;
41}