2011-01-04 5 views
5

Sto lavorando su un codice di ricerca che utilizza scipy.optimize.leastsq per ottimizzare una funzione. Lo fa circa 18 volte per iterazione, quindi vorrei chiamare leastsq in parallelo per ridurre il tempo di esecuzione. Questo non dovrebbe essere un problema perché le ottimizzazioni sono quasi completamente separate, quindi è richiesta pochissima sincronizzazione. Recentemente ho scoperto lo multiprocessing.pool.ThreadPool che mi permetterebbe di farlo senza dover impostare esplicitamente la memoria condivisa (un problema dato che la maggior parte dei miei dati sono in array di NumPy). Così ho fatto una leggera riscrittura del mio codice, sperando che funzionasse, ma genera uno strano errore: SystemError: null argument to internal routine.Parallelismo con SciPy.optimize

Quello che segue è una semplificazione del mio codice:

def optfunc(id): 
    def errfunc(x): 
     return somedata[id] - somefunc(x) 

    lock.acquire() 
    x0 = numpy.copy(currentx[id]) 
    lock.release() 

    result = scipy.optimize.leastsq(errfunc, x0) 

    lock.acquire() 
    currentx[id] = result 
    lock.release() 

ThreadPool(processes=8).map(optfunc, range(idcount)) 

Questo dovrebbe funzionare bene, a meno che scipy.optimize.leastsq non è threadsafe. Così ho provato a mettere un lucchetto intorno allo scipy.optimize.leastsq; ecco, funziona. Tuttavia, l'utilizzo del processore è bloccato al 100%, quindi questo è inutile per me.

La mia domanda è: cosa posso fare a riguardo? Credo che le mie opzioni sono:

  1. Trova un'implementazione thread-safe di LM
  2. Prova con processi piuttosto che le discussioni (non credo che questo sarebbe fare la differenza)
(levmar, forse?)

Qualsiasi aiuto o suggerimento sarebbe molto apprezzato.

+2

Stai utilizzando Windows? C'è un problema noto con il threading in optimize.leastsq su Windows: http://projects.scipy.org/scipy/ticket/1117. –

+0

Hmm, interessante che non è venuto quando ho cercato. Sto usando Ubuntu ma forse influenza entrambi i sistemi operativi. – Steve

risposta

-1

Quante CPU/core? Non c'è niente da guadagnare se quello che hai è in esecuzione al 100% senza threading. Se leastq() non è thread-safe e non si utilizza il 100% del computer in uso, è possibile eseguire un'istanza del programma per core e sincronizzare le istanze tramite il file system.

+0

Ci sono 8 CPU sul computer di ricerca. Non sono sicuro del perché tu dici che non si otterrebbe nulla se funziona al 100%. Quando ho provato l'esempio precedente, il codice sarebbe stato eseguito per un po 'prima di lanciare l'errore SystemError, e durante questo periodo si aggirava intorno al 400% di utilizzo della CPU. Stavo pensando di usare la soluzione che hai proposto, ma penso che potrebbe essere più fastidioso di quanto non valga a questo punto. Grazie per il tuo post però. – Steve

2

L'utilizzo dei processi anziché dei thread farà la differenza: funzionerà indipendentemente dal fatto che il programma sia protetto da thread o meno. Ovviamente, se è più veloce dipende se il tempo necessario per risolvere il problema è maggiore del sovraccarico.

L'utilizzo dei processi potrebbe richiedere alcuni problemi aggiuntivi con l'impostazione di tutti i dati necessari. Il modulo multiprocessing tuttavia si occupa della maggior parte del lavoro, quindi non dovrebbe essere troppo difficile da fare.