2016-12-14 2 views
2

Добрый деньДвойной параллельный цикл с Python Joblib

Я пытаюсь ускорить вычисление, которое включает в себя множество независимых интеграций. Для этого я использую pythons Joblib и многопроцессорность. До сих пор мне удалось распараллелить внутренний цикл моих вычислений, но я хотел бы сделать то же самое с внешним циклом. Поскольку параллельное программирование путается с моим умом, мне интересно, может ли кто-нибудь помочь мне. До сих пор у меня есть:

from joblib import Parallel, delayed 
import multiprocessing 

N = 10 # Some number 
inputs = range(1,N,2) 
num_cores = multiprocessing.cpu_count() 

def processInput(n): 
    u_1 = lambda x,y: f(x,y)g(n,m) # Some function 
    Cn = scintegrate.nquad(u_1, [[A,B],[C,D]]) # A number 
    return Cn*F(x,y)*G(n,m) 

resultsN = [] 

for m in range(1,N,2): # How can this be parallelized? 
    add = Parallel(n_jobs=num_cores)(delayed(processInput)(n) for n in inputs) 
    resultsN = add + resultsN 

resultsN = sum(resultsN) 

Это до сих пор дало правильные результаты. Теперь я хотел бы сделать то же самое с внешним циклом. Кто-нибудь есть идея, как я могу это сделать?

Мне также интересно, можно ли сделать заявление u_1 вне процесса ввода, и любые другие предложения по улучшению будут оценены.

Спасибо за любые ответы.

ответ

2

Если я правильно понял, вы используете свою функцию processInput(n) для диапазона значений n, и вам нужно сделать это m раз и добавить все вместе. Здесь индекс m содержит только количество попыток запуска вашей функции обработки и добавления результатов вместе, но ничего больше. Это позволяет делать все с помощью всего лишь одного уровня параллелизма, а именно создания списка входов, которые уже содержат повторяющиеся значения, и деления этой рабочей нагрузки между вашими ядрами. Быстрая интуиция заключается в том, что вместо обработки входов [1,2,3,4] параллельно, а затем, делая это несколько раз, вы запускаете параллельные входы [1,1,1,2,2,2,3,3,3,4,4,4]. Вот как это могло бы выглядеть (я изменил свои функции на более простую функцию, которую я могу запустить).

import numpy as np 
from joblib import Parallel, delayed 
import multiprocessing 
from math import ceil 

N = 10 # Some number 
inputs = range(1,N,2) 
num_cores = multiprocessing.cpu_count() 

def processInput(n): # toy function 
    return n 

resultsN = [] 
# your original solution with an additional loop that needs 
# to be parallelized 
for m in range(1,N,2): 
    add = Parallel(n_jobs=num_cores)(delayed(processInput)(n) for n in inputs) 
    resultsN = add + resultsN 
resultsN = sum(resultsN) 
print resultsN 

# solution with only one layer of parallelization 
ext_inputs = np.repeat(inputs,ceil(m/2.0)).tolist() 
add = Parallel(n_jobs=num_cores)(delayed(processInput)(n) for n in ext_inputs) 
resultsN = sum(add) 
print resultsN 

The ceil требуется потому, что в исходном цикле m Пропускает каждое второе значение.

Смежные вопросы