MPI,python,Scatterv和重叠数据

时间:2016-04-12 19:44:36

标签: python mpi mpi4py

MPI标准3.0,关于mpi_scatterv:

  

计数,类型和位移的规范不应导致根目录上的任何位置被多次读取。"

但是,我使用下面的代码在python中测试mpi4py并不表示从root用户读取数据有多次出现问题:

import numpy as np
from sharethewealth import sharethewealth

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

counts = [16, 17, 16, 16, 16, 16, 15]
displs = [0, 14, 29, 43, 57, 71, 85]

if rank == 0:
    bigx = np.arange(100, dtype=np.float64)
else:
    bigx = None

my_size = counts[rank]
x = np.zeros(my_size)

comm.Scatterv([bigx, counts, displs, MPI.DOUBLE], x, root = 0)

print x

命令

> mpirun -np 7 python mycode.py

产生

[ 57.  58.  59.  60.  61.  62.  63.  64.  65.  66.  67.  68.  69.  70.  71. 72.]

[ 85.  86.  87.  88.  89.  90.  91.  92.  93.  94.  95.  96.  97.  98.  99.]

[  0.   1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.  13.  14. 15.]

[ 29.  30.  31.  32.  33.  34.  35.  36.  37.  38.  39.  40.  41.  42.  43. 44.]

[ 43.  44.  45.  46.  47.  48.  49.  50.  51.  52.  53.  54.  55.  56.  57. 58.]

[ 71.  72.  73.  74.  75.  76.  77.  78.  79.  80.  81.  82.  83.  84.  85. 86.]

[ 14.  15.  16.  17.  18.  19.  20.  21.  22.  23.  24.  25.  26.  27.  28. 29.  30.]

输出显然是正确的,并且来自根(过程0)的数据在每个边界点处被明确地引用了不止一次。我不理解MPI标准吗?或者这是一种一般不能依赖的偶然行为?

FWIW,我在OSX上运行python 2.7。

2 个答案:

答案 0 :(得分:2)

你不能依赖这个。

这个假设直接源于MPI标准。由于mpi4py大写函数只是MPI之上的一个薄层,这才是最重要的。该标准还指出:

  

基本原理。虽然不需要,但最后的限制是强制执行的   用MPI_GATHER实现对称,其中有相应的限制   (多写限制)是必要的。 (理由结束。)

考虑到它在标准中,MPI实现可以使用它:

  • 忽略违规行为
  • 违反时发出警告
  • 违反时失败
  • 将此假设用于任何可能导致违反时未定义行为的优化

最后一点是最可怕的,因为它可能会引入微妙的错误。考虑到发送缓冲区的只读性质,很难想象这样的优化,但这并不意味着它确实存在/不存在。正如一个想法考虑strict aliasing optimizations。另请注意,MPI实现非常复杂 - 它们的行为可能会在版本,配置,数据大小或其他环境变化之间变得看似不稳定。

还有一个臭名昭着的例子memcpy:标准禁止重叠内存输入,并且在某些时候,glibc实现利用它来进行微小的争议优化。不满足要求的代码开始失败,用户开始听到strange sound on mp3 flash websites,然后是heated debate涉及Linus Torvalds和Ulrich Drepper。

故事的士气是:遵循标准规定的要求,即使它现在有效,但要求对你没有意义。也很高兴有这么详细的标准。

答案 1 :(得分:2)

MPI标准包括许多要求,这些要求通常不会被实施严格检查,主要是出于性能原因。理由是,根据标准,任何正确的程序在给定一组宽松约束的情况下也是正确的。依赖于这种特定于实现的行为会导致不可移植的代码,并且违反标准。

有许多正当理由要求不相交的发送段。立即可见的是MPI_Gatherv的对称性。对于后者,段必须是不相交的,否则收集后的内存内容将取决于底层接收操作的顺序。由于在典型的MPI程序中,散布通常由道集镜像,因此如果相同的约束同时适用于聚集和散布,则可以重用计算的偏移和计数阵列。一个不太明显的原因是,在某些体系结构中,网络设备可能不允许从重叠的内存区域同时读取。

由于非标准MPI行为很容易在开发过程中蔓延到程序代码中,因此可能需要使用像MUST这样的工具来检查程序的正确性。