Перенос результатов параллельного вычисления в окончательный массив в Python - PullRequest
0 голосов
/ 04 августа 2020

У меня есть распараллеленный код python, который вычисляет значение x[(1,i)] для o[(i)] с i в диапазоне (0, npt). Как x[(1,i)] = x1[(i)] * x2[(i)], я вычисляю x1[(i)] и x2[(i)] по отдельности, а затем умножаю их вместе, чтобы получить x[(1,i)].

import cmath, csv, sys, math, re
import numpy as np
import multiprocessing as mp

x1 = np.zeros(npt ,dtype=float)
x2 = np.zeros(npt ,dtype=float)

def chi2(i):
    print("\t wavelength", i+1," of ", npt)
    x1[(i)] = (some function of o[(i)]))

    for k in range(nk):
        for n in range(nb):
            for m in range(nb):
                for l in range(nb):
                        x2[(i)] = (x2[(i)] + (another function of o[(i)]))
    print(i,"x1:",x1[(i)])
    print(i,"x2:",x2[(i)])

    np.set_printoptions(precision=3)
    x[(1,i)] = x1[(i)] * x2[(i)]
    print(i,"x:",x[(1,i)])

    return x[(1,i)]

#-----------single process--------------
for i in range (npt):
    chi2(i)

#------------parallel processes-------------
#pool = mp.Pool(mp.cpu_count())
#pool.map(chi2,[i for i in range (npt)])
#pool.close() 
#-------------------------------------------

print("x:",x)

Результат кода «параллельных процессов» выглядит следующим образом:

wavelength 1  of  6
wavelength 2  of  6
wavelength 3  of  6
wavelength 4  of  6
wavelength 6  of  6
wavelength 5  of  6
1 x1: 13.064431907056434
1 x2: -1.9906250877567282
1 x: -26.006385911476013
5 x1: 32.428696460232054
5 x2: -7.62814423558251
5 x: -247.37077397057408
2 x1: 16.848860458915905
2 x2: -2.8743277048490476
2 x: -48.429146412197625
3 x1: 21.301496841785333
0 x1: 9.893885346287407
3 x2: -4.053590423587782
0 x2: -1.339636506591729
3 x: -86.34754360594641
0 x: -13.254210001919562
4 x1: 26.47666689558421
4 x2: -5.606053928481043
4 x: -148.42962246307385
x: [[1030. 1130. 1230. 1330. 1430. 1530.]
 [   0.    0.    0.    0.    0.    0.]]

Распараллеленный код может получать отдельные значения x1[(i)], x1[(i)] и x[(1,i)], но не может поместить эти значения в полный массив print("x:",x).

Следовательно, я попытался использовать один процесс, и результаты были такими, как я хотел:

         wavelength 1  of  6
0 x1: 9.893885346287407
0 x2: -1.339636506591729
0 x: -13.254210001919562
         wavelength 2  of  6
1 x1: 13.064431907056434
1 x2: -1.9906250877567282
1 x: -26.006385911476013
         wavelength 3  of  6
2 x1: 16.848860458915905
2 x2: -2.8743277048490476
2 x: -48.429146412197625
         wavelength 4  of  6
3 x1: 21.301496841785333
3 x2: -4.053590423587782
3 x: -86.34754360594641
         wavelength 5  of  6
4 x1: 26.47666689558421
4 x2: -5.606053928481043
4 x: -148.42962246307385
         wavelength 6  of  6
5 x1: 32.428696460232054
5 x2: -7.62814423558251
5 x: -247.37077397057408
x: [[1030.    1130.    1230.    1330.    1430.    1530.   ]
 [ -13.254  -26.006  -48.429  -86.348 -148.43  -247.371]]

Кто-нибудь может сказать мне, что мешает распараллеленному коду получить значения в x[(1,i)]?

1 Ответ

1 голос
/ 04 августа 2020

При работе с многопроцессорной обработкой глобальные переменные не разделяются между процессами таким образом. Каждый процесс будет иметь свою собственную копию переменной.

Pool.map возвращает список возвращаемых значений каждой функции для списка заданных входных данных. Вы можете сделать что-то вроде (вместо используемой строки pool.map):

x[1] = pool.map(chi2,[i for i in range (npt)])

Чтобы использовать возвращаемое значение chi2 и вставить его в нужное место в x. Обратите внимание, что здесь используется тот факт, что вы можете назначить список значений столбцу или строке массива numpy.

...