@@ -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