MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_MutuallyExclusiveTime.cpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include <map>
11#include <iostream> // for basic_ostream, etc
12#include <utility> // for pair
13#include "Teuchos_FancyOStream.hpp" // for basic_FancyOStream, etc
14#include "Teuchos_RCP.hpp" // for RCP::operator->, etc
15#include "Teuchos_TestForException.hpp" // for TEUCHOS_TEST_FOR_EXCEPTION
16#include "Teuchos_Time.hpp"
17#include "Teuchos_TimeMonitor.hpp"
18#include "MueLu_ConfigDefs.hpp"
19#include "MueLu_Exceptions.hpp"
20#include "MueLu_BaseClass.hpp"
21#include "MueLu_VerbosityLevel.hpp" // for MsgType::Debug, etc
23#include "MueLu_FactoryBase.hpp"
24#include "MueLu_Level.hpp"
25
26namespace MueLu {
27
28std::map<std::string, std::string> myParent_;
29
30template <class TagName>
31MutuallyExclusiveTime<TagName>::MutuallyExclusiveTime(const std::string& name, bool startFlag)
32 : name_(name)
33 , timer_(rcp(new Teuchos::Time(name, false)))
34 , // second argument is false in any case, because if start==true,
35 // timer has to be started by MutuallyExclusiveTime::start() instead of Teuchos::Time::start().
36 isPaused_(false) {
37 if (startFlag == true) timer_->start();
38}
39
40template <class TagName>
42 // This timer can only be destroyed if it is not in the stack
43 if (isPaused()) {
44 // error message because cannot throw an exception in destructor
45 GetOStream(Errors) << "MutuallyExclusiveTime::~MutuallyExclusiveTime(): Error: destructor called on a paused timer." << std::endl;
46 // TODO: Even if timing results will be wrong, the timer can be removed from the stack to avoid a segmentation fault.
47 }
48
49 stop(); // if isRunning(), remove from the stack, resume previous timer
50}
51
52template <class TagName>
54 TEUCHOS_TEST_FOR_EXCEPTION(isPaused(), Exceptions::RuntimeError, "MueLu::MutuallyExclusiveTime::start(): timer is paused. Use resume().");
55
56 if (isRunning()) {
57 return;
58 } // If timer is already running, do not pause/push-in-the-stack/start the timer.
59 // Otherwise, something bad will happen when this.stop() will be called
60
61 // pause currently running timer
62 if (!timerStack_.empty()) {
63 GetOStream(Debug) << "pausing parent timer " << timerStack_.top()->name_ << std::endl;
64 timerStack_.top()->pause();
65 GetOStream(Debug) << "starting child timer " << this->name_ << std::endl;
66 myParent_[this->name_] = timerStack_.top()->name_;
67 } else {
68 GetOStream(Debug) << "starting orphan timer " << this->name_ << std::endl;
69 myParent_[this->name_] = "no parent";
70 }
71
72 // start this timer
73 timer_->start(reset);
74 timerStack_.push(this);
75}
76
77template <class TagName>
79 if (isPaused())
80 GetOStream(Errors) << "MueLu::MutuallyExclusiveTime::stop(): timer is paused. Use resume()" << std::endl;
81
82 if (!isRunning()) {
83 return timer_->stop();
84 } // stop() can be called on stopped timer
85
86 // Here, timer is running, so it is the head of the stack
87 TopOfTheStack();
88
89 timerStack_.pop();
90 double r = timer_->stop();
91
92 if (!timerStack_.empty()) {
93 GetOStream(Debug) << "resuming timer " << timerStack_.top()->name_ << std::endl;
94 timerStack_.top()->resume();
95 }
96
97 return r;
98}
99
100template <class TagName>
102 if (isPaused()) // calling twice pause() is allowed
103 return;
104
105 TopOfTheStack();
106
107 timer_->stop();
108 isPaused_ = true;
109}
110
111template <class TagName>
113 TopOfTheStack();
114
115 // no 'shortcut' test necessary:
116 // - if timer is stop, it is in pause (cannot be stop and not in pause because this timer is the head of the stack).
117 // - if timer is running, nothing is changed by this function.
118
119 timer_->start(false);
120 isPaused_ = false;
121}
122
123template <class TagName>
125 if (timer_->isRunning()) {
126 // TEUCHOS_TEST_FOR_EXCEPTION(timerStack_.top() != this, Exceptions::RuntimeError,
127 // "MueLu::MutuallyExclusiveTime::isRunning(): this timer is active so it is supposed to be the head of the stack");
128 }
129 return timer_->isRunning();
130}
131
132template <class TagName>
134 TEUCHOS_TEST_FOR_EXCEPTION(isPaused_ && timer_->isRunning(), Exceptions::RuntimeError, "");
135 return isPaused_;
136}
137
138template <class TagName>
139RCP<MutuallyExclusiveTime<TagName> > MutuallyExclusiveTime<TagName>::getNewTimer(const std::string& name) {
140 RCP<MutuallyExclusiveTime<TagName> > timer = rcp(new MutuallyExclusiveTime<TagName>(Teuchos::TimeMonitor::getNewTimer(name)));
141 timer->name_ = name;
142 return timer;
143}
144
145template <class TagName>
146void MutuallyExclusiveTime<TagName>::incrementNumCalls() { timer_->incrementNumCalls(); }
147
148template <class TagName>
150 // key is child, value is parent
151 RCP<Teuchos::FancyOStream> fos = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
152 fos->setOutputToRootOnly(0);
153 *fos << "Parent Child Map" << std::endl;
154 std::map<std::string, std::string>::const_iterator iter;
155 for (iter = ::MueLu::myParent_.begin(); iter != ::MueLu::myParent_.end(); ++iter) {
156 *fos << "Key: " << iter->first << " Value: " << iter->second << std::endl;
157 }
158}
159
160template <class TagName>
162 : timer_(timer)
163 , isPaused_(false) {}
164
165template <class TagName>
167 TEUCHOS_TEST_FOR_EXCEPTION(timerStack_.empty(), Exceptions::RuntimeError, "MueLu::MutuallyExclusiveTime::TopOfTheStack(): timer is not the head of the stack (stack is empty).");
168 // TEUCHOS_TEST_FOR_EXCEPTION(timerStack_.top() != this, Exceptions::RuntimeError, "MueLu::MutuallyExclusiveTime::TopOfTheStack(): timer is not the head of the stack.");
169 TEUCHOS_TEST_FOR_EXCEPTION(!(isRunning() || isPaused()), Exceptions::RuntimeError, "MueLu::MutuallyExclusiveTime::TopOfTheStack(): head of the stack timer is neither active nor paused.");
170}
171
172template <class TagName>
173std::stack<MutuallyExclusiveTime<TagName>*> MutuallyExclusiveTime<TagName>::timerStack_;
174
175// FIXME: move this:
177template class MutuallyExclusiveTime<Level>;
179
180} // namespace MueLu
Exception throws to report errors in the internal logical of the program.
This class wraps a Teuchos::Time and maintains a mutually exclusive property between wrapped timers.
void pause()
Pause running timer. Used internally by start().
void resume()
Resume paused timer. Used internally by stop(). Timer is not reset.
std::string name_
Name of this mutually exclusive timer.
MutuallyExclusiveTime(const std::string &name, bool startFlag=false)
Constructor.
double stop()
Stops the timer. The previous MutuallyExclusiveTime that has been paused when this timer was started ...
static RCP< MutuallyExclusiveTime< TagName > > getNewTimer(const std::string &name)
Return a new MutuallyExclusiveTime that is registered with the Teuchos::TimeMonitor (for timer summar...
void incrementNumCalls()
Increment the number of times this timer has been called.
void start(bool reset=false)
Starts the timer. If a MutuallyExclusiveTime timer is running, it will be stopped.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Namespace for MueLu classes and methods.
@ Debug
Print additional debugging information.
std::stack< MutuallyExclusiveTime< TagName > * > MutuallyExclusiveTime< TagName >::timerStack_
std::map< std::string, std::string > myParent_