Параллельный Python:Как мне указать аргументы для "отправки"?

StackOverflow https://stackoverflow.com/questions/1546429

  •  20-09-2019
  •  | 
  •  

Вопрос

Это только второй вопрос с тегом parallel-python.Просмотрев документацию и погуглив тему, я пришел сюда, поскольку именно там мне больше всего повезло с ответами и предложениями.

Ниже приведен API (я думаю, он называется), который отправляет всю соответствующую информацию в 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()
    """

Вот мое заявление о отправке с его аргументами:

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

Все имена с заглавной буквы в depfuncs это названия классов.Я не был уверен, куда поместить классы или даже нужно ли мне будет включать их в том виде, в каком они есть в globals() словарь.Но когда я запустил его с помощью depfuncs() пустой, это вызвало бы ошибку, такую как "Tree not defined" (например).

Сейчас, key_seq является генератором, поэтому я должен работать с его экземпляром, чтобы иметь возможность использовать .next():

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

ks определяется в globals().Когда я не включил его больше нигде, я получил сообщение об ошибке 'ks is not defined'.Когда я включаю ks в depfuncs, это и есть ошибка:

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

Я почти уверен arg имеется в виду ks.Итак, где мне рассказать .submit() о нас ks?Я не понимаю, что и куда должно идти.Спасибо.

Это было полезно?

Решение

интересно, вы занимаетесь генетическим моделированием?я спрашиваю, потому что вижу там "Хромосому", и я когда-то разработал симуляцию популяционной генетики с использованием parallel python.

ваш подход выглядит действительно сложным.в моей параллельной программе на Python я использовал следующий вызов:

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

как мне это сошло с рук?хитрость в том, что функция doRun не выполняется в том же контексте, что и контекст, в котором вы вызываете sumbit.Например (надуманный пример):

import os, pp

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

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

этот код завершится ошибкой.это связано с тем, что модуль операционной системы не существует в doRun - doRun не выполняется в том же контексте, что и submit.конечно, вы можете пройти мимо os в module параметр submit, но не проще ли просто позвонить import os в Доруне ?

parallel python пытается избежать python's GIL, запуская вашу функцию в совершенно отдельном процессе.он пытается облегчить восприятие этого, позволяя вам "передавать" параметры и пространства имен в кавычках вашей функции, но он делает это с помощью взломов.например, ваши классы будут сериализованы с использованием некоторого варианта pickle а затем несериализован в новом процессе.

Но вместо того, чтобы полагаться на submitитак, просто примите реальность того, что вашей функции потребуется выполнить всю работу по настройке контекста ее запуска.у тебя действительно их два main функции - те, которые настраивают вызов на submit, и тот, который вы вызываете через submit, который фактически настраивает работу, которую вам нужно выполнить.

если вам нужно, чтобы следующее значение из вашего генератора было доступно для запуска pp, также передайте его в качестве параметра!это позволяет избежать лямбда-функций и ссылок на генератор и оставляет вам возможность передавать простую переменную!

мой код больше не поддерживается, но если вам интересно, ознакомьтесь с ним здесь:http://pps-spud.uchicago.edu/viewvc/fps/trunk/python/fps.py?view=markup

Другие советы

Я думаю, вам следует использовать lambda:ks.next() вместо простого старого ks

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top