Skip to content

Commit 8e549b4

Browse files
ikawrakowIwan Kawrakow
andauthored
Allow q8_0 cache on the CPU for FlashMLA-2 (#265)
Co-authored-by: Iwan Kawrakow <iwan.kawrakow@gmail.com>
1 parent 68a5b60 commit 8e549b4

1 file changed

Lines changed: 56 additions & 8 deletions

File tree

ggml/src/ggml.c

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10569,17 +10569,65 @@ static void ggml_compute_forward_dup_q(
1056910569
const struct ggml_compute_params * params,
1057010570
struct ggml_tensor * dst) {
1057110571

10572+
int64_t nrows = ggml_nrows(dst);
10573+
int ith = params->ith;
10574+
int nth = params->nth;
10575+
10576+
if (dst->type == GGML_TYPE_Q8_0 && dst->src[0]->type == GGML_TYPE_Q8_0 &&
10577+
ggml_are_same_shape(dst, dst->src[0])) {
10578+
10579+
// we assume src is transposed and that's why we are here
10580+
10581+
GGML_ASSERT(dst->ne[0] % QK8_0 == 0);
10582+
10583+
struct ggml_tensor * const src = dst->src[0];
10584+
GGML_ASSERT(src->nb[1] == sizeof(block_q8_0));
10585+
10586+
float aux[QK8_0];
10587+
10588+
int64_t n_per_thread = (nrows + nth - 1)/nth;
10589+
int64_t first_row = ith*n_per_thread;
10590+
if (first_row >= nrows) return;
10591+
int64_t last_row = MIN(first_row + n_per_thread, nrows);
10592+
10593+
int64_t nblock = dst->ne[0] / QK8_0;
10594+
for (int64_t ir = first_row; ir < last_row; ++ir) {
10595+
int64_t i3 = ir/(dst->ne[1]*dst->ne[2]);
10596+
int64_t i2 = (ir - i3*dst->ne[1]*dst->ne[2])/dst->ne[1];
10597+
int64_t i1 = ir - i3*dst->ne[1]*dst->ne[2] - i2*dst->ne[1];
10598+
int ib0 = i1/QK8_0;
10599+
int iq0 = i1%QK8_0;
10600+
for (int ib = 0; ib < nblock; ++ib) {
10601+
block_q8_0 * dst_q8 = (block_q8_0 *)((char *)dst->data + i1*dst->nb[1] + i2*dst->nb[2] + i3*dst->nb[3]);
10602+
float amax = 0;
10603+
for (int j = 0; j < QK8_0; ++j) {
10604+
int64_t i0 = ib*QK8_0 + j;
10605+
const block_q8_0 * src_q8 = (const block_q8_0 *)((const char *)src->data + i0*src->nb[0] + i2*src->nb[2] + i3*src->nb[3]);
10606+
float xi = GGML_FP16_TO_FP32(src_q8[ib0].d) * src_q8[ib0].qs[iq0];
10607+
aux[j] = xi;
10608+
xi = fabsf(xi);
10609+
amax = MAX(amax, xi);
10610+
}
10611+
float d = amax/127;
10612+
dst_q8[ib].d = GGML_FP32_TO_FP16(d);
10613+
if (d > 0) {
10614+
float id = 1/d;
10615+
for (int j = 0; j < QK8_0; ++j) dst_q8[ib].qs[j] = roundf(id*aux[j]);
10616+
} else {
10617+
memset(dst_q8[ib].qs, 0, QK8_0);
10618+
}
10619+
}
10620+
}
10621+
return;
10622+
}
10623+
1057210624
GGML_ASSERT(dst->type == GGML_TYPE_F32);
1057310625
struct ggml_tensor * src0 = dst->src[0];
1057410626
GGML_ASSERT(src0->ne[0] == dst->ne[0] && src0->nb[0] == ggml_type_size(src0->type));
1057510627

1057610628
ggml_to_float_t to_float = type_traits[src0->type].to_float;
1057710629
GGML_ASSERT(to_float != NULL);
1057810630

10579-
int64_t nrows = ggml_nrows(dst);
10580-
int ith = params->ith;
10581-
int nth = params->nth;
10582-
1058310631
int64_t n_per_thread = (nrows + nth - 1)/nth;
1058410632
int64_t first_row = ith*n_per_thread;
1058510633
if (first_row >= nrows) return;
@@ -10607,13 +10655,13 @@ static void ggml_compute_forward_dup(
1060710655

1060810656
const struct ggml_tensor * src0 = dst->src[0];
1060910657

10610-
if (src0->type == dst->type) {
10611-
ggml_compute_forward_dup_bytes(params, dst);
10658+
if (ggml_is_quantized(src0->type)) {
10659+
ggml_compute_forward_dup_q(params, dst);
1061210660
return;
1061310661
}
1061410662

10615-
if (ggml_is_quantized(src0->type)) {
10616-
ggml_compute_forward_dup_q(params, dst);
10663+
if (src0->type == dst->type) {
10664+
ggml_compute_forward_dup_bytes(params, dst);
1061710665
return;
1061810666
}
1061910667

0 commit comments

Comments
 (0)