【问题标题】:Program succeeds using OpenMPI but fails in call to MPI_Allreduce when using MPICH 3.2.1程序使用 OpenMPI 成功,但在使用 MPICH 3.2.1 时调用 MPI_Allreduce 失败
【发布时间】:2019-07-01 01:17:12
【问题描述】:

我有一个程序在使用 OpenMPI 库编译时可以正常运行,但在使用 MPICH 3.2.1 编译时失败并出现 MPI_Allreduce() 错误。这在 Linux 和 MacOS 上都会发生。

相关代码是

typedef struct reduction_packet {
  double sig;               /* logev */
  double s_width;           /* starting width */
  double s_nsites;          /* starting nsites */
  double width;             // width of motif
  double nsites_dis;            // final number of sites
  double llr;               // LLR of motif
  double classic;           // true if Classic objective function
  double ID; /* Use a double so the MPI type handle is simple. */
} REDUCE_PACKET;

REDUCE_PACKET a_packet, best_packet;
...
MPI_Allreduce((void *)&a_packet, (void *)&best_packet, 1,
   reduction_packet_type, max_packets_op, MPI_COMM_WORLD);

MPI 堆栈上的根错误是

MPIR_Localcopy(100)......: memcpy arguments alias each other, dst=0x7ffeeadd2f80 src=0x7ffeeadd2fc0 len=72

我的解释是 MPICH MPI 告诉我变量 a_packet 和 best_packet 重叠,因为要复制的变量的长度是 72 个字节,但是这两个变量仅偏移了 64 个字节。

每个缓冲区实际上是一个由 8 个双精度组成的结构,占 64 个字节。我可以想象可能有一些填充来处理对齐,但是编译器似乎很乐​​意在堆栈上分配这两个变量而没有填充。我记录了a_packetbest_packet 的地址,它们与MPIR_Localcopy() 的错误消息中报告的地址相匹配。

如果我将两个变量的声明更改为

REDUCE_PACKET a_packet;
char foo[2];
REDUCE_PACKET best_packet;

程序在 MPICH 和 OpenMPI 上运行没有错误。

为什么 MPICH 认为这个变量需要 72 个字节而不是 64 个字节?我是否遗漏了 MPI/MPICH 文档中的某些内容,告诉我我负责这种手动填充?

【问题讨论】:

  • minimal reproducible example 需要进行更多调查。
  • 同时,您可以打印MPI_Type_get_true_extent(reduction_packet_type, ...)并比较Open MPI和MPICH的输出
  • @GillesGouaillardet 感谢建议检查 MPI_Type_get_true_extent() 是调试此问题的关键。

标签: mpi


【解决方案1】:

如果遇到此类错误,请仔细检查作为第三个参数传递给 MPI_Allreduce() 的 MPI_datatype 的定义:

MPI_Allreduce((void *)&a_packet, (void *)&best_packet, 1,
   reduction_packet_type, max_packets_op, MPI_COMM_WORLD);

事实证明,我们更改了底层 C 数据类型 REDUCE_PACKET 的定义,但没有更新对 MPI_Type_contiguous() 的调用,从而确定了 MPI_datatypereduction_packet_type 的大小。

显然 MPICH 比 OpenMPI 更关注潜在的重叠内存副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 2016-09-19
    相关资源
    最近更新 更多