C MPI矩阵乘法,进程未清理

C MPI矩阵乘法,进程未清理,c,matrix,parallel-processing,mpi,C,Matrix,Parallel Processing,Mpi,我正在尝试使用MPI乘以两个nxn矩阵。第二个矩阵(bb)被广播到所有“从属”,然后从第一个矩阵(aa)发送一行来计算乘积。然后将答案发送回主流程,并存储在产品矩阵cc中。出于某种原因,我得到了错误: = BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES = EXIT CODE: 11 = CLEANING UP REMAINING PROCESSES = YOU CAN IGNORE THE BELOW CLEANUP M

我正在尝试使用MPI乘以两个nxn矩阵。第二个矩阵(bb)被广播到所有“从属”,然后从第一个矩阵(aa)发送一行来计算乘积。然后将答案发送回主流程,并存储在产品矩阵cc中。出于某种原因,我得到了错误:

=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   EXIT CODE: 11
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
我相信主进程正在接收从进程发送的所有消息,反之亦然,所以我不确定这里发生了什么。。。有什么想法吗

主要内容:

#包括“mpi.h”
#包括
#包括
#包括
#包括
#定义最小值(x,y)((x)1){
nrows=atoi(argv[1]);
ncols=nrows;
如果(myid==0){
/*主代码*/
aa=发电机矩阵(nrows,ncols);
bb=发电机矩阵(ncols,nrows);
cc1=malloc(双倍尺寸)*nrows*nrows);
starttime=MPI_Wtime();
缓冲区=(双*)malloc(sizeof(双)*ncols);
numsent=0;
MPI_Bcast(bb、ncols*nrows、MPI_DOUBLE、MASTER、MPI_COMM_WORLD)/*向所有从属设备广播bb*/
对于(i=0;iif(myid此错误消息通常表示至少一个MPI进程崩溃,整个MPI作业随后中止。它可能由任何类型的错误引起,但大多数情况下,它是由错误的内存访问导致的分段错误

我没有仔细看代码,所以我不知道逻辑是否有效等等,但我能告诉你的是,这行代码有一个问题:

MPI_Recv(&ans, nrows, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
         MPI_COMM_WORLD, &status);
事实上,这里有两个问题:

  • &ans
    是一个
    **double
    ,这不是你想要的,我想你想要的是
    ans
  • ans
    尚未分配,因此无法将其用作接收缓冲区
  • 首先尝试解决这个问题,看看会发生什么

    编辑:在新代码上分配
    ans
    ,如下所示:

    ans = (double*)malloc(sizeof(double) * ncols);
    
    for (i = 0; i < nrows; i++) {
        ans[i]=0.0;
    }
    
    MPI_Send(ans, nrows, MPI_DOUBLE, MASTER, row, MPI_COMM_WORLD);
    
    然后按如下方式初始化:

    ans = (double*)malloc(sizeof(double) * ncols);
    
    for (i = 0; i < nrows; i++) {
        ans[i]=0.0;
    }
    
    MPI_Send(ans, nrows, MPI_DOUBLE, MASTER, row, MPI_COMM_WORLD);
    

    这是不一致的:是
    ans
    的大小
    ncol
    还是
    nrows


    您的新错误消息是什么?

    在最后一次发送中,您只发送0个real,而在等待NCOL时,这可能会导致问题。最好事先使用MPI_Probe计算消息的大小。更好的是,事先计算分区,这样您就知道要接收多少行。&ans实际上是一个*双精度,表示我的“矩阵”在1-D数组中。我相信分配不应该是一个问题,因为我传递了地址,但是我可能是错的。但是,我分配了它,我仍然收到相同的错误。您声明了
    double*ans;
    ,所以
    &ans
    是指向
    ans
    的指针,而
    ans
    是声明的
    double*
    ,因此re的意思是
    &ans
    是指向
    double*
    的指针,也称为a
    double**
    。我重复一遍,您没有为接收缓冲区分配内存。也许您现在已经分配了内存,如果是这样,就用新代码编辑问题。顺便说一句,您在发送端也使用
    &ans
    ,这也是错误的。最后,如果您要使用
    &
    更清楚地说明您使用了指针,请使用
    &ans[0]
    是的,我不确定我在想什么。我用C编写代码已经有一段时间了。我修复了这个问题并编辑了上面的代码。我不再收到同样的错误,但它似乎仍然挂起,因为它没有退出。在我的代码中,ncols总是等于nrows,否则程序将退出。但你是对的,理想情况下它应该是ncols(我编辑代码以反映这一点)。这次没有错误,代码不会退出。此外,我的cc1(生成的矩阵)只有前四个索引(4x4的第一行)的值(正确的值)然后剩下的仍然是0。哇……我刚刚意识到我在一个已经使用I的for循环中重用了“I”。修复了这个问题,我的代码现在可以工作了。谢谢你的帮助!