1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 08:13:04 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2024-07-25 18:29:12 +03:00
61 changed files with 1615 additions and 29782 deletions
+1 -1
View File
@@ -213,7 +213,7 @@ file(GLOB_RECURSE dnn_int_hdrs
)
set(dnn_plugin_srcs ${dnn_srcs} ${dnn_int_hdrs})
ocv_list_filterout_ex(dnn_plugin_srcs
"/src/dnn.cpp$|/src/dnn_utils.cpp$|/src/dnn_utils.cpp$|/src/dnn_read.cpp$|/src/registry.cpp$|/src/backend.cpp$"
"/src/dnn.cpp$|/src/dnn_utils.cpp$|/src/dnn_read.cpp$|/src/registry.cpp$|/src/backend.cpp$"
# importers
"/src/(caffe|darknet|onnx|tensorflow)/"
# executors
+58 -35
View File
@@ -973,49 +973,72 @@ INSTANTIATE_TEST_CASE_P(/**/, Layer_Softmax, Combine(
/* withCann= */ false) // only test on CPU
));
using Layer_Elementwise = TestBaseWithParam<tuple<std::vector<int>, std::string, tuple<Backend, Target>>>;
PERF_TEST_P_(Layer_Elementwise, elementwise) {
std::vector<int> input_shape = get<0>(GetParam());
std::string op = get<1>(GetParam());
int backend_id = get<0>(get<2>(GetParam()));
int target_id = get<1>(get<2>(GetParam()));
struct Layer_Elementwise : public TestBaseWithParam<tuple<Backend, Target>> {
void test_layer(const std::string &op_type, const std::vector<int> &input_shape) {
int backend_id = get<0>(GetParam());
int target_id = get<1>(GetParam());
Mat input(input_shape, CV_32F);
randn(input, 0.f, 1.f);
Mat input(input_shape, CV_32F);
randu(input, -10.0f, 10.f);
LayerParams lp;
lp.type = op;
lp.name = "TestLayer";
LayerParams lp;
lp.type = op_type;
lp.name = cv::format("PerfLayer/%s", op_type.c_str());
Net net;
net.addLayerToPrev(lp.name, lp.type, lp);
Net net;
net.addLayerToPrev(lp.name, lp.type, lp);
// Warmup
{
net.setInput(input);
net.setPreferableBackend(backend_id);
net.setPreferableTarget(target_id);
Mat out = net.forward();
// Warmup
{
net.setInput(input);
net.setPreferableBackend(backend_id);
net.setPreferableTarget(target_id);
net.forward();
}
TEST_CYCLE() {
net.forward();
}
SANITY_CHECK_NOTHING();
}
TEST_CYCLE() {
net.forward();
}
int N = 2;
int C = 32;
int H = 416;
int W = 416;
};
SANITY_CHECK_NOTHING();
PERF_TEST_P_(Layer_Elementwise, Gelu) {
test_layer("Gelu", std::vector<int>{1, 50, 3072});
}
PERF_TEST_P_(Layer_Elementwise, Swish) {
test_layer("Swish", std::vector<int>{N, C, H, W});
}
PERF_TEST_P_(Layer_Elementwise, Mish) {
test_layer("Mish", std::vector<int>{N, C, H, W});
}
PERF_TEST_P_(Layer_Elementwise, Elu) {
test_layer("ELU", std::vector<int>{N, C, H, W});
}
PERF_TEST_P_(Layer_Elementwise, Celu) {
test_layer("Celu", std::vector<int>{N, C, H, W});
}
PERF_TEST_P_(Layer_Elementwise, Selu) {
test_layer("Selu", std::vector<int>{N, C, H, W});
}
PERF_TEST_P_(Layer_Elementwise, HardSwish) {
test_layer("HardSwish", std::vector<int>{N, C, H, W});
}
INSTANTIATE_TEST_CASE_P(/**/, Layer_Elementwise, testing::Combine(
testing::Values(std::vector<int>{1, 50, 3072}),
testing::Values(std::string{"Gelu"}),
dnnBackendsAndTargets(/* withInferenceEngine= */ true,
/* withHalide= */ false,
/* withCpuOCV= */ true,
/* withVkCom= */ false,
/* withCUDA= */ true,
/* withNgraph= */ true,
/* withWebnn= */ false,
/* withCann= */ false) // only test on CPU
));
INSTANTIATE_TEST_CASE_P(/**/, Layer_Elementwise,
dnnBackendsAndTargets(/* withInferenceEngine= */ true,
/* withHalide= */ false,
/* withCpuOCV= */ true,
/* withVkCom= */ false,
/* withCUDA= */ true,
/* withNgraph= */ true,
/* withWebnn= */ false,
/* withCann= */ false));
} // namespace
@@ -304,8 +304,8 @@ public:
opt_LASX::fastGEMM1T( sptr, wptr, wstep, biasptr, multptr, dptr, nw, vecsize, outZp );
else
#endif
#if CV_TRY_RVV && defined(__riscv_v_intrinsic) && __riscv_v_intrinsic>=11000
if( useRVV)
#if CV_TRY_RVV && CV_RVV
if( useRVV )
opt_RVV::fastGEMM1T( sptr, wptr, wstep, biasptr, multptr, dptr, nw, vecsize, outZp );
else
#endif
@@ -1257,7 +1257,7 @@ void fastGEMM1T( const int8_t* vec, const int8_t* weights,
}
#endif // CV_LASX
#if !defined(CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY) && CV_RVV && defined(__riscv_v_intrinsic) && __riscv_v_intrinsic>=11000
#if !defined(CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY) && CV_RVV
static const size_t __cv_rvv_e8m1_max = __riscv_vsetvlmax_e8m1();
static const size_t __cv_rvv_e16m1_max = __riscv_vsetvlmax_e16m1();
+1 -1
View File
@@ -1519,7 +1519,7 @@ public:
opt_AVX::fastGEMM( aptr, astep, bptr, bstep, cptr, cstep, mmax, kmax, nmax );
else
#endif
#if CV_TRY_RVV
#if CV_TRY_RVV && CV_RVV
if( useRVV ) {
opt_RVV::fastGEMM( aptr, astep, bptr, bstep, cptr, cstep, mmax, kmax, nmax );
}
@@ -119,7 +119,7 @@ void runDepthwise(InputArray _input, OutputArray _output, const Ptr<FastConv>& c
pad_top, pad_left, bias, relu, inptr0, Hi, Wi, outptr0, c, H0, W0);
else
#endif
#if CV_TRY_RVV
#if CV_TRY_RVV && CV_RVV
if(canRunOpt && conv->useRVV)
opt_RVV::fastDepthwiseConv(weights, Hk, Wk, stride_h, stride_w, dilation_h, dilation_w,
pad_top, pad_left, bias, relu, inptr0, Hi, Wi, outptr0, c, H0, W0);
@@ -264,48 +264,48 @@ void fastDepthwiseConv( const float* wptr,
if( stride_w == 1 )
for( ; out_j < outW1; out_j += vl, avl -= vl)
{
vl = vsetvl_e32m8(avl);
vl = __riscv_vsetvl_e32m8(avl);
int in_j = out_j * stride_w - pad_l;
vfloat32m8_t vout0 = vfmacc_vf_f32m8(vfmv_v_f_f32m8(bias, vl), w00, vle32_v_f32m8(imgptr0 + in_j, vl), vl);
vout0 = vfmacc_vf_f32m8(vout0, w01, vle32_v_f32m8(imgptr0 + in_j + dilation_w, vl), vl);
vout0 = vfmacc_vf_f32m8(vout0, w02, vle32_v_f32m8(imgptr0 + in_j + dilation_w*2, vl), vl);
vout0 = vfmacc_vf_f32m8(vout0, w10, vle32_v_f32m8(imgptr1 + in_j, vl),vl);
vout0 = vfmacc_vf_f32m8(vout0, w11, vle32_v_f32m8(imgptr1 + in_j + dilation_w, vl),vl);
vout0 = vfmacc_vf_f32m8(vout0, w12, vle32_v_f32m8(imgptr1 + in_j + dilation_w*2, vl),vl);
vout0 = vfmacc_vf_f32m8(vout0, w20, vle32_v_f32m8(imgptr2 + in_j, vl), vl);
vout0 = vfmacc_vf_f32m8(vout0, w21, vle32_v_f32m8(imgptr2 + in_j + dilation_w, vl), vl);
vout0 = vfmacc_vf_f32m8(vout0, w22, vle32_v_f32m8(imgptr2 + in_j + dilation_w*2, vl), vl);
vfloat32m8_t vout0 = __riscv_vfmacc_vf_f32m8(__riscv_vfmv_v_f_f32m8(bias, vl), w00, __riscv_vle32_v_f32m8(imgptr0 + in_j, vl), vl);
vout0 = __riscv_vfmacc_vf_f32m8(vout0, w01, __riscv_vle32_v_f32m8(imgptr0 + in_j + dilation_w, vl), vl);
vout0 = __riscv_vfmacc_vf_f32m8(vout0, w02, __riscv_vle32_v_f32m8(imgptr0 + in_j + dilation_w*2, vl), vl);
vout0 = __riscv_vfmacc_vf_f32m8(vout0, w10, __riscv_vle32_v_f32m8(imgptr1 + in_j, vl),vl);
vout0 = __riscv_vfmacc_vf_f32m8(vout0, w11, __riscv_vle32_v_f32m8(imgptr1 + in_j + dilation_w, vl),vl);
vout0 = __riscv_vfmacc_vf_f32m8(vout0, w12, __riscv_vle32_v_f32m8(imgptr1 + in_j + dilation_w*2, vl),vl);
vout0 = __riscv_vfmacc_vf_f32m8(vout0, w20, __riscv_vle32_v_f32m8(imgptr2 + in_j, vl), vl);
vout0 = __riscv_vfmacc_vf_f32m8(vout0, w21, __riscv_vle32_v_f32m8(imgptr2 + in_j + dilation_w, vl), vl);
vout0 = __riscv_vfmacc_vf_f32m8(vout0, w22, __riscv_vle32_v_f32m8(imgptr2 + in_j + dilation_w*2, vl), vl);
if (relu)
{
vbool4_t m = vmfgt_vf_f32m8_b4(vout0, 0, vl);
vout0 = vmerge_vvm_f32m8(m, vfmul_vf_f32m8(vout0, relu_coeff, vl), vout0, vl);
vbool4_t m = __riscv_vmfgt_vf_f32m8_b4(vout0, 0, vl);
vout0 = __riscv_vmerge_vvm_f32m8(__riscv_vfmul_vf_f32m8(vout0, relu_coeff, vl), vout0, m, vl);
}
vse32_v_f32m8(outptr + out_j, vout0, vl);
__riscv_vse32_v_f32m8(outptr + out_j, vout0, vl);
}
else //stride_w == 2 && dilation_w == 1
for( ; out_j < outW1; out_j += vl, avl -= vl)
{
vl = vsetvl_e32m2(avl);
vl = __riscv_vsetvl_e32m2(avl);
int in_j = out_j * stride_w - pad_l;
vfloat32m2_t vout0 = vfmacc_vf_f32m2(vfmv_v_f_f32m2(bias, vl), w00, vlse32_v_f32m2(imgptr0+in_j , 8, vl), vl);
vfloat32m2_t vout1 = vfmul_vf_f32m2(vlse32_v_f32m2(imgptr0+in_j+1, 8, vl), w01, vl);
vfloat32m2_t vout2 = vfmul_vf_f32m2(vlse32_v_f32m2(imgptr0+in_j+2, 8, vl), w02, vl);
vfloat32m2_t vout0 = __riscv_vfmacc_vf_f32m2(__riscv_vfmv_v_f_f32m2(bias, vl), w00, __riscv_vlse32_v_f32m2(imgptr0+in_j , 8, vl), vl);
vfloat32m2_t vout1 = __riscv_vfmul_vf_f32m2(__riscv_vlse32_v_f32m2(imgptr0+in_j+1, 8, vl), w01, vl);
vfloat32m2_t vout2 = __riscv_vfmul_vf_f32m2(__riscv_vlse32_v_f32m2(imgptr0+in_j+2, 8, vl), w02, vl);
vout0 = vfmacc_vf_f32m2(vout0, w10, vlse32_v_f32m2(imgptr1+in_j , 8, vl), vl);
vout1 = vfmacc_vf_f32m2(vout1, w11, vlse32_v_f32m2(imgptr1+in_j+1, 8, vl), vl);
vout2 = vfmacc_vf_f32m2(vout2, w12, vlse32_v_f32m2(imgptr1+in_j+2, 8, vl), vl);
vout0 = __riscv_vfmacc_vf_f32m2(vout0, w10, __riscv_vlse32_v_f32m2(imgptr1+in_j , 8, vl), vl);
vout1 = __riscv_vfmacc_vf_f32m2(vout1, w11, __riscv_vlse32_v_f32m2(imgptr1+in_j+1, 8, vl), vl);
vout2 = __riscv_vfmacc_vf_f32m2(vout2, w12, __riscv_vlse32_v_f32m2(imgptr1+in_j+2, 8, vl), vl);
vout0 = vfmacc_vf_f32m2(vout0, w20, vlse32_v_f32m2(imgptr2+in_j , 8, vl), vl);
vout1 = vfmacc_vf_f32m2(vout1, w21, vlse32_v_f32m2(imgptr2+in_j+1, 8, vl), vl);
vout2 = vfmacc_vf_f32m2(vout2, w22, vlse32_v_f32m2(imgptr2+in_j+2, 8, vl), vl);
vout0 = __riscv_vfmacc_vf_f32m2(vout0, w20, __riscv_vlse32_v_f32m2(imgptr2+in_j , 8, vl), vl);
vout1 = __riscv_vfmacc_vf_f32m2(vout1, w21, __riscv_vlse32_v_f32m2(imgptr2+in_j+1, 8, vl), vl);
vout2 = __riscv_vfmacc_vf_f32m2(vout2, w22, __riscv_vlse32_v_f32m2(imgptr2+in_j+2, 8, vl), vl);
vout0 = vfadd_vv_f32m2(vfadd_vv_f32m2(vout0, vout1, vl), vout2, vl);
vout0 = __riscv_vfadd_vv_f32m2(__riscv_vfadd_vv_f32m2(vout0, vout1, vl), vout2, vl);
if (relu)
{
vbool16_t m = vmfgt_vf_f32m2_b16(vout0, 0, vl);
vout0 = vmerge_vvm_f32m2(m, vfmul_vf_f32m2(vout0, relu_coeff, vl), vout0, vl);
vbool16_t m = __riscv_vmfgt_vf_f32m2_b16(vout0, 0, vl);
vout0 = __riscv_vmerge_vvm_f32m2(__riscv_vfmul_vf_f32m2(vout0, relu_coeff, vl), vout0, m, vl);
}
vse32_v_f32m2(outptr + out_j, vout0, vl);
__riscv_vse32_v_f32m2(outptr + out_j, vout0, vl);
}
}
+219 -26
View File
@@ -730,12 +730,6 @@ struct GeluFunctor : public BaseFunctor {
one = vx_setall_f32(1.0f),
reciprocal_sqrt2 = vx_setall_f32(M_SQRT1_2);
for (; i <= len - vlanes; i += vlanes) {
if (i + vlanes > len) {
if (i == 0 || i == len) {
break;
}
i = len - vlanes;
}
v_float32 x0 = vx_load(srcptr + i);
// t = x * M_SQRT1_2
@@ -910,7 +904,17 @@ const char* const TanHFunctor::BaseDefaultFunctor<TanHFunctor>::ocl_kernel_name
struct SwishFunctor : public BaseDefaultFunctor<SwishFunctor>
{
typedef SwishLayer Layer;
using Layer = SwishLayer;
int vlanes;
explicit SwishFunctor() {
#if (CV_SIMD || CV_SIMD_SCALABLE)
vlanes = VTraits<v_float32>::vlanes();
#else
vlanes = 1;
#endif
}
bool supportBackend(int backendId, int)
{
@@ -925,6 +929,32 @@ struct SwishFunctor : public BaseDefaultFunctor<SwishFunctor>
return x / (1.f + exp(-x));
}
void apply(const float* srcptr, float* dstptr, int stripeStart, int len, size_t planeSize, int cn0, int cn1) const {
CV_UNUSED(stripeStart);
for (int cn = cn0; cn < cn1; cn++, srcptr += planeSize, dstptr += planeSize) {
int i = 0;
#if (CV_SIMD || CV_SIMD_SCALABLE)
// x / (1.f + exp(-x));
v_float32 one = vx_setall_f32(1.0f),
zero = vx_setzero_f32();
for (; i <= len - vlanes; i += vlanes) {
v_float32 x = vx_load(srcptr + i);
v_float32 t = v_sub(zero, x);
t = v_exp(t);
t = v_add(one, t);
t = v_div(x, t);
vx_store(dstptr + i, t);
}
#endif
// In case SIMD is not available or len < vlanes
for (; i < len; i++) {
dstptr[i] = calculate(srcptr[i]);
}
}
}
#ifdef HAVE_CUDA
Ptr<BackendNode> initCUDA(int target, csl::Stream stream)
{
@@ -969,9 +999,27 @@ struct SwishFunctor : public BaseDefaultFunctor<SwishFunctor>
template<>
const char* const SwishFunctor::BaseDefaultFunctor<SwishFunctor>::ocl_kernel_name = "SwishForward";
namespace {
constexpr float MISH_THRESHOLD = -36.73f;
}
/*
This implementation is derived from
https://github.com/vpisarev/ficus/blob/3c9a8b78f49e17489c5e1fd6dd5dd487348c99c2/lib/NN/OpElemwise.fx#L110
*/
struct MishFunctor : public BaseDefaultFunctor<MishFunctor>
{
typedef MishLayer Layer;
using Layer = MishLayer;
int vlanes;
explicit MishFunctor() {
#if (CV_SIMD || CV_SIMD_SCALABLE)
vlanes = VTraits<v_float32>::vlanes();
#else
vlanes = 1;
#endif
}
bool supportBackend(int backendId, int)
{
@@ -983,15 +1031,34 @@ struct MishFunctor : public BaseDefaultFunctor<MishFunctor>
inline float calculate(float x) const
{
// Use fast approximation introduced in https://github.com/opencv/opencv/pull/17200
if (x >= 8.f)
{
return x;
}
float y = x > MISH_THRESHOLD ? std::exp(-x) : 1.f;
x *= x > MISH_THRESHOLD ? 1.f : 0.f;
return x * (1 + 2 * y) / (1 + 2 * y + 2 * y * y);
}
float eX = exp(x);
float n = (eX + 2.f) * eX;
return (x * n) / (n + 2.f);
void apply(const float* srcptr, float* dstptr, int stripeStart, int len, size_t planeSize, int cn0, int cn1) const {
CV_UNUSED(stripeStart);
for (int cn = cn0; cn < cn1; cn++, srcptr += planeSize, dstptr += planeSize) {
int i = 0;
#if (CV_SIMD || CV_SIMD_SCALABLE)
v_float32 v_threshold = vx_setall_f32(MISH_THRESHOLD), one = vx_setall_f32(1.f), z = vx_setzero_f32();
for (; i <= len - vlanes; i += vlanes) {
v_float32 x = vx_load(srcptr + i);
x = v_select(v_le(x, v_threshold), z, x);
v_float32 y = v_exp(v_sub(z, x));
v_float32 _2y = v_add(y, y),
_2ya1 = v_add(_2y, one);
x = v_div(v_mul(x, _2ya1), v_add(_2ya1, v_mul(_2y, y)));
vx_store(dstptr + i, x);
}
#endif
// In case SIMD is not available or len < vlanes
for (; i < len; i++) {
dstptr[i] = calculate(srcptr[i]);
}
}
}
#ifdef HAVE_CUDA
@@ -1105,10 +1172,18 @@ const char* const SigmoidFunctor::BaseDefaultFunctor<SigmoidFunctor>::ocl_kernel
struct ELUFunctor : public BaseDefaultFunctor<ELUFunctor>
{
typedef ELULayer Layer;
float alpha;
using Layer = ELULayer;
explicit ELUFunctor(float alpha_ = 1.f) : alpha(alpha_) {}
float alpha;
int vlanes;
explicit ELUFunctor(float alpha_ = 1.f) : alpha(alpha_) {
#if (CV_SIMD || CV_SIMD_SCALABLE)
vlanes = VTraits<v_float32>::vlanes();
#else
vlanes = 1;
#endif
}
bool supportBackend(int backendId, int)
{
@@ -1126,6 +1201,28 @@ struct ELUFunctor : public BaseDefaultFunctor<ELUFunctor>
return x >= 0.f ? x : alpha * (exp(x) - 1.f);
}
void apply(const float* srcptr, float* dstptr, int stripeStart, int len, size_t planeSize, int cn0, int cn1) const {
CV_UNUSED(stripeStart);
for (int cn = cn0; cn < cn1; cn++, srcptr += planeSize, dstptr += planeSize) {
int i = 0;
#if (CV_SIMD || CV_SIMD_SCALABLE)
v_float32 z = vx_setzero_f32(), v_alpha = vx_setall_f32(alpha), one = vx_setall_f32(1.0f);
for (; i <= len - vlanes; i += vlanes) {
v_float32 x = vx_load(srcptr + i);
v_float32 t = v_mul(v_alpha, v_sub(v_exp(x), one));
x = v_select(v_ge(x, z), x, t);
vx_store(dstptr + i, x);
}
#endif
// In case SIMD is not available or len < vlanes
for (; i < len; i++) {
dstptr[i] = calculate(srcptr[i]);
}
}
}
inline void setKernelParams(ocl::Kernel& kernel) const
{
kernel.set(3, alpha);
@@ -1722,7 +1819,16 @@ const char* const BaseDefaultFunctor<ErfFunctor>::ocl_kernel_name = "ErfForward"
struct HardSwishFunctor : public BaseDefaultFunctor<HardSwishFunctor>
{
typedef HardSwishLayer Layer;
using Layer = HardSwishLayer;
int vlanes;
explicit HardSwishFunctor() {
#if (CV_SIMD || CV_SIMD_SCALABLE)
vlanes = VTraits<v_float32>::vlanes();
#else
vlanes = 1;
#endif
}
bool supportBackend(int backendId, int)
{
@@ -1733,7 +1839,32 @@ struct HardSwishFunctor : public BaseDefaultFunctor<HardSwishFunctor>
inline float calculate(float x) const
{
return x * max(0.f, min(1.f, x / 6.f + 0.5f));
return x * std::max(0.f, std::min(1.f, x / 6.f + 0.5f));
}
void apply(const float* srcptr, float* dstptr, int stripeStart, int len, size_t planeSize, int cn0, int cn1) const {
CV_UNUSED(stripeStart);
for (int cn = cn0; cn < cn1; cn++, srcptr += planeSize, dstptr += planeSize) {
int i = 0;
#if (CV_SIMD || CV_SIMD_SCALABLE)
v_float32 zero = vx_setzero_f32(), one = vx_setall_f32(1.0f),
half = vx_setall_f32(0.5f), sixth = vx_setall_f32(1 / 6.0f);
for (; i <= len - vlanes; i += vlanes) {
v_float32 x = vx_load(srcptr + i);
v_float32 t = v_add(v_mul(x, sixth), half);
t = v_min(one, t);
t = v_max(zero, t);
t = v_mul(x, t);
vx_store(dstptr + i, t);
}
#endif
// In case SIMD is not available or len > vlanes
for (; i < len; i++) {
dstptr[i] = calculate(srcptr[i]);
}
}
}
#ifdef HAVE_CUDA
@@ -1907,11 +2038,18 @@ const char* const BaseDefaultFunctor<TanFunctor>::ocl_kernel_name = "TanForward"
struct CeluFunctor : public BaseDefaultFunctor<CeluFunctor>
{
typedef CeluLayer Layer;
using Layer = CeluLayer;
float alpha;
int vlanes;
explicit CeluFunctor(float alpha_ = 1.f) : alpha(alpha_) {}
explicit CeluFunctor(float alpha_ = 1.f) : alpha(alpha_) {
#if (CV_SIMD || CV_SIMD_SCALABLE)
vlanes = VTraits<v_float32>::vlanes();
#else
vlanes = 1;
#endif
}
bool supportBackend(int backendId, int)
{
@@ -1920,7 +2058,30 @@ struct CeluFunctor : public BaseDefaultFunctor<CeluFunctor>
inline float calculate(float x) const
{
return max(0.f, x) + min(0.f, alpha * expm1(x / alpha));
return std::max(0.f, x) + std::min(0.f, alpha * expm1(x / alpha));
}
void apply(const float* srcptr, float* dstptr, int stripeStart, int len, size_t planeSize, int cn0, int cn1) const {
CV_UNUSED(stripeStart);
for (int cn = cn0; cn < cn1; cn++, srcptr += planeSize, dstptr += planeSize) {
int i = 0;
#if (CV_SIMD || CV_SIMD_SCALABLE)
v_float32 zero = vx_setzero_f32(), v_alpha = vx_setall_f32(alpha),
one = vx_setall_f32(1.0f), v_ralpha = vx_setall_f32(1.0f / alpha);
for (; i <= len - vlanes; i += vlanes) {
v_float32 x = vx_load(srcptr + i);
v_float32 t = v_min(zero, v_mul(v_alpha, v_sub(v_exp(v_mul(x, v_ralpha)), one)));
t = v_add(v_max(zero, x), t);
vx_store(dstptr + i, t);
}
#endif
// In case SIMD is not available or len < vlanes
for (; i < len; i++) {
dstptr[i] = calculate(srcptr[i]);
}
}
}
inline void setKernelParams(ocl::Kernel& kernel) const
@@ -1981,13 +2142,21 @@ const char* const BaseDefaultFunctor<HardSigmoidFunctor>::ocl_kernel_name = "Har
struct SeluFunctor : public BaseDefaultFunctor<SeluFunctor>
{
typedef SeluLayer Layer;
using Layer = SeluLayer;
float alpha;
float gamma;
int vlanes;
explicit SeluFunctor(float alpha_ = 1.67326319217681884765625f,
float gamma_ = 1.05070102214813232421875f) : alpha(alpha_), gamma(gamma_) {}
float gamma_ = 1.05070102214813232421875f)
: alpha(alpha_), gamma(gamma_) {
#if (CV_SIMD || CV_SIMD_SCALABLE)
vlanes = VTraits<v_float32>::vlanes();
#else
vlanes = 1;
#endif
}
bool supportBackend(int backendId, int)
{
@@ -1999,6 +2168,30 @@ struct SeluFunctor : public BaseDefaultFunctor<SeluFunctor>
return gamma * (x > 0.f ? x : alpha * expm1(x));
}
void apply(const float* srcptr, float* dstptr, int stripeStart, int len, size_t planeSize, int cn0, int cn1) const {
CV_UNUSED(stripeStart);
for (int cn = cn0; cn < cn1; cn++, srcptr += planeSize, dstptr += planeSize) {
int i = 0;
#if (CV_SIMD || CV_SIMD_SCALABLE)
v_float32 z = vx_setzero_f32(), one = vx_setall_f32(1.0f),
v_alpha = vx_setall_f32(alpha), v_gamma = vx_setall_f32(gamma);
for (; i <= len - vlanes; i += vlanes) {
v_float32 x = vx_load(srcptr + i);
v_float32 t = v_mul(v_alpha, v_sub(v_exp(x), one));
x = v_select(v_le(x, z), t, x);
x = v_mul(v_gamma, x);
vx_store(dstptr + i, x);
}
#endif
// In case SIMD is not available or len > vlanes
for (; i < len; i++) {
dstptr[i] = calculate(srcptr[i]);
}
}
}
inline void setKernelParams(ocl::Kernel& kernel) const
{
kernel.set(3, alpha);
@@ -276,7 +276,7 @@ public:
opt_AVX::fastGEMM1T( sptr, wptr, wstep, biasptr, dptr, nw, vecsize_aligned);
else
#endif
#if CV_TRY_RVV
#if CV_TRY_RVV && CV_RVV
if( useRVV )
opt_RVV::fastGEMM1T( sptr, wptr, wstep, biasptr, dptr, nw, vecsize);
else
+102 -102
View File
@@ -295,7 +295,7 @@ void fastGEMM( const float* aptr, size_t astep, const float* bptr,
int avl = nb, vl;
for(int n = 0; n < nb; n += vl, avl -= vl)
{
vl = vsetvl_e32m4(avl);
vl = __riscv_vsetvl_e32m4(avl);
for( int m = 0; m < ma; m += 7 )
{
const float* aptr0 = aptr + astep*m;
@@ -314,13 +314,13 @@ void fastGEMM( const float* aptr, size_t astep, const float* bptr,
float* cptr5 = cptr + cstep*std::min(m+5, ma-1);
float* cptr6 = cptr + cstep*std::min(m+6, ma-1);
vfloat32m4_t d0 = vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d1 = vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d2 = vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d3 = vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d4 = vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d5 = vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d6 = vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d0 = __riscv_vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d1 = __riscv_vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d2 = __riscv_vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d3 = __riscv_vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d4 = __riscv_vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d5 = __riscv_vfmv_v_f_f32m4(0, vl);
vfloat32m4_t d6 = __riscv_vfmv_v_f_f32m4(0, vl);
for( int k = 0; k < na; k++ )
{
@@ -332,22 +332,22 @@ void fastGEMM( const float* aptr, size_t astep, const float* bptr,
float a5 = aptr5[k];
float a6 = aptr6[k];
vfloat32m4_t b = vle32_v_f32m4(bptr + k*bstep + n, vl);
d0 = vfmacc_vf_f32m4(d0, a0, b, vl);
d1 = vfmacc_vf_f32m4(d1, a1, b, vl);
d2 = vfmacc_vf_f32m4(d2, a2, b, vl);
d3 = vfmacc_vf_f32m4(d3, a3, b, vl);
d4 = vfmacc_vf_f32m4(d4, a4, b, vl);
d5 = vfmacc_vf_f32m4(d5, a5, b, vl);
d6 = vfmacc_vf_f32m4(d6, a6, b, vl);
vfloat32m4_t b = __riscv_vle32_v_f32m4(bptr + k*bstep + n, vl);
d0 = __riscv_vfmacc_vf_f32m4(d0, a0, b, vl);
d1 = __riscv_vfmacc_vf_f32m4(d1, a1, b, vl);
d2 = __riscv_vfmacc_vf_f32m4(d2, a2, b, vl);
d3 = __riscv_vfmacc_vf_f32m4(d3, a3, b, vl);
d4 = __riscv_vfmacc_vf_f32m4(d4, a4, b, vl);
d5 = __riscv_vfmacc_vf_f32m4(d5, a5, b, vl);
d6 = __riscv_vfmacc_vf_f32m4(d6, a6, b, vl);
}
vse32_v_f32m4(cptr0 + n, d0, vl);
vse32_v_f32m4(cptr1 + n, d1, vl);
vse32_v_f32m4(cptr2 + n, d2, vl);
vse32_v_f32m4(cptr3 + n, d3, vl);
vse32_v_f32m4(cptr4 + n, d4, vl);
vse32_v_f32m4(cptr5 + n, d5, vl);
vse32_v_f32m4(cptr6 + n, d6, vl);
__riscv_vse32_v_f32m4(cptr0 + n, d0, vl);
__riscv_vse32_v_f32m4(cptr1 + n, d1, vl);
__riscv_vse32_v_f32m4(cptr2 + n, d2, vl);
__riscv_vse32_v_f32m4(cptr3 + n, d3, vl);
__riscv_vse32_v_f32m4(cptr4 + n, d4, vl);
__riscv_vse32_v_f32m4(cptr5 + n, d5, vl);
__riscv_vse32_v_f32m4(cptr6 + n, d6, vl);
}
}
}
@@ -356,112 +356,112 @@ void fastGEMM1T( const float* vec, const float* weights,
size_t wstep, const float* bias,
float* dst, int nvecs, int vecsize )
{
const int vlm2 = vsetvlmax_e32m2();
const int vlm2 = __riscv_vsetvlmax_e32m2();
int i = 0;
for( ; i <= nvecs - 15; i += 15 )
{
const float* wptr = weights + i*wstep;
vfloat32m2_t
vs0 = vfmv_v_f_f32m2(0, vlm2), vs1 = vfmv_v_f_f32m2(0, vlm2), vs2 = vfmv_v_f_f32m2(0, vlm2),
vs3 = vfmv_v_f_f32m2(0, vlm2), vs4 = vfmv_v_f_f32m2(0, vlm2), vs5 = vfmv_v_f_f32m2(0, vlm2),
vs6 = vfmv_v_f_f32m2(0, vlm2), vs7 = vfmv_v_f_f32m2(0, vlm2), vs8 = vfmv_v_f_f32m2(0, vlm2),
vs9 = vfmv_v_f_f32m2(0, vlm2), vs10 = vfmv_v_f_f32m2(0, vlm2), vs11 = vfmv_v_f_f32m2(0, vlm2),
vs12 = vfmv_v_f_f32m2(0, vlm2), vs13 = vfmv_v_f_f32m2(0, vlm2), vs14 = vfmv_v_f_f32m2(0, vlm2);
vs0 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs1 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs2 = __riscv_vfmv_v_f_f32m2(0, vlm2),
vs3 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs4 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs5 = __riscv_vfmv_v_f_f32m2(0, vlm2),
vs6 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs7 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs8 = __riscv_vfmv_v_f_f32m2(0, vlm2),
vs9 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs10 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs11 = __riscv_vfmv_v_f_f32m2(0, vlm2),
vs12 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs13 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs14 = __riscv_vfmv_v_f_f32m2(0, vlm2);
int avl = vecsize, vl;
for(int k = 0 ; k < vecsize; k += vl, wptr += vl, avl -= vl)
{
vl = vsetvl_e32m2(avl);
vfloat32m2_t v = vle32_v_f32m2(vec + k, vl);
vs0 = vfmacc_vv_f32m2(vs0, vle32_v_f32m2(wptr, vl), v, vl);
vs1 = vfmacc_vv_f32m2(vs1, vle32_v_f32m2(wptr + wstep, vl), v, vl);
vs2 = vfmacc_vv_f32m2(vs2, vle32_v_f32m2(wptr + wstep*2, vl), v, vl);
vs3 = vfmacc_vv_f32m2(vs3, vle32_v_f32m2(wptr + wstep*3, vl), v, vl);
vs4 = vfmacc_vv_f32m2(vs4, vle32_v_f32m2(wptr + wstep*4, vl), v, vl);
vs5 = vfmacc_vv_f32m2(vs5, vle32_v_f32m2(wptr + wstep*5, vl), v, vl);
vs6 = vfmacc_vv_f32m2(vs6, vle32_v_f32m2(wptr + wstep*6, vl), v, vl);
vs7 = vfmacc_vv_f32m2(vs7, vle32_v_f32m2(wptr + wstep*7, vl), v, vl);
vs8 = vfmacc_vv_f32m2(vs8, vle32_v_f32m2(wptr + wstep*8, vl), v, vl);
vs9 = vfmacc_vv_f32m2(vs9, vle32_v_f32m2(wptr + wstep*9, vl), v, vl);
vs10 = vfmacc_vv_f32m2(vs10, vle32_v_f32m2(wptr + wstep*10, vl), v, vl);
vs11 = vfmacc_vv_f32m2(vs11, vle32_v_f32m2(wptr + wstep*11, vl), v, vl);
vs12 = vfmacc_vv_f32m2(vs12, vle32_v_f32m2(wptr + wstep*12, vl), v, vl);
vs13 = vfmacc_vv_f32m2(vs13, vle32_v_f32m2(wptr + wstep*13, vl), v, vl);
vs14 = vfmacc_vv_f32m2(vs14, vle32_v_f32m2(wptr + wstep*14, vl), v, vl);
vl = __riscv_vsetvl_e32m2(avl);
vfloat32m2_t v = __riscv_vle32_v_f32m2(vec + k, vl);
vs0 = __riscv_vfmacc_vv_f32m2(vs0, __riscv_vle32_v_f32m2(wptr, vl), v, vl);
vs1 = __riscv_vfmacc_vv_f32m2(vs1, __riscv_vle32_v_f32m2(wptr + wstep, vl), v, vl);
vs2 = __riscv_vfmacc_vv_f32m2(vs2, __riscv_vle32_v_f32m2(wptr + wstep*2, vl), v, vl);
vs3 = __riscv_vfmacc_vv_f32m2(vs3, __riscv_vle32_v_f32m2(wptr + wstep*3, vl), v, vl);
vs4 = __riscv_vfmacc_vv_f32m2(vs4, __riscv_vle32_v_f32m2(wptr + wstep*4, vl), v, vl);
vs5 = __riscv_vfmacc_vv_f32m2(vs5, __riscv_vle32_v_f32m2(wptr + wstep*5, vl), v, vl);
vs6 = __riscv_vfmacc_vv_f32m2(vs6, __riscv_vle32_v_f32m2(wptr + wstep*6, vl), v, vl);
vs7 = __riscv_vfmacc_vv_f32m2(vs7, __riscv_vle32_v_f32m2(wptr + wstep*7, vl), v, vl);
vs8 = __riscv_vfmacc_vv_f32m2(vs8, __riscv_vle32_v_f32m2(wptr + wstep*8, vl), v, vl);
vs9 = __riscv_vfmacc_vv_f32m2(vs9, __riscv_vle32_v_f32m2(wptr + wstep*9, vl), v, vl);
vs10 = __riscv_vfmacc_vv_f32m2(vs10, __riscv_vle32_v_f32m2(wptr + wstep*10, vl), v, vl);
vs11 = __riscv_vfmacc_vv_f32m2(vs11, __riscv_vle32_v_f32m2(wptr + wstep*11, vl), v, vl);
vs12 = __riscv_vfmacc_vv_f32m2(vs12, __riscv_vle32_v_f32m2(wptr + wstep*12, vl), v, vl);
vs13 = __riscv_vfmacc_vv_f32m2(vs13, __riscv_vle32_v_f32m2(wptr + wstep*13, vl), v, vl);
vs14 = __riscv_vfmacc_vv_f32m2(vs14, __riscv_vle32_v_f32m2(wptr + wstep*14, vl), v, vl);
}
// Calculate the sum of each vector
float sum[15];
vfloat32m1_t zero = vfmv_v_f_f32m1(0, vlm2);
sum[0] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs0, zero, vlm2));
sum[1] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs1, zero, vlm2));
sum[2] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs2, zero, vlm2));
sum[3] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs3, zero, vlm2));
sum[4] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs4, zero, vlm2));
sum[5] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs5, zero, vlm2));
sum[6] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs6, zero, vlm2));
sum[7] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs7, zero, vlm2));
sum[8] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs8, zero, vlm2));
sum[9] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs9, zero, vlm2));
sum[10] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs10, zero, vlm2));
sum[11] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs11, zero, vlm2));
sum[12] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs12, zero, vlm2));
sum[13] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs13, zero, vlm2));
sum[14] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs14, zero, vlm2));
vfloat32m1_t zero = __riscv_vfmv_v_f_f32m1(0, vlm2);
sum[0] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs0, zero, vlm2));
sum[1] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs1, zero, vlm2));
sum[2] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs2, zero, vlm2));
sum[3] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs3, zero, vlm2));
sum[4] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs4, zero, vlm2));
sum[5] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs5, zero, vlm2));
sum[6] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs6, zero, vlm2));
sum[7] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs7, zero, vlm2));
sum[8] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs8, zero, vlm2));
sum[9] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs9, zero, vlm2));
sum[10] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs10, zero, vlm2));
sum[11] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs11, zero, vlm2));
sum[12] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs12, zero, vlm2));
sum[13] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs13, zero, vlm2));
sum[14] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs14, zero, vlm2));
vfloat32m4_t s0 = vfadd_vv_f32m4(vle32_v_f32m4(sum, 15), vle32_v_f32m4(bias + i, 15), 15);
vse32_v_f32m4(dst + i, s0, 15);
vfloat32m4_t s0 = __riscv_vfadd_vv_f32m4(__riscv_vle32_v_f32m4(sum, 15), __riscv_vle32_v_f32m4(bias + i, 15), 15);
__riscv_vse32_v_f32m4(dst + i, s0, 15);
}
int unroll_tail = nvecs - i;
if (unroll_tail > 0)
{
const float* wptr = weights + i*wstep;
vfloat32m2_t
vs0 = vfmv_v_f_f32m2(0, vlm2), vs1 = vfmv_v_f_f32m2(0, vlm2), vs2 = vfmv_v_f_f32m2(0, vlm2),
vs3 = vfmv_v_f_f32m2(0, vlm2), vs4 = vfmv_v_f_f32m2(0, vlm2), vs5 = vfmv_v_f_f32m2(0, vlm2),
vs6 = vfmv_v_f_f32m2(0, vlm2), vs7 = vfmv_v_f_f32m2(0, vlm2), vs8 = vfmv_v_f_f32m2(0, vlm2),
vs9 = vfmv_v_f_f32m2(0, vlm2), vs10 = vfmv_v_f_f32m2(0, vlm2), vs11 = vfmv_v_f_f32m2(0, vlm2),
vs12 = vfmv_v_f_f32m2(0, vlm2), vs13 = vfmv_v_f_f32m2(0, vlm2);
vs0 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs1 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs2 = __riscv_vfmv_v_f_f32m2(0, vlm2),
vs3 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs4 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs5 = __riscv_vfmv_v_f_f32m2(0, vlm2),
vs6 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs7 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs8 = __riscv_vfmv_v_f_f32m2(0, vlm2),
vs9 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs10 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs11 = __riscv_vfmv_v_f_f32m2(0, vlm2),
vs12 = __riscv_vfmv_v_f_f32m2(0, vlm2), vs13 = __riscv_vfmv_v_f_f32m2(0, vlm2);
int avl = vecsize, vl;
for(int k = 0; k < vecsize; k += vl, wptr += vl, avl -= vl)
{
vl = vsetvl_e32m2(avl);
vfloat32m2_t v = vle32_v_f32m2(vec + k, vl);
vs0 = vfmacc_vv_f32m2(vs0, vle32_v_f32m2(wptr, vl), v, vl);
vs1 = vfmacc_vv_f32m2(vs1, vle32_v_f32m2(wptr + wstep*std::min(1, unroll_tail-1), vl), v, vl);
vs2 = vfmacc_vv_f32m2(vs2, vle32_v_f32m2(wptr + wstep*std::min(2, unroll_tail-1), vl), v, vl);
vs3 = vfmacc_vv_f32m2(vs3, vle32_v_f32m2(wptr + wstep*std::min(3, unroll_tail-1), vl), v, vl);
vs4 = vfmacc_vv_f32m2(vs4, vle32_v_f32m2(wptr + wstep*std::min(4, unroll_tail-1), vl), v, vl);
vs5 = vfmacc_vv_f32m2(vs5, vle32_v_f32m2(wptr + wstep*std::min(5, unroll_tail-1), vl), v, vl);
vs6 = vfmacc_vv_f32m2(vs6, vle32_v_f32m2(wptr + wstep*std::min(6, unroll_tail-1), vl), v, vl);
vs7 = vfmacc_vv_f32m2(vs7, vle32_v_f32m2(wptr + wstep*std::min(7, unroll_tail-1), vl), v, vl);
vs8 = vfmacc_vv_f32m2(vs8, vle32_v_f32m2(wptr + wstep*std::min(8, unroll_tail-1), vl), v, vl);
vs9 = vfmacc_vv_f32m2(vs9, vle32_v_f32m2(wptr + wstep*std::min(9, unroll_tail-1), vl), v, vl);
vs10 = vfmacc_vv_f32m2(vs10, vle32_v_f32m2(wptr + wstep*std::min(10, unroll_tail-1), vl), v, vl);
vs11 = vfmacc_vv_f32m2(vs11, vle32_v_f32m2(wptr + wstep*std::min(11, unroll_tail-1), vl), v, vl);
vs12 = vfmacc_vv_f32m2(vs12, vle32_v_f32m2(wptr + wstep*std::min(12, unroll_tail-1), vl), v, vl);
vs13 = vfmacc_vv_f32m2(vs13, vle32_v_f32m2(wptr + wstep*std::min(13, unroll_tail-1), vl), v, vl);
vl = __riscv_vsetvl_e32m2(avl);
vfloat32m2_t v = __riscv_vle32_v_f32m2(vec + k, vl);
vs0 = __riscv_vfmacc_vv_f32m2(vs0, __riscv_vle32_v_f32m2(wptr, vl), v, vl);
vs1 = __riscv_vfmacc_vv_f32m2(vs1, __riscv_vle32_v_f32m2(wptr + wstep*std::min(1, unroll_tail-1), vl), v, vl);
vs2 = __riscv_vfmacc_vv_f32m2(vs2, __riscv_vle32_v_f32m2(wptr + wstep*std::min(2, unroll_tail-1), vl), v, vl);
vs3 = __riscv_vfmacc_vv_f32m2(vs3, __riscv_vle32_v_f32m2(wptr + wstep*std::min(3, unroll_tail-1), vl), v, vl);
vs4 = __riscv_vfmacc_vv_f32m2(vs4, __riscv_vle32_v_f32m2(wptr + wstep*std::min(4, unroll_tail-1), vl), v, vl);
vs5 = __riscv_vfmacc_vv_f32m2(vs5, __riscv_vle32_v_f32m2(wptr + wstep*std::min(5, unroll_tail-1), vl), v, vl);
vs6 = __riscv_vfmacc_vv_f32m2(vs6, __riscv_vle32_v_f32m2(wptr + wstep*std::min(6, unroll_tail-1), vl), v, vl);
vs7 = __riscv_vfmacc_vv_f32m2(vs7, __riscv_vle32_v_f32m2(wptr + wstep*std::min(7, unroll_tail-1), vl), v, vl);
vs8 = __riscv_vfmacc_vv_f32m2(vs8, __riscv_vle32_v_f32m2(wptr + wstep*std::min(8, unroll_tail-1), vl), v, vl);
vs9 = __riscv_vfmacc_vv_f32m2(vs9, __riscv_vle32_v_f32m2(wptr + wstep*std::min(9, unroll_tail-1), vl), v, vl);
vs10 = __riscv_vfmacc_vv_f32m2(vs10, __riscv_vle32_v_f32m2(wptr + wstep*std::min(10, unroll_tail-1), vl), v, vl);
vs11 = __riscv_vfmacc_vv_f32m2(vs11, __riscv_vle32_v_f32m2(wptr + wstep*std::min(11, unroll_tail-1), vl), v, vl);
vs12 = __riscv_vfmacc_vv_f32m2(vs12, __riscv_vle32_v_f32m2(wptr + wstep*std::min(12, unroll_tail-1), vl), v, vl);
vs13 = __riscv_vfmacc_vv_f32m2(vs13, __riscv_vle32_v_f32m2(wptr + wstep*std::min(13, unroll_tail-1), vl), v, vl);
}
// Calculate the sum of each vector
float sum[14];
vfloat32m1_t zero = vfmv_v_f_f32m1(0, vlm2);
sum[0] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs0, zero, vlm2));
sum[1] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs1, zero, vlm2));
sum[2] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs2, zero, vlm2));
sum[3] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs3, zero, vlm2));
sum[4] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs4, zero, vlm2));
sum[5] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs5, zero, vlm2));
sum[6] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs6, zero, vlm2));
sum[7] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs7, zero, vlm2));
sum[8] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs8, zero, vlm2));
sum[9] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs9, zero, vlm2));
sum[10] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs10, zero, vlm2));
sum[11] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs11, zero, vlm2));
sum[12] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs12, zero, vlm2));
sum[13] = vfmv_f_s_f32m1_f32(vfredosum_vs_f32m2_f32m1(zero, vs13, zero, vlm2));
vfloat32m1_t zero = __riscv_vfmv_v_f_f32m1(0, vlm2);
sum[0] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs0, zero, vlm2));
sum[1] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs1, zero, vlm2));
sum[2] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs2, zero, vlm2));
sum[3] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs3, zero, vlm2));
sum[4] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs4, zero, vlm2));
sum[5] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs5, zero, vlm2));
sum[6] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs6, zero, vlm2));
sum[7] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs7, zero, vlm2));
sum[8] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs8, zero, vlm2));
sum[9] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs9, zero, vlm2));
sum[10] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs10, zero, vlm2));
sum[11] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs11, zero, vlm2));
sum[12] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs12, zero, vlm2));
sum[13] = __riscv_vfmv_f_s_f32m1_f32(__riscv_vfredusum_vs_f32m2_f32m1(vs13, zero, vlm2));
vfloat32m4_t s0 = vfadd_vv_f32m4(vle32_v_f32m4(sum, unroll_tail), vle32_v_f32m4(bias + i, unroll_tail), unroll_tail);
vse32_v_f32m4(dst + i, s0, unroll_tail);
vfloat32m4_t s0 = __riscv_vfadd_vv_f32m4(__riscv_vle32_v_f32m4(sum, unroll_tail), __riscv_vle32_v_f32m4(bias + i, unroll_tail), unroll_tail);
__riscv_vse32_v_f32m4(dst + i, s0, unroll_tail);
}
}
@@ -250,7 +250,10 @@ static const TestCase testConformanceConfig[] = {
{"test_einsum_transpose", 1, 1},
{"test_elu", 1, 1},
{"test_elu_default", 1, 1},
{"test_elu_default_expanded_ver18", 1, 1},
{"test_elu_example", 1, 1},
{"test_elu_example_expanded_ver18", 1, 1},
{"test_elu_expanded_ver18", 1, 1},
{"test_equal", 2, 1},
{"test_equal_bcast", 2, 1},
{"test_erf", 1, 1},
@@ -454,6 +457,8 @@ static const TestCase testConformanceConfig[] = {
{"test_min_uint32", 2, 1},
{"test_min_uint64", 2, 1},
{"test_min_uint8", 2, 1},
{"test_mish", 1, 1},
{"test_mish_expanded", 1, 1},
{"test_mod_broadcast", 2, 1},
{"test_mod_int64_fmod", 2, 1},
{"test_mod_mixed_sign_float16", 2, 1},
@@ -775,7 +780,10 @@ static const TestCase testConformanceConfig[] = {
{"test_sce_sum_log_prob_expanded", 2, 2},
{"test_selu", 1, 1},
{"test_selu_default", 1, 1},
{"test_selu_default_expanded_ver18", 1, 1},
{"test_selu_example", 1, 1},
{"test_selu_example_expanded_ver18", 1, 1},
{"test_selu_expanded_ver18", 1, 1},
{"test_sequence_insert_at_back", 2, 1},
{"test_sequence_insert_at_front", 3, 1},
{"test_shape", 1, 1},
@@ -560,8 +560,14 @@ CASE(test_elu)
// no filter
CASE(test_elu_default)
// no filter
CASE(test_elu_default_expanded_ver18)
// no filter
CASE(test_elu_example)
// no filter
CASE(test_elu_example_expanded_ver18)
// no filter
CASE(test_elu_expanded_ver18)
// no filter
CASE(test_equal)
// no filter
CASE(test_equal_bcast)
@@ -1032,6 +1038,10 @@ CASE(test_min_uint64)
// no filter
CASE(test_min_uint8)
// no filter
CASE(test_mish)
// no filter
CASE(test_mish_expanded)
// no filter
CASE(test_mod_broadcast)
// no filter
CASE(test_mod_int64_fmod)
@@ -1783,8 +1793,14 @@ CASE(test_selu)
// no filter
CASE(test_selu_default)
// no filter
CASE(test_selu_default_expanded_ver18)
// no filter
CASE(test_selu_example)
// no filter
CASE(test_selu_example_expanded_ver18)
// no filter
CASE(test_selu_expanded_ver18)
// no filter
CASE(test_sequence_insert_at_back)
// no filter
CASE(test_sequence_insert_at_front)
@@ -94,6 +94,9 @@
"test_dynamicquantizelinear_min_adjusted_expanded", // ---- same as above ---
"test_edge_pad", // Issue::Parser::Weights are required as inputs
"test_einsum_inner_prod", // Issue::Output shape does not match with reference
"test_elu_default_expanded_ver18",
"test_elu_example_expanded_ver18",
"test_elu_expanded_ver18",
"test_expand_dim_changed", // Issue:: Unkonwn error
"test_expand_dim_unchanged", // Issue:: Unkonwn error
"test_eyelike_populate_off_main_diagonal", // Issues::Layer::Can't create layer::Can't create layer "onnx_node_output_0!y" of type "EyeLike" in function 'getLayerInstance'
@@ -357,6 +360,9 @@
"test_sce_sum_expanded", // ---- same as above ---
"test_sce_sum_log_prob", // ---- same as above ---
"test_sce_sum_log_prob_expanded", // ---- same as above ---
"test_selu_default_expanded_ver18",
"test_selu_example_expanded_ver18",
"test_selu_expanded_ver18",
"test_sequence_insert_at_back", // Issue:: Parser: typeProto.has_tensor_type() in function 'populateNet'
"test_sequence_insert_at_front", // ---- same as above ---
"test_shape", // Issue:: Parser: DNN/ONNX: can't find layer for output name: 'y'. Does model imported properly?