我正在编写一些代码,这些代码对大量(数万到数十万个数值积分)问题进行了一些相当繁重的数值工作。幸运的是,这些集成是令人尴尬的并行,因此很容易使用 Pool.map() 将工作拆分到多个内核。
现在,我有一个具有以下基本工作流程的程序:
#!/usr/bin/env python
from multiprocessing import Pool
from scipy import *
from my_parser import parse_numpy_array
from my_project import heavy_computation
#X is a global multidimensional numpy array
X = parse_numpy_array("input.dat")
param_1 = 0.0168
param_2 = 1.505
def do_work(arg):
return heavy_computation(X, param_1, param_2, arg)
if __name__=='__main__':
pool = Pool()
arglist = linspace(0.0,1.0,100)
results = Pool.map(do_work,arglist)
#save results in a .npy file for analysis
save("Results", [X,results])
由于 X、param_1 和 param_2 是硬编码的,并且对于池中的每个进程都以完全相同的方式初始化,所以这一切都很好。现在我的代码已经工作了,我想让它让用户在运行时输入文件名、param_1 和 param_2,而不是硬编码。
需要注意的一点是,X、param_1 和 param_2 在工作完成时不会被修改。由于我不修改它们,我可以在程序开始时做这样的事情:
import sys
X = parse_numpy_array(sys.argv[1])
param_1 = float(sys.argv[2])
param_2 = float(sys.argv[3])
这样就可以解决问题,但是由于此代码的大多数用户都在 Windows 机器上运行代码,所以我宁愿不走命令行参数的路线。
我真正想做的是这样的:
X, param_1, param_2 = None, None, None
def init(x,p1, p2)
X = x
param_1 = p1
param_2 = p2
if __name__=='__main__':
filename = raw_input("Filename> ")
param_1 = float(raw_input("Parameter 1: "))
param_2 = float(raw_input("Parameter 2: "))
X = parse_numpy_array(filename)
pool = Pool(initializer = init, initargs = (X, param_1, param_2,))
arglist = linspace(0.0,1.0,100)
results = Pool.map(do_work,arglist)
#save results in a .npy file for analysis
save("Results", [X,results])
但是,当 pool.map 调用发生时,这当然会失败并且 X/param_1/param_2 都是 None 。我对多处理很陌生,所以我不确定为什么对初始化程序的调用失败。有没有办法做我想做的事?有没有更好的方法来解决这个问题?我也看过使用共享数据,但根据我对文档的理解,它只适用于不包括 numpy 数组的 ctypes。对此的任何帮助将不胜感激。