← 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)
 
void gemm_nt_q8_0_q8_0_contract_m2 (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 gemm_q8_0_q8_0_m2n4_strided (float *C, int ldc, const void *W, const void *A_q8, 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 324 of file gemm_kernels_q8_0_q8_0_contract.c.

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

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 447 of file gemm_kernels_q8_0_q8_0_contract.c.

454{
455 if (!A || !B || !C || M <= 0 || N <= 0 || K <= 0) {
456 return;
457 }
458
459 const float *A_use = A;
460 const int strict = ck_strict_parity_enabled();
461 const int dump_enabled = strict && ck_q80_contract_dump_enabled();
462 int strict_cached_layer = -1;
463 int strict_dump_layer = -1;
465 const float *cached = ck_strict_consume_next_gemm_a((size_t) M * (size_t) K);
466 if (cached) {
467 A_use = cached;
468 strict_cached_layer = ck_q80_contract_cached_gemm_seq++;
469 }
470 }
471 if (dump_enabled) {
472 strict_dump_layer = strict_cached_layer >= 0
473 ? strict_cached_layer
475 }
476
477 if (dump_enabled && strict_dump_layer >= 0) {
478 ck_q80_contract_dump_tensor(strict_cached_layer >= 0
479 ? "strict_out_proj_input_cached"
480 : "strict_out_proj_input_live",
481 strict_dump_layer,
482 A_use,
483 (size_t) M * (size_t) K);
484 }
485
486 if (strict &&
487 gemm_nt_q8_0_q8_0_ggml_strict(A_use, B, bias, C, M, N, K)) {
488 if (dump_enabled && strict_dump_layer >= 0) {
489 ck_q80_contract_dump_tensor("strict_out_proj_output_ggml",
490 strict_dump_layer,
491 C,
492 (size_t) M * (size_t) N);
493 }
494 return;
495 }
496
497 if (!strict) {
498#pragma omp parallel for schedule(static) if(M > 1)
499 for (int m = 0; m < M; ++m) {
500 gemv_q8_0_q8_0_contract(&C[m * N], B, &A_use[m * K], N, K);
501 if (bias) {
502 for (int n = 0; n < N; ++n) {
503 C[m * N + n] += bias[n];
504 }
505 }
506 }
507 return;
508 }
509
510 for (int m = 0; m < M; ++m) {
511 gemv_q8_0_q8_0_contract(&C[m * N], B, &A_use[m * K], N, K);
512 if (bias) {
513 for (int n = 0; n < N; ++n) {
514 C[m * N + n] += bias[n];
515 }
516 }
517 }
518
519 if (dump_enabled && strict_dump_layer >= 0) {
520 ck_q80_contract_dump_tensor("strict_out_proj_output_fallback",
521 strict_dump_layer,
522 C,
523 (size_t) M * (size_t) N);
524 }
525}
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_contract_m2()

void gemm_nt_q8_0_q8_0_contract_m2 ( const float *  A,
const void *  B,
const float *  bias,
float *  C,
int  M,
int  N,
int  K 
)

Definition at line 418 of file gemm_kernels_q8_0_q8_0_contract.c.

421{
422 if (!A || !B || !C || M != 2 || N <= 0 || K <= 0 ||
423 (K % QK8_0) != 0 || K / QK8_0 > CK_Q80_STACK_Q8_BLOCKS) return;
424 const int nb = K / QK8_0;
428 quantize_row_q8_0_ref_local(A + K, x + nb, K);
429 } else {
430 quantize_row_q8_0(A, x, K);
431 quantize_row_q8_0(A + K, x + nb, K);
432 }
434 gemv_q8_0_q8_0_ref_rows(C, B, x, N, K);
435 gemv_q8_0_q8_0_ref_rows(C + N, B, x + nb, N, K);
436 } else {
437 gemm_q8_0_q8_0_m2n4_strided(C, N, B, x, 2, N, K);
438 }
439 if (bias) {
440 for (int n = 0; n < N; ++n) {
441 C[n] += bias[n];
442 C[(size_t)N + n] += bias[n];
443 }
444 }
445}
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
void gemm_q8_0_q8_0_m2n4_strided(float *C, int ldc, const void *W, const void *A_q8, int M, int N, int K)

References C, CK_Q80_STACK_Q8_BLOCKS, ck_strict_parity_enabled(), gemm_q8_0_q8_0_m2n4_strided(), gemv_q8_0_q8_0_ref_rows(), QK8_0, quantize_row_q8_0(), and quantize_row_q8_0_ref_local().

◆ 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().

◆ gemm_q8_0_q8_0_m2n4_strided()

void gemm_q8_0_q8_0_m2n4_strided ( float *  C,
int  ldc,
const void *  W,
const void *  A_q8,
int  M,
int  N,
int  K 
)

Definition at line 1502 of file gemm_kernels_q8_0.c.

1507{
1508#if defined(__AVX2__) || defined(__AVX512F__)
1509 if (ck_q8_0_q8_0_debug_ref() || (K % QK8_0) != 0) {
1510 const int nb = K / QK8_0;
1511 const block_q8_0 *a = (const block_q8_0 *)A_q8;
1512 for (int m = 0; m < M; ++m) {
1513 gemv_q8_0_q8_0(C + (size_t)m * (size_t)ldc, W,
1514 a + (size_t)m * (size_t)nb, N, K);
1515 }
1516 return;
1517 }
1518
1519 const block_q8_0 *w = (const block_q8_0 *)W;
1520 const block_q8_0 *a = (const block_q8_0 *)A_q8;
1521 const int nb = K / QK8_0;
1522 int m = 0;
1523 for (; m + 1 < M; m += 2) {
1524 const block_q8_0 *a0 = a + (size_t)(m + 0) * (size_t)nb;
1525 const block_q8_0 *a1 = a + (size_t)(m + 1) * (size_t)nb;
1526 int n = 0;
1527 for (; n + 3 < N; n += 4) {
1528 const block_q8_0 *w0 = w + (size_t)(n + 0) * (size_t)nb;
1529 const block_q8_0 *w1 = w + (size_t)(n + 1) * (size_t)nb;
1530 const block_q8_0 *w2 = w + (size_t)(n + 2) * (size_t)nb;
1531 const block_q8_0 *w3 = w + (size_t)(n + 3) * (size_t)nb;
1532 __m256 acc00 = _mm256_setzero_ps();
1533 __m256 acc01 = _mm256_setzero_ps();
1534 __m256 acc02 = _mm256_setzero_ps();
1535 __m256 acc03 = _mm256_setzero_ps();
1536 __m256 acc10 = _mm256_setzero_ps();
1537 __m256 acc11 = _mm256_setzero_ps();
1538 __m256 acc12 = _mm256_setzero_ps();
1539 __m256 acc13 = _mm256_setzero_ps();
1540
1541 for (int ib = 0; ib < nb; ++ib) {
1542 const __m256i qa0 = _mm256_loadu_si256((const __m256i *)a0[ib].qs);
1543 const __m256i qa1 = _mm256_loadu_si256((const __m256i *)a1[ib].qs);
1544 const __m256i qw0 = _mm256_loadu_si256((const __m256i *)w0[ib].qs);
1545 const __m256i qw1 = _mm256_loadu_si256((const __m256i *)w1[ib].qs);
1546 const __m256i qw2 = _mm256_loadu_si256((const __m256i *)w2[ib].qs);
1547 const __m256i qw3 = _mm256_loadu_si256((const __m256i *)w3[ib].qs);
1548 const float da0 = CK_FP16_TO_FP32(a0[ib].d);
1549 const float da1 = CK_FP16_TO_FP32(a1[ib].d);
1550 const float dw0 = CK_FP16_TO_FP32(w0[ib].d);
1551 const float dw1 = CK_FP16_TO_FP32(w1[ib].d);
1552 const float dw2 = CK_FP16_TO_FP32(w2[ib].d);
1553 const float dw3 = CK_FP16_TO_FP32(w3[ib].d);
1554 const __m256 p00 = mul_sum_i8_pairs_float_q8_0_avx2(qw0, qa0);
1555 const __m256 p01 = mul_sum_i8_pairs_float_q8_0_avx2(qw1, qa0);
1556 const __m256 p02 = mul_sum_i8_pairs_float_q8_0_avx2(qw2, qa0);
1557 const __m256 p03 = mul_sum_i8_pairs_float_q8_0_avx2(qw3, qa0);
1558 const __m256 p10 = mul_sum_i8_pairs_float_q8_0_avx2(qw0, qa1);
1559 const __m256 p11 = mul_sum_i8_pairs_float_q8_0_avx2(qw1, qa1);
1560 const __m256 p12 = mul_sum_i8_pairs_float_q8_0_avx2(qw2, qa1);
1561 const __m256 p13 = mul_sum_i8_pairs_float_q8_0_avx2(qw3, qa1);
1562#if defined(__FMA__)
1563 acc00 = _mm256_fmadd_ps(_mm256_set1_ps(dw0 * da0), p00, acc00);
1564 acc01 = _mm256_fmadd_ps(_mm256_set1_ps(dw1 * da0), p01, acc01);
1565 acc02 = _mm256_fmadd_ps(_mm256_set1_ps(dw2 * da0), p02, acc02);
1566 acc03 = _mm256_fmadd_ps(_mm256_set1_ps(dw3 * da0), p03, acc03);
1567 acc10 = _mm256_fmadd_ps(_mm256_set1_ps(dw0 * da1), p10, acc10);
1568 acc11 = _mm256_fmadd_ps(_mm256_set1_ps(dw1 * da1), p11, acc11);
1569 acc12 = _mm256_fmadd_ps(_mm256_set1_ps(dw2 * da1), p12, acc12);
1570 acc13 = _mm256_fmadd_ps(_mm256_set1_ps(dw3 * da1), p13, acc13);
1571#else
1572 acc00 = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(dw0 * da0), p00), acc00);
1573 acc01 = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(dw1 * da0), p01), acc01);
1574 acc02 = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(dw2 * da0), p02), acc02);
1575 acc03 = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(dw3 * da0), p03), acc03);
1576 acc10 = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(dw0 * da1), p10), acc10);
1577 acc11 = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(dw1 * da1), p11), acc11);
1578 acc12 = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(dw2 * da1), p12), acc12);
1579 acc13 = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(dw3 * da1), p13), acc13);
1580#endif
1581 }
1582
1583 C[(size_t)(m + 0) * (size_t)ldc + (n + 0)] = hsum_float_8_q8_0(acc00);
1584 C[(size_t)(m + 0) * (size_t)ldc + (n + 1)] = hsum_float_8_q8_0(acc01);
1585 C[(size_t)(m + 0) * (size_t)ldc + (n + 2)] = hsum_float_8_q8_0(acc02);
1586 C[(size_t)(m + 0) * (size_t)ldc + (n + 3)] = hsum_float_8_q8_0(acc03);
1587 C[(size_t)(m + 1) * (size_t)ldc + (n + 0)] = hsum_float_8_q8_0(acc10);
1588 C[(size_t)(m + 1) * (size_t)ldc + (n + 1)] = hsum_float_8_q8_0(acc11);
1589 C[(size_t)(m + 1) * (size_t)ldc + (n + 2)] = hsum_float_8_q8_0(acc12);
1590 C[(size_t)(m + 1) * (size_t)ldc + (n + 3)] = hsum_float_8_q8_0(acc13);
1591 }
1592 if (n < N) {
1593 gemv_q8_0_q8_0(C + (size_t)(m + 0) * (size_t)ldc + n,
1594 w + (size_t)n * (size_t)nb, a0, N - n, K);
1595 gemv_q8_0_q8_0(C + (size_t)(m + 1) * (size_t)ldc + n,
1596 w + (size_t)n * (size_t)nb, a1, N - n, K);
1597 }
1598 }
1599 if (m < M) {
1600 gemv_q8_0_q8_0_x4(C + (size_t)m * (size_t)ldc, W,
1601 a + (size_t)m * (size_t)nb, N, K);
1602 }
1603#else
1604 const int nb = K / QK8_0;
1605 const block_q8_0 *a = (const block_q8_0 *)A_q8;
1606 for (int m = 0; m < M; ++m) {
1607 gemv_q8_0_q8_0(C + (size_t)m * (size_t)ldc, W,
1608 a + (size_t)m * (size_t)nb, N, K);
1609 }
1610#endif
1611}
#define CK_FP16_TO_FP32(x)
static int ck_q8_0_q8_0_debug_ref(void)
void gemv_q8_0_q8_0_x4(float *y, const void *W, const void *x_q8, int M, int K)
void gemv_q8_0_q8_0(float *y, const void *W, const void *x_q8, int M, int K)
Matrix-vector multiply with Q8_0 weights and Q8_0 input.

Referenced by gemm_nt_q8_0_q8_0_contract_m2(), and gemm_q8_0_q8_0_m2n4().

◆ 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 385 of file gemm_kernels_q8_0_q8_0_contract.c.

390{
391 if (!y || !W || !x || M <= 0 || K <= 0) {
392 return;
393 }
394
395 if ((K % QK8_0) != 0) {
396 gemv_q8_0(y, W, x, M, K);
397 return;
398 }
399
400 const int blocks_per_row = K / QK8_0;
401 if (blocks_per_row > CK_Q80_STACK_Q8_BLOCKS) {
402 gemv_q8_0(y, W, x, M, K);
403 return;
404 }
405
408 quantize_row_q8_0_ref_local(x, x_q8, K);
409 gemv_q8_0_q8_0_ref_rows(y, W, x_q8, M, K);
410 return;
411 }
412 quantize_row_q8_0(x, x_q8, K);
413 gemv_q8_0_q8_0_x4(y, W, x_q8, M, K);
414}
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)

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 366 of file gemm_kernels_q8_0_q8_0_contract.c.

371{
372 const block_q8_0 *w_blocks = (const block_q8_0 *)W;
373 const int blocks_per_row = K / QK8_0;
374
375 for (int row = 0; row < M; ++row) {
377 K,
378 &y[row],
379 &w_blocks[row * blocks_per_row],
380 x_q8
381 );
382 }
383}
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 gemm_nt_q8_0_q8_0_contract_m2(), and 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 332 of file gemm_kernels_q8_0_q8_0_contract.c.

335{
336 const int nb = k / QK8_0;
337
338 for (int i = 0; i < nb; ++i) {
339 float amax = 0.0f;
340 for (int j = 0; j < QK8_0; ++j) {
341 const float v = x[i * QK8_0 + j];
342 const float av = fabsf(v);
343 if (av > amax) {
344 amax = av;
345 }
346 }
347
348 const float d = amax / 127.0f;
349 const float id = d != 0.0f ? 1.0f / d : 0.0f;
350 y[i].d = CK_FP32_TO_FP16(d);
351
352 for (int j = 0; j < QK8_0; ++j) {
353 const float x0 = x[i * QK8_0 + j] * id;
354 int q = ck_nearest_int_q8_0_ref(x0);
355 if (q > 127) {
356 q = 127;
357 }
358 if (q < -127) {
359 q = -127;
360 }
361 y[i].qs[j] = (int8_t) q;
362 }
363 }
364}
#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 gemm_nt_q8_0_q8_0_contract_m2(), and 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}

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().