简体   繁体   English

Boost图形库:在并行模式下从adjacency_list读取时访问冲突

[英]boost graph library: access violation in reading from adjacency_list in parallel mode

I am having trouble with accessing edge properties from a boost adjacency_list in parallel mode. 我在以并行方式从boost adjacency_list访问边缘属性时遇到麻烦。 I am using boost 1.54.0 and OpenMP within C++ code. 我在C ++代码中使用boost 1.54.0和OpenMP。 My problem boils down to the following sandbox example: 我的问题归结为以下沙箱示例:

#include <boost/graph/adjacency_list.hpp>

struct Knoten {int Knoten_Property};
struct Pfeil {int Pfeil_Property};
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, Knoten, Pfeil> Graph;
typedef boost::graph_traits<Graph>::edge_descriptor Edge;
typedef boost::graph_traits<Graph>::edge_iterator Edge_iter;

Graph G;

// […] 
// some initializations for the graph. 
// Test graph contains about  20,000 edges

#pragma omp parallel num_threads(4) 
{
    #pragma omp for private(i) 
    for(int i = 0; i < 100; i++) 
    {
        for(pair<Edge_iter, Edge_iter> ei = edges(G); ei.first != ei.second; ++ei.first)
        {
            for (int i = 0; i < 100000; ++i)
            {
                Edge E = *ei.first;
                int my_test = G[E].Pfeil_Property; // (*)
            }
        }
    }
}

When running this code (parallel mode, 4 threads), I obtain access violations in reading at line (*). 运行此代码(并行模式,4个线程)时,在第(*)行读取时遇到访问冲突。 It seems like I cannot access the property of an edge simultaneously from different threads, though this is a read-only access. 尽管这是只读访问,但似乎无法同时从不同线程访问边缘的属性。 Any help on this issue will be appreciated. 在这个问题上的任何帮助将不胜感激。 Thank you very much! 非常感谢你!

Here is the entire error message (in German); 这是完整的错误消息(德语); it reads: "Exception (first chance) at ... Access Violation when reading at position ... Unhandled exception at ..." 它显示为:“在位置读取时发生异常(第一次机会)...在位置读取时发生访问冲突...在...处发生未处理的异常”

Eine Ausnahme (erste Chance) bei 0x000000014042237f in MyApplication.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x000000000257ac58.
Unbehandelte Ausnahme bei 0x000000014042237f in MyApplication.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x000000000257ac58.

There must be something else that is tripping you up that isn't visible in the snippet. 可能还有其他使您绊倒的内容,在代码段中看不到。 I was able to get this to run with boost graph and openMP 我能够使它与boost graph和openMP一起运行

Update: I changed to code to explicitly show independent work on each iteration of the outer loop and to access cout only once in each loop. 更新:我更改为代码,以明确显示外部循环的每次迭代的独立工作,并且在每个循环中仅访问cout一次。

#include <omp.h>
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <vector>
#include <string>

using namespace std;

struct Knoten {int Knoten_Property;};
struct Pfeil {int Pfeil_Property;};
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, Knoten, Pfeil> Graph;
typedef boost::graph_traits<Graph>::edge_descriptor Edge;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
typedef boost::graph_traits<Graph>::edge_iterator Edge_iter;

string convertInt(int number)
{
   //http://www.cplusplus.com/forum/beginner/7777/
   stringstream ss;//create a stringstream
   ss << number;//add number to the stream
   return ss.str();//return a string with the contents of the stream
}


int main()
{
    Graph G;

    vector<Vertex> verts;

    //add 7 vertices
    for(size_t i = 0; i < 7; ++i){
        Vertex v = add_vertex(G);
        verts.push_back(v);
    }

    add_edge(verts.at(0),verts.at(1),G);
    add_edge(verts.at(0),verts.at(3),G);
    add_edge(verts.at(1),verts.at(2),G);
    add_edge(verts.at(1),verts.at(3),G);
    add_edge(verts.at(1),verts.at(4),G);
    add_edge(verts.at(2),verts.at(4),G);
    add_edge(verts.at(3),verts.at(4),G);
    add_edge(verts.at(3),verts.at(5),G);
    add_edge(verts.at(4),verts.at(5),G);
    add_edge(verts.at(4),verts.at(6),G);
    add_edge(verts.at(5),verts.at(6),G);

    #pragma omp parallel num_threads(4) 
    {
        #pragma omp for private(i) 
        for(int i = 0; i < 10; i++) 
        {
                int threadId = omp_get_thread_num();
        string greeting = "hello from ";
              greeting += convertInt(threadId);
        greeting += " on loop variable ";
        greeting += convertInt(i);
        greeting += " graph edges ";
        greeting += convertInt(num_edges(G));
        greeting += "\n";
        cout << greeting;
        //cout << "edges " << num_edges(G) << endl;
                for(pair<Edge_iter, Edge_iter> ei = edges(G); ei.first != ei.second; ++ei.first)
                {
                    for (int i = 0; i < 10; ++i)
                    {
                     Edge E = *ei.first;
                     int my_test = G[E].Pfeil_Property; // (*)

                  }
              }
          }
    }

    cout << "after join " << num_edges(G) << endl;
    cout << "after join " << num_vertices(G) << endl;

    return 0;
}

Compile with this: BOOST_INC is the root to boost, /usr/lib/gcc ... is the location of omp.h 以此编译:BOOST_INC是要增强的根,/ usr / lib / gcc ...是omp.h的位置

g++ -O -fopenmp -I $BOOST_INC -I . -I /usr/lib/gcc/x86_64-redhat-linux/4.4.7/include/ -c -g  graphOmp.cpp
g++ -g graphOmp.o -o graphOmp -fopenmp

Exporting OPM_NUM_THREADS 汇出OPM_NUM_THREADS

export OMP_NUM_THREADS=4

output looks like: 输出看起来像:

hello from 3 on loop variable 9 graph edges 11
hello from 2 on loop variable 6 graph edges 11
hello from 0 on loop variable 0 graph edges 11
hello from 0 on loop variable 1 graph edges 11
hello from 0 on loop variable 2 graph edges 11
hello from 1 on loop variable 3 graph edges 11
hello from 1 on loop variable 4 graph edges 11
hello from 1 on loop variable 5 graph edges 11
hello from 2 on loop variable 7 graph edges 11
hello from 2 on loop variable 8 graph edges 11
after join 11
after join 7

Here we see that each thread does part of the for iteration. 在这里,我们看到每个线程都执行for迭代的一部分。 After the threads are joined there is only one thread of execution. 连接线程后,只有一个执行线程。 You may need to post the rest of the code. 您可能需要发布其余代码。

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

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