xref: /oneTBB/examples/parallel_reduce/pi/main.cpp (revision 8370742d)
1*8370742dSDmitri Mokhov /*
2*8370742dSDmitri Mokhov     Copyright (c) 2023 Intel Corporation
3*8370742dSDmitri Mokhov 
4*8370742dSDmitri Mokhov     Licensed under the Apache License, Version 2.0 (the "License");
5*8370742dSDmitri Mokhov     you may not use this file except in compliance with the License.
6*8370742dSDmitri Mokhov     You may obtain a copy of the License at
7*8370742dSDmitri Mokhov 
8*8370742dSDmitri Mokhov         http://www.apache.org/licenses/LICENSE-2.0
9*8370742dSDmitri Mokhov 
10*8370742dSDmitri Mokhov     Unless required by applicable law or agreed to in writing, software
11*8370742dSDmitri Mokhov     distributed under the License is distributed on an "AS IS" BASIS,
12*8370742dSDmitri Mokhov     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8370742dSDmitri Mokhov     See the License for the specific language governing permissions and
14*8370742dSDmitri Mokhov     limitations under the License.
15*8370742dSDmitri Mokhov */
16*8370742dSDmitri Mokhov 
17*8370742dSDmitri Mokhov #include "oneapi/tbb/tick_count.h"
18*8370742dSDmitri Mokhov 
19*8370742dSDmitri Mokhov #include "common/utility/get_default_num_threads.hpp"
20*8370742dSDmitri Mokhov #include "common/utility/utility.hpp"
21*8370742dSDmitri Mokhov 
22*8370742dSDmitri Mokhov #include "common.h"
23*8370742dSDmitri Mokhov 
24*8370742dSDmitri Mokhov const number_t chunk_size = 4096; // Multiple of 16, to fit float datatype to a vector register.
25*8370742dSDmitri Mokhov 
26*8370742dSDmitri Mokhov // number of intervals
27*8370742dSDmitri Mokhov number_t num_intervals = 1000000000;
28*8370742dSDmitri Mokhov pi_t step = pi_t(0.0);
29*8370742dSDmitri Mokhov 
30*8370742dSDmitri Mokhov bool silent = false;
31*8370742dSDmitri Mokhov 
compute_pi_serial()32*8370742dSDmitri Mokhov double compute_pi_serial() {
33*8370742dSDmitri Mokhov     double ret = 0;
34*8370742dSDmitri Mokhov 
35*8370742dSDmitri Mokhov     step = pi_t(1.0) / num_intervals;
36*8370742dSDmitri Mokhov 
37*8370742dSDmitri Mokhov     number_t tail = num_intervals % chunk_size;
38*8370742dSDmitri Mokhov     number_t last = num_intervals - tail;
39*8370742dSDmitri Mokhov 
40*8370742dSDmitri Mokhov     for (number_t slice = 0; slice < last; slice += chunk_size) {
41*8370742dSDmitri Mokhov         ret += pi_slice_kernel(slice);
42*8370742dSDmitri Mokhov     }
43*8370742dSDmitri Mokhov     ret += pi_slice_kernel(last, tail);
44*8370742dSDmitri Mokhov     ret *= step;
45*8370742dSDmitri Mokhov 
46*8370742dSDmitri Mokhov     return ret;
47*8370742dSDmitri Mokhov }
48*8370742dSDmitri Mokhov 
main(int argc,char * argv[])49*8370742dSDmitri Mokhov int main(int argc, char* argv[]) {
50*8370742dSDmitri Mokhov     try {
51*8370742dSDmitri Mokhov         tbb::tick_count main_start_time = tbb::tick_count::now();
52*8370742dSDmitri Mokhov         // zero number of threads means to run serial version
53*8370742dSDmitri Mokhov         utility::thread_number_range threads(utility::get_default_num_threads, 0);
54*8370742dSDmitri Mokhov 
55*8370742dSDmitri Mokhov         utility::parse_cli_arguments(
56*8370742dSDmitri Mokhov             argc,
57*8370742dSDmitri Mokhov             argv,
58*8370742dSDmitri Mokhov             utility::cli_argument_pack()
59*8370742dSDmitri Mokhov                 //"-h" option for for displaying help is present implicitly
60*8370742dSDmitri Mokhov                 .positional_arg(threads, "n-of-threads", utility::thread_number_range_desc)
61*8370742dSDmitri Mokhov                 .positional_arg(num_intervals, "n-of-intervals", "number of intervals")
62*8370742dSDmitri Mokhov                 .arg(silent, "silent", "no output except time elapsed"));
63*8370742dSDmitri Mokhov 
64*8370742dSDmitri Mokhov         for (int p = threads.first; p <= threads.last; p = threads.step(p)) {
65*8370742dSDmitri Mokhov             pi_t pi;
66*8370742dSDmitri Mokhov             double compute_time;
67*8370742dSDmitri Mokhov             if (p == 0) {
68*8370742dSDmitri Mokhov                 //run a serial version
69*8370742dSDmitri Mokhov                 tbb::tick_count compute_start_time = tbb::tick_count::now();
70*8370742dSDmitri Mokhov                 pi = compute_pi_serial();
71*8370742dSDmitri Mokhov                 compute_time = (tbb::tick_count::now() - compute_start_time).seconds();
72*8370742dSDmitri Mokhov             }
73*8370742dSDmitri Mokhov             else {
74*8370742dSDmitri Mokhov                 //run a parallel version
75*8370742dSDmitri Mokhov                 threading tp(p);
76*8370742dSDmitri Mokhov                 tbb::tick_count compute_start_time = tbb::tick_count::now();
77*8370742dSDmitri Mokhov                 pi = compute_pi_parallel();
78*8370742dSDmitri Mokhov                 compute_time = (tbb::tick_count::now() - compute_start_time).seconds();
79*8370742dSDmitri Mokhov             }
80*8370742dSDmitri Mokhov 
81*8370742dSDmitri Mokhov             if (!silent) {
82*8370742dSDmitri Mokhov                 if (p == 0) {
83*8370742dSDmitri Mokhov                     std::cout << "Serial run:\tpi = " << pi << "\tcompute time = " << compute_time
84*8370742dSDmitri Mokhov                               << " sec\n";
85*8370742dSDmitri Mokhov                 }
86*8370742dSDmitri Mokhov                 else {
87*8370742dSDmitri Mokhov                     std::cout << "Parallel run:\tpi = " << pi << "\tcompute time = " << compute_time
88*8370742dSDmitri Mokhov                               << " sec\t on " << p << " threads\n";
89*8370742dSDmitri Mokhov                 }
90*8370742dSDmitri Mokhov             }
91*8370742dSDmitri Mokhov         }
92*8370742dSDmitri Mokhov 
93*8370742dSDmitri Mokhov         utility::report_elapsed_time((tbb::tick_count::now() - main_start_time).seconds());
94*8370742dSDmitri Mokhov         return 0;
95*8370742dSDmitri Mokhov     }
96*8370742dSDmitri Mokhov     catch (std::exception& e) {
97*8370742dSDmitri Mokhov         std::cerr << "error occurred. error text is :\"" << e.what() << "\"\n";
98*8370742dSDmitri Mokhov         return 1;
99*8370742dSDmitri Mokhov     }
100*8370742dSDmitri Mokhov }
101