8

環境

クラスターに接続されたノートブックでのインタラクティブなプロトタイピング開発で、クライアント__main__セッションで使用できるクラスを定義し、クラスター エンジン ノードでインタラクティブに更新して、インスタンスを渡すことでそのクラスのインスタンスを移動できるようにしたいと考えています。 LoadBalanced ビューへの引数。以下は、一般的なユーザー セッションを示しています。

最初に並列クラスタリング環境をセットアップします。

>>> from IPython.parallel import Client
>>> rc = Client()
>>> lview = rc.load_balanced_view()
>>> rc[:]
<DirectView [0, 1, 2]>

ノートブック セルで、インタラクティブに編集しているコンポーネントのコード スニペットを定義しましょう。

>>> class MyClass(object):
...     def __init__(self, parameter):
...         self.parameter = parameter
...
...     def update_something(self, some_data):
...         # do something smart here with some_data & internal state
...
...     def compute_something(self, other_data):
...         # do something smart here with other data & internal state
...         return something
...

次のセルでは、このクラスのインスタンスを構築するスクリプトを作成し、クラスター環境の負荷分散ビューを使用して、さまざまな入力パラメーターでコンポーネントを評価します。

>>> def process(obj, some_data, other_data):
...     obj.update_something(some_data)
...     return obj.compute_something(other_data)
...
>>> tasks = []
>>> some_instances = [MyClass(i) for i in range(10)]
>>> for obj in some_instances:
...    for some_data in data_source_1:
...         for other_data in data_source_2:
...             ar = lview.apply_async(process, obj, some_data, other_data)
...             tasks.append(ar)
...
>>> # wait for computation to end
>>> results = [ar.get() for ar in tasks] 

問題

負荷分散されたビューのエンジンは、関数の最初の引数として渡されたインスタンスを unpickle できないため、これは明らかにprocess機能しません。プロセス関数定義自体は正常に渡されます。これは、 apply_async(関数の属性にアクセスすることによって) バイトコード インストロスペクションを実行して.codeピクルし、残りの引数に対して単純なピクルを実行するだけであるためです。

可能な解決策(私にはうまくいきません)

  • 別の解決策の 1 つ%%pxは、クラスの定義を保持するセルでセル マジックを使用することMyClassです。ただし、それでは、スケジューリングも行うクライアント スクリプトでクラス インスタンスを構築できなくなります。魔法を使わずにセルの内容をコピーして別のセルに貼り付ける必要があります%%px(または、魔法を使って 1 回、魔法を使わずにセルを 2 回実行する) 必要がありますが、クラスのメソッドを反復的に編集しているときは面倒です。開発&評価設定。

  • 別の解決策は、クラス定義を関数内に埋め込むことprocessですが、後でノートブックの他の関数でそのクラス定義を再利用したいので、これは実用的ではありません。

  • または、クラスの使用をやめて、最初の引数として then をapply_async. ただし、後でノートブックから抽出し、結果のクラスをオブジェクト指向ライブラリに含めるために、オブジェクト指向の方法でコードのプロトタイプを作成したいので、それも好きではありません。http://nbviewer.ipython.orgパブリッシャーを使用して開発者間でアイデアを交換するために使用する共同プロトタイピング ツールとして機能するノートブック セッション。

  • 最後の代替手段は、ファイル システム上のファイルの Python モジュールにクラスを記述し、そのファイルをたとえば NFS を使用してエンジン PYTHONPATH に送信することです。それは機能しますが、ノートブックでのインタラクティブなプロトタイピングの目的全体を無効にするノートブック環境でのみ作業することを妨げます.

基本的に、クラスをインタラクティブに定義し、その定義をエンジンに送信する方法はありますか?

クライアントでを使用してクラス定義をピクルしinspect.getsource、ソースをエンジンに送信してビルトインを使用することは可能ですが、残念ながら、組み込みモジュールeval内で定義されたクラスに対してソース インスペクションが機能しません。DummyMod

TypeError: <IPython.core.interactiveshell.DummyMod object at 0x10c2c4e50> is a built-in class

代わりにクラス定義のバイトコードを検査する方法はありますか?

または%%px、セルのコンテンツをクライアントと各エンジンの両方でローカルに実行するために魔法を使用することは可能ですか?

4

2 に答える 2

9

詳細な質問に感謝します (そして、Twitter で私に連絡してください)。

まず、単純な解決策は

rc[:]['MyClass'] = MyClass

ただし、インタラクティブに定義されたクラスをピクルすると、参照 ( ) のみが生成され、 '\x80\x02c__main__\nMyClass\nq\x01.'DummyMod AttributeError が返されます。これはおそらく、IPython のシリアル化で内部的に修正できます。

ただし、実際の実用的なソリューションに進みます。

にローカル実行を追加するの%%pxは非常に簡単です。

def pxlocal(line, cell):
    ip = get_ipython()
    ip.run_cell_magic("px", line, cell)
    ip.run_cell(cell)
get_ipython().register_magic_function(pxlocal, "cell")

これで、セルをローカルで実行することに加えて実行される%%pxlocal魔法ができました。%%px

次に、あなたがしなければならないことは次のとおりです。

%%pxlocal

class MyClass(object):
    # etc

どこでもクラスを定義します。--localにフラグを追加する%%pxので、この余分な手順は必要ありません。

完全な実用的なノートブックの例

于 2013-01-06T20:52:25.557 に答える
2

「dill」を使用してインタラクティブに定義されたクラスをピクルすることができ、%%pxlocal マジック、DummyMod の使用、名前空間の偽造について心配する必要はないと思います。

クラスをインタラクティブにピクルするには、"import dill" を実行してから、最初に行ったようにクラスをビルドします。その後、正常なマップまたは apply_async 関数を介して送信できるはずです。

于 2013-09-08T23:41:10.063 に答える