我有一个Python代码(它是一个最小化算法),它调用一个函数' get_drift_time'。这个函数创建了一堆粒子(~100,000),使用函数“漂移粒子”漂移它们中的每一个。并将每个粒子的结果参数保存到列表中。然后我拿这个列表并将其反馈到我的主要最小化代码中,我将进一步使用它。这次迭代(调用' get_drift_time'并从' drift_particles'创建列表)多次发生O(3)。
每个粒子的漂移与任何其他粒子无关。我找到了一种使用Pool类并行化的方法:
from multiprocessing import Pool
# previous code is here
pool = Pool(processes=20)
# start_points gives the initial position of each particle; cube_field and length define the drift environment and are the same for every particle
result_async = pool.map_async(drift_particles, itertools.izip(start_points, itertools.repeat(cube_field), itertools.repeat(length)))
result = np.asarray(result_async.get())
pool.close()
pool.join()
tet_cut = result[:,9] == 1
return tet_cut
我的代码的整体速度受限于我可以多快地让所有粒子漂移。现在使用pool.map_async
时,这反过来似乎受到节点上核心数量的限制。我在一个具有20个内核的节点上运行此代码,但我可以访问许多更多节点,因此我想利用它。我尝试使用分布在不同节点上的40个核心来运行此代码,但它使代码显着变慢。
如何并行化这个过程,以便我可以利用多个节点(每个节点有多个核心)?
编辑:
我研究了使用水壶,但我无法弄清楚如何将它应用到这个例子中。我可以修改我的代码以包含@TaskGenerator,但我不确定是否可以在代码中运行jug。即在水壶网站上,我发现在LSF上运行jug的命令是:
bsub -o output.txt -J "jug[1-100]" jug execute myscript.py
但是,我不想开始myscript.py
的100个工作。而不是在myscript.py
内,我想定期调用jug来运行map(drift_particles, itertools.izip(start_points, itertools.repeat(cube_field), itertools.repeat(length)))
的多个实例。这可能吗?