简体   繁体   English

向量的向量的 OpenMP 并行实例化和修改

[英]OpenMP parallel instantiation and modification of vector of vectors

I'm using OpenMP to parallelize some union operation on Boost::geometry polygons ( BPolygon ).我正在使用 OpenMP 来并行化 Boost::geometry 多边形( BPolygon )上的一些联合操作。 However I am stumbling over very strange exceptions that only occur from time to time (despite my RNGs being seeded with the same seed) so I wonder whether I'm ignoring some undefined behaviors with OpenMP parallelization and containers...但是,我偶然发现了仅不时发生的非常奇怪的异常(尽管我的 RNG 被播种了相同的种子)所以我想知道我是否忽略了 OpenMP 并行化和容器的一些未定义行为......

The code is part of a large and rather complex ensemble so I cannot really provide a MWE but the relevant parts are as follow:该代码是一个大型且相当复杂的集合的一部分,因此我无法真正提供 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++;
        }
    }
}

with the cascading union function being级联联合 function 是

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());
    }
}

The type of errors that are encounter are:遇到的错误类型有:

  • in the first part of the code:在代码的第一部分:
    • a segfault at allocation of container[gid] = std::vector<std::vector<BPolygon>>();分配container[gid] = std::vector<std::vector<BPolygon>>();
    • munmap_chunk(): invalid pointer (precise location unknown) munmap_chunk(): invalid pointer (精确位置未知)
  • in cascading_union :cascading_union
  • an segfault in bg::union_ bg::union_中的段错误
  • free(): invalid next size (fast) (precise location unknown) free(): invalid next size (fast) (精确位置未知)
  • malloc(): unaligned tcache chunk detected (precise location unknown) malloc(): unaligned tcache chunk detected (精确位置未知)

Please let me know if full backtraces would be useful.请让我知道完整的回溯是否有用。

I am wondering whether, though containers are supposed to be thread-safe, it could be an issue with the fact that here I'm dealing with variable size objects inside the container.我想知道,尽管容器应该是线程安全的,但这可能是一个问题,因为我在这里处理的是容器内的可变大小对象。

Note: these errors stem from a recent restructuring, so I think that there is no issue with the polygons or underlying structures because the errors were absent from previous implementations.注意:这些错误源于最近的重组,所以我认为多边形或底层结构没有问题,因为以前的实现中没有这些错误。

Thank to the comments, I realized that my idea about containers being thread-safe was wrong (well they are safe to read but not to modify).感谢评论,我意识到我关于容器是线程安全的想法是错误的(它们可以安全阅读但不能修改)。

Assignments and call to push_back must be wrapped in分配和对push_back的调用必须包含在

#pragma omp critical

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM