使用 MPI 修改函数中的 boost 数组导致断言失败

Posted

技术标签:

【中文标题】使用 MPI 修改函数中的 boost 数组导致断言失败【英文标题】:Modifying boost array in function with MPI leads to assertion fail 【发布时间】:2021-05-09 23:59:21 【问题描述】:

我正在尝试修改函数中的 boost 数组。代码在串行中运行良好并产生预期的结果,而使用 MPI 我得到一个错误。这是一个最小的可重现示例:

#include <stdio.h>
#include <iostream>
#include "boost/multi_array.hpp"


static void myfunc(boost::multi_array<double, 3>& foo)
            std::cout<<foo[0][0][0]<<std::endl;
        

int main()
    typedef boost::multi_array<double, 3> array_type;
    typedef array_type::index index;
    array_type foo(boost::extents[1][1][1]);
    myfunc(foo);
  return 0;

我得到的错误是:

.../src/boost/boost/multi_array/base.hpp:135: Reference boost::detail::multi_array\
::value_accessor_n<T, NumDims>::access(boost::type<Reference>, boost::detail::multi_array::value_accessor_n<T, NumDims>::index, TPtr, const size_type\
*, const index*, const index*) const [with Reference = boost::detail::multi_array::sub_array<double, 2>; TPtr = double*; T = double; long unsigned in\
t NumDims = 3; boost::detail::multi_array::value_accessor_n<T, NumDims>::index = long int; boost::detail::multi_array::multi_array_base::size_type = \
long unsigned int]: Assertion `idx - index_bases[0] >= 0' failed.

root rank 打印出foo[0][0][0],但其他rank 没有,这就是错误发生的时候。我对这种行为的天真解释是其他等级不带有foo[0][0][0],因此我得到类似“索引超出范围错误”的东西。关于如何解决此问题的任何想法?

编辑:当我打印出提升数组的大小时,每个等级都会打印出(数组的初始大小)/(等级数)的大小。

【问题讨论】:

当您提到 MPI 时,是什么让您确定 boost::multi_array 应该以线程安全的方式处理(AFAIK 标准容器也不是这种情况)?我在他们的文档中找不到任何保证。但我可能完全错了,我自己从未与 MPI 合作过。 天真地我猜它们是线程安全的,从这里关于提升向量的第二个答案推断:***.com/questions/9042571/…。但我也可能是错的。无论如何,我仍然需要使用 MPI 修改 boost 数组,所以如果将它传递给另一个对象会在这个方向上安全地引导线程,我会全力以赴。 可能可以通过一个瘦模板包装器和 C++ 标准读/写锁来保护访问操作,以防它不是线程安全容器。 能否请您在一个可重现的最小示例中提供您的解决方案?谢谢你:) 在 Arch Linux 上使用 Open MPI 4.0.5 为我工作:$ mpic++ -o foo foo.cc &amp;&amp; mpiexec -n 4 ./foo 产生 0 四次。 foo.cc 是您的代码的复制粘贴。您的程序中没有任何与 MPI 相关的内容,因此所有等级都执行完全相同的指令。 【参考方案1】:

确实,问题在于并非所有等级都带有所有索引。特别是,如果rank总数为N_ranks,则每个单独的rank为rank,boost数组的维度为NxNxN,每个rank携带[rank * N / N_ranks:(rank + 1) * N / N_ranks, 0:N, 0:N]。因此,如果要访问foo 数组,则应该以一种依赖于秩数的方式对其进行索引。

【讨论】:

我不明白当boost::multi_array 不是分布式数组类型时会出现这种情况。我怀疑您没有向我们展示更多代码。正如我所说,您问题中的示例在我的计算机上具有四个等级时运行良好,如果您在此处写的内容属实,情况就不应该如此。此外,在 Boost 的文档中找不到任何关于分布式数组的内容。 很可能有一些我没有意识到的代码添加到最初的问题中,因此被省略了。您是否怀疑什么条件会导致这种行为?

以上是关于使用 MPI 修改函数中的 boost 数组导致断言失败的主要内容,如果未能解决你的问题,请参考以下文章

boost mpi 集合操作中的操作类型

Boost MPI 在侦听列表时不释放资源?

MPI通信器的范围

我可以告诉 Boost.MPI 哪个类版本与 Boost.Serialization 一起使用吗?

如何释放 boost::mpi::request?

boost::mpi 作为模板类的静态成员