Mario E. U.
Mario E. U.

Reputation: 45

OpenMP always working on the same thread

I'm working with OpenMP and C for a university deliverable and I'm trying to execute the following code, the only thing I wanna do is to see how each section works in every different thread:

#include <omp.h>
#include <stdio.h>
int main() {                             
    int id, np;     

    printf("Max threads number: %d\n",omp_get_max_threads());
    omp_set_num_threads(omp_get_max_threads());

    #pragma omp parallel sections private(id, np)
    {
        np = omp_get_num_threads(); 
        #pragma omp section
        { 
            id = omp_get_thread_num();
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
        #pragma omp section
        { 
            id = omp_get_thread_num();
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
        #pragma omp section
        { 
            id = omp_get_thread_num();
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
        #pragma omp section
        { 
            id = omp_get_thread_num();
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
    }
}

I'm working on Linux, and so when I compile it this say:

g++ prueba.c -lgomp -o prueba

I'm getting the next output:

Max threads number: 4
Hello from thread 0 out of 1 threads
Hello from thread 0 out of 1 threads
Hello from thread 0 out of 1 threads
Hello from thread 0 out of 1 threads

Could anyone tell me why it's always working on the thread number 0, and why the omp_get_num_threads() is always 1?

The output I want to achieve is:

Max threads number: 4
Hello from thread 0 out of 3 threads
Hello from thread 1 out of 3 threads
Hello from thread 2 out of 3 threads
Hello from thread 3 out of 3 threads

Thanks in advance!

Upvotes: 2

Views: 2014

Answers (2)

Zulan
Zulan

Reputation: 22660

First, you are missing the -fopenmp compiler flag, so the pragmas are ignored. Specify fopenmp on all compile and link steps, do not manually link with -lgomp unless necessary.

The first statement

np = omp_get_max_threads();

within a sections construct will still be considered a structured block that is only executed by a single thread, as the other answer explains. So your code is equal to:

 #pragma omp parallel sections private(id)
 {
     #pragma omp section
     {
         np = omp_get_max_threads();
     }
     #pragma omp section
     { 
     id = omp_get_thread_num();
     printf("Hello from thread %d out of %d threads\n", id, np);
     }
....

Note that you could also split the `parallel` / `sections` and initalize the private variables for each thread:

Is just fine. This code is executed by all parallel threads and np (with the same value for each thread) is retained through the worksharing omp sections. You could even move:

#pragma omp parallel
{
    // Declaring the variables within makes them implicitly private
    // and avoids stupid mistakes
    int np = omp_get_max_threads();
    int id = omp_get_thread_num();
    #pragma omp sections
    {
        #pragma omp section
        {
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
        ...
    }
}

Upvotes: 2

Pierre de Buyl
Pierre de Buyl

Reputation: 7293

  1. By specifying np as private, it becomes private to every individual section block. Either copy np = omp_get_num_threads(); to every individual section (keeping it private) or move it out of the parallel construct completely (removing it from private).
  2. section blocks are allowed to run in any sequence, including 4 blocks on the same thread. The output "0, 1, 2, 3" cannot be controlled.

EDIT: to make sure we are on the same line, I copy-paste below the code I tested:

 #include <omp.h>
 #include <stdio.h>
 int main() {
 int id, np;

 printf("Max threads number: %d\n",omp_get_max_threads());
 omp_set_num_threads(omp_get_max_threads());

 #pragma omp parallel sections private(id)
 {
     np = omp_get_max_threads();
     #pragma omp section
     { 
     id = omp_get_thread_num();
     printf("Hello from thread %d out of %d threads\n", id, np);
     }
     #pragma omp section
     { 
     id = omp_get_thread_num();
     printf("Hello from thread %d out of %d threads\n", id, np);
     }
     #pragma omp section
     { 
     id = omp_get_thread_num();
     printf("Hello from thread %d out of %d threads\n", id, np);
     }
     #pragma omp section
     { 
     id = omp_get_thread_num();
     printf("Hello from thread %d out of %d threads\n", id, np);
     }
 }
 }

Upvotes: 1

Related Questions