向量的向量的 OpenMP 并行实例化和修改
OpenMP parallel instantiation and modification of vector of vectors
我正在使用 OpenMP 在 Boost::geometry 多边形 (BPolygon
) 上并行化一些联合操作。
然而,我遇到了非常奇怪的异常,这些异常只是不时发生(尽管我的 RNG 使用相同的种子播种)所以我想知道我是否忽略了 OpenMP 并行化和容器的一些未定义行为......
该代码是一个庞大且相当复杂的整体的一部分,因此我无法真正提供 MWE,但相关部分如下:
std::unordered_map<size_t, std::vector<std::vector<BPolygon>>> container;
#pragma omp parallel
{
std::vector<BPolygon> vec_geom;
#pragma omp for
for (size_t gid : gids)
{
[...]
auto iter_block, iter_block_end;
container[gid] = std::vector<std::vector<BPolygon>>();
while (iter_block != iter_block_end)
{
auto iter_node = neurite_it->second->nodes_cbegin();
auto iter_node_end = neurite_it->second->nodes_cend();
// store the union in vec_geom
vec_geom.clear();
while (iter_node != iter_node_end)
{
cascading_union(node_it->second, vec_geom);
iter_node++;
}
// add the union to the container
container[gid].push_back(vec_geom);
iter_block++;
}
}
}
级联联合函数
void cascading_union(TNodePtr n, std::vector<BPolygon> &vec_geom)
{
auto range = n->segment_range();
auto seg_it = range.begin();
auto seg_end = range.end();
std::vector<BPolygon> vec, vec_tmp;
BPolygon poly1, poly2;
// container associated to `range` cannot be modified so
// we store the first unions in a new vector
while (seg_it != seg_end)
{
poly1 = *((*seg_it).get());
seg_it++;
if (seg_it != seg_end)
{
poly2 = *((*seg_it).get());
bg::union_(poly1, poly2, vec_tmp);
vec.push_back(vec_tmp[0]);
vec_tmp.clear();
}
else
{
vec.push_back(poly1);
}
}
stype imax(vec.size()), imax2;
// cascading union on final vector
while (imax > 1)
{
imax2 = 0;
for (stype i=0; i < imax; i += 2)
{
poly1 = vec[i];
if (i + 1 < imax)
{
poly2 = vec[i + 1];
bg::union_(poly1, poly2, vec_tmp);
vec[imax2] = vec_tmp[0];
vec_tmp.clear();
}
else
{
vec[imax2] = poly1;
}
imax2++;
}
vec.resize(imax2);
imax = imax2;
}
if (imax > 0)
{
vec_geom.push_back(vec.back());
}
}
遇到的错误类型是:
- 在代码的第一部分:
- 分配
container[gid] = std::vector<std::vector<BPolygon>>();
的段错误
munmap_chunk(): invalid pointer
(具体位置未知)
- 在
cascading_union
中:
bg::union_
中的段错误
free(): invalid next size (fast)
(具体位置未知)
malloc(): unaligned tcache chunk detected
(具体位置未知)
如果完整的回溯有用,请告诉我。
我想知道,虽然容器应该是线程安全的,但我在这里处理容器内的可变大小对象是否可能是一个问题。
注意:这些错误源于最近的重组,所以我认为多边形或底层结构没有问题,因为以前的实现中没有错误。
感谢评论,我意识到我关于容器是线程安全的想法是错误的(它们可以安全阅读但不能修改)。
对 push_back
的赋值和调用必须包含在
中
#pragma omp critical
我正在使用 OpenMP 在 Boost::geometry 多边形 (BPolygon
) 上并行化一些联合操作。
然而,我遇到了非常奇怪的异常,这些异常只是不时发生(尽管我的 RNG 使用相同的种子播种)所以我想知道我是否忽略了 OpenMP 并行化和容器的一些未定义行为......
该代码是一个庞大且相当复杂的整体的一部分,因此我无法真正提供 MWE,但相关部分如下:
std::unordered_map<size_t, std::vector<std::vector<BPolygon>>> container;
#pragma omp parallel
{
std::vector<BPolygon> vec_geom;
#pragma omp for
for (size_t gid : gids)
{
[...]
auto iter_block, iter_block_end;
container[gid] = std::vector<std::vector<BPolygon>>();
while (iter_block != iter_block_end)
{
auto iter_node = neurite_it->second->nodes_cbegin();
auto iter_node_end = neurite_it->second->nodes_cend();
// store the union in vec_geom
vec_geom.clear();
while (iter_node != iter_node_end)
{
cascading_union(node_it->second, vec_geom);
iter_node++;
}
// add the union to the container
container[gid].push_back(vec_geom);
iter_block++;
}
}
}
级联联合函数
void cascading_union(TNodePtr n, std::vector<BPolygon> &vec_geom)
{
auto range = n->segment_range();
auto seg_it = range.begin();
auto seg_end = range.end();
std::vector<BPolygon> vec, vec_tmp;
BPolygon poly1, poly2;
// container associated to `range` cannot be modified so
// we store the first unions in a new vector
while (seg_it != seg_end)
{
poly1 = *((*seg_it).get());
seg_it++;
if (seg_it != seg_end)
{
poly2 = *((*seg_it).get());
bg::union_(poly1, poly2, vec_tmp);
vec.push_back(vec_tmp[0]);
vec_tmp.clear();
}
else
{
vec.push_back(poly1);
}
}
stype imax(vec.size()), imax2;
// cascading union on final vector
while (imax > 1)
{
imax2 = 0;
for (stype i=0; i < imax; i += 2)
{
poly1 = vec[i];
if (i + 1 < imax)
{
poly2 = vec[i + 1];
bg::union_(poly1, poly2, vec_tmp);
vec[imax2] = vec_tmp[0];
vec_tmp.clear();
}
else
{
vec[imax2] = poly1;
}
imax2++;
}
vec.resize(imax2);
imax = imax2;
}
if (imax > 0)
{
vec_geom.push_back(vec.back());
}
}
遇到的错误类型是:
- 在代码的第一部分:
- 分配
container[gid] = std::vector<std::vector<BPolygon>>();
的段错误
munmap_chunk(): invalid pointer
(具体位置未知)
- 分配
- 在
cascading_union
中:
bg::union_
中的段错误
free(): invalid next size (fast)
(具体位置未知)malloc(): unaligned tcache chunk detected
(具体位置未知)
如果完整的回溯有用,请告诉我。
我想知道,虽然容器应该是线程安全的,但我在这里处理容器内的可变大小对象是否可能是一个问题。
注意:这些错误源于最近的重组,所以我认为多边形或底层结构没有问题,因为以前的实现中没有错误。
感谢评论,我意识到我关于容器是线程安全的想法是错误的(它们可以安全阅读但不能修改)。
对 push_back
的赋值和调用必须包含在
#pragma omp critical