[英]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.