假设k过程计算矩阵A的元素,其维数为(n,m),其中n为行数,m为列数。我试图使用MPI_GATHER
将这两个矩阵收集到根过程中的矩阵B中,其中B的维数为(n,km)。具体来说,我在下面编写了一个fortran代码示例。这里,我将矩阵A(不是整个矩阵)的列传递给矩阵B,但这是行不通的。当我使用mpirun -n 2 a.out
运行可执行文件时,会得到以下错误:
malloc:*对象0x7ffa89413fb8错误:释放对象的校验和不正确-对象可能在被释放后被修改。
1)为什么我会收到这条错误消息?
2)谁能从概念上解释我为什么要使用MPI_TYPE_VECTOR
?
3)如何纠正代码的MPI_GATHER
部分?我能通过整个矩阵A吗
PROGRAM test
IMPLICIT NONE
INCLUDE "mpif.h"
INTEGER, PARAMETER :: n=100, m=100
INTEGER, ALLOCATABLE, DIMENSION(:,:) :: A
INTEGER, DIMENSION(n,m) :: B
INTEGER :: ind_a, ind_c
INTEGER :: NUM_PROC, PROC_ID, IERROR, MASTER_ID=0
INTEGER :: c
INTEGER, DIMENSION(m) :: cvec
CALL MPI_INIT(IERROR)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, PROC_ID, IERROR)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, NUM_PROC, IERROR)
ALLOCATE(A(n,m/NUM_PROC))
DO ind_c=1,m
cvec(ind_c)=ind_c
END DO
! Fill in matrix A
DO ind_a=1,n
DO ind_c=1,m/NUM_PROC
c=cvec(ind_c+PROC_ID*m/NUM_PROC)
A(ind_a,ind_c)=c*ind_a
END DO
END DO
! Gather the elements at the root process
DO ind_a=1,n
CALL MPI_GATHER(A(ind_a,:),m/NUM_PROC,MPI_INTEGER,B(ind_a,PROC_ID*m/NUM_PROC+1:(PROC_ID+1)*m/NUM_PROC),m/NUM_PROC,MPI_INTEGER,MASTER_ID,MPI_COMM_WORLD,IERROR)
END DO
CALL MPI_FINALIZE(IERROR)
END PROGRAM
发布于 2016-02-07 01:08:45
有两种类型的集合操作可以在二维数组中执行。1.从整个过程的维-2中收集元素,在一个过程的维-2中收集元素;2.从过程的维度-2中收集元素,并在一个过程的维-1中收集元素。
在这个例子中,n=维-1和m=维-2,我们知道Fortran是列大调。因此,在Fortran中,维-1是连续的.
在proc语句中,您试图从所有进程中收集数组的维度2-A,并将其收集到MASTER_ID proc中的Array-B的维度-2中(类型-1)。由于维-2在内存中是不连续的,这就导致了分割错误.
下面所示的单个MPI_Gather调用将达到所需的操作,而不需要任何循环技巧,如上面所示:
CALL MPI_GATHER(A, n*(m/NUM_PROC), MPI_INTEGER, & B, n*(m/NUM_PROC), MPI_INTEGER, MASTER_ID, & MPI_COMM_WORLD, IERROR)
但是,如果您试图在MASTER_ID proc中从数组的第2维收集元素-A的所有进程到数组的维度-1,即当我们需要使用MPI_TYPE_VECTOR时,我们使用非连续元素创建一个新类型。让我知道这是否是目的。
因为,当前的代码逻辑看起来不需要使用MPI_TYPE_VECTOR。
https://stackoverflow.com/questions/35246331
复制相似问题