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

Это только второй вопрос с тегом Parallels-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? Я не понимаю, что должно идти куда. Благодарю.

2 ответа

Решение

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

Ваш подход выглядит действительно сложным. В моей параллельной программе на 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,))

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

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

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

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

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

Я думаю, что вы должны передавать лямбду:ks.next() вместо старых старых ks

Другие вопросы по тегам