使用MPI发送和接收派生类型对象

时间:2015-06-24 13:53:41

标签: fortran

我已经定义了一个名为“图表”的类型:

Type :: chart
  Character(len=32) :: title
  Character(len=32) :: xAxis
  Character(len=32) :: yAxis
  Real(kind=DoubleReal) :: xMin=1.1D99
  Real(kind=DoubleReal) :: xMax=-1.1D99
  Real(kind=DoubleReal) :: yMin=1.1D99
  Real(kind=DoubleReal) :: yMax=-1.1D99
  Logical :: cleanPyFile=.true.
End Type  

我想知道如何使用带有MPI库的Fortran将用户定义的变量从一个进程发送到另一个进程。

1 个答案:

答案 0 :(得分:1)

感谢您的回复和建议的阅读。我查看了C ++主题,并且我还在open-mpi.org找到了有关子例程的信息以及如何使用它们computing.llnl.gov

我刚刚编写了一个子程序,它是我正在编写的程序的一部分,它的边缘有点粗糙,但它有效:

    Module typesM

    ! Setup Modules  
      Use kinds
    ! Force declaration of all variables
      Implicit None
    ! Include MPI header
      Include 'mpif.h'
    ! Declare global variables
    ! Privacy of functions/subroutines/variables
      Private
    ! Public subroutines  
      Public :: SetUpMPITypes

      Contains

      Subroutine SetUpMPITypes()  
        Implicit None   ! Force declaration of all variables
    ! Private variables
        Integer(kind=StandardInteger) :: error
        Integer(kind=StandardInteger) :: iExtent, rExtent, dpExtent
        Integer(kind=StandardInteger) :: elementTypes(0:1), blockCounts(0:1), blockOffset(0:1)
        Integer(kind=StandardInteger) :: rssConfigID
        Integer(kind=StandardInteger) :: mpiProcessCount, mpiProcessID
        Integer(kind=StandardInteger) :: i, processTo, processFrom, tag
        Integer, Dimension(MPI_STATUS_SIZE) :: status
    ! Define my rssConfig type in Fortran
        Type :: rssConfig
          sequence
          Real(kind=DoubleReal) :: total=0.0D0
          Real(kind=DoubleReal) :: energy=0.0D0
          Real(kind=DoubleReal) :: force=0.0D0
          Real(kind=DoubleReal) :: stress=0.0D0
          Integer(kind=StandardInteger) :: n
        End Type rssConfig
    ! Declare rssTest as rssConfig type
        Type (rssConfig) :: rssTest  
    ! Extent of data types
        Call MPI_TYPE_EXTENT(MPI_INTEGER, iExtent, error)
        Call MPI_TYPE_EXTENT(MPI_REAL, rExtent, error)
        Call MPI_TYPE_EXTENT(MPI_DOUBLE_PRECISION, dpExtent, error)    
    ! Block 1
        blockCounts(0) = 4
        blockOffset(0) = 0
        elementTypes(0) = MPI_DOUBLE_PRECISION
    ! Block 2
        blockCounts(1) = 1 
        blockOffset(1) = 4 * dpExtent
        elementTypes(1) = MPI_INTEGER
    ! Make mpi structure
        call MPI_TYPE_STRUCT(2, blockCounts, blockOffset, elementTypes, rssConfigID, error)
        call MPI_TYPE_COMMIT(rssConfigID, error)
    ! Get process ID and total mpi process count
        Call MPI_Comm_size(MPI_COMM_WORLD ,mpiProcessCount,error)
        Call MPI_Comm_rank(MPI_COMM_WORLD,mpiProcessID,error)
    ! Set values on the root process    
        If(mpiProcessID.eq.0)Then
          rssTest%total = 8.1D0
        End If
    ! wait and print out    
        call sleep(1)
        print *,mpiProcessID,rssTest%total
    ! Send from root to workers using rssConfig type
        If(mpiProcessID.eq.0)Then
          Do i=1,(mpiProcessCount-1)
            processTo = i
            tag = 114 + i
            Call MPI_SEND(rssTest,1,rssConfigID,processTo,tag,MPI_COMM_WORLD,error)
          End Do
        End If
    ! Recieve by worker processes from root process
        If(mpiProcessID.gt.0)Then
          processFrom = 0
          tag = 114 + mpiProcessID
          Call MPI_RECV(rssTest,1,rssConfigID,processFrom,tag,MPI_COMM_WORLD,status,error)
        End If  
    ! wait and printout
        call sleep(1)
        print *,mpiProcessID,rssTest%total  
      End Subroutine SetUpMPITypes

    End Module typesM

感谢您的建议。我将来会尝试使用MPI_TYPE_CREATE_STRUCT子程序,但我还没有工作。