← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
attention_oracle_ggml.c
Go to the documentation of this file.
1/**
2 * @file attention_oracle_ggml.c
3 * @brief Strict ggml-backed full-attention oracles for parity debugging.
4 *
5 * These helpers intentionally mirror ggml graph composition for encoder-style
6 * full attention. They are composite parity scaffolding, not production CK
7 * kernels, and are only used from strict parity paths.
8 */
9
10#define CK_ENABLE_LLAMA_CPP_PARITY 1
12#include "ckernel_engine.h"
13#include <ggml.h>
14#include <ggml-backend.h>
15#include <ggml-alloc.h>
16#include <dlfcn.h>
17#ifndef RTLD_DEFAULT
18#define RTLD_DEFAULT ((void *)0)
19#endif
20#include <stdint.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25typedef struct ggml_context *(*ck_ggml_init_fn)(struct ggml_init_params);
26typedef void (*ck_ggml_free_fn)(struct ggml_context *);
27typedef struct ggml_tensor *(*ck_ggml_new_tensor_1d_fn)(struct ggml_context *, enum ggml_type, int64_t);
28typedef struct ggml_tensor *(*ck_ggml_new_tensor_2d_fn)(struct ggml_context *, enum ggml_type, int64_t, int64_t);
29typedef struct ggml_tensor *(*ck_ggml_view_3d_fn)(struct ggml_context *, struct ggml_tensor *, int64_t, int64_t, int64_t, size_t, size_t, size_t);
30typedef struct ggml_tensor *(*ck_ggml_permute_fn)(struct ggml_context *, struct ggml_tensor *, int, int, int, int);
31typedef struct ggml_tensor *(*ck_ggml_cont_fn)(struct ggml_context *, struct ggml_tensor *);
32typedef struct ggml_tensor *(*ck_ggml_cont_2d_fn)(struct ggml_context *, struct ggml_tensor *, int64_t, int64_t);
33typedef struct ggml_tensor *(*ck_ggml_mul_mat_graph_fn)(struct ggml_context *, struct ggml_tensor *, struct ggml_tensor *);
34typedef struct ggml_tensor *(*ck_ggml_soft_max_ext_fn)(struct ggml_context *, struct ggml_tensor *, struct ggml_tensor *, float, float);
35typedef struct ggml_cgraph *(*ck_ggml_new_graph_fn)(struct ggml_context *);
36typedef void (*ck_ggml_build_forward_expand_fn)(struct ggml_cgraph *, struct ggml_tensor *);
37typedef enum ggml_status (*ck_ggml_graph_compute_with_ctx_fn)(struct ggml_context *, struct ggml_cgraph *, int);
38typedef void (*ck_ggml_cpu_init_fn)(void);
39typedef void (*ck_ggml_set_input_fn)(struct ggml_tensor *);
40typedef ggml_backend_t (*ck_ggml_backend_init_by_type_fn)(enum ggml_backend_dev_type, const char *);
41typedef void (*ck_ggml_backend_free_fn)(ggml_backend_t);
42typedef void (*ck_ggml_backend_cpu_set_n_threads_fn)(ggml_backend_t, int);
43typedef ggml_backend_buffer_type_t (*ck_ggml_backend_get_default_buffer_type_fn)(ggml_backend_t);
44typedef void (*ck_ggml_backend_tensor_set_fn)(struct ggml_tensor *, const void *, size_t, size_t);
45typedef void (*ck_ggml_backend_tensor_get_fn)(const struct ggml_tensor *, void *, size_t, size_t);
46typedef ggml_backend_sched_t (*ck_ggml_backend_sched_new_fn)(ggml_backend_t *, ggml_backend_buffer_type_t *, int, size_t, bool, bool);
47typedef void (*ck_ggml_backend_sched_free_fn)(ggml_backend_sched_t);
48typedef void (*ck_ggml_backend_sched_reset_fn)(ggml_backend_sched_t);
49typedef bool (*ck_ggml_backend_sched_alloc_graph_fn)(ggml_backend_sched_t, struct ggml_cgraph *);
50typedef enum ggml_status (*ck_ggml_backend_sched_graph_compute_fn)(ggml_backend_sched_t, struct ggml_cgraph *);
51
53
54typedef struct {
55 char magic[8];
56 uint32_t version;
57 int32_t layer_id;
58 char op_name[32];
59 uint32_t dtype;
60 uint32_t rank;
61 int64_t shape[4];
62 uint32_t elem_count;
63 int32_t token_id;
64 uint8_t reserved[32];
65} __attribute__((packed)) ck_attention_oracle_dump_header_t;
66
67static const char ck_attention_oracle_magic[8] = {'C', 'K', 'D', 'M', 'P', '\0', '\0', '\0'};
68static const uint32_t ck_attention_oracle_version = 1u;
70
72{
73 const char *v = getenv("CK_STRICT_ATTN_DUMP");
74 return v && v[0] && strcmp(v, "0") != 0;
75}
76
78{
79 const char *v = getenv("CK_STRICT_ATTN_DUMP_META");
80 return v && v[0] && strcmp(v, "0") != 0;
81}
82
83static int ck_attention_oracle_exact_dump_layer(int *layer_id_out)
84{
85 const char *v = getenv("CK_STRICT_ATTN_DUMP_LAYER");
86 if (!v || !v[0]) {
87 return 0;
88 }
89 char *end = NULL;
90 long parsed = strtol(v, &end, 10);
91 if (end == v || (end && *end != '\0') || parsed < 0 || parsed > INT32_MAX) {
92 return 0;
93 }
94 if (layer_id_out) {
95 *layer_id_out = (int) parsed;
96 }
97 return 1;
98}
99
101{
102 int exact_layer = -1;
103 if (!ck_attention_oracle_exact_dump_layer(&exact_layer)) {
104 return 1;
105 }
106 return layer_id == exact_layer;
107}
108
109static inline size_t ck_attention_oracle_qkv_index(int h,
110 int t,
111 int d,
112 int num_tokens,
113 int aligned_head_dim)
114{
115 return ((size_t) h * (size_t) num_tokens + (size_t) t) * (size_t) aligned_head_dim +
116 (size_t) d;
117}
118
120{
121 const int layer_id = ck_attention_oracle_layer_seq;
123 return layer_id;
124}
125
126static float ck_attention_oracle_tensor_f32_at(const struct ggml_tensor *t,
127 size_t i0,
128 size_t i1,
129 size_t i2,
130 size_t i3)
131{
132 const uint8_t *base = (const uint8_t *) t->data;
133 const size_t off =
134 i0 * (size_t) t->nb[0] +
135 i1 * (size_t) t->nb[1] +
136 i2 * (size_t) t->nb[2] +
137 i3 * (size_t) t->nb[3];
138 return *(const float *) (base + off);
139}
140
141static void ck_attention_oracle_dump_tensor(const char *name,
142 int layer_id,
143 const struct ggml_tensor *t)
144{
145 const char *dir = getenv("CK_PARITY_DIR");
147 !dir || !dir[0] || !name || !name[0] || !t || !t->data ||
149 return;
150 }
151 if (t->type != GGML_TYPE_F32) {
152 return;
153 }
154
155 const int64_t ne0 = t->ne[0] > 0 ? t->ne[0] : 1;
156 const int64_t ne1 = t->ne[1] > 0 ? t->ne[1] : 1;
157 const int64_t ne2 = t->ne[2] > 0 ? t->ne[2] : 1;
158 const int64_t ne3 = t->ne[3] > 0 ? t->ne[3] : 1;
159 const size_t elem_count =
160 (size_t) ne0 * (size_t) ne1 * (size_t) ne2 * (size_t) ne3;
161 if (elem_count == 0) {
162 return;
163 }
164 const size_t nbytes = elem_count * sizeof(float);
165 float *host = NULL;
166 const uint8_t *base = NULL;
167
168 if (t->buffer != NULL) {
170 if (!ggml_backend_tensor_get_fn) {
171 return;
172 }
173 host = (float *) malloc(nbytes);
174 if (!host) {
175 return;
176 }
177 ggml_backend_tensor_get_fn(t, host, 0, nbytes);
178 base = (const uint8_t *) host;
179 } else if (t->data != NULL) {
180 base = (const uint8_t *) t->data;
181 }
182 if (!base) {
183 free(host);
184 return;
185 }
186
187 char path[4096];
188 snprintf(path, sizeof(path), "%s/%s", dir, "strict_internal.bin");
189 FILE *f = fopen(path, "ab");
190 if (!f) {
191 free(host);
192 return;
193 }
194
195 ck_attention_oracle_dump_header_t h;
196 memset(&h, 0, sizeof(h));
198 h.version = ck_attention_oracle_version;
199 h.layer_id = layer_id;
200 strncpy(h.op_name, name, sizeof(h.op_name) - 1);
201 h.dtype = 0u;
202 h.rank = 1u;
203 h.shape[0] = (int64_t) elem_count;
204 h.elem_count = (uint32_t) elem_count;
205 h.token_id = 0;
206
207 fwrite(&h, sizeof(h), 1, f);
208 for (int64_t i3 = 0; i3 < ne3; ++i3) {
209 for (int64_t i2 = 0; i2 < ne2; ++i2) {
210 for (int64_t i1 = 0; i1 < ne1; ++i1) {
211 for (int64_t i0 = 0; i0 < ne0; ++i0) {
212 const size_t off =
213 (size_t) i0 * (size_t) t->nb[0] +
214 (size_t) i1 * (size_t) t->nb[1] +
215 (size_t) i2 * (size_t) t->nb[2] +
216 (size_t) i3 * (size_t) t->nb[3];
217 const float v = *(const float *) (base + off);
218 fwrite(&v, sizeof(v), 1, f);
219 }
220 }
221 }
222 }
223 fclose(f);
224 free(host);
225}
226
227static void ck_attention_oracle_dump_meta(const char *name,
228 int layer_id,
229 const struct ggml_tensor *t)
230{
231 const char *dir = getenv("CK_PARITY_DIR");
233 !dir || !dir[0] || !name || !name[0] || !t ||
235 return;
236 }
237
238 char path[4096];
239 snprintf(path, sizeof(path), "%s/%s", dir, "meta.jsonl");
240 FILE *f = fopen(path, "a");
241 if (!f) {
242 return;
243 }
244
245 fprintf(
246 f,
247 "{\"name\":\"%s\",\"layer_id\":%d,\"type\":%d,"
248 "\"ne\":[%lld,%lld,%lld,%lld],"
249 "\"nb\":[%zu,%zu,%zu,%zu]}\n",
250 name,
251 layer_id,
252 (int) t->type,
253 (long long) t->ne[0], (long long) t->ne[1], (long long) t->ne[2], (long long) t->ne[3],
254 (size_t) t->nb[0], (size_t) t->nb[1], (size_t) t->nb[2], (size_t) t->nb[3]);
255 fclose(f);
256}
257
259{
260 static int tried = 0;
261 static ck_ggml_init_fn fn = NULL;
262 if (!tried) {
263 tried = 1;
264 fn = (ck_ggml_init_fn) dlsym(RTLD_DEFAULT, "ggml_init");
265 }
266 return fn;
267}
268
270{
271 static int tried = 0;
272 static ck_ggml_free_fn fn = NULL;
273 if (!tried) {
274 tried = 1;
275 fn = (ck_ggml_free_fn) dlsym(RTLD_DEFAULT, "ggml_free");
276 }
277 return fn;
278}
279
281{
282 static int tried = 0;
283 static ck_ggml_new_tensor_1d_fn fn = NULL;
284 if (!tried) {
285 tried = 1;
286 fn = (ck_ggml_new_tensor_1d_fn) dlsym(RTLD_DEFAULT, "ggml_new_tensor_1d");
287 }
288 return fn;
289}
290
292{
293 static int tried = 0;
294 static ck_ggml_new_tensor_2d_fn fn = NULL;
295 if (!tried) {
296 tried = 1;
297 fn = (ck_ggml_new_tensor_2d_fn) dlsym(RTLD_DEFAULT, "ggml_new_tensor_2d");
298 }
299 return fn;
300}
301
303{
304 static int tried = 0;
305 static ck_ggml_view_3d_fn fn = NULL;
306 if (!tried) {
307 tried = 1;
308 fn = (ck_ggml_view_3d_fn) dlsym(RTLD_DEFAULT, "ggml_view_3d");
309 }
310 return fn;
311}
312
314{
315 static int tried = 0;
316 static ck_ggml_permute_fn fn = NULL;
317 if (!tried) {
318 tried = 1;
319 fn = (ck_ggml_permute_fn) dlsym(RTLD_DEFAULT, "ggml_permute");
320 }
321 return fn;
322}
323
325{
326 static int tried = 0;
327 static ck_ggml_cont_fn fn = NULL;
328 if (!tried) {
329 tried = 1;
330 fn = (ck_ggml_cont_fn) dlsym(RTLD_DEFAULT, "ggml_cont");
331 }
332 return fn;
333}
334
336{
337 static int tried = 0;
338 static ck_ggml_cont_2d_fn fn = NULL;
339 if (!tried) {
340 tried = 1;
341 fn = (ck_ggml_cont_2d_fn) dlsym(RTLD_DEFAULT, "ggml_cont_2d");
342 }
343 return fn;
344}
345
347{
348 static int tried = 0;
349 static ck_ggml_mul_mat_graph_fn fn = NULL;
350 if (!tried) {
351 tried = 1;
352 fn = (ck_ggml_mul_mat_graph_fn) dlsym(RTLD_DEFAULT, "ggml_mul_mat");
353 }
354 return fn;
355}
356
358{
359 static int tried = 0;
360 static ck_ggml_soft_max_ext_fn fn = NULL;
361 if (!tried) {
362 tried = 1;
363 fn = (ck_ggml_soft_max_ext_fn) dlsym(RTLD_DEFAULT, "ggml_soft_max_ext");
364 }
365 return fn;
366}
367
369{
370 static int tried = 0;
371 static ck_ggml_new_graph_fn fn = NULL;
372 if (!tried) {
373 tried = 1;
374 fn = (ck_ggml_new_graph_fn) dlsym(RTLD_DEFAULT, "ggml_new_graph");
375 }
376 return fn;
377}
378
380{
381 static int tried = 0;
382 static ck_ggml_build_forward_expand_fn fn = NULL;
383 if (!tried) {
384 tried = 1;
385 fn = (ck_ggml_build_forward_expand_fn) dlsym(RTLD_DEFAULT, "ggml_build_forward_expand");
386 }
387 return fn;
388}
389
391{
392 static int tried = 0;
393 static ck_ggml_graph_compute_with_ctx_fn fn = NULL;
394 if (!tried) {
395 tried = 1;
396 fn = (ck_ggml_graph_compute_with_ctx_fn) dlsym(RTLD_DEFAULT, "ggml_graph_compute_with_ctx");
397 }
398 return fn;
399}
400
402{
403 static int tried = 0;
404 static ck_ggml_cpu_init_fn fn = NULL;
405 if (!tried) {
406 tried = 1;
407 fn = (ck_ggml_cpu_init_fn) dlsym(RTLD_DEFAULT, "ggml_cpu_init");
408 }
409 return fn;
410}
411
413{
414 static int tried = 0;
415 static ck_ggml_set_input_fn fn = NULL;
416 if (!tried) {
417 tried = 1;
418 fn = (ck_ggml_set_input_fn) dlsym(RTLD_DEFAULT, "ggml_set_input");
419 }
420 return fn;
421}
422
424{
425 static int tried = 0;
426 static ck_ggml_backend_init_by_type_fn fn = NULL;
427 if (!tried) {
428 tried = 1;
429 fn = (ck_ggml_backend_init_by_type_fn) dlsym(RTLD_DEFAULT, "ggml_backend_init_by_type");
430 }
431 return fn;
432}
433
435{
436 static int tried = 0;
437 static ck_ggml_backend_free_fn fn = NULL;
438 if (!tried) {
439 tried = 1;
440 fn = (ck_ggml_backend_free_fn) dlsym(RTLD_DEFAULT, "ggml_backend_free");
441 }
442 return fn;
443}
444
446{
447 static int tried = 0;
449 if (!tried) {
450 tried = 1;
451 fn = (ck_ggml_backend_get_default_buffer_type_fn) dlsym(RTLD_DEFAULT, "ggml_backend_get_default_buffer_type");
452 }
453 return fn;
454}
455
457{
458 static int tried = 0;
460 if (!tried) {
461 tried = 1;
462 fn = (ck_ggml_backend_cpu_set_n_threads_fn) dlsym(RTLD_DEFAULT, "ggml_backend_cpu_set_n_threads");
463 }
464 return fn;
465}
466
468{
469 static int tried = 0;
470 static ck_ggml_backend_sched_new_fn fn = NULL;
471 if (!tried) {
472 tried = 1;
473 fn = (ck_ggml_backend_sched_new_fn) dlsym(RTLD_DEFAULT, "ggml_backend_sched_new");
474 }
475 return fn;
476}
477
479{
480 static int tried = 0;
481 static ck_ggml_backend_sched_free_fn fn = NULL;
482 if (!tried) {
483 tried = 1;
484 fn = (ck_ggml_backend_sched_free_fn) dlsym(RTLD_DEFAULT, "ggml_backend_sched_free");
485 }
486 return fn;
487}
488
490{
491 static int tried = 0;
492 static ck_ggml_backend_sched_reset_fn fn = NULL;
493 if (!tried) {
494 tried = 1;
495 fn = (ck_ggml_backend_sched_reset_fn) dlsym(RTLD_DEFAULT, "ggml_backend_sched_reset");
496 }
497 return fn;
498}
499
501{
502 static int tried = 0;
504 if (!tried) {
505 tried = 1;
506 fn = (ck_ggml_backend_sched_alloc_graph_fn) dlsym(RTLD_DEFAULT, "ggml_backend_sched_alloc_graph");
507 }
508 return fn;
509}
510
512{
513 static int tried = 0;
514 static ck_ggml_backend_tensor_set_fn fn = NULL;
515 if (!tried) {
516 tried = 1;
517 fn = (ck_ggml_backend_tensor_set_fn) dlsym(RTLD_DEFAULT, "ggml_backend_tensor_set");
518 }
519 return fn;
520}
521
523{
524 static int tried = 0;
525 static ck_ggml_backend_tensor_get_fn fn = NULL;
526 if (!tried) {
527 tried = 1;
528 fn = (ck_ggml_backend_tensor_get_fn) dlsym(RTLD_DEFAULT, "ggml_backend_tensor_get");
529 }
530 return fn;
531}
532
534{
535 static int tried = 0;
537 if (!tried) {
538 tried = 1;
539 fn = (ck_ggml_backend_sched_graph_compute_fn) dlsym(RTLD_DEFAULT, "ggml_backend_sched_graph_compute");
540 }
541 return fn;
542}
543
545 const float *k_head,
546 const float *v_head,
547 float *out_head,
548 int num_tokens,
549 int head_dim,
550 int aligned_head_dim,
551 float scale)
552{
553 const char *disable_env = getenv("CK_STRICT_DISABLE_REGULAR_ATTN_ORACLE");
554 if (disable_env && disable_env[0] && strcmp(disable_env, "0") != 0) {
555 return 0;
556 }
558 ck_ggml_init_fn ggml_init_fn = ck_resolve_ggml_init();
559 ck_ggml_free_fn ggml_free_fn = ck_resolve_ggml_free();
564 ck_ggml_cont_fn ggml_cont_fn = ck_resolve_ggml_cont();
572
573 if (!ggml_cpu_init_fn || !ggml_init_fn || !ggml_free_fn ||
574 !ggml_new_tensor_1d_fn || !ggml_new_tensor_2d_fn ||
575 !ggml_view_3d_fn || !ggml_permute_fn || !ggml_cont_fn || !ggml_cont_2d_fn ||
576 !ggml_mul_mat_fn || !ggml_soft_max_ext_fn || !ggml_new_graph_fn ||
577 !ggml_build_forward_expand_fn || !ggml_graph_compute_with_ctx_fn ||
578 !ggml_set_input_fn) {
579 return 0;
580 }
581
582 ggml_cpu_init_fn();
583
584 const size_t row_bytes = (size_t) aligned_head_dim * sizeof(float);
585 const size_t tensor_bytes = (size_t) num_tokens * row_bytes;
586 const size_t kq_bytes = (size_t) num_tokens * (size_t) num_tokens * sizeof(float);
587 const size_t mem_size = (size_t) 128 * 1024 * 1024 + tensor_bytes * 3 + kq_bytes * 2;
588
589 struct ggml_init_params params = {
591 .mem_buffer = NULL,
592 .no_alloc = false,
593 };
594 struct ggml_context *ctx = ggml_init_fn(params);
595 if (!ctx) {
596 return 0;
597 }
598
599 int ok = 0;
600 struct ggml_tensor *q_base =
601 ggml_new_tensor_1d_fn(ctx, GGML_TYPE_F32, (int64_t) num_tokens * (int64_t) aligned_head_dim);
602 struct ggml_tensor *k_base =
603 ggml_new_tensor_1d_fn(ctx, GGML_TYPE_F32, (int64_t) num_tokens * (int64_t) aligned_head_dim);
604 struct ggml_tensor *v_base =
605 ggml_new_tensor_1d_fn(ctx, GGML_TYPE_F32, (int64_t) num_tokens * (int64_t) aligned_head_dim);
606 if (!q_base || !k_base || !v_base) {
607 ggml_free_fn(ctx);
608 return 0;
609 }
610
611 q_base->data = (void *) q_head;
612 k_base->data = (void *) k_head;
613 v_base->data = (void *) v_head;
614 ggml_set_input_fn(q_base);
615 ggml_set_input_fn(k_base);
616 ggml_set_input_fn(v_base);
617
618 struct ggml_tensor *q_cur = ggml_view_3d_fn(ctx, q_base, head_dim, 1, num_tokens, row_bytes, row_bytes, 0);
619 struct ggml_tensor *k_cur = ggml_view_3d_fn(ctx, k_base, head_dim, 1, num_tokens, row_bytes, row_bytes, 0);
620 struct ggml_tensor *v_cur = ggml_view_3d_fn(ctx, v_base, head_dim, 1, num_tokens, row_bytes, row_bytes, 0);
621 if (!q_cur || !k_cur || !v_cur) {
622 ggml_free_fn(ctx);
623 return 0;
624 }
625
626 struct ggml_tensor *q = ggml_permute_fn(ctx, q_cur, 0, 2, 1, 3);
627 struct ggml_tensor *k = ggml_permute_fn(ctx, k_cur, 0, 2, 1, 3);
628 struct ggml_tensor *v = ggml_permute_fn(ctx, v_cur, 1, 2, 0, 3);
629 if (!q || !k || !v) {
630 ggml_free_fn(ctx);
631 return 0;
632 }
633
634 v = ggml_cont_fn(ctx, v);
635 struct ggml_tensor *kq_scores = ggml_mul_mat_fn(ctx, k, q);
636 struct ggml_tensor *kq_scores_dump =
638 ? ggml_cont_fn(ctx, kq_scores)
639 : NULL;
640 struct ggml_tensor *kq = kq_scores ?
641 ggml_soft_max_ext_fn(ctx, kq_scores, NULL, scale, 0.0f) : NULL;
642 struct ggml_tensor *kqv = kq ? ggml_mul_mat_fn(ctx, v, kq) : NULL;
643 struct ggml_tensor *cur = kqv ? ggml_permute_fn(ctx, kqv, 0, 2, 1, 3) : NULL;
644 if (cur) {
645 cur = ggml_cont_2d_fn(ctx, cur, cur->ne[0] * cur->ne[1], cur->ne[2] * cur->ne[3]);
646 }
647 if (!cur) {
648 ggml_free_fn(ctx);
649 return 0;
650 }
651
652 struct ggml_cgraph *gf = ggml_new_graph_fn(ctx);
653 if (!gf) {
654 ggml_free_fn(ctx);
655 return 0;
656 }
657 if (kq_scores_dump) {
658 ggml_build_forward_expand_fn(gf, kq_scores_dump);
659 }
660 ggml_build_forward_expand_fn(gf, cur);
661 if (ggml_graph_compute_with_ctx_fn(ctx, gf, 1) != GGML_STATUS_SUCCESS) {
662 ggml_free_fn(ctx);
663 return 0;
664 }
665
666 {
667 const float *src = (const float *) cur->data;
668 for (int t = 0; t < num_tokens; ++t) {
669 memcpy(out_head + (size_t) t * (size_t) aligned_head_dim,
670 src + (size_t) t * (size_t) head_dim,
671 (size_t) head_dim * sizeof(float));
672 for (int d = head_dim; d < aligned_head_dim; ++d) {
673 out_head[(size_t) t * (size_t) aligned_head_dim + (size_t) d] = 0.0f;
674 }
675 }
676 }
677
678 ok = 1;
679 ggml_free_fn(ctx);
680 return ok;
681}
682
684 const float *k,
685 const float *v,
686 float *output,
687 int num_heads,
688 int num_kv_heads,
689 int num_tokens,
690 int head_dim,
691 int aligned_head_dim,
692 int kv_stride_tokens,
693 float scale)
694{
695 const char *disable_env = getenv("CK_STRICT_DISABLE_MULTIHEAD_ATTN_ORACLE");
696 if (disable_env && disable_env[0] && strcmp(disable_env, "0") != 0) {
697 return 0;
698 }
699 if (!q || !k || !v || !output) {
700 return 0;
701 }
702 if (num_heads <= 0 || num_tokens <= 0 || head_dim <= 0) {
703 return 0;
704 }
705 if (num_heads != num_kv_heads) {
706 return 0;
707 }
708 if (aligned_head_dim < head_dim) {
709 return 0;
710 }
711 if (kv_stride_tokens != num_tokens) {
712 return 0;
713 }
714 const int layer_id = ck_attention_oracle_dump_layer_id();
715
717 ck_ggml_init_fn ggml_init_fn = ck_resolve_ggml_init();
718 ck_ggml_free_fn ggml_free_fn = ck_resolve_ggml_free();
723 ck_ggml_cont_fn ggml_cont_fn = ck_resolve_ggml_cont();
731
732 if (!ggml_cpu_init_fn || !ggml_init_fn || !ggml_free_fn ||
733 !ggml_new_tensor_1d_fn || !ggml_new_tensor_2d_fn ||
734 !ggml_view_3d_fn || !ggml_permute_fn || !ggml_cont_fn || !ggml_cont_2d_fn ||
735 !ggml_mul_mat_fn || !ggml_soft_max_ext_fn || !ggml_new_graph_fn ||
736 !ggml_build_forward_expand_fn || !ggml_graph_compute_with_ctx_fn ||
737 !ggml_set_input_fn) {
738 return 0;
739 }
740
741 ggml_cpu_init_fn();
742
743 const size_t row_bytes = (size_t) aligned_head_dim * sizeof(float);
744 const size_t head_bytes = (size_t) num_tokens * row_bytes;
745 const size_t tensor_bytes = (size_t) num_heads * head_bytes;
746 const size_t packed_row_bytes = (size_t) num_heads * (size_t) head_dim * sizeof(float);
747 const size_t fused_qkv_row_bytes = (size_t) 3 * packed_row_bytes;
748 const size_t score_bytes =
749 (size_t) num_heads * (size_t) num_tokens * (size_t) num_tokens * sizeof(float);
750 const size_t mem_size =
751 (size_t) 1024 * 1024 * 1024 + tensor_bytes * 4 + score_bytes * 2;
752
753 struct ggml_init_params params = {
755 .mem_buffer = NULL,
756 .no_alloc = false,
757 };
758 struct ggml_context *ctx = ggml_init_fn(params);
759 if (!ctx) {
760 return 0;
761 }
762
763 int ok = 0;
764 struct ggml_tensor *qkv_base = ggml_new_tensor_2d_fn(
765 ctx, GGML_TYPE_F32, 3 * (int64_t) num_heads * (int64_t) head_dim, num_tokens);
766 if (!qkv_base) {
767 ggml_free_fn(ctx);
768 return 0;
769 }
770 ggml_set_input_fn(qkv_base);
771
772 const size_t embd_elems = (size_t) num_heads * (size_t) head_dim;
773 const size_t qkv_pack_elems = (size_t) num_tokens * 3 * embd_elems;
774 float *qkv_pack = (float *) malloc(qkv_pack_elems * sizeof(float));
775 if (!qkv_pack) {
776 ggml_free_fn(ctx);
777 return 0;
778 }
779 for (int t = 0; t < num_tokens; ++t) {
780 float *q_tok = qkv_pack + (size_t) t * 3 * embd_elems;
781 float *k_tok = q_tok + embd_elems;
782 float *v_tok = k_tok + embd_elems;
783 for (int h = 0; h < num_heads; ++h) {
784 memcpy(q_tok + (size_t) h * (size_t) head_dim,
785 q + ck_attention_oracle_qkv_index(h, t, 0, num_tokens, aligned_head_dim),
786 (size_t) head_dim * sizeof(float));
787 memcpy(k_tok + (size_t) h * (size_t) head_dim,
788 k + ck_attention_oracle_qkv_index(h, t, 0, num_tokens, aligned_head_dim),
789 (size_t) head_dim * sizeof(float));
790 memcpy(v_tok + (size_t) h * (size_t) head_dim,
791 v + ck_attention_oracle_qkv_index(h, t, 0, num_tokens, aligned_head_dim),
792 (size_t) head_dim * sizeof(float));
793 }
794 }
795 qkv_base->data = qkv_pack;
796
797 struct ggml_tensor *q_cur = ggml_view_3d_fn(ctx,
798 qkv_base,
799 head_dim,
800 num_heads,
801 num_tokens,
802 (size_t) head_dim * sizeof(float),
803 fused_qkv_row_bytes,
804 0);
805 struct ggml_tensor *k_cur = ggml_view_3d_fn(ctx,
806 qkv_base,
807 head_dim,
808 num_heads,
809 num_tokens,
810 (size_t) head_dim * sizeof(float),
811 fused_qkv_row_bytes,
812 packed_row_bytes);
813 struct ggml_tensor *v_cur = ggml_view_3d_fn(ctx,
814 qkv_base,
815 head_dim,
816 num_heads,
817 num_tokens,
818 (size_t) head_dim * sizeof(float),
819 fused_qkv_row_bytes,
820 2 * packed_row_bytes);
821 if (!q_cur || !k_cur || !v_cur) {
822 free(qkv_pack);
823 ggml_free_fn(ctx);
824 return 0;
825 }
826
827 struct ggml_cgraph *gf = ggml_new_graph_fn(ctx);
828 if (!gf) {
829 free(qkv_pack);
830 ggml_free_fn(ctx);
831 return 0;
832 }
833
834 ggml_build_forward_expand_fn(gf, q_cur);
835 ggml_build_forward_expand_fn(gf, k_cur);
836 ggml_build_forward_expand_fn(gf, v_cur);
837
838 struct ggml_tensor *q_perm = ggml_permute_fn(ctx, q_cur, 0, 2, 1, 3);
839 struct ggml_tensor *k_perm = ggml_permute_fn(ctx, k_cur, 0, 2, 1, 3);
840 struct ggml_tensor *v_perm = ggml_permute_fn(ctx, v_cur, 1, 2, 0, 3);
841 if (!q_perm || !k_perm || !v_perm) {
842 free(qkv_pack);
843 ggml_free_fn(ctx);
844 return 0;
845 }
846
847 v_perm = ggml_cont_fn(ctx, v_perm);
848 struct ggml_tensor *kq_scores = v_perm ? ggml_mul_mat_fn(ctx, k_perm, q_perm) : NULL;
849 struct ggml_tensor *kq_scores_dump =
851 ? ggml_cont_fn(ctx, kq_scores)
852 : NULL;
853 struct ggml_tensor *kq_softmax = kq_scores ?
854 ggml_soft_max_ext_fn(ctx, kq_scores, NULL, scale, 0.0f) : NULL;
855 struct ggml_tensor *kqv = kq_softmax ? ggml_mul_mat_fn(ctx, v_perm, kq_softmax) : NULL;
856 struct ggml_tensor *cur = kqv ? ggml_permute_fn(ctx, kqv, 0, 2, 1, 3) : NULL;
857 if (cur) {
858 cur = ggml_cont_2d_fn(ctx, cur, cur->ne[0] * cur->ne[1], cur->ne[2] * cur->ne[3]);
859 }
860 if (!cur) {
861 free(qkv_pack);
862 ggml_free_fn(ctx);
863 return 0;
864 }
865
866 if (kq_scores_dump) {
867 ggml_build_forward_expand_fn(gf, kq_scores_dump);
868 }
869 ggml_build_forward_expand_fn(gf, cur);
870 if (ggml_graph_compute_with_ctx_fn(ctx, gf, 1) != GGML_STATUS_SUCCESS) {
871 free(qkv_pack);
872 ggml_free_fn(ctx);
873 return 0;
874 }
875
876 ck_attention_oracle_dump_tensor("kq_scores", layer_id, kq_scores_dump ? kq_scores_dump : kq_scores);
877 ck_attention_oracle_dump_tensor("kq_softmax", layer_id, kq_softmax);
878 ck_attention_oracle_dump_tensor("kqv_raw", layer_id, kqv);
879 ck_attention_oracle_dump_meta("q_cur", layer_id, q_cur);
880 ck_attention_oracle_dump_meta("k_cur", layer_id, k_cur);
881 ck_attention_oracle_dump_meta("v_cur", layer_id, v_cur);
882 ck_attention_oracle_dump_meta("q_perm", layer_id, q_perm);
883 ck_attention_oracle_dump_meta("k_perm", layer_id, k_perm);
884 ck_attention_oracle_dump_meta("v_perm", layer_id, v_perm);
885 ck_attention_oracle_dump_meta("kq_scores", layer_id, kq_scores_dump ? kq_scores_dump : kq_scores);
886 ck_attention_oracle_dump_meta("kq_softmax", layer_id, kq_softmax);
887 ck_attention_oracle_dump_meta("kqv_raw", layer_id, kqv);
888 ck_attention_oracle_dump_meta("kqv_out", layer_id, cur);
889
890 {
891 const size_t cur_elems = (size_t) cur->ne[0] * (size_t) cur->ne[1] * (size_t) cur->ne[2] * (size_t) cur->ne[3];
892 float *cur_host = (float *) malloc(cur_elems * sizeof(float));
893 if (!cur_host) {
894 free(qkv_pack);
895 ggml_free_fn(ctx);
896 return 0;
897 }
898 memcpy(cur_host, cur->data, cur_elems * sizeof(float));
899 const float *src = cur_host;
900 ck_strict_store_next_gemm_a(src, (size_t) num_tokens * (size_t) num_heads * (size_t) head_dim);
901 const size_t token_width = (size_t) num_heads * (size_t) head_dim;
902 for (int t = 0; t < num_tokens; ++t) {
903 const float *token_src = src + (size_t) t * token_width;
904 for (int h = 0; h < num_heads; ++h) {
905 float *dst = output + ck_attention_oracle_qkv_index(h, t, 0, num_tokens, aligned_head_dim);
906 memcpy(dst, token_src + (size_t) h * (size_t) head_dim, (size_t) head_dim * sizeof(float));
907 for (int d = head_dim; d < aligned_head_dim; ++d) {
908 dst[d] = 0.0f;
909 }
910 }
911 }
912 free(cur_host);
913 }
914
915 ok = 1;
916 free(qkv_pack);
917 ggml_free_fn(ctx);
918 return ok;
919}
static ck_ggml_backend_free_fn ck_resolve_ggml_backend_free(void)
static ck_ggml_backend_tensor_set_fn ck_resolve_ggml_backend_tensor_set(void)
static ck_ggml_cont_fn ck_resolve_ggml_cont(void)
static int ck_attention_oracle_should_dump_layer(int layer_id)
static size_t ck_attention_oracle_qkv_index(int h, int t, int d, int num_tokens, int aligned_head_dim)
static ck_ggml_backend_sched_alloc_graph_fn ck_resolve_ggml_backend_sched_alloc_graph(void)
void(* ck_ggml_backend_free_fn)(ggml_backend_t)
void(* ck_ggml_backend_tensor_get_fn)(const struct ggml_tensor *, void *, size_t, size_t)
static ck_ggml_mul_mat_graph_fn ck_resolve_ggml_mul_mat_graph(void)
void(* ck_ggml_cpu_init_fn)(void)
void(* ck_ggml_backend_sched_reset_fn)(ggml_backend_sched_t)
struct ggml_tensor *(* ck_ggml_view_3d_fn)(struct ggml_context *, struct ggml_tensor *, int64_t, int64_t, int64_t, size_t, size_t, size_t)
struct ggml_tensor *(* ck_ggml_new_tensor_2d_fn)(struct ggml_context *, enum ggml_type, int64_t, int64_t)
struct ggml_cgraph *(* ck_ggml_new_graph_fn)(struct ggml_context *)
void(* ck_ggml_set_input_fn)(struct ggml_tensor *)
ggml_backend_buffer_type_t(* ck_ggml_backend_get_default_buffer_type_fn)(ggml_backend_t)
static ck_ggml_view_3d_fn ck_resolve_ggml_view_3d(void)
ggml_backend_t(* ck_ggml_backend_init_by_type_fn)(enum ggml_backend_dev_type, const char *)
void(* ck_ggml_backend_sched_free_fn)(ggml_backend_sched_t)
static ck_ggml_new_tensor_1d_fn ck_resolve_ggml_new_tensor_1d(void)
static ck_ggml_backend_get_default_buffer_type_fn ck_resolve_ggml_backend_get_default_buffer_type(void)
enum ggml_status(* ck_ggml_graph_compute_with_ctx_fn)(struct ggml_context *, struct ggml_cgraph *, int)
static ck_ggml_new_tensor_2d_fn ck_resolve_ggml_new_tensor_2d(void)
static float ck_attention_oracle_tensor_f32_at(const struct ggml_tensor *t, size_t i0, size_t i1, size_t i2, size_t i3)
struct ggml_tensor *(* ck_ggml_permute_fn)(struct ggml_context *, struct ggml_tensor *, int, int, int, int)
static int ck_attention_oracle_dump_layer_id(void)
static void ck_attention_oracle_dump_tensor(const char *name, int layer_id, const struct ggml_tensor *t)
enum ggml_status(* ck_ggml_backend_sched_graph_compute_fn)(ggml_backend_sched_t, struct ggml_cgraph *)
static ck_ggml_build_forward_expand_fn ck_resolve_ggml_build_forward_expand(void)
struct ggml_tensor *(* ck_ggml_cont_2d_fn)(struct ggml_context *, struct ggml_tensor *, int64_t, int64_t)
bool(* ck_ggml_backend_sched_alloc_graph_fn)(ggml_backend_sched_t, struct ggml_cgraph *)
#define RTLD_DEFAULT
static int ck_attention_oracle_dump_enabled(void)
struct ggml_tensor *(* ck_ggml_cont_fn)(struct ggml_context *, struct ggml_tensor *)
void(* ck_ggml_backend_cpu_set_n_threads_fn)(ggml_backend_t, int)
static int ck_attention_oracle_exact_dump_layer(int *layer_id_out)
void(* ck_ggml_free_fn)(struct ggml_context *)
static int ck_attention_oracle_meta_dump_enabled(void)
static ck_ggml_backend_init_by_type_fn ck_resolve_ggml_backend_init_by_type(void)
void(* ck_ggml_build_forward_expand_fn)(struct ggml_cgraph *, struct ggml_tensor *)
struct ggml_tensor *(* ck_ggml_mul_mat_graph_fn)(struct ggml_context *, struct ggml_tensor *, struct ggml_tensor *)
static ck_ggml_graph_compute_with_ctx_fn ck_resolve_ggml_graph_compute_with_ctx(void)
static ck_ggml_backend_sched_new_fn ck_resolve_ggml_backend_sched_new(void)
static ck_ggml_cont_2d_fn ck_resolve_ggml_cont_2d(void)
static void ck_attention_oracle_dump_meta(const char *name, int layer_id, const struct ggml_tensor *t)
static ck_ggml_set_input_fn ck_resolve_ggml_set_input(void)
static ck_ggml_backend_sched_free_fn ck_resolve_ggml_backend_sched_free(void)
static ck_ggml_backend_sched_reset_fn ck_resolve_ggml_backend_sched_reset(void)
int ck_attention_head_full_ggml_graph_oracle_regular(const float *q_head, const float *k_head, const float *v_head, float *out_head, int num_tokens, int head_dim, int aligned_head_dim, float scale)
static ck_ggml_new_graph_fn ck_resolve_ggml_new_graph(void)
static ck_ggml_free_fn ck_resolve_ggml_free(void)
static const uint32_t ck_attention_oracle_version
struct ggml_tensor *(* ck_ggml_new_tensor_1d_fn)(struct ggml_context *, enum ggml_type, int64_t)
struct ggml_context *(* ck_ggml_init_fn)(struct ggml_init_params)
int ck_attention_full_ggml_graph_oracle_multihead(const float *q, const float *k, const float *v, float *output, int num_heads, int num_kv_heads, int num_tokens, int head_dim, int aligned_head_dim, int kv_stride_tokens, float scale)
static ck_ggml_backend_sched_graph_compute_fn ck_resolve_ggml_backend_sched_graph_compute(void)
static ck_ggml_backend_tensor_get_fn ck_resolve_ggml_backend_tensor_get(void)
static int ck_attention_oracle_layer_seq
static ck_ggml_backend_cpu_set_n_threads_fn ck_resolve_ggml_backend_cpu_set_n_threads(void)
struct ggml_tensor *(* ck_ggml_soft_max_ext_fn)(struct ggml_context *, struct ggml_tensor *, struct ggml_tensor *, float, float)
static ck_ggml_init_fn ck_resolve_ggml_init(void)
static ck_ggml_cpu_init_fn ck_resolve_ggml_cpu_init(void)
static const char ck_attention_oracle_magic[8]
static ck_ggml_soft_max_ext_fn ck_resolve_ggml_soft_max_ext(void)
ggml_backend_sched_t(* ck_ggml_backend_sched_new_fn)(ggml_backend_t *, ggml_backend_buffer_type_t *, int, size_t, bool, bool)
void(* ck_ggml_backend_tensor_set_fn)(struct ggml_tensor *, const void *, size_t, size_t)
static ck_ggml_permute_fn ck_resolve_ggml_permute(void)
static const char * op_name(CKOpType op)
void ck_strict_store_next_gemm_a(const float *data, size_t elems)
@ GGML_STATUS_SUCCESS
@ GGML_TYPE_F32
__attribute__((visibility("default"))) CKTokenizer *ck_tokenizer_create(CKTokenizerType type)
uint32_t end
Definition utf8.c:215