Jakub M.
Jakub M.

Reputation: 33867

OpenMP: parallel for(i;...) and i value

I have a following parallel snippet:

#include <omp.h>
#include "stdio.h"

int main()
{

omp_set_num_threads(4);
    int i;
#pragma omp parallel private(i)
    {
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %d\n", omp_get_thread_num(),i);
        }
#pragma omp critical
        printf("i  %d: %d\n", omp_get_thread_num(), i ); 
    }
}

I thought that after the loop, each thread will have i equal to i last value in the thread's loop. My desired output would be:

A  0: 0
A  0: 1
A  0: 2
A  3: 9
A  2: 6
A  2: 7
A  2: 8
A  1: 3
A  1: 4
A  1: 5
i  0: 3
i  3: 10
i  2: 9
i  1: 6

whereas what I get is:

A  0: 0
A  0: 1
A  0: 2
A  3: 9
A  2: 6
A  2: 7
A  2: 8
A  1: 3
A  1: 4
A  1: 5
i  0: -1217085452
i  3: -1217085452
i  2: -1217085452
i  1: -1217085452

How to make i to hold last iteration's value? lastprivate(i) makes i = 10 for all threads, and that is not what I want.

Upvotes: 0

Views: 320

Answers (2)

sehe
sehe

Reputation: 393839

It turns out you can't. OpenMP alters program semantics.

Parallel for loops are rewritten by the compiler according to well-defined set of rules.

This also implies you cannot break from, return from such a loop. You can also not directly manipulate the loop variable. The loop condition can not call random functions or do any conditional expression, in short: a omp parallel for loop is not a for loop

#include <omp.h>
#include "stdio.h"

int main()
{

omp_set_num_threads(4);
#pragma omp parallel
    {
        int i;
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %d\n", omp_get_thread_num(),i);
        }
#pragma omp critical
        printf("i  %d: %d\n", omp_get_thread_num(), i ); 
    }
}

Upvotes: 6

Jakub M.
Jakub M.

Reputation: 33867

Thanks to sehe`s post, I figure out the following dirty trick that solves the problem

    int i, last_i;
#pragma omp parallel private(i)
    {
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %d\n", omp_get_thread_num(),i);
            last_i = i;
        }
#pragma omp critical
        printf("i  %d: %d\n", omp_get_thread_num(), last_i ); 
    }
}

Upvotes: 1

Related Questions