将模板传递给异步函数
Pass a template to an async function
我正在尝试 运行 一个异步函数传递给它一个要执行的函数 f 和一个模板函数 f0 作为属性。
这是我通过模板创建的函数
DivideVerticesInThreads<0> f0(g, {}, {});
模板是
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>>;
然后我这样调用async函数
auto handle = async(std::launch::async,f, f0);
然后我将函数 f:
传递给它
auto f = [&](G const& f0) {
for(vp = vertices(f0); vp.first != vp.second; ++vp.first){
//...
}
};
完整的代码为:
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);
}
问题是异步函数给我这个错误
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);
我不太了解c++和未来,所以错误可能是一些虚拟的。我做错了什么?
我有点同意评论者的观点,.¹
但是,我想我知道发生了什么是由于我在 时做出的选择。
看来我专注于效率,它让您遇到了您不知道如何处理的 C++ 挑战。
我只是要忽略混淆并删除带有运行时参数的静态类型参数。这样你过滤的图段都可以有相同的静态类型
#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}));
}
}
打印例如
Full graph 32736 vertices
0/3 10912 vertices
1/3 10912 vertices
2/3 10912 vertices
或
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
如您所见,使用运行时过滤器参数以性能换取运行时灵活性和类型便利性。
¹ 例如即使是第一个声明“这是我通过模板创建的函数”也是没有意义的,因为接下来的不是函数,也没有模板被用来创建它。
我正在尝试 运行 一个异步函数传递给它一个要执行的函数 f 和一个模板函数 f0 作为属性。
这是我通过模板创建的函数
DivideVerticesInThreads<0> f0(g, {}, {});
模板是
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>>;
然后我这样调用async函数
auto handle = async(std::launch::async,f, f0);
然后我将函数 f:
传递给它auto f = [&](G const& f0) {
for(vp = vertices(f0); vp.first != vp.second; ++vp.first){
//...
}
};
完整的代码为:
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);
}
问题是异步函数给我这个错误
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);
我不太了解c++和未来,所以错误可能是一些虚拟的。我做错了什么?
我有点同意评论者的观点,
但是,我想我知道发生了什么是由于我在
看来我专注于效率,它让您遇到了您不知道如何处理的 C++ 挑战。
我只是要忽略混淆并删除带有运行时参数的静态类型参数。这样你过滤的图段都可以有相同的静态类型
#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}));
}
}
打印例如
Full graph 32736 vertices
0/3 10912 vertices
1/3 10912 vertices
2/3 10912 vertices
或
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
如您所见,使用运行时过滤器参数以性能换取运行时灵活性和类型便利性。
¹ 例如即使是第一个声明“这是我通过模板创建的函数”也是没有意义的,因为接下来的不是函数,也没有模板被用来创建它。