通过使用 MPI 创建 2d 拓扑的矩阵乘法
Posted
技术标签:
【中文标题】通过使用 MPI 创建 2d 拓扑的矩阵乘法【英文标题】:Matrix Multiplication by creating 2d topology using MPI 【发布时间】:2013-05-16 11:37:40 【问题描述】:我通过创建二维拓扑将 MPI 中的 2 个矩阵相乘 我收到了错误
An error occurred in MPI_Type_create_struct
on communicator MPI_COMM_WORLD
MPI_ERR_TYPE: invalid datatype
*** MPI_ERRORS_ARE_FATAL (your MPI job will now abort)
--------------------------------------------------------------------------
mpiexec has exited due to process rank 0 with PID 21294 on
node hpc-nist.nist.local exiting without calling "finalize". This may
have caused other processes in the application to be
terminated by signals sent by mpiexec (as reported here)
我知道它发生在第 74 行,但不知道为什么一切似乎都很好
#include<mpi.h>
#include<stdio.h>
#include<stdlib.h>
#define NUM_ROW_A 225
#define NUM_COL_A 300
#define NUM_ROW_B 300
#define NUM_COL_B 150
int main()
double a[NUM_ROW_A][NUM_COL_A],b[NUM_ROW_B][NUM_COL_B],c[NUM_ROW_A][NUM_COL_B];
int n[3]=NUM_ROW_A,NUM_COL_A,NUM_COL_B;
int p[2]=3,2;
MPI_Comm comm =MPI_COMM_WORLD;
MPI_Comm comm_2d,comm_1d[2],pcomm;
int nn[2];
double aa[3][NUM_COL_A],bb[NUM_COL_A][2],cc[3][2];
int coords[2];
int rank;
int *dispc,*countc;
int i,j,k;//ierr;
int periods[2]=0,0;
int remains[2];
//int sizeofdouble=sizeof(double);
MPI_Aint sizeofreal;
double s_time,f_time;
MPI_Datatype typea,typec,types[2];
int blen[2];
MPI_Aint disp[2];
MPI_Init(NULL,NULL);
s_time=MPI_Wtime();
MPI_Comm_dup(comm,&pcomm);
MPI_Bcast(n,3,MPI_INT,0,pcomm);
MPI_Bcast(p,2,MPI_INT,0,pcomm);
//periods=0,0;
MPI_Cart_create(pcomm,2,p,periods,0,&comm_2d);
MPI_Comm_rank(comm_2d,&rank);
MPI_Cart_coords(comm_2d,rank,2,coords);
for(i=0;i<2;i++)
for(j=0;j<2;j++)
remains[j]=(i==j);
MPI_Cart_sub(comm_2d,remains,&comm_1d[i]);
nn[0]=n[0]/p[0];
nn[1]=n[2]/p[1];
if(rank==0)
for(i=0; i<n[0]; i++)
for(j=0; j<n[1]; j++)
double randNr = (rand()/9.9);
a[i][j] = randNr;
for(i=0; i<n[1]; i++)
for(j=0; j<n[2]; j++)
double randNr = (rand()/9.9);
b[i][j] = randNr;
MPI_Type_vector(n[1],nn[0],n[0],MPI_DOUBLE,&types[0]);
MPI_Type_extent(MPI_DOUBLE,&sizeofreal);
disp[0]=0;
disp[1]=sizeofreal*nn[0];
blen[0]=1;
blen[1]=1;
types[2]=MPI_UB;
printf("hi%ld\n",disp[1]);
MPI_Type_struct(2,blen,disp,types,&typea);
printf("hi\n");
MPI_Type_commit(&typea);
MPI_Type_vector(nn[1],nn[0],n[0],MPI_DOUBLE,&types[1]);
MPI_Type_struct(2,blen,disp,types,&typec);
MPI_Type_commit(&typec);
dispc=(int *)malloc(p[0]*p[1]*sizeof(int));
countc=(int *)malloc(p[0]*p[1]*sizeof(int));
for(i=0;i<p[0];i++)
for(j=0;j<p[1];j++)
dispc[(i-1)*p[1]+j]=((j-1)*p[0]+(i-1)*nn[1]);
countc[(i-1)*p[1]+j]=1;
printf("hi\n");
if(coords[1]==0)
MPI_Scatter(a,1,typea,aa,nn[0]*n[1],MPI_DOUBLE,0,comm_1d[0]);
if(coords[0]==0)
MPI_Scatter(b,n[1]*nn[1],MPI_DOUBLE,bb,n[1]*nn[1],MPI_DOUBLE,0,comm_1d[1]);
MPI_Bcast(aa,nn[0]*n[1],MPI_DOUBLE,0,comm_1d[1]);
MPI_Bcast(bb,n[1]*nn[1],MPI_DOUBLE,0,comm_1d[0]);
for(i=0;i<nn[0];i++)
for(j=0;j<nn[1];j++)
cc[i][j]=0.0;
for(k=0;k<n[1];k++)
cc[i][j]+=a[i][k]*b[k][j];
MPI_Gatherv(cc,nn[0]*nn[1],MPI_DOUBLE,c,countc,dispc,typec,0,comm_2d);
f_time=MPI_Wtime();
if(rank==0)
printf("matrix a:\n");
for(i=0;i<n[0];i++)
for(j=0;j<n[1];j++)
printf("%lf\t",a[i][j]);
printf("\n");
printf("matrix b:\n");
for(i=0;i<n[1];i++)
for(j=0;j<n[2];j++)
printf("%lf\t",b[i][j]);
printf("\n");
printf("matrix c:\n");
for(i=0;i<n[0];i++)
for(j=0;j<n[2];j++)
printf("%lf\t",c[i][j]);
printf("\n");
printf("time take = %1.2lf\n",f_time-s_time);
MPI_Finalize();
return 0;
【问题讨论】:
说真的老兄,如果你需要任何帮助,你必须让 SO 更容易。你的代码缩进太多,需要左右滚动;拨回。您声明错误发生在第 74 行;如果你已经标记了那条线,我看不到它,我不打算开始计算线。最后,您似乎已经发布了整个代码并邀请 SO 对其进行整理。哪里有证据表明你认真地努力解决自己的问题?证明您报告的错误的最小可编译程序等证据。 【参考方案1】:你的错误不在74
线上,而是在I_AM_TOO_LAZY_TO_COUNT
线上:
types[2] = MPI_UB;
^
这很可能改为types[1] = MPI_UB;
。
【讨论】:
谢谢老兄,我也想到了,但后来又出现了另一个问题,现在它给出了信号:总线错误(7)在地址 nil 失败我是 MPI 新手,不知道如何解决这个错误关于 MPI_Error 的书籍也没有多大帮助,请您帮忙 好吧,我发现错误出现在 if(coords[0]==0) MPI_Scatter(b,n[1]*nn[1],MPI_DOUBLE,bb,n[ 1]*nn[1],MPI_DOUBLE,0,comm_1d[1]);我已经检查了 coords(2 个进程,共 6 个,有 coords[0]=0),comm_1d,还好它不能分散,任何帮助??? 好吧,我也反驳了这一点,bb 内存分配不是应该的,所以我动态地将所有 aa bb 和 cc 分配为双指针。但错误依旧。以上是关于通过使用 MPI 创建 2d 拓扑的矩阵乘法的主要内容,如果未能解决你的问题,请参考以下文章
numpy 和 tensorflow 中的各种乘法(点乘和矩阵乘)