Search code examples
c++cparallel-processingopenmpsimd

openmp collapse with inner loop reduction


I'm trying to vectorise a nested loop with #pragma omp simd, but the inner loop has a reduction in it. Is there any way to do this?

  #pragma omp simd collapse(2) reduction(+:total[i])
  for (int i=0; i<N; i++){
    for (int j=0; j<N; j++){

      float distance = sqrt(
      (x[i][0]-x[j][0]) * (x[i][0]-x[j][0]) +
      (x[i][1]-x[j][1]) * (x[i][1]-x[j][1]) +
      (x[i][2]-x[j][2]) * (x[i][2]-x[j][2])
      );

      total[i] += distance; 
    }
  }

at the moment, it just gives this error when compiling:

error: identifier "i" is undefined
#pragma omp simd collapse(2) reduction(+:total[i])
                                               ^

Solution

  • You cannot pass the variable 'i' to +:total[i] either you specify the array subsection to be reduced or just do +:total. Bear in mind, however, that you need a compiler that supports OpenMP 4.5 array reduction feature.

      #pragma omp simd collapse(2) reduction(+:total)
      for (int i=0; i<N; i++){
        for (int j=0; j<N; j++){
    
          float distance = sqrt(
          (x[i][0]-x[j][0]) * (x[i][0]-x[j][0]) +
          (x[i][1]-x[j][1]) * (x[i][1]-x[j][1]) +
          (x[i][2]-x[j][2]) * (x[i][2]-x[j][2])
          );
    
          total[i] += distance; 
        }
      }
    

    When one's compiler does not support the OpenMP 4.5 array reduction feature one can alternatively explicitly implement the reduction (check this SO thread to see how).