Implicit barrier at the end of #pragma for

General OpenMP discussion

Implicit barrier at the end of #pragma for

Postby prathmesh.kallurkar » Tue Jan 24, 2012 9:21 pm

Friends, I am trying to learn the openMP paradigm.
I used the following code to understand the #omp for pragma.

Code: Select all
int main(void){
int tid;
int i;

omp_set_num_threads(5);
#pragma omp parallel \
    private(tid)
{
    tid=omp_get_thread_num();
    printf("tid=%d started ...\n", tid);
    fflush(stdout);

    #pragma omp for
    for(i=1; i<=20; i++){
        printf("t%d - i%d \n",
                omp_get_thread_num(), i);
        fflush(stdout);
    }

    printf("tid=%d work done ...\n", tid);
}

return 0;

}


In the above code, there is an implicit barrier at the end of #pragma omp parallel, meaning all the threads 0,1,2,3,4 must reach there before going to the next statement.

So, to check this barrier, I enclosed this "pragma for" in a condition if(tid!=0), meaning all threads except thread 0 i.e 1,2,3,4 should complete their work in the loop and wait for thread0 indefinitely. But, to my surprise this is not happening. Every thread is doing its iteration and completing successfully. i.e t1 completes iterations 5,6,7,8 ---- t2 does 9,10,11,12 ---- t3 does 13,14,15,16 and t4 does 17,18,19,20. Please note : iteration 1,2,3,4 were never completed.

To dig deeper, instead of tid!=0, I enclosed the same #pragma for in tid!=1 meaning instead of thread0, thread1 bypasses the barrier. To my surprise, the program now hangs and all threads wait for the thread1.

Can somebody please tell me the explanation for such unexpected behavior. Final code that hanged :

Code: Select all
int main(void){
int tid;
int i;

omp_set_num_threads(5);
#pragma omp parallel \
    private(tid)
{
    tid=omp_get_thread_num();
    printf("tid=%d started ...\n", tid);
    fflush(stdout);

    if(tid!=1){
        /* worksharing */
        #pragma omp for
        for(i=1; i<=20; i++){
            printf("t%d - i%d \n",
                omp_get_thread_num(), i);
            fflush(stdout);
        }
    }else{
        printf("t1 reached here. \n");
    }

    printf("tid=%d work done ...\n", tid);
}

return 0;

}


I tried setting i shared or private, but it did not change the behavior of the program.
prathmesh.kallurkar
 
Posts: 1
Joined: Tue Jan 24, 2012 9:15 pm

Re: Implicit barrier at the end of #pragma for

Postby ftinetti » Wed Jan 25, 2012 2:17 pm

Hi,

I've not seen this kind of code before because if different threads are going to execute different sections of code I do not use #omp for or other worksharing constructs. Instead, I explicitly distribute the workload among threads by using some computing based on tid. However, I've not seen anything in the spec. preventing code like yours, so I was playing around a little bit. And now I'm rather... perplexed... The code:
Code: Select all
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
  int tid;
  int i;

  omp_set_num_threads(3);
  #pragma omp parallel private(tid, i)
  {
    tid=omp_get_thread_num();
    printf("tid = %d started ...\n", tid);
    fflush(stdout);

    #pragma omp barrier

    if(tid != 1)
    {
      /* worksharing */
      #pragma omp for schedule(static)
      for(i = 1; i <= 10; i++)
      {
        #pragma omp critical
        {
          printf("t%d - iteration %d \n", omp_get_thread_num(), i);
          fflush(stdout);
        }
      }
    }

    #pragma omp barrier

    #pragma omp critical
    {
      printf("tid=%d work done ...\n", tid);
      fflush(stdout);
    }
  }
}

Minor differences with your code:
1) Every I/O is inside a critical directive, just to avoid some possible problem on concurrent I/O.
2) Added two explicit barriers just to avoid possible mixing of I/O which could add some extra confusion (for me).
3) A little number of threads just to reduce I/O to the minimum but preserving the behavior.
4) I've used explicitly schedule(static) just to avoid some implementation-defined "strange" decision.

I came exactly to the results that you describe:
a) With if(tid != 0) the program always ends but never executes the iterations corresponding to thread 0
b) With if(tid != <other_than_0_value>) the program never ends even when every thread prints "work done" (!)

More specifically:
With
Code: Select all
    if(tid != 0)

the output is
tid = 0 started ...
tid = 1 started ...
tid = 2 started ...
t1 - iteration 5
t2 - iteration 9
t1 - iteration 6
t2 - iteration 10
t1 - iteration 7
t1 - iteration 8
tid=0 work done ...
tid=1 work done ...
tid=2 work done ...
tid=2 work done ...

(note the duplicated last line) and the program ends.

With
Code: Select all
    if(tid != 1)

the output is
tid = 0 started ...
tid = 2 started ...
tid = 1 started ...
t0 - iteration 1
t2 - iteration 9
t0 - iteration 2
t2 - iteration 10
t0 - iteration 3
t0 - iteration 4
tid=1 work done ...
tid=2 work done ...
tid=0 work done ...


and the program does not end.

My guesses/conclusions:
1) Thread 0, as the main thread and the "original and only one" thread defines if the program ends or not. More specifically: when it is not involved in the #pragma omp for then it is not involved in the corresponding implicit barrier at the end of the for and, thus, the program ends. However, I cannot explain why every thread prints the corresponding "work done"
2) There is some error/bug either in the OpenMP spec. or in the gcc implementation I'm using, which in fact is rather up to date:
$ gcc -v
Using built-in specs.
...
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.6-source/gcc-4.6-20111216/configure --enable-languages=c,c++,fortran --enable-checking=release --disable-bootstrap --disable-libmudflap --enable-libgomp --enable-lto --enable-gold --with-plugin-ld=/usr/bin/gold --prefix=/usr/local/gcc-4.6
Thread model: posix
gcc version 4.6.3 20111216 (prerelease) (GCC)

I will try to translate this example to Fortran and see if the behavior is the same...
ftinetti
 
Posts: 582
Joined: Wed Feb 10, 2010 2:44 pm

Re: Implicit barrier at the end of #pragma for

Postby MarkB » Fri Feb 17, 2012 5:22 am

prathmesh.kallurkar wrote:I used the following code to understand the #omp for pragma.

I'm afraid your code is not correct OpenMP: worksharing constructs such as #pragma omp for must be encountered by all the threads in the parallel region or by none of them.
MarkB
 
Posts: 481
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh

Re: Implicit barrier at the end of #pragma for

Postby ftinetti » Sat Feb 18, 2012 2:53 pm

I'm afraid your code is not correct OpenMP: worksharing constructs such as #pragma omp for must be encountered by all the threads in the parallel region or by none of them.

Is this (explicitly) in the Spec.?
If not, do you know if there will be?

Thanks in advance.
ftinetti
 
Posts: 582
Joined: Wed Feb 10, 2010 2:44 pm

Re: Implicit barrier at the end of #pragma for

Postby hhj » Mon Feb 20, 2012 10:15 am

Is this (explicitly) in the Spec.?
If not, do you know if there will be?


The restriction is explicitly spelled in the spec. See the 3.1 spec on page 38, lines 21-22.
hhj
 
Posts: 16
Joined: Thu May 01, 2008 11:59 am

Re: Implicit barrier at the end of #pragma for

Postby ftinetti » Mon Feb 20, 2012 4:56 pm

Thank you very much, hhj.
ftinetti
 
Posts: 582
Joined: Wed Feb 10, 2010 2:44 pm


Return to Using OpenMP

Who is online

Users browsing this forum: Exabot [Bot], Google [Bot] and 14 guests