2014-10-29 110 views
0

我正在尝试使用Pool.starmap_async来运行一些采用多个参数作为输入的代码,以便快速扫描参数空间。代码运行一个有时不会收敛的linalg函数,而是抛出一个np.linalg.LinAlgError。在这种情况下,我希望我的代码返回np.nan,并继续其快乐的方式。理想情况下,我也希望指定一个超时,以便代码在设定的秒数后放弃并继续到不同的参数组合。Python 3多处理:内部和超时错误处理和回调

# 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文件),所有答案都是键值中的一个列表。

回答

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) 
+0

我喜欢这个主意,但是这段代码不起作用 - 地图对象不可迭代。你的逐字代码返回结果为pool.starmap_async(run_solver,params): TypeError:'MapResult'对象不可迭代 – 2014-10-29 16:05:07

+0

我用另一种方法更新了它,以实现类似于我的想法。 – monkut 2014-10-30 01:17:44