MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_MutuallyExclusiveTime.cpp
Go to the documentation of this file.
1// @HEADER
2//
3// ***********************************************************************
4//
5// MueLu: A package for multigrid based preconditioning
6// Copyright 2012 Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact
39// Jonathan Hu (jhu@sandia.gov)
40// Andrey Prokopenko (aprokop@sandia.gov)
41// Ray Tuminaro (rstumin@sandia.gov)
42//
43// ***********************************************************************
44//
45// @HEADER
46
47#include <map>
48#include <iostream> // for basic_ostream, etc
49#include <utility> // for pair
50#include "Teuchos_FancyOStream.hpp" // for basic_FancyOStream, etc
51#include "Teuchos_RCP.hpp" // for RCP::operator->, etc
52#include "Teuchos_TestForException.hpp" // for TEUCHOS_TEST_FOR_EXCEPTION
53#include "Teuchos_Time.hpp"
54#include "Teuchos_TimeMonitor.hpp"
55#include "MueLu_ConfigDefs.hpp"
56#include "MueLu_Exceptions.hpp"
57#include "MueLu_BaseClass.hpp"
58#include "MueLu_VerbosityLevel.hpp" // for MsgType::Debug, etc
60#include "MueLu_FactoryBase.hpp"
61#include "MueLu_Level.hpp"
62
63namespace MueLu {
64
65 std::map<std::string,std::string> myParent_;
66
67 template <class TagName>
68 MutuallyExclusiveTime<TagName>::MutuallyExclusiveTime(const std::string &name, bool startFlag)
69 : name_(name),
70 timer_(rcp(new Teuchos::Time(name, false))), // second argument is false in any case, because if start==true,
71 // timer has to be started by MutuallyExclusiveTime::start() instead of Teuchos::Time::start().
72 isPaused_(false)
73 {
74 if (startFlag == true) timer_->start();
75 }
76
77 template <class TagName>
79 // This timer can only be destroyed if it is not in the stack
80 if (isPaused()) {
81 // error message because cannot throw an exception in destructor
82 GetOStream(Errors) << "MutuallyExclusiveTime::~MutuallyExclusiveTime(): Error: destructor called on a paused timer." << std::endl;
83 //TODO: Even if timing results will be wrong, the timer can be removed from the stack to avoid a segmentation fault.
84 }
85
86 stop(); // if isRunning(), remove from the stack, resume previous timer
87 }
88
89 template <class TagName>
91 TEUCHOS_TEST_FOR_EXCEPTION(isPaused(), Exceptions::RuntimeError, "MueLu::MutuallyExclusiveTime::start(): timer is paused. Use resume().");
92
93 if (isRunning()) { return; } // If timer is already running, do not pause/push-in-the-stack/start the timer.
94 // Otherwise, something bad will happen when this.stop() will be called
95
96 // pause currently running timer
97 if (!timerStack_.empty()) {
98 GetOStream(Debug) << "pausing parent timer " << timerStack_.top()->name_ << std::endl;
99 timerStack_.top()->pause();
100 GetOStream(Debug) << "starting child timer " << this->name_ << std::endl;
101 myParent_[this->name_] = timerStack_.top()->name_;
102 } else {
103 GetOStream(Debug) << "starting orphan timer " << this->name_ << std::endl;
104 myParent_[this->name_] = "no parent";
105 }
106
107 // start this timer
108 timer_->start(reset);
109 timerStack_.push(this);
110 }
111
112 template <class TagName>
114 if(isPaused())
115 GetOStream(Errors) << "MueLu::MutuallyExclusiveTime::stop(): timer is paused. Use resume()" << std::endl;
116
117 if (!isRunning()) { return timer_->stop(); } // stop() can be called on stopped timer
118
119 // Here, timer is running, so it is the head of the stack
120 TopOfTheStack();
121
122 timerStack_.pop();
123 double r = timer_->stop();
124
125 if (!timerStack_.empty()) {
126 GetOStream(Debug) << "resuming timer " << timerStack_.top()->name_ << std::endl;
127 timerStack_.top()->resume();
128 }
129
130 return r;
131 }
132
133 template <class TagName>
135 if (isPaused()) // calling twice pause() is allowed
136 return;
137
138 TopOfTheStack();
139
140 timer_->stop();
141 isPaused_ = true;
142 }
143
144 template <class TagName>
146 TopOfTheStack();
147
148 // no 'shortcut' test necessary:
149 // - if timer is stop, it is in pause (cannot be stop and not in pause because this timer is the head of the stack).
150 // - if timer is running, nothing is changed by this function.
151
152 timer_->start(false);
153 isPaused_ = false;
154 }
155
156 template <class TagName>
158 if (timer_->isRunning()) {
159 // TEUCHOS_TEST_FOR_EXCEPTION(timerStack_.top() != this, Exceptions::RuntimeError,
160 // "MueLu::MutuallyExclusiveTime::isRunning(): this timer is active so it is supposed to be the head of the stack");
161 }
162 return timer_->isRunning();
163 }
164
165 template <class TagName>
167 TEUCHOS_TEST_FOR_EXCEPTION(isPaused_ && timer_->isRunning(), Exceptions::RuntimeError, "");
168 return isPaused_;
169 }
170
171 template <class TagName>
172 RCP<MutuallyExclusiveTime<TagName> > MutuallyExclusiveTime<TagName>::getNewTimer(const std::string& name) {
173 RCP<MutuallyExclusiveTime<TagName> > timer = rcp(new MutuallyExclusiveTime<TagName>(Teuchos::TimeMonitor::getNewTimer(name)));
174 timer->name_ = name;
175 return timer;
176 }
177
178 template <class TagName>
179 void MutuallyExclusiveTime<TagName>::incrementNumCalls() { timer_->incrementNumCalls(); }
180
181 template <class TagName>
183 //key is child, value is parent
184 RCP<Teuchos::FancyOStream> fos = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout)); fos->setOutputToRootOnly(0);
185 *fos << "Parent Child Map" << std::endl;
186 std::map<std::string, std::string >::const_iterator iter;
187 for (iter = ::MueLu::myParent_.begin(); iter != ::MueLu::myParent_.end(); ++iter) {
188 *fos << "Key: " << iter->first << " Value: " << iter->second << std::endl;
189 }
190 }
191
192 template <class TagName>
194 : timer_(timer), isPaused_(false)
195 { }
196
197 template <class TagName>
199 TEUCHOS_TEST_FOR_EXCEPTION(timerStack_.empty(), Exceptions::RuntimeError, "MueLu::MutuallyExclusiveTime::TopOfTheStack(): timer is not the head of the stack (stack is empty).");
200 // TEUCHOS_TEST_FOR_EXCEPTION(timerStack_.top() != this, Exceptions::RuntimeError, "MueLu::MutuallyExclusiveTime::TopOfTheStack(): timer is not the head of the stack.");
201 TEUCHOS_TEST_FOR_EXCEPTION(!(isRunning() || isPaused()), Exceptions::RuntimeError, "MueLu::MutuallyExclusiveTime::TopOfTheStack(): head of the stack timer is neither active nor paused.");
202 }
203
204 template <class TagName>
205 std::stack<MutuallyExclusiveTime<TagName>*> MutuallyExclusiveTime<TagName>::timerStack_;
206
207 //FIXME: move this:
209 template class MutuallyExclusiveTime<Level>;
211
212} // 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_