Python 使用argparse和mpi4py解析参数

Python 使用argparse和mpi4py解析参数,python,parallel-processing,mpi,argparse,Python,Parallel Processing,Mpi,Argparse,我想在MPI下的几个并行进程中运行Python脚本,并且需要传递命令行参数。我在Python中使用argparse模块,但有时有点混乱。如果我没有指定正确的参数,所有进程都会抱怨,因此我会得到同一错误消息的多个副本 我尝试只让进程0解析参数,然后将结果广播给其他进程,但当解析失败时,其他进程挂起,没有任何内容得到广播 如何解析命令行参数,并在解析失败时打印可读的消息?我需要的额外部分是在流程0中的参数解析步骤周围包装一个try/finally。在finally块中,向其他进程广播某些内容。如果解

我想在MPI下的几个并行进程中运行Python脚本,并且需要传递命令行参数。我在Python中使用argparse模块,但有时有点混乱。如果我没有指定正确的参数,所有进程都会抱怨,因此我会得到同一错误消息的多个副本

我尝试只让进程0解析参数,然后将结果广播给其他进程,但当解析失败时,其他进程挂起,没有任何内容得到广播


如何解析命令行参数,并在解析失败时打印可读的消息?

我需要的额外部分是在流程0中的参数解析步骤周围包装一个try/finally。在finally块中,向其他进程广播某些内容。如果解析失败,您将不广播任何内容,并且它们都可以静默退出

from mpi4py import MPI
from time import sleep
import argparse

def parseOptions(comm):
    parser = argparse.ArgumentParser(
        description='Print some messages.')

    parser.add_argument('iteration_count', help='How many times', type=int)
    parser.add_argument('message',
                        help='What to say',
                        nargs=argparse.OPTIONAL,
                        default='Hello, World!')

    args = None
    try:
        if comm.Get_rank() == 0:
            args = parser.parse_args()
    finally:
        args = comm.bcast(args, root=0)

    if args is None:
        exit(0)
    return args

def main():
    comm = MPI.COMM_WORLD  # @UndefinedVariable
    rank = comm.Get_rank()
    size = comm.Get_size()

    args = parseOptions(comm)

    if rank == 0:
        print args.message

    for i in range(args.iteration_count):
        if i%size == rank:
            print '{} in rank {} started.'.format(i, rank)
            sleep(.5)
            print '...'
            sleep(.5)
            print '{} in rank {} ended.'.format(i, rank)

if __name__ == '__main__':
    main()
我使用如下命令运行代码:

mpirun -np 4 python scratch.py 13

如果您有错误案例,通常最简单的方法是让进程中止,而不是尝试做一些花哨的清理工作。在您的情况下,您可以让源进程排名0的调用中止,并让其他所有人退出:

comm.abort()

这样,你就不会让每个人都试图匹配结果。它们只是自动中止。

我是MPI新手,不知道中止。听起来很简单。我试过使用comm.Abort,但要么我没有正确使用,要么它是一个非常钝的工具。它打印一组错误文本,包括根进程已不正确退出的语句。它抱怨对init和finalize的调用不平衡,因此我将坚持我最初的策略,即不广播任何内容来通知其他进程退出。这是真的,可能是打印额外的输出和抱怨。它被设计为在错误情况下调用,听起来就像您看到的一样。