Panzer Version of the Day
Loading...
Searching...
No Matches
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
12#include "Teuchos_Assert.hpp"
13#include "Teuchos_CommHelpers.hpp"
14#include <algorithm>
15#include <cstring>
16
17namespace panzer {
18
19 int PAPICounter2::m_event_set = PAPI_NULL;
20 std::vector<int> PAPICounter2::m_events;
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 {
80 TEUCHOS_TEST_FOR_EXCEPTION(m_is_initialized,
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}
static void addEventCounter(const int event)
static bool m_is_initialized
true if the static members have been intitialized
PAPICounter2(const std::string)
static int m_event_set
PAPI event set.
static std::map< std::string, InternalCounter2 > m_counters
maps the counter name to the data object
std::string m_name
name of this counter
static void report(std::ostream &os, const Teuchos::Comm< int > &comm)
static std::vector< int > m_events
papi event index