python/pyfmi と multiprocessing を使用して、複数の Modelica FMU を並行してシミュレートしようとしています。ただし、FMU が初期化されると、サブプロセスから pyfmi FMI オブジェクトを返すことができません。pyfmi FMI オブジェクト (例: pyfmi.fmi.FMUModelCS2 または pyfmi.fmi.FMUState2) は選択できないようです。また、ディルをピクルスにしようとしましたが、これはうまくいきません。ただし、ディルを使用すると、オブジェクトはピクル化可能です。つまり、エラーはありませんが、後でそれらをリロードしようとすると、何らかの形で破損します。この問題を解決する方法を知っている人はいますか? ありがとう!
3 に答える
私がEstimationPyを作成したとき、私は同様の問題に直面しました。複数のプロセスを使用して同じ FMU の並列シミュレーションを実行するためのラッパーを作成することになりました。
ここで実装を確認することをお勧めします https://github.com/lbl-srg/EstimationPy/blob/master/estimationpy/fmu_utils/fmu_pool.py
そして例にhttp://lbl-srg.github.io/EstimationPy/modules/examples/first_order.html#run-multiple-simulations
問題は、pyfmi.fmiFMUModelCS2 が外部ライブラリに依存する Cython クラスであるため、選択できないことです。そのため、残念ながらできません。
マルチプロセッシングを使用したい場合は、最初にプロセスを作成してから、FMU を個別のプロセスにロードするしかありません。このようにして、クラスをピクルする必要はありません。
pathosモジュールは、 と同様のインターフェースでマルチプロセッシングを可能にしますが、シリアル化の代わりにdillmultiprocessing
に依存しています。このメソッドは、結果がメモリ内で処理される場合、の並列実行に対して機能します。pickle
Pool
model.simulate
n_core = 2
n_simulation = 10
# ====
import pyfmi
model = pyfmi.load_fmu(path_fmu)
def worker(*args):
model.reset()
print "================> %d" % args[0]
return model.simulate(options=dict(result_handling="memory"))["y"]
from pathos.multiprocessing import Pool
pool = Pool(n_core)
out = pool.map(worker, range(n_simulation))
pool.close()
pool.join()
上記のスニペットで、メモリ内の結果を処理する必要があることに注意してください: options=dict(result_handling="memory")
. デフォルトでは、シミュレーションの量が少ない場合に機能する一時ファイルを使用します。ただし、キューが長いほど、次のようなものを取得する可能性が高くなります
Exception in thread Thread-27:
Traceback (most recent call last):
File "/home/USER/anaconda2/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/home/USER/anaconda2/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/USER/anaconda2/lib/python2.7/site-packages/multiprocess/pool.py", line 389, in _handle_results
task = get()
File "/home/USER/anaconda2/lib/python2.7/site-packages/dill/dill.py", line 260, in loads
return load(file)
File "/home/USER/anaconda2/lib/python2.7/site-packages/dill/dill.py", line 250, in load
obj = pik.load()
File "/home/USER/anaconda2/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/home/USER/anaconda2/lib/python2.7/pickle.py", line 1139, in load_reduce
value = func(*args)
TypeError: __init__() takes exactly 2 arguments (1 given)
私が把握できていないもの。