Parallelize nested for loop with openMP

21,052

It is not possible to reduce an array or an struct in OpenMP, which is mentioned here: https://computing.llnl.gov/tutorials/openMP/#REDUCTION.

I think you can declare multiple copies of histogram, each of which is used in one thread. After then use another OpenMP loop to add them up.

Share:
21,052
seb
Author by

seb

Updated on July 10, 2022

Comments

  • seb
    seb almost 2 years

    I am trying to optimize the nested for loop in the function generate_histogram() below with openMP. I have tried around a lot with different combinations of pragmas based on what I've read in this SE post.

    The problem is that the nested for loop performs faster without openMP than with openMP!

    If I try to parallelize my code with reduction instead of the atomic pragma, I end up with netchunk fails. Does anybody know a fancy tweak for this one? I am trying to bin data into a histogram. So the histogram is variable in size in the real code, unlike in the snippet below.

    #include<stdio.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #define float_t float
    #include <time.h>
    #include <omp.h>
    
    float_t generate_histogram(float_t **matrix, int *histogram, int mat_size, int hist_size)
    {
    int i,j,k,count;
    float_t max = 0.;
    float_t sum;
    
    //set histogram to zero everywhere
    for(i = 0; i < hist_size; i++)
        histogram[i] = 0;
    
    
    //matrix computations
    #pragma omp parallel for private(i) shared(histogram,j,k,max) schedule(dynamic)
    //#pragma omp parallel for schedule(runtime)
    for (i = 1; i < (mat_size-1); i++)
    {
        #pragma omp parallel for private(j,k) shared(histogram,max) schedule(dynamic)
        //pragma omp prallel for schedule(dynamic)
        for(j = 1; j < (mat_size-1); j++)
        {
    
            //assign current matrix[i][j] to element in order to reduce memory access
            sum = fabs(matrix[i][j]-matrix[i-1][j]) + fabs(matrix[i][j] - matrix[i+1][j])
                + fabs(matrix[i][j]-matrix[i][j-1]) + fabs(matrix[i][j] - matrix[i][j+1]);
    
            //compute index of histogram bin
            k = (int)(sum * (float)mat_size);
            #pragma omp atomic
            histogram[k] += 1;
    
            //keep track of largest element
            if(sum > max)
                max = sum;
    
        }//end inner for
    }//end outer for
    
    return max;
    }
    
    
    main()
    {
    int i,j,N,boxes;
    N = 10000;
    float_t **matrix;
    int* histogram;
    boxes = N / 2;
    
    //allocate a matrix with some numbers
    matrix = calloc(N, sizeof(float_t **));
    for(i = 0; i < N; i++)
        matrix[i] = calloc(N, sizeof(float_t *));
    for(i = 0; i < N; i++)
        for(j = 0; j < N; j++)
            matrix[i][j] = 1./(float_t) N * (float_t) i;
    
    
    histogram = malloc(boxes * sizeof(int));
    
    generate_histogram(matrix, histogram, N, boxes);
    
    }