Home > Enterprise >  Pass a template to an async function
Pass a template to an async function

Time:11-19

I'm trying to run an async function passing to it a function f to execute and a template function f0 as attribute.

This is the function that I create through a template

DivideVerticesInThreads<0> f0(g, {}, {});

The template is

template <int NSegments, int Segment> struct SegmentVertices {
std::hash<Graph::vertex_descriptor> _h;
bool operator()(Graph::vertex_descriptor vd) const { return (_h(vd) % NSegments) == Segment; }
};

template <int N>
using DivideVerticesInThreads = boost::filtered_graph<Graph, boost::keep_all, SegmentVertices<4, N>>;

Then I call the async function in this way

auto handle = async(std::launch::async,f, f0);

And I pass to it the function f:

auto f = [&](G const& f0) {

    for(vp = vertices(f0); vp.first != vp.second;   vp.first){
        //...
    }
};

The complete piece of code is:

template<typename G>
void parallel_count_adj_luby(G g){


    property_map<Graph,vertex_degree_t>::type deg = get(vertex_degree, g);


    auto f = [&](G const& g1) {

        for(vp = vertices(g1); vp.first != vp.second;   vp.first){
            // ...
        }
    };

    DivideVerticesInThreads<0> f0(g, {}, {});

    auto handle = async(std::launch::async,f, f0);

}

The problem is that the async function gives me this error

error: no matching function for call to 'async(std::launch, parallel_count_adj_luby(G) [with G = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, boost::property<boost::vertex_color_t, int, boost::property<boost::vertex_degree_t, int> > >]::<lambda(const boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, boost::property<boost::vertex_color_t, int, boost::property<boost::vertex_degree_t, int> > >&)>&, DivideVerticesInThreads<0>&)'
         auto handle = async(std::launch::async,f, f0);

I don't know well c and future, so the error may be something dummy. What I did wrong?

CodePudding user response:

I agree somewhat with the commenters, that the problem exposition is needlessly unclear

However, I think I know what's happening is due to a choice I made when presenting this sample code to you in an earlier answer.

It appears I focused on efficiency and it landed you with c challenges you didn't know how to handle.

I'm just going to ignore the confusion and remove the static type parameters with runtime parameters. That way your filtered graph segments can all have the same static type

Live On Compiler Explorer

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/random.hpp>
#include <iostream>
#include <random>

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

using G = boost::adjacency_list<>;
using V = G::vertex_descriptor;

struct SegmentVertices {
    unsigned nsegments, segment;

    bool operator()(V vd) const {
        return (std::hash<V>{}(vd) % nsegments) == segment;
    }
};

using F = boost::filtered_graph<G, boost::keep_all, SegmentVertices>;

G make_graph() {
    G g;
    generate_random_graph(g, 32 * 1024 - (s_prng() % 37), 64 * 1024, s_prng);
    return g;
}

void the_function(G const& g)
{
    std::cout << "Full graph " << size(boost::make_iterator_range(vertices(g)))
              << " vertices\n";
}

void the_function(F const& f)
{
    auto& pred = f.m_vertex_pred;

    std::cout << pred.segment << "/" << pred.nsegments << " "
              << size(boost::make_iterator_range(vertices(f))) << " vertices\n";
}

int main()
{
    G g = make_graph();
    the_function(g);

    unsigned NSegments = s_prng() % 10   2;

    for (unsigned seg = 0; seg < NSegments;   seg) {
        the_function(F(g, {}, {seg, NSegments}));
    }
}

Prints e.g.

Full graph 32736 vertices
0/3 10912 vertices
1/3 10912 vertices
2/3 10912 vertices

Or

Full graph 32741 vertices
0/7 4678 vertices
1/7 4678 vertices
2/7 4677 vertices
3/7 4677 vertices
4/7 4677 vertices
5/7 4677 vertices
6/7 4677 vertices

As you can see, using runtime filter parameters trades performance for runtime flexibility and type convenience.


¹ E.g. even the first claim "This is the function that I create through a template" makes no sense, because what follows is not a function and no template is being used to create it either.

  • Related