Skip to content

Commit 68380ae

Browse files
authored
ggml-cpu: Optimized risc-v cpu q1_0 dot
1 parent cc97e45 commit 68380ae

2 files changed

Lines changed: 98 additions & 1 deletion

File tree

ggml/src/ggml-cpu/arch-fallback.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@
203203
#elif defined(__riscv)
204204
// quants.c
205205
#define ggml_vec_dot_nvfp4_q8_0_generic ggml_vec_dot_nvfp4_q8_0
206-
#define ggml_vec_dot_q1_0_q8_0_generic ggml_vec_dot_q1_0_q8_0
207206
// repack.cpp
208207
#define ggml_quantize_mat_q8_0_4x1_generic ggml_quantize_mat_q8_0_4x1
209208
#define ggml_quantize_mat_q8_0_4x4_generic ggml_quantize_mat_q8_0_4x4

ggml/src/ggml-cpu/arch/riscv/quants.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,104 @@ void ggml_vec_dot_q8_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const voi
480480
#endif
481481
}
482482

483+
#if defined(__riscv_v)
484+
static NOINLINE void ggml_vec_dot_q1_0_q8_0_vl256(const int n, float * GGML_RESTRICT s, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy) {
485+
const int qk = QK1_0;
486+
const int nb = n / qk;
487+
assert(n % qk == 0);
488+
489+
const block_q1_0 * GGML_RESTRICT x = vx;
490+
const block_q8_0 * GGML_RESTRICT y = vy;
491+
492+
//LMUL = 1, VLMAX = 32
493+
const size_t vl32 = __riscv_vsetvl_e8m1(32);
494+
assert(vl32 == 32);
495+
496+
const vint16m1_t zero = __riscv_vmv_v_x_i16m1(0, 1);
497+
498+
float sumf = 0;
499+
500+
for (int ib = 0; ib < nb; ++ib) {
501+
const float d0 = GGML_CPU_FP16_TO_FP32(x[ib].d);
502+
503+
float acc = 0;
504+
505+
for (int k = 0; k < 4; ++k) {
506+
const block_q8_0 * GGML_RESTRICT yb = &y[ib * 4 + k];
507+
const vbool8_t is_not_zero = __riscv_vlm_v_b8(x[ib].qs + 4 * k, vl32);
508+
509+
const vint8m1_t qy = __riscv_vle8_v_i8m1(yb->qs, vl32);
510+
const vint8m1_t neg_qy = __riscv_vneg_v_i8m1(qy, vl32);
511+
const vint8m1_t sy = __riscv_vmerge_vvm_i8m1(neg_qy, qy, is_not_zero, vl32);
512+
513+
const vint16m1_t red = __riscv_vwredsum_vs_i8m1_i16m1(sy, zero, vl32);
514+
acc += GGML_CPU_FP16_TO_FP32(yb->d) * (float)__riscv_vmv_x_s_i16m1_i16(red);
515+
}
516+
517+
sumf += d0 * acc;
518+
}
519+
520+
*s = sumf;
521+
}
522+
523+
static NOINLINE void ggml_vec_dot_q1_0_q8_0_vl128(const int n, float * GGML_RESTRICT s, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy) {
524+
const int qk = QK1_0;
525+
const int nb = n / qk;
526+
assert(n % qk == 0);
527+
528+
const block_q1_0 * GGML_RESTRICT x = vx;
529+
const block_q8_0 * GGML_RESTRICT y = vy;
530+
531+
//LMUL = 2, VLMAX = 32
532+
const size_t vl32 = __riscv_vsetvl_e8m2(32);
533+
assert(vl32 == 32);
534+
535+
const vint16m1_t zero = __riscv_vmv_v_x_i16m1(0, 1);
536+
537+
float sumf = 0;
538+
539+
for (int ib = 0; ib < nb; ++ib) {
540+
const float d0 = GGML_CPU_FP16_TO_FP32(x[ib].d);
541+
542+
float acc = 0;
543+
544+
for (int k = 0; k < 4; ++k) {
545+
const block_q8_0 * GGML_RESTRICT yb = &y[ib * 4 + k];
546+
const vbool4_t is_not_zero = __riscv_vlm_v_b4(x[ib].qs + 4 * k, vl32);
547+
548+
const vint8m2_t qy = __riscv_vle8_v_i8m2(yb->qs, vl32);
549+
const vint8m2_t neg_qy =__riscv_vneg_v_i8m2(qy, vl32);
550+
const vint8m2_t sy = __riscv_vmerge_vvm_i8m2(neg_qy, qy, is_not_zero, vl32);
551+
552+
const vint16m1_t red = __riscv_vwredsum_vs_i8m2_i16m1(sy, zero, vl32);
553+
acc += GGML_CPU_FP16_TO_FP32(yb->d) * (float)__riscv_vmv_x_s_i16m1_i16(red);
554+
}
555+
556+
sumf += d0 * acc;
557+
}
558+
559+
*s = sumf;
560+
}
561+
#endif
562+
563+
void ggml_vec_dot_q1_0_q8_0(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
564+
#if defined(__riscv_v)
565+
assert(nrc == 1);
566+
567+
const size_t vlen_bits = __riscv_vlenb() * 8;
568+
569+
if (vlen_bits >= 256) {
570+
ggml_vec_dot_q1_0_q8_0_vl256(n, s, vx, vy);
571+
} else if (vlen_bits >= 128) {
572+
ggml_vec_dot_q1_0_q8_0_vl128(n, s, vx, vy);
573+
} else {
574+
ggml_vec_dot_q1_0_q8_0_generic(n, s, bs, vx, bx, vy, by, nrc);
575+
}
576+
#else
577+
ggml_vec_dot_q1_0_q8_0_generic(n, s, bs, vx, bx, vy, by, nrc);
578+
#endif
579+
}
580+
483581
void ggml_vec_dot_q2_K_q8_K(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
484582
assert(nrc == 1);
485583
UNUSED(nrc);

0 commit comments

Comments
 (0)