使用MPI_gatherv从其他较小的矩阵创建新矩阵

时间:2018-04-06 21:58:46

标签: fortran mpi

我认为每个处理器都有自己独特的矩阵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)

我试图理解为什么我需要第二个派生类型来接收。我不确定那个应该是什么样的。

0 个答案:

没有答案
相关问题