python - 围绕IPython并行包裹我的脑袋

python - 围绕IPython并行包裹我的脑袋,第1张

我试图围绕在我的python代码中应用并行计算的基本概念。我已经阅读了很多关于IPython并行的教程;但是,我似乎并不完全理解如何在一些基本的python代码中优雅地应用它。例如,演示代码如下所示:my_script.py:

# imports
import numpy as np
from IPython.parallel import Client

# class definition
class MyClass():
    def do_something(self, x, y):
        return np.sum(x, y)

# some variables
x = [1, 2, 3, 4, 5, 6, 7, 8 ,9, 10]
y = [1, 2, 3, 4, 5, 6, 7, 8 ,9, 10]

# create client and direct view to all engines available
client = Client()
dview = client[:]
dview.block = True

# here is what i'm currently doing to achieve parallelism
dview.execute('import numpy as np')
dview['MyClass'] = MyClass
dview.scatter('x', x)
dview.scatter('y', y)
dview.execute('my = MyClass()')
dview.execute('z = my.do_something(x, y)')
z = dview.gather('z')

我的问题:

  1. 有没有办法在所有命名空间中将numpy包含为np一次而不是两次? (一次在第一个上导入,然后在执行()中第二个。

  2. 与第一个问题相同,但对于MyClass。有没有更优雅的方法在所有命名空间中包含MyClass,而不是明确地将类类型作为变量推送?

  3. 您如何以最优雅的pythonic / ipythonic方式编写上述代码?

  4. 最佳答案:

    1 个答案:

    答案 0 :(得分:2)

    我认为将IPython视为在流程之间移动数据是有帮助的,但通常不是代码。值得注意的例外是函数(使用map()apply())。

    问题1 :我认为只能导入一次numpy,因为您的主进程和客户端进程不相同。对于更易读的代码,您可以执行以下操作:

    from IPython.parallel import Client
    
    client = Client()  # create client and direct view to all engines available
    dview = client[:]
    dview.block = True
    
    with dview.sync_imports():  # import on all client processes 
        import numpy  # `import numpy as np` does not work
    
    def f(x , y):
        """ return x**2   y """
        return numpy.power(x, 2)   y
    
    x = np.arange(5)
    y = 1000 * np.arange(5)
    zz = dview.map(f, x, y) # execute f() in parallel on different clients
    print(zz)  # gives: [0, 1001, 2004, 3009, 4016]
    

    查看IPython manual为什么import numpy as np无效。

    问题2 :在我看来,我认为最干净的方法是将MyClass放在一个单独的文件中,然后像上面的numpy一样导入它。原因是并行处理(MyClass)和管理(分发和收集数据)应该是分开的。可以说这也是一个品味问题。

    问题3 :您的方法do_something()不起作用,因为np.sum()总结了单个数组的元素。所以我假设您要并行计算x[0] y[0]x[1] y[1]...。类和并行进程不能很好地结合在一起,因为类的实例的主要思想是具有状态(以成员变量的形式)并且有状态函数很难并行化。因此,作为并行化的一般方法,请尝试使用dview.map(),因为它负责将数组拆分为块并将其分发给客户端。它还强制传递的函数不具有本地状态。如果您需要在每个流程中都有一个本地状态,请使用问题2的方法。

    本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复