使用 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 && mpiexec -n 4 ./foo
产生 0
四次。 foo.cc
是您的代码的复制粘贴。您的程序中没有任何与 MPI 相关的内容,因此所有等级都执行完全相同的指令。
【参考方案1】:
确实,问题在于并非所有等级都带有所有索引。特别是,如果rank总数为N_ranks
,则每个单独的rank为rank
,boost数组的维度为N
xN
xN
,每个rank携带[rank * N / N_ranks:(rank + 1) * N / N_ranks, 0:N, 0:N]
。因此,如果要访问foo
数组,则应该以一种依赖于秩数的方式对其进行索引。
【讨论】:
我不明白当boost::multi_array
不是分布式数组类型时会出现这种情况。我怀疑您没有向我们展示更多代码。正如我所说,您问题中的示例在我的计算机上具有四个等级时运行良好,如果您在此处写的内容属实,情况就不应该如此。此外,在 Boost 的文档中找不到任何关于分布式数组的内容。
很可能有一些我没有意识到的代码添加到最初的问题中,因此被省略了。您是否怀疑什么条件会导致这种行为?以上是关于使用 MPI 修改函数中的 boost 数组导致断言失败的主要内容,如果未能解决你的问题,请参考以下文章