我认为每个处理器都有自己独特的矩阵A
,大小为Nx2
,其中N随处理器而变化。我想将所有这些矩阵收集到一个buff (NxP)x2
矩阵中,其中P是处理器的数量。
Fortran中的大小明智,它们被分配为,
A(N,2)
buff(N*P,2)
例如,让P = 2
和每个处理器的A矩阵为
for Proc-1
10 11
10 11
for Proc-2
20 21
20 21
为此,我使用MPI_GATHERV
并将各个矩阵保存在buff矩阵中。如果我这样做,那么buff将会是这样的,
10 20
10 20
11 21
11 21
但我想要的是矩阵看起来像这样,
10 11
10 11
20 21
20 21
在记忆中(我认为)Buff:|10 , 10 , 20, 20 , 11 , 11 , 21 , 21|
示例代码如下,
...
! size = 2
root = 0
ALLOCATE ( count(size), num(size) )
! -----------------------------------------------------------
! Mock data
! -----------------------------------------------------------
IF(rank.eq.0) THEN
m = 2
mm = m*2
allocate(A(m,2))
A(1,1) = 10
A(1,2) = 11
A(2,1) = 10
A(2,2) = 11
ELSE
m = 2
mm = m*2
allocate(A(m,2))
A(1,1) = 20
A(1,2) = 21
A(2,1) = 20
A(2,2) = 21
END IF
! -----------------------------------------------------------
! send number of elements
! -----------------------------------------------------------
CALL MPI_GATHER(mm,1,MPI_INTEGER,count,1,MPI_INTEGER,root,cworld,ierr)
! -----------------------------------------------------------
! Figure out displacement vector needed for gatherv
! -----------------------------------------------------------
if(rank.eq.0) THEN
ALLOCATE (buff(SUM(count)/2,2), disp(size), rdisp(size))
rdisp = count
disp(1) = 0
DO i = 2,size
disp(i) = disp(i-1) + count(i-1)
END DO
END IF
! -----------------------------------------------------------
! Rank-0 gathers msg
! -----------------------------------------------------------
CALL MPI_GATHERV(A,mm,MPI_INTEGER,buff,rdisp,disp,MPI_INTEGER,root,cworld,ierr)
! -----------------------------------------------------------
! Print buff
! -----------------------------------------------------------
if(rank.eq.0) THEN
DO i = 1,sum(count)/2
print*, buff(i,:)
end do
END IF
我看过Using Gatherv for 2d Arrays in Fortran,但对解释感到有些困惑。
我对MPI细节不是很熟悉,但是有一种“简单”的方法来收集所有矩阵并将它们放在buff的正确记忆位置吗?
****编辑****
想念Gilles Gouaillardet所说的话。我想知道如何做到这一点,
发送行的派生类型应该看起来像这样(我认为),
CALL MPI_TYPE_vector(2,1,2,MPI_INTEGER,MPI_ROWS,ierr)
CALL MPI_TYPE_COMMIT(MPI_ROWS,ierr)
然后我延伸,
call MPI_Type_size(MPI_INTEGER, msg_size, ierr)
lb = 0
extent = 2*msg_size
call MPI_Type_create_resized(MPI_ROWS, lb, extent , MPI_ROWS_extend, ierr)
CALL MPI_TYPE_COMMIT(, MPI_ROWS_extend,ierr)
我试图理解为什么我需要第二个派生类型来接收。我不确定那个应该是什么样的。