#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include #include // -------------------------------------------------------- // Graph generation // -------------------------------------------------------- struct Node { std::string name; size_t idx {0}; size_t level {0}; bool visited {false}; std::atomic dependents {0}; std::vector successors; void precede(Node& n) { successors.emplace_back(&n); n.dependents ++; } }; std::unique_ptr make_dag(size_t num_nodes, size_t max_degree) { std::unique_ptr nodes(new Node[num_nodes]); // Make sure nodes are in clean state for(size_t i=0; i make_chain(size_t num_nodes) { std::unique_ptr nodes(new Node[num_nodes]); // Make sure nodes are in clean state for(size_t i=0; i level(0); std::vector tasks; for(size_t i=0; ilevel = ++level; v->visited = true; for(size_t j=0; jsuccessors.size(); ++j) { v->successors[j]->dependents.fetch_sub(1); } }).name(nodes[i].name); tasks.push_back(task); } for(size_t i=0; iidx]); } } executor.run(tf).wait(); // block until finished for(size_t i=0; ilevel); } } } } // -------------------------------------------------------- // Testcase: DynamicTraversal // -------------------------------------------------------- TEST_CASE("DynamicTraversal" * doctest::timeout(300)) { std::atomic level; std::function traverse; traverse = [&] (Node* n, tf::Subflow& subflow) { REQUIRE(!n->visited); n->visited = true; size_t S = n->successors.size(); for(size_t i=0; isuccessors[i]->dependents.fetch_sub(1) == 1) { n->successors[i]->level = ++level; subflow.emplace([s=n->successors[i], &traverse](tf::Subflow &subflow2){ traverse(s, subflow2); }); } } }; size_t max_degree = 4; size_t num_nodes = 1000; for(unsigned w=1; w<=4; w++) { auto nodes = make_dag(num_nodes, max_degree); std::vector src; for(size_t i=0; ilevel); } } } } // -------------------------------------------------------- // Testcase: RecursiveTraversal // -------------------------------------------------------- //TEST_CASE("RecursiveTraversal" * doctest::timeout(300)) { // // std::atomic level; // // std::function traverse; // // traverse = [&] (Node* n, tf::Subflow& subflow) { // REQUIRE(!n->visited); // n->visited = true; // size_t S = n->successors.size(); // for(size_t i=0; isuccessors[i]->dependents.fetch_sub(1) == 1) { // n->successors[i]->level = ++level; // subflow.emplace([s=n->successors[i], &traverse](tf::Subflow &subflow){ // traverse(s, subflow); // }); // } // } // }; // // size_t num_nodes = 1000; // // for(unsigned w=1; w<=4; w++) { // // auto nodes = make_chain(num_nodes); // // std::vector src; // for(size_t i=0; ilevel); // } // } // } //} // -------------------------------------------------------- // Testcase: ParallelTraversal // -------------------------------------------------------- /*void parallel_traversal(unsigned num_threads) { tf::Executor executor(num_threads); std::vector threads; for(unsigned t=0; t level {0}; size_t max_degree = 4; size_t num_nodes = 1000; auto nodes = make_dag(num_nodes, max_degree); std::vector src; for(size_t i=0; i traverse; traverse = [&] (Node* n, tf::Subflow& subflow) { REQUIRE(!n->visited); n->visited = true; size_t S = n->successors.size(); for(size_t i=0; isuccessors[i]->dependents.fetch_sub(1) == 1) { n->successors[i]->level = ++level; subflow.emplace([s=n->successors[i], &traverse](tf::Subflow &subflow){ traverse(s, subflow); }); } } }; tf::Taskflow tf; for(size_t i=0; ilevel); } } }); } for(auto& thread : threads) thread.join(); } TEST_CASE("ParallelTraversal.1" * doctest::timeout(300)) { parallel_traversal(1); } TEST_CASE("ParallelTraversal.2" * doctest::timeout(300)) { parallel_traversal(2); } TEST_CASE("ParallelTraversal.3" * doctest::timeout(300)) { parallel_traversal(3); } TEST_CASE("ParallelTraversal.4" * doctest::timeout(300)) { parallel_traversal(4); } TEST_CASE("ParallelTraversal.5" * doctest::timeout(300)) { parallel_traversal(5); } TEST_CASE("ParallelTraversal.6" * doctest::timeout(300)) { parallel_traversal(6); } TEST_CASE("ParallelTraversal.7" * doctest::timeout(300)) { parallel_traversal(7); } TEST_CASE("ParallelTraversal.8" * doctest::timeout(300)) { parallel_traversal(8); } */