diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 5aca984378..e07c07d318 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -7229,10 +7229,17 @@ int predictOptimalVectorWidth(InputArray src1, InputArray src2, InputArray src3, { const ocl::Device & d = ocl::Device::getDefault(); - int vectorWidths[] = { d.preferredVectorWidthChar(), d.preferredVectorWidthChar(), - d.preferredVectorWidthShort(), d.preferredVectorWidthShort(), - d.preferredVectorWidthInt(), d.preferredVectorWidthFloat(), - d.preferredVectorWidthDouble(), d.preferredVectorWidthHalf() }; + // Indexed by depth: must span CV_DEPTH_MAX. bf16 has no OpenCL vector type. + int vectorWidths[CV_DEPTH_MAX] = { + d.preferredVectorWidthChar(), d.preferredVectorWidthChar(), // CV_8U, CV_8S + d.preferredVectorWidthShort(), d.preferredVectorWidthShort(), // CV_16U, CV_16S + d.preferredVectorWidthInt(), d.preferredVectorWidthFloat(), // CV_32S, CV_32F + d.preferredVectorWidthDouble(), d.preferredVectorWidthHalf(), // CV_64F, CV_16F + 1, // CV_16BF + d.preferredVectorWidthChar(), // CV_Bool + d.preferredVectorWidthLong(), d.preferredVectorWidthLong(), // CV_64U, CV_64S + d.preferredVectorWidthInt() // CV_32U + }; // if the device says don't use vectors if (vectorWidths[0] == 1) diff --git a/modules/core/test/ocl/test_arithm.cpp b/modules/core/test/ocl/test_arithm.cpp index cbf31ff3a0..ad15ee93eb 100644 --- a/modules/core/test/ocl/test_arithm.cpp +++ b/modules/core/test/ocl/test_arithm.cpp @@ -2124,6 +2124,30 @@ OCL_TEST(Normalize, DISABLED_regression_5876_inplace_change_type) EXPECT_EQ(0, cvtest::norm(um, uresult, NORM_INF)); } +// Regression: predictOptimalVectorWidth() must handle every depth without +// reading past its per-depth table. +OCL_TEST(Arithm, predictOptimalVectorWidth_all_depths) +{ + if (!cv::ocl::useOpenCL()) + return; + + const int depths[] = { CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F, + CV_16F, CV_16BF, CV_Bool, CV_64U, CV_64S, CV_32U }; + for (size_t i = 0; i < sizeof(depths) / sizeof(depths[0]); ++i) + { + const int depth = depths[i]; + for (int cn = 1; cn <= 4; ++cn) + { + const int type = CV_MAKE_TYPE(depth, cn); + UMat a(11, 13, type), b(11, 13, type); + EXPECT_GE(cv::ocl::predictOptimalVectorWidth(a), 1) + << "depth=" << depth << " cn=" << cn; + EXPECT_GE(cv::ocl::predictOptimalVectorWidth(a, b), 1) + << "depth=" << depth << " cn=" << cn; + } + } +} + } } // namespace opencv_test::ocl #endif // HAVE_OPENCL