diff --git a/modules/dnn/src/layers/cpu_kernels/conv2_depthwise.simd.hpp b/modules/dnn/src/layers/cpu_kernels/conv2_depthwise.simd.hpp index 642695dfbe..e6933584f5 100644 --- a/modules/dnn/src/layers/cpu_kernels/conv2_depthwise.simd.hpp +++ b/modules/dnn/src/layers/cpu_kernels/conv2_depthwise.simd.hpp @@ -38,14 +38,7 @@ static void depthwiseConv32f(const void* inp__, const void* residual__, parallel_for_(Range(0, NC1), [&](const Range& range) { constexpr int MAX_CONV_DIMS = ConvState::MAX_CONV_DIMS; -#if CV_SIMD_SCALABLE - // RVV: universal intrinsics use LMUL=2, so the float vector width tracks - // the hardware VLEN at runtime. The block size C0 == defaultC0 == vlanes() - // (e.g. 16 at VLEN=256), so read it at runtime instead of fixing it to 8 (#28852). - const int C0 = (int)cs.inpshape.back(); -#else constexpr int C0 = 8; -#endif CV_Assert(cs.nspatialdims <= MAX_CONV_DIMS && MAX_CONV_DIMS == 3); CV_Assert(C0 == cs.inpshape.back()); @@ -80,14 +73,7 @@ static void depthwiseConv32f(const void* inp__, const void* residual__, const float* activParams = cs.activParams.data(); ActivationFunc activation = cs.activation; float maxval = FLT_MAX, defaultAlpha = 0.f; -#if CV_SIMD_SCALABLE - // C0 is runtime on RVV; size scratch by the compile-time upper bound. - float scalebuf[VTraits::max_nlanes]; - float biasbuf[VTraits::max_nlanes]; - float alphabuf[VTraits::max_nlanes]; -#else float scalebuf[C0], biasbuf[C0], alphabuf[C0]; -#endif if (fastActivation == FAST_ACTIV_CLIP) { CV_Assert(cs.activParams.size() == 2u); maxval = activParams[1]; diff --git a/modules/dnn/src/layers/cpu_kernels/conv2_kernels.simd.hpp b/modules/dnn/src/layers/cpu_kernels/conv2_kernels.simd.hpp index c49f02b24d..e16af3e22a 100644 --- a/modules/dnn/src/layers/cpu_kernels/conv2_kernels.simd.hpp +++ b/modules/dnn/src/layers/cpu_kernels/conv2_kernels.simd.hpp @@ -2202,17 +2202,11 @@ static void conv32fC8(const void* inp__, const void* residual__, void* out__, parallel_for_(Range(0, total_tasks_gen), [&](const Range& range) { constexpr int SPAT_BLOCK_SIZE = 10; -#if CV_SIMD_SCALABLE - // RVV: block size follows the runtime vector width (defaultC0 = vlanes(), LMUL=2). - const int C0 = (int)inpshape.back(); - int C0shift = 0; while ((1 << C0shift) < C0) C0shift++; - const int K0 = C0, K0shift = C0shift; - constexpr int C0BUF = VTraits::max_nlanes; // compile-time scratch bound -#else + // The block size is a fixed property of the blocked layout on every platform, + // so C0/K0 are compile-time constants here (#29454). constexpr int C0shift = 3, K0shift = C0shift; constexpr int C0 = 1 << C0shift, K0 = C0; constexpr int C0BUF = K0; -#endif CV_Assert_N(inpshape.back() == C0, outshape.back() == K0); @@ -2557,16 +2551,9 @@ static void conv32fC8(const void* inp__, const void* residual__, void* out__, cv::dnn::ConvFunc getConvFunc_(int depth, int C0) { ConvFunc func = nullptr; -#if CV_SIMD_SCALABLE - // RVV: block size follows the runtime vector width; accept the supported pow2 widths. - if (depth == CV_32F && (C0 == 8 || C0 == 16 || C0 == 32 || C0 == 64)) { - func = conv32fC8; - } -#else if (depth == CV_32F && C0 == 8) { func = conv32fC8; } -#endif return func; } diff --git a/modules/dnn/src/net_impl.cpp b/modules/dnn/src/net_impl.cpp index 92445d657e..14aa808527 100644 --- a/modules/dnn/src/net_impl.cpp +++ b/modules/dnn/src/net_impl.cpp @@ -5,7 +5,6 @@ #include "precomp.hpp" #include "net_impl.hpp" -#include "opencv2/core/hal/intrin.hpp" #ifdef HAVE_ONNXRUNTIME #include @@ -74,14 +73,10 @@ Net::Impl::Impl() // onnx_opset = 0; accuracy = CV_32F; + // The block size is a network-wide memory-layout contract, so it must not depend + // on the SIMD width of the host: C0 == 8 is the mainstream, well-tested setting. + // (Deriving it from vlanes() made the layout hardware-dependent; see #29454.) defaultC0 = DEFAULT_C0; -#if CV_SIMD_SCALABLE - // RVV: the universal intrinsics use LMUL=2, so the float vector width is - // (VLEN/32)*2 (16 at VLEN=256). The blocked-layout kernels fill a full - // vector per channel block, so the net-wide block size must match that - // width rather than the fixed default of 8 (#28852). - defaultC0 = std::max((int)DEFAULT_C0, VTraits::vlanes()); -#endif enableFP16 = haveFP16 = false; // FP16 is not ready yet in the new DNN engine // Ticket: https://github.com/opencv/opencv/issues/26196 diff --git a/modules/dnn/src/net_impl2.cpp b/modules/dnn/src/net_impl2.cpp index f7fb5d45f0..d497352dd1 100644 --- a/modules/dnn/src/net_impl2.cpp +++ b/modules/dnn/src/net_impl2.cpp @@ -5,7 +5,6 @@ #include "precomp.hpp" #include "net_impl.hpp" -#include "opencv2/core/hal/intrin.hpp" #include @@ -546,16 +545,6 @@ void Net::Impl::prepareForInference() #endif if (!prepared) { -#if CV_SIMD_SCALABLE - // RVV (#28852): keep quantized graphs at C0=8. The int8 kernels are hardwired to - // C0=8 (VNNI/NEON weight packing + per-channel quantization) and run scalar on RVV, - // so a wider block gives no benefit and breaks them. Only fp32 graphs use the wider - // vlanes()-based defaultC0. Signed-int8 (CV_8S) args are the quantization signature - // (uint8 image inputs are CV_8U, so they don't trigger this). - for (const ArgData& a : args) { - if (a.type == CV_8S) { defaultC0 = 8; break; } - } -#endif fuseQDQ(); constFold(); fuseBN();