aboutsummaryrefslogtreecommitdiff
path: root/Carpet/Timers/src/Timer.cc
blob: 50631c3748e2bcc6834a997a100db8d1771136b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <cassert>

#include <cctk.h>
#include <cctk_Parameters.h>

#include <Timer.hh>
#include <TimerTree.hh>



namespace Timers {
  
  using namespace std;
  
  /*********************************************************************
   Timer
  *********************************************************************/
  
  
  
  TimerTree main_timer_tree;
  TimerTree mode_timer_tree;
  
  
  
  /// Create a timer with a given name, but do not start it, and do
  /// not associate it with a point in the timer hierarchy.
  Timer::Timer(string name_p, int tree):
    d_name(name_p), d_tree(tree==0 ? &main_timer_tree : &mode_timer_tree)
  {
  }
  
  /// Destroy the timer
  Timer::~Timer()
  {
  }
  
  /// Insert the timer into the tree of timers as a child of the most
  /// recently started timer that has not been stopped. Don't start
  /// the timer. This routine ensures a timer is created even if it is
  /// never started.
  void Timer::instantiate()
  {
    TimerNode *current_timer = d_tree->current;
    if (not d_tree->root) return; // do nothing if there is no root
    assert(current_timer);
    current_timer->getChildTimer(name())->instantiate();
  }
  
  /// Start the timer and insert it into the tree of timers as a child
  /// of the most recently started timer that has not been stopped.
  void Timer::start()
  {
    TimerNode *current_timer = d_tree->current;
    if (not d_tree->root) return; // do nothing if there is no root
    assert(current_timer);
    current_timer->getChildTimer(name())->start();
  }
  
  /// Stop the timer - it must be the most recently started timer
  void Timer::stop()
  {
    TimerNode *current = d_tree->current;
    if (not d_tree->root) return; // do nothing if there is no root
    if (current->getName() != name())
      CCTK_VError(__LINE__, __FILE__, CCTK_THORNSTRING,
                  "Trying to stop enclosing timer '%s' before enclosed time '%s'",
                  name().c_str(), current->getName().c_str());
    current->stop();
  }
  
  /// Return the name of the timer
  string Timer::name() const
  {
    return d_name;
  }
  
  /// Return the current time of the timer as a double
  double Timer::getTime()
  {
    return d_tree->current->getTime();
  }
  
  void Timer::outputTree(string name)
  {
    DECLARE_CCTK_PARAMETERS;
    
    TimerNode *tt = main_timer_tree.root->getChildTimer(name.c_str());
    double total_avg, total_max;
    tt->getGlobalTime(total_avg, total_max);
    tt->print
      (cout, total_max, 0, threshold_percentage, output_precision);
    mode_timer_tree.root->getGlobalTime(total_avg, total_max);
    mode_timer_tree.root->print
      (cout, total_max, 0, threshold_percentage, output_precision);
  }
  
  void Timer::outputTreeXML()
  {
    DECLARE_CCTK_PARAMETERS;
    
    main_timer_tree.root->outputXML(out_dir, CCTK_MyProc(0));
  }
  
  
  
  extern "C"
  int Timer_Startup()
  {
    // This must happen before any Timer objects are created
    main_timer_tree.root = new TimerNode(&main_timer_tree, "main");
    main_timer_tree.current = 0; // No timer has been started yet
    main_timer_tree.root->start();
    
    mode_timer_tree.root = new TimerNode(&mode_timer_tree, "meta mode");
    mode_timer_tree.current = 0; // No timer has been started yet
    mode_timer_tree.root->start();
    
    return 0;
  }
  
  extern "C"
  int Timer_Shutdown()
  {
    // main_timer_tree.root->stop();
    // mode_timer_tree.root->stop();
    
    // Delete timer tree
    delete main_timer_tree.root; main_timer_tree.root = 0;
    delete mode_timer_tree.root; mode_timer_tree.root = 0;
    
    return 0;
  }
  
} // namespace Timers