3.18. omp_get_num_threads Routine#

In the following example, the omp_get_num_threads call returns 1 in the sequential part of the code, so np will always be equal to 1. To determine the number of threads that will be deployed for the parallel region, the call should be inside the parallel region.

//%compiler: clang
//%cflags: -fopenmp

/*
* name: get_nthrs.1
* type: C
*/
#include <omp.h>
void work(int i);

void incorrect() {
  int np, i;

  np = omp_get_num_threads();  /* misplaced */

  #pragma omp parallel for schedule(static)
  for (i=0; i < np; i++)
    work(i);
}
!!%compiler: gfortran
!!%cflags: -fopenmp

! name: get_nthrs.1
! type: F-fixed
      SUBROUTINE WORK(I)
      INTEGER I
        I = I + 1
      END SUBROUTINE WORK

      SUBROUTINE INCORRECT()
        INCLUDE "omp_lib.h"      ! or USE OMP_LIB
        INTEGER I, NP

        NP = OMP_GET_NUM_THREADS()   !misplaced: will return 1
!$OMP   PARALLEL DO SCHEDULE(STATIC)
          DO I = 0, NP-1
            CALL WORK(I)
          ENDDO
!$OMP   END PARALLEL DO
      END SUBROUTINE INCORRECT

The following example shows how to rewrite this program without including a query for the number of threads:

//%compiler: clang
//%cflags: -fopenmp

/*
* name: get_nthrs.2
* type: C
*/
#include <omp.h>
void work(int i);

void correct()
{
  int i;

  #pragma omp parallel private(i)
  {
    i = omp_get_thread_num();
    work(i);
  }
}
!!%compiler: gfortran
!!%cflags: -fopenmp

! name: get_nthrs.2
! type: F-fixed
      SUBROUTINE WORK(I)
        INTEGER I

        I = I + 1

      END SUBROUTINE WORK

      SUBROUTINE CORRECT()
        INCLUDE "omp_lib.h"     ! or USE OMP_LIB
        INTEGER I

!$OMP    PARALLEL PRIVATE(I)
          I = OMP_GET_THREAD_NUM()
          CALL WORK(I)
!$OMP   END PARALLEL

      END SUBROUTINE CORRECT