2

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...私はこれまでこの問題に悩まされており、回避策を見つけることができませんでした.

それは正常ですか?この動作を期待する必要がありますか? 回避策はありますか? 明らかな何かを見逃していますか?

どんな助けでも大歓迎です!

4

2 に答える 2

7

qOpenMP で言えば、「リージョン内にあるがコンストラクト内にはない」エンティティです。ローカルであるサブルーチンqは、並列構成中に呼び出されるプロシージャ内にありますが、qそれ自体は PARALLEL 指令と END PARALLEL 指令の間に語彙的に現れません。

OpenMP でのそのようなエンティティのデータ共有規則では、q が非公開であることが規定されています。

DEFAULT(SHARED) などのデータ共有句は、構文自体に現れるもの (PARALLEL と END PARALLEL の間に語彙的に現れるもの) にのみ適用されます。(通常、リージョン内のものには適用できません。リージョン内で呼び出されるプロシージャは、個別にコンパイルされている可能性があり、並列構造の外部で呼び出される可能性があります。)

于 2013-03-05T18:52:42.693 に答える
3

配列qは、呼び出されたサブルーチン内で定義されます。すべてのスレッドがこのサブルーチンを個別に呼び出すため、すべてのスレッドが独自のコピーを持ちます。shared外側のサブルーチンのディレクティブはこれを変更できません。save属性で宣言してみてください。

于 2013-03-05T18:52:29.597 に答える