【问题标题】:MPI_Finalize() does not end any processesMPI_Finalize() 不结束任何进程
【发布时间】:2015-08-07 00:34:33
【问题描述】:

我在搞乱 openMPI,我有一个奇怪的错误。

似乎,即使在 MPI_Finalize() 之后,每个线程都继续运行。 我遵循了一个简单的 Hello World 程序的指南,它看起来像这样:

#include <mpi.h>;

int main(int argc, char** argv) {

// Initialize the MPI environment
    MPI_Init(NULL, NULL);

// 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);

// Get the name of the processor
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processor_name, &name_len);

// Print off a hello world message
       printf("Hello world from processor %s, rank %d"
       " out of %d processors\n",
       processor_name, world_rank, world_size);

// Finalize the MPI environment.
    MPI_Finalize();

    printf("This is after finalize");
}

注意最后一个 printf()... 这应该只打印一次,因为并行部分已经完成,对吧?!

但是,如果我使用 6 个处理器运行该程序,则该程序的输出是:

mpirun -np 6 ./hello_world

Hello world from processor ubuntu, rank 2 out of 6 processors
Hello world from processor ubuntu, rank 1 out of 6 processors
Hello world from processor ubuntu, rank 3 out of 6 processors
Hello world from processor ubuntu, rank 0 out of 6 processors
Hello world from processor ubuntu, rank 4 out of 6 processors
Hello world from processor ubuntu, rank 5 out of 6 processors
This is after finalize...
This is after finalize...
This is after finalize...
This is after finalize...
This is after finalize...
This is after finalize...

我是否误解了 MPI 的工作原理?每个线程/进程不应该被finalize停止吗?

【问题讨论】:

  • 是的,您误解了 MPI 的工作原理。 mpi_finalize 本质上是一个声明,表示您此后将不再发布 mpi 指令。它不是关闭进程的指令。没有指定底层系统做什么,您报告的行为是典型的。如需更多乐趣,请尝试将 printf 语句复制到 mpi_init 之前。
  • 谢谢.. (你是第一个,所以请给出一个我可以接受的答案:))所以我真正应该做的是将我想做的任何逻辑只放在 if(world_rank = = 0) { } 以确保它只执行一次?还是有更好的最佳实践?
  • @HighPerformanceMark “声明说您此后将不再发出 mpi 指令”这是错误的!该过程必须在之后退出。它不应该做任何事情而不是返回。看我的回答。
  • 对不起@addy2012,但 HighPerformanceMark 实际上是正确的。 MPI 标准中有一些语言指定了这一点(手册页不是福音)。

标签: c parallel-processing mpi openmpi


【解决方案1】:

这只是未定义的行为。

调用此例程后运行的进程数为 不明确的;最好不要执行超过返回 rc 之后 调用 MPI_Finalize。

http://www.mpich.org/static/docs/v3.1/www3/MPI_Finalize.html

【讨论】:

    【解决方案2】:

    MPI 标准只要求等级 0 从MPI_FINALIZE 返回。我不会在这里复制整个文本,因为它相当冗长,但您可以在第 8 章第 8.7 节(启动)第 359 - 361 页的标准 3.0 版(再过几天的最新版)中找到它。以下是最相关的部分:

    虽然不要求所有进程都从MPI_FINALIZE返回,但要求至少MPI_COMM_WORLD中的进程0返回,这样用户才能知道MPI部分的计算已经结束。此外,在 POSIX 环境中,用户可能希望为从 MPI_FINALIZE 返回的每个进程提供退出代码。

    甚至有一个例子试图完全按照你说的做:

    示例 8.10 下面说明了要求至少一个进程返回并且已知进程 0 是返回的进程之一的用法。无论返回多少进程,都希望下面的代码能够正常工作。

    ...  
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    ...
    MPI_Finalize();
    if (myrank == 0) {
        resultfile = fopen("outfile","w");
        dump_results(resultfile);
        fclose(resultfile);
    } exit(0);
    

    在调用MPI_FINALIZE 之后,MPI 标准没有说明应用程序的行为。所有这些功能需要做的是清理内部 MPI 状态、完成通信操作等。虽然在调用 MPI_FINALIZE 后 MPI 肯定有可能(并且允许)杀死应用程序的其他级别,但实际上,几乎从来都不是它的完成方式。可能有一个反例,但我不知道。

    【讨论】:

      【解决方案3】:

      当我启动 MPI 时,我在使用 MPI_Init 和 MPI_Finalize 方法时遇到了同样的问题。我认为这些功能之间并行工作和外部工作串行。最后我看到了这个答案,我弄清楚了它的功能。

      J Teller 的回答: https://stackoverflow.com/a/2290951/893863

      int main(int argc, char *argv[]) {
          MPI_Init(&argc, &argv);  
          MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
          MPI_Comm_rank(MPI_COMM_WORLD,&myid);
      
          if (myid == 0) { // Do the serial part on a single MPI thread
              printf("Performing serial computation on cpu %d\n", myid);
              PreParallelWork();
          }
      
          ParallelWork();  // Every MPI thread will run the parallel work
      
          if (myid == 0) { // Do the final serial part on a single MPI thread
              printf("Performing the final serial computation on cpu %d\n", myid);
              PostParallelWork();
          }
      
          MPI_Finalize();  
          return 0;  
      }  
      

      【讨论】:

        猜你喜欢
        • 2015-06-30
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-16
        • 2013-12-03
        相关资源
        最近更新 更多