Sacado Package Browser (Single Doxygen Collection)  Version of the Day
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 #ifdef HAVE_SACADO_CXX11
63  ,"cbrt"
64 #endif
65  ,"cos"
66  ,"sin"
67  ,"tan"
68  ,"acos"
69  ,"asin"
70  ,"atan"
71  ,"atan2"
72  ,"cosh"
73  ,"sinh"
74  ,"tanh"
75  ,"abs"
76  ,"pow"
77  ,"max"
78  ,"min"
79 };
80 const char*
82 {
83  "="
84  ,"all +-"
85  ,"all *"
86  ,"all /"
87  ,"<,>,=="
88  ,"nonlinear"
89 };
90 unsigned int
92 
94 {
95  reset();
96 }
97 
98 void
100 {
101  ds_array<unsigned int>::zero( &partialFlopCounts[0], int(NUM_OPS) );
102  ds_array<unsigned int>::zero( &partialSummaryFlopCounts[0],
103  int(NUM_SUMMARY_OPS) );
104  ds_array<double>::zero( &flopCounts[0], int(NUM_OPS) );
105  ds_array<double>::zero( &summaryFlopCounts[0], int(NUM_SUMMARY_OPS) );
106  totalFlopCount = 0.0;
107 }
108 
109 void
111 {
112  for (int i=0; i<NUM_OPS; i++) {
113  flopCounts[i] += static_cast<double>(partialFlopCounts[i]);
114  partialFlopCounts[i] = 0;
115  }
116  for (int i=0; i<NUM_SUMMARY_OPS; i++) {
117  summaryFlopCounts[i] += static_cast<double>(partialSummaryFlopCounts[i]);
118  partialSummaryFlopCounts[i] = 0;
119  }
120  totalFlopCount = 0;
121  for (int i=0; i<NUM_OPS; i++)
122  totalFlopCount += flopCounts[i];
123 }
124 
125 void
127 {
128  ESummaryFlopType sft = getSummaryType(ft);
129  if (partialFlopCounts[ft] > flopGranularity) {
130  flopCounts[ft] += static_cast<double>(partialFlopCounts[ft]);
131  partialFlopCounts[ft] =0;
132  }
133  if (partialSummaryFlopCounts[sft] > flopGranularity) {
134  summaryFlopCounts[sft] +=
135  static_cast<double>(partialSummaryFlopCounts[sft]);
136  partialSummaryFlopCounts[sft] = 0;
137  }
138  ++partialFlopCounts[ft];
139  ++partialSummaryFlopCounts[sft];
140 }
141 
144 {
145  switch(ft) {
146  case ASSIGN:
147  return SUMMARY_ASSIGN;
148  break;
149  case PLUS:
150  case PLUS_ASSIGN:
151  case UNARY_PLUS:
152  case MINUS:
153  case MINUS_ASSIGN:
154  case UNARY_MINUS:
155  return SUMMARY_PLUS_MINUS;
156  break;
157  case MULTIPLY:
158  case MULTIPLY_ASSIGN:
159  return SUMMARY_MULTIPLY;
160  break;
161  case DIVIDE:
162  case DIVIDE_ASSIGN:
163  return SUMMARY_DIVIDE;
164  break;
165  case EXP:
166  case LOG:
167  case LOG10:
168  case SQRT:
169 #ifdef HAVE_SACADO_CXX11
170  case CBRT:
171 #endif
172  case COS:
173  case SIN:
174  case TAN:
175  case ACOS:
176  case ASIN:
177  case ATAN:
178  case ATAN2:
179  case COSH:
180  case SINH:
181  case TANH:
182  case ABS:
183  case POW:
184  case MAX:
185  case MIN:
186  return SUMMARY_NONLINEAR;
187  break;
188  case GREATER_THAN:
189  case GREATER_THAN_EQUAL:
190  case LESS_THAN:
191  case LESS_THAN_EQUAL:
192  case EQUAL:
193  return SUMMARY_COMPARISON;
194  break;
195  default:
196  assert(0);
197  }
198 
199  // This code is un-reachable, but some compilers will issue a warning
200  // without it
201  return SUMMARY_ASSIGN;
202 }
203 
204 std::ostream&
206  const char* names[],
207  const char* abbr[],
208  const FlopCounts counts[],
209  std::ostream &out)
210 {
211  assert( n >= 1 && names && abbr && counts );
212  const int wo = 10;
213  const int wc = 20;
214  const char spacero[] = "----------";
215  const char spacerc[] = "--------------------";
216  // Print legend
217  if(names) {
218  out << "\nLegend\n------\n";
219  for( int j = 0; j < n; ++j )
220  out << " " << abbr[j] << " = " << names[j] << std::endl;
221  out << std::endl;
222  }
223  // Print table header
224  out << std::left << " " << std::setw(wo) << "op\\count";
225  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << abbr[j];
226  out << std::endl;
227  out << std::right << " " << std::setw(wo) << spacero;
228  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
229  out << std::endl;
230  // Print rows of all operation counts
231  for( int i = 0; i < FlopCounts::NUM_OPS; ++i ) {
232  double theseFlops = 0;
233  for( int j = 0; j < n; ++j ) theseFlops += counts[j].flopCounts[i];
234  if(theseFlops) {
235  out << " " << std::setw(wo) << FlopCounts::flopCountsNames[i];
236  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << counts[j].flopCounts[i];
237  out << std::endl;
238  }
239  }
240  out << std::right << " " << std::setw(wo) << spacero;
241  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
242  out << std::endl;
243  // Print summary rows
244  std::vector<double> totalFlops(n);
245  for( int i = 0; i < FlopCounts::NUM_SUMMARY_OPS; ++i ) {
246  double theseFlops = 0;
247  for( int j = 0; j < n; ++j ) {
248  const double flops = counts[j].summaryFlopCounts[i];
249  theseFlops += flops;
250  totalFlops[j] += flops;
251  }
252  if(theseFlops) {
253  out << " " << std::setw(wo) << FlopCounts::summaryFlopCountsNames[i];
254  for( int j = 0; j < n; ++j )
255  out << " " << std::setw(wc) << counts[j].summaryFlopCounts[i];
256  out << std::endl;
257  }
258  }
259  out << std::right << " " << std::setw(wo) << spacero;
260  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
261  out << std::endl;
262  // Print total flops
263  out << " " << std::setw(wo) << "all flops";
264  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << totalFlops[j];
265  out << std::endl;
266  //
267  return out;
268 }
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.
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.
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.
static KOKKOS_INLINE_FUNCTION void zero(T *dest, int sz)
Zero out array dest of length sz.
double flopCounts[NUM_OPS]
Individual flop counts.
static const char * summaryFlopCountsNames[NUM_SUMMARY_OPS]
Names for summary operation categories.