Search code examples
c++visual-c++openmp

Compiler-dependent OpenMP min/max reduction pragma


My C++ code uses OpenMP directives and needs to compile with GCC and Visual Studio 2019. OpenMP min/max reduction operators were introduced in OpenMP 3.1, but Visual Studio 2019 only supports OpenMP 2.0.

I'd like my code to revert to a serial loop under Visual Studio, but I understand that the preprocessor cannot represent a conditional pragma like this:

// invalid use of preprocessor:
#ifdef _MSC_VER
#define OMP_MIN(expr)
#else
#define OMP_MIN(expr) #pragma omp parallel for reduction(min:(expr))
#endif

double x = 10.0;

OMP_MIN(x)
for (int i = 0; i < array_size; i++) {
    x = fmin(x, array[i]);
}

Is there a way to achieve this?


Solution

  • You can use _Pragma() from C++11 to have a function-like macro that conditionally enables a pragma:

    #include <cmath>
    
    #ifdef _MSC_VER
    #define OMP_MINX()
    #else
    #define OMP_MINX() _Pragma("omp parallel for reduction(min:x)")
    #endif
    
    int main() {
      double x = 10.0;
      double array[50];
      int array_size = 50;
    
      OMP_MINX()
      for (int i = 0; i < array_size; i++) {
        x = std::fmin(x, array[i]);
      }
    }
    

    but I haven't figured out how to make gcc accept anything other than a literal string for the argument to allow using an arbitrary variable - not even the preprocessor's stringification operator works, meaning you might as well just use

    #ifndef _MSC_VER
    #pragma omp parallel for reduction(min:x)
    #endif
    for (int i = 0; i < array_size; i++) {
      x = std::fmin(x, array[i]);
    }