Random access to vertices using Boost :: graph

I am trying to iterate over my vertices of an acceleration graph in parallel using OpenMP. This seems to require an iterator that supports random access to the elements (such as itr[i]

getting the i

th element ). However, the iterator that vertices(g)

returns (a vertex_iterator

) doesn't seem to support this. Is there an efficient, clean way to achieve this? Ideally, I want a standard for the loop, for example:

for (int i = 0; i < num_vertices; i++) {
  vertex v = itr[i];
  // Compute on vertex
}

      

which will collaborate with OpenMP. Thank!

+3


source to share


1 answer


Using adjacency_list<..., vecS, ...>

or adjacency_matrix

would allow this to be done with integral type vertex descriptors.

Thinking a little out of the box, have a look at the Parallel Boost Graph Library (Parallel BGL). It is very likely that it does what you want (and more), but better?

Tiny Demo

Live On Coliru



Sample output (on my system):

Generated 50000000 vertices in 1879ms
Using 8 threads.
Sum of volumes for 50000000 vertices in 94ms: 2.5603e+10

      

Full list:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/random.hpp>
#include <chrono>
#include <iostream>
#include <omp.h>
#include <random>

static std::mt19937 prng { std::random_device{}() };

struct MyVertex {
    uintmax_t volume = [] { static std::uniform_int_distribution<int> pick(0, 1024); return pick(prng); }();
};

using namespace boost;
using G = adjacency_list<vecS, vecS, directedS, MyVertex>;

G generate() {
    using namespace std::chrono;
    auto start = high_resolution_clock::now();

    G g;
    generate_random_graph(g, 50000000, 0, prng);

    auto end = high_resolution_clock::now();
    std::cerr << "Generated " << num_vertices(g) << " vertices " << "in " << duration_cast<milliseconds>(end-start).count() << "ms\n";

    return g;
}

int main() {

    auto const g = generate();

    using namespace std::chrono;
    auto start = high_resolution_clock::now();
    double sum = 0;
#pragma omp parallel
    {
#pragma omp single
        std::cerr << "Using " << omp_get_num_threads() << " threads.\n";

#pragma omp for reduction(+:sum)
        for (G::vertex_descriptor u = 0; u < num_vertices(g); ++u) {
            sum += g[vertex(u, g)].volume;
        }
    }

    auto end = high_resolution_clock::now();
    std::cerr << "Sum of volumes for " << num_vertices(g)                                << " vertices "
              << "in "                 << duration_cast<milliseconds>(end-start).count() << "ms: " << sum << "\n";
}

      

+4


source







All Articles