2012-05-05 8 views
1

Я хочу распараллелить функцию с помощью IPython.parallel, и когда я определяю его в IPython оболочки это работает безотказно:IPython.parallel пространств имен

Type:  function 
Base Class: <type 'function'> 
String Form:<function gradient at 0x3ae0398> 
Namespace: Interactive 
File:  /root/<ipython-input-30-cf7eabdfef84> 
Definition: gradient(w) 
Source: 
def gradient(w): 
    s = (1.0 + exp(y * (X * w)))**-1 
    return C*X.T*((1 - s) * y) 

rc = Client() 
rc[:].apply_sync(gradient, w) 
... 

Однако, когда я определяю его в модуле и использования импорт:

Type:  function 
Base Class: <type 'function'> 
String Form:<function gradient at 0x3933d70> 
Namespace: Interactive 
File:  /root/mv.py 
Definition: mv.gradient(w) 
Source: 
def gradient(w): 
    s = (1.0 + exp(y * (X * w)))**-1 
    return C*X.T*((1 - s) * y) 

import mv 
rc = Client() 
rc[:].apply_sync(mv.gradient, w) 

CompositeError: one or more exceptions from call to method: gradient 
[0:apply]: NameError: global name 'y' is not defined 
[1:apply]: NameError: global name 'y' is not define 

Кроме того, она отлично работает одна моя локальная система работает на Python 2.7.2/IPython 0.12, в то время как он падает на Python 2.7.2 +/IPython 0.12 с использованием новейшего Starcluster Ubuntu AMI.

Что здесь происходит?

ОБНОВЛЕНИЕ: Я установил версию IPython 0.13.dev из github и теперь он работает.

+0

где вы задаете 'x' и' y'? они не являются параметрами функции, поэтому откуда они? что, по-видимому, является причиной проблемы. – mata

+0

Я устанавливаю их в функции init: для c, f в zip (rc, files): c.execute ("X, y = load ..." – kyrre

ответ

3

Разница заключается в модуле глобализации. Когда функция определена в модуле, глобальное пространство имён - это модуль (то есть mv.y). Когда этот модуль равен __main__, например. интерактивно определенная функция, тогда глобальное пространство имен является вашим user_ns в Engine, и на него влияет execute("y=5").

IPython предоставляет декоратор, если вы хотите, чтобы определить функции в модулях, которые должны вести себя так, как будто они в интерактивном режиме определены (имеют доступ к пространству имен пользователя как глобал):

 
# mymod 

from IPython.parallel.util import interactive 

@interactive 
def by_a(b): 
    """multiply a by b" 
    return a*b 

и в интерактивном режиме, вы можете сделать :

 
from mymod import by_a 

e0 = rc[0] 
e0.execute("a=5") 
print e0.apply_sync(by_a, 10) # 50 
e0.execute("a=10") 
print e0.apply_sync(by_a, 10) # 100