Параллельный 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