Search code examples
fortranopenmp

error: reduction variable ‘v1’ is private in outer context


I have the following Fortran code

program hello

    use omp_lib
    implicit none
    
    integer :: num_threads = 2
    
    print*, "Display Hello world!"
    print*, "Number of threads used = ", num_threads
    
    call loop()
    
end program hello


subroutine loop()
    integer :: i,j,k,n
    real :: c0
    real, allocatable :: v1(:,:)

    n = 3
    c0 = 0.
    if (.not. allocated (v1)) allocate(v1(n,n))    
    v1 = c0
    
    !$omp do private(i, j, k) schedule(dynamic) reduction(+: v1)    
    do i = 1, n 
      do j = 1, n
        do k = 1, n
          v1(i,j) = v1(i,j) + k
        end do
        write (*,*) i, j, v1(i,j)
      end do
    end do  
    !$omp end do   

end subroutine

gfotran -fopenmp leads to

error: reduction variable ‘v1’ is private in outer context
     !$omp do private(i, j, k) schedule(dynamic) reduction(+: v1)

I checked reduction variable is private in outer context but still unsure the reason for my issue. v1 is only used inside the loop.

What's the reason for the error message reduction variable ‘v1’ is private in outer context ?

[Solved, by adding !$omp parallel and !$omp end parallel]


Solution

  • Thanks for Ian Bush's comment. By adding !$omp parallel and !$omp end parallel, i.e.,

    program hello
    
        use omp_lib
        implicit none
        
        integer :: num_threads = 2
        
        print*, "Display Hello world!"
        print*, "Number of threads used = ", num_threads
              
        call loop()
        
    end program hello
    
    
    subroutine loop()
        integer :: i,j,k,n
        real :: c0
        real, allocatable :: v1(:,:)
    
        n = 3
        c0 = 0.
        if (.not. allocated (v1)) allocate(v1(n,n))    
        
        !$omp parallel
        !$omp do private(i, j, k) schedule(dynamic) reduction(+: v1)    
        do i = 1, n 
          do j = 1, n
            v1(i,j) = c0
            do k = 1, n
              v1(i,j) = v1(i,j) + k
            end do
            write (*,*) i, j, v1(i,j)
          end do
        end do  
        !$omp end do  
        !$omp end parallel
    
    end subroutine
    
    

    the code runs normally.