How to disable parallelism in OpenCV? - c++

I've built OpenCV using Intel IPP, so I suppose that whenever possible it's used (e.g. matrix multiplication).
I want to test the scalability of my parallel application by comparing it with a serial version. In order to do so, when it I do:
omp_set_num_threads(1);
cv::setNumThreads(1);
However, by monitoring the CPU usage I see that multiple CPUs are still used. Why is that? And how can I force the program execution by using just one CPU?

Re-building OpenCV from source with following CMake parameters should works:
cmake .. -DWITH_IPP=OFF -DWITH_TBB=OFF -DWITH_OPENMP=OFF -DWITH_PTHREADS_PF=OFF
and you will find the macro CV_PARALLEL_FRAMEWORK is not defined to something in modules/core/src/parallel.cpp any more:
#if defined HAVE_TBB
# define CV_PARALLEL_FRAMEWORK "tbb"
#elif defined HAVE_HPX
# define CV_PARALLEL_FRAMEWORK "hpx"
#elif defined HAVE_OPENMP
# define CV_PARALLEL_FRAMEWORK "openmp"
#elif defined HAVE_GCD
# define CV_PARALLEL_FRAMEWORK "gcd"
#elif defined WINRT
# define CV_PARALLEL_FRAMEWORK "winrt-concurrency"
#elif defined HAVE_CONCURRENCY
# define CV_PARALLEL_FRAMEWORK "ms-concurrency"
#elif defined HAVE_PTHREADS_PF
# define CV_PARALLEL_FRAMEWORK "pthreads"
#endif

You can disable it with:
cv::setNumThreads(0);
OpenCV will try to set the number of threads for the next parallel region.If threads == 0, OpenCV will disable threading optimizations and run all it's
functions sequentially. Passing threads < 0 will reset threads number to system
default. This function must be called outside of parallel region.
https://docs.opencv.org/4.5.1/db/de0/group__core__utils.html

add ippSetNumThreads(1); before the first IPP call in your code. This should set number of OpenMP threads in IPP to 1. More info can be found here in the "Controlling OpenMP Threading in the Intel IPP Primitives" section

Are you using opencv from multi threads ? You have to disable opencv's multi threading from each thread, atleast in my experience with it.
Opencv' parallel_for functions creates multiple threads to distribute the work across.

Related

Two versions of a code based on a #define

I'm working with a microcontroller and writing in C/C++ and I want to separate stuff that's supposed to work only in the transmissor and stuff that will work for the receiver. For this I thought about having a #define DEVICE 0 being 0 for transmissor and 1 for receiver.
How would I use this define to cancel other defines? I have multiple defines that should only work on one of the devices.
You have the following directives:
#if (DEVICE == 0)
...
#else
...
#endif
To be sure the code will be exclusive.
Although I recommended to do it dynamically: you can have a boolean global attribute/function parameter and execute code according to its value.
The code will be optimized-out on a certain target (even with the lowest optimization setting).
One compilation will be enough to check compilation errors instead of 2 with a define change.
Bear in mind you will still need a define for the boolean value to be changed and so test every case, but this can be done automatically with any Dynamic code analysis, while not possible with a #define implementation.

Exclude parts from compilation - still syntax-check

We have a pretty large project here in C++/.NET/Visual Studio, for performance testing we incuded some code that makes it possible to evaluate the execution time between certain points.
PERFORMANCE_TEST BeginMeasureTime("execute someCode")
someCode
PERFORMANCE_TEST EndMeasureTime("execute someCode")
Usually while developing the PERFORMANCE_TEST macro would be set to // so the evaluation code is switched off. So if code / interfaces etc. change and the code after the PERFORMANCE_TEST macro becomes invalid, the developer will not notice that.
Is there any smarter way to have the performance evaluation code only built in a special version of the project but still make sure that it stays consistent? How would you normally do something like that?
One easy way would be to change
PERFORMANCE_TEST xxx
to
PERFORMANCE_TEST(xxx)
Then instead of
#if PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST
#else
#define PERFORMANCE_TEST //
#endif
you could have
#if PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST(x) {x;}
#else
#define PERFORMANCE_TEST(x) if(0) { x; }
#endif
An optimizing compiler should generate no code for the second version if performance tests are disabled (or at the very least it'll not branch on the if), but it'll still be part of the compilation.
Alternatively, if build times aren't a huge concern you could simply always build both versions into separate directories.
It's been a while since I did something like this the following should be what you want. If the MACRO is defined then the function is included, else it the function is a noop and compiled out the code.
#ifdef MACRO
#define MACRO_NAME(arg1, arg2, ...) [code to expand to]
#else
#define MACRO_NAME(arg1, arg2, ...) noop
#endif
Update:
Ok so I slightly got the question a bit incorrect.
Most static analysis tools can be configured to scan certain #defines
CPPCheck for example can be given the following arguments.
-D<ID> Define preprocessor symbol. Unless --max-configs or
--force is used, Cppcheck will only check the given
configuration when -D is used.
Example: '-DDEBUG=1 -D__cplusplus'.
So you can then scan the code twice, thus achieving your goal.
I would say this is the best of both before you can add more scans if you add more #define
Or you can use some of the following to scan more configurations.
-f, --force Force checking of all configurations in files. If used
together with '--max-configs=', the last option is the
one that is effective.
and
--max-configs=<limit>
Maximum number of configurations to check in a file
before skipping it. Default is '12'. If used together
with '--force', the last option is the one that is
effective.
We used this type of operation at a previous company, we build code for WIN32, Pocket PC and WM5 and WM6 all from the same code base but had static checking on all build configurations. But the end result was the removal of non redundant code in all builds.

Can I do conditional selection of USE statements using preprocessor directives which rely on data from a file interface/header file in Fortran?

I would like to use different libraries in my fortran code (I am using intel fortran compiler as well) depending on which version of MKL is available at compile time. There is a file interface included with an install of MKL which defines preprocessor macros for version numbers and build date - /opt/intel/mkl/include/mkl.fi
I thought the flow would be as follows:
Get version number of MKL from file interface mentioned above
Use the version number to decide which library to use via preprocessor directives
execute use statement to compile with correct library
If I place any use statements after an include statement, however, the compilation aborts after throwing error #6278: This USE statement is not positioned correctly within the scoping unit.
Is there any way to achieve conditional selection of use statements using preprocessor directives which rely on information from a file interface or header file?
I cannot see how it is possible, because any use statements have to be before the include statement which provides the data required to decide which use statement to execute. I have included below a sample which demonstrates what I'm trying to do, but will not work·
module MKLVersion
!Test for definition and value up here
#ifdef INTEL_MKL_VERSION
#if INTEL_MKL_VERSION >= 110200
use LAPACK95, only : ggevx, geevx, sygvd
#elif INTEL_MKL_VERSION < 110200
use MKL95_LAPACK, only : ggevx, geevx, sygvd
#endif
#endif
! but dont actually get the definition till we get here
include '/opt/intel/mkl/include/mkl.fi'
end module MKLVersion
The short answer to this question is, ultimately, no - as Steve Lionel pointed out, the included file had INTERFACE statements, which cannot come before a USE statement.
However, I found a solution for my particular use case, which enables compilation of code with both old and new MKL versions. According to this intel article from 2009, there is a way to call libraries which will work with older version of MKL:
Notes:
* f95_precision.mod, mkl95_lapack.mod and mkl95_precision.mod files will be removed in one of the future releases. The current version supports two USE statements - so you can choose or "USE MKL95_LAPACK" or " USE LAPACK95 ". For the future compatibility we recommend using "USE LAPACK95" statement.
So USE MKL95_LAPACK can be replaced with USE LAPACK95 without breaking everything, which is good.

'pthread_setname_np' was not declared in this scope

I have created multiple threads in my application. I want to assign a name to each pthread so I used pthread_setname_np which worked on Ubuntu but is not working on SUSE Linux.
I googled it and came to know '_np' means 'non portable' and this api is not available on all OS flavors of Linux.
So now I want to do it only if the API is available. How to determine whether the api is available or not ? I need something like this.
#ifdef SOME_MACRO
pthread_setname_np(tid, "someName");
#endif
You can use the feature_test_macro _GNU_SOURCE to check if this function might be available:
#ifdef _GNU_SOURCE
pthread_setname_np(tid, "someName");
#endif
But the manual states that the pthread_setname_np and pthread_getname_np are introduced in glibc 2.12. So if you are using an older glibc (say 2.5) then defining _GNU_SOURCE will not help.
So it's best to avoid these non portable function and you can easily name the threads yourself as part of your thread creation, for example, using a map between thread ID and a array such as:
pthread_t tid[128];
char thr_names[128][256]; //each name corresponds to on thread in 'tid'
You can check the glibc version using:
getconf GNU_LIBC_VERSION
Since this function was introduced in glibc 2.12, you could use:
#if ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12)))
pthread_setname_np(tid, "someName");
#endif
This kind of thing - finding out if a particular function exists in your compilation environment - is what people use GNU Autoconf scripts for.
If your project is already using autoconf, you can add this to your configure source, after the point where you have checked for the pthreads compiler and linker flags:
AC_CHECK_FUNCS(pthread_setname_np)
...and it will define a macro HAVE_PTHREAD_SETNAME_NP if the function exists.

Declaring the Unix flavour in C/C++

How do I declare in C/C++ that the code that is written is to be built in either HP-UX or Solaris or AIX?
I found that, a good way to figure this king of question, is, at least with gcc, to have this makefile:
defs:
g++ -E -dM - < /dev/null
then, :
$ make defs
should output all the definitions you have available.
So:
$ make defs | grep -i AIX
$ make defs | grep -i HP
should give you the answer. Example for Linux:
$ make defs | grep -i LINUX
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define linux 1
Once you found the define you are looking for, you type at the beginning of your code:
#if !(defined(HP_DEFINE) || defined(AIX_DEFINE) || defined(SOLARIS_DEFINE))
# error This file cannot be compiled for your plateform
#endif
How about a macro passed to the compiler ?
i.e. gcc -Dmacro[=defn]
Then test for the macro in your code with a simple #ifdef of #if (if you've given it a value). There may already be a predefined macro for your target platform as well.
[EDIT: Put some of my comments here in my answer that explain how -D works]
-Dmacro[=defn] on the command line for the compiler is the same as having #define macro defn in the code. You expand it out like this: -Dfoo=bar is equivalent to #define foo bar. Also, the definition is optional so -Dfoo is equivalent to #define foo.
Be careful about how you handle this. You should identify the features of the O/S that you want to use by feature, not by O/S, and write your code accordingly. Then, in one header, you can identify which of the features are available on the O/S that you are compiling on. This is the technique used by autoconf, and even if you do not use autoconf itself, the technique it espouses is better than the platform-based technique. Remember, the features found on one O/S often migrate and become available on others too, so if you work by features, you can adapt to the future more easily than if you work solely on the O/S.
You also have to write your code appropriately, and portably. Isolate the O/S dependencies in separate files whenever possible, and code to an abstract O/S interface that does what you need. Taken to an extreme, you end up with a Java JVM; you don't need to go that far, but you can obviate most of the problems.
Take a look at portable libraries like the Apache Portable Runtime (APR) library.
And write your code along the lines of:
#ifdef HAVE_PWRITE
...code using pread() and pwrite()...
#else
...code using plain old read() and write()...
#endif
This is a grossly over-simplified example - there could be a number of fallbacks before you use plain read() and write(). Nevertheless, this is the concept used in the most portable code - things like GCC and Apache and so on.
Perhaps a less convoluted solution that some of those suggested is to consult Pre-defined C/C++ Compiler Macros. This site provides an extensive list of compiler macros for a large number of compiler/OS/Architecture combinations.