Search code examples
arrayscconcatenationopenmp

Concatenate private arrays after OpenMP


I am using OpenMP to parallelize the code below.

int *neighbors = malloc(num_of_neigh * sizeof(int));
int pos = 0;
for(int i=0;i<n;i++){
    if(M[n*element+i]==1 && element!=i){
        neighbors[pos] = i;
        pos++;
    }
}

Below is the code which works properly. However for a great number of n, I have a slower implementation due to the shared variables neighbors and pos.

int *neighbors = malloc(num_of_neigh * sizeof(int));
int pos = 0;

#pragma omp parallel for num_threads(8)
for(int i=0;i<n;i++){
    if(M[n*element+i]==1 && element!=i){
        #pragma omp critical
        {
            neighbors[pos] = i;
            pos++;
        }
    }
}

As a result, I decided to use local variables for neighbors and pos and concatenate the private variables to a global one after the calculations. However, I have some troubles with these concatenations.

int *neighbors = malloc(num_of_neigh * sizeof(int));
int pos = 0;
#pragma omp parallel num_threads(8)
{
    int *temp_neighbors = malloc(num_of_neigh * sizeof(int));
    int temp_pos = 0;
    #pragma omp for
    for(int i=0;i<n;i++){
        if(M[n*element+i]==1 && element!=i){
            temp_neighbors[temp_pos] = i;
            temp_pos++;
        }
    }

    // I want here to concatenate the local variables temp_neighbors to the global one neighbors.
}

I tried the code below in order to achieve the concatenation, but neighbors only takes the last value of the temp_neighbors, while the rest elements are 0.

#pragma omp critical
{
    memcpy(neighbors+pos, temp_neighbors, num_of_neigh * sizeof(neighbors));
    pos++;
}

So, the question is: How can I concatenate private variables (and especially arrays) to a global one? I searched a lot, but didn't find any proper answer. Thanks in advance and sorry for the big question.


Solution

  • The global section should look like the following.

    #pragma omp critical
    {
        memcpy(neighbors + pos, temp_neighbors, temp_pos * sizeof(int));
        pos += temp_pos;
    }
    

    memcpy copies temp_pos elements (temp_pos * sizeof(int) bytes) of data to first unused position in neighbors (neighbors + pos). Then pos is increased to be index of next unused position.