1 /**********************************************************************************************/
2 /*  This program is part of the Barcelona OpenMP Tasks Suite                                  */
3 /*  Copyright (C) 2009 Barcelona Supercomputing Center - Centro Nacional de Supercomputacion  */
4 /*  Copyright (C) 2009 Universitat Politecnica de Catalunya                                   */
5 /*                                                                                            */
6 /*  This program is free software; you can redistribute it and/or modify                      */
7 /*  it under the terms of the GNU General Public License as published by                      */
8 /*  the Free Software Foundation; either version 2 of the License, or                         */
9 /*  (at your option) any later version.                                                       */
10 /*                                                                                            */
11 /*  This program is distributed in the hope that it will be useful,                           */
12 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of                            */
13 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                             */
14 /*  GNU General Public License for more details.                                              */
15 /*                                                                                            */
16 /*  You should have received a copy of the GNU General Public License                         */
17 /*  along with this program; if not, write to the Free Software                               */
18 /*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA            */
19 /**********************************************************************************************/
20 
21 /***********************************************************************
22  * main function & common behaviour of the benchmark.
23  **********************************************************************/
24 #include <CLI11.hpp>
25 #include "strassen.hpp"
26 
strassen_alg(const std::string & model,const unsigned num_threads,const unsigned num_rounds)27 void strassen_alg(
28   const std::string& model,
29   const unsigned num_threads,
30   const unsigned num_rounds
31   ) {
32 
33   std::cout << std::setw(12) << "runtime"
34             << std::endl;
35 
36   double runtime {0.0};
37 
38   for(unsigned j=0; j<num_rounds; ++j) {
39     if(model == "tf") {
40       runtime += measure_time_taskflow(num_threads, MatrixA, MatrixB, MatrixC, MATRIX_SIZE).count();
41     }
42     else if(model == "tbb") {
43       runtime += measure_time_tbb(num_threads, MatrixA, MatrixB, MatrixC, MATRIX_SIZE).count();
44     }
45     else if(model == "omp") {
46       runtime += measure_time_omp(num_threads, MatrixA, MatrixB, MatrixC, MATRIX_SIZE).count();
47     }
48     else assert(false);
49   }
50 
51   std::cout << std::setw(12) << runtime / num_rounds / 1e3
52             << std::endl;
53 }
54 
55 
56 
57 
58 /***********************************************************************
59  * main:
60  **********************************************************************/
main(int argc,char * argv[])61 int main(int argc, char* argv[]) {
62   CLI::App app{"Strassen algorithm for matrix multiplication"};
63 
64   unsigned num_threads {1};
65   app.add_option("-t,--num_threads", num_threads, "number of threads (default=1)");
66 
67   unsigned num_rounds {1};
68   app.add_option("-r,--num_rounds", num_rounds, "number of rounds (default=1)");
69 
70   bool check_result {false};
71   app.add_option("-c,--check", check_result, "compare result with sequential mode (default=false)");
72 
73   std::string model = "tf";
74   app.add_option("-m,--model", model, "model name tbb|omp|tf (default=tf)")
75      ->check([] (const std::string& m) {
76         if(m != "tbb" && m != "tf" && m != "omp") {
77           return "model name should be \"tbb\", \"omp\", or \"tf\"";
78         }
79         return "";
80      });
81 
82   CLI11_PARSE(app, argc, argv);
83 
84   std::cout << "model=" << model << ' '
85             << "num_threads=" << num_threads << ' '
86             << "num_rounds=" << num_rounds << ' '
87             << "check result=" << check_result << ' '
88             << std::endl;
89 
90 
91   init_ABC();
92 
93   strassen_alg(model, num_threads, num_rounds);
94 
95   if(check_result) {
96     // Compare against the sequential matrix multiplication
97     double *D;
98     D = alloc_matrix(MATRIX_SIZE);
99     auto beg = std::chrono::high_resolution_clock::now();
100     //OptimizedStrassenMultiply_seq(D, MatrixA, MatrixB, MATRIX_SIZE, MATRIX_SIZE, MATRIX_SIZE, MATRIX_SIZE, 1);
101     auto end = std::chrono::high_resolution_clock::now();
102     std::cout << "Seq: " << std::chrono::duration_cast<std::chrono::microseconds>(end - beg).count()/1e3 << std::endl;
103     matrixmul(MATRIX_SIZE, MatrixA, MATRIX_SIZE, MatrixB, MATRIX_SIZE, D, MATRIX_SIZE);
104     assert(compare_matrix(MATRIX_SIZE, MatrixC, MATRIX_SIZE, D, MATRIX_SIZE) == 1);
105     std::cout << "Correct!\n";
106     free(D);
107   }
108 
109   free(MatrixA);
110   free(MatrixB);
111   free(MatrixC);
112 
113   return 0;
114 }
115 
116