我可以对巴图的答案进行一些改进(我认为这是一个很好的答案,但可能没有详细说明为什么使用这些选项)。 ipython 文档目前在这一点上也严重不足。所以你的函数的形式是:
def myfxn(a,b,c,d):
....
return z
并存储在一个名为mylib。假设 b、c 和 d 在运行期间相同,因此您编写一个 lambda 函数将其简化为 1 参数函数。
import mylib
mylamfxn=lambda a:mylib.myfxn(a,b,c,d)
并且你想运行:
z=dview.map_sync(mylamfxn, iterable_of_a)
在梦想的世界里,一切都会像那样神奇地进行。但是,首先您会收到“未找到 mylib”的错误,因为 ipcluster 进程尚未加载 mylib。如有必要,请确保 ipcluster 进程的 python 路径中有“mylib”,并且位于 myfxn 的正确工作目录中。然后你需要添加到你的Python代码中:
dview.execute('import mylib')
它运行import mylib
每个进程的命令。如果再试一次,您将收到类似“全局变量 b 未定义”的错误,因为虽然变量位于 Python 会话中,但它们并不位于 ipcluster 进程中。然而,python提供了一种将一组变量复制到子进程的方法。继续上面的例子:
mydict=dict(b=b, c=c, d=d)
dview.push(mydict)
现在所有子进程都可以访问 b、c 和 d。然后你可以运行:
z=dview.map_sync(mylamfxn, iterable_of_a)
现在它应该像广告中那样工作了。不管怎样,我是Python并行计算的新手,并且发现这个线程很有用,所以我想我应该尝试帮助解释一些让我有点困惑的点......
最终的代码是:
import mylib
#set up parallel processes, start ipcluster from command line prior!
from IPython.parallel import Client
rc=Client()
dview=rc[:]
#...do stuff to get iterable_of_a and b,c,d....
mylamfxn=lambda a:mylib.myfxn(a,b,c,d)
dview.execute('import mylib')
mydict=dict(b=b, c=c, d=d)
dview.push(mydict)
z=dview.map_sync(mylamfxn, iterable_of_a)
这可能是让几乎任何令人尴尬的并行代码在 python 中并行运行的最快、最简单的方法......
UPDATE您还可以使用 dview 不循环地推送所有数据,然后使用 lview (即lview=rc.load_balanced_view(); lview.map(...)
以负载平衡的方式进行实际计算。