0

パラメータ スペースをすばやくスイープするために、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 ファイルとして) に詰め込まれた辞書を返し、すべての回答がキー値のリストになっています。

4

1 に答える 1

0

ここで問題を完全に理解しているとは思いませんがLinAlgError、計算関数で をキャッチするこのようなものに単純化するとどうなるでしょうか。

ここでapply_asyncは、プールに送信された各タスクの結果オブジェクトを取得するために使用されます。これにより、結果オブジェクトにタイムアウトを簡単に適用できます。

def run_solver(A, B):
    try:
       result = A + B
    except np.linalg.LinAlgError:
       result = np.nan
    return result

results = []
with Pool(processes=15) as pool:
    params = (zip(A, B))
    result_pool = [pool.apply_async(run_solver, args) for args in params]
    for result in result_pool:
        try:
            results.append(result.get(15))
        except context.TimeoutError:
            # do desired action on timeout
            results.append(None)
于 2014-10-29T07:17:53.520 に答える