Search code examples
c++openmppragma

C++ omp for loop with conditional counter (not loop index, not a reduction)


I am parallelizing a code where elements of an array B are a function of elements of an array A. B is smaller than A (i know both sizes in advance) and B[n] is written only if A[n] satisfy a certain condition. A representation of the code would be copy A[n] to B[n] only if A[n] is even, like:

#include<omp.h>
#include<iostream>

bool isEven(int number)
{
    if (number%2 == 0) 
        return true;
    else 
        return false;
}

int main()
{

    int array_length = 100;
    int A [array_length] = {};
    int B [array_length/2] = {};

    // fill A with natural numbers
    for (int a=0; a<array_length; a++)
    {
        A[a] = a;
    } 


    int count = 0;
    #pragma omp parallel for 
    for (int n=0; n<array_length; n++)
    {
        if (isEven(A[n]))
        {
            #pragma omp critical
            {
                count++;
                B[(count-1)] = A[n];
            }
        }
    }


        // print values of b
    std::cout << "B is : " ;
    for (size_t i = 0; i < array_length/2; i++) {
        std::cout << B[i] << ' ';
    }
    std::cout << std::endl;

    return 0;
}

I am trying several combinations of critical and atomic pragmas, as well as increment of count without any success: there is a race condition on count and the final result is garbage in B. Anyone has any idea on how to make it work?


Solution

  • You say that copying A into B is a "representation" of your code. If computing the B elements actually takes some amount of work, then you could let the A loop be done sequentially, and create tasks for the computation of the B elements.