パラメータ スペースをすばやくスイープするために、Pool.starmap_async を使用して、複数のパラメータを入力として受け取るコードを実行しようとしています。このコードは、時々収束しない linalg 関数を実行し、代わりに np.linalg.LinAlgError をスローします。この場合、コードが np.nan を返し、その陽気な方法を続けたいと思います。また、理想的には、タイムアウトを指定して、コードが設定された秒数の後にあきらめて、別のパラメーターの組み合わせに進むようにしたいと思います。
# This is actually some long function that sometimes returns a linalg error
def run_solver(A, B):
return A+B
if __name__ == '__main__':
# Parameters
Asearch = np.arange(4, 8, 1)
Bsearch = np.arange(0.2, 2, 0.2)
# Search all combinations of Qsearch and Rmsearch
AB = np.array(list(itertools.product(Qsearch, Rmsearch)))
A = AB[:, 0]
B = AB[:, 1]
result = {}
with Pool(processes=15) as pool:
def cb(r):
print("callback")
result[params] = r
def ec(r):
result[params] = np.nan
print("error callback")
raise np.linalg.LinAlgError
try:
params = (zip(A, B))
r = pool.starmap_async(run_solver, params, callback=cb, error_callback=ec)
print(r.get(timeout=10))
except np.linalg.LinAlgError:
print("parameters did not converge")
except mp.context.TimeoutError:
print("Timeout error. Continuing...")
pickle.dump(result, open("result.p", "wb"))
print("pickling output:", result)`
コードが続行されるように TimeoutError を例外としてキャッチしようとしましたが、意図的に LinAlgError を発生させています。なぜなら、コードが時間切れになったときと収束に失敗したときを区別しようとしているからです。それは冗長です。1 つには、結果の辞書は意図したとおりにはなりません。現在のプロセスのパラメーターを照会し、それらを辞書のキーとして使用する方法はありますか? また、タイムアウト エラーが発生した場合は、何らかの方法でこれらのパラメーターにフラグを立てることが理想的です。これを行う最善の方法は何ですか?
最後に、このコードでコールバックが 1 回だけ呼び出されるのはなぜですか? 各プロセスが正常に完了すると呼び出されるべきではありませんか? このコードは、すべてのパラメーターが 1 つのキー (.zip ファイルとして) に詰め込まれた辞書を返し、すべての回答がキー値のリストになっています。