运行并行Python线程调用通过PBS提交的外部MPI程序

0 投票
1 回答
1359 浏览
提问于 2025-04-17 06:22

我对Python还很陌生,不太确定在一个分布式集群上实现多线程或多进程代码的最佳方法是什么。

我正在尝试用Python写一个包装脚本,这个脚本会调用一个在大型集群上运行的外部MPI程序,使用的是PBS排队系统。我正在做的脚本的一个(非常)简化版本如下,代码会进入一个特定的目录,运行外部MPI程序,并检查结果,看是否有大的变化。

#!/local/python-2.7.1/bin/python2.7

import os
import subprocess as sp
import coordinate_functions as coord_funcs

os.chdir('/usr/work/cmurray/SeachTest/')
print os.getcwd()

# Gets nodefile and num procs (NP)
cat_np = sp.Popen('cat $PBS_NODEFILE | wc -l', shell = True, stdout=sp.PIPE)
NP = int(cat_np.communicate()[0])
sp.call('cat $PBS_NODEFILE > nodefile', shell = True)

def run_mpi(np, nodefile):
        mpi_cmd = 'mpirun -machinefile %s -np %d mpipg > calc.out' % (nodefile, np)
        sp.call(vasp_cmd, shell = True)


def search_loop(calc_dir, t_total, nodefile, num_procs):

    os.chdir(calc_dir)
    no_events = True
    while no_events or t < t_total:
        run_mpi(mynodefile, NP)
        num_events = coord_funcs.change_test('OUTFILE', 'INFILE', 0.01)
        if num_events > 0:
            event = True
        else:
            t += 1

search_loop('/usr/work/cmurray/SeachTest/calc_1/', 10, mynodefile, NP)

然后,这个脚本会通过以下方式提交到队列中:

qsub -l nodes=4 -N SeachTest ./SearchTest

我想做的是在不同的目录中并行运行多个版本的search_loop函数(比如说,这些目录里有不同的起始位置),这些目录是从一个列表中读取的。这个过程非常依赖输入输出,因为每次调用MPI计算可能需要几分钟才能完成。

我想知道threading模块是否适合这个目的,还是multiprocessing模块更好?我可能需要在线程或进程之间传递一些简单的信息,比如上面例子中的event布尔值。

另外,我该如何确保Python脚本不会使用我分配给MPI运行的处理器呢?

1 个回答

0

我想做的是在不同的文件夹里同时运行多个版本的search_loop函数,这些文件夹里可能有不同的起始位置,这些信息是从一个列表中读取的。这个过程非常依赖输入输出,因为MPI计算每次调用可能需要几分钟才能完成。

我想问一下,使用线程模块合适吗?还是说使用多进程模块更好?我可能需要在线程或进程之间传递一些简单的信息,比如上面例子中的事件布尔值。

对于一个输入输出密集型的程序,我会先尝试使用多线程,前提是有足够的带宽来真正实现输入输出的并行处理。

另外,我该如何确保我的Python脚本不会使用我分配给MPI运行的处理器呢?

如果你不使用多进程,脚本将只会使用一个CPU,因为有一个叫做全局解释器锁的机制。

撰写回答