MRheinhardt
MRheinhardt

Reputation: 11

OpenMP reductions inside subgrograms

The following Fortran code fails (random result), but replacing the call to mysum by abc=abc+1 gives the correct result. How to make OpenMP recognizing the reduction in a subprogram?

  program reduc

    use omp_lib
    implicit none

    integer :: abc=0, icount
    call OMP_set_num_threads(8)

    !$omp parallel private (icount) reduction(+:abc)
    !$omp do

    do icount = 1,8
      !abc = abc + 1
      call mysum(OMP_get_thread_num())
    end do

    !$omp end do
    !$omp end parallel
    print*,"abc at end: ",abc

    contains

    subroutine mysum(omp_rank)

    integer :: omp_rank

      abc = abc + 1
      print*,"OMP rank: ", omp_rank, " abc: ", abc

    endsubroutine mysum

  end program reduc

I also tried to put !$omp threadprivate (abc) into mysum, which was rejected with "Error: Symbol 'abc' at (1) has no IMPLICIT type.", which is of course not true.

Upvotes: 1

Views: 96

Answers (1)

PierU
PierU

Reputation: 2688

Because of the reduction, the original variable abc is privatised in each thread, but abc in the contained subroutine always refers to the original, non privatised variable.

The solution is to pass it as an argument:

subroutine mysum(omp_rank,abc)
    integer, intent(in) :: omp_rank
    integer, intent(inout) :: abc
    
    abc = abc + 1
    print*,"OMP rank: ", omp_rank, " abc: ", abc
endsubroutine mysum

Upvotes: 0

Related Questions