1

MPIを使用してFortran90プログラムを並列化していると、本当に奇妙な動作が発生します。長さnn+1の配列iaがあり、プロセス0からプロセス1、...、ntasks-1にチャンクで送信しています。各プロセスには、他のすべてのプロセスが持つiaの開始位置を示すリストproc_startと、各プロセスが持つポイントの数を示すリストpts_per_procもあります。次のコードが機能します。

if (me == 0) then
    print *, 'Eat my shorts'
else
    allocate( ia(pts_per_proc(me+1)+1) )
endif

! If this is the boss process, send the array ia,
if (me == 0) then
    do n=1,ntasks-1
        call mpi_send(ia(proc_start(n+1)),pts_per_proc(n+1)+1, &
            & mpi_integer,n,n,mpi_comm_world,ierr)
    enddo
! but if it's a worker, receive this array.
else
    call mpi_recv(ia,pts_per_proc(me+1)+1,mpi_integer, &
            & 0,me,mpi_comm_world,stat,ierr)
endif

セグメンテーション違反はありません。行をコメントアウトするとき

print *, 'Eat my shorts'

mpi_barrierの呼び出しをどこに含めても、セグメンテーション違反が発生します。たとえば、最初のビットをコードに置き換えます

call mpi_barrier(mpi_comm_world,ierr)
if (me /= 0) then
    allocate( ia(pts_per_proc(me+1)+1) )
endif
call mpi_barrier(mpi_comm_world,ierr)

セグメンテーション違反が発生します。この問題を回避するために代わりにmpi_scattervを使用することもできますが、ここで何が問題になっているのかを知りたいのです。バリアは、故障が発生しないことを保証する必要があります。

4

1 に答える 1

0

ステートメントによって隠されたセグメンテーション違反print *は珍しいことではなく、プログラムのどこかでメモリ破損の症状であることがよくあります。

このような場合、Valgrindのmemcheckツールは多くの問題を回避できますが、MPIで使用するためにツールを適切に構成する必要があります(そして、簡単に検出できるいくつかの誤検知が予想されます)。

于 2012-10-22T07:24:07.150 に答える