MPI C树结构化全局和

时间:2015-05-08 01:29:54

标签: c tree sum mpi

如何在C中使用MPI配对进程?这是一种树状结构方法。进程0应该从所有其他偶数进程中添加,它们与之配对。我只需要它为2的权力工作。

我应该使用MPI_Reduce而不是MPI发送/接收吗?如果是这样,为什么?

我的程序似乎没有超过第一个if语句中的循环。为什么?

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <mpi.h>

int main(void){
  int sum, comm_sz, my_rank, i, next, value;
  int divisor = 2;
  int core_difference = 1;

  MPI_Init(NULL, NULL);
  MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  srandom((unsigned)time(NULL) + my_rank);
  value = random() % 10;

      //process should recieve and add
      if (my_rank % divisor == 0){

          printf("IF----");

          printf("Process %d generates: %d\n", my_rank, value);

          for (i = 0; i < comm_sz; i++)
          {
              MPI_Recv(&value, 1, MPI_INT, i, my_rank , MPI_COMM_WORLD, MPI_STATUS_IGNORE);
               sum += value;  
               printf("Current Sum=: %d\n", sum);

          }

          printf("The NEW divisor is:%d\n", divisor);
          divisor *= 2;
          core_difference *= 2;

      }

      //sending the random value - no calculation
      else if (my_rank % divisor == core_difference){
          printf("ELSE----");
          printf("Process %d generates: %d\n", my_rank, value);
          MPI_Send(&value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
      }
      else
         if (my_rank==0)
            printf("Sum=: %d\n", sum);

  MPI_Finalize();

  return 0;
}

1 个答案:

答案 0 :(得分:2)

问题在于您的流程都是自己接收的。如果我在每次发送之前添加一个print语句并接收操作中涉及的进程,那么输出如下:

$ mpiexec -n 8 ./a.out
IF----Process 0 generates: 5
ELSE----Process 1 generates: 1
ELSE----Process 3 generates: 1
IF----Process 4 generates: 9
ELSE----Process 5 generates: 7
IF----Process 6 generates: 2
ELSE----Process 7 generates: 0
0 RECV FROM 0
1 SEND TO 0
3 SEND TO 0
4 RECV FROM 0
5 SEND TO 0
6 RECV FROM 0
7 SEND TO 0
IF----Process 2 generates: 7
2 RECV FROM 0
1 SEND TO 0 DONE
3 SEND TO 0 DONE
5 SEND TO 0 DONE
7 SEND TO 0 DONE

显然,每个人都在等待等级0时挂起,包括等级0.如果你想发送给自己,你需要使用MPI_Sendrecv同时进行发送和接收时间或使用非阻塞发送和接收(MPI_Isend / MPI_Irecv)。

正如你所说,另一种选择是使用集体,但如果你这样做,你就需要创建新的子传播者。集体要求沟通者中的所有流程都参与其中。你不能只挑选一个子集。