feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake

1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
wangzhengyang
2022-05-10 09:54:44 +08:00
parent ecdd171c6f
commit 718c41634f
10018 changed files with 3593797 additions and 186748 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,469 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Jia Haipeng, jiahaipeng95@gmail.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#ifdef HAVE_OPENCL
namespace opencv_test {
namespace ocl {
//////////////////////////////////////// Merge ///////////////////////////////////////////////
PARAM_TEST_CASE(Merge, MatDepth, int, bool)
{
int depth, nsrc;
bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src1);
TEST_DECLARE_INPUT_PARAMETER(src2);
TEST_DECLARE_INPUT_PARAMETER(src3);
TEST_DECLARE_INPUT_PARAMETER(src4);
TEST_DECLARE_OUTPUT_PARAMETER(dst);
std::vector<Mat> src_roi;
std::vector<UMat> usrc_roi;
virtual void SetUp()
{
depth = GET_PARAM(0);
nsrc = GET_PARAM(1);
use_roi = GET_PARAM(2);
CV_Assert(nsrc >= 1 && nsrc <= 4);
}
int type()
{
return CV_MAKE_TYPE(depth, randomInt(1, 3));
}
void generateTestData()
{
Size roiSize = randomSize(1, MAX_VALUE);
{
Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src1, src1_roi, roiSize, src1Border, type(), 2, 11);
Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src2, src2_roi, roiSize, src2Border, type(), -1540, 1740);
Border src3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src3, src3_roi, roiSize, src3Border, type(), -1540, 1740);
Border src4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src4, src4_roi, roiSize, src4Border, type(), -1540, 1740);
}
UMAT_UPLOAD_INPUT_PARAMETER(src1);
UMAT_UPLOAD_INPUT_PARAMETER(src2);
UMAT_UPLOAD_INPUT_PARAMETER(src3);
UMAT_UPLOAD_INPUT_PARAMETER(src4);
src_roi.clear(); usrc_roi.clear(); // for test_loop_times > 1
src_roi.push_back(src1_roi), usrc_roi.push_back(usrc1_roi);
if (nsrc >= 2)
src_roi.push_back(src2_roi), usrc_roi.push_back(usrc2_roi);
if (nsrc >= 3)
src_roi.push_back(src3_roi), usrc_roi.push_back(usrc3_roi);
if (nsrc >= 4)
src_roi.push_back(src4_roi), usrc_roi.push_back(usrc4_roi);
int dcn = 0;
for (int i = 0; i < nsrc; ++i)
dcn += src_roi[i].channels();
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, dcn), 5, 16);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
}
void Near(double threshold = 0.)
{
OCL_EXPECT_MATS_NEAR(dst, threshold);
}
};
OCL_TEST_P(Merge, Accuracy)
{
for(int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(cv::merge(src_roi, dst_roi));
OCL_ON(cv::merge(usrc_roi, udst_roi));
Near();
}
}
//////////////////////////////////////// Split ///////////////////////////////////////////////
PARAM_TEST_CASE(Split, MatType, Channels, bool)
{
int depth, cn;
bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst1);
TEST_DECLARE_OUTPUT_PARAMETER(dst2);
TEST_DECLARE_OUTPUT_PARAMETER(dst3);
TEST_DECLARE_OUTPUT_PARAMETER(dst4);
std::vector<Mat> dst_roi, dst;
std::vector<UMat> udst_roi, udst;
virtual void SetUp()
{
depth = GET_PARAM(0);
cn = GET_PARAM(1);
use_roi = GET_PARAM(2);
CV_Assert(cn >= 1 && cn <= 4);
}
void generateTestData()
{
Size roiSize = randomSize(1, MAX_VALUE);
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, CV_MAKE_TYPE(depth, cn), 5, 16);
{
Border dst1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst1, dst1_roi, roiSize, dst1Border, depth, 2, 11);
Border dst2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst2, dst2_roi, roiSize, dst2Border, depth, -1540, 1740);
Border dst3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst3, dst3_roi, roiSize, dst3Border, depth, -1540, 1740);
Border dst4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst4, dst4_roi, roiSize, dst4Border, depth, -1540, 1740);
}
UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst1);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst2);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst3);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst4);
dst_roi.push_back(dst1_roi), udst_roi.push_back(udst1_roi),
dst.push_back(dst1), udst.push_back(udst1);
if (cn >= 2)
dst_roi.push_back(dst2_roi), udst_roi.push_back(udst2_roi),
dst.push_back(dst2), udst.push_back(udst2);
if (cn >= 3)
dst_roi.push_back(dst3_roi), udst_roi.push_back(udst3_roi),
dst.push_back(dst3), udst.push_back(udst3);
if (cn >= 4)
dst_roi.push_back(dst4_roi), udst_roi.push_back(udst4_roi),
dst.push_back(dst4), udst.push_back(udst4);
}
};
OCL_TEST_P(Split, Accuracy)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(cv::split(src_roi, dst_roi));
OCL_ON(cv::split(usrc_roi, udst_roi));
for (int i = 0; i < cn; ++i)
{
EXPECT_MAT_NEAR(dst[i], udst[i], 0.0);
EXPECT_MAT_NEAR(dst_roi[i], udst_roi[i], 0.0);
}
}
}
//////////////////////////////////////// MixChannels ///////////////////////////////////////////////
PARAM_TEST_CASE(MixChannels, MatType, bool)
{
int depth;
bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src1);
TEST_DECLARE_INPUT_PARAMETER(src2);
TEST_DECLARE_INPUT_PARAMETER(src3);
TEST_DECLARE_INPUT_PARAMETER(src4);
TEST_DECLARE_OUTPUT_PARAMETER(dst1);
TEST_DECLARE_OUTPUT_PARAMETER(dst2);
TEST_DECLARE_OUTPUT_PARAMETER(dst3);
TEST_DECLARE_OUTPUT_PARAMETER(dst4);
std::vector<Mat> src_roi, dst_roi, dst;
std::vector<UMat> usrc_roi, udst_roi, udst;
std::vector<int> fromTo;
virtual void SetUp()
{
depth = GET_PARAM(0);
use_roi = GET_PARAM(1);
}
// generate number of channels and create type
int type()
{
int cn = randomInt(1, 5);
return CV_MAKE_TYPE(depth, cn);
}
void generateTestData()
{
src_roi.clear();
dst_roi.clear();
dst.clear();
usrc_roi.clear();
udst_roi.clear();
udst.clear();
fromTo.clear();
Size roiSize = randomSize(1, MAX_VALUE);
{
Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src1, src1_roi, roiSize, src1Border, type(), 2, 11);
Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src2, src2_roi, roiSize, src2Border, type(), -1540, 1740);
Border src3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src3, src3_roi, roiSize, src3Border, type(), -1540, 1740);
Border src4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src4, src4_roi, roiSize, src4Border, type(), -1540, 1740);
}
{
Border dst1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst1, dst1_roi, roiSize, dst1Border, type(), 2, 11);
Border dst2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst2, dst2_roi, roiSize, dst2Border, type(), -1540, 1740);
Border dst3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst3, dst3_roi, roiSize, dst3Border, type(), -1540, 1740);
Border dst4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst4, dst4_roi, roiSize, dst4Border, type(), -1540, 1740);
}
UMAT_UPLOAD_INPUT_PARAMETER(src1);
UMAT_UPLOAD_INPUT_PARAMETER(src2);
UMAT_UPLOAD_INPUT_PARAMETER(src3);
UMAT_UPLOAD_INPUT_PARAMETER(src4);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst1);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst2);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst3);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst4);
int nsrc = randomInt(1, 5), ndst = randomInt(1, 5);
src_roi.push_back(src1_roi), usrc_roi.push_back(usrc1_roi);
if (nsrc >= 2)
src_roi.push_back(src2_roi), usrc_roi.push_back(usrc2_roi);
if (nsrc >= 3)
src_roi.push_back(src3_roi), usrc_roi.push_back(usrc3_roi);
if (nsrc >= 4)
src_roi.push_back(src4_roi), usrc_roi.push_back(usrc4_roi);
dst_roi.push_back(dst1_roi), udst_roi.push_back(udst1_roi),
dst.push_back(dst1), udst.push_back(udst1);
if (ndst >= 2)
dst_roi.push_back(dst2_roi), udst_roi.push_back(udst2_roi),
dst.push_back(dst2), udst.push_back(udst2);
if (ndst >= 3)
dst_roi.push_back(dst3_roi), udst_roi.push_back(udst3_roi),
dst.push_back(dst3), udst.push_back(udst3);
if (ndst >= 4)
dst_roi.push_back(dst4_roi), udst_roi.push_back(udst4_roi),
dst.push_back(dst4), udst.push_back(udst4);
int scntotal = 0, dcntotal = 0;
for (int i = 0; i < nsrc; ++i)
scntotal += src_roi[i].channels();
for (int i = 0; i < ndst; ++i)
dcntotal += dst_roi[i].channels();
int npairs = randomInt(1, std::min(scntotal, dcntotal) + 1);
fromTo.resize(npairs << 1);
for (int i = 0; i < npairs; ++i)
{
fromTo[i<<1] = randomInt(0, scntotal);
fromTo[(i<<1)+1] = randomInt(0, dcntotal);
}
}
};
OCL_TEST_P(MixChannels, Accuracy)
{
for (int j = 0; j < test_loop_times + 10; j++)
{
generateTestData();
OCL_OFF(cv::mixChannels(src_roi, dst_roi, fromTo));
OCL_ON(cv::mixChannels(usrc_roi, udst_roi, fromTo));
for (size_t i = 0, size = dst_roi.size(); i < size; ++i)
{
EXPECT_MAT_NEAR(dst[i], udst[i], 0.0);
EXPECT_MAT_NEAR(dst_roi[i], udst_roi[i], 0.0);
}
}
}
//////////////////////////////////////// InsertChannel ///////////////////////////////////////////////
PARAM_TEST_CASE(InsertChannel, MatDepth, Channels, bool)
{
int depth, cn, coi;
bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp()
{
depth = GET_PARAM(0);
cn = GET_PARAM(1);
use_roi = GET_PARAM(2);
}
void generateTestData()
{
Size roiSize = randomSize(1, MAX_VALUE);
coi = randomInt(0, cn);
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, depth, 2, 11);
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, cn), 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
}
};
OCL_TEST_P(InsertChannel, Accuracy)
{
for(int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(cv::insertChannel(src_roi, dst_roi, coi));
OCL_ON(cv::insertChannel(usrc_roi, udst_roi, coi));
OCL_EXPECT_MATS_NEAR(dst, 0);
}
}
//////////////////////////////////////// ExtractChannel ///////////////////////////////////////////////
PARAM_TEST_CASE(ExtractChannel, MatDepth, Channels, bool)
{
int depth, cn, coi;
bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp()
{
depth = GET_PARAM(0);
cn = GET_PARAM(1);
use_roi = GET_PARAM(2);
}
void generateTestData()
{
Size roiSize = randomSize(1, MAX_VALUE);
coi = randomInt(0, cn);
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, CV_MAKE_TYPE(depth, cn), 2, 11);
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, depth, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
}
};
OCL_TEST_P(ExtractChannel, Accuracy)
{
for(int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(cv::extractChannel(src_roi, dst_roi, coi));
OCL_ON(cv::extractChannel(usrc_roi, udst_roi, coi));
OCL_EXPECT_MATS_NEAR(dst, 0);
}
}
//////////////////////////////////////// Instantiation ///////////////////////////////////////////////
OCL_INSTANTIATE_TEST_CASE_P(Channels, Merge, Combine(OCL_ALL_DEPTHS, Values(1, 2, 3, 4), Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Channels, Split, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Channels, MixChannels, Combine(OCL_ALL_DEPTHS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Channels, InsertChannel, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Channels, ExtractChannel, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
} } // namespace opencv_test::ocl
#endif // HAVE_OPENCL

View File

@ -0,0 +1,190 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Peng Xiao, pengxiao@multicorewareinc.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors as is and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#ifdef HAVE_OPENCL
enum OCL_FFT_TYPE
{
R2R = 0,
C2R = 1,
R2C = 2,
C2C = 3
};
namespace opencv_test {
namespace ocl {
////////////////////////////////////////////////////////////////////////////
// Dft
PARAM_TEST_CASE(Dft, cv::Size, OCL_FFT_TYPE, MatDepth, bool, bool, bool, bool)
{
cv::Size dft_size;
int dft_flags, depth, cn, dft_type;
bool hint;
bool is1d;
TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp()
{
dft_size = GET_PARAM(0);
dft_type = GET_PARAM(1);
depth = GET_PARAM(2);
dft_flags = 0;
switch (dft_type)
{
case R2R: dft_flags |= cv::DFT_REAL_OUTPUT; cn = 1; break;
case C2R: dft_flags |= cv::DFT_REAL_OUTPUT; cn = 2; break;
case R2C: dft_flags |= cv::DFT_COMPLEX_OUTPUT; cn = 1; break;
case C2C: dft_flags |= cv::DFT_COMPLEX_OUTPUT; cn = 2; break;
}
if (GET_PARAM(3))
dft_flags |= cv::DFT_INVERSE;
if (GET_PARAM(4))
dft_flags |= cv::DFT_ROWS;
if (GET_PARAM(5))
dft_flags |= cv::DFT_SCALE;
hint = GET_PARAM(6);
is1d = (dft_flags & DFT_ROWS) != 0 || dft_size.height == 1;
}
void generateTestData()
{
src = randomMat(dft_size, CV_MAKE_TYPE(depth, cn), 0.0, 100.0);
usrc = src.getUMat(ACCESS_READ);
}
};
OCL_TEST_P(Dft, Mat)
{
generateTestData();
int nonzero_rows = hint ? src.rows - randomInt(1, src.rows-1) : 0;
OCL_OFF(cv::dft(src, dst, dft_flags, nonzero_rows));
OCL_ON(cv::dft(usrc, udst, dft_flags, nonzero_rows));
// In case forward R2C 1d transform dst contains only half of output
// without complex conjugate
if (dft_type == R2C && is1d && (dft_flags & cv::DFT_INVERSE) == 0)
{
dst = dst(cv::Range(0, dst.rows), cv::Range(0, dst.cols/2 + 1));
udst = udst(cv::Range(0, udst.rows), cv::Range(0, udst.cols/2 + 1));
}
double eps = src.size().area() * 1e-4;
EXPECT_MAT_NEAR(dst, udst, eps);
}
////////////////////////////////////////////////////////////////////////////
// MulSpectrums
PARAM_TEST_CASE(MulSpectrums, bool, bool)
{
bool ccorr, useRoi;
TEST_DECLARE_INPUT_PARAMETER(src1);
TEST_DECLARE_INPUT_PARAMETER(src2);
TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp()
{
ccorr = GET_PARAM(0);
useRoi = GET_PARAM(1);
}
void generateTestData()
{
Size srcRoiSize = randomSize(1, MAX_VALUE);
Border src1Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
randomSubMat(src1, src1_roi, srcRoiSize, src1Border, CV_32FC2, -11, 11);
Border src2Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
randomSubMat(src2, src2_roi, srcRoiSize, src2Border, CV_32FC2, -11, 11);
Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, srcRoiSize, dstBorder, CV_32FC2, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src1);
UMAT_UPLOAD_INPUT_PARAMETER(src2);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
}
};
OCL_TEST_P(MulSpectrums, Mat)
{
for (int i = 0; i < test_loop_times; ++i)
{
generateTestData();
OCL_OFF(cv::mulSpectrums(src1_roi, src2_roi, dst_roi, 0, ccorr));
OCL_ON(cv::mulSpectrums(usrc1_roi, usrc2_roi, udst_roi, 0, ccorr));
OCL_EXPECT_MATS_NEAR_RELATIVE(dst, 1e-6);
}
}
OCL_INSTANTIATE_TEST_CASE_P(OCL_ImgProc, MulSpectrums, testing::Combine(Bool(), Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Core, Dft, Combine(Values(cv::Size(45, 72), cv::Size(36, 36), cv::Size(512, 1), cv::Size(1280, 768)),
Values((OCL_FFT_TYPE) R2C, (OCL_FFT_TYPE) C2C, (OCL_FFT_TYPE) R2R, (OCL_FFT_TYPE) C2R),
Values(CV_32F, CV_64F),
Bool(), // DFT_INVERSE
Bool(), // DFT_ROWS
Bool(), // DFT_SCALE
Bool() // hint
)
);
} } // namespace opencv_test::ocl
#endif // HAVE_OPENCL

View File

@ -0,0 +1,165 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Peng Xiao, pengxiao@multicorewareinc.com
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors as is and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#ifdef HAVE_OPENCL
namespace opencv_test {
namespace ocl {
////////////////////////////////////////////////////////////////////////////
// GEMM
PARAM_TEST_CASE(Gemm,
MatType,
bool, // GEMM_1_T
bool, // GEMM_2_T
bool, // GEMM_3_T
bool // ROI
)
{
bool use_roi;
int type, flags;
bool atrans, btrans, ctrans;
double alpha, beta;
int M, N, K;
TEST_DECLARE_INPUT_PARAMETER(A);
TEST_DECLARE_INPUT_PARAMETER(B);
TEST_DECLARE_INPUT_PARAMETER(C);
TEST_DECLARE_OUTPUT_PARAMETER(D);
virtual void SetUp()
{
atrans = btrans = ctrans = false;
type = GET_PARAM(0);
use_roi = GET_PARAM(4);
flags = 0;
if (GET_PARAM(1))
flags |= GEMM_1_T, atrans = true;
if (GET_PARAM(2))
flags |= GEMM_2_T, btrans = true;
if (GET_PARAM(3))
flags |= GEMM_3_T, ctrans = true;
}
void generateTestData()
{
M = (int)randomDoubleLog(1, 100);
N = (int)randomDoubleLog(1, 100);
K = (int)randomDoubleLog(1, 1200);
M = roundUp(M, 1);
N = roundUp(N, 1);
K = roundUp(K, 1);
Size ARoiSize = (atrans) ? Size(M, K) : Size(K, M);
Border ABorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(A, A_roi, ARoiSize, ABorder, type, -11, 11);
Size BRoiSize = (btrans) ? Size(K, N) : Size(N, K);
Border BBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(B, B_roi, BRoiSize, BBorder, type, -11, 11);
Size CRoiSize = (ctrans) ? Size(M, N) : Size(N, M);
Border CBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(C, C_roi, CRoiSize, CBorder, type, -11, 11);
Size DRoiSize = Size(N, M);
Border DBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(D, D_roi, DRoiSize, DBorder, type, -11, 11);
alpha = randomDouble(-4, 4);
beta = randomDouble(-4, 4);
UMAT_UPLOAD_INPUT_PARAMETER(A);
UMAT_UPLOAD_INPUT_PARAMETER(B);
UMAT_UPLOAD_INPUT_PARAMETER(C);
UMAT_UPLOAD_OUTPUT_PARAMETER(D);
}
};
OCL_TEST_P(Gemm, Accuracy)
{
for (int i = 0; i < test_loop_times; ++i)
{
generateTestData();
SCOPED_TRACE(cv::format("i=%d: M=%d N=%d K=%d", i, M, N, K));
OCL_OFF(cv::gemm(A_roi, B_roi, alpha, C_roi, beta, D_roi, flags));
OCL_ON(cv::gemm(uA_roi, uB_roi, alpha, uC_roi, beta, uD_roi, flags));
double eps = D_roi.size().area() * (1e-5 * K);
OCL_EXPECT_MATS_NEAR(D, eps);
}
}
OCL_INSTANTIATE_TEST_CASE_P(Core, Gemm, ::testing::Combine(
testing::Values(CV_32FC1, CV_32FC2, CV_64FC1, CV_64FC2),
Bool(), Bool(), Bool(), Bool()));
// Test for non-Intel GPUs to check CL_INVALID_WORK_GROUP_SIZE when localsize > globalsize
OCL_TEST(Gemm, small)
{
UMat A(2, 3, CV_32F), B(4, 3, CV_32F), uC(2, 4, CV_32F);
Mat C(2, 4, CV_32F);
randu(A, -1, 1);
randu(B, -1, 1);
OCL_OFF(cv::gemm(A, B, 1, noArray(), 0, C, GEMM_2_T));
OCL_ON(cv::gemm(A, B, 1, noArray(), 0, uC, GEMM_2_T));
EXPECT_LE(cvtest::norm(C, uC, cv::NORM_INF), 1e-5);
}
} } // namespace opencv_test::ocl
#endif // HAVE_OPENCL

View File

@ -0,0 +1,96 @@
// 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.
// Copyright (C) 2014, Itseez, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#ifdef HAVE_OPENCL
namespace opencv_test {
namespace ocl {
TEST(Image2D, createAliasEmptyUMat)
{
if (cv::ocl::haveOpenCL())
{
UMat um;
EXPECT_FALSE(cv::ocl::Image2D::canCreateAlias(um));
}
else
std::cout << "OpenCL runtime not found. Test skipped." << std::endl;
}
TEST(Image2D, createImage2DWithEmptyUMat)
{
if (cv::ocl::haveOpenCL())
{
UMat um;
EXPECT_ANY_THROW(cv::ocl::Image2D image(um));
}
else
std::cout << "OpenCL runtime not found. Test skipped." << std::endl;
}
TEST(Image2D, createAlias)
{
if (cv::ocl::haveOpenCL())
{
const cv::ocl::Device & d = cv::ocl::Device::getDefault();
int minor = d.deviceVersionMinor(), major = d.deviceVersionMajor();
// aliases is OpenCL 1.2 extension
if (1 < major || (1 == major && 2 <= minor))
{
UMat um(128, 128, CV_8UC1);
bool isFormatSupported = false, canCreateAlias = false;
EXPECT_NO_THROW(isFormatSupported = cv::ocl::Image2D::isFormatSupported(CV_8U, 1, false));
EXPECT_NO_THROW(canCreateAlias = cv::ocl::Image2D::canCreateAlias(um));
if (isFormatSupported && canCreateAlias)
{
EXPECT_NO_THROW(cv::ocl::Image2D image(um, false, true));
}
else
std::cout << "Impossible to create alias for selected image. Test skipped." << std::endl;
}
}
else
std::cout << "OpenCL runtime not found. Test skipped" << std::endl;
}
TEST(Image2D, turnOffOpenCL)
{
if (cv::ocl::haveOpenCL())
{
// save the current state
bool useOCL = cv::ocl::useOpenCL();
bool isFormatSupported = false;
cv::ocl::setUseOpenCL(true);
UMat um(128, 128, CV_8UC1);
cv::ocl::setUseOpenCL(false);
EXPECT_NO_THROW(isFormatSupported = cv::ocl::Image2D::isFormatSupported(CV_8U, 1, true));
if (isFormatSupported)
{
EXPECT_NO_THROW(cv::ocl::Image2D image(um));
}
else
std::cout << "CV_8UC1 is not supported for OpenCL images. Test skipped." << std::endl;
// reset state to the previous one
cv::ocl::setUseOpenCL(useOCL);
}
else
std::cout << "OpenCL runtime not found. Test skipped." << std::endl;
}
} } // namespace opencv_test::ocl
#endif // HAVE_OPENCL

View File

@ -0,0 +1,103 @@
// 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.
// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#ifdef HAVE_OPENCL
namespace opencv_test {
namespace ocl {
//////////////////////////////// UMat Expressions /////////////////////////////////////////////////
PARAM_TEST_CASE(UMatExpr, MatDepth, Channels)
{
int type;
Size size;
virtual void SetUp()
{
type = CV_MAKE_TYPE(GET_PARAM(0), GET_PARAM(1));
}
void generateTestData()
{
size = randomSize(1, MAX_VALUE);
}
};
//////////////////////////////// UMat::eye /////////////////////////////////////////////////
OCL_TEST_P(UMatExpr, Eye)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
Mat m = Mat::eye(size, type);
UMat um = UMat::eye(size, type);
EXPECT_MAT_NEAR(m, um, 0);
}
}
//////////////////////////////// UMat::zeros /////////////////////////////////////////////////
OCL_TEST_P(UMatExpr, Zeros)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
Mat m = Mat::zeros(size, type);
UMat um = UMat::zeros(size, type);
EXPECT_MAT_NEAR(m, um, 0);
}
}
//////////////////////////////// UMat::ones /////////////////////////////////////////////////
OCL_TEST_P(UMatExpr, Ones)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
Mat m = Mat::ones(size, type);
UMat um = UMat::ones(size, type);
EXPECT_MAT_NEAR(m, um, 0);
}
}
//////////////////////////////// with usageFlags /////////////////////////////////////////////////
OCL_TEST_P(UMatExpr, WithUsageFlags)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
UMat u0 = UMat::zeros(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
UMat u1 = UMat::ones(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
UMat u8 = UMat::eye(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u0.usageFlags);
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u1.usageFlags);
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u8.usageFlags);
}
}
//////////////////////////////// Instantiation /////////////////////////////////////////////////
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, UMatExpr, Combine(OCL_ALL_DEPTHS_16F, OCL_ALL_CHANNELS));
} } // namespace opencv_test::ocl
#endif

View File

@ -0,0 +1,224 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Jia Haipeng, jiahaipeng95@gmail.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#ifdef HAVE_OPENCL
namespace opencv_test {
namespace ocl {
////////////////////////////////converto/////////////////////////////////////////////////
PARAM_TEST_CASE(ConvertTo, MatDepth, MatDepth, Channels, bool)
{
int src_depth, cn, dstType;
bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp()
{
src_depth = GET_PARAM(0);
cn = GET_PARAM(2);
dstType = CV_MAKE_TYPE(GET_PARAM(1), cn);
use_roi = GET_PARAM(3);
}
void generateTestData()
{
Size roiSize = randomSize(1, MAX_VALUE);
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, CV_MAKE_TYPE(src_depth, cn), -MAX_VALUE, MAX_VALUE);
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, dstType, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
}
};
OCL_TEST_P(ConvertTo, WithScale_Accuracy)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
double alpha = randomDouble(-4, 4), beta = randomDouble(-4, 4);
OCL_OFF(src_roi.convertTo(dst_roi, dstType, alpha, beta));
OCL_ON(usrc_roi.convertTo(udst_roi, dstType, alpha, beta));
double eps = CV_MAT_DEPTH(dstType) >= CV_32F ? 2e-4 : 1;
OCL_EXPECT_MATS_NEAR(dst, eps);
}
}
OCL_TEST_P(ConvertTo, NoScale_Accuracy)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(src_roi.convertTo(dst_roi, dstType, 1, 0));
OCL_ON(usrc_roi.convertTo(udst_roi, dstType, 1, 0));
double eps = CV_MAT_DEPTH(dstType) >= CV_32F ? 2e-4 : 1;
OCL_EXPECT_MATS_NEAR(dst, eps);
}
}
//////////////////////////////// CopyTo /////////////////////////////////////////////////
PARAM_TEST_CASE(CopyTo, MatDepth, Channels, bool, bool)
{
int depth, cn;
bool use_roi, use_mask;
Scalar val;
TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_INPUT_PARAMETER(mask);
TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp()
{
depth = GET_PARAM(0);
cn = GET_PARAM(1);
use_roi = GET_PARAM(2);
use_mask = GET_PARAM(3);
}
void generateTestData(bool one_cn_mask = false)
{
const int type = CV_MAKE_TYPE(depth, cn);
Size roiSize = randomSize(1, MAX_VALUE);
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, type, -MAX_VALUE, MAX_VALUE);
if (use_mask)
{
Border maskBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
int mask_cn = 1;
if (!one_cn_mask && randomDouble(0.0, 2.0) > 1.0)
mask_cn = cn;
randomSubMat(mask, mask_roi, roiSize, maskBorder, CV_8UC(mask_cn), 0, 2);
cv::threshold(mask, mask, 0.5, 255., THRESH_BINARY);
}
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, type, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src);
if (use_mask)
UMAT_UPLOAD_INPUT_PARAMETER(mask);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
val = randomScalar(-MAX_VALUE, MAX_VALUE);
}
};
OCL_TEST_P(CopyTo, Accuracy)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
if (use_mask)
{
OCL_OFF(src_roi.copyTo(dst_roi, mask_roi));
OCL_ON(usrc_roi.copyTo(udst_roi, umask_roi));
}
else
{
OCL_OFF(src_roi.copyTo(dst_roi));
OCL_ON(usrc_roi.copyTo(udst_roi));
}
OCL_EXPECT_MATS_NEAR(dst, 0);
}
}
typedef CopyTo SetTo;
OCL_TEST_P(SetTo, Accuracy)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData(true); // see modules/core/src/umatrix.cpp Ln:791 => CV_Assert( mask.size() == size() && mask.type() == CV_8UC1 );
if (use_mask)
{
OCL_OFF(dst_roi.setTo(val, mask_roi));
OCL_ON(udst_roi.setTo(val, umask_roi));
}
else
{
OCL_OFF(dst_roi.setTo(val));
OCL_ON(udst_roi.setTo(val));
}
OCL_EXPECT_MATS_NEAR(dst, 0);
}
}
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, ConvertTo, Combine(
OCL_ALL_DEPTHS, OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, CopyTo, Combine(
OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool(), Bool()));
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, SetTo, Combine(
OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool(), Bool()));
} } // namespace opencv_test::ocl
#endif

View File

@ -0,0 +1,318 @@
// 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.
#include "../test_precomp.hpp"
#include <opencv2/core/ocl.hpp>
namespace opencv_test { namespace {
static void testOpenCLKernel(cv::ocl::Kernel& k)
{
ASSERT_FALSE(k.empty());
cv::UMat src(cv::Size(4096, 2048), CV_8UC1, cv::Scalar::all(100));
cv::UMat dst(src.size(), CV_8UC1);
size_t globalSize[2] = {(size_t)src.cols, (size_t)src.rows};
size_t localSize[2] = {8, 8};
int64 kernel_time = k.args(
cv::ocl::KernelArg::ReadOnlyNoSize(src), // size is not used (similar to 'dst' size)
cv::ocl::KernelArg::WriteOnly(dst),
(int)5
).runProfiling(2, globalSize, localSize);
ASSERT_GE(kernel_time, (int64)0);
std::cout << "Kernel time: " << (kernel_time * 1e-6) << " ms" << std::endl;
cv::Mat res, reference(src.size(), CV_8UC1, cv::Scalar::all(105));
dst.copyTo(res);
EXPECT_EQ(0, cvtest::norm(reference, res, cv::NORM_INF));
}
TEST(OpenCL, support_binary_programs)
{
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
if (!ctx.ptr())
{
throw cvtest::SkipTestException("OpenCL is not available");
}
cv::ocl::Device device = cv::ocl::Device::getDefault();
if (!device.compilerAvailable())
{
throw cvtest::SkipTestException("OpenCL compiler is not available");
}
std::vector<char> program_binary_code;
cv::String module_name; // empty to disable OpenCL cache
{ // Generate program binary from OpenCL C source
static const char* opencl_kernel_src =
"__kernel void test_kernel(__global const uchar* src, int src_step, int src_offset,\n"
" __global uchar* dst, int dst_step, int dst_offset, int dst_rows, int dst_cols,\n"
" int c)\n"
"{\n"
" int x = get_global_id(0);\n"
" int y = get_global_id(1);\n"
" if (x < dst_cols && y < dst_rows)\n"
" {\n"
" int src_idx = y * src_step + x + src_offset;\n"
" int dst_idx = y * dst_step + x + dst_offset;\n"
" dst[dst_idx] = src[src_idx] + c;\n"
" }\n"
"}\n";
cv::ocl::ProgramSource src(module_name, "simple", opencl_kernel_src, "");
cv::String errmsg;
cv::ocl::Program program(src, "", errmsg);
ASSERT_TRUE(program.ptr() != NULL);
cv::ocl::Kernel k("test_kernel", program);
EXPECT_FALSE(k.empty());
program.getBinary(program_binary_code);
std::cout << "Program binary size: " << program_binary_code.size() << " bytes" << std::endl;
}
cv::ocl::Kernel k;
{ // Load program from binary (without sources)
ASSERT_FALSE(program_binary_code.empty());
cv::ocl::ProgramSource src = cv::ocl::ProgramSource::fromBinary(module_name, "simple_binary", (uchar*)&program_binary_code[0], program_binary_code.size(), "");
cv::String errmsg;
cv::ocl::Program program(src, "", errmsg);
ASSERT_TRUE(program.ptr() != NULL);
k.create("test_kernel", program);
}
testOpenCLKernel(k);
}
TEST(OpenCL, support_SPIR_programs)
{
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
if (!ctx.ptr())
{
throw cvtest::SkipTestException("OpenCL is not available");
}
cv::ocl::Device device = cv::ocl::Device::getDefault();
if (!device.isExtensionSupported("cl_khr_spir"))
{
throw cvtest::SkipTestException("'cl_khr_spir' extension is not supported by OpenCL device");
}
std::vector<char> program_binary_code;
cv::String fname = cv::format("test_kernel.spir%d", device.addressBits());
std::string full_path = cvtest::findDataFile(std::string("opencl/") + fname);
{
std::fstream f(full_path.c_str(), std::ios::in|std::ios::binary);
ASSERT_TRUE(f.is_open());
size_t pos = (size_t)f.tellg();
f.seekg(0, std::fstream::end);
size_t fileSize = (size_t)f.tellg();
std::cout << "Program SPIR size: " << fileSize << " bytes" << std::endl;
f.seekg(pos, std::fstream::beg);
program_binary_code.resize(fileSize);
f.read(&program_binary_code[0], fileSize);
ASSERT_FALSE(f.fail());
}
cv::String module_name; // empty to disable OpenCL cache
cv::ocl::Kernel k;
{ // Load program from SPIR format
ASSERT_FALSE(program_binary_code.empty());
cv::ocl::ProgramSource src = cv::ocl::ProgramSource::fromSPIR(module_name, "simple_spir", (uchar*)&program_binary_code[0], program_binary_code.size(), "");
cv::String errmsg;
cv::ocl::Program program(src, "", errmsg);
if (program.ptr() == NULL && device.isAMD())
{
// https://community.amd.com/t5/opencl/spir-support-in-new-drivers-lost/td-p/170165
throw cvtest::SkipTestException("Bypass AMD OpenCL runtime bug: 'cl_khr_spir' extension is declared, but it doesn't really work");
}
ASSERT_TRUE(program.ptr() != NULL);
k.create("test_kernel", program);
}
testOpenCLKernel(k);
}
TEST(OpenCL, image2Dcount_regression_19334)
{
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
if (!ctx.ptr())
{
throw cvtest::SkipTestException("OpenCL is not available");
}
cv::ocl::Device device = cv::ocl::Device::getDefault();
if (!device.compilerAvailable())
{
throw cvtest::SkipTestException("OpenCL compiler is not available");
}
std::string module_name; // empty to disable OpenCL cache
static const char* opencl_kernel_src =
"__kernel void test_kernel(int a,\n"
" __global const uchar* src0, int src0_step, int src0_offset, int src0_rows, int src0_cols,\n"
" __global const uchar* src1, int src1_step, int src1_offset, int src1_rows, int src1_cols,\n"
" __global const uchar* src2, int src2_step, int src2_offset, int src2_rows, int src2_cols,\n"
" __read_only image2d_t image)\n"
"{\n"
"}";
cv::ocl::ProgramSource src(module_name, "test_opencl_image_arg", opencl_kernel_src, "");
cv::String errmsg;
cv::ocl::Program program(src, "", errmsg);
ASSERT_TRUE(program.ptr() != NULL);
cv::ocl::Kernel k("test_kernel", program);
ASSERT_FALSE(k.empty());
std::vector<UMat> images(4);
for (size_t i = 0; i < images.size(); ++i)
images[i] = UMat(10, 10, CV_8UC1);
cv::ocl::Image2D image;
try
{
cv::ocl::Image2D image_(images.back());
image = image_;
}
catch (const cv::Exception&)
{
throw cvtest::SkipTestException("OpenCL images are not supported");
}
int nargs = 0;
int a = 0;
nargs = k.set(nargs, a);
ASSERT_EQ(1, nargs);
nargs = k.set(nargs, images[0]);
ASSERT_EQ(6, nargs);
nargs = k.set(nargs, images[1]);
ASSERT_EQ(11, nargs);
nargs = k.set(nargs, images[2]);
ASSERT_EQ(16, nargs);
// do not throw (issue of #19334)
ASSERT_NO_THROW(nargs = k.set(nargs, image));
ASSERT_EQ(17, nargs);
// allow to replace image argument if kernel is not running
UMat image2(10, 10, CV_8UC1);
ASSERT_NO_THROW(nargs = k.set(16, cv::ocl::Image2D(image2)));
ASSERT_EQ(17, nargs);
}
TEST(OpenCL, move_construct_assign)
{
cv::ocl::Context ctx1 = cv::ocl::Context::getDefault();
if (!ctx1.ptr())
{
throw cvtest::SkipTestException("OpenCL is not available");
}
void* const ctx_ptr = ctx1.ptr();
cv::ocl::Context ctx2(std::move(ctx1));
ASSERT_EQ(ctx1.ptr(), nullptr);
ASSERT_EQ(ctx2.ptr(), ctx_ptr);
cv::ocl::Context ctx3 = std::move(ctx2);
ASSERT_EQ(ctx2.ptr(), nullptr);
ASSERT_EQ(ctx3.ptr(), ctx_ptr);
cv::ocl::Platform pl1 = cv::ocl::Platform::getDefault();
void* const pl_ptr = pl1.ptr();
cv::ocl::Platform pl2(std::move(pl1));
ASSERT_EQ(pl1.ptr(), nullptr);
ASSERT_EQ(pl2.ptr(), pl_ptr);
cv::ocl::Platform pl3 = std::move(pl2);
ASSERT_EQ(pl2.ptr(), nullptr);
ASSERT_EQ(pl3.ptr(), pl_ptr);
std::vector<cv::ocl::PlatformInfo> platformInfos;
cv::ocl::getPlatfomsInfo(platformInfos);
const cv::String pi_name = platformInfos[0].name();
cv::ocl::PlatformInfo pinfo2(std::move(platformInfos[0]));
ASSERT_EQ(platformInfos[0].name(), cv::String());
ASSERT_EQ(pinfo2.name(), pi_name);
cv::ocl::PlatformInfo pinfo3 = std::move(pinfo2);
ASSERT_EQ(pinfo2.name(), cv::String());
ASSERT_EQ(pinfo3.name(), pi_name);
cv::ocl::Queue q1 = cv::ocl::Queue::getDefault();
void* const q_ptr = q1.ptr();
cv::ocl::Queue q2(std::move(q1));
ASSERT_EQ(q1.ptr(), nullptr);
ASSERT_EQ(q2.ptr(), q_ptr);
cv::ocl::Queue q3 = std::move(q2);
ASSERT_EQ(q2.ptr(), nullptr);
ASSERT_EQ(q3.ptr(), q_ptr);
cv::ocl::Device d1 = cv::ocl::Device::getDefault();
if (!d1.compilerAvailable())
{
throw cvtest::SkipTestException("OpenCL compiler is not available");
}
void* const d_ptr = d1.ptr();
cv::ocl::Device d2(std::move(d1));
ASSERT_EQ(d1.ptr(), nullptr);
ASSERT_EQ(d2.ptr(), d_ptr);
cv::ocl::Device d3 = std::move(d2);
ASSERT_EQ(d2.ptr(), nullptr);
ASSERT_EQ(d3.ptr(), d_ptr);
if (d3.imageSupport()) {
cv::UMat umat1 = cv::UMat::ones(640, 480, CV_32FC1);
cv::ocl::Image2D img1(umat1);
void *const img_ptr = img1.ptr();
cv::ocl::Image2D img2(std::move(img1));
ASSERT_EQ(img1.ptr(), nullptr);
ASSERT_EQ(img2.ptr(), img_ptr);
cv::ocl::Image2D img3 = std::move(img2);
ASSERT_EQ(img2.ptr(), nullptr);
ASSERT_EQ(img3.ptr(), img_ptr);
}
static const char* opencl_kernel_src =
"__kernel void test_kernel(__global const uchar* src, int src_step, int src_offset,\n"
" __global uchar* dst, int dst_step, int dst_offset, int dst_rows, int dst_cols,\n"
" int c)\n"
"{\n"
" int x = get_global_id(0);\n"
" int y = get_global_id(1);\n"
" if (x < dst_cols && y < dst_rows)\n"
" {\n"
" int src_idx = y * src_step + x + src_offset;\n"
" int dst_idx = y * dst_step + x + dst_offset;\n"
" dst[dst_idx] = src[src_idx] + c;\n"
" }\n"
"}\n";
cv::String module_name; // empty to disable OpenCL cache
cv::ocl::ProgramSource ps1(module_name, "move_construct_assign", opencl_kernel_src, "");
cv::ocl::ProgramSource::Impl* const ps_ptr = ps1.getImpl();
cv::ocl::ProgramSource ps2(std::move(ps1));
ASSERT_EQ(ps1.getImpl(), nullptr);
ASSERT_EQ(ps2.getImpl(), ps_ptr);
cv::ocl::ProgramSource ps3 = std::move(ps2);
ASSERT_EQ(ps2.getImpl(), nullptr);
ASSERT_EQ(ps3.getImpl(), ps_ptr);
cv::String errmsg;
cv::ocl::Program prog1(ps3, "", errmsg);
void* const prog_ptr = prog1.ptr();
ASSERT_NE(prog_ptr, nullptr);
cv::ocl::Program prog2(std::move(prog1));
ASSERT_EQ(prog1.ptr(), nullptr);
ASSERT_EQ(prog2.ptr(), prog_ptr);
cv::ocl::Program prog3 = std::move(prog2);
ASSERT_EQ(prog2.ptr(), nullptr);
ASSERT_EQ(prog3.ptr(), prog_ptr);
cv::ocl::Kernel k1("test_kernel", prog3);
void* const k_ptr = k1.ptr();
ASSERT_NE(k_ptr, nullptr);
cv::ocl::Kernel k2(std::move(k1));
ASSERT_EQ(k1.ptr(), nullptr);
ASSERT_EQ(k2.ptr(), k_ptr);
cv::ocl::Kernel k3 = std::move(k2);
ASSERT_EQ(k2.ptr(), nullptr);
ASSERT_EQ(k3.ptr(), k_ptr);
testOpenCLKernel(k3);
}
}} // namespace