5

私はIPythonのドキュメント/チュートリアルを読んだり読み直したりしてきましたが、この特定のコードの問題を理解できません。各エンジンに配信される名前空間には関数dimensionless_runが表示されないようですが、関数はで定義されており__main__、グローバル名前空間の一部として明確に表示されるため、混乱しています。

wrapper.py:

import math, os

def dimensionless_run(inputs):
    output_file = open(inputs['fn'],'w')
    ...
    return output_stats

def parallel_run(inputs):
    import math, os  ## Removing this line causes a NameError: global name 'math'
                     ## is not defined.
    folder = inputs['folder']
    zfill_amt = int(math.floor(math.log10(inputs['num_iters'])))
    for i in range(inputs['num_iters']):
        run_num_str = str(i).zfill(zfill_amt)
        if not os.path.exists(folder + '/'):
            os.mkdir(folder)
        dimensionless_run(inputs)
    return

if __name__ == "__main__":
    inputs = [input1,input2,...]
    client = Client()
    lbview = client.load_balanced_view()
    lbview.block = True
    for x in sorted(globals().items()):
        print x
    lbview.map(parallel_run,inputs)

後にこのコードを実行すると、 andモジュール、およびand関数ipcluster start --n=6を含むソートされたグローバルディクショナリが生成されます。この後にIPython.parallel.error.CompositeErrorが続きます。メソッドの呼び出しからの1つ以上の例外:parallel_run。これは多数の、で構成され、nは0から5まで実行されます。mathosparallel_rundimensionless_run[n:apply]: NameError: global name 'dimensionless_run' is not defined

私が理解していないことが2つあり、それらは明確に関連しています。

  1. dimensionless_runコードがグローバル名前空間で識別されないのはなぜですか?
  2. parallel_runの定義import math, osで必要なのはなぜですか?

編集:これは名前空間エラーの多くではないことが判明しました-私はipcluster start --n=6コードが含まれていないディレクトリで実行していました。これを修正するには、コードのディレクトリでstartコマンドを実行するだけで済みました。また、次の行を追加して修正しました。

    inputs = input_pairs
    os.system("ipcluster start -n 6") #NEW
    client = Client()
    ...
    lbview.map(parallel_run,inputs)
    os.system("ipcluster stop")       #NEW

必要なクラスターを適切な場所で開始します。

4

1 に答える 1

8

これは主に IPython.parallel に関する Python 名前空間の問題の複製であり、より詳細な回答がありますが、要点は次のとおりです。

クライアントがエンジンに送信するとき、関数が定義されている名前空間全体 (モジュール)parallel_runではなく、その関数のみを送信します。__main__したがって、 remote を実行する場合、orまたはparallel_runへのルックアップは最初に(関数で既に定義されているもの、つまり関数内インポート) を参照し、次にengineのモジュールである を参照します。mathosdimensionless_runlocals()globals()__main__

エンジンで確実に名前を使用できるようにするためのさまざまな方法がありますが、おそらく最も簡単なのは、それらをエンジンに明示的に定義/送信することです (インタラクティブな名前空間 __main__、IPython でローカルにあるのと同じように、エンジンにあります)。

client[:].execute("import os, math")
client[:]['dimensionless_run'] = dimensionless_run

その場合、すべてが期待どおりに機能するはずです。

これは、対話的に/スクリプトで定義されたモジュールに固有の問題です。このファイルがスクリプトではなくモジュールである場合は発生しません。

from mymod import parallel_run
lbview.map(parallel_run, inputs)

この場合、globals()これはモジュール グローバルであり、通常はどこでも同じです。

于 2012-09-06T20:17:08.050 に答える