Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_ScalarFlopCounter.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 // @HEADER
29 
30 #include <cassert>
31 #include <iomanip>
32 #include <vector>
33 #include <iostream>
34 
37 
38 // Initialization of static members
39 const char*
41 {
42  "="
43  ,"+"
44  ,"+="
45  ,"unary +"
46  ,"-"
47  ,"-="
48  ,"unary -"
49  ,"*"
50  ,"*="
51  ,"/"
52  ,"/="
53  ,">"
54  ,">="
55  ,"<"
56  ,"<="
57  ,"=="
58  ,"exp"
59  ,"log"
60  ,"log10"
61  ,"sqrt"
62  ,"cbrt"
63  ,"cos"
64  ,"sin"
65  ,"tan"
66  ,"acos"
67  ,"asin"
68  ,"atan"
69  ,"atan2"
70  ,"cosh"
71  ,"sinh"
72  ,"tanh"
73  ,"abs"
74  ,"pow"
75  ,"max"
76  ,"min"
77 };
78 const char*
80 {
81  "="
82  ,"all +-"
83  ,"all *"
84  ,"all /"
85  ,"<,>,=="
86  ,"nonlinear"
87 };
88 unsigned int
90 
92 {
93  reset();
94 }
95 
96 void
98 {
99  ds_array<unsigned int>::zero( &partialFlopCounts[0], int(NUM_OPS) );
100  ds_array<unsigned int>::zero( &partialSummaryFlopCounts[0],
101  int(NUM_SUMMARY_OPS) );
102  ds_array<double>::zero( &flopCounts[0], int(NUM_OPS) );
103  ds_array<double>::zero( &summaryFlopCounts[0], int(NUM_SUMMARY_OPS) );
104  totalFlopCount = 0.0;
105 }
106 
107 void
109 {
110  for (int i=0; i<NUM_OPS; i++) {
111  flopCounts[i] += static_cast<double>(partialFlopCounts[i]);
112  partialFlopCounts[i] = 0;
113  }
114  for (int i=0; i<NUM_SUMMARY_OPS; i++) {
115  summaryFlopCounts[i] += static_cast<double>(partialSummaryFlopCounts[i]);
116  partialSummaryFlopCounts[i] = 0;
117  }
118  totalFlopCount = 0;
119  for (int i=0; i<NUM_OPS; i++)
120  totalFlopCount += flopCounts[i];
121 }
122 
123 void
125 {
126  ESummaryFlopType sft = getSummaryType(ft);
127  if (partialFlopCounts[ft] > flopGranularity) {
128  flopCounts[ft] += static_cast<double>(partialFlopCounts[ft]);
129  partialFlopCounts[ft] =0;
130  }
131  if (partialSummaryFlopCounts[sft] > flopGranularity) {
132  summaryFlopCounts[sft] +=
133  static_cast<double>(partialSummaryFlopCounts[sft]);
134  partialSummaryFlopCounts[sft] = 0;
135  }
136  ++partialFlopCounts[ft];
137  ++partialSummaryFlopCounts[sft];
138 }
139 
142 {
143  switch(ft) {
144  case ASSIGN:
145  return SUMMARY_ASSIGN;
146  case PLUS:
147  case PLUS_ASSIGN:
148  case UNARY_PLUS:
149  case MINUS:
150  case MINUS_ASSIGN:
151  case UNARY_MINUS:
152  return SUMMARY_PLUS_MINUS;
153  case MULTIPLY:
154  case MULTIPLY_ASSIGN:
155  return SUMMARY_MULTIPLY;
156  case DIVIDE:
157  case DIVIDE_ASSIGN:
158  return SUMMARY_DIVIDE;
159  case EXP:
160  case LOG:
161  case LOG10:
162  case SQRT:
163  case CBRT:
164  case COS:
165  case SIN:
166  case TAN:
167  case ACOS:
168  case ASIN:
169  case ATAN:
170  case ATAN2:
171  case COSH:
172  case SINH:
173  case TANH:
174  case ABS:
175  case POW:
176  case MAX:
177  case MIN:
178  return SUMMARY_NONLINEAR;
179  case GREATER_THAN:
180  case GREATER_THAN_EQUAL:
181  case LESS_THAN:
182  case LESS_THAN_EQUAL:
183  case EQUAL:
184  return SUMMARY_COMPARISON;
185  default:
186  assert(0);
187  }
188 
189  // This code is un-reachable, but some compilers will issue a warning
190  // without it
191  return SUMMARY_ASSIGN;
192 }
193 
194 std::ostream&
196  const char* names[],
197  const char* abbr[],
198  const FlopCounts counts[],
199  std::ostream &out)
200 {
201  assert( n >= 1 && names && abbr && counts );
202  const int wo = 10;
203  const int wc = 20;
204  const char spacero[] = "----------";
205  const char spacerc[] = "--------------------";
206  // Print legend
207  if(names) {
208  out << "\nLegend\n------\n";
209  for( int j = 0; j < n; ++j )
210  out << " " << abbr[j] << " = " << names[j] << std::endl;
211  out << std::endl;
212  }
213  // Print table header
214  out << std::left << " " << std::setw(wo) << "op\\count";
215  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << abbr[j];
216  out << std::endl;
217  out << std::right << " " << std::setw(wo) << spacero;
218  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
219  out << std::endl;
220  // Print rows of all operation counts
221  for( int i = 0; i < FlopCounts::NUM_OPS; ++i ) {
222  double theseFlops = 0;
223  for( int j = 0; j < n; ++j ) theseFlops += counts[j].flopCounts[i];
224  if(theseFlops) {
225  out << " " << std::setw(wo) << FlopCounts::flopCountsNames[i];
226  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << counts[j].flopCounts[i];
227  out << std::endl;
228  }
229  }
230  out << std::right << " " << std::setw(wo) << spacero;
231  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
232  out << std::endl;
233  // Print summary rows
234  std::vector<double> totalFlops(n);
235  for( int i = 0; i < FlopCounts::NUM_SUMMARY_OPS; ++i ) {
236  double theseFlops = 0;
237  for( int j = 0; j < n; ++j ) {
238  const double flops = counts[j].summaryFlopCounts[i];
239  theseFlops += flops;
240  totalFlops[j] += flops;
241  }
242  if(theseFlops) {
243  out << " " << std::setw(wo) << FlopCounts::summaryFlopCountsNames[i];
244  for( int j = 0; j < n; ++j )
245  out << " " << std::setw(wc) << counts[j].summaryFlopCounts[i];
246  out << std::endl;
247  }
248  }
249  out << std::right << " " << std::setw(wo) << spacero;
250  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
251  out << std::endl;
252  // Print total flops
253  out << " " << std::setw(wo) << "all flops";
254  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << totalFlops[j];
255  out << std::endl;
256  //
257  return out;
258 }
void reset()
Reset flop counters before starting a block of computations. */.
ESummaryFlopType getSummaryType(EFlopType ft)
Get summary op enum from op enum.
void increment(EFlopType ft)
Increment an individual flop counter.
static SACADO_INLINE_FUNCTION void zero(T *dest, int sz)
Zero out array dest of length sz.
std::ostream & printCountersTable(const int n, const char *names[], const char *abbr[], const FlopCounts counts[], std::ostream &out)
Print a list of flop counts into a single table.
static unsigned int flopGranularity
The number of flops to accumulate as an integer before converting to a double.
#define MIN(a, b)
ESummaryFlopType
Enum of summary operation categories.
double summaryFlopCounts[NUM_SUMMARY_OPS]
Summary category flop counts.
static const char * flopCountsNames[NUM_OPS]
Names of individual flops.
Class storing flop counts and summary flop counts.
double flopCounts[NUM_OPS]
Individual flop counts.
static const char * summaryFlopCountsNames[NUM_SUMMARY_OPS]
Names for summary operation categories.