MPI_TYPE_CREATE_STRUCT:无效的数据类型

时间:2019-01-31 17:11:37

标签: fortran mpi

我有一个子例程,它是较大的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)

1 个答案:

答案 0 :(得分:2)

在您的Mac上,您包括了MPICH中的mpif.h,但错误消息来自Open MPI。

您应该简单地include 'mpif.h'并使用MPI包装器(例如mpifort)来构建您的应用程序。

如果您的MPI和编译器支持,最好选择use mpi,最好选择use mpi_f08(请注意,后者要求您更新代码)。