IPython Notebook: 如何并行运行外部脚本

4
我想使用 ipython 并行库中的并行计算。但是我对此知之甚少,从不懂并行计算的角度看,我觉得文档很难理解。
有趣的是,我找到的所有教程都只是重复文档中的示例,并给出相同的解释。在我看来,这是没有用的。
基本上,我想做的就是在后台运行几个脚本,以便它们同时执行。在 bash 中,类似于:
for my_file in $(cat list_file); do
    python pgm.py my_file &
done

但是Ipython笔记本中的bash解释器无法处理后台模式。 似乎解决方案是使用IPython的并行库。 我尝试过:
from IPython.parallel import Client
rc = Client()
rc.block = True
dview = rc[:2] # I take only 2 engines

但是我卡住了。我不知道如何同时运行两次或更多次相同的脚本或程序。

谢谢。

2个回答

6
一年后,我最终得到了我想要的。 1)创建一个函数,在不同的CPU上对你想要做的事情进行操作。在这里,它只是使用魔法ipython命令从bash调用脚本。我猜这也可以使用call()函数实现。
def my_func(my_file):
    !python pgm.py {my_file}

不要忘记在使用!时加上{}。 同时请注意,由于集群是从notebook启动(当使用jupyter notebookipython notebook时),所以my_file的路径应该是绝对路径,而不一定是当前路径。 2) 以你想要的CPU数量启动你的ipython笔记本集群。等待2秒并执行以下单元格:
from IPython import parallel
rc = parallel.Client()
view = rc.load_balanced_view()

3) 获取要处理的文件列表:

files = list_of_files

将您的函数与所有文件异步映射到刚创建的引擎的视图中。(不确定措辞是否正确)
r = view.map_async(my_func, files)

在程序运行时,你可以在笔记本上做其他事情(它在“后台”运行!)。你还可以调用r.wait_interactive()来交互式地枚举已处理的文件数、已花费的时间以及剩余的文件数。这将防止你运行其他单元格(但你可以中断它)。
如果你有比引擎更多的文件,不用担心,它们将在引擎处理完一个文件后立即处理。
希望这对其他人有所帮助!
这个教程可能会有所帮助: http://nbviewer.ipython.org/github/minrk/IPython-parallel-tutorial/blob/master/Index.ipynb 请注意,我仍然使用IPython 2.3.1,我不知道自从Jupyter以来是否发生了变化。
编辑:在Jupyter中仍然可以使用,请参见此处的区别和可能遇到的问题
请注意,如果你的函数使用外部库,则需要通过以下方式在不同的引擎上导入它们:
%px import numpy as np

或者
%%px
import numpy as np
import pandas as pd

与变量和其他函数一样,您需要将它们推送到引擎名称空间中。
rc[:].push(dict(
                foo=foo,
                bar=bar))


谢谢您的回答,这个方法甚至在Jupyter Lab上也能完美运行! - Feishi

1
如果您想并行执行一些外部脚本,就不需要使用IPython的并行功能。可以通过以下方式使用子进程模块来复制bash的并行执行:
import subprocess

procs = []
for i in range(10):
    procs.append(subprocess.Popen(['ls', '/Users/shad/tmp/'], stdout=subprocess.PIPE))

results = []
for proc in procs:
    stdout, _ = proc.communicate()
    results.append(stdout)

请注意,如果您的子进程生成大量输出,该进程将会阻塞。如果您打印输出(结果),您将获得:

print results

['file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n', 'file1\nfile2\n']

谢谢你的回答。你能解释一下使用os.popen("""the_bash_script_above""")的区别吗?或者解释一下communicate部分是什么意思? - jrjc
1
os.popen自Python 2.6起已被弃用。当您要求stdout或stderr作为PIPE时,communicate()方法返回进程的标准输出和标准错误。请参阅此处subprocess模块的文档:https://docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate - shad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接