#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include\"mpi.h\"
main(int argc, char *argv[])
{
int rank;
int size;
int tag=100;
int N1=4;
int N2;
int N3;
int N4;
int N5;
int i,j,k;
int m,n;
int a[N1][N1];
int b[N1][N1];
int c[N1][N1];
int d[N1][N1];
double time1,time2;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
srand(time(NULL));
N2=N1/size;
if(rank==0)
{
for(i=0;i<N1;i++)
{
for(j=0;j<N1;j++)
{
a[i][j]=rand()%10; //設定A矩陣(亂數)//
b[i][j]=rand()%10; //設定B矩陣(亂數)//
c[i][j]=0;
d[i][j]=0;
}
}
printf(\"This is a[i][j]\\n\");
for(i=0;i<N1;i++)
{
for(j=0;j<N1;j++)
{
printf(\"%d \",a[i][j]);
}
printf(\"\\n\");
}
printf(\"This is b[i][j]\\n\");
for(i=0;i<N1;i++)
{
for(j=0;j<N1;j++)
{
printf(\"%d \",b[i][j]);
}
printf(\"\\n\");
}
}
MPI_Barrier(MPI_COMM_WORLD);
time1=MPI_Wtime(); //計算時間用//
MPI_Bcast(a,N1*N1,MPI_INT,0,MPI_COMM_WORLD); //把A矩陣傳給每一台工作的電腦//
MPI_Bcast(b,N1*N1,MPI_INT,0,MPI_COMM_WORLD);//把B矩陣傳給每一台工作的電腦//
printf(\"This is %d\\n\",rank);//每台電腦各自計算分配到的區域//
for(k=rank*N2;k<rank*N2+N2;k++)
{
for(j=0;j<N1;j++)
{
for(i=0;i<N1;i++)
{
// printf(\"m=%d=%d n=%d=%d \",m,n,a[k][i],b[i][j]);
c[k][j]+=a[k][i]*b[i][j];
// printf(\"c[%d][%d]=%d*%d \",k,j,a[k][i],b[i][j]);
// printf(\"a[%d][%d]*b[%d][%d]=%d*%d \",k,i,i,j,a[k][i],b[i][j]);
// printf(\"%d \",c[k][j]);
// if(rank==2&&k==2&&j==3)
// printf(\"c[%d][%d]=a[%d][%d]*b[%d][%d]=%d=%d*%d=%d \",k,j,k,i,i,j,c[k][j],a[k][i],b[i][j],a[k][i]*b[i][j]);
// printf(\"\\n\");
// if(rank==3)
// printf(\"a[%d][%d]*b[%d][%d]=%d*%d \",k,i,i,j,a[k][i],b[i][j]);
}
printf(\"\\n\");
}
printf(\"\\n\");
}
MPI_Gather (c,N2*N1,MPI_INT,d,N2*N1,MPI_INT,0,MPI_COMM_WORLD);
//把每台電腦所得到的答案存到d陣列中,並傳給編號為0的電腦//
time2=MPI_Wtime()-time1;//計算時間//
if(rank==0)
{
// printf(\"Matrix %dx%d with %d processor(s)\\n\",N1,N1,size);
for(k=0;k<N1;k++)
{
for(j=0;j<N1;j++)
{
printf(\"%d \",d[k][j]);//輸出陣列//
}
printf(\"\\n\");
}
printf(\"Total time:%f\\n\",time2);
MPI_Finalize();
}
return(0);
}
基本上這個程式我是設計成"無論幾X幾的矩陣,幾台電腦皆可計算" (前提是矩陣的邊長數可以被電腦的總數給整除) 但是這個程式是測試用的, 故矩陣邊長及工作電腦數量皆設為4; 但是這個程式的問題, 已以下的跑出來的例子來做說明 This is a[i][j] 9 9 4 2 6 9 0 7 5 6 2 2 5 8 2 0 This is b[i][j] 5 0 8 1 4 4 7 7 0 9 2 4 6 2 2 3 這是亂數跑出的兩個矩陣 93 76 147 94 120 0 0 0 120 0 0 0 120 0 0 0 這是答案
在測試之中,給4台電腦跑出來的結果, 是只有process0所負責的部份可以跑出正確的答案, 無論是用多少台電腦都是一樣, 之後再加上一些測試用的程式碼, 發現無論是哪一台電腦, 皆可接收到自己所負責的部份(a,b矩陣有傳過去), 但是在做矩陣相乘的時候所得到的答案卻是錯誤的, 希望對平行處理有研究的大大可以幫忙解答一下,謝謝。 (不知道這樣說明有沒有人聽的懂........)
看到你的回答了, 不知道是我說的不清不楚,還是這隻程式真的寫爛了。 因為之前有參考到類似的程式而做出的簡易程式 a(4*4)乘b(4*1)的,同樣也是分給4台電腦做。 這隻程式就可以跑出正確的答案, 現在有問題的程式是改過擴大版的...... (大大要看的話我在放上來) 對於你的回答我想解釋一下, 我的構想是這樣的, a*b=c的計算,分給4台電腦去做(process0~3) process0負責(c00,c01,c02,c03)的答案計算 process1負責(c10,c11,c12,c13)的答案計算 ......以此類推
以矩陣相乘來說的話 c00=a00*b00+a01*b10+a02*b20+a03*b30 c01=a00*b01+a01*b11+a02*b21+a03*b31 c02=a00*b02+a01*b12+a02*b22+a03*b32 c01=a00*b03+a01*b13+a02*b23+a03*b33 這是process0所負責計算的部份
c10=a10*b00+a11*b10+a12*b20+a13*b30 c11=a10*b01+a11*b11+a12*b21+a13*b31 c12=a10*b02+a11*b12+a12*b22+a13*b32 c11=a10*b03+a11*b13+a12*b23+a13*b33 這是process1所負責計算的部份 ......以此類推
以process0為例, 因為只要做c00,c01,c02,c03的計算, 由上面可得知, a矩陣的資料只需要a00,a01,a02,a03而已, b矩陣的資料則是需要全部。 那一開始我就把這兩個矩陣的資料都傳給各個process, (其實a的部份只要傳1/4而已,我想之後再改) 然後各個process接收到之後,計算完之後再把答案由c傳到d, 再由0輸出, (因為由process0來說,他所獲得的資料只有c00,c01,c02,c03, process1則是c10,c11,c12,c13,所以想用Gather把答案按照順序放在d中再輸出)
至於大大在"齊行"的地方我看不懂,因為我並沒有"全部做一樣的東東", 程式不好請見諒,謝謝。 Cannon's Algorithm