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 #include <cstdlib>
18d86ed7fbStbbdev #include <cstdio>
19d86ed7fbStbbdev #include <cstring>
20d86ed7fbStbbdev #include <cctype>
21d86ed7fbStbbdev
22d86ed7fbStbbdev #include <utility>
23d86ed7fbStbbdev #include <iostream>
24d86ed7fbStbbdev #include <sstream>
25d86ed7fbStbbdev
26d86ed7fbStbbdev #include "oneapi/tbb/tick_count.h"
27d86ed7fbStbbdev
28d86ed7fbStbbdev #include "common/utility/utility.hpp"
29d86ed7fbStbbdev
30d86ed7fbStbbdev #include "primes.hpp"
31d86ed7fbStbbdev
32d86ed7fbStbbdev struct RunOptions {
33d86ed7fbStbbdev //! NumberType of threads to use.
34d86ed7fbStbbdev utility::thread_number_range threads;
35d86ed7fbStbbdev //whether to suppress additional output
36d86ed7fbStbbdev bool silentFlag;
37d86ed7fbStbbdev //
38d86ed7fbStbbdev NumberType n;
39d86ed7fbStbbdev //! Grain size parameter
40d86ed7fbStbbdev NumberType grainSize;
41d86ed7fbStbbdev // number of time to repeat calculation
42d86ed7fbStbbdev NumberType repeatNumber;
43d86ed7fbStbbdev
RunOptionsRunOptions44d86ed7fbStbbdev RunOptions(utility::thread_number_range threads_,
45d86ed7fbStbbdev NumberType grainSize_,
46d86ed7fbStbbdev NumberType n_,
47d86ed7fbStbbdev bool silentFlag_,
48d86ed7fbStbbdev NumberType repeatNumber_)
49d86ed7fbStbbdev : threads(threads_),
50d86ed7fbStbbdev silentFlag(silentFlag_),
51d86ed7fbStbbdev n(n_),
52d86ed7fbStbbdev grainSize(grainSize_),
53d86ed7fbStbbdev repeatNumber(repeatNumber_) {}
54d86ed7fbStbbdev };
55d86ed7fbStbbdev
56d86ed7fbStbbdev //! Parse the command line.
ParseCommandLine(int argc,char * argv[])57d86ed7fbStbbdev static RunOptions ParseCommandLine(int argc, char* argv[]) {
58d86ed7fbStbbdev utility::thread_number_range threads(
59d86ed7fbStbbdev utility::get_default_num_threads, 0, utility::get_default_num_threads());
60d86ed7fbStbbdev NumberType grainSize = 1000;
61d86ed7fbStbbdev bool silent = false;
62d86ed7fbStbbdev NumberType number = 100000000;
63d86ed7fbStbbdev NumberType repeatNumber = 1;
64d86ed7fbStbbdev
65d86ed7fbStbbdev utility::parse_cli_arguments(
66d86ed7fbStbbdev argc,
67d86ed7fbStbbdev argv,
68d86ed7fbStbbdev utility::cli_argument_pack()
69d86ed7fbStbbdev //"-h" option for displaying help is present implicitly
70d86ed7fbStbbdev .positional_arg(threads, "n-of-threads", utility::thread_number_range_desc)
71d86ed7fbStbbdev .positional_arg(number,
72d86ed7fbStbbdev "number",
73d86ed7fbStbbdev "upper bound of range to search primes in, must be a positive integer")
74d86ed7fbStbbdev .positional_arg(grainSize, "grain-size", "must be a positive integer")
75d86ed7fbStbbdev .positional_arg(
76d86ed7fbStbbdev repeatNumber,
77d86ed7fbStbbdev "n-of-repeats",
78d86ed7fbStbbdev "repeat the calculation this number of times, must be a positive integer")
79d86ed7fbStbbdev .arg(silent, "silent", "no output except elapsed time"));
80d86ed7fbStbbdev
81d86ed7fbStbbdev RunOptions options(threads, grainSize, number, silent, repeatNumber);
82d86ed7fbStbbdev return options;
83d86ed7fbStbbdev }
84d86ed7fbStbbdev
main(int argc,char * argv[])85d86ed7fbStbbdev int main(int argc, char* argv[]) {
86d86ed7fbStbbdev oneapi::tbb::tick_count mainBeginMark = oneapi::tbb::tick_count::now();
87d86ed7fbStbbdev RunOptions options = ParseCommandLine(argc, argv);
88d86ed7fbStbbdev
89d86ed7fbStbbdev // Try different numbers of threads
90d86ed7fbStbbdev for (int p = options.threads.first; p <= options.threads.last; p = options.threads.step(p)) {
91d86ed7fbStbbdev for (NumberType i = 0; i < options.repeatNumber; ++i) {
92d86ed7fbStbbdev oneapi::tbb::tick_count iterationBeginMark = oneapi::tbb::tick_count::now();
93d86ed7fbStbbdev NumberType count = 0;
94d86ed7fbStbbdev NumberType n = options.n;
95d86ed7fbStbbdev if (p == 0) {
96d86ed7fbStbbdev count = SerialCountPrimes(n);
97d86ed7fbStbbdev }
98d86ed7fbStbbdev else {
99d86ed7fbStbbdev NumberType grainSize = options.grainSize;
100d86ed7fbStbbdev count = ParallelCountPrimes(n, p, grainSize);
101d86ed7fbStbbdev }
102d86ed7fbStbbdev oneapi::tbb::tick_count iterationEndMark = oneapi::tbb::tick_count::now();
103d86ed7fbStbbdev if (!options.silentFlag) {
104d86ed7fbStbbdev std::cout << "#primes from [2.." << options.n << "] = " << count << " ("
105d86ed7fbStbbdev << (iterationEndMark - iterationBeginMark).seconds() << " sec with ";
106d86ed7fbStbbdev if (0 != p)
107d86ed7fbStbbdev std::cout << p << "-way parallelism";
108d86ed7fbStbbdev else
109d86ed7fbStbbdev std::cout << "serial code";
110d86ed7fbStbbdev std::cout << ")\n";
111d86ed7fbStbbdev }
112d86ed7fbStbbdev }
113d86ed7fbStbbdev }
114d86ed7fbStbbdev utility::report_elapsed_time((oneapi::tbb::tick_count::now() - mainBeginMark).seconds());
115d86ed7fbStbbdev return 0;
116d86ed7fbStbbdev }
117