Repository: ggerganov/llama.cpp
File: ggml/src/ggml-cpu/simd-mappings.h (C/C++)

Code before:
    sum1 = svadd_f32_m(DEFAULT_PG, sum1, sum5);        \
    (res) = (ggml_float) GGML_F32xt_REDUCE_ONE(sum1);  \
}
#define GGML_F32xt_REDUCE(...) GGML_F32xt_REDUCE_IMPL(DEFAULT_PG, __VA_ARGS__)

#define GGML_F32_VEC        GGML_F32xt
#define GGML_F32_VEC_ZERO   GGML_F32xt_ZERO
#define GGML_F32_VEC_SET1   GGML_F32xt_SET1
#define GGML_F32_VEC_LOAD   GGML_F32xt_LOAD
#define GGML_F32_VEC_STORE  GGML_F32xt_STORE
#define GGML_F32_VEC_FMA    GGML_F32xt_FMA
#define GGML_F32_VEC_ADD    GGML_F32xt_ADD
#define GGML_F32_VEC_MUL    GGML_F32xt_MUL
#define GGML_F32_VEC_REDUCE GGML_F32xt_REDUCE

// F16 SVE
#define DEFAULT_PG32    svptrue_b32()
#define DEFAULT_PG16    svptrue_b16()

#define GGML_F32Cxt                         svfloat16_t
#define GGML_F32Cxt_ZERO                    svdup_n_f16(0.0f)
#define GGML_F32Cxt_SET1(x)                 svdup_n_f16(x)
#define GGML_F32Cxt_LOAD(p)                 svld1_f16(DEFAULT_PG16, (const __fp16 *)(p))
#define GGML_F32Cxt_STORE(dst_ptr, src_vec) svst1_f16(DEFAULT_PG16, (__fp16 *)(dst_ptr), (src_vec))

#define GGML_F32Cxt_FMA_IMPL(pg, a, b, c)   svmad_f16_x(pg, a, b, c)
#define GGML_F32Cxt_FMA(...)                GGML_F32Cxt_FMA_IMPL(DEFAULT_PG16, __VA_ARGS__)
#define GGML_F32Cxt_ADD_IMPL(pg, a, b)      svadd_f16_x(pg, a, b)
#define GGML_F32Cxt_ADD(...)                GGML_F32Cxt_ADD_IMPL(DEFAULT_PG16, __VA_ARGS__)
#define GGML_F32Cxt_MUL_IMPL(pg, a, b)      svmul_f16_x(pg, a, b)
#define GGML_F32Cxt_MUL(...)                GGML_F32Cxt_MUL_IMPL(DEFAULT_PG16, __VA_ARGS__)
#define GGML_F32Cxt_REDUCE                  GGML_F16xt_REDUCE_MIXED

#define GGML_F16x_VEC                GGML_F32Cxt
#define GGML_F16x_VEC_ZERO           GGML_F32Cxt_ZERO
#define GGML_F16x_VEC_SET1           GGML_F32Cxt_SET1
#define GGML_F16x_VEC_LOAD(p, i)     GGML_F32Cxt_LOAD(p)
#define GGML_F16x_VEC_STORE(p, r, i) GGML_F32Cxt_STORE((__fp16 *)(p), r)
#define GGML_F16x_VEC_FMA            GGML_F32Cxt_FMA
#define GGML_F16x_VEC_ADD            GGML_F32Cxt_ADD
#define GGML_F16x_VEC_MUL            GGML_F32Cxt_MUL
#define GGML_F16x_VEC_REDUCE         GGML_F32Cxt_REDUCE

#define GGML_F16xt_REDUCE_ONE_IMPL(pg, a) svaddv_f16(pg, a)
#define GGML_F16xt_REDUCE_ONE(...)        GGML_F16xt_REDUCE_ONE_IMPL(DEFAULT_PG16, __VA_ARGS__)

#define GGML_F16xt_REDUCE_MIXED_IMPL(pg16, res, sum1, sum2, sum3, sum4)  \
{                                                      \
    sum1 = svadd_f16_x(pg16, sum1, sum2);              \
    sum3 = svadd_f16_x(pg16, sum3, sum4);              \
    sum1 = svadd_f16_x(pg16, sum1, sum3);              \

Review comment (suggestion):
The argument order of `svfmad_f16_x` doesn't match the usual `GGML_F32_VEC_FMA`.

From <https://developer.arm.com/architectures/instruction-sets/intrinsics/svmad[_f16]_x>:

> `op3[i] + op1[i] * op2[i]`

While `GGML_F32_VEC_FMA(a, b, c)` does `a + b * c`.

<https://github.com/ggml-org/llama.cpp/blob/0d8831543cdc368fb248bae6f1b4aa5516684edc/ggml/src/ggml-cpu/vec.cpp#L100>

Same with `GGML_F16_VEC_FMA`:

<https://github.com/ggml-org/llama.cpp/blob/0d8831543cdc368fb248bae6f1b4aa5516684edc/ggml/src/ggml-cpu/vec.cpp#L213>

```suggestion
#define GGML_F32Cxt_FMA_IMPL(pg, a, b, c)   svmad_f16_x(pg, b, c, a)
```

The places where `GGML_F16x_VEC_FMA` is used would also need to be updated, though.

(Since those don't get renamed to `GGML_F32_VEC_FMA` or `GGML_F16_VEC_FMA`, this isn't really a problem, but it would be mostly for consistency)

Code after:
#define GGML_F32_VEC        GGML_F32xt
#define GGML_F32_VEC_ZERO   GGML_F32xt_ZERO
#define GGML_F32_VEC_SET1   GGML_F32xt_SET1
#define GGML_F32_VEC_LOAD   GGML_F32xt_LOAD
#define GGML_F32_VEC_STORE  GGML_F32xt_STORE
#define GGML_F32_VEC_FMA    GGML_F32xt_FMA
#define GGML_F32_VEC_ADD    GGML_F32xt_ADD
#define GGML_F32_VEC_MUL    GGML_F32xt_MUL
#define GGML_F32_VEC_REDUCE GGML_F32xt_REDUCE

// F16 SVE
#define DEFAULT_PG32    svptrue_b32()
#define DEFAULT_PG16    svptrue_b16()

#define GGML_F32Cxt                         svfloat16_t
#define GGML_F32Cxt_ZERO                    svdup_n_f16(0.0f)
#define GGML_F32Cxt_SET1(x)                 svdup_n_f16(x)
#define GGML_F32Cxt_LOAD(p)                 svld1_f16(DEFAULT_PG16, (const __fp16 *)(p))
#define GGML_F32Cxt_STORE(dst_ptr, src_vec) svst1_f16(DEFAULT_PG16, (__fp16 *)(dst_ptr), (src_vec))

#define GGML_F32Cxt_FMA_IMPL(pg, a, b, c)   svmad_f16_x(pg, b, c, a)
#define GGML_F32Cxt_FMA(...)                GGML_F32Cxt_FMA_IMPL(DEFAULT_PG16, __VA_ARGS__)
#define GGML_F32Cxt_ADD_IMPL(pg, a, b)      svadd_f16_x(pg, a, b)
#define GGML_F32Cxt_ADD(...)                GGML_F32Cxt_ADD_IMPL(DEFAULT_PG16, __VA_ARGS__)
#define GGML_F32Cxt_MUL_IMPL(pg, a, b)      svmul_f16_x(pg, a, b)
#define GGML_F32Cxt_MUL(...)                GGML_F32Cxt_MUL_IMPL(DEFAULT_PG16, __VA_ARGS__)
#define GGML_F32Cxt_REDUCE                  GGML_F16xt_REDUCE_MIXED

#define GGML_F16x_VEC                GGML_F32Cxt
#define GGML_F16x_VEC_ZERO           GGML_F32Cxt_ZERO
#define GGML_F16x_VEC_SET1           GGML_F32Cxt_SET1
#define GGML_F16x_VEC_LOAD(p, i)     GGML_F32Cxt_LOAD(p)
#define GGML_F16x_VEC_STORE(p, r, i) GGML_F32Cxt_STORE((__fp16 *)(p), r)
#define GGML_F16x_VEC_FMA            GGML_F32Cxt_FMA
#define GGML_F16x_VEC_ADD            GGML_F32Cxt_ADD
#define GGML_F16x_VEC_MUL            GGML_F32Cxt_MUL
#define GGML_F16x_VEC_REDUCE         GGML_F32Cxt_REDUCE

#define GGML_F16xt_REDUCE_ONE_IMPL(pg, a) svaddv_f16(pg, a)
#define GGML_F16xt_REDUCE_ONE(...)        GGML_F16xt_REDUCE_ONE_IMPL(DEFAULT_PG16, __VA_ARGS__)

#define GGML_F16xt_REDUCE_MIXED_IMPL(pg16, res, sum1, sum2, sum3, sum4)  \
{                                                      \
    sum1 = svadd_f16_x(pg16, sum1, sum2);              \
    sum3 = svadd_f16_x(pg16, sum3, sum4);              \
    sum1 = svadd_f16_x(pg16, sum1, sum3);              \
    __fp16 sum_f16 = svaddv_f16(pg16, sum1);           \
    (res) = (ggml_float) sum_f16;                      \
}
#define GGML_F16xt_REDUCE_MIXED(...) GGML_F16xt_REDUCE_MIXED_IMPL(DEFAULT_PG16, __VA_ARGS__)