3

I have C/C++ source files written with OMP instrumentation. For example, in a C++ class file:

#pragma omp parallel sections
{
    #pragma omp section
        cp = ModularSquareRoot(cp, m_p);
    #pragma omp section
        cq = ModularSquareRoot(cq, m_q);
}

For benchmarking and testing, I want to build the library with -fopenmp but disable it on this particular class file. I hope I can add something like #pragma omp disable or similar in the class's header file to disable it for the translation unit. But #pragma omp disable was silently ignored.

I've looked through Using OpenMP: Portable Shared Memory Parallel Programming, but I have not seen how to do it. (I could well be missing it because I have not read it completely).

I'm trying to avoid modifying CXXFLAGS, makefile recipes and Visual Studio project settings.

Is there a way to disable OMP in a particular translation unit at the source file?

jww
  • 97,681
  • 90
  • 411
  • 885
  • Relevant: [1](http://stackoverflow.com/questions/28344564/cmake-remove-a-compile-flag-for-a-single-translation-unit), [2](http://stackoverflow.com/questions/7847900/disable-openmp-in-nice-way), [3](http://stackoverflow.com/questions/1357604/turn-off-openmp). – Avi Ginsburg Jun 22 '15 at 08:11
  • Thanks Avi. None of them apply. (1) uses Cmake, and this is a makefile based project. (2) requires me to modify makefiles and recipes. (3) disables it for the entire program. I'm interested in disabling it for one translation unit at a time without doing much more than `#pragma omp off` for the translation unit. Surely I'm not the only guy who wanted to do this.... – jww Jun 22 '15 at 08:18
  • 1
    3 doesn't inherently disable for the entire program. You could put `omp_set_num_threads(1);` at the beginning of the translation unit, and `omp_set_num_threads(backed_up_N);` at the end, effectively removing parallelization (doesn't actually disable OMP). – Avi Ginsburg Jun 22 '15 at 08:22
  • 2
    A remark : using `omp_set_num_threads(1);` or disabling OMP give different behaviours. Setting `omp_set_num_threads(1);` can reveal to be slower. Hence for benchmarking I prefer to disable it in order to measure parallel efficiency. – coincoin Jun 22 '15 at 09:55
  • @coincoin Agreed. I thought I made that clear in the comment, but clarification is always good. – Avi Ginsburg Jun 22 '15 at 12:08

1 Answers1

3

I am not sure you can do that in a "simple" way.
The solution I came up with was to use a #define to toggle OpenMP on/off for a specific file and wrap your pragmas :

#ifdef USE_OMP
#pragma omp ...
#endif

Then at the top of your header file, you can then specify

  • #define USE_OMP when you want to use OpenMP
  • or comment the line //#define USE_OMP when you want to disable it.

This is not very elegant but does the work.

As pointed out by Avi Ginsburg's comments, you could also use the if clause from OpenMP :

 pragma omp parallel sections if(USE_OMP)

where USE_OMP is set to true or false. However, I am not sure this solution will give the same behaviour as disabling OpenMP. Note that depending of your OpenMP version, the clause might not be available for all of your directives.

coincoin
  • 4,595
  • 3
  • 23
  • 47
  • As OP pointed out, he doesn't want to modify "modify makefiles and recipes". – Avi Ginsburg Jun 22 '15 at 12:21
  • Thanks indeed. I edited the post to make it clearer but since it is just a define, you can just put it in a header file. – coincoin Jun 22 '15 at 12:24
  • 2
    You could make it a little simpler by using an `if` clause in the pragmas. – Avi Ginsburg Jun 22 '15 at 12:25
  • Yes, after it's a matter of taste. `#if USE_OMP` with `#define OMP 1` would also work. I prefer to keep the `#ìfdef` version if you want to change your Makefiles potentially. – coincoin Jun 22 '15 at 12:29
  • 1
    That wasn't what I meant. The pragma would be `#pragma omp ... if(USE_OMP)...` with no `#if` or `#ifdef`; the define would be `#define USE_OMP true` or `#define USE_OMP false`. – Avi Ginsburg Jun 22 '15 at 12:31
  • 1
    Oh I see you mean the `if` from omp pragma. I am not sure that it will guarantee no overhead as by disabling completely OpenMP. Furthermore, it will only work for `omp for` and `omp sections` directives. Since we do not fully know the code's author. But I will add your solution which looks also nice. – coincoin Jun 22 '15 at 12:37
  • @Avi - the `if` clause may work (that's clever). Let me benchmark it that way (with the `if` clause and disabling by hand by commenting out all the `#pragma omp`) to see if they are comparable. – jww Jun 22 '15 at 15:58
  • 1
    @coincoin What omp pragma wouldn't work with an `if` clause? Tasks (omp >=3.0) work with [it](https://software.intel.com/sites/products/documentation/doclib/iss/2013/compiler/cpp-lin/GUID-243B37C4-0633-45C1-8207-66569BFDE799.htm). Microsoft is stuck at omp 2.0, therefore their docs don't reflect the newer options. – Avi Ginsburg Jun 22 '15 at 16:18
  • You are right currently reading [OpenMP 4.0 examples](http://openmp.org/mp-documents/OpenMP_Examples_4.0.1.pdf). It seems that the `if clause`can be used in larger context. Rectifying that. – coincoin Jun 22 '15 at 17:32
  • @coincoin - the problem with `#ifdef USE_OMP ... #endif` is I have to duplicate the code. I don't mind duplicating for testing, but that sort of thing won't be accepted as a patch. – jww Jun 26 '15 at 19:21
  • Thanks guys. The `if (USE_OMP)` clause worked. I got nearly equivalent benchmarks. – jww Jun 26 '15 at 20:42