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