From 778224cee22e9739a9bbeaad692c4e1c6e3453d5 Mon Sep 17 00:00:00 2001 From: Julien Jerphanion Date: Wed, 19 Aug 2026 23:36:25 +0200 Subject: [PATCH] Add a WASM SIMD128 2x2 CGEMM microkernel Vectorize the packed 2x2 CGEMM/ZGEMM inner loop with f32x4/f64x2 complex mul. Do not let kernel/wasm/KERNEL override the target kernel the way 4x4 real GEMM already guards TRMM. Signed-off-by: Julien Jerphanion --- kernel/wasm/KERNEL | 20 + kernel/wasm/KERNEL.WASM128_GENERIC | 4 +- kernel/wasm/zgemmkernel_2x2_wasm128.c | 949 ++++++++++++++++++++++++++ 3 files changed, 971 insertions(+), 2 deletions(-) create mode 100644 kernel/wasm/zgemmkernel_2x2_wasm128.c diff --git a/kernel/wasm/KERNEL b/kernel/wasm/KERNEL index 0c8dcfcc29..84693d9ca1 100644 --- a/kernel/wasm/KERNEL +++ b/kernel/wasm/KERNEL @@ -142,17 +142,37 @@ ifndef DGEMMOTCOPYOBJ DGEMMOTCOPYOBJ = dgemm_otcopy$(TSUFFIX).$(SUFFIX) endif +ifndef CGEMMKERNEL CGEMMKERNEL = ../generic/zgemmkernel_2x2.c +endif +ifndef CGEMMONCOPY CGEMMONCOPY = ../generic/zgemm_ncopy_2.c +endif +ifndef CGEMMOTCOPY CGEMMOTCOPY = ../generic/zgemm_tcopy_2.c +endif +ifndef CGEMMONCOPYOBJ CGEMMONCOPYOBJ = cgemm_oncopy$(TSUFFIX).$(SUFFIX) +endif +ifndef CGEMMOTCOPYOBJ CGEMMOTCOPYOBJ = cgemm_otcopy$(TSUFFIX).$(SUFFIX) +endif +ifndef ZGEMMKERNEL ZGEMMKERNEL = ../generic/zgemmkernel_2x2.c +endif +ifndef ZGEMMONCOPY ZGEMMONCOPY = ../generic/zgemm_ncopy_2.c +endif +ifndef ZGEMMOTCOPY ZGEMMOTCOPY = ../generic/zgemm_tcopy_2.c +endif +ifndef ZGEMMONCOPYOBJ ZGEMMONCOPYOBJ = zgemm_oncopy$(TSUFFIX).$(SUFFIX) +endif +ifndef ZGEMMOTCOPYOBJ ZGEMMOTCOPYOBJ = zgemm_otcopy$(TSUFFIX).$(SUFFIX) +endif ifndef STRSMKERNEL_LN STRSMKERNEL_LN = ../generic/trsm_kernel_LN.c diff --git a/kernel/wasm/KERNEL.WASM128_GENERIC b/kernel/wasm/KERNEL.WASM128_GENERIC index 0265085b1c..699ce029d7 100644 --- a/kernel/wasm/KERNEL.WASM128_GENERIC +++ b/kernel/wasm/KERNEL.WASM128_GENERIC @@ -112,13 +112,13 @@ DGEMMOTCOPY = ../generic/gemm_tcopy_4.c DGEMMONCOPYOBJ = dgemm_oncopy$(TSUFFIX).$(SUFFIX) DGEMMOTCOPYOBJ = dgemm_otcopy$(TSUFFIX).$(SUFFIX) -CGEMMKERNEL = ../generic/zgemmkernel_2x2.c +CGEMMKERNEL = zgemmkernel_2x2_wasm128.c CGEMMONCOPY = ../generic/zgemm_ncopy_2.c CGEMMOTCOPY = ../generic/zgemm_tcopy_2.c CGEMMONCOPYOBJ = cgemm_oncopy$(TSUFFIX).$(SUFFIX) CGEMMOTCOPYOBJ = cgemm_otcopy$(TSUFFIX).$(SUFFIX) -ZGEMMKERNEL = ../generic/zgemmkernel_2x2.c +ZGEMMKERNEL = zgemmkernel_2x2_wasm128.c ZGEMMONCOPY = ../generic/zgemm_ncopy_2.c ZGEMMOTCOPY = ../generic/zgemm_tcopy_2.c ZGEMMONCOPYOBJ = zgemm_oncopy$(TSUFFIX).$(SUFFIX) diff --git a/kernel/wasm/zgemmkernel_2x2_wasm128.c b/kernel/wasm/zgemmkernel_2x2_wasm128.c new file mode 100644 index 0000000000..a5ae37dff5 --- /dev/null +++ b/kernel/wasm/zgemmkernel_2x2_wasm128.c @@ -0,0 +1,949 @@ +#include "common.h" +#if defined(__wasm_simd128__) +#include +#if defined(__wasm_relaxed_simd__) +#define MADD_F32(a, b, c) wasm_f32x4_relaxed_madd((a), (b), (c)) +#define MADD_F64(a, b, c) wasm_f64x2_relaxed_madd((a), (b), (c)) +#else +#define MADD_F32(a, b, c) wasm_f32x4_add((c), wasm_f32x4_mul((a), (b))) +#define MADD_F64(a, b, c) wasm_f64x2_add((c), wasm_f64x2_mul((a), (b))) +#endif +#endif +/******************************** + SIMD128 2x2 complex GEMM (CGEMM/ZGEMM). Remainders stay scalar. + ADD1 a*c +*********************************/ +int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alphar,FLOAT alphai,FLOAT* ba,FLOAT* bb,FLOAT* C,BLASLONG ldc +#ifdef TRMMKERNEL + , BLASLONG offset +#endif + ) +{ + BLASLONG i,j,k; + FLOAT *C0,*C1,*ptrba,*ptrbb; + FLOAT res0,res1,res2,res3,res4,res5,res6,res7,load0,load1,load2,load3,load4,load5,load6,load7,load8,load9,load10,load11,load12,load13,load14,load15; + for (j=0; j