Parfor for Python

Dat*_*Chu 47 python parallel-processing matlab

我正在寻找一个确定的答案MATLAB的parfor for Python(Scipy,Numpy).

有没有类似于parfor的解决方案?如果没有,创建一个的复杂性是什么?

更新:这是我需要加速的典型数值计算代码

import numpy as np

N = 2000
output = np.zeros([N,N])
for i in range(N):
    for j in range(N):
        output[i,j] = HeavyComputationThatIsThreadSafe(i,j)
Run Code Online (Sandbox Code Playgroud)

重计算函数的一个例子是:

import scipy.optimize

def HeavyComputationThatIsThreadSafe(i,j):
    n = i * j

    return scipy.optimize.anneal(lambda x: np.sum((x-np.arange(n)**2)), np.random.random((n,1)))[0][0,0]
Run Code Online (Sandbox Code Playgroud)

Jud*_*ill 27

内置于python的那个将是multiprocessingdocs在这里.我总是使用multiprocessing.Pool与处理器一样多的工人.然后每当我需要做一个类似for循环的结构时我就会使用它Pool.imap

只要你的函数体不依赖于任何先前的迭代,那么你应该接近线性加速.这也要求您的输入和输出是pickle可用的,但这对于标准类型来说非常容易确保.

更新:更新功能的一些代码只是为了表明它是多么容易:

from multiprocessing import Pool
from itertools import product

output = np.zeros((N,N))
pool = Pool() #defaults to number of available CPU's
chunksize = 20 #this may take some guessing ... take a look at the docs to decide
for ind, res in enumerate(pool.imap(Fun, product(xrange(N), xrange(N))), chunksize):
    output.flat[ind] = res
Run Code Online (Sandbox Code Playgroud)


Sve*_*ach 19

有很多用于并行计算的Python框架.我最喜欢的是IPython,但我对其他任何一个都不太了解.在IPython中,parfor的一个类似物将是文档中关于快速简单并行client.MultiEngineClient.map()性的其他结构.


Ion*_*ica 6

这可以通过Ray优雅地完成,这是一个允许您轻松并行化和分发 Python 代码的系统。

要并行化您的示例,您需要使用@ray.remote装饰器定义您的函数,然后使用.remote.

import numpy as np
import time

import ray

ray.init()

# Define the function. Each remote function will be executed 
# in a separate process.
@ray.remote
def HeavyComputationThatIsThreadSafe(i, j):
    n = i*j
    time.sleep(0.5) # Simulate some heavy computation. 
    return n

N = 10
output_ids = []
for i in range(N):
    for j in range(N):
        # Remote functions return a future, i.e, an identifier to the 
        # result, rather than the result itself. This allows invoking
        # the next remote function before the previous finished, which
        # leads to the remote functions being executed in parallel.
        output_ids.append(HeavyComputationThatIsThreadSafe.remote(i,j))

# Get results when ready.
output_list = ray.get(output_ids)
# Move results into an NxN numpy array.
outputs = np.array(output_list).reshape(N, N)

# This program should take approximately N*N*0.5s/p, where
# p is the number of cores on your machine, N*N
# is the number of times we invoke the remote function,
# and 0.5s is the time it takes to execute one instance
# of the remote function. For example, for two cores this
# program will take approximately 25sec. 
Run Code Online (Sandbox Code Playgroud)

多处理模块相比,使用 Ray 有许多优点。特别是,相同的代码将在单台机器和机器集群上运行。有关 Ray 的更多优势,请参阅此相关帖子

注意:要记住的一点是,每个远程函数都在一个单独的进程中执行,可能在不同的机器上,因此远程函数的计算应该比调用远程函数花费的时间更多。根据经验,远程函数的计算应该至少需要几十毫秒的时间来分摊远程函数的调度和启动开销。


rsc*_*c05 5

Jupyter笔记本

要查看示例,请考虑您要在Python上编写此Matlab代码的等效内容

matlabpool open 4
parfor n=0:9
   for i=1:10000
       for j=1:10000
           s=j*i   
       end
   end
   n
end
disp('done')
Run Code Online (Sandbox Code Playgroud)

特别是在jupyter笔记本中,可能是用python编写的。您必须在工作目录(我称为FunForParFor.py)中创建一个函数,该函数具有以下内容

def func(n):
    for i in range(10000):
        for j in range(10000):
            s=j*i
    print(n)
Run Code Online (Sandbox Code Playgroud)

然后,我转到Jupyter笔记本并编写以下代码

import multiprocessing  
import FunForParFor

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=4)
    pool.map(FunForParFor.func, range(10))
    pool.close()
    pool.join()   
    print('done')
Run Code Online (Sandbox Code Playgroud)

这对我有用!我只是想在这里分享它,以给您一个特定的例子。