nareshmlx/opencv-pr huggingface dataset:
**File:** modules/dnn/src/model.cpp
**Change Type:** modified
**Context:** PR #17570: [GSoC] High Level API and Samples for Scene Text Detection and Recognition
**Review Line:** 816

**Code Changes:**
```diff
+    float getConfidenceThreshold() const { return confThreshold; }
+
+    void setNMSThreshold(float nmsThreshold_) { nmsThreshold = nmsThreshold_; }
+    float getNMSThreshold() const { return nmsThreshold; }
+
+    // TODO: According to article EAST supports quadrangles output: https://arxiv.org/pdf/1704.03155.pdf
+#if 0
+    virtual
+    std::vector< std::vector<Point2f> > detect(InputArray frame, CV_OUT std::vector<float>& confidences) CV_OVERRIDE
+#endif
+
```

Review comment:
You can find that the performance of QUAD is worse than RBOX in Table. 3 and the authors do not provide official code and models. Some good re-implementations of EAST only support RBOX. TF: https://github.com/argman/EAST PyTorch: https://github.com/songdejia/EAST
**File:** doc/tutorials/dnn/dnn_text_spotting/dnn_text_spotting.markdown
**Change Type:** added
**Context:** PR #17570: [GSoC] High Level API and Samples for Scene Text Detection and Recognition
**Review Line:** 291

**Code Changes:**
```diff
+
+#### Test with an image
+Examples:
+```bash
+example_dnn_scene_text_recognition -mp=path/to/crnn_cs.onnx -i=path/to/an/image -rgb=1 -vp=/path/to/alphabet_94.txt
+example_dnn_scene_text_detection -mp=path/to/DB_TD500_resnet50.onnx -i=path/to/an/image -ih=736 -iw=736
+example_dnn_scene_text_spotting -dmp=path/to/DB_IC15_resnet50.onnx -rmp=path/to/crnn_cs.onnx -i=path/to/an/image -iw=1280 -ih=736 -rgb=1 -vp=/path/to/alphabet_94.txt
+example_dnn_text_detection -dmp=path/to/EAST.pb -rmp=path/to/crnn_cs.onnx -i=path/to/an/image -rgb=1 -vp=path/to/alphabet_94.txt
+```
+
+#### Test on public datasets
```

Review comment:
Is there a tutorial on training custom models and converting existing models to onnx?
**File:** modules/core/include/opencv2/core/hal/intrin_rvv.hpp
**Change Type:** modified
**Context:** PR #21012: Update RVV backend for using Clang.

**Code Changes:**
```diff
@@ -19,6 +19,8 @@ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
 #define CV_SIMD128_64F 1
 
 //////////// Unsupported native intrinsics in C++ ////////////
+// The following types have been defined in clang, but not in GCC yet.
+#ifndef __clang__
 
 struct vuint8mf2_t
 {
@@ -224,6 +226,7 @@ inline vint16mf2_t vwcvt_x_x_v_i16mf2 (vint8mf4_t src, size_t vl)
```

Review comment:
width1, width2, vl1, vl2 are not used any more. I propose to simplify the macro and it's usage.
**File:** modules/core/include/opencv2/core/hal/intrin_rvv.hpp
**Change Type:** modified
**Context:** PR #21012: Update RVV backend for using Clang.
**Review Line:** 1699

**Code Changes:**
```diff
 OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int32x4, v_uint32x4, vuint64m2_t, vwsub_vv_i64m2, vnclipu_wx_u32m1, 4)
+#else
+#define OPENCV_HAL_IMPL_RVV_ABSDIFF_S(_Tpvec, _rTpvec, _nwTpvec, sub, rshr, width, vl) \
+inline _rTpvec v_absdiff(const _Tpvec& a, const _Tpvec& b) \
+{ \
+    return _rTpvec(rshr(vreinterpret_u##width##m2(sub(v_max(a, b), v_min(a, b), vl)), 0, vl)); \
+}
 
+OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int8x16, v_uint8x16, vuint16m2_t, vwsub_vv_i16m2, vnclipu_wx_u8m1, 16, 16)
+OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int16x8, v_uint16x8, vuint32m2_t, vwsub_vv_i32m2, vnclipu_wx_u16m1, 32, 8)
+OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int32x4, v_uint32x4, vuint64m2_t, vwsub_vv_i64m2, vnclipu_wx_u32m1, 64, 4)
```

Review comment:
I propose to apply bit-wise and with mask 011....1b for sub result. It drops negative sign, if any. With this approach we get 2 operations (sub, bitwise and) instead of 3 operations (min, max, sub).
**File:** modules/core/include/opencv2/core/hal/intrin_rvv.hpp
**Change Type:** modified
**Context:** PR #21012: Update RVV backend for using Clang.
**Review Line:** 667

**Code Changes:**
```diff
+    return v_float32x4(vreinterpret_v_u32m1_f32m1(vreinterpret_v_u64m1_u32m1(vreinterpret_v_f64m1_u64m1(v))));\
+} \
+inline v_float64x2 v_reinterpret_as_f64(const v_float32x4& v) \
+{ \
+    return v_float64x2(vreinterpret_v_u64m1_f64m1(vreinterpret_v_u32m1_u64m1(vreinterpret_v_f32m1_u32m1(v))));\
+}
 
 ////////////// Extract //////////////
 
@@ -686,7 +710,7 @@ OPENCV_HAL_IMPL_RVV_EXTRACT_FP(v_float64x2, double, f64, vfmv_f_s_f64m1_f64, 2)
 #define OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(_Tpvec, _nTpvec, _Tp, hvl, vl, width, suffix, vmv) \
```

Review comment:
Sounds very suspicious. I think `vfncvt` call fits better.
**File:** modules/core/include/opencv2/core/hal/intrin_rvv.hpp
**Change Type:** modified
**Context:** PR #21012: Update RVV backend for using Clang.

**Code Changes:**
```diff
@@ -19,6 +19,8 @@ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
 #define CV_SIMD128_64F 1
 
 //////////// Unsupported native intrinsics in C++ ////////////
+// The following types have been defined in clang, but not in GCC yet.
+#ifndef __clang__
 
 struct vuint8mf2_t
 {
@@ -224,6 +226,7 @@ inline vint16mf2_t vwcvt_x_x_v_i16mf2 (vint8mf4_t src, size_t vl)
```

Review comment:
Agree. `_Tp1`, `_Tpvec2`, `_Tp2`, `_nTpvec1`, `width1`, `width2`, `vl1`, `vl2` in NATIVE_REINTERPRET and `_Tp1`, `_Tpvec2`, `_Tp2`, `_nTpvec1`, `vl1`, `vl2` in TWO_TIMES_REINTERPRET are not used. Removed.
**File:** modules/core/include/opencv2/core/hal/intrin_rvv.hpp
**Change Type:** modified
**Context:** PR #21012: Update RVV backend for using Clang.
**Review Line:** 667

**Code Changes:**
```diff
+    return v_float32x4(vreinterpret_v_u32m1_f32m1(vreinterpret_v_u64m1_u32m1(vreinterpret_v_f64m1_u64m1(v))));\
+} \
+inline v_float64x2 v_reinterpret_as_f64(const v_float32x4& v) \
+{ \
+    return v_float64x2(vreinterpret_v_u64m1_f64m1(vreinterpret_v_u32m1_u64m1(vreinterpret_v_f32m1_u32m1(v))));\
+}
 
 ////////////// Extract //////////////
 
@@ -686,7 +710,7 @@ OPENCV_HAL_IMPL_RVV_EXTRACT_FP(v_float64x2, double, f64, vfmv_f_s_f64m1_f64, 2)
 #define OPENCV_HAL_IMPL_RVV_LOADSTORE_OP(_Tpvec, _nTpvec, _Tp, hvl, vl, width, suffix, vmv) \
```

Review comment:
I think `vfncvt` is more like type conversion but not reinterpret and can not use in here. For example: When `v_float32x4 v_reinterpret_as_f32(const v_float64x2& v)` is called. We want to treat the 128bits(64 bit * 2) in the register as (32bits *4). However, `vfloat32m1_t vfncvt_f_f_w_f32m1 (vfloat64m2_t src, size_t vl);` means there are four float64 is converting to four float32.
**File:** modules/core/include/opencv2/core/hal/intrin_rvv.hpp
**Change Type:** modified
**Context:** PR #21012: Update RVV backend for using Clang.
**Review Line:** 1699

**Code Changes:**
```diff
 OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int32x4, v_uint32x4, vuint64m2_t, vwsub_vv_i64m2, vnclipu_wx_u32m1, 4)
+#else
+#define OPENCV_HAL_IMPL_RVV_ABSDIFF_S(_Tpvec, _rTpvec, _nwTpvec, sub, rshr, width, vl) \
+inline _rTpvec v_absdiff(const _Tpvec& a, const _Tpvec& b) \
+{ \
+    return _rTpvec(rshr(vreinterpret_u##width##m2(sub(v_max(a, b), v_min(a, b), vl)), 0, vl)); \
+}
 
+OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int8x16, v_uint8x16, vuint16m2_t, vwsub_vv_i16m2, vnclipu_wx_u8m1, 16, 16)
+OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int16x8, v_uint16x8, vuint32m2_t, vwsub_vv_i32m2, vnclipu_wx_u16m1, 32, 8)
+OPENCV_HAL_IMPL_RVV_ABSDIFF_S(v_int32x4, v_uint32x4, vuint64m2_t, vwsub_vv_i64m2, vnclipu_wx_u32m1, 64, 4)
```

Review comment:
> It drops negative sign, if any. Agree. But I think register saves data in the form of two's Complemented. So for negative numbers, setting the sign position to zero by bit-wise and with the mask is not work.
**File:** modules/dnn/src/cuda/functors.hpp
**Change Type:** modified
**Context:** PR #21176: Add acos, acosh, asin, asinh, atan, atanh, cos, cosh, erf, hardswish, sin, sinh, softplus, softsign, tan layers

**Code Changes:**
```diff
@@ -303,6 +303,231 @@ struct NotFunctor {
     }
 };
 
+template <class T>
+struct AcosFunctor {
+    struct Params {
+        CUDA4DNN_HOST_DEVICE Params() { }
+    };
+
```

Review comment:
``` using csl::device::log1pexp; return log1pexp(value); ```
**File:** cmake/OpenCVFindLibsGUI.cmake
**Change Type:** modified
**Context:** PR #20183: improve compatibility for qt 6.

**Code Changes:**
```diff
@@ -11,25 +11,50 @@ if(WITH_WIN32UI)
     CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32")
 endif()
 
+macro(ocv_find_package_Qt4)
+  find_package(Qt4 COMPONENTS QtCore QtGui QtTest ${ARGN})
+  if(QT4_FOUND)
+    set(QT_FOUND 1)
+    ocv_assert(QT_VERSION_MAJOR EQUAL 4)
+  endif()
```

Review comment:
Cases with: - `WITH_QT=4` - `WITH_QT=5` - `WITH_QT=6` - and `WITH_QT=ON` should be handled properly.
**File:** cmake/OpenCVFindLibsGUI.cmake
**Change Type:** modified
**Context:** PR #20183: improve compatibility for qt 6.

**Code Changes:**
```diff
@@ -11,25 +11,50 @@ if(WITH_WIN32UI)
     CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32")
 endif()
 
+macro(ocv_find_package_Qt4)
+  find_package(Qt4 COMPONENTS QtCore QtGui QtTest ${ARGN})
+  if(QT4_FOUND)
+    set(QT_FOUND 1)
+    ocv_assert(QT_VERSION_MAJOR EQUAL 4)
+  endif()
```

Review comment:
This block is not used to handle QT4, please see "if(NOT WITH_QT EQUAL 4)" and code at line 42 ...
**File:** cmake/OpenCVFindLibsGUI.cmake
**Change Type:** modified
**Context:** PR #20183: improve compatibility for qt 6.

**Code Changes:**
```diff
@@ -11,25 +11,50 @@ if(WITH_WIN32UI)
     CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32")
 endif()
 
+macro(ocv_find_package_Qt4)
+  find_package(Qt4 COMPONENTS QtCore QtGui QtTest ${ARGN})
+  if(QT4_FOUND)
+    set(QT_FOUND 1)
+    ocv_assert(QT_VERSION_MAJOR EQUAL 4)
+  endif()
```

Review comment:
Clean 3.4 branch + Fedora 33 with Qt4 + Qt5: - &#x2714; WITH_QT=ON => `YES (ver 5.15.2)` - &#x2714; WITH_QT=4 => `YES (ver 4.8.7 EDITION = OpenSource)` - &#x2714; WITH_QT=5 => `YES (ver 5.15.2)` - &#x2716; WITH_QT=6 => `YES (ver 5.15.2)` Patch original (May) + Fedora 33 with Qt4 + Qt5: - &#x2714; WITH_QT=ON => `YES (ver 5.15.2)` - &#x2714; WITH_QT=4 => `YES (ver 4.8.7 EDITION = OpenSource)` - &#x2714; WITH_QT=5 => `YES (ver 5.15.2)` - &#x2716; WITH_QT=6 => `YES (ver 5.15.2)` Patch updated + Fedora 33 with Qt4 + Qt5: - &#x2714; WITH_QT=ON => `YES (ver 5.15.2)` - &#x2714; WITH_QT=4 => `YES (ver 4.8.7 EDITION = OpenSource)` - &#x2714; WITH_QT=5 => `YES (ver 5.15.2)` - &#x2714; WITH_QT=6 => **FAILED** --- Need someone with Qt6 environment to validate behavior
**File:** modules/core/include/opencv2/core.hpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -819,12 +819,45 @@ mixChannels , or split .
 @param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
 @param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
 @param mask optional mask used to select a sub-array.
-@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
+@sa max, min, reduceArgMin, reduceArgMax, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
 */
 CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
                             CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
                             CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
```

Review comment:
> output array datatype? CV_32SC1? layout dims? dims - 1 or `dims[axis] = 1`? (the first one would not properly work with 2D/1D arrays)
**File:** modules/core/include/opencv2/core.hpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -819,12 +819,45 @@ mixChannels , or split .
 @param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
 @param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
 @param mask optional mask used to select a sub-array.
-@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
+@sa max, min, reduceArgMin, reduceArgMax, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
 */
 CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
                             CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
                             CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
```

Review comment:
contiguous arrays only? NaNs handling? or not supported
**File:** modules/core/test/test_arithm.cpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -2,6 +2,7 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 #include "test_precomp.hpp"
+#include "ref_reduce_arg.impl.hpp"
 
 namespace opencv_test { namespace {
 
@@ -1387,6 +1388,73 @@ struct MinMaxLocOp : public BaseElemWiseOp
     }
```

Review comment:
> core/argMax.yml BTW, currently almost all tests of the "core" module don't require testdata (except filesystem based). Reference non-optimized implementation is added as part of test code.
**File:** modules/core/include/opencv2/core.hpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -819,12 +819,45 @@ mixChannels , or split .
 @param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
 @param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
 @param mask optional mask used to select a sub-array.
-@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
+@sa max, min, reduceArgMin, reduceArgMax, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
 */
 CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
                             CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
                             CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
```

Review comment:
BTW, there is [`reduce()`](https://docs.opencv.org/3.4/d2/de8/group__core__array.html#ga4b78072a303f29d9031d56e5638da78e) call in OpenCV for similar operations.
**File:** modules/core/test/test_arithm.cpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -2,6 +2,7 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 #include "test_precomp.hpp"
+#include "ref_reduce_arg.impl.hpp"
 
 namespace opencv_test { namespace {
 
@@ -1387,6 +1388,73 @@ struct MinMaxLocOp : public BaseElemWiseOp
     }
```

Review comment:
I know, but this code is already unoptimized, so I wasn't sure how to test it.
**File:** modules/core/include/opencv2/core.hpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -819,12 +819,45 @@ mixChannels , or split .
 @param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
 @param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
 @param mask optional mask used to select a sub-array.
-@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
+@sa max, min, reduceArgMin, reduceArgMax, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
 */
 CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
                             CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
                             CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
```

Review comment:
Maybe it makes sense to add REDUCE_{MIN,MAX}_INDEX to reduce itself along with support for higher dimensions.
**File:** modules/core/include/opencv2/core.hpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -819,12 +819,45 @@ mixChannels , or split .
 @param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
 @param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
 @param mask optional mask used to select a sub-array.
-@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
+@sa max, min, reduceArgMin, reduceArgMax, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
 */
 CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
                             CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
                             CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
```

Review comment:
I added NaN handling - they are ignored. Contiguous mats are supported through clone for now.
**File:** modules/core/test/test_arithm.cpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -2,6 +2,7 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 #include "test_precomp.hpp"
+#include "ref_reduce_arg.impl.hpp"
 
 namespace opencv_test { namespace {
 
@@ -1387,6 +1388,73 @@ struct MinMaxLocOp : public BaseElemWiseOp
     }
```

Review comment:
Just copy this non-optimized implementation into tests. To ensure that future optimizations don't break results.
**File:** modules/core/include/opencv2/core.hpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -819,12 +819,45 @@ mixChannels , or split .
 @param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
 @param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
 @param mask optional mask used to select a sub-array.
-@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
+@sa max, min, reduceArgMin, reduceArgMax, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
 */
 CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
                             CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
                             CV_OUT Point* maxLoc = 0, InputArray mask = noArray());
```

Review comment:
> reduceMinMax IMHO, we don't want to mess min/max in that way in public API. Especially with enum. You don't want to process "both" indices at least. As suggested on the meeting we should have: - reduceArgMin - reduceArgMax You may add `bool lastIndex = false` optional parameter or add these functions: - reduceArgMinLast - reduceArgMaxLast
**File:** modules/core/include/opencv2/core/detail/dispatch_helper.impl.hpp
**Change Type:** added
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -0,0 +1,49 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#ifndef OPENCV_CORE_DETAIL_DISPATCH_HELPER_IMPL_HPP
+#define OPENCV_CORE_DETAIL_DISPATCH_HELPER_IMPL_HPP
+
+//! @cond IGNORED
+
```

Review comment:
Please update guard name too.
**File:** modules/core/perf/perf_reduce.cpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -65,4 +65,33 @@ PERF_TEST_P(Size_MatType_ROp, reduceC,
     SANITY_CHECK(vec, 1);
 }
 
+typedef tuple<Size, MatType, int> Size_MatType_RMode_t;
+typedef perf::TestBaseWithParam<Size_MatType_RMode_t> Size_MatType_RMode;
+
+PERF_TEST_P(Size_MatType_RMode, DISABLED_reduceArgMinMax, testing::Combine(
+        testing::Values(TYPICAL_MAT_SIZES),
+        testing::Values(CV_8U, CV_32F),
```

Review comment:
Do we really need performance tests now? Can we disable them by default (`DISABLED_reduceArgMinMax`)? - what is about 3D / 4D layouts? (DNN doesn't use 2D matrices in general)
**File:** modules/core/perf/perf_reduce.cpp
**Change Type:** modified
**Context:** PR #20733: Implement ArgMax and ArgMin

**Code Changes:**
```diff
@@ -65,4 +65,33 @@ PERF_TEST_P(Size_MatType_ROp, reduceC,
     SANITY_CHECK(vec, 1);
 }
 
+typedef tuple<Size, MatType, int> Size_MatType_RMode_t;
+typedef perf::TestBaseWithParam<Size_MatType_RMode_t> Size_MatType_RMode;
+
+PERF_TEST_P(Size_MatType_RMode, DISABLED_reduceArgMinMax, testing::Combine(
+        testing::Values(TYPICAL_MAT_SIZES),
+        testing::Values(CV_8U, CV_32F),
```

Review comment:
3D/4D layouts perform similarly if the number of pixels is the same.
**File:** modules/dnn/src/layers/layers_common.simd.hpp
**Change Type:** modified
**Context:** PR #20658: dnn: LSTM optimisation

**Code Changes:**
```diff
@@ -550,13 +550,24 @@ void fastDepthwiseConv( const float* wptr,
     _mm256_zeroupper();
 }
 
+// Used to generate the mask used when calculating tails
+static const uint32_t tailMaskArray[15] = {
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL
+};
+
```

Review comment:
use static preallocated/reinitialized buffer:`static uint32_t tailMaskArray[15] = { ... };`
**File:** modules/dnn/src/layers/layers_common.simd.hpp
**Change Type:** modified
**Context:** PR #20658: dnn: LSTM optimisation

**Code Changes:**
```diff
@@ -550,13 +550,24 @@ void fastDepthwiseConv( const float* wptr,
     _mm256_zeroupper();
 }
 
+// Used to generate the mask used when calculating tails
+static const uint32_t tailMaskArray[15] = {
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL, 0xffffffffUL
+};
+
```

Review comment:
please avoid unrelated whitespace changes
**File:** modules/dnn/src/layers/recurrent_layers.cpp
**Change Type:** modified
**Context:** PR #20658: dnn: LSTM optimisation

**Code Changes:**
```diff
@@ -46,6 +46,8 @@
 #include <cmath>
 #include <opencv2/dnn/shape_utils.hpp>
 
+#include "layers_common.hpp"
+
 namespace cv
 {
 namespace dnn
@@ -118,10 +120,23 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
```

Review comment:
Please add braces and indentation for gemm call: ``` { gemm(...) } ```
**File:** modules/dnn/src/layers/recurrent_layers.cpp
**Change Type:** modified
**Context:** PR #20658: dnn: LSTM optimisation

**Code Changes:**
```diff
@@ -46,6 +46,8 @@
 #include <cmath>
 #include <opencv2/dnn/shape_utils.hpp>
 
+#include "layers_common.hpp"
+
 namespace cv
 {
 namespace dnn
@@ -118,10 +120,23 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
```

Review comment:
Please use conditional compilation: ``` #if CV_TRY_AVX , useAVX(checkHardwareSupport(CPU_AVX)) #endif #if CV_TRY_AVX2 , useAVX2(checkHardwareSupport(CPU_AVX2)) #endif ```
**File:** modules/dnn/src/layers/recurrent_layers.cpp
**Change Type:** modified
**Context:** PR #20658: dnn: LSTM optimisation

**Code Changes:**
```diff
@@ -46,6 +46,8 @@
 #include <cmath>
 #include <opencv2/dnn/shape_utils.hpp>
 
+#include "layers_common.hpp"
+
 namespace cv
 {
 namespace dnn
@@ -118,10 +120,23 @@ class LSTMLayerImpl CV_FINAL : public LSTMLayer
```

Review comment:
could you please improve readability of the code as it does at the [fully connected layer](https://github.com/opencv/opencv/blob/master/modules/dnn/src/layers/fully_connected_layer.cpp#L231)? Condition ```c++ gates.isContinuous() && bias.isContinuous() && gates.depth() == CV_32F && bias.depth() == CV_32F ``` could be calculated once. Or you can add a helper to ensure that Mats are continuous and have 32F type.
**File:** modules/dnn/src/layers/recurrent_layers.cpp
**Change Type:** modified
**Context:** PR #20658: dnn: LSTM optimisation
**Review Line:** 461

**Code Changes:**
```diff
+                }
+                else
+#endif
+                {
+                    gemm(hInternal, Wh, 1, gates, 1, gates, GEMM_2_T);  //+Wh * h_{t-1}
+                }
 
                 Mat gateI = gates.colRange(0*numOut, 1*numOut);
                 Mat gateF = gates.colRange(1*numOut, 2*numOut);
```

Review comment:
is it possible to add optimization in case of peephole too? https://github.com/opencv/opencv/blob/master/modules/dnn/src/layers/recurrent_layers.cpp#L377