试图绕过一些非阻塞的 mpi 行为

Trying to wrap my head around some nonblocking mpi behaviour

所以我一直在 MPI 中尝试一些东西来感受它,并且我产生了一些我无法通过梳理文档来解释的结果。我正在使用开放式 mpi。

#include <mpi.h>
#include <stdio.h>
#include <unistd.h>

#define PROBLEMSIZE 41 
int main(int argc, char** argv) {
    // Initialize the MPI environment
    MPI_Init(&argc, &argv);

    // Get the number of processes
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    // Get the rank of the process
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    double send[PROBLEMSIZE];
    MPI_Request request[PROBLEMSIZE];
    int flag;
    int array_of_indices[PROBLEMSIZE];
    MPI_Status status[PROBLEMSIZE];

    if(world_rank == 0)
    {
        for (int i = 0; i < PROBLEMSIZE; i++)
        {
            request[i] = MPI_REQUEST_NULL;
            send[i] = i;
        }

        for (int i = 0; i < PROBLEMSIZE; i++)
        {
            MPI_Isend(&send[i],1,MPI_DOUBLE,1,i,MPI_COMM_WORLD,&request[i]);
        }
        MPI_Waitall(PROBLEMSIZE,request,status);
        for (int i = 0; i < PROBLEMSIZE; i++)
        {
            //printf("%i count %i", i, status[i].count);
            //printf("%i cancel %i", i, status[i].cancel);
            printf("%i MPI_SOURCE %i\n", i, status[i].MPI_SOURCE);
            printf("%i MPI_TAG %i\n", i, status[i].MPI_TAG);
            printf("%i MPI_ERROR %i\n \n", i, status[i].MPI_ERROR);
        }
        printf("thread 0 done");
    }

    if (world_rank == 1)
    {  
        sleep(10);
        for (int i = 0; i < PROBLEMSIZE; i++)
        {
            MPI_Irecv(&send[i],1,MPI_DOUBLE,0,i,MPI_COMM_WORLD, &request[i]);
        }
        int outcount;
        
 
        do {
            MPI_Testsome(PROBLEMSIZE,request, &outcount, array_of_indices, MPI_STATUSES_IGNORE);
            printf("did some waiting, outcount is %i\n",outcount);
        } while (outcount != 0);



        for (int i = 0; i < PROBLEMSIZE; i++)
        {
            printf("%f \n",send[i]);
        }
        
        /*
        sleep(20);

        MPI_Testall(PROBLEMSIZE,request,MPI_STATUSES_IGNORE);

        for (int i = 0; i < PROBLEMSIZE; i++)
        {
            printf("%f \n",send[i]);
        }
        */
    }



    MPI_Finalize();
    return 0;
}

/编辑

我想要实现的是能够从一个进程向另一个进程发送带有不同标签的任意数量的数据,发送方可以阻止并等待它被接收,但接收方不应该'没有什么可接收的时候就阻塞。

编辑/

下面是让我感到困惑的事情:

    在通信发生之前,第 36 行的
  1. MPI_Waitall 实际上似乎不会阻塞。因此,之后打印的状态完全是伪造的。 (来源 = -2,标记 = -1,错误 = 0)。然而,下一行 printf("thread 0 done"); 似乎确实要等到程序完成,这让我有点困惑。

  2. 当尝试接收第 59 行的号码时,似乎只有前 16 个成功,我尝试使用 MPI_Testall、MPI_Testsome 和 MPI_Waitsome对于所有这些都具有相同的结果。我假设这是由于缓冲区达到了某种限制,并且只要它正在接收东西就尝试多次循环它。根据文档 outcount 应该包含收到的东西的数量,但是当用 MPI_Testsome 尝试它时总是 0,而当用 MPI_Waitsome 尝试它时总是 -32766。这两个显然都是可疑数字,但我不确定它如何或为什么会溢出到 -32766。

  3. 使用 MPI_Waitall 在线程 1 中接收数据会产生所需的行为,这让我怀疑这是缓冲区的问题。但是,该实现不是我想要的,因为我希望线程 1 能够执行某些操作,并定期检查是否有新数据传入。

  1. MPI_Statussend 请求相关时,我不确定 MPI_TAGMPI_SOURCE 字段是否相关
  2. MPI_Test() 和 friends 是立即 return 的非阻塞子程序。我不确定你在这里想要达到什么目的,但你可能想改用 MPI_Waitsome()