我正在尝试使用MPI库解决一个简单的程序。
在过程0上存储4 * N×4 * N矩阵。矩阵每边的长度为DIM LEN = 4 * N.我需要创建一个对角数据类型。但是,不是4 * N,数据类型应该只覆盖对角线上的N个连续元素。然后我必须使用创建的数据类型在MPI程序的进程之间平均分配该矩阵的对角线。总数 进程数为4。
散射后我无法正确接收对角元素。
Non root : 3
Non root : 1
2.000000 0.000000
6.000000 0.000000
Non root : 2
4.000000 0.000000
这是程序
#include "mpi.h"
#include <stdio.h>
#define DIM_LEN 8
int main( int argc, char *argv[] )
{
int myid, numprocs;
double mat[DIM_LEN][DIM_LEN];
double matRcv[DIM_LEN/4];
int i,j;
MPI_Datatype diagonal;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Type_vector(DIM_LEN/4, 1, DIM_LEN +1 , MPI_DOUBLE, &diagonal);
MPI_Type_commit(&diagonal);
if (myid == 0){
printf("Root : %d \n",myid);
for ( i=0; i<DIM_LEN; i++)
for ( j=0; j<DIM_LEN; j++ )
mat[i][j] = i+j;
for ( i=0; i<DIM_LEN; i++){
for ( j=0; j<DIM_LEN; j++ ){
printf("%lf \t",mat[i][j] );
}
printf("\n");
}
/* Scatter the big table to everybody's little table */
}
MPI_Scatter(&mat[0] , 1, diagonal, &matRcv ,1, diagonal, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
if(myid != 0){
printf("Non root : %d \n",myid);
for ( i=0; i<DIM_LEN/4; i++)
printf("%lf ",matRcv[i] );
printf("\n");
}
MPI_Type_free(&diagonal);
MPI_Finalize();
return 0;
}
答案 0 :(得分:0)
行。既然您正确地跨越了diagonal
数据类型,那么您的数据类型应该正确反映您在2D数组mat
中所需的内存位置。但请注意,您的diagonal
数据类型不会反映您在1D数组matRcv
中最终需要的内存位置。您要接收的内存位置是从DIM_LEN/4
开始的matRcv[0]
个连续内存插槽。您可以创建第二种数据类型来描述此内存映射(使用MPI_Type_contiguous
)或更轻松地将其称为DIM_LEN/4
doubles
。
因此,您的MPI_Scatter
电话应如下:
MPI_Scatter(&mat[0], 1, diagonal, &matRcv, DIM_LEN/4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
另请注意,这是一个阻塞集体,所以在调用它之后不需要MPI_Barrier()
;障碍是隐含的。
答案 1 :(得分:0)
// Without this it would not work.
MPI_Type_create_resized(myType, 0, (DIM_LEN+1)*sizeof(int)*4, &colType);
// So resize the userdefined datatype whenever Vector Type is used.
MPI_Type_commit(&colType);
MPI_Scatter(&matrix[0], 1, colType, receiveBuffer, DIM_LEN/4, MPI_INT, 0, MPI_COMM_WORLD);