2017-05-09 13 views
2

計算に任意のパッケージを使用するマルチプロセッシングプールを実装する必要があります。このために、私はPythonとjoblib 0.9.0を使用しています。このコードは、基本的に私が望む構造です。 Windowsの10およびRed Hat Enterprise Linuxの両方でPythonマルチプロセッシングプール関数が定義されていません

import numpy as np 
from joblib import pool 

def someComputation(x): 
    return np.interp(x, [-1, 1], [-1, 1]) 

if __name__ == '__main__': 
    some_set_of_numbers = [-1,-0.5,0,0.5,1] 
    the_pool = pool.Pool(processes=2) 
    solutions = [the_pool.apply_async(someComputation, (x,)) for x in some_set_of_numbers] 
    print(solutions[0].get()) 

アナコンダは、Python 3.6.0(だけでなく、仮想ENVSと3.5と3.4を)4.3.1実行している、私は( 'NP' がsomeComputationに渡されていないことを取得)エラーに

File "C:\Anaconda3\lib\site-packages\multiprocessing_on_dill\pool.py", line 608, in get 
    raise self._value 
NameError: name 'np' is not defined 

を上げる機能は、しかし、私のMac OS X 10.11.6は、Python 3.5と同じJOBLIBを実行する上で、私はまったく同じコードでの「-1」、予想される出力を得ます。 This質問は本質的に同じですが、それはpathlを扱い、joblibは扱っていません。一般的な答えは期待どおりになりまし出力「-1」機能

from joblib import pool 

def someComputation(x): 
    import numpy as np 
    return np.interp(x, [-1, 1], [-1, 1]) 

if __name__ == '__main__': 
    some_set_of_numbers = [-1,-0.5,0,0.5,1] 
    the_pool = pool.Pool(processes=2) 
    solutions = [the_pool.apply_async(someComputation, (x,)) for x in some_set_of_numbers] 
    print(solutions[0].get()) 

これは、WindowsとLinuxマシン上で問題を解決し、内部のnumpyのimport文を含めることでしたが、この解決策は不格好と思われます。何らかの理由がありますなぜのコードの最初のビットはMacでは動作しますが、WindowsまたはLinuxでは動作しませんか?私は最終的にLinuxマシン上でこのコードを実行する必要があるので、関数の中にimport文を置くことを含まない修正はありますか?

編集

さらにビットを調査した後、私は問題を引き起こしているように見える私は数年前に入れ、古い回避策を見つけました。 JOBLIB/pool.pyにおいて、Iは、任意の関数の酸洗をサポートするために

from multiprocessing_on_dill.pool import Pool 

from multiprocessing.pool import Pool 

からライン44を変更しました。何らかの理由で、この変更はWindowsとLinuxで本当に問題を引き起こしていますが、Macマシンはうまく動作します。 multiprocessing_on_dillの代わりにマルチプロセッシングを使用すると上記の問題は解決しますが、コードはピクルできないため、大部分のケースでは機能しません。

+0

これがあなたの質問に答えるかどうかわかりませんが、関数にインポートを置くよりも良い方法は、 'def someComputation(x、np = np):'として宣言することです。モジュールは、モジュールが最初に解釈されるときに関数内のローカル名にバインドする必要があり、毎回インポート機構を実行する必要がありません。 –

+0

本当にうまくいくと私は確かにそれを使うことができます。 –

答えて

1

正確な問題はわかりませんが、グローバルスコープをタスクを実行するサブプロセスに転送するには問題があるようです。あなたは、潜在的に、関数のパラメータとして名前npを結合することによって、名前のエラーを回避することができます

def someComputation(x, np=np): 
    return np.interp(x, [-1, 1], [-1, 1]) 

これは輸入機械への呼び出し機能が実行されるたびに必要としないという利点を有します。 npという名前は、モジュールのロード中に最初に評価されたときに関数にバインドされます。

関連する問題