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