Python parallelo: Come faccio a fornire argomenti a 'submit'?
-
20-09-2019 - |
Domanda
Questa è solo la seconda domanda con il tag parallelo pitone. Dopo aver guardato attraverso la documentazione e googling per il soggetto, sono venuto qui perché è dove ho avuto la miglior fortuna con risposte e suggerimenti.
Quello che segue è l'API (credo che si chiama) che presenta tutte le informazioni pertinenti a pp.
def submit(self, func, args=(), depfuncs=(), modules=(),
callback=None, callbackargs=(), group='default', globals=None):
"""Submits function to the execution queue
func - function to be executed
args - tuple with arguments of the 'func'
depfuncs - tuple with functions which might be called from 'func'
modules - tuple with module names to import
callback - callback function which will be called with argument
list equal to callbackargs+(result,)
as soon as calculation is done
callbackargs - additional arguments for callback function
group - job group, is used when wait(group) is called to wait for
jobs in a given group to finish
globals - dictionary from which all modules, functions and classes
will be imported, for instance: globals=globals()
"""
Ecco la mia presentare dichiarazione con i suoi argomenti:
job_server.submit(reify, (pop1, pop2, 1000),
depfuncs = (key_seq, Chromosome, Params, Node, Tree),
modules = ("math",),
callback = sum.add, globals = globals())
Tutti i nomi capitalizzati in depfuncs
sono i nomi delle classi. Non ero sicuro dove mettere le classi o anche se avrei bisogno di comprendere come sono nel dizionario globals()
. Ma quando mi sono imbattuto con il depfuncs()
vuoto, solleverebbe un errore come "Tree not defined
" (per esempio).
Ora, key_seq
è un generatore, quindi devo lavorare con un'istanza di esso al fine di essere in grado di utilizzare .next()
:
def key_seq():
a = 0
while True:
yield a
a = a + 1
ks = key_seq()
ks
è definito in globals()
. Quando non ho incluso in qualsiasi altro luogo, ho ottenuto un errore che dice 'ks is not defined
'.
Quando mi includo ks
in depfuncs
, questo è l'errore:
Traceback (most recent call last):
File "C:\Python26\Code\gppp.py", line 459, in <module>
job_server.submit(reify, (pop1, pop2, 1000), depfuncs = (key_seq, ks, Chromosome, Params, Node, Tree), modules = ("math",), callback = sum.add, globals = globals())
File "C:\Python26\lib\site-packages\pp.py", line 449, in submit
sfunc = self.__dumpsfunc((func, ) + depfuncs, modules)
File "C:\Python26\lib\site-packages\pp.py", line 634, in __dumpsfunc
sources = [self.__get_source(func) for func in funcs]
File "C:\Python26\lib\site-packages\pp.py", line 713, in __get_source
sourcelines = inspect.getsourcelines(func)[0]
File "C:\Python26\lib\inspect.py", line 678, in getsourcelines
lines, lnum = findsource(object)
File "C:\Python26\lib\inspect.py", line 519, in findsource
file = getsourcefile(object) or getfile(object)
File "C:\Python26\lib\inspect.py", line 441, in getsourcefile
filename = getfile(object)
File "C:\Python26\lib\inspect.py", line 418, in getfile
raise TypeError('arg is not a module, class, method, '
TypeError: arg is not a module, class, method, function, traceback, frame, or code object
Sono abbastanza sicuro arg
si riferisce ks
. Allora, dove posso dire .submit()
su ks
? Non capisco che cosa è supposto per andare dove. Grazie.
Soluzione
interessanti - simulazioni di genetica stai facendo? Lo chiedo perché vedo 'Cromosoma' in là, e una volta ho sviluppato una simulazione genetica di popolazione con python parallelo.
il tuo approccio sembra davvero complicato. nel mio programma python parallelo, ho usato la seguente chiamata:
job = jobServer.submit( doRun, (param,))
Come ho ricevuto via con questo? il trucco è che la funzione doRun non viene eseguito nello stesso contesto come il contesto in cui si chiama compila. Per esempio (esempio inventato):
import os, pp
def doRun(param):
print "your name is %s!" % os.getlogin()
jobServer = pp.Server()
jobServer.submit( doRun, (param,))
questo codice non sarà riuscito. questo è perché il modulo os non esiste in doRun - doRun non è in esecuzione nello stesso contesto come presentare. certo, si può passare os
nel parametro module
di submit
, ma non è più facile solo per chiamare import os
in doRun?
cerca pitone parallele per evitare GIL di pitone eseguendo la funzione in un processo totalmente separata. si cerca di rendere questo più facile da inghiottire, consentendo di citazione-parametri "Pass" e spazi dei nomi alla funzione, ma lo fa utilizzando hack. per esempio, le vostre classi saranno serializzati mediante qualche variante di pickle
e poi deserializzate nel nuovo processo.
Ma invece di basarsi su hack del submit
, basta accettare la realtà che la funzione sta andando ad avere bisogno di fare tutto il lavoro di costituzione è gestito contesto. davvero hanno due funzioni main
- uno che imposta la chiamata a submit
, e uno, che voi chiamate via submit
, che in realtà imposta il lavoro che devi fare.
se è necessario il valore successivo dal generatore ad essere disponibile per una corsa pp, anche passarla come parametro! questo evita funzioni lambda e riferimenti generatore, e ti lascia con passaggio di una variabile semplice!
il mio codice non è più mantenuto, ma se siete curiosi controllare qui: http: //pps-spud.uchicago. edu / viewvc / fps / trunk / python / fps.py? view = markup
Altri suggerimenti
Credo che si dovrebbe essere di passaggio in lambda: ks.next () al posto di vecchi ks pianura