Pergunta

Esta é apenas a segunda pergunta com a tag paralela-python. Depois de examinar a documentação e pesquisar no assunto, cheguei aqui, pois é onde tive a melhor sorte com respostas e sugestões.

A seguir, a API (acho que é chamada) que envia todas as informações pertinentes ao 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()
    """

Aqui está minha declaração de envio com seus argumentos:

job_server.submit(reify, (pop1, pop2, 1000), 
                  depfuncs = (key_seq, Chromosome, Params, Node, Tree), 
                  modules = ("math",), 
                  callback = sum.add, globals = globals())

Todos os nomes capitalizados em depfuncs são os nomes das classes. Eu não tinha certeza de onde colocar as aulas ou mesmo se eu precisará incluí -las como elas estão no globals() dicionário. Mas quando eu o corri com o depfuncs() vazio, levantaria um erro como "Tree not defined" (por exemplo).

Agora, key_seq é um gerador, então tenho que trabalhar com uma instância para poder usar .next():

def key_seq():
    a = 0
    while True:
        yield a
        a = a + 1
ks = key_seq()

ks é definido em globals(). Quando não o incluí em nenhum outro lugar, recebi um erro dizendo 'ks is not defined'. Quando eu incluo ks dentro depfuncs, este é o erro:

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

Eu tenho certeza arg está se referindo a ks. Então, onde eu digo .submit() cerca de ks? Não entendo o que deveria ir para onde. Obrigado.

Foi útil?

Solução

Interessante - você está fazendo simulações de genética? Pergunto porque vejo 'cromossomo' lá e uma vez desenvolvi uma simulação de genética populacional usando python paralelo.

Sua abordagem parece realmente complicada. No meu programa Python paralelo, usei a seguinte chamada:

job = jobServer.submit( doRun, (param,))

Como eu fui com isso? O truque é que a função dorun não é executada no mesmo contexto que o contexto em que você chama Sumbit. Por exemplo (exemplo artificial):

import os, pp

def doRun(param):
    print "your name is %s!" % os.getlogin()

jobServer = pp.Server()
jobServer.submit( doRun, (param,))

Este código falhará. Isso ocorre porque o módulo OS não existe em Dorun - Dorun não está em execução no mesmo contexto que o envio. Claro, você pode passar os no module parâmetro de submit, mas não é mais fácil apenas ligar import os em Dorun?

O Python paralelo tenta evitar o GIL do Python, executando sua função em um processo totalmente separado. Ele tenta facilitar isso, permitindo que você cite os parâmetros e os espaços para nomes de "passe" para sua função, mas faz isso usando hacks. por exemplo, suas aulas serão serializadas usando alguma variante de pickle e depois não érializado no novo processo.

Mas em vez de confiar submitOs hacks, apenas aceitam a realidade de que sua função precisará fazer todo o trabalho de configurar seu contexto de execução. você realmente tem dois main funções - uma que configura a chamada para submit, e um, que você chama via submit, que realmente configura o trabalho que você precisa fazer.

Se você precisar do próximo valor do seu gerador para estar disponível para uma execução de PP, passe -o também como um parâmetro! Isso evita funções lambda e referências ao gerador e deixa você passando uma variável simples!

Meu código não é mais mantido, mas se você estiver curioso, confira aqui:http://pps-spud.uchicago.edu/viewvc/fps/trunk/python/fps.py?view=markup

Outras dicas

Eu acho que você deveria estar passando em lambda: ks.next () em vez de ks antigo e simples

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top