我遇到OpenMP和共享变量的问题,我无法理解。我所做的每件事都在Fortran 90/95。Fortran中的OpenMP和共享变量不共享
这是我的问题:我在我的main
程序中定义了一个并行区域,其中有条款DEFAULT(SHARED)
,其中我调用了一个执行一些计算的子例程。我有一个局部变量(一个数组),我分配并在其上进行计算。我期待这个数组被分享(因为DEFAULT(SHARED)
条款),但它似乎并非如此。
这里是什么,我试图做一个例子,并且重现错误,我得到:
program main
!$ use OMP_LIB
implicit none
integer, parameter :: nx=10, ny=10
real(8), dimension(:,:), allocatable :: array
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP SINGLE
allocate(array(nx,ny))
!$OMP END SINGLE
!$OMP WORKSHARE
array = 1.
!$OMP END WORKSHARE
call compute(array,nx,ny)
!$OMP SINGLE
deallocate(array)
!$OMP END SINGLE
!$OMP END PARALLEL
contains
!=============================================================================
! SUBROUTINES
!=============================================================================
subroutine compute(array, nx, ny)
!$ use OMP_LIB
implicit none
real(8), dimension(nx,ny) :: array
integer :: nx, ny
real(8), dimension(:,:), allocatable :: q
integer :: i, j
!$OMP SINGLE
allocate(q(nx,ny))
!$OMP END SINGLE
!$OMP WORKSHARE
q = 0.
!$OMP END WORKSHARE
print*, 'q before: ', q(1,1)
!$OMP DO SCHEDULE(RUNTIME)
do j = 1, ny
do i = 1, nx
if(mod(i,j).eq.0) then
q(i,j) = array(i,j)*2.
else
q(i,j) = array(i,j)*0.5
endif
end do
end do
!$OMP END DO
print*, 'q after: ', q(1,1)
!$OMP SINGLE
deallocate(q)
!$OMP END SINGLE
end subroutine compute
!=============================================================================
end program main
当我执行它这样,我得到一个分段错误,因为本地阵列q
分配在一个线程上但不在其他线程上,而当其他人试图在内存中访问它时,它会崩溃。
如果我摆脱了本地阵列q
被分配SINGLE
区域的(虽然有时它崩溃,这是有意义的,如果不同的线程尝试分配它,而它已经是这样了(实际上它为什么它让我为难每次都不会崩溃)),但是很明显,数组q
是私有的(因此一个线程返回给我预期值,而其他线程返回给我一些其他值)。
它真的让我很困惑,为什么q
数组没有被共享,虽然我用DEFAULT(SHARED)
条款声明了我的并行区域。由于我处于孤儿子程序中,因此我无法明确地声明q
为共享,因为它仅在子例程compute
中已知......我对此问题坚持到目前为止,我无法找到解决方法。
这是正常的吗?我应该期待这种行为吗?有没有解决方法?我错过了明显的东西吗?
任何帮助将不胜感激!
感谢弗拉基米尔的解释和解决方法!事实上,通过'save'属性的工作,我的示例编译并运行。谢谢! – MBR 2013-03-05 18:59:41