我有一个子例程,它是较大的Fortran程序的一部分,当在Mac笔记本电脑上用mpi调用时,该子例程将无法运行。该程序是使用mpifort编译的,可以在串行模式下完美运行。
使用mpifort在HEC上编译时,该程序将成功运行-每个文件所包含的mpif.h文件都显示在下面的代码顶部。
我看过上一篇文章(Invalid datatype when running mpirun),其中讨论了如何更改块数来解决此错误;但是,这并不能解释为什么该程序将在不同的体系结构上运行。
subroutine Initialise_f(Nxi, XI, BBC, B, nprofile, &
kTzprofile, kTpprofile, vzprofile, Nspecies, particle, &
neighbourLeft, neighbourRight, comm1d)
use SpecificTypes
implicit none
include '/opt/pgi/osx86-64/2017/mpi/mpich/include/mpif.h' !MPI for MAC
!include '/usr/shared_apps/packages/openmpi-1.10.0-gcc/include/mpif.h' !MPI for HEC
type maxvector
double precision, allocatable :: maxf0(:)
end type maxvector
integer Nxi, Nspecies
double precision XI(Nxi), BBC(2), B(Nxi), nprofile(Nxi,Nspecies), &
kTzprofile(Nxi,Nspecies), kTpprofile(Nxi,Nspecies), &
vzprofile(Nxi,Nspecies)
type(species) particle(Nspecies)
integer neighbourLeft, neighbourRight, comm1d
! Variables for use with mpi based communication
integer (kind=MPI_ADDRESS_KIND) :: offsets(2)
integer ierr, blockcounts(2), tag, oldtypes(2), &
b_type_sendR, b_type_sendL, b_type_recvR, b_type_recvL, &
istart, Nmess, rcount, fnodesize, fspecsize, maxf0size, &
fspecshape(2), requestIndex, receiveLeftIndex, receiveRightIndex
! Allocate communication buffers if necessary
fnodesize = sum( particle(:)%Nvz * particle(:)%Nmu )
Nmess = 0
if (neighbourLeft>-1) then
Nmess = Nmess + 2
allocate( send_left%ivzoffsets(Nspecies*2) )
allocate( send_left%fs(fnodesize*2 ))
allocate( receive_left%ivzoffsets(Nspecies*2) )
allocate( receive_left%fs(fnodesize*2) )
send_left%ivzoffsets = 0
send_left%fs = 0.0d0
receive_left%ivzoffsets = 0
receive_left%fs = 0.0d0
end if
! Build a few mpi data types for communication purposes
oldtypes(1) = MPI_INTEGER
blockcounts(1) = Nspecies*2
oldtypes(2) = MPI_DOUBLE_PRECISION
blockcounts(2) = fnodesize*2
if (neighbourLeft>-1) then
call MPI_GET_ADDRESS(receive_left%ivzoffsets, offsets(1), ierr)
call MPI_GET_ADDRESS(receive_left%fs, offsets(2), ierr)
offsets = offsets-offsets(1)
call MPI_TYPE_CREATE_STRUCT(2,blockcounts,offsets,oldtypes,b_type_recvL,ierr)
call MPI_TYPE_COMMIT(b_type_recvL, ierr)
call MPI_GET_ADDRESS(send_left%ivzoffsets, offsets(1), ierr)
call MPI_GET_ADDRESS(send_left%fs, offsets(2), ierr)
offsets = offsets-offsets(1)
call MPI_TYPE_CREATE_STRUCT(2,blockcounts,offsets,oldtypes,b_type_sendL,ierr)
call MPI_TYPE_COMMIT(b_type_sendL, ierr)
end if
这将解决以下错误:
[dyn-191-250:31563] *** An error occurred in MPI_Type_create_struct
[dyn-191-250:31563] *** reported by process [1687683073,0]
[dyn-191-250:31563] *** on communicator MPI_COMM_WORLD
[dyn-191-250:31563] *** MPI_ERR_TYPE: invalid datatype
[dyn-191-250:31563] *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
[dyn-191-250:31563] *** and potentially your MPI job)
答案 0 :(得分:2)
在您的Mac上,您包括了MPICH中的mpif.h
,但错误消息来自Open MPI。
您应该简单地include 'mpif.h'
并使用MPI包装器(例如mpifort
)来构建您的应用程序。
如果您的MPI和编译器支持,最好选择use mpi
,最好选择use mpi_f08
(请注意,后者要求您更新代码)。