mpi实现矩阵相乘

主要是用了mpi中的MPI_Scatter()和MPI_Gather()函数

#include<stdio.h>
#include<string.h>
#include<mpi.h>
#include <malloc.h>
int main(void){
int comm_sz;
int my_rank;
int size=1000;
int *a,*b,*result,*local_a,*local_result;
int m,n,k;//a矩阵为m*n,b矩阵为n*k
int local_m;
a=(int*)malloc(sizeof(int)*size*size);
b=(int*)malloc(sizeof(int)*size*size);
result=(int*)malloc(sizeof(int)*size*size);
//由于不知道俩矩阵的大小,但最大为1000*1000,所以先将所有初始化为1000*1000

MPI_Init(NULL,NULL);
MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
//0号进程用于读取矩阵,分发数据,一部分计算和聚集打印数据
if(my_rank==0){
    printf("Enter the numbers of first matrix's rows :");
    scanf("%d",&m);
    printf("Enter the numbers of first maxtrix's columns :");
    scanf("%d",&n);
    int i,j;

    for(i=0;i<m*n;i++)
    {
        printf("Enter the first matrix one by one :");
        scanf("%d",&a[i]);
    }


    printf("Enter the numbers of second maxtrix's columns :");
    scanf("%d",&k);

    for(j=0;j<k*n;j++)
    {
        printf("Enter the second matrix one by one :");
        scanf("%d",&b[j]);
    }

    //由于只有0号进程读取到m,n,k,但是其他进程计算中都需要用到,所以将它们广播到其他进程
    MPI_Bcast(&m,1,MPI_INT,0,MPI_COMM_WORLD);
    MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
    MPI_Bcast(&k,1,MPI_INT,0,MPI_COMM_WORLD);

    //分发数据
    local_m=m/comm_sz;
    local_a=(int *)malloc(sizeof(int)*local_m*n);    
    MPI_Scatter(a,local_m*n,MPI_INT,local_a,local_m*n,MPI_INT,0,MPI_COMM_WORLD);

    //将b矩阵广播到其他进程
    MPI_Bcast(b,n*k,MPI_INT,0,MPI_COMM_WORLD);

    //进行分得的部分计算
    local_result=(int *)malloc(sizeof(int)*local_m*k);
    int p;
    for(i=0;i<local_m;i++)
        for(j=0;j<k;j++)
        {
            local_result[i*k+j]=0;
            for(p=0;p<n;p++)
                local_result[i*k+j]+=local_a[i*n+p]*b[p*k+j];
        }
    //将各进程结果聚集到result矩阵
    MPI_Gather(local_result,local_m*k,MPI_INT,result,local_m*k,MPI_INT,0,MPI_COMM_WORLD);

    //不能整除的情况下a剩余行的处理
    int rest=m%comm_sz;
    if(rest!=0){
        for(i=m-1-rest;i<m;i++)
            for(j=0;j<k;j++)
            {
                result[i*k+j]=0;
                for(p=0;p<n;p++)
                    result[i*k+j]+=a[i*n+p]*b[p*k+j];
            }
    }
    free(a);
    free(b);
    free(local_a);
    free(local_result);

    将result中结果打印出来
    for(i=0;i<m;i++)
    {
        for(j=0;j<k;j++)
            printf("%d ",result[i*k+j]);
        printf("\n");
    }
    free(result);
}else{
    //其他进程所做的工作和0号进程的计算是一模一样的,所以可以直接复制代码
    int i,j;
    MPI_Bcast(&m,1,MPI_INT,0,MPI_COMM_WORLD);
    MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
    MPI_Bcast(&k,1,MPI_INT,0,MPI_COMM_WORLD);           

    local_m=m/comm_sz;
    local_a=(int *)malloc(sizeof(int)*local_m*n);    
    MPI_Scatter(a,local_m*n,MPI_INT,local_a,local_m*n,MPI_INT,0,MPI_COMM_WORLD);

    MPI_Bcast(b,n*k,MPI_INT,0,MPI_COMM_WORLD);
    local_result=(int *)malloc(sizeof(int)*local_m*k);
    int p;
    for(i=0;i<local_m;i++)
        for(j=0;j<k;j++)
        {
            local_result[i*k+j]=0;
            for(p=0;p<n;p++)
                local_result[i*k+j]+=local_a[i*n+p]*b[p*k+j];
        }
    MPI_Gather(local_result,local_m*k,MPI_INT,result,local_m*k,MPI_INT,0,MPI_COMM_WORLD);
    free(a);
    free(b);
    free(local_a);
    free(local_result);
    free(result);
}
MPI_Finalize();
return 0;
}       
展开阅读全文

没有更多推荐了,返回首页