0

を使用して、3D 配列を他のすべてのプロセス (FORTRAN 77) に渡そうとしていMPI_Bcastます。v1一般的なブロック配列です。また、共通配列の計算値をv1他のすべてのプロセスにブロードキャストする必要があるかどうか、または共通であるため各プロセスで変更されるかどうかもわかりません。関連するコードは次のとおりです。

  parameter (nprocz=48,nzro=1)

    do i=i101,i102
      dist  = 0.015*float(i-iv0)
      adamp = exp(-dist*dist)
      do j = je0, je1-1
      do k = ke0, ke1
        v1(k,j,i) = v1(k,j,i)*adamp
      end do
      end do
    end do

    nmpi01=floor((iv0-ie0-nzro)/(nprocz-1))
    if (mpirank .le. nprocz-2) then
       i101=ie0+(mpirank*nmpi01)
       i102=ie0+(mpirank+1)*nmpi01-1
    else
       i101=ie0+(mpirank*nmpi01)
       i102=iv0-1
    endif

   MPI_Bcast(v1(:,:,i101:i102),(ke1-ke0+1)*(je1-je0)*(i102-i101+1)
 & ,MPI_FLOAT,mpirank,MPI_COMM_WORLD,ierr01)

エラーメッセージが表示されます:

PGFTN-S-0081-Matrix/vector v1 illegal as subprogram argument

渡される配列のサイズは正しいです。任意のコメント?


コードを修正し、ランクをループして、各ランクの rcount と displs のすべての要素を計算しました。

integer :: myscount, myi101

do rank = 0, nprocz-1
  nmpi01=floor((iv0-ie0-nzro)/(nprocz-1))
  if (rank .le. nprocz-2) then
    i101=ie0+(rank*nmpi01)
    i102=ie0+(rank+1)*nmpi01-1
  else
    i101=ie0+(rank*nmpi01)
    i102=iv0-1
  endif
  scount=(i102-i101+1)*(je1-je0)*(ke1-ke0+1)
  rcount(rank+1)=scount
  displs(rank+1)=rank*scount+1
  if (rank .eq. mpirank) then
    myscount = scount
    myi101 = i101
 end if
end do

scount = myscount
i101 = myi101

call mpi_allgatherv(...)

しかし、それでも間違った結果です。1-私の場合、各部分の結果は次の部分、特に後に使用されます。それぞれの後mpi_allgathervに追加する必要がありますか? 2-mpi_in_place を使用する必要がありますか? 各サブ配列が何らかのプロセスによって計算される3D配列が1つしかなく、計算されたサブ配列を同じ配列の適切な部分に配置したいと考えています。3- fortran77 では常に displs(1)=1 であることを考えると、for i=>2 が必要だと思います。だから私はこれを修正しました:ループの前、ループの内側、ループの後。私は正しいですか?mpi_barriermpi_allgathervv1v1(1,1,i)displs(i) = sum(rcount(1:i-1))+1displs(1)=1displs(rank+2)=rank*scount+1displs(nprocz+1)=0

4

1 に答える 1

0

私が思い出したように、Fortran 77 は Fortran 90 よりも配列添字に関して制限が厳しく、pgftn は Fortran 77 コンパイラです。v1(1,1,i101)ではなく、mpi_bcast に渡そうとしv1(:,:,i101:i102)ます。(または、"-Mfixed" フラグを指定して pgf95 を使用します。)

各プロセスが v1 を確認する必要がある場合は、MPI を使用して通信する必要があります。共通ブロック内の変数であっても、MPI タスク間で共有される変数はありません。ただし、すべてのプロセスが v1 の異なる部分を計算しているため、すべてのプロセスが他のすべてのプロセスの一部を必要とする場合、それを行うために を使用mpi_bcastすることはできません。代わりに使用mpi_allgatherします。

また、前述のように、MPI プロシージャを使用する場合はcall、サブルーチンであるため使用する必要があります。

于 2013-08-18T10:17:54.213 に答える