【发布时间】: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 合作过。 -
天真地我猜它们是线程安全的,从这里关于提升向量的第二个答案推断:stackoverflow.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 相关的内容,因此所有等级都执行完全相同的指令。