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 #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  case PLUS:
149  case PLUS_ASSIGN:
150  case UNARY_PLUS:
151  case MINUS:
152  case MINUS_ASSIGN:
153  case UNARY_MINUS:
154  return SUMMARY_PLUS_MINUS;
155  case MULTIPLY:
156  case MULTIPLY_ASSIGN:
157  return SUMMARY_MULTIPLY;
158  case DIVIDE:
159  case DIVIDE_ASSIGN:
160  return SUMMARY_DIVIDE;
161  case EXP:
162  case LOG:
163  case LOG10:
164  case SQRT:
165 #ifdef HAVE_SACADO_CXX11
166  case CBRT:
167 #endif
168  case COS:
169  case SIN:
170  case TAN:
171  case ACOS:
172  case ASIN:
173  case ATAN:
174  case ATAN2:
175  case COSH:
176  case SINH:
177  case TANH:
178  case ABS:
179  case POW:
180  case MAX:
181  case MIN:
182  return SUMMARY_NONLINEAR;
183  case GREATER_THAN:
184  case GREATER_THAN_EQUAL:
185  case LESS_THAN:
186  case LESS_THAN_EQUAL:
187  case EQUAL:
188  return SUMMARY_COMPARISON;
189  default:
190  assert(0);
191  }
192 
193  // This code is un-reachable, but some compilers will issue a warning
194  // without it
195  return SUMMARY_ASSIGN;
196 }
197 
198 std::ostream&
200  const char* names[],
201  const char* abbr[],
202  const FlopCounts counts[],
203  std::ostream &out)
204 {
205  assert( n >= 1 && names && abbr && counts );
206  const int wo = 10;
207  const int wc = 20;
208  const char spacero[] = "----------";
209  const char spacerc[] = "--------------------";
210  // Print legend
211  if(names) {
212  out << "\nLegend\n------\n";
213  for( int j = 0; j < n; ++j )
214  out << " " << abbr[j] << " = " << names[j] << std::endl;
215  out << std::endl;
216  }
217  // Print table header
218  out << std::left << " " << std::setw(wo) << "op\\count";
219  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << abbr[j];
220  out << std::endl;
221  out << std::right << " " << std::setw(wo) << spacero;
222  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
223  out << std::endl;
224  // Print rows of all operation counts
225  for( int i = 0; i < FlopCounts::NUM_OPS; ++i ) {
226  double theseFlops = 0;
227  for( int j = 0; j < n; ++j ) theseFlops += counts[j].flopCounts[i];
228  if(theseFlops) {
229  out << " " << std::setw(wo) << FlopCounts::flopCountsNames[i];
230  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << counts[j].flopCounts[i];
231  out << std::endl;
232  }
233  }
234  out << std::right << " " << std::setw(wo) << spacero;
235  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
236  out << std::endl;
237  // Print summary rows
238  std::vector<double> totalFlops(n);
239  for( int i = 0; i < FlopCounts::NUM_SUMMARY_OPS; ++i ) {
240  double theseFlops = 0;
241  for( int j = 0; j < n; ++j ) {
242  const double flops = counts[j].summaryFlopCounts[i];
243  theseFlops += flops;
244  totalFlops[j] += flops;
245  }
246  if(theseFlops) {
247  out << " " << std::setw(wo) << FlopCounts::summaryFlopCountsNames[i];
248  for( int j = 0; j < n; ++j )
249  out << " " << std::setw(wc) << counts[j].summaryFlopCounts[i];
250  out << std::endl;
251  }
252  }
253  out << std::right << " " << std::setw(wo) << spacero;
254  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << spacerc;
255  out << std::endl;
256  // Print total flops
257  out << " " << std::setw(wo) << "all flops";
258  for( int j = 0; j < n; ++j ) out << " " << std::setw(wc) << totalFlops[j];
259  out << std::endl;
260  //
261  return out;
262 }
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.
#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.
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.