← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
gemm_kernels_q8_0_q8_0_contract.c File Reference

FP32 API adapters that enforce Q8_0 x Q8_0 activation contract. More...

#include "ckernel_engine.h"
#include "ckernel_quant.h"
#include "ggml_runtime_compat.h"
#include <dlfcn.h>
#include <stdint.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 
#define CK_Q80_STACK_Q8_BLOCKS   1024
 

Typedefs

typedef void(* ck_q80_ggml_build_forward_expand_fn) (struct ggml_cgraph *, struct ggml_tensor *)
 
typedef void(* ck_q80_ggml_cpu_init_fn) (void)
 
typedef void(* ck_q80_ggml_free_fn) (struct ggml_context *)
 
typedef float *(* ck_q80_ggml_get_data_f32_fn) (const struct ggml_tensor *)
 
typedef void *(* ck_q80_ggml_get_data_fn) (const struct ggml_tensor *)
 
typedef enum ggml_status(* ck_q80_ggml_graph_compute_with_ctx_fn) (struct ggml_context *, struct ggml_cgraph *, int)
 
typedef struct ggml_context *(* ck_q80_ggml_init_fn) (struct ggml_init_params)
 
typedef struct ggml_tensor *(* ck_q80_ggml_mul_mat_fn) (struct ggml_context *, struct ggml_tensor *, struct ggml_tensor *)
 
typedef size_t(* ck_q80_ggml_nbytes_fn) (const struct ggml_tensor *)
 
typedef struct ggml_cgraph *(* ck_q80_ggml_new_graph_fn) (struct ggml_context *)
 
typedef struct ggml_tensor *(* ck_q80_ggml_new_tensor_2d_fn) (struct ggml_context *, enum ggml_type, int64_t, int64_t)
 

Functions

static int ck_nearest_int_q8_0_ref (float fval)
 
static int ck_q80_contract_cached_input_enabled (void)
 
static int ck_q80_contract_dump_enabled (void)
 
static void ck_q80_contract_dump_tensor (const char *name, int layer_id, const float *data, size_t elem_count)
 
static ck_q80_ggml_build_forward_expand_fn ck_q80_resolve_ggml_build_forward_expand (void)
 
static ck_q80_ggml_cpu_init_fn ck_q80_resolve_ggml_cpu_init (void)
 
static ck_q80_ggml_free_fn ck_q80_resolve_ggml_free (void)
 
static ck_q80_ggml_get_data_fn ck_q80_resolve_ggml_get_data (void)
 
static ck_q80_ggml_get_data_f32_fn ck_q80_resolve_ggml_get_data_f32 (void)
 
static ck_q80_ggml_graph_compute_with_ctx_fn ck_q80_resolve_ggml_graph_compute_with_ctx (void)
 
static ck_q80_ggml_init_fn ck_q80_resolve_ggml_init (void)
 
static ck_q80_ggml_mul_mat_fn ck_q80_resolve_ggml_mul_mat (void)
 
static ck_q80_ggml_nbytes_fn ck_q80_resolve_ggml_nbytes (void)
 
static ck_q80_ggml_new_graph_fn ck_q80_resolve_ggml_new_graph (void)
 
static ck_q80_ggml_new_tensor_2d_fn ck_q80_resolve_ggml_new_tensor_2d (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)
 
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)
 
void gemv_q8_0_q8_0_contract (float *y, const void *W, const float *x, int M, int K)
 
static void gemv_q8_0_q8_0_ref_rows (float *y, const void *W, const void *x_q8, int M, int K)
 
static void quantize_row_q8_0_ref_local (const float *x, block_q8_0 *y, int k)
 
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)
 

Variables

static int ck_q80_contract_cached_gemm_seq = 0
 
static const char ck_q80_contract_magic [8] = {'C', 'K', 'D', 'M', 'P', '\0', '\0', '\0'}
 
static const uint32_t ck_q80_contract_version = 1u
 

Detailed Description

FP32 API adapters that enforce Q8_0 x Q8_0 activation contract.

Definition in file gemm_kernels_q8_0_q8_0_contract.c.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 7 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ CK_Q80_STACK_Q8_BLOCKS

#define CK_Q80_STACK_Q8_BLOCKS   1024

Definition at line 21 of file gemm_kernels_q8_0_q8_0_contract.c.

Typedef Documentation

◆ ck_q80_ggml_build_forward_expand_fn

typedef void(* ck_q80_ggml_build_forward_expand_fn) (struct ggml_cgraph *, struct ggml_tensor *)

Definition at line 91 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_cpu_init_fn

typedef void(* ck_q80_ggml_cpu_init_fn) (void)

Definition at line 93 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_free_fn

typedef void(* ck_q80_ggml_free_fn) (struct ggml_context *)

Definition at line 87 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_get_data_f32_fn

typedef float *(* ck_q80_ggml_get_data_f32_fn) (const struct ggml_tensor *)

Definition at line 95 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_get_data_fn

typedef void *(* ck_q80_ggml_get_data_fn) (const struct ggml_tensor *)

Definition at line 94 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_graph_compute_with_ctx_fn

typedef enum ggml_status(* ck_q80_ggml_graph_compute_with_ctx_fn) (struct ggml_context *, struct ggml_cgraph *, int)

Definition at line 91 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_init_fn

typedef struct ggml_context *(* ck_q80_ggml_init_fn) (struct ggml_init_params)

Definition at line 52 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_mul_mat_fn

typedef struct ggml_tensor *(* ck_q80_ggml_mul_mat_fn) (struct ggml_context *, struct ggml_tensor *, struct ggml_tensor *)

Definition at line 87 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_nbytes_fn

typedef size_t(* ck_q80_ggml_nbytes_fn) (const struct ggml_tensor *)

Definition at line 96 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_new_graph_fn

typedef struct ggml_cgraph *(* ck_q80_ggml_new_graph_fn) (struct ggml_context *)

Definition at line 87 of file gemm_kernels_q8_0_q8_0_contract.c.

◆ ck_q80_ggml_new_tensor_2d_fn

typedef struct ggml_tensor *(* ck_q80_ggml_new_tensor_2d_fn) (struct ggml_context *, enum ggml_type, int64_t, int64_t)

Definition at line 87 of file gemm_kernels_q8_0_q8_0_contract.c.

Function Documentation

◆ ck_nearest_int_q8_0_ref()

static int ck_nearest_int_q8_0_ref ( float  fval)
inlinestatic

Definition at line 322 of file gemm_kernels_q8_0_q8_0_contract.c.

323{
324 float val = fval + 12582912.f;
325 int i;
326 memcpy(&i, &val, sizeof(int));
327 return (i & 0x007fffff) - 0x00400000;
328}

Referenced by quantize_row_q8_0_ref_local().

◆ ck_q80_contract_cached_input_enabled()

static int ck_q80_contract_cached_input_enabled ( void  )
static

Definition at line 46 of file gemm_kernels_q8_0_q8_0_contract.c.

47{
48 const char *v = getenv("CK_STRICT_GEMM_USE_CACHED_A");
49 return v && v[0] && strcmp(v, "0") != 0;
50}

Referenced by gemm_nt_q8_0_q8_0_contract().

◆ ck_q80_contract_dump_enabled()

static int ck_q80_contract_dump_enabled ( void  )
static

Definition at line 40 of file gemm_kernels_q8_0_q8_0_contract.c.

41{
42 const char *v = getenv("CK_STRICT_GEMM_DUMP");
43 return v && v[0] && strcmp(v, "0") != 0;
44}

Referenced by gemm_nt_q8_0_q8_0_contract().

◆ ck_q80_contract_dump_tensor()

static void ck_q80_contract_dump_tensor ( const char *  name,
int  layer_id,
const float *  data,
size_t  elem_count 
)
static

Definition at line 52 of file gemm_kernels_q8_0_q8_0_contract.c.

56{
57 const char *dir = getenv("CK_PARITY_DIR");
58 if (!dir || !dir[0] || !data || elem_count == 0 || !name || !name[0]) {
59 return;
60 }
61
62 char path[4096];
63 snprintf(path, sizeof(path), "%s/%s", dir, "strict_internal.bin");
64 FILE *f = fopen(path, "ab");
65 if (!f) {
66 return;
67 }
68
69 ck_q80_contract_dump_header_t h;
70 memset(&h, 0, sizeof(h));
71 memcpy(h.magic, ck_q80_contract_magic, sizeof(ck_q80_contract_magic));
72 h.version = ck_q80_contract_version;
73 h.layer_id = layer_id;
74 strncpy(h.op_name, name, sizeof(h.op_name) - 1);
75 h.dtype = 0u;
76 h.rank = 1u;
77 h.shape[0] = (int64_t) elem_count;
78 h.elem_count = (uint32_t) elem_count;
79 h.token_id = 0;
80
81 fwrite(&h, sizeof(h), 1, f);
82 fwrite(data, sizeof(float), elem_count, f);
83 fclose(f);
84}
static const char ck_q80_contract_magic[8]
static const uint32_t ck_q80_contract_version

References ck_q80_contract_magic, and ck_q80_contract_version.

Referenced by gemm_nt_q8_0_q8_0_contract().

◆ ck_q80_resolve_ggml_build_forward_expand()

static ck_q80_ggml_build_forward_expand_fn ck_q80_resolve_ggml_build_forward_expand ( void  )
static

Definition at line 153 of file gemm_kernels_q8_0_q8_0_contract.c.

154{
155 static int tried = 0;
157 if (!tried) {
158 tried = 1;
159 fn = (ck_q80_ggml_build_forward_expand_fn) dlsym(RTLD_DEFAULT, "ggml_build_forward_expand");
160 }
161 return fn;
162}
#define RTLD_DEFAULT
void(* ck_q80_ggml_build_forward_expand_fn)(struct ggml_cgraph *, struct ggml_tensor *)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_cpu_init()

static ck_q80_ggml_cpu_init_fn ck_q80_resolve_ggml_cpu_init ( void  )
static

Definition at line 175 of file gemm_kernels_q8_0_q8_0_contract.c.

176{
177 static int tried = 0;
178 static ck_q80_ggml_cpu_init_fn fn = NULL;
179 if (!tried) {
180 tried = 1;
181 fn = (ck_q80_ggml_cpu_init_fn) dlsym(RTLD_DEFAULT, "ggml_cpu_init");
182 }
183 return fn;
184}
void(* ck_q80_ggml_cpu_init_fn)(void)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_free()

static ck_q80_ggml_free_fn ck_q80_resolve_ggml_free ( void  )
static

Definition at line 109 of file gemm_kernels_q8_0_q8_0_contract.c.

110{
111 static int tried = 0;
112 static ck_q80_ggml_free_fn fn = NULL;
113 if (!tried) {
114 tried = 1;
115 fn = (ck_q80_ggml_free_fn) dlsym(RTLD_DEFAULT, "ggml_free");
116 }
117 return fn;
118}
void(* ck_q80_ggml_free_fn)(struct ggml_context *)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_get_data()

static ck_q80_ggml_get_data_fn ck_q80_resolve_ggml_get_data ( void  )
static

Definition at line 186 of file gemm_kernels_q8_0_q8_0_contract.c.

187{
188 static int tried = 0;
189 static ck_q80_ggml_get_data_fn fn = NULL;
190 if (!tried) {
191 tried = 1;
192 fn = (ck_q80_ggml_get_data_fn) dlsym(RTLD_DEFAULT, "ggml_get_data");
193 }
194 return fn;
195}
void *(* ck_q80_ggml_get_data_fn)(const struct ggml_tensor *)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_get_data_f32()

static ck_q80_ggml_get_data_f32_fn ck_q80_resolve_ggml_get_data_f32 ( void  )
static

Definition at line 197 of file gemm_kernels_q8_0_q8_0_contract.c.

198{
199 static int tried = 0;
200 static ck_q80_ggml_get_data_f32_fn fn = NULL;
201 if (!tried) {
202 tried = 1;
203 fn = (ck_q80_ggml_get_data_f32_fn) dlsym(RTLD_DEFAULT, "ggml_get_data_f32");
204 }
205 return fn;
206}
float *(* ck_q80_ggml_get_data_f32_fn)(const struct ggml_tensor *)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_graph_compute_with_ctx()

static ck_q80_ggml_graph_compute_with_ctx_fn ck_q80_resolve_ggml_graph_compute_with_ctx ( void  )
static

Definition at line 164 of file gemm_kernels_q8_0_q8_0_contract.c.

165{
166 static int tried = 0;
168 if (!tried) {
169 tried = 1;
170 fn = (ck_q80_ggml_graph_compute_with_ctx_fn) dlsym(RTLD_DEFAULT, "ggml_graph_compute_with_ctx");
171 }
172 return fn;
173}
enum ggml_status(* ck_q80_ggml_graph_compute_with_ctx_fn)(struct ggml_context *, struct ggml_cgraph *, int)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_init()

static ck_q80_ggml_init_fn ck_q80_resolve_ggml_init ( void  )
static

Definition at line 98 of file gemm_kernels_q8_0_q8_0_contract.c.

99{
100 static int tried = 0;
101 static ck_q80_ggml_init_fn fn = NULL;
102 if (!tried) {
103 tried = 1;
104 fn = (ck_q80_ggml_init_fn) dlsym(RTLD_DEFAULT, "ggml_init");
105 }
106 return fn;
107}
struct ggml_context *(* ck_q80_ggml_init_fn)(struct ggml_init_params)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_mul_mat()

static ck_q80_ggml_mul_mat_fn ck_q80_resolve_ggml_mul_mat ( void  )
static

Definition at line 131 of file gemm_kernels_q8_0_q8_0_contract.c.

132{
133 static int tried = 0;
134 static ck_q80_ggml_mul_mat_fn fn = NULL;
135 if (!tried) {
136 tried = 1;
137 fn = (ck_q80_ggml_mul_mat_fn) dlsym(RTLD_DEFAULT, "ggml_mul_mat");
138 }
139 return fn;
140}
struct ggml_tensor *(* ck_q80_ggml_mul_mat_fn)(struct ggml_context *, struct ggml_tensor *, struct ggml_tensor *)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_nbytes()

static ck_q80_ggml_nbytes_fn ck_q80_resolve_ggml_nbytes ( void  )
static

Definition at line 208 of file gemm_kernels_q8_0_q8_0_contract.c.

209{
210 static int tried = 0;
211 static ck_q80_ggml_nbytes_fn fn = NULL;
212 if (!tried) {
213 tried = 1;
214 fn = (ck_q80_ggml_nbytes_fn) dlsym(RTLD_DEFAULT, "ggml_nbytes");
215 }
216 return fn;
217}
size_t(* ck_q80_ggml_nbytes_fn)(const struct ggml_tensor *)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_new_graph()

static ck_q80_ggml_new_graph_fn ck_q80_resolve_ggml_new_graph ( void  )
static

Definition at line 142 of file gemm_kernels_q8_0_q8_0_contract.c.

143{
144 static int tried = 0;
145 static ck_q80_ggml_new_graph_fn fn = NULL;
146 if (!tried) {
147 tried = 1;
148 fn = (ck_q80_ggml_new_graph_fn) dlsym(RTLD_DEFAULT, "ggml_new_graph");
149 }
150 return fn;
151}
struct ggml_cgraph *(* ck_q80_ggml_new_graph_fn)(struct ggml_context *)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ ck_q80_resolve_ggml_new_tensor_2d()

static ck_q80_ggml_new_tensor_2d_fn ck_q80_resolve_ggml_new_tensor_2d ( void  )
static

Definition at line 120 of file gemm_kernels_q8_0_q8_0_contract.c.

121{
122 static int tried = 0;
123 static ck_q80_ggml_new_tensor_2d_fn fn = NULL;
124 if (!tried) {
125 tried = 1;
126 fn = (ck_q80_ggml_new_tensor_2d_fn) dlsym(RTLD_DEFAULT, "ggml_new_tensor_2d");
127 }
128 return fn;
129}
struct ggml_tensor *(* ck_q80_ggml_new_tensor_2d_fn)(struct ggml_context *, enum ggml_type, int64_t, int64_t)

References RTLD_DEFAULT.

Referenced by gemm_nt_q8_0_q8_0_ggml_strict().

◆ gemm_nt_q8_0_q8_0_contract()

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 
)

Definition at line 414 of file gemm_kernels_q8_0_q8_0_contract.c.

421{
422 if (!A || !B || !C || M <= 0 || N <= 0 || K <= 0) {
423 return;
424 }
425
426 const float *A_use = A;
427 const int strict = ck_strict_parity_enabled();
428 const int dump_enabled = strict && ck_q80_contract_dump_enabled();
429 int strict_cached_layer = -1;
430 int strict_dump_layer = -1;
432 const float *cached = ck_strict_consume_next_gemm_a((size_t) M * (size_t) K);
433 if (cached) {
434 A_use = cached;
435 strict_cached_layer = ck_q80_contract_cached_gemm_seq++;
436 }
437 }
438 if (dump_enabled) {
439 strict_dump_layer = strict_cached_layer >= 0
440 ? strict_cached_layer
442 }
443
444 if (dump_enabled && strict_dump_layer >= 0) {
445 ck_q80_contract_dump_tensor(strict_cached_layer >= 0
446 ? "strict_out_proj_input_cached"
447 : "strict_out_proj_input_live",
448 strict_dump_layer,
449 A_use,
450 (size_t) M * (size_t) K);
451 }
452
453 if (strict &&
454 gemm_nt_q8_0_q8_0_ggml_strict(A_use, B, bias, C, M, N, K)) {
455 if (dump_enabled && strict_dump_layer >= 0) {
456 ck_q80_contract_dump_tensor("strict_out_proj_output_ggml",
457 strict_dump_layer,
458 C,
459 (size_t) M * (size_t) N);
460 }
461 return;
462 }
463
464 if (!strict) {
465#pragma omp parallel for schedule(static) if(M > 1)
466 for (int m = 0; m < M; ++m) {
467 gemv_q8_0_q8_0_contract(&C[m * N], B, &A_use[m * K], N, K);
468 if (bias) {
469 for (int n = 0; n < N; ++n) {
470 C[m * N + n] += bias[n];
471 }
472 }
473 }
474 return;
475 }
476
477 for (int m = 0; m < M; ++m) {
478 gemv_q8_0_q8_0_contract(&C[m * N], B, &A_use[m * K], N, K);
479 if (bias) {
480 for (int n = 0; n < N; ++n) {
481 C[m * N + n] += bias[n];
482 }
483 }
484 }
485
486 if (dump_enabled && strict_dump_layer >= 0) {
487 ck_q80_contract_dump_tensor("strict_out_proj_output_fallback",
488 strict_dump_layer,
489 C,
490 (size_t) M * (size_t) N);
491 }
492}
const float * ck_strict_consume_next_gemm_a(size_t elems)
int ck_strict_parity_enabled(void)
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)
void gemv_q8_0_q8_0_contract(float *y, const void *W, const float *x, int M, int K)
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)
static int ck_q80_contract_cached_gemm_seq
static int ck_q80_contract_dump_enabled(void)
#define C(color)
Definition show_config.c:39

References C, ck_q80_contract_cached_gemm_seq, ck_q80_contract_cached_input_enabled(), ck_q80_contract_dump_enabled(), ck_q80_contract_dump_tensor(), ck_strict_consume_next_gemm_a(), ck_strict_parity_enabled(), gemm_nt_q8_0_q8_0_ggml_strict(), and gemv_q8_0_q8_0_contract().

◆ gemm_nt_q8_0_q8_0_ggml_strict()

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

Definition at line 219 of file gemm_kernels_q8_0_q8_0_contract.c.

226{
238
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 ||
242 !ggml_nbytes_fn) {
243 return 0;
244 }
245
246 ggml_cpu_init_fn();
247
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;
250
251 struct ggml_init_params params = {
253 .mem_buffer = NULL,
254 .no_alloc = false,
255 };
256 struct ggml_context *ctx = ggml_init_fn(params);
257 if (!ctx) {
258 return 0;
259 }
260
261 int ok = 0;
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);
264 if (!w || !x) {
265 ggml_free_fn(ctx);
266 return 0;
267 }
268
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) {
273 ggml_free_fn(ctx);
274 return 0;
275 }
276
277 memcpy(w_data, B, w_nbytes);
278 memcpy(x_data, A, (size_t) M * (size_t) K * sizeof(float));
279
280 struct ggml_tensor *y = ggml_mul_mat_fn(ctx, w, x);
281 if (!y) {
282 ggml_free_fn(ctx);
283 return 0;
284 }
285
286 struct ggml_cgraph *gf = ggml_new_graph_fn(ctx);
287 if (!gf) {
288 ggml_free_fn(ctx);
289 return 0;
290 }
291 ggml_build_forward_expand_fn(gf, y);
292 if (ggml_graph_compute_with_ctx_fn(ctx, gf, 1) != GGML_STATUS_SUCCESS) {
293 ggml_free_fn(ctx);
294 return 0;
295 }
296
297 {
298 const float *src = ggml_get_data_f32_fn(y);
299 if (!src) {
300 ggml_free_fn(ctx);
301 return 0;
302 }
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));
307 if (bias) {
308 for (int n = 0; n < N; ++n) {
309 C[(size_t) m * (size_t) N + (size_t) n] += bias[n];
310 }
311 }
312 }
313 }
314
315 ok = 1;
316 ggml_free_fn(ctx);
317 return ok;
318}
static ck_q80_ggml_new_tensor_2d_fn ck_q80_resolve_ggml_new_tensor_2d(void)
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)
static ck_q80_ggml_cpu_init_fn ck_q80_resolve_ggml_cpu_init(void)
static ck_q80_ggml_graph_compute_with_ctx_fn ck_q80_resolve_ggml_graph_compute_with_ctx(void)
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 ck_q80_ggml_build_forward_expand_fn ck_q80_resolve_ggml_build_forward_expand(void)
static ck_q80_ggml_get_data_fn ck_q80_resolve_ggml_get_data(void)
static ck_q80_ggml_mul_mat_fn ck_q80_resolve_ggml_mul_mat(void)
@ GGML_STATUS_SUCCESS
@ GGML_TYPE_F32
@ GGML_TYPE_Q8_0

References C, ck_q80_resolve_ggml_build_forward_expand(), ck_q80_resolve_ggml_cpu_init(), ck_q80_resolve_ggml_free(), ck_q80_resolve_ggml_get_data(), ck_q80_resolve_ggml_get_data_f32(), ck_q80_resolve_ggml_graph_compute_with_ctx(), ck_q80_resolve_ggml_init(), ck_q80_resolve_ggml_mul_mat(), ck_q80_resolve_ggml_nbytes(), ck_q80_resolve_ggml_new_graph(), ck_q80_resolve_ggml_new_tensor_2d(), GGML_STATUS_SUCCESS, GGML_TYPE_F32, GGML_TYPE_Q8_0, and ggml_init_params::mem_size.

Referenced by gemm_nt_q8_0_q8_0_contract().

◆ gemv_q8_0_q8_0_contract()

void gemv_q8_0_q8_0_contract ( float *  y,
const void *  W,
const float *  x,
int  M,
int  K 
)

Definition at line 383 of file gemm_kernels_q8_0_q8_0_contract.c.

388{
389 if (!y || !W || !x || M <= 0 || K <= 0) {
390 return;
391 }
392
393 if ((K % QK8_0) != 0) {
394 gemv_q8_0(y, W, x, M, K);
395 return;
396 }
397
398 const int blocks_per_row = K / QK8_0;
399 if (blocks_per_row > CK_Q80_STACK_Q8_BLOCKS) {
400 gemv_q8_0(y, W, x, M, K);
401 return;
402 }
403
406 quantize_row_q8_0_ref_local(x, x_q8, K);
407 gemv_q8_0_q8_0_ref_rows(y, W, x_q8, M, K);
408 return;
409 }
410 quantize_row_q8_0(x, x_q8, K);
411 gemv_q8_0_q8_0_x4(y, W, x_q8, M, K);
412}
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.
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)
#define QK8_0
static void quantize_row_q8_0_ref_local(const float *x, block_q8_0 *y, int k)
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

References CK_Q80_STACK_Q8_BLOCKS, ck_strict_parity_enabled(), gemv_q8_0(), gemv_q8_0_q8_0_ref_rows(), gemv_q8_0_q8_0_x4(), QK8_0, quantize_row_q8_0(), and quantize_row_q8_0_ref_local().

Referenced by gemm_nt_q8_0_q8_0_contract().

◆ gemv_q8_0_q8_0_ref_rows()

static void gemv_q8_0_q8_0_ref_rows ( float *  y,
const void *  W,
const void *  x_q8,
int  M,
int  K 
)
static

Definition at line 364 of file gemm_kernels_q8_0_q8_0_contract.c.

369{
370 const block_q8_0 *w_blocks = (const block_q8_0 *)W;
371 const int blocks_per_row = K / QK8_0;
372
373 for (int row = 0; row < M; ++row) {
375 K,
376 &y[row],
377 &w_blocks[row * blocks_per_row],
378 x_q8
379 );
380 }
381}
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)

References QK8_0, and vec_dot_q8_0_q8_0_ref().

Referenced by gemv_q8_0_q8_0_contract().

◆ quantize_row_q8_0_ref_local()

static void quantize_row_q8_0_ref_local ( const float *  x,
block_q8_0 y,
int  k 
)
static

Definition at line 330 of file gemm_kernels_q8_0_q8_0_contract.c.

333{
334 const int nb = k / QK8_0;
335
336 for (int i = 0; i < nb; ++i) {
337 float amax = 0.0f;
338 for (int j = 0; j < QK8_0; ++j) {
339 const float v = x[i * QK8_0 + j];
340 const float av = fabsf(v);
341 if (av > amax) {
342 amax = av;
343 }
344 }
345
346 const float d = amax / 127.0f;
347 const float id = d != 0.0f ? 1.0f / d : 0.0f;
348 y[i].d = CK_FP32_TO_FP16(d);
349
350 for (int j = 0; j < QK8_0; ++j) {
351 const float x0 = x[i * QK8_0 + j] * id;
352 int q = ck_nearest_int_q8_0_ref(x0);
353 if (q > 127) {
354 q = 127;
355 }
356 if (q < -127) {
357 q = -127;
358 }
359 y[i].qs[j] = (int8_t) q;
360 }
361 }
362}
#define CK_FP32_TO_FP16(x)
static int ck_nearest_int_q8_0_ref(float fval)
int8_t qs[32]
int32_t id
Definition tokenizer.h:316

References CK_FP32_TO_FP16, ck_nearest_int_q8_0_ref(), block_q8_0::d, id, QK8_0, and block_q8_0::qs.

Referenced by gemv_q8_0_q8_0_contract().

◆ vec_dot_q8_0_q8_0_ref()

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)

Parameters
nNumber of elements (must be multiple of 32)
sOutput: scalar dot product result
vxQ8_0 quantized weights
vyQ8_0 quantized input

Definition at line 1140 of file gemm_kernels_q8_0.c.

1141{
1142 const int qk = QK8_0; /* 32 */
1143 const int nb = n / qk;
1144
1145 const block_q8_0 *x = (const block_q8_0 *)vx;
1146 const block_q8_0 *y = (const block_q8_0 *)vy;
1147
1148 float sumf = 0.0f;
1149
1150 for (int ib = 0; ib < nb; ib++) {
1151 int sumi = 0;
1152
1153 for (int j = 0; j < qk; j++) {
1154 sumi += x[ib].qs[j] * y[ib].qs[j];
1155 }
1156
1157 sumf += sumi * (CK_FP16_TO_FP32(x[ib].d) * CK_FP16_TO_FP32(y[ib].d));
1158 }
1159
1160 *s = sumf;
1161}
#define CK_FP16_TO_FP32(x)

References CK_FP16_TO_FP32, QK8_0, and block_q8_0::qs.

Referenced by gemv_q8_0_q8_0_ref_rows(), and vec_dot_q8_0_q8_0().

Variable Documentation

◆ ck_q80_contract_cached_gemm_seq

int ck_q80_contract_cached_gemm_seq = 0
static

Definition at line 38 of file gemm_kernels_q8_0_q8_0_contract.c.

Referenced by gemm_nt_q8_0_q8_0_contract().

◆ ck_q80_contract_magic

const char ck_q80_contract_magic[8] = {'C', 'K', 'D', 'M', 'P', '\0', '\0', '\0'}
static

Definition at line 36 of file gemm_kernels_q8_0_q8_0_contract.c.

36{'C', 'K', 'D', 'M', 'P', '\0', '\0', '\0'};

Referenced by ck_q80_contract_dump_tensor().

◆ ck_q80_contract_version

const uint32_t ck_q80_contract_version = 1u
static

Definition at line 37 of file gemm_kernels_q8_0_q8_0_contract.c.

Referenced by ck_q80_contract_dump_tensor().