OpenMP と共有変数で問題が発生し、理解できません。私が行うことはすべて Fortran 90/95 です。
ここに私の問題があります: 私は自分の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
そのように実行すると、ローカル配列が1つのスレッドに割り当てられているが他のスレッドには割り当てられていないため、セグメンテーション違反が発生q
し、他のスレッドがメモリ内でアクセスしようとするとクラッシュします。
SINGLE
ローカル配列q
が割り当てられている領域を取り除くと(ただし、別のスレッドがそれを割り当てようとすると、クラッシュすることがありますが、これは理にかなっていますが、実際にはそうではありません(実際には、なぜ毎回クラッシュしないのか不思議です))その場合、明らかに配列q
がプライベートであるかのようになります (したがって、1 つのスレッドが期待値を返し、他のスレッドは別の値を返します)。
q
節で並列領域を宣言したのに、なぜ配列が共有されないのか、本当に困惑しましたDEFAULT(SHARED)
。そして、私は孤立したサブルーチンにq
いるので、サブルーチンでのみ知られているため、明示的に共有として宣言することはできませんcompute
...私はこれまでこの問題に悩まされており、回避策を見つけることができませんでした.
それは正常ですか?この動作を期待する必要がありますか? 回避策はありますか? 明らかな何かを見逃していますか?
どんな助けでも大歓迎です!