在FORTRAN中全部聚集或散射多维数组的一大块

时间:2014-07-11 01:42:56

标签: arrays fortran mpi

按照@ Jonathan的评论,我试图重新构思我的问题。我有一个五维数组,在各种处理器的部分计算。在计算好块之后,我需要收集所有处理器中的元素(在MPI术语中)。

根据Jonathan对2D数组中类似问题的回答(https://stackoverflow.com/a/17530368/2895678),我构建了我的测试程序,该程序成功地散布(通过MPI_Scatterv)块。代码是

program scatter
  use mpi
  implicit none

  integer, dimension(2,2,2,6,2) :: gpsi
  integer, dimension(2,2,2,2,2) :: local
  integer, dimension(3) :: displs,counts
  integer :: ierr,rank,comsize
  integer :: p,newtype,i,j,k,l,m,intsize,resizedtype
  integer, dimension(5) :: totsize,subsize,starts
  integer, dimension(MPI_STATUS_SIZE) :: rstatus
  integer(kind=MPI_ADDRESS_KIND) :: extent, begin

  call MPI_Init(ierr)
  call MPI_Comm_size(MPI_COMM_WORLD, comsize, ierr)
  call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)

  gpsi = 0.0
  if(rank == 0) then
    call f(gpsi)
    do m = 1,2
      do l = 1,6
        do k = 1,2
          do j = 1,2
            do i = 1,2
              print*,i,j,k,l,m,gpsi(i,j,k,l,m)
            enddo
          enddo
        enddo
      enddo
    enddo
  endif

  totsize = [2,2,2,6,2]
  subsize = [2,2,2,2,2]
  starts = [0,0,0,0,0]

  call MPI_type_create_subarray(5,totsize,subsize,starts, &
                                MPI_ORDER_FORTRAN, MPI_INTEGER, &
                                newtype,ierr)
  call MPI_type_size(MPI_INTEGER,intsize,ierr)
  extent = intsize
  begin = 0
  call MPI_type_create_resized(newtype,begin,extent,resizedtype,ierr)
  call MPI_type_commit(resizedtype,ierr)
  counts = 1
  displs = [0,16,32]
  call MPI_scatterv(gpsi,counts,displs,resizedtype,local,32, &
                  MPI_INTEGER,0,MPI_COMM_WORLD,ierr)

  do p = 1,comsize
    if(rank == p-1) then
       print*,'Rank =',rank
       print*,local(:,:,:,:,:)
       print*,''
    endif
    call MPI_barrier(MPI_COMM_WORLD,ierr)
  enddo

  call MPI_Type_free(newtype,ierr)
  call MPI_Finalize(ierr)
end program scatter

subroutine f(psi)
  implicit none
  integer, dimension(96) :: psi
  integer :: i

  do i = 1,96
    psi(i) = i
  enddo
  return
end

在这里,我将块gpsi(:,:,:,1:2,:)发送到proc 1(即root),gpsi(:,:,:,3:4,:)发送到proc 2,gpsi(:,:,:,5:6,:)发送到proc 3(用于三个触发器)。请注意,我创建了一个名为f(psi)的虚拟子例程,用于将多维数组96的所有gpsi元素分配到连续的内存空间中,以便我可以正确计算位移数组{ {1}},在本例中为displs。在这种情况下,我在proc 1中成功获得值displs[0,16,32]1,2,…,15,16,在proc 2中成功获得49,50,…,63,6417,18,…,31,3265,66,…,79,80和{{1}在33,34,…,47,48之后的proc 3中。

然而,我的实际问题是,我想分散不同的块,然后将它们全部收集起来。例如,如果我想将81,82,…,95,96发送到proc 1,MPI_Scatterv发送到proc 2,并将gpsi(:,:,:,1:2,:)发送到proc 3.问题是如何构建子阵列现在每个子阵列都是因此,原则上,每个处理器的新数据类型现在是不同的。怎么实现呢?非常感谢任何帮助。

此致

Madhurjya

0 个答案:

没有答案