Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transfer data from Mat/oclMat to cl_mem (OpenCV + OpenCL)

Tags:

opencv

opencl

I am working on a project that needs a lot of OpenCL code. I am using OpenCV's ocl module to develop my project faster but there are some functions not implemented and I will have to write my own OpenCL code.

My question is this: what is the quickest and cheapest way to transfer data from Mat and/or oclMat to a cl_mem array. Re-wording this, is there a good way to transfer or enqueue (clEnqueueWriteBuffer) data from oclMat or Mat?

Currently, I am using a for-loop to read data from Mat (or download from oclMat and then use for-loops) and then enqueuing it. This is turning out to be costly, hence my question.

Thanks to anyone who sees this question :)

like image 753
ponderingfish Avatar asked Jan 25 '14 21:01

ponderingfish


3 Answers

I've written a set of interop functions for the Boost.Compute library which ease the use of OpenCL and OpenCV. Take a look at the opencv_copy_mat_to_buffer() function.

There are also functions for copying from a OpenCL buffer back to the host cv::Mat and for copying cv::Mat to OpenCL image2d objects.

like image 152
Kyle Lutz Avatar answered Nov 10 '22 05:11

Kyle Lutz


Calculate memory bandwidth, achieved in Host-Device interconnections.

If you get ~60% and more of maximal bandwidth, you've nothing to do, memory transfer is as fast as it can be. But if your bandwidth results are lower that 55% - 60% of theoretical maximum, try to use multiple command queues with unblocking operations (don't forget to sync at the end). Also, pay attention on avg image size. Small data transfers usually have big overhead rate.

If your Device uses shared memory, use memory mapping instead of read/write, this may dramatically save time. If Device has it's own memory, apply pinned memory technique, which is well described in NVIDIA OpenCL Best Practices Guide.

like image 26
Roman Arzumanyan Avatar answered Nov 10 '22 05:11

Roman Arzumanyan


The documentation of oclMat states that there is some sort of functionality to the underlying ocl buffer data:

//! pointer to the data(OCL memory object)
uchar *data;

If you have clMat already in the device, you can simply perform a copy buffer from clMat.data to your clBuffer. But you will have to hack a little bit the memory, accessing some private members of the oclMat

Something like:

clEnqueueCopyBuffer(command_queue, (clBuffer *)oclMat.data, dst_buffer, 0, 0, size);

NOTE: Take care with the casting, maybe you have to cast another pointer.

like image 23
DarkZeros Avatar answered Nov 10 '22 06:11

DarkZeros