OpenMPI突破循环

时间:2012-10-16 19:41:47

标签: openmpi

我很难弄清楚如何在c中使用OpenMPI打破循环。

这是我的循环

 for( i=1; i<=steps;i++) {

    do_calculation(psi,new_psi,&mydiff,i1,i2,j1,j2);

    if (breakNow == 1) {
       break;
    }

     diff = find_difference();
    if(myid == mpi_master && i % iout == 0){
       printf("%8d %15.5f\n",i,diff);


       if (diff == 0.00) {
        printf("DONE!");

        breakNow = 1;

         MPI_Bcast(&breakNow, 1, MPI_INT, mpi_master, MPI_COMM_WORLD);
       }          
    }
  }

当存在0.00的差异时,我需要将所有处理器从循环中断开,但似乎breakNow变量没有被广播到所有处理器。我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

MPI_Bcast是一项集体行动。您需要在所有进程中调用它才能完成。在排名匹配mpi_root的过程中,广播将像发送操作一样运行,而在所有其他排名中,它将表现为接收操作。

只需将调用移至条件限制之外的MPI_Bcast即可。可能是if (breakNow == 1) break;行之前的正确位置。

另一个建议:如果find_difference在所有进程中返回相同的值,您可以执行类似的操作:

for (i = 1; i <= steps; i++) {

   do_calculation(psi, new_psi, &mydiff, i1, i2, j1, j2);

   diff = find_difference();
   if (i % iout == 0) {
      if (myid == mpi_master) {
          printf("%8d %15.5f\n", i, diff);
          if (diff == 0.00)
             printf("DONE!");
      }
      if (diff == 0.00) break;
   }
}

如果find_difference仅在主进程中提供有意义的结果,则修改如下:

for (i = 1; i <= steps; i++) {

   do_calculation(psi, new_psi, &mydiff, i1, i2, j1, j2);

   diff = find_difference();
   if (i % iout == 0) {
      if (myid == mpi_master) {
          printf("%8d %15.5f\n", i, diff);
          if (diff == 0.00)
             printf("DONE!");
      }
      MPI_Bcast(&diff, 1, MPI_DOUBLE, mpi_master, MPI_COMM_WORLD);
      if (diff == 0.00) break;
   }
}

(我假设diff的类型为double并保留了代码的原始语义,以便每iout步检查一次零差异