2012-06-01 20 views
10

IPython paralel araçlarını denemeye başladım ve bir sorun yaşıyorum. Sonra şu kod iyi çalışırPython paralel alan ipython ile alan sorunları

ipcluster start -n 3 

: Birlikte benim piton motorları başlatmak

from IPython.parallel import Client 

def dop(x): 
    rc = Client() 
    dview = rc[:] 
    dview.block=True 
    dview.execute('a = 5') 
    dview['b'] = 10 
    ack = dview.apply(lambda x: a+b+x, x) 
    return ack 

ack = dop(27) 
print ack 

döner [42, 42, 42] olması gerektiği gibi. dop.py: Farklı dosyalarına kod kırmak Ama eğer

from IPython.parallel import Client 

def dop(x): 
    rc = Client() 
    dview = rc[:] 
    dview.block=True 
    dview.execute('a = 5') 
    dview['b'] = 10 
    print dview['a'] 
    ack = dview.apply(lambda x: a+b+x, x) 
    return ack 

ve aşağıdakileri deneyin:

[0:apply]: NameError: global name 'a' is not defined 
[1:apply]: NameError: global name 'a' is not defined 
[2:apply]: NameError: global name 'a' is not defined 

ı don:

from dop import dop 
ack = dop(27) 
print ack 

ben her motordan hataları olsun Anlamadım ... neden farklı bir dosyada işlevi koyamıyorum ve içe aktaramam?

cevap

16

Hızlı cevap:

 
from IPython.parallel.util import interactive 
f = interactive(lambda x: a+b+x) 
ack = dview.apply(f, x) 

fiili açıklama:

ipython kullanıcı ad alanıdır IPython.parallel.util dan @interactive bunu motorun genel ad erişmesini istiyorsanız [1] ile işlevini süslemeleri Esasen modül __main__. Bu, execute('a = 5') yaptığınızda kodun çalıştırıldığı yerdir.

etkileşimli bir işlev tanımlarsanız, onun modül ayrıca __main__ geçerli:

Motor bir işlev unserializes
 
lam = lambda x: a+b+x 
lam.__module__ 
'__main__' 

, bu işlevin modül için uygun global ad alanında yapar, böylece işlevleri içinde __main__ tanımlanan Müşteriniz ayrıca, Motor üzerinde __main__'da tanımlanmıştır ve böylece a'a erişebilir. Eğer bir dosyaya koydu ve içe kez

ardından fonksiyonları artık __main__ bağlı, ancak modül dop gibidir: geleneksel o modülde tanımlanan

 
from dop import dop 
dop.__module__ 
'dop' 

tüm fonksiyonları (lambda'lar dahil) sahip olacak Bu değer, Motor üzerinde paketlenmediklerinde, global ad alanı, dop modülünün, __main__ değil, bu nedenle 'a' değerinize erişilemeyecektir.

Bu nedenle, IPython, işlevin gerçekte nerede tanımlandığına bakılmaksızın __main__'da tanımlandığı gibi paketlenmemiş herhangi bir işlevle sonuçlanan basit bir @interactive dekoratör sağlar. farkın bir örnek için

, bu dop.py atın:

 
from IPython.parallel import Client 
from IPython.parallel.util import interactive 

a = 1 

def dop(x): 
    rc = Client() 
    dview = rc[:] 
    dview['a'] = 5 
    f = lambda x: a+x 
    return dview.apply_sync(f, x) 

def idop(x): 
    rc = Client() 
    dview = rc[:] 
    dview['a'] = 5 
    f = interactive(lambda x: a+x) 
    return dview.apply_sync(f, x) 

Şimdi dop 'a' dop modülünden ve idop kullanacak kullanacaktır 'a' daki motor ad gelen.

 
from dop import dop, idop 
print dop(5) # 6 
print idop(5) # 10 
[1]

: ipython> = 0.13 (gelecek olan salım) 'de, @interactive da from IPython.parallel import interactive olarak mevcut olduğu her zaman gerekir arasındaki tek fark uygulamak geçirilen fonksiyon @interactive sarılmış olmasıdır olmuştu.