diff options
4 files changed, 215 insertions, 4 deletions
diff --git a/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv/0110-core-implement-OpenCL-kernel-for-UMat-diag-to-avoid-.patch b/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv/0110-core-implement-OpenCL-kernel-for-UMat-diag-to-avoid-.patch new file mode 100644 index 000000000..0b8b90582 --- /dev/null +++ b/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv/0110-core-implement-OpenCL-kernel-for-UMat-diag-to-avoid-.patch | |||
| @@ -0,0 +1,155 @@ | |||
| 1 | From 60858fce9e0c1a4dc3421e479b5633c140aa2191 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: jiajia Qian <jiajia.qian@nxp.com> | ||
| 3 | Date: Wed, 29 Apr 2026 16:19:00 +0800 | ||
| 4 | Subject: [PATCH] core: implement OpenCL kernel for UMat::diag to avoid | ||
| 5 | aliasing races | ||
| 6 | MIME-Version: 1.0 | ||
| 7 | Content-Type: text/plain; charset=UTF-8 | ||
| 8 | Content-Transfer-Encoding: 8bit | ||
| 9 | |||
| 10 | The previous OpenCL implementation of UMat::diag() relied on a sequence of | ||
| 11 | operations involving buffer initialization followed by copy/transpose on | ||
| 12 | an aliased diag() view. Although these operations were enqueued on an | ||
| 13 | in-order command queue, this implicitly assumed memory visibility between | ||
| 14 | kernels operating on aliased regions of the same buffer. | ||
| 15 | |||
| 16 | According to the OpenCL specification, in-order command queues only guarantee | ||
| 17 | command scheduling order, while memory visibility between commands is only | ||
| 18 | established through explicit command-level synchronization points (e.g. | ||
| 19 | events, barriers, or clFinish).Under OpenCL’s relaxed memory model, such | ||
| 20 | assumptions are not guaranteed without an explicit command-level synchronization | ||
| 21 | point, and can lead to data races and incorrect results, especially for very | ||
| 22 | small matrices (e.g. 1x1). The issue is more likely to be exposed on Mesa-based drivers | ||
| 23 | when the GPU is running at lower frequencies (e.g. 500 MHz). | ||
| 24 | |||
| 25 | This change introduces a dedicated OpenCL kernel to construct the diagonal | ||
| 26 | matrix in a single kernel invocation, avoiding intermediate aliasing and | ||
| 27 | eliminating the need for implicit ordering assumptions. If the OpenCL path | ||
| 28 | is unavailable or unsupported, the implementation transparently falls back | ||
| 29 | to the CPU path. | ||
| 30 | |||
| 31 | Upstream-Status: Backport [https://github.com/opencv/opencv/commit/60858fce9e0c1a4dc3421e479b5633c140aa2191] | ||
| 32 | Signed-off-by: jiajia Qian <jiajia.qian@nxp.com> | ||
| 33 | --- | ||
| 34 | modules/core/src/opencl/copyset.cl | 44 ++++++++++++++++++++++++++++ | ||
| 35 | modules/core/src/umatrix.cpp | 46 +++++++++++++++++++++++++++++- | ||
| 36 | 2 files changed, 89 insertions(+), 1 deletion(-) | ||
| 37 | |||
| 38 | diff --git a/modules/core/src/opencl/copyset.cl b/modules/core/src/opencl/copyset.cl | ||
| 39 | index beeccffed8..17aec71b5b 100644 | ||
| 40 | --- a/modules/core/src/opencl/copyset.cl | ||
| 41 | +++ b/modules/core/src/opencl/copyset.cl | ||
| 42 | @@ -98,6 +98,50 @@ __kernel void copyToMask(__global const uchar * srcptr, int src_step, int src_of | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | +#elif defined(SET_DIAG) | ||
| 47 | + | ||
| 48 | +#ifdef cl_khr_fp64 | ||
| 49 | +#pragma OPENCL EXTENSION cl_khr_fp64 : enable | ||
| 50 | +#endif | ||
| 51 | + | ||
| 52 | +__kernel void setDiag(__global uchar* dst, int dst_step, int dst_offset, | ||
| 53 | + int dst_rows, int dst_cols, | ||
| 54 | + __global const uchar* src, int src_step, int src_offset, | ||
| 55 | + int len) | ||
| 56 | +{ | ||
| 57 | + int x = get_global_id(0); | ||
| 58 | + int y = get_global_id(1); | ||
| 59 | + | ||
| 60 | + if (x < dst_cols && y < dst_rows) | ||
| 61 | + { | ||
| 62 | + int elem_size = (int)sizeof(T1) * cn; | ||
| 63 | + int dst_idx = mad24(y, dst_step, mad24(x, elem_size, dst_offset)); | ||
| 64 | + | ||
| 65 | + if (x == y && x < len) | ||
| 66 | + { | ||
| 67 | +#if IS_ROW_VECTOR | ||
| 68 | + int src_idx = src_offset + x * elem_size; | ||
| 69 | +#else | ||
| 70 | + int src_idx = mad24(x, src_step, src_offset); | ||
| 71 | +#endif | ||
| 72 | + __global T1* dst_ptr = (__global T1*)(dst + dst_idx); | ||
| 73 | + __global const T1* src_ptr = (__global const T1*)(src + src_idx); | ||
| 74 | + | ||
| 75 | + #pragma unroll | ||
| 76 | + for (int c = 0; c < cn; ++c) | ||
| 77 | + dst_ptr[c] = src_ptr[c]; | ||
| 78 | + } | ||
| 79 | + else | ||
| 80 | + { | ||
| 81 | + __global T1* dst_ptr = (__global T1*)(dst + dst_idx); | ||
| 82 | + | ||
| 83 | + #pragma unroll | ||
| 84 | + for (int c = 0; c < cn; ++c) | ||
| 85 | + dst_ptr[c] = (T1)0; | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | #else | ||
| 91 | |||
| 92 | #ifndef dstST | ||
| 93 | diff --git a/modules/core/src/umatrix.cpp b/modules/core/src/umatrix.cpp | ||
| 94 | index ceb4c064ec..f8845442d3 100644 | ||
| 95 | --- a/modules/core/src/umatrix.cpp | ||
| 96 | +++ b/modules/core/src/umatrix.cpp | ||
| 97 | @@ -993,10 +993,54 @@ UMat UMat::reshape(int new_cn, int new_rows) const | ||
| 98 | return hdr; | ||
| 99 | } | ||
| 100 | |||
| 101 | +#ifdef HAVE_OPENCL | ||
| 102 | +namespace { | ||
| 103 | +static bool ocl_setDiag(const UMat& d, UMat& m, int len) | ||
| 104 | +{ | ||
| 105 | + int cn = d.channels(); | ||
| 106 | + int depth = d.depth(); | ||
| 107 | + | ||
| 108 | + if (depth == CV_64F && !ocl::Device::getDefault().doubleFPConfig()) | ||
| 109 | + return false; | ||
| 110 | + | ||
| 111 | + String opts = format("-D SET_DIAG -D T1=%s -D cn=%d -D IS_ROW_VECTOR=%d", | ||
| 112 | + ocl::memopTypeToStr(depth), | ||
| 113 | + cn, | ||
| 114 | + (d.rows == 1) ? 1 : 0); | ||
| 115 | + | ||
| 116 | + ocl::Kernel k("setDiag", ocl::core::copyset_oclsrc, opts); | ||
| 117 | + if (k.empty()) | ||
| 118 | + return false; | ||
| 119 | + | ||
| 120 | + k.args(ocl::KernelArg::WriteOnly(m), | ||
| 121 | + ocl::KernelArg::ReadOnlyNoSize(d), | ||
| 122 | + len); | ||
| 123 | + | ||
| 124 | + size_t globalsize[2] = { (size_t)len, (size_t)len }; | ||
| 125 | + return k.run(2, globalsize, NULL, false); | ||
| 126 | +} | ||
| 127 | +} | ||
| 128 | +#endif | ||
| 129 | + | ||
| 130 | UMat UMat::diag(const UMat& d, UMatUsageFlags usageFlags) | ||
| 131 | { | ||
| 132 | - CV_Assert( d.cols == 1 || d.rows == 1 ); | ||
| 133 | + CV_INSTRUMENT_REGION(); | ||
| 134 | + | ||
| 135 | + CV_Assert(d.cols == 1 || d.rows == 1); | ||
| 136 | int len = d.rows + d.cols - 1; | ||
| 137 | + | ||
| 138 | +#ifdef HAVE_OPENCL | ||
| 139 | + if (ocl::useOpenCL()) | ||
| 140 | + { | ||
| 141 | + UMat m(len, len, d.type(), usageFlags); | ||
| 142 | + if (ocl_setDiag(d, m, len)) | ||
| 143 | + { | ||
| 144 | + CV_IMPL_ADD(CV_IMPL_OCL); | ||
| 145 | + return m; | ||
| 146 | + } | ||
| 147 | + } | ||
| 148 | +#endif | ||
| 149 | + | ||
| 150 | UMat m(len, len, d.type(), Scalar(0), usageFlags); | ||
| 151 | UMat md = m.diag(); | ||
| 152 | if( d.cols == 1 ) | ||
| 153 | -- | ||
| 154 | 2.34.1 | ||
| 155 | |||
diff --git a/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv/0111-lF-18405-opencv-example_tapi_clahe-sample-failed-wit.patch b/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv/0111-lF-18405-opencv-example_tapi_clahe-sample-failed-wit.patch new file mode 100644 index 000000000..d6e1c1e3d --- /dev/null +++ b/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv/0111-lF-18405-opencv-example_tapi_clahe-sample-failed-wit.patch | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | From 19be131ad53f835a2b569b05556bc4a12aa415c8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Chingling Wang <chingling.wang@nxp.com> | ||
| 3 | Date: Tue, 4 Aug 2026 15:55:15 -0700 | ||
| 4 | Subject: [PATCH] lF-18405 opencv example_tapi_clahe sample failed with | ||
| 5 | segmentation fault for imx8 platform | ||
| 6 | |||
| 7 | gpu viv is asynchonous SVM mapping. imread() allocated memory is temp, may be deleted before mapping to | ||
| 8 | GPU memory. need a temp Mat src to store the image data. Otheweise, may cause memory corruption leading to | ||
| 9 | segmenation fault. | ||
| 10 | |||
| 11 | Upstream-Status: Pending | ||
| 12 | Signed-off-by: Chingling Wang <chingling.wang@nxp.com> | ||
| 13 | --- | ||
| 14 | samples/tapi/clahe.cpp | 10 +++++++--- | ||
| 15 | 1 file changed, 7 insertions(+), 3 deletions(-) | ||
| 16 | |||
| 17 | diff --git a/samples/tapi/clahe.cpp b/samples/tapi/clahe.cpp | ||
| 18 | index ebef65f4e4..406102fd8d 100644 | ||
| 19 | --- a/samples/tapi/clahe.cpp | ||
| 20 | +++ b/samples/tapi/clahe.cpp | ||
| 21 | @@ -52,6 +52,7 @@ int main(int argc, char** argv) | ||
| 22 | createTrackbar("Tile Size", "CLAHE", &tilesize, 32, (TrackbarCallback)TSize_Callback); | ||
| 23 | createTrackbar("Clip Limit", "CLAHE", &cliplimit, 20, (TrackbarCallback)Clip_Callback); | ||
| 24 | |||
| 25 | + Mat src; | ||
| 26 | UMat frame, outframe; | ||
| 27 | |||
| 28 | int cur_clip; | ||
| 29 | @@ -66,7 +67,8 @@ int main(int argc, char** argv) | ||
| 30 | if(!infile.empty()) | ||
| 31 | { | ||
| 32 | infile = samples::findFile(infile); | ||
| 33 | - imread(infile).copyTo(frame); | ||
| 34 | + src = imread(infile); | ||
| 35 | + src.copyTo(frame); | ||
| 36 | if(frame.empty()) | ||
| 37 | { | ||
| 38 | cout << "error read image: " << infile << endl; | ||
| 39 | @@ -85,8 +87,10 @@ int main(int argc, char** argv) | ||
| 40 | { | ||
| 41 | if(capture.isOpened()) | ||
| 42 | capture.read(frame); | ||
| 43 | - else | ||
| 44 | - imread(infile).copyTo(frame); | ||
| 45 | + else{ | ||
| 46 | + src = imread(infile); | ||
| 47 | + src.copyTo(frame); | ||
| 48 | + } | ||
| 49 | if(frame.empty()) | ||
| 50 | { | ||
| 51 | waitKey(); | ||
| 52 | -- | ||
| 53 | 2.43.0 | ||
| 54 | |||
diff --git a/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv_4.13.0.imx.bb b/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv_4.13.0.imx.bb index 5ed168bbe..2fad969a8 100644 --- a/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv_4.13.0.imx.bb +++ b/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv_4.13.0.imx.bb | |||
| @@ -260,10 +260,10 @@ do_install:append() { | |||
| 260 | rm -rf ${D}${bindir}/setup_vars_opencv4.sh | 260 | rm -rf ${D}${bindir}/setup_vars_opencv4.sh |
| 261 | fi | 261 | fi |
| 262 | 262 | ||
| 263 | for fn in arithm.vsx3.cpp convert.vsx3.cpp; do | 263 | # Backported from meta-openembedded fdfca71954 (newer than the header's |
| 264 | if [ -f ${B}/modules/core/$fn ]; then | 264 | # Upstream hash). |
| 265 | sed -i -e 's,${S},/usr/src/debug/${PN}/${PV},g' ${B}/modules/core/$fn | 265 | find ${B}/modules -name "*.cpp" | xargs -r grep -l "${S}" | while read -r fn; do |
| 266 | fi | 266 | sed -i -e 's,${S},/usr/src/debug/${PN}/${PV},g' "$fn" |
| 267 | done | 267 | done |
| 268 | 268 | ||
| 269 | if [ -d ${D}/${bindir}/shape ]; then | 269 | if [ -d ${D}/${bindir}/shape ]; then |
diff --git a/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv_4.13.0.imx.inc b/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv_4.13.0.imx.inc index 97803c8e5..95390c5aa 100644 --- a/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv_4.13.0.imx.inc +++ b/dynamic-layers/openembedded-layer/recipes-support/opencv/opencv_4.13.0.imx.inc | |||
| @@ -32,6 +32,8 @@ SRC_URI += "\ | |||
| 32 | file://0107-imgproc-perf-HoughLines-Fix-test-tolerance-and-compa.patch \ | 32 | file://0107-imgproc-perf-HoughLines-Fix-test-tolerance-and-compa.patch \ |
| 33 | file://0108-imgproc-perf-HoughLines-Fix-lower-bound-for-line-cou.patch \ | 33 | file://0108-imgproc-perf-HoughLines-Fix-lower-bound-for-line-cou.patch \ |
| 34 | file://0109-core-ocl-fix-incorrect-results-for-in-place-flip-on-.patch \ | 34 | file://0109-core-ocl-fix-incorrect-results-for-in-place-flip-on-.patch \ |
| 35 | file://0110-core-implement-OpenCL-kernel-for-UMat-diag-to-avoid-.patch \ | ||
| 36 | file://0111-lF-18405-opencv-example_tapi_clahe-sample-failed-wit.patch \ | ||
| 35 | " | 37 | " |
| 36 | 38 | ||
| 37 | # Add opencv_extra | 39 | # Add opencv_extra |
