【问题标题】:How can scipy.weave.inline be used in a MPI-enabled application on a cluster?scipy.weave.inline 如何在集群上启用 MPI 的应用程序中使用?
【发布时间】:2013-06-13 19:29:11
【问题描述】:

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

【问题讨论】:

  • 我有一个解决方案,但我还不能发布它。仍然欢迎其他解决方案。

标签: python scipy cluster-computing mpi


【解决方案1】:

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

【讨论】:

  • 就我而言,这个解决方案比我自己的解决方案更简单、更直接。我仍然会在几个小时后发布我的解决方案。
  • 恐怕我不得不接受你的回答。如果有多个实例在同一个节点的不同处理器上运行,这并不能解决问题。
【解决方案2】:

我之前对这个问题的想法:

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

我选择了后者。 scipy.weave.inline 函数使用一个目录,该目录绑定到scipy.weave.inline 模块的模块级名称function_catalog。这可以通过查看该模块的代码 (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)

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2018-09-28
      • 1970-01-01
      • 2017-01-09
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-01
      相关资源
      最近更新 更多