I am trying to parallelize a modified BFS but it’s segfaulting. My idea is that it is segafaulting due to the else if section as some threads might be unwantedly accessing it. I cannot figure out any other way to fix it. Can someone suggest any changes?
This is the source for original BFS:
https://p.ip.fi/LTLr
This is another reference:
https://github.com/cmu15418/assignment3/blob/master/bfs/bfs.cpp
void make_bfs_step(int u, int n, vector<int> &frontier, vector<int> &new_frontier, vector<int> &distances, vvi &backedge, vvi &adj, vvi &tree)
{
// vector<int> frontier, new_frontier;
int local_count = 0;
int count = frontier.size();
#pragma omp parallel num_threads(NUM_THREADS)
// shared(new_frontier, par, vis, tree, frontier)
{
vector<int> local_frontier;
int id = omp_get_thread_num();
int nthrds = omp_get_num_threads();
for (int i = id; i < frontier.size(); i += nthrds)
{
int node = frontier[i];
// std::cout << id << " here " << node << endl;
for (auto v : adj[node])
{
// cout << v << " " << distances[v] << endl;
if (__sync_bool_compare_and_swap(&distances[v], NOT_VISITED_MARKER, distances[node] + 1))
{
vis[v] = 1;
par[v] = node;
tree[node].push_back(v);
local_frontier.push_back(v);
}
else if (par[node] != v)
backedge[node].push_back(v);
}
}
#pragma omp critical
{
new_frontier.insert(new_frontier.end(), local_frontier.begin(), local_frontier.end());
}
}
// cout << "n" << endl;
}
int make_tree_bfs_par(int u, vvi &backedge, vvi &adj, vvi &tree)
{
vector<int> frontier, new_frontier, distances(n);
for (int i = 0; i < n; i++)
distances[i] = NOT_VISITED_MARKER;
frontier.push_back(u);
// set the root distance with 0
distances[u] = 0;
// just like pop the queue
while (frontier.size() != 0)
{
new_frontier.clear();
make_bfs_step(u, n, frontier, new_frontier, distances, backedge, adj, tree);
swap(frontier, new_frontier);
}
return n;
}