C 用MPI发送/接收实现自己的矩阵乘法

C 用MPI发送/接收实现自己的矩阵乘法,c,mpi,C,Mpi,我试图编写一个名为matrixMultiply的函数,它只需要取两个名为a和b的4x4矩阵,将它们相乘,并将结果存储在4x4矩阵c中。在这之后,我想把程序扩展成一个更通用的程序,用于nxn矩阵。遗憾的是,程序编译了,但在执行过程中被卡住了。我将非常感谢你们中的某个人能告诉我我的错误在哪里 #import <stdio.h> #import "mpi.h" void matrixMultiply(int argc, char* argv[], int a[][4], int b[][

我试图编写一个名为matrixMultiply的函数,它只需要取两个名为a和b的4x4矩阵,将它们相乘,并将结果存储在4x4矩阵c中。在这之后,我想把程序扩展成一个更通用的程序,用于nxn矩阵。遗憾的是,程序编译了,但在执行过程中被卡住了。我将非常感谢你们中的某个人能告诉我我的错误在哪里

#import <stdio.h>
#import "mpi.h"

void matrixMultiply(int argc, char* argv[], int a[][4], int b[][4], int c[][4])
{
    int n = 4;
    int procs;
    int rank;
    int rootRank = 0;

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD, &procs);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if(rank == rootRank) {
        int current_row[4];
        for(int i = 0; i < n; i++) {

            int current_column[4];
            for(int j = 0; j < n; j++) {

                //getting the i-th row
                for(int k = 0; k < n; k++) {
                    current_row[k] = a[i][k];
                }

                //getting the j-th column
                for (int k = 0; k < n; k++)
                {
                    current_column[k] = b[k][j];
                }

                //MPI_Send(void* data, int count, MPI_Datatype datatype, int destination, int tag, MPI_Comm communicator)
                MPI_Bsend(current_row, 4, MPI_INT, i, 0, MPI_COMM_WORLD);
                MPI_Bsend(current_column, 4, MPI_INT, i, 1, MPI_COMM_WORLD);

                int result;
                //MPI_Recv(void* data, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm communicator, MPI_Status* status)
                MPI_Recv(&result, 1, MPI_INT, i ,2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
                c[i][j]=result;
            }
        }

        /* this code is only used to check the resulting matrix c*/
        printf("c:\n");
        for(int i = 0; i < 4; i++) {
            for(int j = 0; j < 4; j++) {
                printf("%d ", c[i][j]);
            }
            printf("\n");
        }
        printf("\n");

    }
    else {
        int result = 0;
        int local_row[4] = {0,0,0,0};
        int local_column[4] = {2,2,2,2};

        //MPI_Recv(void* data, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm communicator, MPI_Status* status)
        MPI_Recv(local_row, 4, MPI_INT, rootRank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        MPI_Recv(local_column, 4, MPI_INT, rootRank, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

        for(int i = 0; i < 4; i++) {
            result+= local_row[i] * local_column[i];
        }

        //MPI_Send(void* data, int count, MPI_Datatype datatype, int destination, int tag, MPI_Comm communicator)
        MPI_Bsend(&result, 1, MPI_INT, rootRank, 2, MPI_COMM_WORLD);
    }
    MPI_Finalize();
    return;
}

int main(int argc, char* argv[]) {
    int d[][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12},{13,14,15,16}};
    int e[][4] = {{16,15,14,13}, {12,11,10,9}, {8,7,6,5}, {4,3,2,1}};
    int f[][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}};

    matrixMultiply(argc, argv, d, e, f);

}
#导入
#导入“mpi.h”
无效矩阵倍数(int argc,char*argv[],int a[][4],int b[][4],int c[][4])
{
int n=4;
int程序;
整数秩;
int rootRank=0;
MPI_Init(&argc,&argv);
MPI通信大小(MPI通信世界和过程);
MPI通信等级(MPI通信世界和等级);
if(秩==根秩){
int当前_行[4];
对于(int i=0;i
需要解决的几个问题:

MPI\u Bsend
(与
MPI\u Send
相反)需要先调用
MPI\u Buffer\u attach
。请参阅此处的注释:或MPI规范的任何最新版本

先试试这个变化。这可能足以让它继续下去。如果没有,请仔细检查发送和接收的顺序(全局考虑),以查看系统中是否存在死锁

另一方面,您可以通过切换到非阻塞发送和接收(
MPI-Isend
MPI-Irecv
及相关),并在启动后通过
MPI-Waitall
MPI-Testall
或类似方式来完成,从而提高性能并避免某些死锁情况。这与MPI实现通常在引擎盖下执行集体操作的方式更为相似——这也可能比单独发送和接收呼叫具有性能优势,因为MPI实现更了解硬件和引擎盖下发生的事情,并且能够围绕这一点优化排序。您所做的看起来像是一个
MPI\u Bcast
,然后是一个
MPI\u聚集
,这是一种可能的替代模式,它将更加依赖于实现来为您进行优化。

请修剪您的代码(例如,使其成为一个新的)。一般来说,<代码> MPIY-BSEND()/<代码>是邪恶的,你应该考虑另一种方法。另外,请说明您正在运行多少MPI任务。