モジュール、派生データ型、および MPI を使用する Fortran 90 コードでしばらく行き詰まっています。
私が抱えている問題は、派生データ型をブロードキャストした後、マスター ノードの変数のみが正しい値を持ち、他のすべてのノードの変数には必要なものが含まれていないことです。より大きなコードから最小限の例を抽出しました。メインプログラムが含まれています:
include 'hello_types.f90'
include 'mpi_circle.f90'
program hello_world
use type_hello_world
use create_mpi_types
implicit none
include 'mpif.h'
integer :: ierr, num_procs, my_id, mesg_mpi_circle
type(circle_) :: circle
call MPI_Init(ierr)
!find out MY process ID, and how many processes were started.
call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr)
call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr)
allocate(circle%diameter(3),circle%straal(3))
if (my_id==0) then
print*,'enter straal and diameter'
read*,circle%diameter(1),circle%straal(1)
circle%diameter(2)=circle%diameter(1)
circle%straal(2)=circle%straal(1)
endif
call build_derived_circle(circle,mesg_mpi_circle)
call MPI_BCAST(circle,1,mesg_mpi_circle,0,MPI_COMM_WORLD,ierr)
print *, "Hello world! I'm process ", my_id, " out of", num_procs, " processes."
print*,my_id,mesg_mpi_circle%diameter(my_id+1),mesg_mpi_circle%straal(my_id+1)
call MPI_Finalize(ierr)
end program hello_world
出力には 2 つの print ステートメントが含まれます。最初のステートメントは proc_id のみを出力し (正常に動作します)、2 番目のステートメントはそれぞれのノードの変数を出力します (ここで問題が発生し、マスター ノードでのみ値が正常です)。 . 変数は、マスター ノードで読み込まれます。
さらに、型が定義されているモジュールがあります。
module type_hello_world
type circle_
real,allocatable :: straal(:),diameter(:)
end type circle_
end module type_hello_world
私が言ったように、私はこれをより大きなコードから抽象化したので、このモジュールは役に立たないように見えるかもしれませんが、元のコードでは意味があります。
そして 3 番目として、派生データ型のブロードキャストの変位を計算するサブルーチンを含むモジュール ..... http://ladon.iqfr.csic.es/docs/MPI_ug_in_FORTRAN.pdfから Fortran の MPI ユーザー ガイドに従いました。
module create_mpi_types
contains
subroutine build_derived_circle(circle,mesg_mpi_circle)
use type_hello_world
implicit none
include 'mpif.h'
type(circle_),intent(in) :: circle
! local
integer,parameter :: number=2
integer :: ierr, i
integer :: block_lengths(number)
integer :: displacements(number)
integer :: address(number+1)
integer :: typelist(number)
!output
integer,intent(out) :: mesg_mpi_circle
!----------------------------------------
! first specify the types
typelist(1)=MPI_REAL
typelist(2)=MPI_REAL
! specify the number of elements of each type
block_lengths(1)=size(circle%straal)
block_lengths(2)=size(circle%diameter)
! calculate displacements relative to refr.
call MPI_Address(circle,address(1),ierr)
call MPI_Address(circle%straal,address(2),ierr)
call MPI_Address(circle%diameter,address(3),ierr)
do i = 1, number
displacements(i)=address(i+1)-address(i)
enddo
! build the derived data type
call MPI_TYPE_STRUCT(number,block_lengths,displacements,&
typelist,mesg_mpi_circle,ierr)
! commit it to the system, so it knows we ll use it
! for communication
call MPI_TYPE_COMMIT(mesg_mpi_circle,ierr)
return
end subroutine build_derived_circle
!------------- END SUBROUTINE----------------------------
end module create_mpi_types
セットアップ用: コードは、Intel fortran でコンパイルされた CentOs6 の下の ETH Brutus クラスターで実行することを目的としています。ただし、同じ問題が発生するいくつかのマシンでテストしたため、バージョンの問題ではないと思います。