项目文件夹

文件
2026-07-13 13:33:03 +08:00

74 行
2.7 KiB
C++

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
//
// MNNFloat2Int8.cpp
// MNN
//
// Created by MNN on 2026/04/01.
// Copyright © 2018, Alibaba Group Holding Limited
//
#include <riscv_vector.h>
#include <stdint.h>
#include <sys/types.h>
#include "../../compute/Int8FunctionsOpt.h"
void MNNFloat2Int8_RVV(const float* src, int8_t* dst, size_t sizeQuad, const float* scalep, ssize_t minValue,
ssize_t maxValue, const float* zeroPoint, ssize_t quanParamVec) {
float scale[4] = {scalep[0], scalep[0], scalep[0], scalep[0]};
float zero[4] = {zeroPoint[0], zeroPoint[0], zeroPoint[0], zeroPoint[0]};
if (quanParamVec & 1) {
scale[0] = scalep[0];
scale[1] = scalep[1];
scale[2] = scalep[2];
scale[3] = scalep[3];
}
if (quanParamVec & 2) {
zero[0] = zeroPoint[0];
zero[1] = zeroPoint[1];
zero[2] = zeroPoint[2];
zero[3] = zeroPoint[3];
}
const float minf = (float)minValue;
const float maxf = (float)maxValue;
const size_t total = sizeQuad * 4;
// get vl,create scale/zero cyclic template
// template by e32m1
size_t vl_template = __riscv_vsetvlmax_e32m2();
// iota + modulo operation,create channel index,then gather scale/zero
// index: [0,1,2,3,0,1,2,3,...]
vuint32m2_t v_idx = __riscv_vid_v_u32m2(vl_template); // [0,1,2,...,vl-1]
vuint32m2_t v_ch = __riscv_vremu_vx_u32m2(v_idx, 4, vl_template); // [0,1,2,3,0,1,2,3,...]
// gatherfrom scale[4] to zero[4] by channel index
vfloat32m2_t v_scale_tpl =
__riscv_vloxei32_v_f32m2(scale, __riscv_vsll_vx_u32m2(v_ch, 2, vl_template), vl_template);
vfloat32m2_t v_zero_tpl = __riscv_vloxei32_v_f32m2(zero, __riscv_vsll_vx_u32m2(v_ch, 2, vl_template), vl_template);
vfloat32m2_t v_min = __riscv_vfmv_v_f_f32m2(minf, vl_template);
vfloat32m2_t v_max = __riscv_vfmv_v_f_f32m2(maxf, vl_template);
// main loop
size_t i = 0;
while (i < total) {
size_t vl = __riscv_vsetvl_e32m2(total - i);
vfloat32m2_t v_src = __riscv_vle32_v_f32m2(src + i, vl);
// scale&zero using templatevl <= vl_template,the previous v1 elements is aligned
vfloat32m2_t v_mul = __riscv_vfmul_vv_f32m2(v_src, v_scale_tpl, vl);
vfloat32m2_t v_add = __riscv_vfadd_vv_f32m2(v_mul, v_zero_tpl, vl);
vfloat32m2_t v_clamp = __riscv_vfmin_vv_f32m2(__riscv_vfmax_vv_f32m2(v_add, v_min, vl), v_max, vl);
// float→int8
vint32m2_t v_i32 = __riscv_vfcvt_x_f_v_i32m2(v_clamp, vl);
vint16m1_t v_i16 = __riscv_vncvt_x_x_w_i16m1(v_i32, vl);
vint8mf2_t v_i8 = __riscv_vncvt_x_x_w_i8mf2(v_i16, vl);
__riscv_vse8_v_i8mf2(dst + i, v_i8, vl);
i += vl;
}
}