Skip to content

Commit a80ff18

Browse files
authored
ggml-cpu : fix leftover handling in ggml_vec_scale_f32 for SVE (#16443)
This commit updates the leftover handling in ggml_vec_scale_f32. The motivation for this is that the code currently incorrectly assumes there would be fewer than ggml_f32_epr leftover elements. However, since the main loop processes 2*ggml_f32_epr elements per iteration , there can be up to (2*ggml_f32_epr - 1) leftover elements. The original single-pass leftover code could only process ggml_f32_epr elements, leaving some elements unscaled. Example scenario with 256-bit SVE: ``` ggml_f32_epr = 8 (elements per register) ggml_f32_step = 16 (two registers per iteration) n = 25 np = 16 leftovers = 9 elements (16-24) Original : processes only elements 16-23, misses element 24 This commit : loop processes elements 16-23, then element 24 ``` Refs: https://github.com/ggml-org/llama.cpp/actions/runs/18070620247/job/51419855630
1 parent 1d49ca3 commit a80ff18

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

ggml/src/ggml-cpu/vec.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -654,11 +654,11 @@ inline static void ggml_vec_scale_f32(const int n, float * y, const float v) {
654654
}
655655
// leftovers
656656
// maximum number of leftover elements will be less that ggml_f32_epr. Apply predicated svmad on available elements only
657-
if (np < n) {
658-
svbool_t pg = svwhilelt_b32(np, n);
659-
ay1 = svld1_f32(pg, y + np);
657+
for (int i = np; i < n; i += ggml_f32_epr) {
658+
svbool_t pg = svwhilelt_b32(i, n);
659+
ay1 = svld1_f32(pg, y + i);
660660
ay1 = svmul_f32_m(pg, ay1, vx);
661-
svst1_f32(pg, y + np, ay1);
661+
svst1_f32(pg, y + i, ay1);
662662
}
663663
#elif defined(__riscv_v_intrinsic)
664664
for (int i = 0, avl; i < n; i += avl) {

0 commit comments

Comments
 (0)