1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-28 23:03:03 +04:00

2770 Commits

Author SHA1 Message Date
Abhishek Gola 62732ab966 Merge pull request #29524 from abhishek-gola/onnx_coverage
Fix: 0-D / empty-Mat Python binding
2026-07-28 22:14:50 +05:30
Alexander Smorkalov 4ba2752f36 Merge pull request #29601 from Teddy-Yangjiale:rvv-fast-attn
dnn: enable the existing SIMD attention-softmax on scalable RVV
2026-07-26 12:06:45 +03:00
velonica0 18b39f1f34 RVV: switch scalable universal intrinsics from LMUL=2 to LMUL=1 (#29493)
* dnn:rvv: restore the fixed block size C0 == 8

#29304 made the net-wide block size follow the RVV vector width
(defaultC0 = max(8, vlanes())), so the blocked memory layout of every tensor
depended on the host's VLEN and on the LMUL of the universal intrinsics in core.
The same model gets a different layout on a 128-, 256- or 1024-bit machine.

Restore the fixed default of 8, which is the mainstream, well-tested setting on
every platform. C0/K0 become compile-time constants again on RVV as they already
were elsewhere, so the runtime block-size plumbing and the vlanes()-based scratch
sizing are dropped, and getConvFunc_ no longer advertises block sizes the kernels
cannot handle.

The blocked kernels currently require C0 == vlanes(), which this alone does not
satisfy; the next commit removes that requirement.

* dnn:rvv: pin the vector length to the channel block

The blocked kernels assumed one channel block is exactly one vector
(C0 == vlanes()). That is not a property of the layout, it is a property of the
hardware, so the kernels only worked where the two happened to coincide: with
C0 fixed at 8 they break wherever vlanes() != 8 -- under-filling the block when
the vector is narrower (silently leaving output channels unwritten) and
overrunning it when the vector is wider (CV_Assert).

The universal intrinsics cannot express this: v_float32 is always vlanes() wide
and there is no way to make it span exactly C0 elements. So the RVV paths drop to
native intrinsics and set the vector length explicitly:

    const size_t _vl = __riscv_vsetvl_e32m2(C0);   // == 8 on every VLEN >= 128

LMUL=2 is required, not incidental: vlmax(e32,m2) = VLEN/32*2 >= 8 even at
VLEN=128, the narrowest RVV configuration, so _vl == C0 on every RVV 1.0 core.
One vector then spans precisely one channel block regardless of VLEN, and the
C0-vs-vlanes asserts and VLEN-dependent branches are removed rather than extended.
The existing int8 kernels already choose LMUL=2 for the same reason
(conv2_int8_kernels.simd.hpp).

This is a native per-kernel choice and is independent of the LMUL the universal
intrinsics are built with; dnn no longer reads the vector width of
intrin_rvv_scalable.hpp at all.

conv, deconv, maxpool, avgpool and depthwise use native intrinsics. batch_norm
stays portable and instead replicates the C0-wide coefficient pattern across the
vector, which keeps full lane utilisation where a fixed vl would idle most of it.
The x86/ARM paths are restored to their pre-#29304 form and are unchanged.

Tested on SpaceMIT K3 (X100 VLEN=256, A100 VLEN=1024), opencv_test_dnn: no
regressions against upstream on either core.

* core:rvv: switch scalable universal intrinsics from LMUL=2 to LMUL=1

Move the RVV universal-intrinsic types (v_uint8..v_float64) from m2 (paired
registers, 16 usable) to m1 (individual registers, 32 usable) per #29454, to
relieve register pressure in the complex kernels that rely on universal
intrinsics. Simple kernels that regress can take native RVV branches; the complex
ones cannot, so the default should suit them.

Only intrin_rvv_scalable.hpp changes. The widening/narrowing cascades and
max_nlanes are adjusted, and helpers that spell an LMUL into the intrinsic name
shift down one step (m2->m1, m1->mf2): v_popcount, v_lut (vector and f64 paths),
the f64 dot-product reduction (#27003), v_matmul, and the byte-indexed v_lut
added by #29250, whose __riscv_vluxei8_v_u8m2 no longer matches the m1 base type.

VLEN=1024 needs no change: under m1, max_nlanes = CV_RVV_MAX_VLEN/SZ equals
vlanes() at 1024, and CV_RVV_MAX_VLEN already defaults to 1024. Verified on a
1024-bit core.

Tested on SpaceMIT K3, which exposes both a 256-bit (X100) and a 1024-bit (A100)
core. opencv_test_core: 5605/5612, the 7 failures (filestorage_base64, globbing)
non-SIMD and failing identically on the m2 baseline. Perf (x-factor = m2/m1,
>1 = m1 faster), median >= 300us: core 0.966 -> 0.996 and imgproc 0.950 -> 1.038
as VLEN goes 256 -> 1024, i.e. m2's width advantage disappears once both are wide
while m1's register headroom persists. m1 wins resize (1.50/1.41), Exp (1.28),
gaussianBlur (1.23), norm (1.22), scharr (1.20); m2 still wins the light
memory-streaming kernels addWeighted (0.76), compare (0.82) and dot (0.87), which
are the natural candidates for native RVV branches.

* Revert "dnn:rvv: pin the vector length to the channel block"

This reverts commit 40587c6dd9.

* dnn:rvv: disable CV_SIMD_SCALABLE in the new-engine conv kernel

Under the m1 switch the RVV conv kernel breaks at VLEN=128: it assumes
K0 == vlanes(), but m1 makes vlanes()=4 while the block stays C0=K0=8, so it
computes only half of each output block. Temporarily disable the RVV
(CV_SIMD_SCALABLE) branches so conv runs scalar on RVV, exactly as #29180 did for
the other new-engine layers. The vectorized path will be restored in a follow-up.

Only conv is affected: maxpool/avgpool/depthwise/deconv/batch_norm already handle
C0 == 2*vlanes (the SSE/NEON case) and stay on their universal-intrinsic paths.

* dnn:rvv: document the supported VLEN range and the v_setvlmax follow-up

With the fixed C0=8 the RVV blocked kernels cover VLEN=128 and 256 (C0 >= vlanes);
VLEN>=512 (C0 < vlanes) is not yet handled. Add TODO notes recording this and
pointing at the planned fix: a portable v_setvlmax<VT>(n) universal intrinsic that
caps the vector to the block (no-op on fixed-width ISAs, sets the vl/mask on
RVV/SVE), with an optimized multi-pixel variant as a later step, possibly an RVV
HAL for the new dnn engine. See the #29493 discussion.

* dnn:rvv: disable CV_SIMD_SCALABLE in max/avg pooling and depthwise

These three blocked kernels assert (C0 == nlanes || ...) at VLEN>=512, where the
fixed C0=8 is narrower than the vector register — breaking whole networks
(AlexNet/ResNet/YOLO) on wide RVV cores, though CI (VLEN=128) is unaffected.
Disable their RVV (CV_SIMD_SCALABLE) paths so they run scalar on RVV at every
VLEN, matching #29180's scope. Verified on a SpaceMIT K3: this removes the 92
VLEN=1024 assert failures, with no change at VLEN=128/256.

deconv and batch_norm are left enabled: they degrade to scalar at VLEN>=512
(deconv's C0 % vlanes guard, batch_norm's vector-loop bound) without asserting,
so they stay correct and keep their 128/256 vectorization. All of these
re-vectorize uniformly via the v_setvlmax<VT>(n) follow-up.
2026-07-26 02:31:52 +03:00
Teddy-Yangjiale 73c580723c dnn: enable the existing SIMD attention-softmax on scalable RVV 2026-07-26 00:06:23 +08:00
Abhishek Gola fe482bd575 Merge pull request #29577 from abhishek-gola:scan_layer
Add Scan layer to the new engine #29577

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2026-07-25 11:39:47 +03:00
Abhishek Gola b83e561526 Merge pull request #29579 from abhishek-gola:cumprod_causalconv_layers
Added Cumprod and Causalconv layers in new dnn engine #29579

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2026-07-25 11:35:48 +03:00
Abhishek Gola 864f9594ad Merge pull request #29574 from Teddy-Yangjiale/gemm-fast
dnn: keep fastGemmThin accumulators in registers on scalable-vector targets (RVV)
2026-07-24 18:11:22 +05:30
Abhishek Gola a1084efef2 Merge pull request #29548 from vpisarev/no_ocl_fp16
dnn: map FP16 input types to FP32 in getFLOPS for the new graph engine
2026-07-24 15:06:59 +05:30
Teddy-Yangjiale 1af832250b dnn: parameterize fastGemmThin accuracy test (TEST_P) 2026-07-23 23:40:52 +08:00
Abhishek Gola c42778a0e8 Merge pull request #29560 from abhishek-gola:update_conformance_test_list
Updated ONNX conformance list #29560

updated ONNX conformance list with onnx version = 1.22.0

Current ONNX coverage in OpenCV ENGINE_NEW is now **72.1%**
 
Merge with: https://github.com/opencv/opencv_extra/pull/1398 
### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2026-07-23 10:43:35 +03:00
Teddy-Yangjiale 6b04d456b3 add accuracy test for fastGemmThin 2026-07-23 10:17:18 +08:00
Teddy-Yangjiale 7cc9947809 dnn: keep fastGemmThin accumulators in registers on scalable-vector targets (RVV) 2026-07-22 22:42:25 +08:00
Vadim Pisarevsky fd4491fcb1 dnn: map FP16 input types to FP32 in getFLOPS for the new graph engine
The new graph engine has no FP16 execution path yet and runs FP32 on CPU
regardless of the requested target. When an OpenCL FP16 target is requested,
callers may pass CV_16F input types to Net::getFLOPS(), which then flow through
tryInferShapes() -> Layer::getTypes() and get rejected (CV_16F is only allowed
when preferableTarget == DNN_TARGET_OPENCL_FP16, which the new engine never sets).

Normalize FP16 input types to FP32 in the mainGraph path of getFLOPS via a small
filterFP16InputTypes() helper. This fixes the OCL_FP16 parameterization of the
DNNTestNetwork perf tests (e.g. YuNet_320/640/1280) which crashed in getFLOPS.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 02:28:41 +03:00
Vadim Pisarevsky f968fb969f Broadcasting element-wise engine for cv::Mat (+ cv::texpr) (#29426)
* experimental new arithmetics; work-in-progress

* continue working on new-gen arithmetic expressions

* * improved performance of the new add on small arrays
* added sub
* extended tests

* fixed potential bug when adding multi-channel array and a single-channel scalar

* improved const handling

* * added copyMask
* added mul/dev (without scale so far)

* * accelerated mul
* addedd scale to mul and div

* * done substantial refactoring; however a few more rounds of refactoring are ahead.
* added min, max, absdiff, addweighted.

* improved performance of the new arithmetic functions, but some of them are still slow, e.g. operations with mask have some bugs (that affect speed, not accuracy).

* * further (significantly) accelerated several functions, especially on small arrays: mul, binary ops with mask

* further polished the new arithmetic engine

* started integration of the new element-wise arithmetic engine into core

* big step forward. We now use the new engine inside cv::add, subtract, multiply, divide, absdiff, min and max.

* big progress:
* added bitwise operations
* fixed and accelerated compare
* ported regression tests to test new broadcasting behaviour of arithmetic functions

* lot's of improvements in compare, divide, addWeighted!

* lot's of small and big performance improvements in the new arithmetics

* * some more optimizations; parsing texpr-expressions is now faster as well

* port new_arithm to Linux/x86: dispatch guards, scalar-Mat compat fallback, dnn shape-contract fixes

Core:
- arithm.simd.hpp: CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY guards (the file is included
  once per dispatched mode on x86), vx_load_expand instead of the 128-bit v_load_expand,
  VTraits::vlanes() instead of ::nlanes
- arithm.cpp/precomp.hpp: compat fallback for scalar-like Mat operands (1x1, 1xcn/cnx1,
  4x1 CV_64F - java/python tuples, operator-(Mat, Matx)): treated as a per-channel scalar
  ONLY when the shapes are not broadcast-compatible, so every valid numpy-style broadcast
  keeps its meaning and calls that would otherwise throw get the 4.x semantics

DNN (fallout of the stricter shape semantics, found by the new engine):
- dict.hpp: DictValue relied on fresh AutoBuffer having size()==fixed_size; allocate explicitly
- batch_norm: weights_/bias_ are 1-D [n] now; 0/1-D forward runs on exact-shape 1-D views
- net_impl2: extend the post-forward sanity check to non-temp outputs - a layer that
  reallocates its preallocated output tensor now fails loudly instead of silently
  detaching the result from the graph
- LSTM/LSTM2 batchwise (layout=1): getMemoryShapes now matches what forward() writes
  (ONNX: Y=(batch,seq,dirs,hid), Yh/Yc=(batch,dirs,hid)); forward assembles seq-major
  results in a local buffer and transposes INTO the preallocated outputs in place

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* u8/s8 multiply: exact integer SIMD path on non-FP16 builds (3-10x vs 5.x)

The unit-scale branch of vecBinaryKernel already supported a separate work-vector
type Wvec1 (used by the ARM f16 build and by u16/s16 everywhere), but on x86 the
u8/s8 same-type multiply still went through the f32 hub. Route it through
v_uint16/v_int16: products of 8-bit values fit exactly (255^2 < 2^16), the
saturating pack on store gives bit-exact results at half the vector traffic.

Also fix a latent kernel bug this exposed: the unit-scale branch stepped by
Wvec's lane count while loading/storing Wvec1 vectors. All previous Wvec1
instantiations had equal lane counts, but u8's v_uint16 has 2x the lanes of
v_float32 - the pairs overlapped (50% redundant work) and the tail backoff
could write VECSZ bytes past the row end. The branch now derives its step,
offsets and tail condition from Wvec1 itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* vecBinaryKernel: constexpr Op::useScalar instead of a runtime-only scale check

Every binary op functor now declares whether it consumes the scale scalar
(params[0]): true only for mul and the two div variants. Ops that ignore it
(add/sub/min/max/absdiff) take the fast 2-arg branch unconditionally - the
'scalar == 1' check used to fail for them (their params[0] is 0), sending them
through the preproc branch, and the condition now folds at compile time.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* restore cv::hal::mul8u as a wrapper over the element-wise engine

The symbol is still declared in core/hal/hal.hpp and called directly by external
code (the G-API fluid backend in opencv_contrib), but its implementation went
away with the old arithm kernels. Forward it to getMulFunc(CV_8U, CV_8U) - with
scale==1 it lands on the new exact integer SIMD path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* silence every new-arithm warning reported by CI (ARM64/Mac) and gcc 15

- arithm.cpp: bitwise_op_ocl and the actualScalarDepth/coerceTypes helpers are
  consumed only by the OpenCL paths - guard them with HAVE_OPENCL; haveScalar in
  cv::compare is read only inside CV_OCL_RUN - CV_UNUSED for OpenCL-less builds
- arithm_expr.hpp: declare getBitwiseFunc/getNotFunc/getAddWeightedFunc next to
  the other per-op entry points (-Wmissing-prototypes in arithm.dispatch.cpp)
- arithm.simd.hpp: define CV_SIMD_16F to 0 when FP16 SIMD is absent (-Wundef);
  {}-init the expandScalar staging buffers (-Wmaybe-uninitialized: they are
  fully written before use, but the compiler cannot prove it with runtime
  vector widths); rename the compare kernel's lambda parameter (-Wshadow)
- arithm_expr.cpp: rename the exec tile-lambda's hot-field locals that shadowed
  TExpr members and outer locals (-Wshadow)
- test_new_arithm_extensive.cpp: rename the name-generator lambdas' parameter
  shadowing the INSTANTIATE macro's own (-Wshadow), drop an unused variable

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* restore 4.x scalar semantics for the bindings' 4x1 CV_64F Scalar columns

The python/java bindings materialize numbers and tuples as a 2-D 4x1 CV_64F
Mat - or UMat, when the call carries UMat arguments. Three CI-reported python
failures came from those pseudo-scalars reaching the engine as arrays:

- absdiff(int_arr, 0): the (4,1) column is broadcast-COMPATIBLE with a 1-D
  array, so numpy semantics silently won - an outer-product f64 result instead
  of the int per-channel-scalar one;
- subtract(u8 4x8x4, (40,)): same, by the rows==4 coincidence;
- multiply(UMat, 2., dst=UMat): the scalar arrives as a UMAT, which the
  scalar detection did not recognize at all.

isScalarArg now treats the exact bindings shape - 2-D 4x1 CV_64F single-channel
Mat/UMat against a <=4-channel array - as a scalar UNCONDITIONALLY (a 1-D [4]
array has dims==1 and still broadcasts). One exception, decided in arithm_op:
when the partner is itself a tiny scalar-shaped array, both are honest data and
ride the broadcast (compare(Mat 4x1, Mat 1x1) - issue #8999 - stays elementwise).

Small-array discipline, this all runs per engine call: the probes read Mat/UMat
fields directly (rows == 4 alone rejects almost everything, no _InputArray
getter dispatch), and a UMAT scalar's 32 bytes are copied into a caller-stack
buffer - no heap, no getMat mapping. Measured: no latency change on 4x4/16x16
element-wise calls.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* cv::texpr: std::string_view -> const std::string& in the public API

string_view in an exported signature breaks some CUDA toolchain builds, and for
short expression strings the difference is immaterial (SSO, parsed once). The
parser internals keep string_view - the argument converts implicitly. Also drop
the now-unused <string_view> include from cvstd.hpp, so the header does not
reach every nvcc TU.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* compare boundary-rewrite: fixed 4-slot kind/bound arrays instead of AutoBuffers

A CONST operand is capped at 4 channels (addConst), so the per-channel
kind/bound staging needs no dynamic buffers - plain int[4]/double[4], with a
CV_Assert on the contract. This is also what gcc's -Wmaybe-uninitialized was
flagging (it could not see the AutoBuffer's inline storage get filled).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* element-wise engine: unary math kernels (sqrt/exp/log/sin/cos/tanh/erf/relu) + select

New dispatched pair math.simd.hpp / math.dispatch.cpp - the unary/ternary sibling
of arithm.simd.hpp:

- vecUnaryKernel: T -> T over f16/bf16/f32/f64 on top of the intrin_math
  primitives (v_exp/v_log/v_sin/v_cos/v_sqrt/v_erf/v_max). f32/f64 compute
  natively, f16/bf16 ride the f32 hub inside the kernel (vx_load_pair_as /
  v_store_pair_as) - no materialized casts. Continuity collapse + the halide
  right-edge backoff, suppressed in-place (it would re-apply Op to
  already-written values). tanh = (e^2x-1)/(e^2x+1) with the input clamped to
  +/-10 (f32) / +/-20 (f64) - unclamped saturation hits inf/inf = NaN. erf has
  no f64 SIMD primitive: std::erf per lane.
- selectKernel(mask, x, y): 1-byte mask expanded to lane width and tested
  against zero in the INTEGER domain (immune to DAZ/FTZ), branches of any
  depth by element size, broadcast branches supported.
- emitUnary: math over a float input is T -> T now (f16 in -> f16 out, native
  kernel when input and result depths match); integer inputs still compute in
  the float domain and land in f32.
- emitTernary/select: literal branches are typed via typedConstFrom (an
  OP_CAST of a depth-less flex const crashed); a non-1-byte mask is normalized
  by an explicit "mask != 0" compare, never a value cast.

texpr already parsed the function names - they now execute. Tests: per-depth
accuracy of all 8 ops against the double std:: reference, integer input,
in-place, select over 4 depths / const branch / float mask.

Perf vs the classic kernels (1920x1080 f32, 16 threads, AVX2): exp 3.7x,
log 2.6x, sqrt 5.7x faster; polarToCart expressed as (r*cos(a), r*sin(a)) 4.0x.
Accuracy improves too (max rel err vs f64 reference): exp 8.1e-8 vs 2.1e-7,
log 8.0e-8 vs 1.5e-7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* engine: OP_COPY_MASK folded into OP_SELECT; selectKernel moved to arithm.simd.hpp

copyMask(dst, mask, src) is select(mask, src, dst) - one masking primitive
instead of two. The compiler emits the masked-op tail as
addInsn(OP_SELECT, mask, r, out, out): the output slot rides as both arg2 and
the result, so unmasked elements are preserved by reading them back through
the b-branch. OP_COPY_MASK, copyMaskKernel and getCopyMaskFunc are gone.

selectKernel (moved from math.simd.hpp to arithm.simd.hpp) inherits every
copyMaskKernel optimization:
- the interleaved multichannel fast path (2..4 channels under a per-pixel
  mask: expand the mask once per VECSZ rows, v_store_interleave across lanes);
- the per-row scalar path with the row-skip when the selected source row IS
  dst (the "leave the output untouched" half of copyMask);
- plus the select-specific ones: branch broadcasts (stepx == 0) and the
  right-edge tail backoff under dst-aliases-a-branch - safe because re-running
  select over already-blended elements is idempotent; only dst == mask keeps
  the backoff off (the store would rewrite mask bytes before the re-read).

Masked-add perf is on par with the old copyMask (1280x720, 1 thread: 8UC3
204 -> 198 us, 32FC3 1395 -> 1344, 8UC1/32FC1 within noise). Full core suite
24117 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* engine: dedicated vectorized pow kernel (moved from arithm to math.simd.hpp)

pow was the last scalar-only binary op (scalarBinaryKernel + std::pow, f32/f64
only). The new powKernel keeps exact std::pow semantics and is T x T -> T over
all four float depths (f16/bf16 via the f32 hub):

- scalar exponent (the dominant call shape - texpr literals ride as 0-dim
  broadcast consts) is dispatched PER ROW to the special cases:
  y==2 -> x*x, y==3 -> x*x*x, y==0.5 -> v_sqrt, y==1 -> copy, y==0 -> fill 1;
- everything else - including a per-element exponent array - runs the general
  vectorized exp(y * log(x)) path, valid for x > 0; a vector pair containing
  any x <= 0 lane falls back to scalar std::pow for that pair (v_check_any),
  which preserves every std::pow subtlety: signed results for integer y on
  negative bases, NaN for fractional y, the x == 0 family;
- no right-edge tail backoff: pow is not idempotent, in-place calls finish
  rows in the scalar tail.

Perf vs the classic cv::pow (1920x1080 f32, 16 threads, AVX2): p=2 1.4x
(classic special-cases it too), p=3 6.1x, p=0.5 6.3x, fractional p 4.5x with
slightly better accuracy (6.1e-7 vs 7.4e-7 max rel err). Tests: exponent
sweep 2/3/0.5/1/0/2.5/-1.5 vs the double std::pow reference on f32/f64,
negative bases (exact signed cubes, NaN for fractional), array exponent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* powKernel: halide right-edge tail backoff in every SIMD loop

Same shape as vecBinaryKernel: the final partial vector re-processes
[width - VECSZ*2, width) instead of finishing scalar, suppressed when dst
aliases an input (pow is not idempotent - the overlap region must be
recomputed from an untouched source, which the no-alias case guarantees).

Modest measured win (~2% on ROI rows for the special-cased exponents; the
general path tail was already cheap - modern libm powf is fast), no
regressions; mainly aligns the kernel with the house style, where every
SIMD loop ends vector-wide.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix MSVC 2019 C2975: function-local constexpr as a template argument inside a lambda

MSVC 2019 loses the constexpr-ness of function-local constants (LOCAL_OPS,
MAX_DIMS, ...) when they are used as template arguments inside a lambda body
(AutoBuffer<Slice, LOCAL_OPS> / std::array<int, MAX_DIMS> in the parallel
bodies of BroadcastOp::run and TExpr::exec). Hoist them to namespace scope -
no behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ocl_arithm_op: route 16U multiply to the CPU engine on Apple OpenCL

The Apple OpenCL driver miscompiles the 16U multiply kernel: products near
the top of the u16 range come back wrapped instead of saturated (CPU vs GPU
NORM_INF up to 65535 in OCL_Arithm/Mul.Mat CV_16U cases). The same arithm.cl
kernel is correct on Intel NEO and NVIDIA drivers - verified not to reproduce
on Linux/Intel iGPU - so gate the decline to __APPLE__ only; the CPU engine
computes 16u multiply exactly (integer SIMD path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* engine: neg/abs as compositions, clamp kernel, ** and ?: operators, abs(a-b) peephole

- OP_NEG and OP_ABS need no kernels: neg = sub(0, a), abs = absdiff(a, 0) -
  including the engine absdiff auto-type rule (signed |a| lands in the
  UNSIGNED type of the same width: |SHRT_MIN| fits u16 exactly instead of
  saturating; NB the public cv::absdiff auto depth keeps the source type for
  4.x compatibility - values agree, the depth rule is the engine own).
- peephole: abs(x - y) rewrites to absdiff(x, y) ALWAYS. On integers the
  literal semantics differ (the subtract saturates first: u8 gives
  max(x-y, 0)), but whoever writes abs(a - b) means absdiff - we deliberately
  hand out the useful semantics instead of the saturation artifact. The just-
  emitted OP_SUB is retired via the moveToOutput manoeuvre, so the program
  shrinks to the single absdiff instruction. abs(x), abs(x - 0) and
  absdiff(x, 0) all give one result.
- OP_CLAMP kernel (arithm.simd.hpp): v_min(v_max(x, lo), hi) over
  u8/s8/u16/s16/u32/s32/f32 (+f64 with 64-bit SIMD), scalar f16/bf16/64-bit
  ints; lo/hi may broadcast (the common clamp(img, a, b) shape) or be full
  arrays; the tail backoff stays on under dst-aliases-x (clamp is idempotent).
  emitTernary types literal bounds via typedConstFrom (same flex-const crash
  select had) and keeps the auto result type pinned to x.
- parser: "a ** b" == pow(a, b), precedence above * /, RIGHT-associative
  (a ** 2 ** 3 == a ** 8); "cond ? a : b" == select(cond, a, b), precedence
  below everything, right-associative chains (f1 ? a : f2 ? b : c) work
  without parentheses. parseTernary() is the expression entry point now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* cv::exp/log/sqrt on the engine via math_op; hal functions wrapped as engine kernels

math_op is the master function of the unary math family (the arithm_op
analogue): same-shape same-type output over f16/bf16/f32/f64 (classic
exp/log accepted f32/f64 only - the half floats are new), two tiers:
- small (<= 100000 elements) and continuous: call the kernel DIRECTLY over
  the flattened data - no TExpr, no broadcastOp, no parallel_for setup;
- everything else: the usual single-instruction program via compile()/exec()
  (parallelism for large arrays, real steps for ROIs).

getMathFunc routes OP_EXP/OP_LOG at f32/f64 through the full cv::hal stack -
an external vendor HAL (CALL_HAL), IPP, or the built-in table kernels,
whichever is installed - by wrapping hal::exp32f/exp64f/log32f/log64f as
engine kernels with the function pointer in TKernel::userdata, the same
mechanism castKernel uses for core BinaryFuncs. The engine adds tiling and
parallelism on top, so every tier gets the best available scalar-span
implementation. v_exp/v_log remain for f16/bf16 (the f32 hub) and the ops
hal has no entry points for.

v_log_default_32f: the degree-8 polynomial is evaluated by Estrin pairing
(4 dependent levels) instead of an 8-FMA Horner chain (~5% on the f16 hub
path). An exp64 Taylor-without-division rewrite was tried and benched SLOWER
than the Cephes Pade scheme (the evaluation is FMA-throughput-bound, and
vdivpd pipelines well enough) - reverted; a table-based reduction is the only
way further there.

cv::exp f32 (16 threads, AVX2+IPP build), old -> new: 640 elements
0.16 -> 0.15 us, 16k 2.79 -> 2.49, 640x480 47 -> 20, 1920x1080 452 -> 60 us
(the old CPU loops were single-threaded); f64 exp 1080p 1295 -> 161 us.
No size regresses; small arrays now run at installed-HAL speed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* getMathFunc: IPP tier + raw-HAL probing; the exp/log table kernels are deleted

The raw cv_hal_* entry points return int for a reason: without an installed
HAL they are stubs returning CV_HAL_ERROR_NOT_IMPLEMENTED. getMathFunc now
selects the exp/log implementation in three tiers:
 1. HAVE_IPP && ipp::useIPP(): ippsExp/ippsLn through thin int adapters (IPP
    is not routed through the cv_hal_ hooks, so it needs its own tier);
 2. the raw cv_hal_exp32f/... hook, PROBED once with a 1-element call on the
    safe input 1.0 (cached in magic statics): implemented -> wrapped as an
    engine kernel with the function pointer in TKernel::userdata;
 3. the engine own v_exp/v_log kernels.
Whichever wins, the engine adds tiling and parallelism on top.

The EXPTAB/LOGTAB table kernels and their tables (~790 lines in
mathfuncs_core.simd.hpp + mathfuncs.cpp) are DELETED: they benched within
~15% of v_exp/v_log, not worth a second implementation. The public
cv::hal::exp32f/exp64f/log32f/log64f keep their contract - CALL_HAL, then
IPP, then the built-in implementation - but the built-in is now the engine
vector kernel via ew::mathSpanEngine (one contiguous span, exported from
math.dispatch.cpp).

All unary math kernels (vec/scalar/hal wrappers, pow) also handle the
vertical-broadcast tile (s0y == 0, a row expanded into a matrix): the first
row is computed, the rest are memcpy of it - transcendentals cost far more
than a row copy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* texpr: hypot(x, y) binary op (alias: mag)

hypot = sqrt(x^2 + y^2), NAIVE like cv::magnitude (not the overflow-safe
std::hypot), computed in the float work type; kernels for the four float
depths only (T x T -> T; integer inputs ride the usual f32-compute + cast).
A 10-line EwHypot functor on top of vecBinaryKernel in arithm.simd.hpp -
broadcast branches, continuity collapse and the tail backoff come for free.
Registered in the parser as both "hypot" (the C/numpy name) and "mag" (the
cv::magnitude-flavored alias). A building block for the future cartToPolar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* texpr: atan2(y, x) binary op - radians, standard C range

v_atan2 (arithm.simd.hpp, generic over the universal-intrinsic float vector):
the fastAtan2 minimax polynomial from mathfuncs_core v_atan_f32 reworked to
plain radians - the 180/pi factor dropped from the coefficients and the C
quadrant logic instead of the [0, 360) wrap, so the result matches std::atan2
over (-pi, pi]. Measured absolute accuracy ~1.6e-4 rad. (v_atan_f32 itself is
untouched - cv::phase/fastAtan2 keep their degree semantics.)

EwAtan2 rides vecBinaryKernel: f16/bf16/f32 through v_atan2 (the f32 hub),
f64 through exact scalar std::atan2. arg0 = y, arg1 = x, like std::atan2;
float depths only, same emitBinary policy as pow/hypot. Parser name "atan2".
Together with hypot this completes the cartToPolar building blocks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix the RISC-V RVV build and two ARM64 warnings

The new f64 kernel registrations (hypot, pow, the unary math family) gate on
CV_SIMD_64F || CV_SIMD_SCALABLE_64F, but the vx_setall_as(const double*,
v_float64&) helper family in arithm.simd.hpp was still CV_SIMD_64F-only -
scalable platforms (RVV) have v_float64 with CV_SIMD_64F == 0, so
vecBinaryKernel<double, ...> failed to instantiate there. Widen the helper
gate to match (verified with a riscv64 rv64gcv cross-build of opencv_core -
the engine f64 paths now vectorize on RVV instead of not compiling).

cv::exp/cv::log: the depth local is consumed by CV_OCL_RUN only - CV_UNUSED
for OpenCL-less builds (ARM64 -Wunused-variable).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* silence the remaining ARM64 gcc warnings

- compare boundary-rewrite: {}-init the fixed kind/bound arrays (filled for
  every channel used below, but gcc cannot prove it across the cn <= 4 loop);
- cv::exp/log: [[maybe_unused]] on the depth local (consumed by CV_OCL_RUN
  only), instead of the CV_UNUSED idiom;
- AutoBuffer::reserve: a targeted -Wmaybe-uninitialized suppression around
  the live-element copy loop - only [0, sz) is read, all written before, but
  gcc inlining a grow-from-inline-storage chain cannot see that. An
  annotation for the analyzer, no behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* saturating 32-bit add/sub kernels; cv::texpr python binding; two CI warnings

- v_add_sat/v_sub_sat for v_int32/v_uint32, local to arithm.simd.hpp for now
  (the plan is to grow them into proper universal intrinsics later): NEON
  single-instruction vqadd/vqsub, elsewhere the Hacker Delight bit tricks
  over universal intrinsics (u32 add is 2 ops: or with the wrapped-compare
  mask). EwAdd/EwSub overload vec() for the 32-bit lanes and getAddSubFunc
  routes 32S/32U T->T through vecBinaryKernel instead of the former pure
  scalar kernel. Semantics unchanged - the scalar int64 tail already
  saturated; directed boundary tests added (both rails, 0 - INT_MIN, u32
  cases, a full-range random block vs an exact int64 reference).
  640x480 32S add: 0.48x of 5.x -> parity (memory-bound); 1080p: 6-8x.

- cv::texpr becomes CV_EXPORTS_W: python gets cv.texpr(expr, [inputs]) ->
  tuple of ndarrays, so `res, = cv.texpr(...)` and `mag, ang = cv.texpr(...)`
  unpacking both work. modules/python/test/test_expr.py covers arithmetic,
  the fused abs(a-b), casts, broadcasting, ?: and ** operators, math
  functions vs numpy, clamp, named temporaries, tuple outputs, the one-line
  cartToPolar and the int32 saturation cases.

- warnings: {}-init the parser args array (gcc -Wmaybe-uninitialized on
  Ubuntu 20/22); the compare short-row block gates sizeof(T) <= 4 as
  constexpr so the f64 instantiation does not leave set-but-unused locals
  (gcc 9 -Wunused-but-set-variable).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* arithm_op: direct-kernel fast path for small continuous arrays

Building and compiling the 1-instruction program plus the BroadcastOp setup
costs ~40-250ns per call - negligible on big images, dominant at 127x61-class
sizes where the classic 5.x functions were 1.3-2x faster. Mirror math_op two
tiers in arithm_op: two same-type same-shape continuous arrays, no mask, no
scalar, result depth == input depth, <= 100k elements -> call the T x T -> T
kernel directly over the flattened elements (checks ordered cheapest-first).
Applies to add/subtract/min/max/absdiff/multiply/addWeighted/and/or/xor;
compare and divide lower to more than a single kernel (boundary rewrites, int
guards) and keep the ordinary path. addWeighted falls through automatically
for the 32/64-bit int types whose lowering is wide-compute + cast
(getElemwiseFunc returns no direct kernel there).

127x61 vs 5.x, was -> now: add/subtract 8UC1 0.76x -> 1.3x, min/max u8
0.6x -> ~1x, addWeighted 1.0x -> 1.1-1.4x (32SC1 stays 4.5x); the one
remaining laggard is add/sub 32SC1 (0.74-0.82x) - the price of the new
SATURATING semantics (7-instruction AVX2 emulation vs the wrapping single
add of 5.x; single-instruction on NEON).

The 127x61 size is ADDED PERMANENTLY to the arithmetic/addWeighted/compare
perf grids: per-call overhead regressions in these base functions must be
caught by CI, not discovered by users.

dst creation goes through createSameSize (whole-shape transfer including
layout and future metadata, not piecemeal dims+sizes) here and in math_op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* cv::pow rebuilt on the engine; integer-exponent and 1/sqrt(x) kernel branches

Routing: p = 0/1/2 keep their early special cases (fill/copy/multiply); an
INTEGER array with an INTEGER power keeps the classic iPow multiply chain -
bit-exact compatibility, including its wrap-around quirks (iPow squares in
int, so e.g. pow(255,4) on u8 wraps negative and saturates to 0 - somebody
may rely on that). Everything else goes through the engine with the math_op
two-tier scheme: small continuous arrays call powKernel directly (the
exponent rides as a broadcast T scalar), the rest run the tiled parallel
program. Integer arrays with fractional powers compute in the float domain
and saturate back; the 32U/64-bit depths (classic iPow asserted on them) and
f16/bf16 (the classic float path misread them) now just work.

powKernel gets two new per-row exponent branches:
- p == -0.5: 1/v_sqrt(x) (the classic path used IPP ippsInvSqrt_A21, a
  21-bit approximation; ours is exact - slightly slower on small arrays,
  4.5x faster at 1080p via parallelism);
- any other INTEGER p (|p| <= 65536): LSB-first binary exponentiation, the
  same multiply chain and order as iPow, fully vectorized - a few ulp
  accurate vs ~2e-7 of exp(p*log x), and exact on non-positive bases (the
  sign falls out of the multiplies, 0^negative divides to inf) - no scalar
  patching.

cv::pow f32 vs 5.x: p=0.5 365 -> 61 us at 1080p (6x), p=3 7.7x, p=5 7x AND
faster at every size (the old scalar chain: 0.81 -> 0.47 us at 127x61),
p=2.5 5.3x. The s16^5 iPow path is untouched (118.7 == 118.5 us).
pow_exponents accuracy tests extended to 11 exponents x f32/f64 against the
double std::pow reference.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* perf: SANITY_CHECK_NOTHING for the tests whose grids got the 127x61 size

The 127x61 entry added to guard per-call overhead has no regression data in
opencv_extra, so the legacy SANITY_CHECK in addWeighted/compare failed on CI
(locally it passes silently without the test-data path). Accuracy of both
functions is covered by the accuracy suite; the perf tests should measure
time. PatchNaNs/finiteMask keep their SANITY_CHECK - their grids are
untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix a temp-buffer double release in the liveness pass ("d*d" crash)

When the same temp is passed as SEVERAL arguments of its last-use
instruction (e.g. the named-intermediate expression "d = {0} - {1}; d*d",
where the MUL consumes slot d twice), the buffer-reuse scan pushed the
temp's physical buffer onto the free list once per argument. That
overflows the ntemps-sized freeBufs array (caught by the AutoBuffer range
check in Debug: python test_expr.py::test_named_temporary) and, in larger
programs, would hand the same physical buffer to two live temps.

Release the buffer once by retiring lastUse[t] after the first hit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* executor: recalibrate opCost to vectorized cycles + clamp the stripe count

The per-element op costs fed into the parallel_for_ stripe hint were
scalar-era estimates (~20x above the vectorized reality: the atan2/exp
polynomials run at ~1.5 cycles/element, not 30). The hint therefore split
transcendental/divide work into hundreds of ~1 us jobs, which the
macOS/GCD backend dispatches poorly under sustained load, on top of the
P/E-core equal-share straggler effect. Measured on M4 Max (12P+4E),
sustained medians @1920x1080 f32: texpr atan2 320 -> 133 us, cv::exp
280 -> 141 us, cv::log 301 -> ~200 us, cv::pow(x,2.5) 388 -> 376 us;
the PR tables' math rows improved ~1.5-2x across the board.

- opCost is now in units of ~1/4 cycle/element of the SIMD kernels:
  cheap ops 1 (unchanged), div/sqrt/hypot/convert_scale 10 -> 3,
  transcendentals 30 -> 6.
- the stripe hint is clamped by min(4*nthreads, max(32, 3*nthreads)):
  ~4 stripes/thread is plenty of granularity for element-wise work, and
  the ceiling is 32 pieces except on machines with many (heterogeneous)
  cores, where anything coarser than ~3 pieces/worker turns the slow
  cores into equal-share bottlenecks (measured: 32 stripes on 16 threads
  is the worst point of the curve - 193 us vs 137 us at 48 for atan2).
  getNumThreads() is clamped from below (WINRT/plugin backends may
  report 0).

Not addressed here (needs cross-machine data, M2/M3 Ultra): streaming
memory-bound ops saturate the M4 Max fabric at ~8 fat stripes and E-core
participation only adds contention - a cost model cannot express that;
candidate follow-up is a bytes-aware clamp or a GCD-backend-level fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* multiply: v_mul_sat integer kernels (full product clamped to the type)

v_mul_sat(V, V) -> V for u8/s8/u16/s16/u32/s32 - the full-precision
product clamped to the lane type, which is exactly cv::multiply's integer
semantics at scale == 1. Local to arithm.simd.hpp for now, next to
v_add_sat/v_sub_sat, to be promoted into proper universal intrinsics
later. NEON: widening vmull + saturating narrow (vqmovn); other backends:
the portable v_mul_expand + saturating v_pack composition for 8/16-bit
lanes. 32-bit lanes have no universal widening multiply (no v_mul_expand
for s32), so the 32-bit integer fast path is NEON-only for now and the
other backends keep the previous f64 work-vector kernels (which measure
well on x86 with IPP-free AVX2).

EwMul::vec() now routes the integer lane types through v_mul_sat, and
getMulFunc_ passes the NATIVE lane vector as the scale==1 fast-path type:
whole-register loads/stores, the widening happens inside the multiply.
Replaces both the half-register widening loads (u8/s8/u16/s16) and the
scalar-equivalent f64 path for 32S/32U on NEON.

M4 Max, 640x480 (the sizes where the old kernels lost to carotene):
8U 22.0 -> 13.6 us, 8S 15.0 -> 11.1, 16S 21.2 -> 17.4, 32S 84.8 -> 30.5
(parity with the classic path everywhere, 32S was 0.38x). 1920x1080:
8S 1.30x -> 1.78x, 16S 2.57x -> 2.98x, 32S 2.20x -> 4.02x vs 5.x.
Correctness: exhaustive 8-bit (all 65536 pairs per sign), directed
saturation corners for 16/32-bit (46341^2, INT_MIN*-1, 65536*65536, all
sign combinations) against an exact int64 reference.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* NEON: make v_cvt_f64(v_int32) exact (was via f32, losing bits > 2^24)

The NEON implementations of v_cvt_f64/v_cvt_f64_high for v_int32 did
s32 -> f32 -> f64 (vcvt_f32_s32 + vcvt_f64_f32), silently rounding any
|x| > 2^24. Every vectorized f64 work path with int32 inputs on AArch64
was affected: the engine's addWeighted/divide 32S kernels, convertTo
32S -> 64F, etc. Found via addWeighted 32SC1 on values ~1e9: max error
was 32 vs the exact double reference (the classic carotene path is worse
still - it computes in f32 end-to-end with f32-truncated weights, max
error 96 on the same data).

The exact sequence sxtl + scvtf (vmovl_s32 + vcvtq_f64_s64) is the same
2 instructions, so there is no cost. addWeighted 32SC1 on the engine now
matches the exact-double reference bit-for-bit and stays at parity/1.4x
vs the classic path (640x480/1920x1080).

Pre-existing upstream bug (same code in 4.x) - worth a standalone
backport with directed large-value tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* math_op: drop the temporary direct-IPP tier for exp/log

Upstream moved the IPP math wrappers into the hal/ipp HAL module (cv_hal_exp32f/
log32f & co now resolve to ipp_hal_* which honor cv::ipp::useIPP via
CV_HAL_CHECK_USE_IPP). The engine's single probeHalUnary(cv_hal_*) probe already
picks that up uniformly, so the stopgap #ifdef HAVE_IPP ippExp/ippLog tier and its
ipp::useIPP() branch in getMathFunc are now redundant - removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* arithm: restore cv::hal::and8u/or8u/xor8u/not8u as engine wrappers

These public CV_EXPORTS entry points (core/hal/hal.hpp) lost their definitions when
the bitwise ops moved to the element-wise engine, but they are still declared and called
by other modules (opencv_objdetect's aruco) and external code - the link broke with
undefined references to cv::hal::and8u/xor8u. Restore them as thin forwarders over the
engine's byte-wise bitwise kernels (getBitwiseFunc / getNotFunc), mirroring the existing
mul8u wrapper. CV_Assert guards the kernel lookup.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* blobdetector: guard empty contour when computing blob radius

The new AutoBuffer leaves its tail uninitialized for trivial types, which surfaced a
-Wmaybe-uninitialized in findBlobs where the median of per-point distances is read. Use a
std::vector, default the radius to 0, and compute the median only for a non-empty contour -
no unproven size invariant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 01:26:36 +03:00
Alexander Smorkalov 507c824cd8 Renamed model to prevent name conflict. 2026-07-15 15:58:50 +03:00
Abhishek Gola ae392712b1 onnx coverage 2026-07-15 17:26:50 +05:30
Alexander Smorkalov 647b32ac7c Merge pull request #29517 from Teddy-Yangjiale:rvv-k1-05-conv-mr1
dnn: add RVV fp32 microkernel for MR=1 (depthwise-remain) convolution
2026-07-14 16:06:10 +03:00
Teddy-Yangjiale 60825757e4 dnn: add RVV fp32 microkernel for MR=1 (depthwise-remain) convolution 2026-07-13 22:47:39 +08:00
Prasadayus 56ae1e603b replace Qualcomm yolov3.onnx with darknet-converted yolov3 2026-07-13 16:20:24 +05:30
Alexander Smorkalov bc647fe3ec Merge pull request #29484 from velonica0:dnn-rvv-winograd-vlen-fix
dnn: fix out-of-bounds access in RVV Winograd kernels when VLEN > 256
2026-07-10 11:02:30 +03:00
Vincent Rabaud cbd227741f Merge pull request #29453 from vrabaud:persistence
Replace "static inline" by "inline" in headers #29453

This fixes #29436

I also replaced CV_INLINE which can be removed in a later PR.

I can make a similar PR for 4.x if you want.

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
2026-07-10 10:52:42 +03:00
Abhishek Gola aa1b8a2a21 Merge pull request #29288 from abhishek-gola:doc_v3
Documentation fixes, Added How to use pre-built opencv doc #29288

closes: https://github.com/opencv/opencv/issues/29263

co-authored by: @kirtijindal14 @Akansha-977 
### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2026-07-09 17:31:43 +03:00
velonica0 c86d642d19 dnn: fix out-of-bounds access in RVV Winograd kernels when VLEN > 256 2026-07-09 02:37:34 -07:00
Alexander Smorkalov abb0115648 Merge branch 4.x 2026-07-09 12:17:24 +03:00
Alexander Smorkalov 4ce2389a62 Merge pull request #29425 from fkenmar:dnn_remove_caffe_leftovers
dnn: remove Caffe protobuf leftovers, fix builds with external protobuf
2026-07-07 12:52:37 +03:00
Scott d1264cc6ec Merge pull request #29457 from Scott-Nx:fix/objdetect-new-dnn-target
dnn: silence false-positive CPU target warning for New graph engine #29457

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

* [x] I agree to contribute to the project under Apache 2 License.
* [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
* [x] The PR is proposed to the proper branch (`5.x`)
* [ ] There is a reference to the original bug report and related work
  No existing OpenCV issue or pull request directly covers this warning. This PR is the original report and fix.
* [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
  Not applicable. This patch changes only diagnostic behavior for an existing CPU no-op path.
* [ ] The feature is well documented and sample code can be built with the project CMake
  Not applicable. This patch adds no feature or public API.

## Summary

Suppress a misleading warning emitted when OpenCV 5 New DNN graph engine receives its default CPU target request.

`FaceDetectorYN` and `FaceRecognizerSF` call:

```cpp
net.setPreferableTarget(DNN_TARGET_CPU);
```

after loading their networks.

When New graph engine is active, target switching is not supported. OpenCV therefore currently prints:

```text
Targets are not supported by the new graph engine for now
```

However, New graph engine already executes on CPU. The CPU request does not require a target change, is ignored, and inference continues through New graph engine.

The warning therefore suggests a failed configuration or fallback to Classic DNN even though neither occurs.

## Change

Treat `DNN_TARGET_CPU` as a silent no-op when generic New graph engine is active.

```text
New graph engine + CPU target
→ no target change needed
→ return unchanged
→ no warning

New graph engine + non-CPU target
→ target remains unsupported
→ preserve existing warning
→ return unchanged
```

## Behavior before

```text
New graph engine active
→ caller requests CPU
→ request is ignored
→ warning emitted
→ inference continues on New graph engine
```

## Behavior after

```text
New graph engine active
→ caller requests CPU
→ request is ignored
→ no warning
→ inference continues on New graph engine
```

## Unchanged behavior

* New graph engine selection is unchanged.
* Inference execution is unchanged.
* CPU remains the effective target for generic New graph engine.
* Classic DNN behavior is unchanged.
* ONNX Runtime handling is unchanged.
* Non-CPU targets continue to emit the existing warning.

## Motivation

The current diagnostic is a false positive for the default CPU request. It reports unsupported target selection even though CPU is already the active execution target and inference succeeds through New graph engine.

## Testing

* Built OpenCV locally.
* Ran relevant DNN tests.
* Verified New graph engine still loads and executes affected models.
* Verified CPU target requests no longer emit the misleading warning.
* Verified non-CPU target requests retain the existing unsupported-target warning.
2026-07-07 11:32:25 +03:00
Kenmar Francisco f7ad23157f dnn: remove Caffe protobuf leftovers, fix external protobuf builds
The Caffe importer removal (#28678) left behind the protoc-generated
opencv-caffe.pb.{cc,h} and caffe_io.{cpp,hpp}. The generated files can
only be compiled with an old libprotobuf and can no longer be
regenerated since opencv-caffe.proto was deleted, so any build with
PROTOBUF_UPDATE_FILES=ON or an external protobuf failed (#29291, #29419).

- Move the generic ReadProto* helpers, the only remaining consumers of
  caffe_io (used by the TensorFlow importer), to src/protobuf_io.{hpp,cpp};
  delete src/caffe and misc/caffe, and move glog_emulator.hpp to src/.
- Guard the protobuf version check so it also works with newer protobuf
  where GOOGLE_PROTOBUF_VERSION is not defined.
- Drop the unconditional opencv-onnx.pb.h include from cast2_layer.cpp,
  using the spec-fixed ONNX data type values instead, and update stale
  readNetFromONNX/readNetFromTensorflow stubs to the current signatures
  so WITH_PROTOBUF=OFF builds link again.
2026-07-06 14:38:46 -04:00
Alexander Smorkalov bb96382942 Skip some BERT tests on 32-bit platforms as they do not fit into 2gb ram. 2026-07-06 10:08:21 +03:00
Alexander Smorkalov db37d38eb4 Merge pull request #29424 from Teddy-Yangjiale:rvv-k1-03-conv2-int8-kernel
dnn: add RVV kernel for new-engine int8 convolution
2026-07-03 10:48:59 +03:00
Teddy-Yangjiale e39c6c6bcc dnn: add RVV kernel for new-engine int8 convolution 2026-07-02 07:16:59 +08:00
Teddy-Yangjiale dcae1f1dc1 dnn: add RISC-V RVV FP32 fastGemm micro-kernel and Pack-B support 2026-07-02 05:46:43 +08:00
Uwez Khan b4164a4bc4 bound einsum subscript index before reading input shape 2026-07-01 18:19:00 +05:30
Abhishek Gola c7b8fb28b6 Merge pull request #29333 from abhishek-gola:attention_layer_extension
Extended Attention layer support #29333

Implemented present/past KV support.

Merge with: https://github.com/opencv/opencv_extra/pull/1381

Co-authored by: @Akansha-977 

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2026-07-01 15:41:44 +03:00
Teddy-Yangjiale 5866bbd9ff Merge pull request #29411 from Teddy-Yangjiale:rvv-dnn-int8-conv
dnn: add Winograd F(6,3) RVV implementation for RISC-V (VLEN≥256) #29411

### Summary

Adds a RISC-V Vector (RVV) backend for the Winograd F(6,3) convolution path
in the DNN module, targeting VLEN≥256 processors (tested on SpacemiT K1,
rv64gcv).

### Background

The Winograd F(6,3) path was already gated on `useSIMD128 || useAVX ||
useAVX2 || useNEON` at runtime, and protected by the same set of compile-time
macros. RVV was simply missing from both guards, so it always fell through to
generic convolution even when the hardware supports it.

A second issue: `conv_winograd_f63` was registered with
`ocv_add_dispatched_file`, which skips ISA variants not present in the host
toolchain during cross-compilation. Changing to `ocv_add_dispatched_file_force_all`
forces the `.rvv.cpp` translation unit to be generated unconditionally, matching
how every other RVV-enabled kernel in the DNN module is registered.

### Implementation notes

**Atom width.** `vsetvlmax_e32m1()` returns 8 on VLEN=256, so `winoAtomF32=8`
is chosen, matching the AVX2 atom width. The `impl_accum_F32` and transform
functions are structured identically to the AVX2 path (4 output channels ×
6 input tiles per atom).

**Input/output transform.** AVX2 uses `_mm256_unpacklo/hi_ps` + `permute2f128`
for an in-register 8×8 transpose. RVV has no equivalent cross-lane shuffle at
this width without `vrgather`, which adds index-vector overhead for a
non-bottleneck step. Instead the 8×8 intermediate matrix is transposed
scalar-in-memory between the two `wino_bt8x8_rvv` / `wino_at8x6_rvv` passes.
This keeps the transform code simple and correct; the GEMM in `impl_accum_F32`
dominates runtime.

**VLEN guard.** `getWinofunc_F32` checks `vsetvlmax_e32m1() >= 8` at runtime
and returns an empty functor on narrower implementations, so the code is safe
on VLEN=128 targets without a separate code path.

### Testing

**Correctness:** `ConvolutionWinograd.Accuracy` passes on the K1 board (9 ms).

**Performance:** `opencv_perf_dnn`, SpacemiT K1 (rv64gcv, VLEN=256),
GCC 13, `-O2 -march=rv64gcv`. Reported times are per-iteration medians from
`[ PERFSTAT ]` output (`--perf_min_samples=5`). "Generic" is the same build
with Winograd disabled via `OPENCV_DNN_DISABLE_WINOGRAD=1`.

| Input → Output C         | Winograd (ms) | Generic (ms) | Speedup |
|--------------------------|--------------|-------------|---------|
| {1,128,52,52} → 256     | 35.97        | 62.86       | 1.75×   |
| {1,512,13,13} → 1024    | 65.18        | 112.50      | 1.73×   |
| {1,256,75,75} → 256     | 159.75       | 271.65      | 1.70×   |
| {1,64,300,300} → 64     | 174.21       | 295.32      | 1.69×   |
| {1,1152,16,16} → 1152   | 176.12       | 245.33      | 1.39×   |

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
2026-07-01 14:33:46 +03:00
Saravana Balaji Mohan Balaji e2f0876777 Merge pull request #29217 from MBSaravanaBalaji:feat/onnx-lppool
dnn: implement LpPool ONNX operator #29217

## Summary

Implements the `LpPool` ONNX operator (opset 1–18), which was previously unregistered and caused a parse failure. `LpPool` computes the Lp-norm pooling: `(sum(|x|^p))^(1/p)` over a sliding window.

## Changes

- New `LpPoolLayer` in `modules/dnn/src/layers/lppool_layer.cpp`
  - Supports `kernel_shape`, `strides`, `dilations`, `pads`, `auto_pad` (NOTSET/SAME_UPPER), `ceil_mode`, and `p` (default 2)
  - SIMD fast paths for p=1 (abs + accumulate) and p=2 (square + accumulate + sqrt); scalar fallback for other values of p
- Registered `LpPool` dispatch entry in both `onnx_importer.cpp` (classic engine) and `onnx_importer2.cpp` (new graph engine)
- Added `LpPoolLayer` declaration to `modules/dnn/include/opencv2/dnn/all_layers.hpp`
- Registered layer class in `modules/dnn/src/init.cpp`
- Re-enabled 8 lppool conformance tests in `test_onnx_conformance.cpp` (previously in parser denylist)
- `test_lppool_2d_same_lower` added to the global conformance denylist — same known SAME_LOWER padding bug that affects `averagepool` and `maxpool`

## Testing

All applicable ONNX conformance tests pass:

| Test | Result |
|------|--------|
| test_lppool_1d_default | PASSED |
| test_lppool_2d_default | PASSED |
| test_lppool_2d_dilations | PASSED |
| test_lppool_2d_pads | PASSED |
| test_lppool_2d_same_lower | SKIPPED (known SAME_LOWER padding bug, consistent with avgpool/maxpool) |
| test_lppool_2d_same_upper | PASSED |
| test_lppool_2d_strides | PASSED |
| test_lppool_3d_default | PASSED |

Tested on: macOS (x86_64/SSE4, Rosetta 2) and Linux x86_64 (AVX2/AVX-512, GCC 13.3.0), Release build
OpenCV version: 5.0.0-pre

## Related Issues

None

---

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
2026-07-01 13:27:55 +03:00
Alexander Smorkalov d36133b325 Merge pull request #29403 from Teddy-Yangjiale:rvv-dnn-conv-rvv
dnn: add RISC-V RVV fp32 microkernel for classic ConvolutionLayer
2026-06-30 14:19:32 +03:00
Alexander Smorkalov 5b83b0c440 Merge pull request #29405 from Teddy-Yangjiale:rvv-dnn-conv-4x
dnn: add RVV LMUL=1 kernel for convBlock_F32 (ConvolutionLayer, rv64gcv)
2026-06-29 18:08:55 +03:00
Teddy-Yangjiale c831290769 dnn: add RVV LMUL=1 kernel for convBlock_F32 (ConvolutionLayer, rv64gcv) 2026-06-29 00:47:44 +08:00
Alexander Smorkalov edd89cfca5 Merge pull request #29371 from uwezkhan:tflite-pad-resize-bounds
check parameter tensor length in tflite parsePadding and parseResize
2026-06-28 14:19:17 +03:00
Teddy-Yangjiale cb0b3d820b dnn: add RISC-V RVV fp32 microkernel for classic ConvolutionLayer 2026-06-28 05:44:31 +08:00
Tonu Samuel 4d839a16f0 dnn: SIMD for 13 transcendental activations in the 5.x engine
Port of #29377 to 5.x. Wires Log, Erf, Exp, Sin, Cos, Sinh, Cosh, Tan,
Softplus, BNLL, Asinh, Acosh, Atanh into the dispatched activation_kernels
registry, plus a Layer_Activation perf test. 1.4-12.3x across
M4/A76/Threadripper/Xeon, correct to <=5e-7 vs scalar.
2026-06-27 09:11:09 +03:00
uwezkhan 69d2303531 Merge pull request #29345 from uwezkhan:onnx-tile-bounds
bound tile axis and repeats length in onnx parseTile #29345

OpenCV Extra: https://github.com/opencv/opencv_extra/pull/1385

parseTile sizes repeats_vec from the input-0 rank, then fills it from fields of the model that are never checked against that size. In the tile-1 path the axis taken from the third input indexes repeats_vec directly, and in the tile>1 path the loop writes one entry per element of the repeats tensor. A crafted ONNX with an out-of-range axis, or a repeats tensor longer than the input rank, writes past repeats_vec while loading the model through readNetFromONNX.

The fix runs axis through normalize_axis, the same helper the squeeze and concat paths in this file already use, so a negative or oversized axis is rejected before the write, and it checks the repeats length equals the input rank before the loop. Keeping both bounds in the parser puts the check next to the write instead of trusting the model to be well formed. Before, a repeats tensor shorter than the rank was silently accepted; after, it is rejected, which matches the ONNX rule that repeats carries one entry per input dimension.

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
- [ ] The feature is well documented and sample code can be built with the project CMake
2026-06-26 12:39:04 +03:00
Tõnu Samuel b64a215e71 Merge pull request #29377 from tonuonu:perf-dnn-activation-simd
dnn: SIMD for transcendental activation layers (15 functors) 🧑‍💻🤖 #2937

# dnn: SIMD for transcendental activation layers (15 functors) 🧑‍💻🤖

### Summary

Many `BaseDefaultFunctor`-based activation functors fall back to the scalar `BaseDefaultFunctor::apply`
— one `libm` call per element. This PR adds vectorized `apply()` overrides (universal intrinsics,
matching the existing `MishFunctor`/`GeluFunctor`/`SigmoidFunctor` pattern, each with a scalar tail) to
the **15 transcendental activations** that have a clean SIMD path:

| functor | uses | | functor | uses |
|---|---|---|---|---|
| TanH | `v_exp` (1−2/(e²ˣ+1)) | | Asinh | `v_log`,`v_sqrt` (sign·log(\|x\|+√(x²+1))) |
| Log | `v_log` | | Acosh | `v_log`,`v_sqrt` |
| Erf | `v_erf` | | Atanh | `v_log` |
| Exp | `v_exp` | | Softplus | `v_exp`,`v_log` |
| Sin | `v_sin` | | BNLL | `v_exp`,`v_log` (max(x,0)+log1p(e^−\|x\|)) |
| Cos | `v_cos` | | GeluApproximation | `v_exp` (tanh) |
| Tan | `v_sin`/`v_cos` | | Sinh / Cosh | `v_exp` |

Functors compile at the baseline SIMD width (SSE on x86, NEON on ARM — same as the existing SIMD
functors). `Sqrt`/`Floor`/`Ceil`/`Round`/`Abs`/etc. are intentionally **not** included — those are
single cheap ops the compiler already auto-vectorizes (measured `Sqrt` at 0.95×). `Asin`/`Acos`/`Atan`
are omitted (no `v_atan`/`v_asin`/`v_acos` intrinsic).

### Performance

Real `opencv_perf_dnn` `Layer_Activation` (added here), 8×256×128×100 = 26.2 M-elem CV_32F blob, A/B
vs the scalar fallback, median speedup:

| functor | M4 clang/NEON | A76 gcc/NEON | Threadripper gcc | Xeon W-2235 gcc | functor | M4 | A76 | TR | Xeon |
|---|---|---|---|---|---|---|---|---|---|
| TanH | 9.1× | 2.3× | 7.3× | 7.3× | Sinh | 3.3× | 3.2× | 5.2× | 5.0× |
| Cos | 8.8× | 3.0× | 3.3× | 3.0× | Acosh | 3.2× | 2.9× | 2.7× | 2.6× |
| Log | 7.8× | 3.0× | 2.5× | 2.4× | Cosh | 2.8× | 3.2× | 2.6× | 2.5× |
| Sin | 7.8× | 3.0× | 3.4× | 2.9× | Exp | 2.4× | 2.5× | 1.4× | 1.5× |
| GeluApprox | 7.6× | 2.4× | 6.6× | 5.8× | BNLL | 4.2× | 2.0× | 1.6× | 1.4× |
| Atanh | 7.0× | 3.6× | 6.0× | 5.2× | Softplus | 2.0× | 2.0× | 3.3× | 2.7× |
| Tan | 6.8× | 3.6× | 6.6× | 6.0× | Erf | 4.2× | 2.4× | 3.9× | 3.5× |
| Asinh | 3.9× | 2.4× | 5.8× | 5.7× | | | | | |

Every functor is a win on every tested out-of-order core (worst case 1.4×). On the **in-order
Cortex-A55** (a55-tuned build) all 15 measure 0.985–0.99× — neutral, within noise: the SIMD
polynomials are dependency-chain-bound, which an in-order pipeline can neither accelerate nor (here)
slow down. So: meaningful wins on out-of-order ARM + x86, no regression on in-order ARM.

### Accuracy

Uses the `v_exp`/`v_log`/`v_erf`/`v_sin`/`v_cos` polynomials OpenCV already ships and relies on (Gelu
via `v_erf`, Mish/Sigmoid via `v_exp`). Verified vs scalar `libm` on 320 K random elements per functor
with domain-correct inputs (Acosh x≥1, Atanh |x|<1, …): **max abs error ≤ 3e-5** (most ≤ 2e-6), zero
elements exceeding rel>1e-3 & abs>1e-4. ONNX conformance and the layer accuracy tests exercise these ops.

### Pull Request Readiness Checklist

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch (4.x)
- [ ] There is a reference to the original bug report and related work — N/A (perf improvement)
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable — perf test added (`Layer_Activation`, `SANITY_CHECK_NOTHING`); accuracy covered by existing ONNX conformance/layer tests
- [ ] The feature is well documented and sample code can be built with the project CMake — N/A (internal optimization, no new API)
2026-06-26 11:06:53 +03:00
uwezkhan 8b06f28e1b Merge pull request #29370 from uwezkhan:onnx-tensor-payload-size-5.x
Validate onnx tensor payload size in getMatFromTensor (5.x) #29370

5.x port of #29314. The DNN ONNX importer diverged here, so the change is ported manually.

`getMatFromTensor()` sizes the output blob from `TensorProto.dims` and then reads that many elements out of the tensor payload, but the payload is sized independently in the model and never checked against the shape. In 5.x the payload reaches the read through three sources: a typed `*_data` field, `raw_data`, or external-file data routed through `getTensorRAWData()`. An initializer whose dims claim more elements than the payload holds makes the `Mat` copy/convert read past the buffer.

### Before
A FLOAT tensor declaring `[1000000]` backed by a 4-byte `raw_data` reads about 4 MB out of bounds (ASan flags a heap over-read in `cv::Mat::copyTo`). The same mismatch is present in every datatype branch and for both the typed-field and `rawdata` sources, reachable from `readNetFromONNX`/`readNetFromONNXBuffer` for every initializer.

### After
Compute the element count the shape implies once, then check each payload source holds at least that many elements before the read. `getTensorRAWData()` now reports the byte count it returns (covering both `raw_data` and external-file data), and `getMatFromTensor()` validates the typed fields and the raw byte count per datatype. A short payload throws a clear `cv::Exception` instead of over-reading.

### Tradeoffs
The check lives in `getMatFromTensor` because that is the one place the shape and the payload meet, so every initializer and attribute tensor is covered without each caller repeating it. The added cost is one multiply-accumulate over the dims plus a comparison per tensor at load time; well-formed models, where the payload already matches the shape, are unaffected. The element-count accumulation saturates on overflow so an oversized shape can't wrap to a small total and slip past the check.

### Pull Request Readiness Checklist

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
- [ ] The feature is well documented and sample code can be built with the project CMake
2026-06-25 16:05:22 +03:00
Savya Sanchi Sharma 5d121b768f Merge pull request #29386 from SavyaSanchi-Sharma:test_debug
fixed Dynamic quantized linear layer error #29386

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2026-06-25 15:44:02 +03:00
Uwez Khan 6678e48c12 check parameter tensor length in tflite parsePadding and parseResize
guard the parsePadding NHWC swap on paddings.total()==8 and require the parseResize size tensor to hold height and width, matching the existing parseStridedSlice check
2026-06-23 16:46:41 +05:30
Alexander Smorkalov 2adeab8504 Merge pull request #29314 from uwezkhan:onnx-tensor-payload-size
validate onnx tensor payload size in getMatFromTensor
2026-06-23 13:18:24 +03:00
velonica0 c02b096a77 Merge pull request #29357 from velonica0:dnn_conv_rvv
dnn: vectorize fp32 convolution on RISC-V RVV #29357

### Summary

Vectorizes the new DNN engine's fp32 convolution on RISC-V **RVV**. Convolution was the last major block-layout operator still running scalar on RVV; this brings it to parity with the already-vectorized depthwise/pool/batchnorm path.

Single file, **purely additive** (`#elif CV_SIMD_SCALABLE` branches only) — x86/AVX2, ARM/NEON and AArch64 codegen are unchanged.

### Background

- **#28585** introduced block-layout conv with fp32 kernels specialized for AVX2 (`C0=8`) and NEON, scalar `#else` for everything else, and explicitly noted *"we could add the respective kernels later."*
- On RVV that `#else` meant conv ran **scalar at every VLEN** — the C0=8 fixed width approach doesn't transfer to a variable-VLEN ISA.
- **#29304** made the block size track the hardware width (`C0 = vlanes()`), fixing the VLEN≥256 assertion but leaving conv scalar.
- **This PR** supplies the deferred RVV conv vectorization, on top of that `C0=vlanes()` foundation.

### Approach

- Re-enable the `SPAT_BLOCK_SIZE=10` **blocked path** on RVV. Because `K0 == vlanes()`, one `v_float32` accumulator covers a full output-channel block, so 10 accumulators process 10 output positions together. A single K0-wide weight `vx_load` is reused across all 10 — amortizing the per-output-point load that bottlenecks the scalar path (this is what enables multi-core scaling; the scalar/per-FMA-load path is bandwidth-bound).
- Vectorize the **scalar tail** (the `<10`-position remainder) the same way.
- **Vector-length-agnostic:** `C0` is runtime, the kernel is written in terms of `v_float32`/`vlanes()`, so the same binary runs at full width on VLEN 128/256/512/1024 with no recompile. No per-VLEN kernels.
- The six `C0=8` specialized kernels stay `#if !CV_SIMD_SCALABLE`-gated (they can't run at `C0=vlanes()`); on RVV all shapes use the generic kernel.

### Performance

Convolution throughput, blocked (this PR) vs scalar, same machine/engine (VLEN=256, 8× rv64 @ 2.4 GHz), GFLOP/s:

| layer | scalar 1T | this 1T | scalar 8T | this 8T | 8T speedup |
|---|---|---|---|---|---|
| 3×3, 256→256, 64² | 1.13 | 13.23 | 8.28 | 75.62 | **9.1×** |
| 1×1, 256→256, 64² | 1.08 | 11.73 | 8.02 | 71.70 | 8.9× |
| 3×3, 128→128, 128² | 1.10 | 13.02 | 8.45 | 89.14 | **10.6×** |

≈ **12× single-thread, 9–11× at 8 threads**. Convolution dominates CNN inference time, so this is a large end-to-end win on RVV hardware.

### Validation

K3-class RVV board, VLEN=256: `Test_ONNX_layers` **264/264**, `Test_ONNX_conformance` **1641/1641**, **0 assertions**. Output is bit-identical to the scalar path (same accumulation order, just vectorized over `K0`).
Vector-length-agnosticism confirmed by running the VLEN=256 binary unchanged at **VLEN=1024**.


### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2026-06-23 12:37:27 +03:00
Pratham Kumar df0c9d7950 Merge pull request #29316 from pratham-mcw:dnn-arm64-neon-blobfromimages
dnn: optimize blobFromImages using NEON intrinsics on ARM64 #29316

- This PR optimizes the HWC-to-NCHW conversion in blobFromImages() by adding NEON implementation.
- On x64, the MSVC compiler automatically vectorizes the existing scalar implementation, resulting in significantly better performance.
- On Windows ARM64, MSVC does not auto-vectorize this stride-3 access pattern, leading to a noticeable performance gap compared to x64.
- Added CV_NEON macro guard to ensure SIMD optimization is enabled on ARM64 architecture, leaving behavior on other platforms completely unchanged.

**Performance Improvements**

- This optimization significantly improves the performance of HWC-to-NCHW conversion on Windows ARM64.

<img width="823" height="254" alt="image" src="https://github.com/user-attachments/assets/84b22deb-22da-4607-8009-3405c2529b80" />

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [X] The PR is proposed to the proper branch
2026-06-23 09:25:30 +03:00
Abhishek Gola 81621ced10 Merge pull request #29323 from abhishek-gola:split_layer_extension
Extended support for Resize and Split layers #29323

Merge with: https://github.com/opencv/opencv_extra/pull/1379

Key changes: 

Resize layer: 
_antialias_ (linear & cubic) :- PIL-style separable resampling with stretched filter support and edge-clamped, renormalized weights.
_axes_ (incl. reversed [3,2]) :- getOutShape, the scale override, and runtime _tf_crop_and_resize_ ROI parsing now map 2-element sizes/scales/roi by the axes order instead of assuming [2,3].
_keep_aspect_ratio_policy_ (not_larger/not_smaller) :- output size from min/max per-axis scale.
_half_pixel_symmetric_ :- new coordinate-transform mode + importer mapping.
_align_corners_ downsampling :- coordinate scale uses the unfloored scaled length (in−1)/(in·x_scale−1).

Split Layer:
_convertTo empty 1-D Mat:_ the empty-Mat branch collapsed a 1-D [0] to 2-D [1,0] via cv::Size(); now uses allowTransposed like the non-empty path.
### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2026-06-23 09:23:19 +03:00