aboutsummaryrefslogtreecommitdiff
path: root/Carpet/Carpet/src/TimerNode.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Carpet/Carpet/src/TimerNode.cc')
-rw-r--r--Carpet/Carpet/src/TimerNode.cc373
1 files changed, 0 insertions, 373 deletions
diff --git a/Carpet/Carpet/src/TimerNode.cc b/Carpet/Carpet/src/TimerNode.cc
deleted file mode 100644
index 93833a72d..000000000
--- a/Carpet/Carpet/src/TimerNode.cc
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- *
- * The MIT License
- *
- * Copyright (c) 1997-2010 Center for the Simulation of Accidental Fires and
- * Explosions (CSAFE), and Scientific Computing and Imaging Institute (SCI),
- * University of Utah.
- *
- * License for the specific language governing rights and limitations under
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * */
-
-#include <algorithm>
-#include <cassert>
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <map>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include <dist.hh>
-#include <mpi_string.hh>
-
-#include "TimerNode.hh"
-
-namespace Carpet {
-
- using namespace std;
-
- TimerNode::TimerNode(TimerTree *tree, string name):
- d_name(name), d_parent(0), d_tree(tree), d_running(0), timer(0)
- {
- }
-
- TimerNode::~TimerNode()
- {
- for(map<string,TimerNode*>::iterator iter=d_children.begin();
- iter!=d_children.end(); ++iter)
- {
- delete iter->second;
- }
- d_children.clear();
- delete timer;
- }
-
- string TimerNode::pathName() const
- {
- assert(d_parent != this);
- if (d_parent)
- return d_parent->pathName() + string("/") + getName();
- else
- return getName();
- }
-
- void TimerNode::instantiate()
- {
- assert(!d_running);
- d_parent = d_tree->current;
- d_tree->current = this;
- if (timer == 0)
- timer = new CactusTimer(pathName());
- d_tree->current = d_parent;
- }
-
- void TimerNode::start()
- {
- assert(!d_running);
-
- d_running = true;
- d_parent = d_tree->current;
- d_tree->current = this;
- if (timer == 0)
- timer = new CactusTimer(pathName());
- assert(timer);
- timer->start();
- }
-
- void TimerNode::stop()
- {
- assert(d_running);
-
- // A timer can only be stopped if it is the current timer
- if(this != d_tree->current)
- CCTK_VError (__LINE__, __FILE__, CCTK_THORNSTRING,
- "Tried to stop non-current timer '%s'", getName().c_str());
-
- timer->stop();
-
- d_running = false;
- d_tree->current = d_parent;
- }
-
- /// Get the name of the timer
- string TimerNode::getName() const
- {
- assert(d_name.length() > 0);
- return d_name;
- }
-
- /// Determine if the timer is running
- bool TimerNode::isRunning() const
- {
- return d_running;
- }
-
- /// Find the child timer that matches the name provided. If it is
- /// not found then a new timer with that name is allocated.
- TimerNode* TimerNode::getChildTimer(string name)
- {
- // Find child
- TimerNode *child=d_children[name];
-
- // If the pointer is null then allocate it
- if(child == 0)
- d_children[name] = child = new TimerNode(d_tree, name);
-
- return child;
- }
-
- /// Get the time measured by this timer
- double TimerNode::getTime()
- {
- return timer->getTime();
- }
-
- /// Get the global time measured by this timer
- void TimerNode::getGlobalTime(double& avg, double& max)
- {
- return timer->getGlobalTime(avg, max);
- }
-
- /// Get the names of all clocks of this timer
- vector<pair<string,string> > TimerNode::getAllTimerNames() const
- {
- return timer->getAllTimerNames();
- }
-
- /// Get the values of all clocks of this timer
- vector<double> TimerNode::getAllTimerValues()
- {
- return timer->getAllTimerValues();
- }
-
- /// Print this node and its children as an ASCII tree
- void TimerNode::print(ostream& out, double total, int level,
- double threshold, int precision)
- {
- string space;
-
- // Compute the level of indentation for this depth
- for(int i=0;i<level-1;i++)
- space += "| ";
-
- if (level != 0)
- space += "|_";
-
- const int pcw = 6;
- const int tw = 8;
- const int tnw = 40; // timer name
- const int vw = 9; // clock values
- const streamsize oldprecision = out.precision();
- const ios_base::fmtflags oldflags = out.flags();
-
- // const double t = getTime();
- double tavg, tmax;
- getGlobalTime(tavg, tmax);
- const vector<double> values = getAllTimerValues();
- const string hyphens = string(precision-1, '-');
- const string spaces = string(precision-1, ' ');
-
- if (level == 0)
- {
- const vector<pair<string,string> > names = getAllTimerNames();
-
- out << "--------" << hyphens
- << "--------" << hyphens
- << "--------" << hyphens
- << "--" << string(tnw, '-');
- for (size_t i=0; i<values.size(); ++i) {
- out << "--" << string(vw, '-');
- }
- out << "\n";
-
- // timer names
- out << "Time " << spaces
- << " Time " << spaces
- << " Imblnc " << spaces
- << " " << setw(tnw) << left << "Timer" << right;
- for (size_t i=0; i<names.size(); ++i) {
- out << " " << setw(vw) << names[i].first.substr(0,vw);
- }
- out << "\n";
-
- // timer units
- out << "percent " << spaces
- << " secs " << spaces
- << " percent" << spaces
- << " " << setw(tnw) << " ";
- for (size_t i=0; i<names.size(); ++i) {
- out << " " << setw(vw) << names[i].second.substr(0,vw);
- }
- out << "\n";
-
- out << "--------" << hyphens
- << "--------" << hyphens
- << "--------" << hyphens
- << "--" << string(tnw, '-');
- for (size_t i=0; i<values.size(); ++i) {
- out << "--" << string(vw, '-');
- }
- out << "\n";
- }
-
- // Print this timer value
- out << fixed << setw(pcw) << setprecision(precision)
- << 100.0 * tavg / total << "%"
- << " " << fixed << setw(tw) << setprecision(precision) << tavg
- << " " << fixed << setw(pcw) << setprecision(precision)
- << 100.0 * (1.0 - tavg / tmax) << "%"
- << " " << space << setw(max(size_t(0), tnw - space.length())) << left
- << d_name.substr(0, max(size_t(10), tnw - space.length())) << right;
- for (size_t i=0; i<values.size(); ++i) {
- out.unsetf(ios_base::floatfield);
- out << " " << setw(vw) << setprecision(vw-5) << values[i];
- }
- out << "\n";
-
- // TODO: Don't call getGlobalTime for all timers separately.
- // Instead, call a single function that takes a snapshot of all
- // timers, and reduces these snapshots to average and maximum.
- // While printing, access these snapshots.
-
- //double children_time = 0;
- double children_tavg = 0.0;
- bool printed_children = false;
-
- // Recursively print the children
- for(map<string,TimerNode*>::iterator iter = d_children.begin();
- iter != d_children.end(); iter++)
- {
- const string timername = iter->first;
- const string root_timername =
- CarpetLib::broadcast_string(dist::comm(), 0, timername);
- if (timername != root_timername) {
- CCTK_VError(__LINE__, __FILE__, CCTK_THORNSTRING,
- "Timers are inconsistent across processes: root process expects timer %s, this process has timer %s instead",
- root_timername.c_str(), timername.c_str());
- }
- double child_avg, child_max;
- iter->second->getGlobalTime(child_avg, child_max);
- if (child_max * 100.0 / total > threshold) {
- iter->second->print(out,total,level+1,threshold,precision);
- printed_children = true;
- }
- //children_time += iter->second->getTime();
- children_tavg += child_avg;
- }
- {
- const string timername = "[done]";
- const string root_timername =
- CarpetLib::broadcast_string(dist::comm(), 0, timername);
- if (timername != root_timername) {
- CCTK_VError(__LINE__, __FILE__, CCTK_THORNSTRING,
- "Timers are inconsistent across processes: root process expects timer %s, this process has timer %s instead",
- root_timername.c_str(), timername.c_str());
- }
- }
-
- if (d_children.size() > 0 && printed_children) {
- //const double untimed = t - children_time;
- const double untimed = tavg - children_tavg;
-
- if (100.0 * untimed / total > threshold) {
- // Print the untimed portion
- out << fixed << setw(pcw) << setprecision(1)
- << 100.0 * untimed / total << "%"
- << " " << fixed << setw(tw) << setprecision(1) << untimed
- << " "
- << " | " << space << "untimed" << "\n";
- }
- }
- out.precision (oldprecision);
- out.setf (oldflags);
-
- if (level == 0) {
- out << "--------" << hyphens
- << "--------" << hyphens
- << "--------" << hyphens
- << "--" << string(tnw, '-');
- for (size_t i=0; i<values.size(); ++i) {
- out << "--" << string(vw, '-');
- }
- out << "\n";
- }
- }
-
- void TimerNode::outputXML(const string &out_dir, int proc)
- {
- ostringstream filenamebuf;
- filenamebuf << out_dir << "/timertree." << proc << ".xml";
- string filenamestr = filenamebuf.str();
- const char * filename = filenamestr.c_str();
- ofstream file;
- file.open (filename, ios::out | ios::trunc);
-
- printXML(file,0);
-
- file.close();
- assert (file.good());
- }
-
- /// Print this node and its children as an XML file
- void TimerNode::printXML(ostream& out, int level)
- {
- string space;
-
- // Compute the level of indentation for this node
- for(int i=0;i<level;i++)
- space=space+" ";
-
- out << space << "<timer name = " << "\"" << escapeForXML(d_name) << "\"> ";
- out << getTime() << " ";
-
- // For compactness, only use multiple lines if there are children
- if (d_children.size() != 0)
- {
- out << "\n";
-
- // Recursively print the children
- for(map<string,TimerNode*>::iterator iter=d_children.begin();iter!=d_children.end();++iter)
- iter->second->printXML(out,level+1);
- out << space;
- }
-
- out << "</timer>" << "\n";
- }
-
- /// Make a string suitable for inclusion in an XML file
- string TimerNode::escapeForXML(const string &s) const
- {
- // XML attributes cannot contain unescaped angle-brackets. As a
- // simple solution to this, replace them with | characters.
-
- string s2(s);
- using std::string;
- using std::replace;
-
- replace(s2.begin(), s2.end(), '<', '|');
- replace(s2.begin(), s2.end(), '>', '|');
- replace(s2.begin(), s2.end(), '&', '|');
-
- return s2;
- }
-}