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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
Reference in New Issue
Block a user