mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
dnn: add RVV LMUL=1 kernel for convBlock_F32 (ConvolutionLayer, rv64gcv)
This commit is contained in:
@@ -2206,6 +2206,70 @@ void convBlock_F32(int np, const float* a, const float* b, float* c, int ldc, bo
|
||||
return;
|
||||
}
|
||||
convBlockNoSIMD(np, a, b, c, ldc, init_c, outLen, convMR, convNR);
|
||||
#elif CV_RVV
|
||||
{
|
||||
// LMUL=1 kernel: vlanes = VLEN/32 (8 at VLEN=256).
|
||||
// OpenCV's v_float32 is vfloat32m2_t (LMUL=2, vlanes=2*VLEN/32=16 at VLEN=256);
|
||||
// 24 % 16 != 0, so the 24-wide tile requires LMUL=1 and native intrinsics.
|
||||
// vfmacc.vf (scalar-into-vector FMA) avoids a broadcast register.
|
||||
// Only the exact full-tile case (outLen==convNR) is handled; tails fall to scalar.
|
||||
const size_t vl = __riscv_vsetvlmax_e32m1();
|
||||
if (convMR == 4 && (size_t)convNR == 3 * vl && outLen == convNR)
|
||||
{
|
||||
vfloat32m1_t c00 = __riscv_vfmv_v_f_f32m1(0.f, vl);
|
||||
vfloat32m1_t c01 = c00, c02 = c00;
|
||||
vfloat32m1_t c10 = c00, c11 = c00, c12 = c00;
|
||||
vfloat32m1_t c20 = c00, c21 = c00, c22 = c00;
|
||||
vfloat32m1_t c30 = c00, c31 = c00, c32 = c00;
|
||||
for (int p = 0; p < np; p++, a += convMR, b += convNR)
|
||||
{
|
||||
vfloat32m1_t b0 = __riscv_vle32_v_f32m1(b, vl);
|
||||
vfloat32m1_t b1 = __riscv_vle32_v_f32m1(b + vl, vl);
|
||||
vfloat32m1_t b2 = __riscv_vle32_v_f32m1(b + 2 * vl, vl);
|
||||
c00 = __riscv_vfmacc_vf_f32m1(c00, a[0], b0, vl);
|
||||
c01 = __riscv_vfmacc_vf_f32m1(c01, a[0], b1, vl);
|
||||
c02 = __riscv_vfmacc_vf_f32m1(c02, a[0], b2, vl);
|
||||
c10 = __riscv_vfmacc_vf_f32m1(c10, a[1], b0, vl);
|
||||
c11 = __riscv_vfmacc_vf_f32m1(c11, a[1], b1, vl);
|
||||
c12 = __riscv_vfmacc_vf_f32m1(c12, a[1], b2, vl);
|
||||
c20 = __riscv_vfmacc_vf_f32m1(c20, a[2], b0, vl);
|
||||
c21 = __riscv_vfmacc_vf_f32m1(c21, a[2], b1, vl);
|
||||
c22 = __riscv_vfmacc_vf_f32m1(c22, a[2], b2, vl);
|
||||
c30 = __riscv_vfmacc_vf_f32m1(c30, a[3], b0, vl);
|
||||
c31 = __riscv_vfmacc_vf_f32m1(c31, a[3], b1, vl);
|
||||
c32 = __riscv_vfmacc_vf_f32m1(c32, a[3], b2, vl);
|
||||
}
|
||||
if (!init_c)
|
||||
{
|
||||
c00 = __riscv_vfadd_vv_f32m1(c00, __riscv_vle32_v_f32m1(c, vl), vl);
|
||||
c01 = __riscv_vfadd_vv_f32m1(c01, __riscv_vle32_v_f32m1(c + vl, vl), vl);
|
||||
c02 = __riscv_vfadd_vv_f32m1(c02, __riscv_vle32_v_f32m1(c + 2 * vl, vl), vl);
|
||||
c10 = __riscv_vfadd_vv_f32m1(c10, __riscv_vle32_v_f32m1(c + ldc, vl), vl);
|
||||
c11 = __riscv_vfadd_vv_f32m1(c11, __riscv_vle32_v_f32m1(c + ldc + vl, vl), vl);
|
||||
c12 = __riscv_vfadd_vv_f32m1(c12, __riscv_vle32_v_f32m1(c + ldc + 2 * vl, vl), vl);
|
||||
c20 = __riscv_vfadd_vv_f32m1(c20, __riscv_vle32_v_f32m1(c + 2 * ldc, vl), vl);
|
||||
c21 = __riscv_vfadd_vv_f32m1(c21, __riscv_vle32_v_f32m1(c + 2 * ldc + vl, vl), vl);
|
||||
c22 = __riscv_vfadd_vv_f32m1(c22, __riscv_vle32_v_f32m1(c + 2 * ldc + 2 * vl, vl), vl);
|
||||
c30 = __riscv_vfadd_vv_f32m1(c30, __riscv_vle32_v_f32m1(c + 3 * ldc, vl), vl);
|
||||
c31 = __riscv_vfadd_vv_f32m1(c31, __riscv_vle32_v_f32m1(c + 3 * ldc + vl, vl), vl);
|
||||
c32 = __riscv_vfadd_vv_f32m1(c32, __riscv_vle32_v_f32m1(c + 3 * ldc + 2 * vl, vl), vl);
|
||||
}
|
||||
__riscv_vse32_v_f32m1(c, c00, vl);
|
||||
__riscv_vse32_v_f32m1(c + vl, c01, vl);
|
||||
__riscv_vse32_v_f32m1(c + 2 * vl, c02, vl);
|
||||
__riscv_vse32_v_f32m1(c + ldc, c10, vl);
|
||||
__riscv_vse32_v_f32m1(c + ldc + vl, c11, vl);
|
||||
__riscv_vse32_v_f32m1(c + ldc + 2 * vl, c12, vl);
|
||||
__riscv_vse32_v_f32m1(c + 2 * ldc, c20, vl);
|
||||
__riscv_vse32_v_f32m1(c + 2 * ldc + vl, c21, vl);
|
||||
__riscv_vse32_v_f32m1(c + 2 * ldc + 2 * vl, c22, vl);
|
||||
__riscv_vse32_v_f32m1(c + 3 * ldc, c30, vl);
|
||||
__riscv_vse32_v_f32m1(c + 3 * ldc + vl, c31, vl);
|
||||
__riscv_vse32_v_f32m1(c + 3 * ldc + 2 * vl, c32, vl);
|
||||
return;
|
||||
}
|
||||
convBlockNoSIMD(np, a, b, c, ldc, init_c, outLen, convMR, convNR);
|
||||
}
|
||||
#else
|
||||
convBlockNoSIMD(np, a, b, c, ldc, init_c, outLen, convMR, convNR);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user