بيثون الموازي: كيف يمكنني تقديم الحجج إلى "إرسال"؟

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

  •  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 القديم العادي

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top