nareshmlx/opencv-pr huggingface dataset:
**File:** modules/dnn/src/layers/convolution_layer.cpp
**Change Type:** modified
**Context:** PR #18783: Add support for Conv1D on OpenCV backend - resolves https://github.com/opencv/opencv/issues/18205 **merge with extra:** https://github.com/...
**Review Line:** 721

**Code Changes:**
```diff
+            CV_Check(weights.step1(), weights.step1() % VEC_ALIGN == 0, "");
+            CV_CheckType(weights.type(), CV_32FC1, "");
             ParallelConv p;
 
             p.input_ = &input;
             p.weights_ = &weights;
             p.output_ = &output;
-            for( int i = 0; i < 4; i++ ) p.outShape[i] = output.size[i];
+            int max_ind = isConv1D? 3: 4;
+            for( int i = 0; i < max_ind; i++ ) p.outShape[i] = output.size[i];
             p.outShape[1] /= ngroups;
```

Review comment:
We define all the variables outside cycle loops for better code comprehension. *kernel_d, dil_d, pad_d* are unused for Conv1d and Conv2d, they are declared because otherwise the code won't compile. I can move them inside **if** braces, but I don't think it would be better this way
**File:** modules/dnn/src/layers/convolution_layer.cpp
**Change Type:** modified
**Context:** PR #18783: Add support for Conv1D on OpenCV backend - resolves https://github.com/opencv/opencv/issues/18205 **merge with extra:** https://github.com/...

**Code Changes:**
```diff
@@ -113,17 +113,22 @@ class BaseConvolutionLayerImpl : public ConvolutionLayer
         MatSize weightShape = blobs.empty() ? inputs[1].size : blobs[0].size;
 
         CV_Assert(inputs[0].dims == outputs[0].dims);
+        if (weightShape.dims() == 3)
+        {
+            kernel_size.assign(1, kernel_size[0]);
+            strides.assign(1, strides[0]);
+        }
         CV_Assert(weightShape.dims() == kernel_size.size() + 2);
```

Review comment:
Same here. Let's keep unchanged just to track the history of the file.
**File:** modules/dnn/src/layers/convolution_layer.cpp
**Change Type:** modified
**Context:** PR #18783: Add support for Conv1D on OpenCV backend - resolves https://github.com/opencv/opencv/issues/18205 **merge with extra:** https://github.com/...

**Code Changes:**
```diff
@@ -113,17 +113,22 @@ class BaseConvolutionLayerImpl : public ConvolutionLayer
         MatSize weightShape = blobs.empty() ? inputs[1].size : blobs[0].size;
 
         CV_Assert(inputs[0].dims == outputs[0].dims);
+        if (weightShape.dims() == 3)
+        {
+            kernel_size.assign(1, kernel_size[0]);
+            strides.assign(1, strides[0]);
+        }
         CV_Assert(weightShape.dims() == kernel_size.size() + 2);
```

Review comment:
Due we excluded IE from supported targets, let's keep 4 and 5
**File:** modules/dnn/src/layers/convolution_layer.cpp
**Change Type:** modified
**Context:** PR #18783: Add support for Conv1D on OpenCV backend - resolves https://github.com/opencv/opencv/issues/18205 **merge with extra:** https://github.com/...

**Code Changes:**
```diff
@@ -113,17 +113,22 @@ class BaseConvolutionLayerImpl : public ConvolutionLayer
         MatSize weightShape = blobs.empty() ? inputs[1].size : blobs[0].size;
 
         CV_Assert(inputs[0].dims == outputs[0].dims);
+        if (weightShape.dims() == 3)
+        {
+            kernel_size.assign(1, kernel_size[0]);
+            strides.assign(1, strides[0]);
+        }
         CV_Assert(weightShape.dims() == kernel_size.size() + 2);
```

Review comment:
Maybe better `CV_CheckEq(kernel_size().size(), input.dims - 2, "")`?
**File:** modules/dnn/src/layers/convolution_layer.cpp
**Change Type:** modified
**Context:** PR #18783: Add support for Conv1D on OpenCV backend - resolves https://github.com/opencv/opencv/issues/18205 **merge with extra:** https://github.com/...

**Code Changes:**
```diff
@@ -113,17 +113,22 @@ class BaseConvolutionLayerImpl : public ConvolutionLayer
         MatSize weightShape = blobs.empty() ? inputs[1].size : blobs[0].size;
 
         CV_Assert(inputs[0].dims == outputs[0].dims);
+        if (weightShape.dims() == 3)
+        {
+            kernel_size.assign(1, kernel_size[0]);
+            strides.assign(1, strides[0]);
+        }
         CV_Assert(weightShape.dims() == kernel_size.size() + 2);
```

Review comment:
extra change
**File:** modules/dnn/src/layers/convolution_layer.cpp
**Change Type:** modified
**Context:** PR #18783: Add support for Conv1D on OpenCV backend - resolves https://github.com/opencv/opencv/issues/18205 **merge with extra:** https://github.com/...

**Code Changes:**
```diff
@@ -113,17 +113,22 @@ class BaseConvolutionLayerImpl : public ConvolutionLayer
         MatSize weightShape = blobs.empty() ? inputs[1].size : blobs[0].size;
 
         CV_Assert(inputs[0].dims == outputs[0].dims);
+        if (weightShape.dims() == 3)
+        {
+            kernel_size.assign(1, kernel_size[0]);
+            strides.assign(1, strides[0]);
+        }
         CV_Assert(weightShape.dims() == kernel_size.size() + 2);
```

Review comment:
extra whitespaces
**File:** modules/dnn/src/layers/convolution_layer.cpp
**Change Type:** modified
**Context:** PR #18783: Add support for Conv1D on OpenCV backend - resolves https://github.com/opencv/opencv/issues/18205 **merge with extra:** https://github.com/...

**Code Changes:**
```diff
@@ -113,17 +113,22 @@ class BaseConvolutionLayerImpl : public ConvolutionLayer
         MatSize weightShape = blobs.empty() ? inputs[1].size : blobs[0].size;
 
         CV_Assert(inputs[0].dims == outputs[0].dims);
+        if (weightShape.dims() == 3)
+        {
+            kernel_size.assign(1, kernel_size[0]);
+            strides.assign(1, strides[0]);
+        }
         CV_Assert(weightShape.dims() == kernel_size.size() + 2);
```

Review comment:
extra modification
**File:** modules/objc/generator/gen_objc.py
**Change Type:** modified
**Context:** PR #18771: Xcode 12 and Python 2/3 fixes
**Review Line:** 3

**Code Changes:**
```diff
@@ -1,23 +1,20 @@
 #!/usr/bin/env python
 
+from __future__ import print_function, unicode_literals
 import sys, re, os.path, errno, fnmatch
 import json
 import logging
 import codecs
+import io
```

Review comment:
Probably `from __future__ import unicode_literals` is not used too (non-ASCII symbols should be avoided in .py source code).
**File:** modules/objc/generator/gen_objc.py
**Change Type:** modified
**Context:** PR #18771: Xcode 12 and Python 2/3 fixes
**Review Line:** 3

**Code Changes:**
```diff
@@ -1,23 +1,20 @@
 #!/usr/bin/env python
 
+from __future__ import print_function, unicode_literals
 import sys, re, os.path, errno, fnmatch
 import json
 import logging
 import codecs
+import io
```

Review comment:
Turns out that the `unicode_literals` import is needed to prevent this failure on Python 2: ``` File "/Volumes/build-storage/build/precommit_ios/opencv/modules/objc/generator/../generator/gen_objc.py", line 1224, in gen_class {0}\n}};\n\n""".format(",\n ".join(["%s = %s" % (c.name, c.value) for c in consts]), typeName, typeName) TypeError: unicode argument expected, got 'str' ```
**File:** modules/core/src/dxt.cpp
**Change Type:** modified
**Context:** PR #18158: Optimize opencv dft by vectorizing radix2 and radix3.
**Review Line:** 558

**Code Changes:**
```diff
+//  r_re + i*r_im = (a_re + i*a_im)*(b_re + i*b_im)
+// r_re and r_im are placed respectively in bits 31:0 and 63:32 of the resulting
+// vector register.
+inline __m128 complexMul(const Complex<float>* const a, const Complex<float>* const b) {
+    const __m128 z = _mm_setzero_ps();
+    const __m128 neg_elem0 = _mm_set_ps(0.0f,0.0f,0.0f,-0.0f);
+    // v_a[31:0] is a->re and v_a[63:32] is a->im.
+    const __m128 v_a = _mm_loadl_pi(z, (const __m64*)a);
+    const __m128 v_b = _mm_loadl_pi(z, (const __m64*)b);
+    // x_1 = v[nx] * wave[dw].
+    const __m128 v_a_riri = _mm_shuffle_ps(v_a, v_a, _MM_SHUFFLE(0, 1, 0, 1));
```

Review comment:
New code with native SSE/AVX intrinsics is not accepted anymore without a strong reason. Please try to use approach with "Universal SIMD Intrinsics" instead (which covers multiple platforms like ARM NEON, Power VSX, etc). Some words with motivation: https://github.com/opencv/opencv/wiki/OE-27.-Wide-Universal-Intrinsics BTW, Modern compilers are smart enough with optimization or auto-vectorization of floating-point code.
**File:** modules/core/src/dxt.cpp
**Change Type:** modified
**Context:** PR #18158: Optimize opencv dft by vectorizing radix2 and radix3.
**Review Line:** 558

**Code Changes:**
```diff
+//  r_re + i*r_im = (a_re + i*a_im)*(b_re + i*b_im)
+// r_re and r_im are placed respectively in bits 31:0 and 63:32 of the resulting
+// vector register.
+inline __m128 complexMul(const Complex<float>* const a, const Complex<float>* const b) {
+    const __m128 z = _mm_setzero_ps();
+    const __m128 neg_elem0 = _mm_set_ps(0.0f,0.0f,0.0f,-0.0f);
+    // v_a[31:0] is a->re and v_a[63:32] is a->im.
+    const __m128 v_a = _mm_loadl_pi(z, (const __m64*)a);
+    const __m128 v_b = _mm_loadl_pi(z, (const __m64*)b);
+    // x_1 = v[nx] * wave[dw].
+    const __m128 v_a_riri = _mm_shuffle_ps(v_a, v_a, _MM_SHUFFLE(0, 1, 0, 1));
```

Review comment:
Tested with disabled added native SSE code. Regression is about 7-9%. Also there is `DFT_VecR4` implementation with native SSE code which is not added by this patch. So just removal of native intrinsics is not a good option. Unfortunately there is no resources to port on OpenCV SIMD UI too, so lets merge this "as is".
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
This `#endif` should be a string upper - it's disabling too many `}`
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
Alignment here and below
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...
**Review Line:** 495

**Code Changes:**
```diff
+    }
+
+    return 0;
+}
+#endif
+
 template<typename DST, typename SRC1, typename SRC2>
 static void run_arithm(Buffer &dst, const View &src1, const View &src2, Arithm arithm,
                        double scale=1)
@@ -168,29 +510,37 @@ static void run_arithm(Buffer &dst, const View &src1, const View &src2, Arithm a
     // NB: assume in/out types are not 64-bits
```

Review comment:
I suggest moving all the new SIMD functions up (before function `absdiff`) or down (after 'divr') as they are now in the middle of the old plain functions
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
The `absDiff` kernel can't change a matrix type, so `DST` must always `== SRC` - the fact which you actually use in this function. I suggest reducing template arguments, but adding a `static_assert` in `run_arithm` function under `switch ABSDIFF` (see [comment ](https://github.com/opencv/opencv/pull/18338#discussion_r495617785)below)
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
I suggest to add right in here: ``` static_assert(std::is_same<DST, SRC1>::value, "Input and output types must match"); ``` (like [here](https://github.com/opencv/opencv/blob/95fd61c9b4c2cbe099f84740c35587e53d55b6bb/modules/gapi/src/backends/fluid/gfluidcore.cpp#L809) )
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
unnecessary empty line
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
Would it be faster in theory if all these `reinterpret_cast`s were made outside of the cycle?
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
+1 to remove DST (and rename SRC)
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
Since it's always `sametype`, you can rename this function to something like `absdiff_impl`
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
And you can miss template parameters here, compiler will deduce them for you: ``` absdiff_simd_sametype(reinterpret_cast<const uchar*>(in1), reinterpret_cast<const uchar*>(in2), reinterpret_cast<uchar*>(out), length, x); ```
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...
**Review Line:** 230

**Code Changes:**
```diff
+    else if (std::is_same<T, float>::value)
+    {
+        return absdiff_impl<float, v_float32>(reinterpret_cast<const float*>(in1),
+                                              reinterpret_cast<const float*>(in2),
+                                              reinterpret_cast<float*>(out), length);
+    }
+
+    return 0;
+}
+
+template<typename T, typename VT>
```

Review comment:
Please put `else` here with static_assert on unsupported combination of types
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
You can change this function to return x, not necessary though, but will help to understand this return
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...
**Review Line:** 233

**Code Changes:**
```diff
+                                              reinterpret_cast<const float*>(in2),
+                                              reinterpret_cast<float*>(out), length);
+    }
+
+    return 0;
+}
+
+template<typename T, typename VT>
+CV_ALWAYS_INLINE int add_simd_sametype(const T in1[], const T in2[], T out[], int length)
+{
+    constexpr int nlanes = static_cast<int>(VT::nlanes);
```

Review comment:
I'd move `absdiff_simd` to overload mechanism here: ``` // Default implementation template<typename T> static inline void absdiff_simd(const T in1[], const T in2[], char T[], int length, int& x) { // Do nothing } // Special implementation which will prevale over the default one static inline void absdiff_simd(const char in1[], const char in2[], char out[], int length, int& x) { absdiff_impl<v_uint8>(in1, in2, out, length, x); } ``` Also you can add traits not to declare every overloaded function. Or you can file a ticket on that :)
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
in any case, we must pass a universal intrinsic type, because it can't be determined from the types of the function arguments.
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
I think it's not so beautiful and not so important ;-)
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...
**Review Line:** 233

**Code Changes:**
```diff
+                                              reinterpret_cast<const float*>(in2),
+                                              reinterpret_cast<float*>(out), length);
+    }
+
+    return 0;
+}
+
+template<typename T, typename VT>
+CV_ALWAYS_INLINE int add_simd_sametype(const T in1[], const T in2[], T out[], int length)
+{
+    constexpr int nlanes = static_cast<int>(VT::nlanes);
```

Review comment:
I've already implemented this feature via overloads of "..._simd" functions. I've tested that implementation. However, this didn't provide brevity, beauty of snippet or performance gains. It also gives a lot of nested calls which doesn't speed up performance. So I'd prefer to leave this implementation as is if you don't mind :-)
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
Static assert will not work correctly here because there are instantiations of template of the run_arithm function where SRC not equal to DST. At compile time, the compiler does not know what type of operation will come to the template instantiation, when it be called at run time. So static assert will call here constantly. So set static assert here isn't good solution.
**File:** modules/gapi/src/backends/fluid/gfluidcore.cpp
**Change Type:** modified
**Context:** PR #18338: Univ Intrinsics implementation of Add, Sub, Absdiff kernels - Performance report: [AbsDiff_Add_Sub_perf_report.xlsx](https://github.com/ope...

**Code Changes:**
```diff
@@ -151,6 +151,348 @@ GAPI_FLUID_KERNEL(GFluidAddW, cv::gapi::core::GAddW, false)
 
 enum Arithm { ARITHM_ABSDIFF, ARITHM_ADD, ARITHM_SUBTRACT, ARITHM_MULTIPLY, ARITHM_DIVIDE };
 
+#if CV_SIMD
+CV_ALWAYS_INLINE void absdiff_store(short out[], const v_int16& a, const v_int16& b, int x)
+{
+    vx_store(&out[x], v_absdiffs(a, b));
+}
+
```

Review comment:
No, it's not good solution. Also it don't give speedup.