Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_PAPI_Counter2.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Panzer: A partial differential equation assembly
4 // engine for strongly coupled complex multiphysics systems
5 //
6 // Copyright 2011 NTESS and the Panzer contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #include "Panzer_PAPI_Counter2.hpp"
12 #include "Teuchos_Assert.hpp"
13 #include "Teuchos_CommHelpers.hpp"
14 #include <algorithm>
15 #include <cstring>
16 
17 namespace panzer {
18 
19  int PAPICounter2::m_event_set = PAPI_NULL;
20  std::vector<int> PAPICounter2::m_events;
21  bool PAPICounter2::m_is_initialized = false;
22  std::map<std::string,PAPICounter2::InternalCounter2> PAPICounter2::m_counters;
23 
26  PAPICounter2::PAPICounter2(const std::string counter_name) :
27  m_name(counter_name)
28  {
29  if (!m_is_initialized) {
30  TEUCHOS_ASSERT( PAPI_library_init(PAPI_VER_CURRENT) == PAPI_VER_CURRENT );
31 
32  TEUCHOS_ASSERT( PAPI_create_eventset(&m_event_set) == PAPI_OK );
33 
34  for (std::vector<int>::const_iterator event = m_events.begin();
35  event != m_events.end(); ++event) {
36  TEUCHOS_ASSERT( PAPI_add_event(m_event_set,*event) == PAPI_OK );
37  }
38 
39  TEUCHOS_ASSERT( PAPI_start(m_event_set) == PAPI_OK );
40  m_is_initialized = true;
41  }
42 
43  // initialize the specific timer first time in
44  std::map<std::string,InternalCounter2>::const_iterator counter;
45  counter = m_counters.find(m_name);
46  if (counter == m_counters.end()) {
48  c.accumulated_time = 0;
49  c.start_counters.resize(m_events.size());
50  c.stop_counters.resize(m_events.size());
51  c.accumulated_counters.resize(m_events.size());
52  c.num_calls = 0;
53  }
54 
55  // mark start time
57  TEUCHOS_ASSERT( PAPI_read(m_event_set, &(c.start_counters[0])) == PAPI_OK );
58  c.start_time = PAPI_get_real_usec();
59  c.num_calls +=1;
60  }
61 
63  {
64  // accumulate totals
66 
67  TEUCHOS_ASSERT( PAPI_read(m_event_set, &(c.stop_counters[0])) == PAPI_OK );
68  c.accumulated_time += PAPI_get_real_usec() - c.start_time;
69 
70  std::vector<long_long>::iterator accum = c.accumulated_counters.begin();
71  std::vector<long_long>::const_iterator start = c.start_counters.begin();
72  std::vector<long_long>::const_iterator stop = c.stop_counters.begin();
73  for (; accum != c.accumulated_counters.end(); ++accum,++start,++stop)
74  *accum += *stop - *start;
75 
76  }
77 
78  void PAPICounter2::addEventCounter(const int event)
79  {
81  std::logic_error,
82  "Error - cannot add event after PAPICounter is initialized!");
83 
84  m_events.push_back(event);
85  }
86 
88  {
89  TEUCHOS_ASSERT(PAPI_start(m_event_set) == PAPI_OK);
90  }
91 
93  {
94  //TEUCHOS_ASSERT(PAPI_stop(m_event_set) == PAPI_OK);
95  }
96 
97  void PAPICounter2::report(std::ostream& os, const Teuchos::Comm<int>& comm)
98  {
99 
100  os << std::endl;
101  os << "************************************************************" << std::endl;
102  os << "* PAPI Counter Report (over all processes) " << std::endl;
103  os << "************************************************************" << std::endl;
104 
105  for (std::map<std::string,InternalCounter2>::const_iterator timer = m_counters.begin();
106  timer != m_counters.end(); ++timer) {
107 
108  // Communicate totals across processes
109 
110  const std::vector<long long int>& accum = timer->second.accumulated_counters;
111  std::vector<long long int> global_min(accum.size(),0);
112  std::vector<long long int> global_max(accum.size(),0);
113  std::vector<long long int> global_sum(accum.size(),0);
114  std::vector<long long int> global_avg(accum.size(),0);
115  long long int average_time = 0;
116 
117  Teuchos::reduceAll(comm, Teuchos::REDUCE_MIN, static_cast<int>(accum.size()), &accum[0], &global_min[0]);
118  Teuchos::reduceAll(comm, Teuchos::REDUCE_MAX, static_cast<int>(accum.size()), &accum[0], &global_max[0]);
119  Teuchos::reduceAll(comm, Teuchos::REDUCE_SUM, static_cast<int>(accum.size()), &accum[0], &global_sum[0]);
120  Teuchos::reduceAll(comm, Teuchos::REDUCE_SUM, static_cast<int>(accum.size()), &accum[0], &global_avg[0]);
121 
122  for (std::vector<long long int>::iterator i = global_avg.begin();
123  i != global_avg.end(); ++i)
124  (*i) = *i / Teuchos::as<long long int>(comm.getSize());
125 
126  Teuchos::reduceAll(comm, Teuchos::REDUCE_SUM, 1, &(timer->second.accumulated_time), &average_time);
127  average_time /= Teuchos::as<long long int>(comm.getSize());
128 
129  os << timer->first<< ": Average Process Time (seconds) = "
130  << timer->second.accumulated_time / 1.0e6 << std::endl;
131  os << timer->first<< ": Number of Calls = " << timer->second.num_calls << std::endl;
132 
133  int i=0;
134  for (std::vector<long_long>::const_iterator event=timer->second.accumulated_counters.begin();
135  event != timer->second.accumulated_counters.end(); ++event,++i) {
136  char event_name[PAPI_MAX_STR_LEN];
137  TEUCHOS_ASSERT( PAPI_event_code_to_name(m_events[i],event_name) == PAPI_OK);
138  std::string string_event_name(event_name);
139  os << timer->first << ": " << string_event_name << " = "
140  << "min:" << global_min[i]
141  << ", max:" << global_max[i]
142  << ", total:" << global_sum[i]
143  << ", avg:" << global_avg[i]
144  << std::endl;
145  }
146 
147  }
148 
149  os << "************************************************************" << std::endl;
150  }
151 
152 }
PAPICounter2(const std::string)
virtual int getSize() const =0
static bool m_is_initialized
true if the static members have been intitialized
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
std::string m_name
name of this counter
static std::map< std::string, InternalCounter2 > m_counters
maps the counter name to the data object
static void addEventCounter(const int event)
static void report(std::ostream &os, const Teuchos::Comm< int > &comm)
static std::vector< int > m_events
papi event index
static int m_event_set
PAPI event set.
#define TEUCHOS_ASSERT(assertion_test)