1d86ed7fbStbbdev /*
2*b15aabb3Stbbdev Copyright (c) 2005-2021 Intel Corporation
3d86ed7fbStbbdev
4d86ed7fbStbbdev Licensed under the Apache License, Version 2.0 (the "License");
5d86ed7fbStbbdev you may not use this file except in compliance with the License.
6d86ed7fbStbbdev You may obtain a copy of the License at
7d86ed7fbStbbdev
8d86ed7fbStbbdev http://www.apache.org/licenses/LICENSE-2.0
9d86ed7fbStbbdev
10d86ed7fbStbbdev Unless required by applicable law or agreed to in writing, software
11d86ed7fbStbbdev distributed under the License is distributed on an "AS IS" BASIS,
12d86ed7fbStbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d86ed7fbStbbdev See the License for the specific language governing permissions and
14d86ed7fbStbbdev limitations under the License.
15d86ed7fbStbbdev */
16d86ed7fbStbbdev
17d86ed7fbStbbdev /* Example program that shows how to use parallel_for_each to do parallel preorder
18d86ed7fbStbbdev traversal of a directed acyclic graph. */
19d86ed7fbStbbdev
20d86ed7fbStbbdev #include <cstdlib>
21d86ed7fbStbbdev
22d86ed7fbStbbdev #include <iostream>
23d86ed7fbStbbdev #include <vector>
24d86ed7fbStbbdev
25d86ed7fbStbbdev #include "oneapi/tbb/tick_count.h"
26d86ed7fbStbbdev #include "oneapi/tbb/global_control.h"
27d86ed7fbStbbdev #include "common/utility/utility.hpp"
28d86ed7fbStbbdev #include "common/utility/get_default_num_threads.hpp"
29d86ed7fbStbbdev
30d86ed7fbStbbdev #include "Graph.hpp"
31d86ed7fbStbbdev
32d86ed7fbStbbdev // some forward declarations
33d86ed7fbStbbdev class Cell;
34d86ed7fbStbbdev void ParallelPreorderTraversal(const std::vector<Cell*>& root_set);
35d86ed7fbStbbdev
36d86ed7fbStbbdev //------------------------------------------------------------------------
37d86ed7fbStbbdev // Test driver
38d86ed7fbStbbdev //------------------------------------------------------------------------
39d86ed7fbStbbdev static unsigned nodes = 1000;
40d86ed7fbStbbdev static unsigned traversals = 500;
41d86ed7fbStbbdev static bool SilentFlag = false;
42d86ed7fbStbbdev
43d86ed7fbStbbdev //! Parse the command line.
ParseCommandLine(int argc,char * argv[],utility::thread_number_range & threads)44d86ed7fbStbbdev static void ParseCommandLine(int argc, char* argv[], utility::thread_number_range& threads) {
45d86ed7fbStbbdev utility::parse_cli_arguments(
46d86ed7fbStbbdev argc,
47d86ed7fbStbbdev argv,
48d86ed7fbStbbdev utility::cli_argument_pack()
49d86ed7fbStbbdev //"-h" option for displaying help is present implicitly
50d86ed7fbStbbdev .positional_arg(threads, "n-of-threads", utility::thread_number_range_desc)
51d86ed7fbStbbdev .positional_arg(nodes, "n-of-nodes", "number of nodes in the graph.")
52d86ed7fbStbbdev .positional_arg(
53d86ed7fbStbbdev traversals,
54d86ed7fbStbbdev "n-of-traversals",
55d86ed7fbStbbdev "number of times to evaluate the graph. Reduce it (e.g. to 100) to shorten example run time\n")
56d86ed7fbStbbdev .arg(SilentFlag, "silent", "no output except elapsed time "));
57d86ed7fbStbbdev }
58d86ed7fbStbbdev
main(int argc,char * argv[])59d86ed7fbStbbdev int main(int argc, char* argv[]) {
60d86ed7fbStbbdev utility::thread_number_range threads(utility::get_default_num_threads);
61d86ed7fbStbbdev oneapi::tbb::tick_count main_start = oneapi::tbb::tick_count::now();
62d86ed7fbStbbdev ParseCommandLine(argc, argv, threads);
63d86ed7fbStbbdev
64d86ed7fbStbbdev // Start scheduler with given number of threads.
65d86ed7fbStbbdev for (int p = threads.first; p <= threads.last; p = threads.step(p)) {
66d86ed7fbStbbdev oneapi::tbb::tick_count t0 = oneapi::tbb::tick_count::now();
67d86ed7fbStbbdev oneapi::tbb::global_control c(oneapi::tbb::global_control::max_allowed_parallelism, p);
68d86ed7fbStbbdev srand(2);
69d86ed7fbStbbdev std::size_t root_set_size = 0;
70d86ed7fbStbbdev {
71d86ed7fbStbbdev Graph g;
72d86ed7fbStbbdev g.create_random_dag(nodes);
73d86ed7fbStbbdev std::vector<Cell*> root_set;
74d86ed7fbStbbdev g.get_root_set(root_set);
75d86ed7fbStbbdev root_set_size = root_set.size();
76d86ed7fbStbbdev for (unsigned int trial = 0; trial < traversals; ++trial) {
77d86ed7fbStbbdev ParallelPreorderTraversal(root_set);
78d86ed7fbStbbdev }
79d86ed7fbStbbdev }
80d86ed7fbStbbdev oneapi::tbb::tick_count::interval_t interval = oneapi::tbb::tick_count::now() - t0;
81d86ed7fbStbbdev if (!SilentFlag) {
82d86ed7fbStbbdev std::cout << interval.seconds() << " seconds using " << p << " threads ("
83d86ed7fbStbbdev << root_set_size << " nodes in root_set)\n";
84d86ed7fbStbbdev }
85d86ed7fbStbbdev }
86d86ed7fbStbbdev utility::report_elapsed_time((oneapi::tbb::tick_count::now() - main_start).seconds());
87d86ed7fbStbbdev
88d86ed7fbStbbdev return 0;
89d86ed7fbStbbdev }
90