I'm probably misusing OpenCV by using it as wrapper to the official OpenCL C++ bindings so that I can launch my own kernels.
However, OpenCV does have classes like Program, ProgramSource, Kernel, Queue, etc. that seem to tell me that I can launch my own (even non-image-based) kernels with OpenCV. I am having trouble finding documentation out there for these classes, let alone examples. So, I took a stab at it so far:
#include <fstream>
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/core/ocl.hpp"
#define ARRAY_SIZE 128
using namespace std;
using namespace cv;
int main(int, char)
{
std::ifstream file("kernels.cl");
std::string kcode(std::istreambuf_iterator<char>(file),
(std::istreambuf_iterator<char>()));
cv::ocl::ProgramSource * programSource;
programSource = new cv::ocl::ProgramSource(kcode.c_str());
cv::String errorMessage;
cv::ocl::Program * program;
program = new cv::ocl::Program(*programSource, NULL, errorMessage);
cv::ocl::Kernel * kernel;
kernel = new cv::ocl::Kernel("simple_add", *program);
/* I'm stuck here at the args. */
size_t globalSize[2] = { ARRAY_SIZE, 1 };
size_t localSize[2] = { ARRAY_SIZE, 1 };
kernel->run(ARRAY_SIZE, globalSize, localSize, true);
return 0;
}
Note that I haven't set up my host variables yet. I'm stuck at kernel->args(...). There are 15 overloads and none of them specify what order I should specify the following, per argument:
- The parameter index, so I manually match the parameter in the order given in the kernel.
- The host variable itself.
- The host variable's array size - typically I say something like
sizeof(int) * ARRAY_SIZE, though I used to specify that on the clEnqueueWriteBuffer function in plain OpenCL. - Device buffer memory access, for example CL_MEM_READ_ONLY
It doesn't look like I call enqueueWriteBufer(...), enqueueNDRangeKernel(...), or enqueueReadBuffer(...) because (I guess) the kernel->run() does all of that for me under the hood. I assume that kernel->run() will write the new values to my output parameter.
I didn't specify a command queue, device, or context. I think that there is only one command queue and one context, and the default device - all created under-the-hood and are accessible from these classes.
So again, how do I use the args function of the kernel?