Jak poprawnie przekazać kilka argumentów do pool.map. Obecnie mam błąd mówiący:

File "C:/Users/maxime/Desktop/execom/di.py", line 42, in <module>
    A = pool.map(energy2, args)
  File "C:\Python36\lib\multiprocessing\pool.py", line 266, in map
    return self._map_async(func, iterable, mapstar, chunksize).get()
  File "C:\Python36\lib\multiprocessing\pool.py", line 644, in get
    raise self._value
TypeError: energy2() missing 2 required positional arguments: 'window' and 'i'

Zip też nie działa. Próbuję też czegoś częściowo, ale jeśli wszystkie argumenty muszą być odmienne w każdym procesie, jest to bezcelowe.

import numpy as np
from numba import njit
import multiprocessing
from functools import partial
from itertools import repeat
import itertools


def energy2(signal, window,i ):
    L2 = int(len(window ) /2)
    Lw = len(window)
    taille = len(signal)
    channel_buffer = np.zeros(len(signal))
    filtered_signalI = np.hstack((np.zeros(L2) ,signal ,np.zeros(len(window))))
    for k in range(0 ,taille):
        buffer = (filtered_signalI[k : k + Lw ] * window)
        channel_buffer[k] = np.sqrt(np.sum(buffer * buffer))
    return channel_buffer / Lw



if __name__=="__main__":
    multiprocessing.freeze_support()
    # serial
    window = np.random.rand(32)
    N = 10
    Signals = np.zeros((N,1000))
    for i in range(N):
        Signals[i,:] = np.random.rand(1000)
    Res = np.zeros(Signals.shape)
    for i in range(N):
        Res[i, :] = energy2(Signals[i, :], window,i)
    print(Res)
    # parallel
    cpu_nb = 11  # multiprocessin
    Res2 = np.zeros(Signals.shape)
    idx = 0
    pool = multiprocessing.Pool(cpu_nb)
    args = []
    for h in range(N):
        args.append([window,Signals[h, :],h])
    A = pool.map(energy2, args)
    for imap in range(len(A)):
        Res2[imap, :] = A[imap]


    print(Res - Res2) #find same results
0
ymmx 9 marzec 2020, 17:51

2 odpowiedzi

Najlepsza odpowiedź

Myślę, że odpowiedź na to pytanie leży w mapie gwiazd. Zobacz to, aby zapoznać się z poprzednim rozwiązaniem. Nie jestem pewien formatu twoich danych wejściowych, ale przypuszczam, że będziesz musiał je spakować, jeśli rzeczywiście masz listę list.

if __name__=="__main__":
    multiprocessing.freeze_support()
    # serial
    window = np.random.rand(32)
    N = 10
    Signals = np.zeros((N,1000))
    for i in range(N):
        Signals[i,:] = np.random.rand(1000)
    Res = np.zeros(Signals.shape)
    for i in range(N):
        Res[i, :] = energy2(Signals[i, :], window,i)
    print(Res)
    # parallel
    cpu_nb = 11  # multiprocessin
    Res2 = np.zeros(Signals.shape)
    idx = 0
    pool = multiprocessing.Pool(cpu_nb)
    args = []
    for h in range(N):
        args.append([window,Signals[h, :],h])
    A = pool.starmap(energy2, args)
    for imap in range(len(A)):
        Res2[imap, :] = A[imap]


    print(Res - Res2) #find same results
2
davidkunio 9 marzec 2020, 15:02

To dużo kodu, ale myślę, że zmienię funkcję energy2 na:

def energy2(items):
    signal, window, i = items
    ...

Załatwi sprawę. Wydaje się, że problem polega na tym, że przekazujesz listę do funkcji, która oczekuje 3 wartości. Zwykle możesz to zrobić, używając wyrażenia oznaczonego gwiazdką , ale w twoim przypadku jest to nieco bardziej delikatne, ponieważ używasz map .. Pozwól więc funkcji obsłużyć swoje dane wejściowe.

1
Ma0 9 marzec 2020, 15:00