#ifdef WITH_TBB #include #include #include "common.h" #include "decl.h" /* *** */ /* TBB */ auto tbbElsInner(tsp::Solution const& solution, RNG& rng, std::size_t nCore) { tsp::Solution best; std::vector solutions(ELS_GEN); /* repeatability at loop level */ std::vector rngs(ELS_GEN); for(std::size_t i = 0; i < ELS_GEN; ++i) rngs[i].seed(rng()); /* ***** */ using ElsGenP = std::tuple; using ElsGenR = std::tuple; tbb::flow::graph g; tbb::flow::function_node fElsGen(g, nCore, [](ElsGenP t) { return std::make_tuple(hwElsGen(*std::get<0>(t), *std::get<1>(t)), std::get<2>(t)); } ); tbb::flow::function_node fSelectMin(g, nCore, [](ElsGenR t) { *std::get<1>(t) = (selectMin(std::get<0>(t), *std::get<1>(t))); return true; } ); tbb::flow::make_edge(fElsGen, fSelectMin); if(ELS_GEN) solutions[0] = hwElsGen(solution, rngs[0]); for(std::size_t i = 1; i < ELS_GEN; ++i) fElsGen.try_put(std::make_tuple(&solution, &rngs[i], &solutions[i])); g.wait_for_all(); best = *std::min_element(std::begin(solutions), std::end(solutions)); return best; } auto tbbEls(tsp::Solution const& solution, RNG& rng,std::size_t nCore) { tsp::Solution best = Descent{}(solution); for(std::size_t i = 0; i < ELS_ITER_MAX; ++i) { tsp::Solution current = tbbElsInner(best, rng, nCore); best = selectMin(std::move(best), std::move(current)); } return best; } auto tbbGraspGen(tsp::Problem const& problem, RNG& rng, std::size_t nCore) { return tbbEls(rgreedy()(problem, rng), rng, nCore); } template tsp::Solution tbbGraspElsPar(tsp::Problem const& problem, RNG& rng) { tsp::Solution best; std::vector solutions(GRASP_N); tbb::task_scheduler_init init(K); /* repeatability at loop level */ std::vector rngs(GRASP_N); for(std::size_t i = 0; i < GRASP_N; ++i) rngs[i].seed(rng()); /* ***** */ using GraspGenP = std::tuple; using GraspGenR = std::tuple; tbb::flow::graph g; tbb::flow::function_node fGraspGen(g, K, [](GraspGenP t) { return std::make_tuple(tbbGraspGen(*std::get<0>(t), *std::get<1>(t), std::get<2>(t)), std::get<3>(t)); } ); tbb::flow::function_node fSelectMin(g, K, [](GraspGenR t) { *std::get<1>(t) = (selectMin(std::get<0>(t), *std::get<1>(t))); return true; } ); tbb::flow::make_edge(fGraspGen, fSelectMin); for(std::size_t i = 0; i < GRASP_N; ++i) fGraspGen.try_put(std::make_tuple(&problem, &rngs[i], K, &solutions[i])); g.wait_for_all(); /* Selection */ best = *std::min_element(std::begin(solutions), std::end(solutions)); return best; } tsp::Solution tbb_par(tsp::Problem const& p, RNG& rng, Arguments const&) { return tbbGraspElsPar(p, rng); } #else #include "common.h" tsp::Solution tbb_par(tsp::Problem const&, RNG&, Arguments const&) { std::clog << "must compile with -ltbb -DWITH_TBB to enable TBB\n"; return {}; } #endif