Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/core/test/ocl/test_opencl.cpp
16339 views
1
// This file is part of OpenCV project.
2
// It is subject to the license terms in the LICENSE file found in the top-level directory
3
// of this distribution and at http://opencv.org/license.html.
4
#include "../test_precomp.hpp"
5
6
#include <opencv2/core/ocl.hpp>
7
8
namespace opencv_test { namespace {
9
10
static void testOpenCLKernel(cv::ocl::Kernel& k)
11
{
12
ASSERT_FALSE(k.empty());
13
cv::UMat src(cv::Size(4096, 2048), CV_8UC1, cv::Scalar::all(100));
14
cv::UMat dst(src.size(), CV_8UC1);
15
size_t globalSize[2] = {(size_t)src.cols, (size_t)src.rows};
16
size_t localSize[2] = {8, 8};
17
int64 kernel_time = k.args(
18
cv::ocl::KernelArg::ReadOnlyNoSize(src), // size is not used (similar to 'dst' size)
19
cv::ocl::KernelArg::WriteOnly(dst),
20
(int)5
21
).runProfiling(2, globalSize, localSize);
22
ASSERT_GE(kernel_time, (int64)0);
23
std::cout << "Kernel time: " << (kernel_time * 1e-6) << " ms" << std::endl;
24
cv::Mat res, reference(src.size(), CV_8UC1, cv::Scalar::all(105));
25
dst.copyTo(res);
26
EXPECT_EQ(0, cvtest::norm(reference, res, cv::NORM_INF));
27
}
28
29
TEST(OpenCL, support_binary_programs)
30
{
31
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
32
if (!ctx.ptr())
33
{
34
throw cvtest::SkipTestException("OpenCL is not available");
35
}
36
cv::ocl::Device device = cv::ocl::Device::getDefault();
37
if (!device.compilerAvailable())
38
{
39
throw cvtest::SkipTestException("OpenCL compiler is not available");
40
}
41
std::vector<char> program_binary_code;
42
43
cv::String module_name; // empty to disable OpenCL cache
44
45
{ // Generate program binary from OpenCL C source
46
static const char* opencl_kernel_src =
47
"__kernel void test_kernel(__global const uchar* src, int src_step, int src_offset,\n"
48
" __global uchar* dst, int dst_step, int dst_offset, int dst_rows, int dst_cols,\n"
49
" int c)\n"
50
"{\n"
51
" int x = get_global_id(0);\n"
52
" int y = get_global_id(1);\n"
53
" if (x < dst_cols && y < dst_rows)\n"
54
" {\n"
55
" int src_idx = y * src_step + x + src_offset;\n"
56
" int dst_idx = y * dst_step + x + dst_offset;\n"
57
" dst[dst_idx] = src[src_idx] + c;\n"
58
" }\n"
59
"}\n";
60
cv::ocl::ProgramSource src(module_name, "simple", opencl_kernel_src, "");
61
cv::String errmsg;
62
cv::ocl::Program program(src, "", errmsg);
63
ASSERT_TRUE(program.ptr() != NULL);
64
cv::ocl::Kernel k("test_kernel", program);
65
EXPECT_FALSE(k.empty());
66
program.getBinary(program_binary_code);
67
std::cout << "Program binary size: " << program_binary_code.size() << " bytes" << std::endl;
68
}
69
70
cv::ocl::Kernel k;
71
72
{ // Load program from binary (without sources)
73
ASSERT_FALSE(program_binary_code.empty());
74
cv::ocl::ProgramSource src = cv::ocl::ProgramSource::fromBinary(module_name, "simple_binary", (uchar*)&program_binary_code[0], program_binary_code.size(), "");
75
cv::String errmsg;
76
cv::ocl::Program program(src, "", errmsg);
77
ASSERT_TRUE(program.ptr() != NULL);
78
k.create("test_kernel", program);
79
}
80
81
testOpenCLKernel(k);
82
}
83
84
85
TEST(OpenCL, support_SPIR_programs)
86
{
87
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
88
if (!ctx.ptr())
89
{
90
throw cvtest::SkipTestException("OpenCL is not available");
91
}
92
cv::ocl::Device device = cv::ocl::Device::getDefault();
93
if (!device.isExtensionSupported("cl_khr_spir"))
94
{
95
throw cvtest::SkipTestException("'cl_khr_spir' extension is not supported by OpenCL device");
96
}
97
std::vector<char> program_binary_code;
98
cv::String fname = cv::format("test_kernel.spir%d", device.addressBits());
99
std::string full_path = cvtest::findDataFile(std::string("opencl/") + fname);
100
101
{
102
std::fstream f(full_path.c_str(), std::ios::in|std::ios::binary);
103
ASSERT_TRUE(f.is_open());
104
size_t pos = (size_t)f.tellg();
105
f.seekg(0, std::fstream::end);
106
size_t fileSize = (size_t)f.tellg();
107
std::cout << "Program SPIR size: " << fileSize << " bytes" << std::endl;
108
f.seekg(pos, std::fstream::beg);
109
program_binary_code.resize(fileSize);
110
f.read(&program_binary_code[0], fileSize);
111
ASSERT_FALSE(f.fail());
112
}
113
114
cv::String module_name; // empty to disable OpenCL cache
115
116
cv::ocl::Kernel k;
117
118
{ // Load program from SPIR format
119
ASSERT_FALSE(program_binary_code.empty());
120
cv::ocl::ProgramSource src = cv::ocl::ProgramSource::fromSPIR(module_name, "simple_spir", (uchar*)&program_binary_code[0], program_binary_code.size(), "");
121
cv::String errmsg;
122
cv::ocl::Program program(src, "", errmsg);
123
ASSERT_TRUE(program.ptr() != NULL);
124
k.create("test_kernel", program);
125
}
126
127
testOpenCLKernel(k);
128
}
129
130
}} // namespace
131
132