Reducing on array in OpenMP

Viewed 47572

I am trying to parallelize the following program, but don't know how to reduce on an array. I know it is not possible to do so, but is there an alternative? Thanks. (I added reduction on m which is wrong but would like to have an advice on how to do it.)

#include <iostream>
#include <stdio.h>
#include <time.h>
#include <omp.h>
using namespace std;

int main ()
{
  int A [] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13};
  int S [10];

  time_t start_time = time(NULL);
  #pragma omp parallel for private(m) reduction(+:m)
  for (int n=0 ; n<10 ; ++n ){
    for (int m=0; m<=n; ++m){
      S[n] += A[m];
    }
  }
  time_t end_time = time(NULL);
  cout << end_time-start_time;

  return 0;
}
5 Answers

Since none of the other answers mentioned, I am adding this answer.

I am trying to parallelize the following program, but don't know how to reduce on an array. I know it is not possible to do so, but is there an > alternative?

With OpenMP 4.5 you can reduce array using pragmas, namely:

#pragma omp parallel for reduction(+:S)

A full running example:

#define S_SIZE 10
#include <stdio.h>
#include <time.h>
#include <omp.h>
int main ()
{
  int A [] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13};
  int S [S_SIZE] = {0};

  #pragma omp parallel for reduction(+:S[:S_SIZE])
  for (int n=0 ; n<S_SIZE ; ++n ){
    for (int m=0; m<=n; ++m){
      S[n] += A[m];
    }
  }
  int expected_output [] = {84, 114, 209, 303, 339, 412, 464, 487, 489, 502};   
  for(int i = 0; i < S_SIZE; i++){
      if(S[i] == expected_output[i])
        printf("%d\n", S[i]);
     else
       printf("ERROR! it should have been %d instead of %d\n", expected_output[i], S[i]);
  }
  
  return 0;
}

Output:

84
114
209
303
339
412
464
487
489
502

With parallel loop, each thread will process a given subset of indexes of the loop according to the scheduler. Then the array S won't need reduction as each index n will be processed independently for the outer loop. Also there should be no problem of race condition as each thread will write in different position S[n]. So the code above will work just fine by only using the directive

#pragma omp parallel for

For the outer loop .

Related