按照@ 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,64
和17,18,…,31,32
,65,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