1

我很难弄清楚如何在 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 变量没有被广播到所有处理器。我错过了什么吗?

4

1 回答 1

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只在master进程中给出有意义的结果,那么修改如下:

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

于 2012-10-17T19:43:55.500 回答