私は、大規模な(数万から数十万の数値積分)一連の問題に対してかなり重い数値作業を行うコードに取り組んでいます。幸い、これらの統合は驚異的並列であるため、Pool.map()を使用して作業を複数のコアに分割するのは簡単です。
現在、この基本的なワークフローを持つプログラムがあります。
#!/usr/bin/env python
from multiprocessing import Pool
from scipy import *
from my_parser import parse_numpy_array
from my_project import heavy_computation
#X is a global multidimensional numpy array
X = parse_numpy_array("input.dat")
param_1 = 0.0168
param_2 = 1.505
def do_work(arg):
return heavy_computation(X, param_1, param_2, arg)
if __name__=='__main__':
pool = Pool()
arglist = linspace(0.0,1.0,100)
results = Pool.map(do_work,arglist)
#save results in a .npy file for analysis
save("Results", [X,results])
X、param_1、およびparam_2はハードコーディングされており、プール内の各プロセスに対してまったく同じ方法で初期化されるため、これはすべて正常に機能します。コードが機能するようになったので、ファイル名、param_1、およびparam_2がハードコーディングされるのではなく、実行時にユーザーによって入力されるようにします。
注意すべきことの1つは、作業が行われている間、X、param_1、およびparam_2は変更されないということです。私はそれらを変更しないので、プログラムの開始時に次のようなことを行うことができます。
import sys
X = parse_numpy_array(sys.argv[1])
param_1 = float(sys.argv[2])
param_2 = float(sys.argv[3])
これでうまくいきますが、このコードのほとんどのユーザーはWindowsマシンからコードを実行しているので、コマンドライン引数のルートには行きたくありません。
私が本当にやりたいのは次のようなものです。
X, param_1, param_2 = None, None, None
def init(x,p1, p2)
X = x
param_1 = p1
param_2 = p2
if __name__=='__main__':
filename = raw_input("Filename> ")
param_1 = float(raw_input("Parameter 1: "))
param_2 = float(raw_input("Parameter 2: "))
X = parse_numpy_array(filename)
pool = Pool(initializer = init, initargs = (X, param_1, param_2,))
arglist = linspace(0.0,1.0,100)
results = Pool.map(do_work,arglist)
#save results in a .npy file for analysis
save("Results", [X,results])
ただし、もちろん、これは失敗し、pool.map呼び出しが発生すると、X / param_1/param_2はすべてNoneになります。私はマルチプロセッシングにかなり慣れていないので、イニシャライザーの呼び出しが失敗する理由がわかりません。私がやりたいことをする方法はありますか?これを完全に回避するためのより良い方法はありますか?共有データの使用も検討しましたが、ドキュメントの理解から、numpy配列を含まないctypeでのみ機能します。これに関する助けをいただければ幸いです。