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 因为我试图在代码用完与未能及时收敛时分开 - 我意识到那是多余的。一方面,结果字典并没有达到我的预期:有没有办法查询当前进程的参数并将它们用作字典键?另外,如果发生超时错误,我理想情况下会以某种方式标记这些参数——最好的方法是什么?

最后,为什么在这段代码中回调只调用一次?不应该在每个过程成功完成时调用它吗?该代码返回一个字典,其中所有参数都被塞进一个键(作为 .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 回答