【问题标题】:Does a program started with mpiexec know it was started with mpiexec?以 mpiexec 启动的程序是否知道它是以 mpiexec 启动的?
【发布时间】:2013-04-27 01:52:04
【问题描述】:

我正在向 Fortran 程序添加一个选项,以便使用 MPI 使用多个处理器运行它。如果用户要并行运行它,用户需要指定不同的输入文件——为问题的每个域(处理器)指定一个文件。默认情况下,该程序将查找特定的文件名(名为“serial.inp”的文件)。所以我需要程序知道它何时并行运行,以便它可以改为查找其他文件名(例如“parallel_1.inp”、“parallel_2.inp”、“parallel_3.inp”等)。我的第一个想法是让用户在执行程序时将参数传递给程序,例如:

mpiexec -n 4 myprogram.exe -parallel

这样,当该参数存在时,它将查找并行文件。但这似乎有点多余。如果使用 mpiexec 调用程序,则毫无疑问用户正在尝试并行运行它。有什么方法可以让我的程序知道它是使用 mpiexec 启动的?还是命令行参数是我最好的选择?

【问题讨论】:

    标签: fortran mpi


    【解决方案1】:

    使用mpiexec 运行的进程将设置各种环境变量,向子进程指示它们是主进程还是从属进程等。

    查看mpiexec 的文档以了解具体细节。微软也有some documentation online

    【讨论】:

      【解决方案2】:

      为什么不以编程方式进行呢?这就是我在我的程序中的做法:

      #ifdef MPI
        CALL MPI_Init(ierr)                    ! Initialize MPI
        CALL MPI_Comm_rank(mpicomm,nproc,ierr) ! Who am I?
        CALL MPI_Comm_size(mpicomm,size,ierr)  ! How many processes?
      #else
        nproc = 0
        size  = 1
      #endif
      

      程序中的这一点之后,可以通过查询size的值来查询程序是串行的还是并行的。

      【讨论】:

      • 这是一个有点不同的问题。据我了解,rks 知道他使用 -DMPI 编译了他的程序,但他希望运行时检测执行方式。
      • 如果我错了,请纠正我,但 ifdef 语句的第一部分(MPI 调用)仅在源构建时使用 MPI 支持(mpif90)然后第二部分(否则) 如果代码没有在这种支持下编译,会被执行吗?如果是这样,即使代码在没有 mpirun 的情况下执行(只要它是在 MPI 支持下构建的),此解决方案仍会查找并行文件。我希望它在通过键入 ./myprogram.exe 执行时查找 serial.inp,无论它是否使用 MPI 支持构建。
      • 你是对的。看看乔纳森·杜尔西的回答,这是我的例子的延伸。检查它是单进程程序还是多进程程序并决定使用哪些输入文件需要您实现的代码部分。所以,我的观点是,对于您的问题,您无需担心程序是否由mpiexec 运行,或者代码是否使用-DMPI 编译。你关心有多少个进程,这些信息由上面示例中的变量size 提供。
      【解决方案3】:

      Alex Leach 是对的,您可以使用特定于 MPI 实现的环境变量查找来做到这一点,但没有可移植的方式来做到这一点。

      但据我了解,我认为您确实不需要;您只需检查它是否以一个等级运行即可获得大部分所需的内容:

      program filenames
          use mpi
          implicit none
      
          integer :: comsize, rank, ierr
          character(len=128) :: inputfilename
      
          call MPI_Init(ierr)
      
          call MPI_Comm_size(MPI_COMM_WORLD,comsize,ierr)
          call MPI_Comm_rank(MPI_COMM_WORLD,rank,ierr)
      
          if (comsize == 1) then
              inputfilename = 'serial.inp'
          else
              write(inputfilename, '(A,I0,A)'), 'parallel_',rank,'.imp'
          endif
      
          write(*,'(I,1X,A)'), rank, trim(inputfilename)
      
          call MPI_Finalize(ierr)
      end program filenames
      

      跑步给予

      $ mpirun -np 4 ./filenames
                 0 parallel_0.imp
                 1 parallel_1.imp
                 2 parallel_2.imp
                 3 parallel_3.imp
      $ ./filenames
                 0 serial.inp
      

      这并不完美;如果您使用mpirun -np 1 filenames 运行,它将给出串行结果,但取决于您的用例,换取便携的东西可能不是一件可怕的事情。

      【讨论】:

      • 这正是我想要的。我对这段代码的并行化非常严格。用户需要使用与其模型中的域相同数量的 proc。如果他们只有 1 个域,它将是串行运行,所以“-np 1”问题对我来说实际上不是问题。换言之,不可能只有一个并行文件“parallel_1.inp”。它们必须有“serial.inp”或多个“parallel_*.inp”文件。否则他们会收到一条错误消息。
      猜你喜欢
      • 1970-01-01
      • 2013-01-13
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 2013-09-13
      • 1970-01-01
      • 2012-09-27
      相关资源
      最近更新 更多