使用MPI在顺序和并行之间切换

使用MPI在顺序和并行之间切换,mpi,Mpi,我有一个代码可以计算一些导体的热传递。一个导体中发生的情况不会影响模型中的其他导体。因此,我试图使这些导体的解决方案并行运行,每个处理器采用一组不同的导体。现在,我认为代码可以在一个内核上运行,直到它到达这个循环,我在其中放置了命令: MPI_INIT MPI_FINALIZE 然后在我请求的多个内核上运行这段代码,然后在命令后返回到在一个内核上运行: MPI_INIT MPI_FINALIZE 遇到了。但我看到的是,输入文件由两个内核读取(如果我使用2个内核),所有输出也打印两次。MP

我有一个代码可以计算一些导体的热传递。一个导体中发生的情况不会影响模型中的其他导体。因此,我试图使这些导体的解决方案并行运行,每个处理器采用一组不同的导体。现在,我认为代码可以在一个内核上运行,直到它到达这个循环,我在其中放置了命令:

MPI_INIT
MPI_FINALIZE
然后在我请求的多个内核上运行这段代码,然后在命令后返回到在一个内核上运行:

MPI_INIT
MPI_FINALIZE

遇到了。但我看到的是,输入文件由两个内核读取(如果我使用2个内核),所有输出也打印两次。MPI不像我想的那样工作吗?如果没有,那么我如何才能实现我想要的行为?我只希望代码在多个核心上运行,而不是在MPI_INIT和MPI_FINALIZE之外的任何其他子例程或部分代码中。

我不认为我完全理解这个问题,但首先要注意的是,MPI最多可以初始化一次。如此反复

MPI_Init
...
MPI_Finalize
这是不允许的。此外,
MPI_Init
MPI_Finalize
是昂贵的操作;你不想在循环中调用它们

MPI最初是围绕静态流程模型设计的,这意味着一组流程启动、工作和退出。听起来您希望在运行时更改进程数。这在MPI-2中是可能的(请参见
MPI\u Comm\u spawn

另一方面,持续启动和关闭过程会很慢。进程调用了
MPI\u Init
并不意味着它必须参与所有通信。以下是我将如何处理这个问题:

  • 启动一个进程池。在程序开始时对所有进程调用
    MPI_Init
    ,即使是那些只在本地工作的进程
  • 在每个循环迭代中,为需要使用
    MPI\u Comm\u create
    进行通信的进程创建一个新的通信器,并将其用于所有通信,而不是
    MPI\u Comm\u WORLD
  • 在程序结束时,所有进程调用
    MPI\u Finalize

  • 我不认为我完全理解这个问题,但首先要注意的是MPI最多只能初始化一次。如此反复

    MPI_Init
    ...
    MPI_Finalize
    
    这是不允许的。此外,
    MPI_Init
    MPI_Finalize
    是昂贵的操作;你不想在循环中调用它们

    MPI最初是围绕静态流程模型设计的,这意味着一组流程启动、工作和退出。听起来您希望在运行时更改进程数。这在MPI-2中是可能的(请参见
    MPI\u Comm\u spawn

    另一方面,持续启动和关闭过程会很慢。进程调用了
    MPI\u Init
    并不意味着它必须参与所有通信。以下是我将如何处理这个问题:

  • 启动一个进程池。在程序开始时对所有进程调用
    MPI_Init
    ,即使是那些只在本地工作的进程
  • 在每个循环迭代中,为需要使用
    MPI\u Comm\u create
    进行通信的进程创建一个新的通信器,并将其用于所有通信,而不是
    MPI\u Comm\u WORLD
  • 在程序结束时,所有进程调用
    MPI\u Finalize

  • 这是一个常见的误解,尤其是在那些有类似OpenMP的经验的人当中,在OpenMP中,线程在程序中的不同点被分叉和连接

    在MPI中,
    MPI_Init
    MPI_Finalize
    初始化并完成MPI库;就这样。虽然标准有意对Init之前和Finalize之后发生的事情保持沉默,但实际上,
    mpirun
    mpiexec
    命令通常会创建和启动进程。如果你打字

    mpirun -np 4 hostname
    
    例如,启动了四个进程,每个进程都运行
    hostname
    命令——这绝对不是MPI可执行文件,并且没有任何
    MPI\u Init
    MPI\u Finalize
    调用。这些进程中的每一个都从开始到结束运行可执行文件,因此得到四个输出。启动进程的是mpirun(或mpiexec),而不是程序内部的任何MPI函数调用


    那么,在您的程序中,整个程序将按照您的要求由尽可能多的进程运行。

    这是一个常见的误解,尤其是在有类似OpenMP的经验的人中,在OpenMP中,线程在程序中的不同点分叉并连接

    在MPI中,
    MPI_Init
    MPI_Finalize
    初始化并完成MPI库;就这样。虽然标准有意对Init之前和Finalize之后发生的事情保持沉默,但实际上,
    mpirun
    mpiexec
    命令通常会创建和启动进程。如果你打字

    mpirun -np 4 hostname
    
    例如,启动了四个进程,每个进程都运行
    hostname
    命令——这绝对不是MPI可执行文件,并且没有任何
    MPI\u Init
    MPI\u Finalize
    调用。这些进程中的每一个都从开始到结束运行可执行文件,因此得到四个输出。启动进程的是mpirun(或mpiexec),而不是程序内部的任何MPI函数调用


    然后,在您的程序中,整个程序将按您要求的数量运行。

    直到现在,我才意识到OpenMP和MPI之间存在差异。。。几年前,我修了一门并行编程的短期课程,这门课程一定是在OpenMP中,我认为MPI是这样工作的。无论如何,这给我带来的问题是,所有write语句都在写N