#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<math.h>
#include <string.h>
#include "mpi.h"
#define matrixLength 8
#define matrixMaxValue 50
void initialMatrix(int matrixA[matrixLength][matrixLength],int matrixB[matrixLength][matrixLength])
{int i=-1;
int j=-1;
for(i=0;i<matrixLength;i++)
for(j=0;j<matrixLength;j++)
{matrixA[i][j]=i*matrixLength+j;
matrixB[i][j]=1;
}
}
int main(int argc, char *argv[])
{
/*serial implementation*/
int rank,nproc;
MPI_Init( &argc, &argv );
MPI_Comm_size( MPI_COMM_WORLD, &nproc);
MPI_Comm_rank( MPI_COMM_WORLD, &rank);
const int childMatrixLength=matrixLength/(int)pow(nproc,0.5);
int A[childMatrixLength][childMatrixLength];//every process has a small matrix
int B[childMatrixLength][childMatrixLength];
int C[childMatrixLength][childMatrixLength];
int tempA[matrixLength*matrixLength];
int tempB[matrixLength*matrixLength];
int i=-1;
int j=-1;
memset(C,0,matrixLength*matrixLength/nproc*sizeof(int));
srand(time(0));
if(0==rank)
{int matrixA[matrixLength][matrixLength];
int matrixB[matrixLength][matrixLength];
initialMatrix(matrixA,matrixB);
int tempCount=0;
int i=-1;
int j=-1;
for(i=0;i<pow(nproc,0.5);i++)
for(j=0;j<pow(nproc,0.5);j++)
{int row=-1;
int col=-1;
for(row=i*childMatrixLength;row<(i+1)*childMatrixLength;row++)
for(col=j*childMatrixLength;col<(j+1)*childMatrixLength;col++)
{
tempA[tempCount]=matrixA[row][col];
tempB[tempCount]=matrixB[row][col];
tempCount++;
}
}
for(i=0;i<matrixLength*matrixLength;i++)
printf("%d ",tempA[i]);
printf("\n");
}
MPI_Scatter(tempA,childMatrixLength*childMatrixLength,MPI_INT,A,childMatrixLength*childMatrixLength,MPI_INT,0,MPI_COMM_WORLD);
MPI_Scatter(tempB,childMatrixLength*childMatrixLength,MPI_INT,B,childMatrixLength*childMatrixLength,MPI_INT,0,MPI_COMM_WORLD);
/*parallel implementation fox*/
int messageCount=0;
int receiveDataRow[childMatrixLength][childMatrixLength];
int receiveDataCol[childMatrixLength][childMatrixLength];
for(i=0;i<childMatrixLength;i++)
for(j=0;j<childMatrixLength;j++)
{receiveDataRow[i][j]=A[i][j];
receiveDataCol[i][j]=B[i][j];
}
while(messageCount!=(int)pow(nproc,0.5))
{
//printf("messageCount:%d\n",messageCount);
//printf("abs %d\n",abs(rank/matrixLength-rank%matrixLength));
//if(messageCount==abs(rank/matrixLength-rank%matrixLength))//prpcess(i,j)(j>=i) send data to the process of ith row.
if(rank==((rank/(int)pow(nproc,0.5)*(int)pow(nproc,0.5)
+rank/(int)pow(nproc,0.5)+messageCount-rank/(int)pow(nproc,0.5)*(int)pow(nproc,0.5))
%(int)pow(nproc,0.5)+rank/(int)pow(nproc,0.5)*(int)pow(nproc,0.5)))
{
printf("sendrank:%d messageCount: %d\n",rank,messageCount);
int i=-1;
int start=rank/(int)pow(nproc,0.5)*(int)pow(nproc,0.5);
for(i=start;i<start+(int)pow(nproc,0.5);i++)
{
MPI_Request request;
MPI_Isend(A,childMatrixLength*childMatrixLength,MPI_INT,i,rank,MPI_COMM_WORLD,&request);
}
}
MPI_Status status;
int sourceProcessRow=((rank/(int)pow(nproc,0.5))*(int)pow(nproc,0.5)+
rank/(int)pow(nproc,0.5)+messageCount-(rank/(int)pow(nproc,0.5))*(int)pow(nproc,0.5))
%(int)pow(nproc,0.5)+(rank/(int)pow(nproc,0.5))*(int)pow(nproc,0.5);
//printf("A:rank:%d from %d\n",rank,sourceProcessRow);
MPI_Recv(receiveDataRow,childMatrixLength*childMatrixLength,MPI_INT,sourceProcessRow,sourceProcessRow,MPI_COMM_WORLD,&status);//receive row data
//C=C+receiveDataRow*receiveDataCol;//********
int i=-1;
int j=-1;
int ci=-1;
for(i=0;i<childMatrixLength;i++)
for(j=0;j<childMatrixLength;j++)
for(ci=0;ci<childMatrixLength;ci++)
C[i][j]=C[i][j]+receiveDataRow[i][ci]*receiveDataCol[ci][j];
messageCount++;
//printf("rank: %d messageCount: %d\n",rank,messageCount);
int destProcess=(rank/(int)pow(nproc,0.5)-1+(int)pow(nproc,0.5))%(int)pow(nproc,0.5)*(int)pow(nproc,0.5)+rank%(int)pow(nproc,0.5);
MPI_Request request;
MPI_Isend(receiveDataCol,childMatrixLength*childMatrixLength,MPI_INT,destProcess,rank,MPI_COMM_WORLD,&request);//Every process(i,j) send matrixB to(i-1,j)
int sourceProcessCol=(rank/(int)pow(nproc,0.5)+1)%(int)pow(nproc,0.5)*(int)pow(nproc,0.5)+rank%(int)pow(nproc,0.5);
MPI_Recv(receiveDataCol,childMatrixLength*childMatrixLength,MPI_INT,sourceProcessCol,sourceProcessCol,MPI_COMM_WORLD,&status);//Every process(i,j) receive matrixB to(i+1,j)
//printf("C[%d,%d]=+A[%d,%d]*B[%d,%d]\n",row,col,sourceProcessRow/(int)pow(nproc,0.5),sourceProcessRow%(int)pow(nproc,0.5),sourceProcessCol/(int)pow(nproc,0.5)-1,sourceProcessCol%(int)pow(nproc,0.5));
}
int allValue[matrixLength*matrixLength];
MPI_Gather(C,childMatrixLength*childMatrixLength,MPI_INT,allValue,childMatrixLength*childMatrixLength, MPI_INT, 0,MPI_COMM_WORLD);
///problem!!!!!!!!!!!!!!!!!
if(0==rank)
{int ultimate[matrixLength][matrixLength];
int tempCount=0;
for(i=0;i<pow(nproc,0.5);i++)
for(j=0;j<pow(nproc,0.5);j++)
{int row=-1;
int col=-1;
for(row=i*childMatrixLength;row<(i+1)*childMatrixLength;row++)
for(col=j*childMatrixLength;col<(j+1)*childMatrixLength;col++)
{
ultimate[row][col]=allValue[tempCount];
tempCount++;
}
}
printf("************************\n");
for(i=0;i<matrixLength;i++)
{for(j=0;j<matrixLength;j++)
printf("%d ",ultimate[i][j]);
printf("\n");
}
printf("************************\n");
}
MPI_Finalize();
return 0;
}
fox 算法 mpi 实现
最新推荐文章于 2023-02-24 14:49:32 发布