MPI状态获取错误的发件人

时间:2018-01-09 18:07:36

标签: c parallel-processing mpi

我正在使用MPI解决负载平衡问题:主进程将任务发送到从属进程并在计算和收回其作业时收集结果。 由于我想尽可能地提高性能,我使用非阻塞通信:Master发送几个任务,然后等待一个进程发回其响应,以便主服务器可以向其发送额外的工作,等等。

我使用MPI_Waitany(),因为我事先并不知道哪个从属进程响应,然后我从状态获取发件人,我可以将新作业发送给它。

我的问题是,我收到的发件人有时是错的(不在MPI_COMM_WORLD中),程序崩溃了;其他时候它工作正常。

这是代码。谢谢!

//master
if (rank == 0) {

    int N_chunks = 10;
    MPI_Request request[N_chunks];
    MPI_Status status[N_chunks];
    int N_computed = 0;
    int dest,index_completed;

    //initialize array of my data structure
    vec send[N_chunks];
    vec recv[N_chunks];


    //send one job to each process in communicator
    for(int i=1;i<size;i++){

      MPI_Send( &send[N_computed], 1, mpi_vec_type, i, tag, MPI_COMM_WORLD);
      MPI_Irecv(&recv[N_computed], 1, mpi_vec_type, i, tag, MPI_COMM_WORLD,  
                &request[N_computed]);
      N_computed++;
    }

    // loop
    while (N_computed < N_chunks){

      //get processed messages
      MPI_Waitany(N_computed,request,&index_completed,status);

      //get sender ID dest
      dest = status[index_completed].MPI_SOURCE;

      //send a new job to that process
      MPI_Send( &send[N_computed], 1, mpi_vec_type, dest, tag, MPI_COMM_WORLD);
      MPI_Irecv(&recv[N_computed], 1, mpi_vec_type, dest, tag, MPI_COMM_WORLD,
                &request[N_computed]);

      N_computed++;
  }

  MPI_Waitall(N_computed,request,status);

  //close all process
  printf("End master\n");
}

2 个答案:

答案 0 :(得分:1)

您没有正确使用MPI_Waitany()

应该是

MPI_Status status;
MPI_Waitany(N_computed,request,&index_completed,&status);
dest = status.MPI_SOURCE;

注意:

  • 您需要额外循环MPI_Wait()最后size - 1次请求
  • 您可以修改算法并使用MPI_Request request[size-1];,从而节省一些内存

答案 1 :(得分:0)

我忘了在初始帖子中添加一行,我等待所有待处理的请求:顺便说一句,如果我每次在Waitany初始化新状态时主进程崩溃;我需要跟踪哪些进程仍处于待处理阶段才能等待适当的次数... 谢谢你的方式

编辑:现在即使我发现它不是很聪明,它也能正常工作;是否有可能在开始时初始化MPI_Status数组,而不是每次等待之前都这样做?

//master
if (rank == 0) {

    int N_chunks = 10;
    MPI_Request request[size-1];
    int N_computed = 0;
    int dest;
    int index_completed;

    //initialize array of vec
    vec send[N_chunks];
    vec recv[N_chunks];



    //initial case
    for(int i=1;i<size;i++){

      MPI_Send(&send[N_computed], 1, mpi_vec_type, i, tag, MPI_COMM_WORLD);
      MPI_Irecv(&recv[N_computed], 1, mpi_vec_type, i, tag, MPI_COMM_WORLD, &request[N_computed]);
      N_computed++;
    }



    // loop
    while (N_computed < N_chunks){

      MPI_Status status;
      //get processed messages
      MPI_Waitany(N_computed,request,&index_completed,&status);

      //get sender ID dest
      dest = status.MPI_SOURCE;

      MPI_Send(&send[N_computed], 1, mpi_vec_type, dest, tag, MPI_COMM_WORLD);
      MPI_Irecv(&recv[N_computed], 1, mpi_vec_type, dest, tag, MPI_COMM_WORLD, &request[N_computed]);

      N_computed++;
    }

    //wait other process to send back their load
    for(int i=0;i<size-1;i++){

      MPI_Status status;
      MPI_Waitany(N_computed, request, &index_completed,&status);

    }


    //end
    printf("Ms finish\n");
}