2014-04-04 33 views
1

我使用Ipython.parallel一个loadbalancedview来调用一个迭代函数,即IPython的并行LoadBalancedView GIL

from IPython.parallel import Client 
from functools import partial 

rc = Client() 
lview = rc.load_balanced_view() 
lview.block = True 

def func(arg0, arg1, arg2): 
    return func2(arg0) + arg1 + arg2 

def func2(arg0): 
    return 2*arg0 

answer = lview.map(partial(func, arg1=A, arg2=B), iterable_data) 

这是否FUNC调用FUNC2使FUNC不能并行(执行即事实确实的GIL起作用了吗?)我假设当你调用map时,每个集群节点都会得到一个func副本,但是他们是否也获得了func2副本。此外,我使用functools.partial会导致任何问题吗?

回答

3

这是否FUNC调用FUNC2使FUNC不能并行执行的事实(即没有GIL的发挥作用?)

不是。 GIL在这里并不重要,在IPython中并行也没有关系。 GIL只有在协调每个引擎中的线程或客户端进程本身时才会出现。

我假设当你调用map时,每个集群节点都得到一个func的副本,但是他们是否也获得了func2的副本。

应该,但其实这是你的代码有问题。 IPython的不自动跟踪关闭,并且代码依赖于互动的命名空间,所以你会看到:

AttributeError: 'DummyMod' object has no attribute 'func' 

这是因为partial(func, arg1=A, arg2=B)包含引用__main__.func,当地func本身不是代码。 当部分到达引擎时,它被反序列化,并且请求__main__.func,但未定义(__main__是引擎上的交互式命名空间)。你可以简单地通过确保funcfunc2的引擎上定义的解决这个问题:

rc[:].push(dict(func=func, func2=func2)) 

在这一点,你应该map像预期的那样。

如果您指示IPython使用增强型酸洗库dill,它将更接近于不必手动发送参考,但它不涵盖每种情况。

+0

嗨,秘书,谢谢你的回应。到目前为止我发现的是,即使没有莳萝,我也没有得到任何错误并且代码会运行,但它比非并行版本慢大约10倍(实际的func使用numpy数组,所以我怀疑它是来回传递很多)。我对ipython如何对待在使用远程客户端的模块中声明的函数有点困惑。我从来没有将func2推送到远程客户端,那为什么它在尝试执行时不会抛出NameError呢? – sheridp

+0

啊,我注意到,你指定了“... **交互式**命名空间中的代码依赖...”。我应该提到,这段代码实际上被放置在一个模块中并被导入。 IPython是否跟踪导入模块中的代码依赖关系?我只是做了一个快速检查,并且您在交互式会话中测试时遇到AttributeError是正确的。 – sheridp

+0

它不需要跟踪模块情况下的任何依赖关系。序列化时,pickle存储引用。除了交互式定义的名称之外,这些反序列化在网络边界上几乎完美无缺。 – minrk