Is it possible to do a reduction on an array with openmp?

22,301

Solution 1

Only in Fortran in OpenMP 3.0, and probably only with certain compilers.

See the last example (Example 3) on:

http://wikis.sun.com/display/openmp/Fortran+Allocatable+Arrays

Solution 2

Array reduction is now possible with OpenMP 4.5 for C and C++. Here's an example:

#include <iostream>

int main()
{

  int myArray[6] = {};

  #pragma omp parallel for reduction(+:myArray[:6])
  for (int i=0; i<50; ++i)
  {
    double a = 2.0; // Or something non-trivial justifying the parallelism...
    for (int n = 0; n<6; ++n)
    {
      myArray[n] += a;
    }
  }
  // Print the array elements to see them summed   
  for (int n = 0; n<6; ++n)
  {
    std::cout << myArray[n] << " " << std::endl;
  } 
}

Outputs:

100
100
100
100
100
100

I compiled this with GCC 6.2. You can see which common compiler versions support the OpenMP 4.5 features here: https://www.openmp.org/resources/openmp-compilers-tools/

Note from the comments above that while this is convenient syntax, it may invoke a lot of overheads from creating copies of each array section for each thread.

Solution 3

Now the latest openMP 4.5 spec has supports of reduction of C/C++ arrays. http://openmp.org/wp/2015/11/openmp-45-specs-released/

And latest GCC 6.1 also has supported this feature. http://openmp.org/wp/2016/05/gcc-61-released-supports-openmp-45/

But I didn't give it a try yet. Wish others can test this feature.

Solution 4

OpenMP cannot perform reductions on array or structure type variables (see restrictions).

You also might want to read up on private and shared clauses. private declares a variable to be private to each thread, where as shared declares a variable to be shared among all threads. I also found the answer to this question very useful with regards to OpenMP and arrays.

Share:
22,301
Andrew Wagner
Author by

Andrew Wagner

I'm currently a Post-Doc researcher at the University of Leuven, Belgium working on launching systems for flying wind turbines.

Updated on July 09, 2022

Comments

  • Andrew Wagner
    Andrew Wagner almost 2 years

    Does OpenMP natively support reduction of a variable that represents an array?

    This would work something like the following...

    float* a = (float*) calloc(4*sizeof(float));
    omp_set_num_threads(13);
    #pragma omp parallel reduction(+:a)
    for(i=0;i<4;i++){
       a[i] += 1;  // Thread-local copy of a incremented by something interesting
    }
    // a now contains [13 13 13 13]
    

    Ideally, there would be something similar for an omp parallel for, and if you have a large enough number of threads for it to make sense, the accumulation would happen via binary tree.

  • Hugo Raguet
    Hugo Raguet about 8 years
    It is now possible since OpenMP 4.5; see the answer of Chen Jiang below. Basically, you must specify array sections (see Section 2.4, p. 44 of OpenMP 4.5 spec.). Your #pragma specification would look like this: #pragma omp parallel reduction(+:a[:4]) Be careful with this however, you have to realize that each thread will allocate its own version of the array section; if you do this on large arrays with many threads, you might make your memory need explode.
  • RL-S
    RL-S over 2 years
    it irks me a bit that your int main() doesn't return an 'int' :D