如何在群集上的MPI应用程序中使用scipy.weave.inline?

时间:2013-06-17 18:34:19

标签: python scipy cluster-computing mpi

如果在一个大型并行MPI启用的应用程序中调用scipy.weave.inline,该应用程序在具有所有节点通用的主目录的集群上运行,则每个实例都会访问编译代码的相同目录:$ HOME / .pythonxx_compiled。由于明显的原因这很糟糕,并导致许多错误消息。如何规避这个问题呢?

3 个答案:

答案 0 :(得分:1)

根据the scipy docs,您可以将已编译的数据存储在不在NFS共享上的目录中(例如/ tmp或/ scratch或您的系统可用的任何内容)。那你就不用担心你的冲突了。您只需要将PYTHONCOMPILED环境变量设置为其他内容。

答案 1 :(得分:1)

我之前对此问题的看法:

scipy.weave.catalog必须使用适当的锁定机制进行增强,以便序列化对目录的访问,或者每个实例都必须使用自己的目录。

我选择后者。 scipy.weave.inline函数使用绑定到function_catalog模块的模块级名称scipy.weave.inline的目录。通过查看此模块的代码(https://github.com/scipy/scipy/tree/v0.12.0/scipy/weave)可以发现这一点。

简单的解决方案现在是在程序开头将这个名称单个化为其他名称:

from mpi4py import MPI

import numpy as np

import scipy.weave.inline_tools
import scipy.weave.catalog

import os
import os.path

comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()

catalog_dir = os.path.join(some_path,  'rank'+str(rank))
try:
    os.makedirs(catalog_dir)
except OSError:
    pass

#monkeypatching the catalog
scipy.weave.inline_tools.function_catalog = scipy.weave.catalog.catalog(catalog_dir)

现在inline顺利运行:每个实例在公共NFS目录中都有自己的目录。当然,如果两个不同的并行任务同时运行,则此命名方案会中断,但如果目录位于/ tmp中,情况也会如此。

编辑:如上面的评论所述,如果并行运行多个独立作业,此过程仍然存在问题。这可以通过在路径名中添加随机uuid来解决:

import uuid

u = None
if rank == 0:
    u = str(uuid.uuid4())

u = comm.scatter([u]*size, root=0)

catalog_dir = os.path.join('/tmp/<username>/pythoncompiled',  u+'-'+str(rank))
os.makedirs(catalog_dir)

#monkeypatching the catalog
scipy.weave.inline_tools.function_catalog = scipy.weave.catalog.catalog(catalog_dir)

当然,在计算后删除这些文件会很好:

shutil.rmtree(catalog_dir)

修改:还有一些其他问题。由于来自不同实例的同时访问,存储cpp和o文件的中间目录也存在一些问题,因此必须将上述方法扩展到此目录:

basetmp = some_path
catalog_dir = os.path.join(basetmp, 'pythoncompiled',  u+'-'+str(rank))
intermediate_dir = os.path.join(basetmp, 'pythonintermediate',  u+'-'+str(rank))

os.makedirs(catalog_dir, mode=0o700)
os.makedirs(intermediate_dir, mode=0o700)

#monkeypatching the catalog and intermediate_dir
scipy.weave.inline_tools.function_catalog = scipy.weave.catalog.catalog(catalog_dir)
scipy.weave.catalog.intermediate_dir = lambda: intermediate_dir

#... calculations here ...

shutil.rmtree(catalog_dir)
shutil.rmtree(intermediate_dir)

答案 2 :(得分:0)

一个快速的解决方法是在每个节点上使用本地目录(例如Wesley所说的/ tmp),但如果您有容量,则每个节点使用一个MPI任务。