21#define CK_Q80_STACK_Q8_BLOCKS 1024
42 const char *v = getenv(
"CK_STRICT_GEMM_DUMP");
43 return v && v[0] && strcmp(v,
"0") != 0;
48 const char *v = getenv(
"CK_STRICT_GEMM_USE_CACHED_A");
49 return v && v[0] && strcmp(v,
"0") != 0;
57 const char *dir = getenv(
"CK_PARITY_DIR");
58 if (!dir || !dir[0] || !data || elem_count == 0 || !name || !name[0]) {
63 snprintf(path,
sizeof(path),
"%s/%s", dir,
"strict_internal.bin");
64 FILE *f = fopen(path,
"ab");
69 ck_q80_contract_dump_header_t h;
70 memset(&h, 0,
sizeof(h));
73 h.layer_id = layer_id;
74 strncpy(h.op_name, name,
sizeof(h.op_name) - 1);
77 h.shape[0] = (int64_t) elem_count;
78 h.elem_count = (uint32_t) elem_count;
81 fwrite(&h,
sizeof(h), 1, f);
82 fwrite(data,
sizeof(
float), elem_count, f);
88typedef struct ggml_tensor *(*ck_q80_ggml_new_tensor_2d_fn)(
struct ggml_context *,
enum ggml_type, int64_t, int64_t);
89typedef struct ggml_tensor *(*ck_q80_ggml_mul_mat_fn)(
struct ggml_context *,
struct ggml_tensor *,
struct ggml_tensor *);
90typedef struct ggml_cgraph *(*ck_q80_ggml_new_graph_fn)(
struct ggml_context *);
94typedef void *(*ck_q80_ggml_get_data_fn)(
const struct ggml_tensor *);
95typedef float *(*ck_q80_ggml_get_data_f32_fn)(
const struct ggml_tensor *);
100 static int tried = 0;
111 static int tried = 0;
122 static int tried = 0;
133 static int tried = 0;
144 static int tried = 0;
155 static int tried = 0;
166 static int tried = 0;
177 static int tried = 0;
188 static int tried = 0;
199 static int tried = 0;
210 static int tried = 0;
239 if (!ggml_cpu_init_fn || !ggml_init_fn || !ggml_free_fn || !ggml_new_tensor_2d_fn ||
240 !ggml_mul_mat_fn || !ggml_new_graph_fn || !ggml_build_forward_expand_fn ||
241 !ggml_graph_compute_with_ctx_fn || !ggml_get_data_fn || !ggml_get_data_f32_fn ||
248 const size_t output_bytes = (size_t) M * (
size_t) N *
sizeof(float);
249 const size_t mem_size = ((size_t) 128 * 1024 * 1024) + output_bytes;
256 struct ggml_context *ctx = ggml_init_fn(params);
262 struct ggml_tensor *w = ggml_new_tensor_2d_fn(ctx,
GGML_TYPE_Q8_0, K, N);
263 struct ggml_tensor *x = ggml_new_tensor_2d_fn(ctx,
GGML_TYPE_F32, K, M);
269 void *w_data = ggml_get_data_fn(w);
270 void *x_data = ggml_get_data_fn(x);
271 const size_t w_nbytes = ggml_nbytes_fn(w);
272 if (!w_data || !x_data || w_nbytes == 0) {
277 memcpy(w_data, B, w_nbytes);
278 memcpy(x_data, A, (
size_t) M * (
size_t) K *
sizeof(
float));
280 struct ggml_tensor *y = ggml_mul_mat_fn(ctx, w, x);
286 struct ggml_cgraph *gf = ggml_new_graph_fn(ctx);
291 ggml_build_forward_expand_fn(gf, y);
298 const float *src = ggml_get_data_f32_fn(y);
303 for (
int m = 0; m < M; ++m) {
304 memcpy(
C + (
size_t) m * (
size_t) N,
305 src + (
size_t) m * (
size_t) N,
306 (
size_t) N *
sizeof(
float));
308 for (
int n = 0; n < N; ++n) {
309 C[(size_t) m * (
size_t) N + (size_t) n] += bias[n];
324 float val = fval + 12582912.f;
326 memcpy(&i, &val,
sizeof(
int));
327 return (i & 0x007fffff) - 0x00400000;
334 const int nb = k /
QK8_0;
336 for (
int i = 0; i < nb; ++i) {
338 for (
int j = 0; j <
QK8_0; ++j) {
339 const float v = x[i *
QK8_0 + j];
340 const float av = fabsf(v);
346 const float d = amax / 127.0f;
347 const float id = d != 0.0f ? 1.0f / d : 0.0f;
350 for (
int j = 0; j <
QK8_0; ++j) {
351 const float x0 = x[i *
QK8_0 + j] *
id;
359 y[i].
qs[j] = (int8_t) q;
371 const int blocks_per_row = K /
QK8_0;
373 for (
int row = 0; row < M; ++row) {
377 &w_blocks[row * blocks_per_row],
389 if (!y || !W || !x || M <= 0 || K <= 0) {
393 if ((K %
QK8_0) != 0) {
398 const int blocks_per_row = K /
QK8_0;
422 if (!A || !B || !
C || M <= 0 || N <= 0 || K <= 0) {
426 const float *A_use = A;
429 int strict_cached_layer = -1;
430 int strict_dump_layer = -1;
439 strict_dump_layer = strict_cached_layer >= 0
440 ? strict_cached_layer
444 if (dump_enabled && strict_dump_layer >= 0) {
446 ?
"strict_out_proj_input_cached"
447 :
"strict_out_proj_input_live",
450 (size_t) M * (
size_t) K);
455 if (dump_enabled && strict_dump_layer >= 0) {
459 (
size_t) M * (
size_t) N);
465#pragma omp parallel for schedule(static) if(M > 1)
466 for (
int m = 0; m < M; ++m) {
469 for (
int n = 0; n < N; ++n) {
470 C[m * N + n] += bias[n];
477 for (
int m = 0; m < M; ++m) {
480 for (
int n = 0; n < N; ++n) {
481 C[m * N + n] += bias[n];
486 if (dump_enabled && strict_dump_layer >= 0) {
490 (
size_t) M * (
size_t) N);
static const char * op_name(CKOpType op)
void gemv_q8_0(float *y, const void *W, const float *x, int M, int K)
Auto-dispatch GEMV for Q8_0 weights based on CPU features.
const float * ck_strict_consume_next_gemm_a(size_t elems)
void gemv_q8_0_q8_0_x4(float *y, const void *W, const void *x_q8, int M, int K)
void quantize_row_q8_0(const float *x, void *y, int k)
Quantize FP32 to Q8_0 format (scalar reference)
int ck_strict_parity_enabled(void)
Quantization block structures for weight-only quantization.
#define CK_FP32_TO_FP16(x)
static ck_q80_ggml_new_tensor_2d_fn ck_q80_resolve_ggml_new_tensor_2d(void)
void(* ck_q80_ggml_free_fn)(struct ggml_context *)
void *(* ck_q80_ggml_get_data_fn)(const struct ggml_tensor *)
static void quantize_row_q8_0_ref_local(const float *x, block_q8_0 *y, int k)
static int gemm_nt_q8_0_q8_0_ggml_strict(const float *A, const void *B, const float *bias, float *C, int M, int N, int K)
static ck_q80_ggml_nbytes_fn ck_q80_resolve_ggml_nbytes(void)
static ck_q80_ggml_free_fn ck_q80_resolve_ggml_free(void)
static ck_q80_ggml_get_data_f32_fn ck_q80_resolve_ggml_get_data_f32(void)
void gemv_q8_0_q8_0_contract(float *y, const void *W, const float *x, int M, int K)
static ck_q80_ggml_cpu_init_fn ck_q80_resolve_ggml_cpu_init(void)
struct ggml_cgraph *(* ck_q80_ggml_new_graph_fn)(struct ggml_context *)
static ck_q80_ggml_graph_compute_with_ctx_fn ck_q80_resolve_ggml_graph_compute_with_ctx(void)
struct ggml_tensor *(* ck_q80_ggml_new_tensor_2d_fn)(struct ggml_context *, enum ggml_type, int64_t, int64_t)
static int ck_q80_contract_cached_input_enabled(void)
static void ck_q80_contract_dump_tensor(const char *name, int layer_id, const float *data, size_t elem_count)
void vec_dot_q8_0_q8_0_ref(int n, float *s, const void *vx, const void *vy)
Quantized dot product: Q8_0 weights x Q8_0 input (scalar reference)
void(* ck_q80_ggml_build_forward_expand_fn)(struct ggml_cgraph *, struct ggml_tensor *)
static ck_q80_ggml_init_fn ck_q80_resolve_ggml_init(void)
static ck_q80_ggml_new_graph_fn ck_q80_resolve_ggml_new_graph(void)
static const char ck_q80_contract_magic[8]
struct ggml_tensor *(* ck_q80_ggml_mul_mat_fn)(struct ggml_context *, struct ggml_tensor *, struct ggml_tensor *)
void(* ck_q80_ggml_cpu_init_fn)(void)
enum ggml_status(* ck_q80_ggml_graph_compute_with_ctx_fn)(struct ggml_context *, struct ggml_cgraph *, int)
static const uint32_t ck_q80_contract_version
struct ggml_context *(* ck_q80_ggml_init_fn)(struct ggml_init_params)
size_t(* ck_q80_ggml_nbytes_fn)(const struct ggml_tensor *)
static int ck_q80_contract_cached_gemm_seq
float *(* ck_q80_ggml_get_data_f32_fn)(const struct ggml_tensor *)
static int ck_nearest_int_q8_0_ref(float fval)
static ck_q80_ggml_build_forward_expand_fn ck_q80_resolve_ggml_build_forward_expand(void)
static void gemv_q8_0_q8_0_ref_rows(float *y, const void *W, const void *x_q8, int M, int K)
#define CK_Q80_STACK_Q8_BLOCKS
static ck_q80_ggml_get_data_fn ck_q80_resolve_ggml_get_data(void)
static int ck_q80_contract_dump_enabled(void)
static ck_q80_ggml_mul_mat_fn ck_q80_resolve_ggml_mul_mat(void)
void gemm_nt_q8_0_q8_0_contract(const float *A, const void *B, const float *bias, float *C, int M, int N, int K)
__attribute__((visibility("default"))) CKTokenizer *ck_tokenizer_create(CKTokenizerType type)