Пространства имен IPython.parallel

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

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, и теперь она работает.


person kyrre    schedule 05.05.2012    source источник
comment
где вы устанавливаете x и y? они не являются параметрами функции, так откуда они берутся? видимо это и есть причина проблемы.   -  person mata    schedule 05.05.2012
comment
я устанавливаю их в функции инициализации: for c, f в zip(rc, files): c.execute( X, y = load...   -  person kyrre    schedule 05.05.2012


Ответы (1)


Разница заключается в глобальных модулях. Когда функция определена в модуле, глобальным пространством имен является пространство имен модуля (т. е. mv.y). Когда этот модуль __main__, например. интерактивно определенная функция, то глобальное пространство имен — это ваше user_ns на движке, и на него влияет 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
person minrk    schedule 05.05.2012