Как вернуть генератор с помощью joblib.Parallel ()? - PullRequest
0 голосов
/ 08 марта 2020

У меня есть фрагмент кода ниже, где 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 может стать очень большим, поэтому я просто хотел бы вызывать каждый генератор в списке по одному.

1 Ответ

1 голос
/ 08 марта 2020

Q : "Как мне вернуть генератор, используя joblib.Parallel?"

Учитывая joblib цель и реализация, сфокусированные на распределении модулей выполнения кода, использующих набор порожденных, независимых процессов (да, мотивированных повышенной производительностью после побега из центрального танца GIL-блокировки, повторяющего [SERIAL] танец * 1014) * один-GIL-шаг-за-другим-GIL-шаг-после -... ), сделанный конструктором syntacti c, известным как joblib.Parallel(...)( delayed()(...) ), мое, очевидно, ограниченное воображение, говорит мне, что максимально достижимо, если только сделать "удаленно" выполненными процессами, чтобы вернуть обратно к главному запрошенный генератор (ы) , которые joblib -собраны (из одного control) в список.

Таким образом, достижимый максимум - это получение списка генераторов , а не какой-либо формы отложенного выполнения, обернутого при возврате в качестве генератора, учитывая вышеуказанный набор начальных условий и заданной функции fun(), установленной для введения через delayed( fun )(...) в joblib.Parallel( n_jobs = ... ) -мани "удаленных" -процессах , действительно так и будет.


Бонусная часть:

...