What is the macro CV_OCL_RUN used for in OpenCV? - c++

I was learning hog.cpp implemented in OpenCV, when encountered the macro CV_OCL_RUN and confused with it.
In hog.cpp where detectMultiScale() locates, you can find CV_OCL_RUN and a method called ocl_detectMultiScale() in it. Compared between detectMultiScale() and ocl_detectMultiScale(), not only their names but their implement are quite similar.
Here are my questions:
What is the macro CV_OCL_RUN used for? Does it for test or other purpose?
Since detectMultiScale() and ocl_detectMultiScale() are so similar in functionality, why the later is embedded in the former ? What ways are they called in?
Thanks in advance!

CV_OCL_RUN is for OpenCL code.
If your computer is not able to use OpenCL capabilities (no GPU or no OpenCL driver), regular code (CPU) is run. You can also switch between regular code or use OpenCL version in the code. If setUseOptimized() or setUseOpenCL() is set to false, regular code will be used.
You can find in the opencl directory the kernel code which will be run on the GPU device.
PS: OpenCL is not only for GPU.

Related

No performance gain with OpenCV 3.2 on OpenCL (TAPI)

Absolute TAPI beginner here. I recently ported my CV code to make use of UMat intstead of Mat since my CPU was on it's limit, especially morphologic operations seemed to consume quite some computing power.
Now with UMat I cannot see any changes in my framerate, it is exactly the same no matter if I use UMat or not, also Process Explorer reports no GPU usage whatsoever. I did a small test with a few calls of dilation and closing on a full HD image -- no effect.
Am I missing something here? I'm using the latest OpenCV 3.2 build for Windows and a GTX 980 with driver 378.49. cv::ocl::haveOpenCL() and cv::ocl::useOpenCL() both return true and cv::ocl::Context::getDefault().device( 0 ) also gives me the correct device, everything looks good as far as I can tell. Also, I'm using some custom CL code via cv::ocl::Kernel which is definitely invoked.
I realize it is a naive way of thinking that just changing Mat to UMat will result in huge performance gain (although every of the the very limited number of ressources covering TAPI I find online suggests exactly that). Still, I was hoping to get some gain for starters and then further optimize step-by-step from there. However, the fact that I can't discover any GPU usage whatsoever highliy irritates me.
Is there something I have to watch out for? Maybe my usage of TAPI prevents from a streamlined execution of OpenCL code, maybe by accidental/hidden readbacks I'm not aware of? Do you see any way of profiling the code with respect to that matter?
Are there any how-to's, best practices or common pitfalls for using TAPI? Things like "don't use local UMat instances within functions", "use getUMat() instead of copyTo()", "avoid calls of function x since it will cause a cv::ocl::flush()", things of that sort?
Are there OpenCV operations that are not ported to OpenCL yet? Is there documentation accordingly? In the OpenCV source code I saw that, if built with HAVE_OPENCL flat, the functions try to run CL code using the CV_OCL_RUN macro, however there are a few conditions checked beforehand, otherwise it falls back to CPU. It does not seem like I have any possitility to figure out if the GPU or the CPU was actually used apart from stepping into each and every OpenCL function with the debugger, am I right?
Any ideas/experiences apart from that? I'd appreciate any input that relates to this matter.

How to compile OpenCL Kernel file(.cl) to llvm IR file

How do I obtain an LLVM-IR file(.ll) from OpenCL Kernel file with clang?
The solution in this link seems working with some files, but for the codes which contains OpenCL vector types such as uchar4, seems not working (emitting type errors).
Is there an easy way to do this or is it not possible to gain LLVM-IR form with clang?
At least on OS X, there's an LLVM-based offline compiler for OpenCL kernels, you can find it in the following location:
/System/Library/Frameworks/OpenCL.framework/Libraries/openclc
(It supports the --help command line argument showing you the possible options.)
I'm not aware of any published source code for openclc so I guess that means you can't use it on other platforms, but as far as I'm aware, there's no standardised binary format for OpenCL kernels anyway, so you couldn't achieve platform independence with it.

Use CPU fallback if OpenCV's Cuda extensions are not available

In my code I'm trying to capitalize the power of a possibly present cuda capable GPU. While this code works well on computers that have cuda available (and where OpenCV was compiled with cuda support), I have troubles implementing a fallback to CPU. Even building fails, since the imports I'm using
#include "opencv2/core/cuda.hpp"
#include "opencv2/cudaimgproc.hpp"
#include "opencv2/cudaarithm.hpp"
are not found. I'm quite a novice regarding C++ program architecture. How would I need to model my code to support such a fallback functionality?
If you are implementing a fallback you probably want to switch to it at runtime. But the fact that you are getting compiler error messages suggests that you are compiling with different flags. In general, you probably want something like this:
if (HasCuda()) {
RunCudaCode(...);
} else {
RunCpuCode(...);
}
Alternatively, you could build two shared libraries one with and one without Cuda and load the one that you need based on HasCuda(). However, that approach only makes sense if your binary is huge and you're running into memory issues.
It might be necessary to have a similar block in your startup code that initializes Cuda.

Is it possible to convert mex code to C++ code?

I have written some mex (c++) code, i have used mxArrays, and few other Matlab functions, i am wondering is it possible to convert it to C++ code easily by including the appropriate header and making some minor changes ?
edit:
By "convert", i mean that i want to compile and run my code without relying (using) on matlab.
As mentioned in the comments above, making this work depends greatly on the nature of the MATLAB functions you are using. Since you have successfully ported much of your MATLAB code to C++, I suggest you continue doing so until you are no longer reliant on the MATLAB libraries to build.
Are there any toolbox functions you are relying on? If so this may be a bigger task than you realize.
Good luck!
You can make executable by using SimulinkCoder - so you can run it without Matlab ... but you still must use Matlab to make executable every time you make change in the code.
Make basic Simulink model with single S-function block in which you specify your mex file.
Use SimulinkCoder (Real Time Workshop) to make executable out of the Simulink model.

Matlab to C or C++

I am working on an image processing project using Matlab. We should run our program (intended to be an application) on a cell phone.We were then asked to convert our code into C or C++ language so we get a feel of how long it would take for execution and then choose a platform. So far we didn't figure out how to do this conversion.. Any ideas of what to do to convert Matlab to C or C++??
The first thing you need to realise is that porting code from one language to another (especially languages as different as Matlab and C++) is generally non-trivial and time-consuming. You need to know both languages well, and you need to have similar facilities available in both. In the case of Matlab and C++, Matlab gives you a lot of stuff that you just won't have available in C++ without using libraries. So the first thing to do is identify which libraries you're going to need to use in C++. (You can write some of the stuff yourself, but you'll be there a long time if you write all of it yourself.)
If you're doing image processing, I highly recommend looking into something like ITK at http://www.itk.org -- I've written my image processing software twice in C++, once without ITK (coding everything myself) and once with, and the version that used ITK was finished faster, performed better and was ten times more fun to work on. FWIW.
Matlab can gererate C code for you.
See:
http://www.mathworks.com/products/featured/embeddedmatlab/
The generated code does however depend on matlab libraries. So you probably can't use it for a cell phone. But it might save you some time anyways.
I also used the MATLAB Coder to convert some functions consisting of a few hundred lines of MATLAB into C. This included using MATLAB's eigenvalue solver and matrix inversion functions.
Although Coder was able to produce C code (which theoretically was identical), it was very convoluted, bloated, impossible to decipher, and appeared to be extremely inefficient. It literally created about 10x as many lines of code as it should have needed. I ended up converting it all by hand so that I would actually be able to comprehend the C code later and make further changes/updates. This task however, can be very tedious/dangerous, as the array indexing in Matlab is 1-based and in C it's 0-based. You're likely to add bugs into the code, as I experienced. you'll also have to convert any vector/matrix arithmetic into loops that handle scalars (or use some type of C matrix algebra package)
The MathWorks provides a product called MATLAB Coder that claims to generate "readable and portable C and C++ code from MATLABĀ® code". I haven't tried it myself, so I can't comment on how well it accomplishes these goals.
With regard to the Image Processing Toolbox, this list (presumably for R2016b) shows which functions have been enabled for code generation and any limitations they may have.
Matlab has a tool called "Matlab Coder" which can convert your matlab file to C code or mex file. My code is relatively simple so it works fine. Speed up gain is about 10 times faster. This saves me time coding a few hundreds lines. Hope it's helpful for you too
Quick Start Guide for MATLAB Coder Confirmation
The links describe the process of converting your code in 3 major steps:
First you need to make a few simplifications in your present code so that it would be simple enough for the Coder to translate.
Second, you will use the tool to generate a mex file and test if everything is actually working.
Finally you would change some setting and generate the C code. In my case, the C code has about 700 lines including all the original matlab code (about 150 lines) as comments. I think it's quite readable and could be improve upon. However, I already get a 10 times speed up gain from the mex file anyway. So this is definitely a good thing.
We can't not be sure that this will work in all case but it's definitely worth trying.
I remember there is a tool to export m-files as c(++)-files. But I could never get that running. You need to add some obscure MATLAB-headers in the c/c++code, ... And I think it is also not recommended.
If you have running MATLAB-code, it shouldn't take too much effort to do the conversion "by hand". I have been working on several project where MATLAB was used and it was never consider to use any tools to convert the code to C/C++. It was always done "by hand".
I believe to have been the only one who ever investigate into using a tool.
Well there is not straight conversion from matlab to c/c++ You will need to understand the language and the differences between matlab and c/c++ and then start coding it in c/c++. Code a little test a little until it works.