بيثون الموازي: كيف يمكنني تقديم الحجج إلى "إرسال"؟
-
20-09-2019 - |
سؤال
هذا هو السؤال الثاني فقط مع علامة python الموازية. بعد النظر في الوثائق و googling للموضوع ، أتيت إلى هنا حيث كان لدي حظ أفضل مع الإجابات والاقتراحات.
فيما يلي واجهة برمجة التطبيقات (أعتقد أنها تسمى) التي تقدم جميع المعلومات ذات الصلة إلى 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
؟ لا أفهم ما يفترض أن يذهب إلى أين. شكرًا.
المحلول
مثيرة للاهتمام - هل تقوم بمحاكاة الوراثة؟ أسأل لأنني أرى "كروموسوم" هناك ، وقد طورت ذات مرة محاكاة الوراثة السكانية باستخدام الثعبان المتوازي.
نهجك يبدو معقدًا حقًا. في برنامج 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 لا تعمل في نفس سياق إرسال. بالتأكيد ، يمكنك المرور os
في ال module
معلمة submit
, ، لكن أليس من الأسهل فقط الاتصال import os
في دورون؟
يحاول بيثون الموازي تجنب جيل بيثون عن طريق تشغيل وظيفتك في عملية منفصلة تمامًا. إنه يحاول أن يجعل هذا الأسهل للابتلاع عن طريق السماح لك باقتباس المعلمات ومساحات الأسماء "تمرير" إلى وظيفتك ، ولكنه يفعل ذلك باستخدام الاختراقات. على سبيل المثال ، سيتم تسلسل الفصول الخاصة بك باستخدام بعض المتغيرات pickle
ثم غير ضروري في العملية الجديدة.
ولكن بدلا من الاعتماد على submit
اختراق ، فقط قبول حقيقة أن وظيفتك ستحتاج إلى القيام بكل أعمال إعداد سياق تشغيلها. لديك حقا اثنين main
وظائف - واحدة تقوم بإعداد المكالمة إلى submit
, وواحد تسميه عبر submit
, ، الذي يقوم بالفعل بإعداد العمل الذي تحتاج إلى القيام به.
إذا كنت بحاجة إلى القيمة التالية من المولد الخاص بك لتكون متاحة لتشغيل PP ، فقم أيضًا بتمريرها كمعلمة! هذا يتجنب وظائف Lambda ومراجع المولدات ، ويتركك مع تمرير متغير بسيط!
لم يعد الكود الخاص بي يتم الحفاظ عليه بعد الآن ، ولكن إذا كنت فضوليًا ، تحقق من ذلك هنا:http://pps-spud.uchicago.edu/viewvc/fps/trunk/python/fps.py؟view=markup
نصائح أخرى
أعتقد أنك يجب أن تمر في Lambda: Ks.Next () بدلاً من KS القديم العادي