簡體   English   中英

Boost圖形庫:在並行模式下從adjacency_list讀取時訪問沖突

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

我在以並行方式從boost adjacency_list訪問邊緣屬性時遇到麻煩。 我在C ++代碼中使用boost 1.54.0和OpenMP。 我的問題歸結為以下沙箱示例:

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

運行此代碼(並行模式,4個線程)時,在第(*)行讀取時遇到訪問沖突。 盡管這是只讀訪問,但似乎無法同時從不同線程訪問邊緣的屬性。 在這個問題上的任何幫助將不勝感激。 非常感謝你!

這是完整的錯誤消息(德語); 它顯示為:“在位置讀取時發生異常(第一次機會)...在位置讀取時發生訪問沖突...在...處發生未處理的異常”

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.

可能還有其他使您絆倒的內容,在代碼段中看不到。 我能夠使它與boost graph和openMP一起運行

更新:我更改為代碼,以明確顯示外部循環的每次迭代的獨立工作,並且在每個循環中僅訪問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;
}

以此編譯: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

匯出OPM_NUM_THREADS

export OMP_NUM_THREADS=4

輸出看起來像:

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

在這里,我們看到每個線程都執行for迭代的一部分。 連接線程后,只有一個執行線程。 您可能需要發布其余代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM