ipython notebook:如何并行化外部脚本

时间:2014-06-19 17:00:14

标签: parallel-processing ipython ipython-notebook jupyter ipython-parallel

我试图从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

然后我被卡住了。我不知道如何同时运行两次(或更多)相同的脚本或pgm。

感谢。

2 个答案:

答案 0 :(得分:4)

一年后,我最终设法得到了我想要的东西。

1)使用您想要在不同的cpu上执行的操作创建一个函数。这里只是使用! magic ipython命令从bash调用脚本。我想它适用于call()函数。

def my_func(my_file):
    !python pgm.py {my_file}

使用{}

时请勿忘记!

另请注意,my_file的路径应该是绝对的,因为群集是您启动笔记本的位置(执行jupyter notebookipython notebook时),这不一定是您的位置。

2)使用所需的CPU数启动ipython notebook群集。 等待2s并执行以下单元格:

from IPython import parallel
rc = parallel.Client()
view = rc.load_balanced_view()

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

files = list_of_files

4)将您的所有文件异步映射到您刚创建的引擎的view。 (不确定措辞)。

r = view.map_async(my_func, files)

当它正在运行时,您可以在笔记本上执行其他操作(它运行在" 背景"!)。您还可以调用r.wait_interactive(),以交互方式枚举已处理的文件数,到目前为止所花费的时间和剩余的文件数。这将阻止您运行其他单元格(但您可以中断它)。

如果你有比引擎更多的文件,不用担心,只要引擎完成1个文件就会处理它们。

希望这会有所帮助!

本教程可能会有所帮助:

http://nbviewer.ipython.org/github/minrk/IPython-parallel-tutorial/blob/master/Index.ipynb

另请注意,我仍然IPython 2.3.1,我不知道自Jupyter以来它是否发生了变化。

编辑:仍然适用于Jupyter,请参阅here for difference and potential issues you may encounter

请注意,如果在函数中使用外部库,则需要在不同的引擎上导入它们:

%px import numpy as np

%%px
import numpy as np
import pandas as pd

与变量和其他函数相同,您需要将它们推送到引擎名称空间:

rc[:].push(dict(
                foo=foo,
                bar=bar))

答案 1 :(得分: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']