MPI——矩阵乘法


#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include "mpi.h"

#define N 3

int main(int argc,char **argv)
{
MPI_Init(&argc,&argv);
int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);

int m=atoi(argv[1]);
int n=atoi(argv[2]);
int block=(m+size-1)/size*n;
if(rank==size-1 && block>m*n-(size-1)*block) block=m*n-(size-1)*block;

int *A=NULL;
int *TA=(int*)malloc(block*sizeof(int));
int **B=(int**)malloc(m*sizeof(int*));
int *counts=NULL;
int *ofss=NULL;
int i,j;

for(i=0;i<m;++i)
B[i]=(int*)malloc(n*sizeof(int));
if(rank==0)
{
counts=(int*)malloc(size*sizeof(int));
ofss=(int*)malloc(size*sizeof(int));
for(i=0;i<size-1;++i)
{
counts[i]=block;
ofss[i]=i*block;
}
counts[i]=block<=m*n-i*block?block:m*n-i*block;
ofss[i]=i*block;
//for(i=0;i<size;++i)
// printf("%d\t%d\n",counts[i],ofss[i]);
// printf("constructing %d * %d matrix\n",m,n);
A=(int*)malloc(m*n*sizeof(int));
srand((int)time(0));
for(i=0;i<m;++i)
{
for(j=0;j<n;++j)
{
A[i*n+j]=(int)rand()%N;
B[i][j]=(int)rand()%N;
}
}
/* printf("A:\n");
for(i=0;i<m;++i)
{
for(j=0;j<n;++j)
printf("%d\t",A[i*n+j]);
printf("\n");
}
printf("B:\n");
for(i=0;i<n;++i)
{
for(j=0;j<m;++j)
printf("%d\t",B[j][i]);
printf("\n");
}*/
}
for(i=0;i<m;++i)
MPI_Bcast(B[i],n,MPI_INT,0,MPI_COMM_WORLD);
MPI_Scatterv(A,counts,ofss,MPI_INT,TA,block,MPI_INT,0,MPI_COMM_WORLD);
/*printf("B in %d:\n",rank);
for(i=0;i<m;++i)
{
for(j=0;j<n;++j)
printf("%d\t",B[i][j]);
printf("\n");
}
printf("A in %d\n",rank);
for(i=0;i<block;++i)
printf("%d\t",TA[i]);
printf("\n");*/

int col=block/n;

int *RETA=(int*)malloc(col*m*sizeof(int));
int *RES=NULL;
if(rank==0)
RES=(int*)malloc(m*m*sizeof(int));

int k;
for(k=0;k<m;++k)
{
for(i=0;i<col;++i)
{
int tmp=0;
for(j=0;j<n;++j)
tmp+=TA[i*n+j]*B[k][j];
RETA[i*m+k]=tmp;
}
}
if(rank==0)
{
ofss[0]=0;
counts[0]=col*m;
for(i=1;i<size;++i)
{
counts[i]=counts[i]/n*m;
ofss[i]=ofss[i-1]+counts[i-1];
}
}
MPI_Gatherv(RETA,col*m,MPI_INT,RES,counts,ofss,MPI_INT,0,MPI_COMM_WORLD);

if(rank==0)
{
printf("A:\n");
for(i=0;i<m;++i)
{
printf("[\t");
for(j=0;j<n;++j)
printf("%d\t",A[i*n+j]);
printf("]\n");
}
printf("B:\n");
for(i=0;i<n;++i)
{
printf("[\t");
for(j=0;j<m;++j)
printf("%d\t",B[j][i]);
printf("]\n");
}
printf("=:\n");
for(i=0;i<m;++i)
{
printf("[\t");
for(j=0;j<m;++j)
printf("%d\t",RES[i*m+j]);
printf("]\n");
}
free(A);
free(counts);
free(ofss);
free(RES);
}
free(TA);
free(RETA);
for(i=0;i<m;++i)
free(B[i]);
free(B);

MPI_Finalize();
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于MPI实现矩阵乘法的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <mpi.h> #define N 100 int main(int argc, char *argv[]) { int rank, size; int i, j, k; int A[N][N], B[N][N], C[N][N]; int rowA[N], rowC[N]; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size != N) { printf("Error: number of processes must be %d\n", N); MPI_Finalize(); return 0; } // Initialize matrices A and B for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { A[i][j] = i + j; B[i][j] = i - j; C[i][j] = 0; } } // Scatter matrix A to all processes MPI_Scatter(A, N*N/N, MPI_INT, rowA, N, MPI_INT, 0, MPI_COMM_WORLD); // Broadcast matrix B to all processes MPI_Bcast(B, N*N, MPI_INT, 0, MPI_COMM_WORLD); // Compute rows of matrix C for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { rowC[j] = 0; for (k = 0; k < N; k++) { rowC[j] += rowA[k] * B[k][j]; } } MPI_Reduce(rowC, &C[i], N, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); } // Gather matrix C from all processes MPI_Gather(rowC, N*N/N, MPI_INT, C, N*N/N, MPI_INT, 0, MPI_COMM_WORLD); // Print matrix C if (rank == 0) { printf("Matrix C:\n"); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { printf("%d ", C[i][j]); } printf("\n"); } } MPI_Finalize(); return 0; } ``` 该程序将矩阵A均分给所有进程,每个进程计算矩阵C的一行。使用MPI_Reduce函数将每个进程计算出的行向量相加,得到最终的矩阵C。最后,使用MPI_Gather函数将矩阵C收集到进程0中,并打印输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值