Frage

Dies ist nur die zweite Frage mit dem Parallel-Python-Tag. Nachdem ich die Dokumentation und das Googeln nach dem Thema durchgesehen hatte, bin ich hierher gekommen, da ich dort das beste Glück mit Antworten und Vorschlägen hatte.

Das Folgende ist die API (ich denke, sie heißt genannt), die alle relevanten Informationen an PP unterbreitet.

    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()
    """

Hier ist meine Einreichungserklärung mit seinen Argumenten:

job_server.submit(reify, (pop1, pop2, 1000), 
                  depfuncs = (key_seq, Chromosome, Params, Node, Tree), 
                  modules = ("math",), 
                  callback = sum.add, globals = globals())

Alle kapitalisierten Namen in depfuncs sind die Namen von Klassen. Ich war mir nicht sicher, wo ich die Klassen einfügen sollte oder ob ich sie so einbeziehen müsste, wie sie in der globals() Wörterbuch. Aber als ich es mit dem leitete depfuncs() Leer, es würde einen Fehler aufwerfen, wie z. "Tree not defined" (zum Beispiel).

Jetzt, key_seq ist ein Generator, also muss ich mit einer Instanz arbeiten, um verwenden zu können .next():

def key_seq():
    a = 0
    while True:
        yield a
        a = a + 1
ks = key_seq()

ks ist definiert in globals(). Als ich es nirgendwo anders angemeldet habe, bekam ich einen Fehler, der sagte: 'ks is not defined'. Wenn ich eingehört habe ks in depfuncs, Dies ist der Fehler:

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

Ich bin ziemlich sicher arg bezieht sich auf ks. Also, wo sage ich .submit() um ks? Ich verstehe nicht, was wohin gehen soll. Vielen Dank.

War es hilfreich?

Lösung

Interessant - machen Sie Genetiksimulationen? Ich frage, weil ich dort 'Chromosom' sehe, und ich habe einmal eine Populationsgenetiksimulation mit parallelem Python entwickelt.

Ihr Ansatz sieht wirklich kompliziert aus. In meinem parallelen Python -Programm habe ich den folgenden Anruf verwendet:

job = jobServer.submit( doRun, (param,))

Wie bin ich damit davongekommen? Der Trick ist, dass die Dorun -Funktion nicht im gleichen Kontext wie der Kontext ausgeführt wird, in dem Sie Sumbit nennen. Zum Beispiel (erfundenes Beispiel):

import os, pp

def doRun(param):
    print "your name is %s!" % os.getlogin()

jobServer = pp.Server()
jobServer.submit( doRun, (param,))

Dieser Code fällt fehl. Dies liegt daran, dass das Betriebssystemmodul in Dorun nicht existiert - Dorun läuft nicht im selben Kontext wie Subjekt. Sicher, Sie können passieren os in dem module Parameter von submit, aber ist es nicht einfacher, nur anzurufen import os in Dorun?

Parallel Python versucht, Pythons Gil zu vermeiden, indem Sie Ihre Funktion in einem völlig separaten Prozess ausführen. Es wird versucht, dies einfacher zu schlucken, indem Sie Parameter und Namespaces "übergeben" können, um Ihre Funktion zu erhalten, aber es wird mit Hacks verwendet. Zum Beispiel werden Ihre Klassen unter Verwendung einer Variante von serialisiert pickle und dann im neuen Prozess unverzweigt.

Aber anstatt sich darauf zu verlassen submitHacks, akzeptieren Sie einfach die Realität, dass Ihre Funktion die gesamte Arbeit des Einrichtens des Run -Kontexts erledigen muss. Sie haben wirklich zwei main Funktionen - eine, die den Anruf einsetzt submit, und eine, über die Sie nennen submit, was tatsächlich die Arbeit einstellt, die Sie erledigen müssen.

Wenn Sie den nächsten Wert von Ihrem Generator benötigen, um für einen PP -Lauf verfügbar zu sein, geben Sie ihn auch als Parameter weiter! Dies vermeidet Lambda -Funktionen und Generatorreferenzen und lässt Sie mit einer einfachen Variablen vorbei!

Mein Code wird nicht mehr gepflegt, aber wenn Sie neugierig sind, schauen Sie ihn hier aus:http://pps-spud.uchicago.edu/viewvc/fps/trunk/python/fps.py?view=markup

Andere Tipps

Ich denke, Sie sollten in Lambda vorbeikommen: ks.next () anstelle von einfachen alten ks

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top