当前位置:文档之家› 北航并行计算矩阵转置作业

北航并行计算矩阵转置作业

}
fclose(fdA);
}
MPI_Bcast(&size,1,MPI_INT,0,MPI_COMM_WORLD);
t=(int)sqrt(p);
if (t>size)
t=size;
if(size%t!=0)
for(;;)
{
t--;
if(size%t==0)
break;
}
p=t*t;
m=size/t;
p=group_size;
if(my_rank==0)
{
starttime=MPI_Wtime();
fdA=fopen("dataIn.txt","r");
fscanf(fdA,"%d %d", &size, &N);
if(size != N)
{
puts("The input is error!");
{
v= my_rank/t;
u= my_rank%t;
for(i=0;i<m;i++)
for(j=0;j<m;j++)
b(i,j)=a(i,j);
MPI_Recv(a,m*m,MPI_FLOAT, (u*t+v), my_rank,MPI_COMM_WORLD,&status);
MPI_Send(b,m*m,MPI_FLOAT, (u*t+v),(u*t+v),MPI_COMM_WORLD);
double time1;
double time2;
int my_rank;
int p;
MPI_Status status;
FILE *fdA;
void Environment_Finalize(float *a,float *b)
{
free(a);
free(b);
}
int main(int argc, char **argv)
MPI_Finalize();
Environment_Finalize(a,b);
return(0);
}
exit(0);
}
A=(float*)malloc(floatsize*size*size);
B=(float*)malloc(floatsize*size*size);
for(i = 0; i < size; i ++)
{
for(j = 0; j < size; j ++) fscanf(fdA, "%f", A+i*size+j);
for(j=0;j<m;j++)
a(i,j)=A(i,j);
}
if (my_rank==0)
{
for(i=1;i<p;i++)
{
v=i/t;
u=i%t;
for(j=v*m;j<(v+1)*m;j++)
for(k=u*m;k<(u+1)*m;k++)
b((j%m),(k%m))=A(j,k);
MPI_Send(b,m*m,MPI_FLOAT,i,i,MPI_COMM_WORLD);
矩阵转置并行实现
1、算法描述:
若处理器个数为p,且它们的编号依次是0,1,…,p-1,则将n阶矩阵A分成p个大小为mxm的子块,m=[n/p]。p个子块组成一个子块阵列,记其中第i行第j列的子块为Aij,它含有第(i-1)m+1至第im行中的第(j-1)m+1至第jm列的所有元素。对每一处理器按行主方式赋以二维下标,记编号为i的处理器的二维下标为(v,u),其中v=[i/ ],u=imod ,将A的子块存入下标为(v,u)表示的对应处理器中。转置分为两步进行:第一步,子块转置;第二步,处理器内部转置。为了避免对应子块交换数据是处理器发生死锁,可令下三角块先向与之对应的上三角子块发送数据,然后从上三角子块接收数据;上三角子块数据先存放在缓冲区buffer中,然后从与之对应的下三角子块接收数据,最后再将缓冲区中的数据发送给下三角子块,流程图如下所示:
2、程序代码:
#include "stdio.h"
#include "stdlib.h"
#include "mpi.h"
#include "math.h"
#define E 0.0001
#define a(x,y) a[x*m+y]
#define b(x,y) b[x*m+y]
#define A(x,y) A[x*size+y]
}
}
else if(my_rank<p)
MPI_Send(a,m*m,MPI_FLOAT, 0,my_rank,MPI_COMM_WORLD);
if (my_rank==0)
{
printf("Input of file \"dataIn.txt\"\n");
printf("%d\t%d\n", size, size);
{
int i,j,k,my_rank,group_size;
float *a,*b;
int u,v;
float temp;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&group_size);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
printf("Distribute data time = %f seconds\n",time1-starttime);
printf("Parallel compute time = %f seconds\n",time2-time1);
}
MPI_Barrier(MPI_COMM_WORLD);
for(i=0;i<size;i++)
{
for(j=0;j<size;j++) printf("%f\t",A(i,j));
printf("\n");
}
printf("\nOutput of Matrix AT\n");
for(i=0;i<size;i++)
{
for(j=0;j<size;j++) printf("%f\t",B(i,j));
}
for(i=1;i<m;i++)
for(j=0;j<i;j++)
{
temp=a(i,j);
a(i,j)=a(j,i);
a(j,i)=temp;
}
if (my_rank==0)
{
for(i=0;i<m;i++)
for(j=0;j<m;j++)
B(i,j)=a(i,j);
}
if (my_rank==0)
u= my_rank%t;
MPI_Send(a,m*m,MPI_FLOAT, (u*t+v),(u*t+v),MPI_COMM_WORLD);
MPI_Recv(a,m*m,MPI_FLOAT, (u*t+v),my_rank,MPI_COMM_WORLD,&status);
}
if ((my_rank/t)<(my_rank%t)&&my_rank<p)
{
for(i=1;i<p;i++)
{
MPI_Recv(a,m*m,MPI_FLOAT,i,i,MPI_COMM_WORLD,&status);
v= i/t;
u= i%t;
for(j=v*m;j<(v+1)*m;j++)
for(k=u*m;k<(u+1)*m;k++)
B(j,k)=a((j%m),(k%m));
a=(float *)malloc(floatsize*m*m);
b=(float *)malloc(floatsize*m*m);
if (a==NULL||b==NULL)
printf("allocate space fail!");
if (my_rank==0)
{
for(i=0;i<m;i++)
printf("\n");
}
}
time2=MPI_Wtime();
if (my_rank==0)
{
printf("\n");
printf("processor number:%d\n",p);
printf("Whole running time = %f seconds\n",time2-starttime);
}
}
else if (my_rank<p)
MPI_Recv(a,m*m,MPI_FLOAT,0,my_rank,MPI_COMM_WORLD,&status);
time1=MPI_Wtime();
if ((my_rank/t)>(my_rank%t)&&my_rank<p)
相关主题