首页 > 解决方案 > 如何使用 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会变得非常大,所以我只想一次调用列表中的每个生成器。

标签: pythonparallel-processingmultiprocessinggeneratorjoblib

解决方案


“我如何使用返回生成器joblib.Parallel?”

鉴于joblib目的和实现,专注于分布代码执行单元,使用一组衍生的、独立的进程(是的,动机是从中央 GIL 锁的逃生中提升性能 - 重新[SERIAL]调整舞蹈GIL 步骤 - after-another-GIL-step-after-... ) 由被称为 的句法构造函数制成joblib.Parallel(...)( delayed()(...) ),我的想象力显然有限,告诉我,可实现的最大值只是让“远程”执行的进程返回到 main请求的生成器(s)joblib组装(不受控制)到一个列表中。

所以一个可实现的最大值是接收一个生成器列表,而不是任何形式的延迟执行,在返回时包装为生成器,给定上述一组初始条件和函数fun(),设置为通过-manydelayed( fun )(...)注入“远程” -进程,确实会这样做。joblib.Parallel( n_jobs = ... )


奖励部分:

如果我们确实是迂腐的纯粹主义者,那么唯一的机会是接收“一个(一个)使用joblib.Parallel()的生成器,要做到这一点,n_jobs就需要是 just == 1,这在词汇和逻辑上都将满足定义的目标——返回(但是)a (一)发电机——但比把钱扔进尼罗河更没有效率,也更没有意义……


推荐阅读