Files
2026-07-13 13:33:03 +08:00

70 lines
2.0 KiB
C++

#include <riscv_vector.h>
#include <cstring>
#include <stdint.h>
#include <stddef.h>
#include "core/Macro.h"
#define RVV_MATMUL_LP 1
#define RVV_MATMUL_HP 4
void MNNPackForMatMul_B_RVV(float* destC, const float* sourceC, size_t h, size_t kernelsize, size_t ic,
bool transpose) {
auto dest = (int32_t*)destC;
auto source = (int32_t*)sourceC;
int LP = RVV_MATMUL_LP;
int HP = RVV_MATMUL_HP;
auto l = kernelsize * ic;
size_t dest_size = ROUND_UP(h, HP) * ROUND_UP(ic, LP) * kernelsize * 4;
memset(dest, 0, dest_size);
auto stride0 = kernelsize * ROUND_UP(ic, LP) * HP;
auto stride1 = ROUND_UP(ic, LP) * HP;
auto stride2 = HP * LP;
auto srcStride0 = l;
auto srcStride1 = 1;
if (!transpose) {
srcStride0 = 1;
srcStride1 = h;
}
size_t h_blocks = ROUND_UP(h, HP) / HP;
for (size_t yHu = 0; yHu < h_blocks; ++yHu) {
size_t y_start = yHu * HP;
size_t y_end = (y_start + HP < h) ? (y_start + HP) : h;
size_t y_len = y_end - y_start;
if (y_len == 0)
break;
for (size_t k = 0; k < kernelsize; ++k) {
for (size_t x = 0; x < ic; ++x) {
auto xLu = x / LP;
auto xLp = x % LP;
int32_t* dst_ptr = dest + yHu * stride0 + k * stride1 + xLu * stride2 + xLp;
size_t l_idx = x + k * ic;
const int32_t* src_ptr = source + y_start * srcStride0 + l_idx * srcStride1;
size_t vl;
for (size_t yHp = 0; yHp < y_len; yHp += vl) {
vl = __riscv_vsetvl_e32m1(y_len - yHp);
vint32m1_t v_src;
if (!transpose) {
v_src = __riscv_vle32_v_i32m1(src_ptr + yHp, vl);
} else {
v_src = __riscv_vlse32_v_i32m1(src_ptr + yHp * l, l * sizeof(int32_t), vl);
}
__riscv_vse32_v_i32m1(dst_ptr + yHp, v_src, vl);
}
}
}
}
}