Параллельный Python:Как мне указать аргументы для "отправки"?
-
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