[英]Why is it important to protect the main loop when using joblib.Parallel?
[英]How to return a generator using joblib.Parallel()?
我在下面有一段代码,其中joblib.Parallel()
返回一个列表。
import numpy as np
from joblib import Parallel, delayed
lst = [[0.0, 1, 2], [3, 4, 5], [6, 7, 8]]
arr = np.array(lst)
w, v = np.linalg.eigh(arr)
def proj_func(i):
return np.dot(v[:,i].reshape(-1, 1), v[:,i].reshape(1, -1))
proj = Parallel(n_jobs=-1)(delayed(proj_func)(i) for i in range(len(w)))
我如何使用joblib.Parallel()
返回生成器而不是列表?
编辑:
我已经按照@user3666197 在下面评论中的建议更新了代码。
import numpy as np
from joblib import Parallel, delayed
lst = [[0.0, 1, 2], [3, 4, 5], [6, 7, 8]]
arr = np.array(lst)
w, v = np.linalg.eigh(arr)
def proj_func(i):
yield np.dot(v[:,i].reshape(-1, 1), v[:,i].reshape(1, -1))
proj = Parallel(n_jobs=-1)(delayed(proj_func)(i) for i in range(len(w)))
但我收到此错误:
TypeError: can't pickle generator objects
我错过了什么吗? 我该如何解决? 我在这里的主要收获是减少内存,因为proj
可能会变得非常大,所以我只想一次调用列表中的每个生成器。
问: “如何使用
joblib.Parallel
返回生成器?”
考虑到joblib
目的和实现,专注于分发代码执行单元,使用一组衍生的独立进程(是的,其动机是从中央 GIL 锁的逃逸中获得提升的性能 - [SERIAL]
-ised dance one- GIL-step-after-another-GIL-step-after-... ) 由称为joblib.Parallel(...)( delayed()(...) )
的语法构造函数制作,我的想象力显然有限,告诉我,最大可实现的只是使“远程”执行的进程返回主请求的生成器,这些生成器是由joblib
(不受控制的)到一个列表中。
因此,可实现的最大值是接收生成器列表,而不是任何形式的延迟执行,在返回时作为生成器包装,给定上述初始条件集和函数fun()
,设置为通过delayed( fun )(...)
注入delayed( fun )(...)
进入joblib.Parallel( n_jobs = ... )
许多“远程” -processes ,确实会这样做。
如果我们确实是迂腐的纯粹主义者,那么唯一的机会是接收“使用
joblib.Parallel()
的(一个)生成器” ,为此n_jobs
只需要== 1
,这在词法和逻辑上将满足定义的目标——返回(但)一个(一个)生成器—— ,但与将钱扔进尼罗河相比,效率更低,意义也更小……
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.