好文档 - 专业文书写作范文服务资料分享网站

并行程序设计-王刚(2002) 矩阵乘法的并行化的设计与实现

天下 分享 时间: 加入收藏 我要投稿 点赞

* 输入: 无 * 返回值:无 */

void readData() {

int i,j;

starttime = MPI_Wtime();

dataFile=fopen(\

fscanf(dataFile,\列数M,K */

A=(float *)malloc(floatsize*M*K); /* */

for(i = 0; i < M; i++) /* 素 */ {

for(j = 0; j < K; j++) {

fscanf(dataFile,\ } }

fscanf(dataFile,\列数P,N */

if (K!=P) /* K矩阵无法相乘 */ {

printf(\ exit(1); }

B=(float *)malloc(floatsize*K*N); /* */

for(i = 0; i < K; i++) /* B的各元素 */ {

for(j = 0; j < N; j++) {

fscanf(dataFile,\ } }

fclose(dataFile);

printf(\

printf(\读取矩阵A的行,为矩阵A分配空间读入矩阵A的各元读取矩阵B的行,应该等于P,否则为矩阵B分配空间从文件中读入矩阵输出A矩阵的维数

*/

for(i=0;i

for(j=0;j

printf(\输出B矩阵的维数 */

for(i=0;i

for(j=0;j

C=(float *)malloc(floatsize*M*N); /* 为结果矩阵C[M,N]分配空间 */ } /*

* 函数名: gcd

* 功能: 此函数用来返回两个整数的不大于group_size的最大公因子 * 输入: M,N:要求最大公因数的两个整数

* group_size所求公因子必须小于此参数,此参数代表用户指定的通信子大小

* 返回值:M和N的不大于group_size的最大公因子 */

int gcd(int M,int N,int group_size) {

int i;

for(i=M; i>0; i--) {

if((M%i==0)&&(N%i==0)&&(i<=group_size)) return i;

}

return 1; } /*

* 函数名: printResult

* 功能:此函数被rankID为0的进程调用,用来将A,B,C矩阵打印输出给用户, * 并输出用于分发数据和并行计算的时间 * 输入:无 * 返回值:无 */

void printResult() {

int i,j;

printf(\

for(i=0;i

for(j=0;j

endtime=MPI_Wtime(); printf(\

printf(\ printf(\ printf(\ } /*

* 函数名: main

* 功能:程序的主函数

* 输入:argc为命令行参数个数;

* argv为每个命令行参数组成的字符串数组。

* 输出:返回0代表程序正常结束;其它值表明程序出错。 */

int main(int argc, char **argv) {

int i,j,k,l,group_size,mp1,mm1;

MPI_Init(&argc,&argv);

MPI_Comm_size(MPI_COMM_WORLD,&group_size); MPI_Comm_rank(MPI_COMM_WORLD,&myid); p=group_size;

//下面一段程序负责从dataIn.txt文件中读入A[M,K],B[P,N]两个相乘矩阵的数据,

//并为结果矩阵C[M,N]分配空间。C[N,N]=A[M,K]*B[P,N]

//注意这段程序只有编号为0的处理器才执行此步操作 if(myid==0) {

readData(); }

if (myid==0) /* 由编号为0的进程将A,B两矩阵的行列维数M,K,N发送给所有其他进程 */ for(i=1;i

MPI_Send(&M,1,MPI_INT,i,i,MPI_COMM_WORLD); MPI_Send(&K,1,MPI_INT,i,i,MPI_COMM_WORLD); MPI_Send(&N,1,MPI_INT,i,i,MPI_COMM_WORLD); }

else /* 编号非0的进程负责接收A,B两矩阵的行列维数M,K,N */ {

MPI_Recv(&M,1,MPI_INT,0,myid,MPI_COMM_WORLD,&status); MPI_Recv(&K,1,MPI_INT,0,myid,MPI_COMM_WORLD,&status); MPI_Recv(&N,1,MPI_INT,0,myid,MPI_COMM_WORLD,&status); }

p=gcd(M,N,group_size);

m=M/p; /* m代表将矩阵按行分块后每块的行数 */

n=N/p; /* m代表将矩阵按列分块后每块的列数 */

if(myid

a=(float *)malloc(floatsize*m*K); /* a[m,K]用来存储本处理器拥有的矩阵A的行块 */

b=(float *)malloc(floatsize*K*n); /* b[K,n]用来存储此时处理器拥有的矩阵B的列块 */

c=(float *)malloc(floatsize*m*N); /* c[m,N]用来存储本处理器计算p-1次得到所有结果 */

if (myid%2!=0) /* 为标号为奇数的处理器分配发送缓冲空间 */

buffer=(float *)malloc(K*n*floatsize);

if (a==NULL||b==NULL||c==NULL) /* 如果分配空间出错,则打印出错信息 */

printf(\

if (myid==0) /* 标号为0的处理器将应该它拥有的矩阵A,B的元素读入自己的a,b中 */ {

for (i=0;i

for (i=0;i

if (myid==0) /* 标号为0的处理器将其他处理器的初始数据分别发给各处理器 */ {

for (i=1;i

MPI_Send(&A(m*i,0),K*m,MPI_FLOAT,i,i,MPI_COMM_WORLD);

for (j=0;j

MPI_Send(&B(j,n*i),n,MPI_FLOAT,i,i,MPI_COMM_WORLD); }

free(A);

free(B); /* 至此,A,B两矩阵的数据已经完全被分散到各处理器。释放A,B所占空间 */ }

else /* 标号非0的处理器从0处理器接受各自的初始矩阵数据 */ {

MPI_Recv(a,K*m,MPI_FLOAT,0,myid,MPI_COMM_WORLD,&status);

for (j=0;j

MPI_Recv(&b(j,0),n,MPI_FLOAT,0,myid,MPI_COMM_WORLD,&status); }

if (myid==0)

time1=MPI_Wtime(); /* 标号为0的处理器记录开始矩阵相乘计算的时间 */

并行程序设计-王刚(2002) 矩阵乘法的并行化的设计与实现

*输入:无*返回值:无*/voidreadData(){inti,j;starttime=MPI_Wtime();dataFile=fopen(\fscanf(dataFile,\列数M,K*/A=(float*)malloc
推荐度:
点击下载文档文档为doc格式
7uy0w3xxmd9jajr88ky455t2h95xc900wd0
领取福利

微信扫码领取福利

微信扫码分享