Skip to content

Commit 15b909e

Browse files
committed
ocl: add SPIR Program loading test
SPIR kernels are located in opencv_extra
1 parent a82d236 commit 15b909e

File tree

1 file changed

+66
-16
lines changed

1 file changed

+66
-16
lines changed

modules/core/test/ocl/test_opencl.cpp

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,29 @@
44
#include "../test_precomp.hpp"
55

66
#include <opencv2/core/ocl.hpp>
7+
#include <fstream>
78

89
namespace opencv_test { namespace {
910

11+
static void testOpenCLKernel(cv::ocl::Kernel& k)
12+
{
13+
ASSERT_FALSE(k.empty());
14+
cv::UMat src(cv::Size(4096, 2048), CV_8UC1, cv::Scalar::all(100));
15+
cv::UMat dst(src.size(), CV_8UC1);
16+
size_t globalSize[2] = {(size_t)src.cols, (size_t)src.rows};
17+
size_t localSize[2] = {8, 8};
18+
int64 kernel_time = k.args(
19+
cv::ocl::KernelArg::ReadOnlyNoSize(src), // size is not used (similar to 'dst' size)
20+
cv::ocl::KernelArg::WriteOnly(dst),
21+
(int)5
22+
).runProfiling(2, globalSize, localSize);
23+
ASSERT_GE(kernel_time, (int64)0);
24+
std::cout << "Kernel time: " << (kernel_time * 1e-6) << " ms" << std::endl;
25+
cv::Mat res, reference(src.size(), CV_8UC1, cv::Scalar::all(105));
26+
dst.copyTo(res);
27+
EXPECT_EQ(0, cvtest::norm(reference, res, cv::NORM_INF));
28+
}
29+
1030
TEST(OpenCL, support_binary_programs)
1131
{
1232
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
@@ -59,23 +79,53 @@ TEST(OpenCL, support_binary_programs)
5979
k.create("test_kernel", program);
6080
}
6181

62-
{ // Run kernel
63-
ASSERT_FALSE(k.empty());
64-
cv::UMat src(cv::Size(4096, 2048), CV_8UC1, cv::Scalar::all(100));
65-
cv::UMat dst(src.size(), CV_8UC1);
66-
size_t globalSize[2] = {(size_t)src.cols, (size_t)src.rows};
67-
size_t localSize[2] = {8, 8};
68-
int64 kernel_time = k.args(
69-
cv::ocl::KernelArg::ReadOnlyNoSize(src), // size is not used (similar to 'dst' size)
70-
cv::ocl::KernelArg::WriteOnly(dst),
71-
(int)5
72-
).runProfiling(2, globalSize, localSize);
73-
ASSERT_GE(kernel_time, (int64)0);
74-
std::cout << "Kernel time: " << (kernel_time * 1e-6) << " ms" << std::endl;
75-
cv::Mat res, reference(src.size(), CV_8UC1, cv::Scalar::all(105));
76-
dst.copyTo(res);
77-
EXPECT_EQ(0, cvtest::norm(reference, res, cv::NORM_INF));
82+
testOpenCLKernel(k);
83+
}
84+
85+
86+
TEST(OpenCL, support_SPIR_programs)
87+
{
88+
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
89+
if (!ctx.ptr())
90+
{
91+
throw cvtest::SkipTestException("OpenCL is not available");
92+
}
93+
cv::ocl::Device device = cv::ocl::Device::getDefault();
94+
if (!device.isExtensionSupported("cl_khr_spir"))
95+
{
96+
throw cvtest::SkipTestException("'cl_khr_spir' extension is not supported by OpenCL device");
97+
}
98+
std::vector<char> program_binary_code;
99+
cv::String fname = cv::format("test_kernel.spir%d", device.addressBits());
100+
std::string full_path = cvtest::findDataFile(std::string("opencl/") + fname);
101+
102+
{
103+
std::fstream f(full_path.c_str(), std::ios::in|std::ios::binary);
104+
ASSERT_TRUE(f.is_open());
105+
size_t pos = (size_t)f.tellg();
106+
f.seekg(0, std::fstream::end);
107+
size_t fileSize = (size_t)f.tellg();
108+
std::cout << "Program SPIR size: " << fileSize << " bytes" << std::endl;
109+
f.seekg(pos, std::fstream::beg);
110+
program_binary_code.resize(fileSize);
111+
f.read(&program_binary_code[0], fileSize);
112+
ASSERT_FALSE(f.fail());
78113
}
114+
115+
cv::String module_name; // empty to disable OpenCL cache
116+
117+
cv::ocl::Kernel k;
118+
119+
{ // Load program from SPIR format
120+
ASSERT_FALSE(program_binary_code.empty());
121+
cv::ocl::ProgramSource src = cv::ocl::ProgramSource::fromSPIR(module_name, "simple_spir", (uchar*)&program_binary_code[0], program_binary_code.size(), "");
122+
cv::String errmsg;
123+
cv::ocl::Program program(src, "", errmsg);
124+
ASSERT_TRUE(program.ptr() != NULL);
125+
k.create("test_kernel", program);
126+
}
127+
128+
testOpenCLKernel(k);
79129
}
80130

81131
}} // namespace

0 commit comments

Comments
 (0)