Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : /** 12 : * A node in the PerfGraph. Stores the timing for a particular section of code. 13 : * 14 : * The design here is that _children are automatically added and kept track of 15 : * within the Node - and only raw pointers are handed back out. 16 : */ 17 : 18 : #include "MooseTypes.h" 19 : #include "MemoryUtils.h" 20 : 21 : #include <chrono> 22 : #include <map> 23 : 24 : class PerfNode 25 : { 26 : public: 27 : /** 28 : * Create a PerfNode with the given ID 29 : */ 30 9465285 : PerfNode(const PerfID id) : _id(id), _total_time(0), _num_calls(0), _total_memory(0) {} 31 : 32 : /** 33 : * Get the ID of this Node 34 : */ 35 123069327 : PerfID id() const { return _id; } 36 : 37 : /** 38 : * Set the current start time 39 : */ 40 93796228 : void setStartTimeAndMemory(const std::chrono::time_point<std::chrono::steady_clock> time, 41 : const long int memory) 42 : { 43 93796228 : _start_time = time; 44 93796228 : _start_memory = memory; 45 93796228 : } 46 : 47 : /** 48 : * Get the currnet start time 49 : * Only makes sense if this node is running. 50 : */ 51 : const std::chrono::time_point<std::chrono::steady_clock> & startTime() const 52 : { 53 : return _start_time; 54 : } 55 : 56 : /** 57 : * Get the current start memory 58 : * Only makes sense if this node is running. 59 : */ 60 0 : const long unsigned int & startMemory() const { return _start_memory; } 61 : 62 : /** 63 : * Add some time into this Node by taking the difference with the time passed in 64 : */ 65 93715583 : void addTimeAndMemory(const std::chrono::time_point<std::chrono::steady_clock> time, 66 : const long int memory) 67 : { 68 93715583 : _total_time += time - _start_time; 69 93715583 : _total_memory += memory - _start_memory; 70 93715583 : } 71 : 72 : /** 73 : * Increments the number of calls 74 : */ 75 93315269 : void incrementNumCalls() { _num_calls++; } 76 : 77 : /** 78 : * Add some time into this Node 79 : */ 80 : void addTimeAndMemory(const std::chrono::steady_clock::duration time) { _total_time += time; } 81 : 82 : /** 83 : * Get a child node with the unique id given 84 : * 85 : * Note: this will automatically create the Node internally if it needs to. 86 : * 87 : * Implemented in header to allow for more optimization 88 : * 89 : * @param id The unique ID of the child node 90 : * @return The pointer to the child node 91 : */ 92 95254195 : PerfNode * getChild(const PerfID id) 93 : { 94 : // RHS insertion on purpose 95 95254195 : auto & child_node = _children[id]; 96 : 97 95254195 : if (!child_node) 98 9402530 : child_node = std::make_unique<PerfNode>(id); 99 : 100 95254195 : return child_node.get(); 101 : } 102 : 103 : /** 104 : * Get the children 105 : */ 106 30443864 : const std::map<PerfID, std::unique_ptr<PerfNode>> & children() const { return _children; } 107 : 108 : /** 109 : * Get the time this node took 110 : */ 111 : std::chrono::steady_clock::duration selfTime() const; 112 : /** 113 : * Get the time this node took in seconds 114 : */ 115 18631291 : Real selfTimeSec() const { return std::chrono::duration<Real>(selfTime()).count(); } 116 : /** 117 : * The average time this node took in seconds 118 : */ 119 809387 : Real selfTimeAvg() const { return selfTimeSec() / static_cast<Real>(numCalls()); } 120 : 121 : /** 122 : * The time this Node plus all of it's children took 123 : */ 124 : std::chrono::steady_clock::duration totalTime() const; 125 : /** 126 : * The time this Node plus all of its children took in seconds 127 : */ 128 20245197 : Real totalTimeSec() const { return std::chrono::duration<Real>(totalTime()).count(); } 129 : /** 130 : * The average time this Node plus all of its children took in seconds 131 : */ 132 809387 : Real totalTimeAvg() const { return totalTimeSec() / static_cast<Real>(numCalls()); } 133 : 134 : /** 135 : * Get the time this nodes children took 136 : */ 137 : std::chrono::steady_clock::duration childrenTime() const; 138 : /** 139 : * The time this node's children took in seconds 140 : */ 141 16198262 : Real childrenTimeSec() const { return std::chrono::duration<Real>(childrenTime()).count(); } 142 : 143 : /** 144 : * Get the number of times this node was called 145 : */ 146 18631291 : unsigned long int numCalls() const { return _num_calls; } 147 : 148 : /** 149 : * Get the amount of memory added by this node 150 : */ 151 : long int selfMemory() const; 152 : 153 : /** 154 : * Get the amount of memory added by this node 155 : */ 156 : long int childrenMemory() const; 157 : 158 : /** 159 : * Get the amount of memory added by this node 160 : */ 161 50519959 : long int totalMemory() const { return _total_memory; } 162 : 163 : private: 164 : /// The unique ID for the section this Node corresponds to 165 : const PerfID _id; 166 : 167 : /// The current start_time for this node (if it's on the stack) 168 : std::chrono::time_point<std::chrono::steady_clock> _start_time; 169 : 170 : /// The total elapsed time for this node 171 : std::chrono::steady_clock::duration _total_time; 172 : 173 : /// The starting memory for this node 174 : long unsigned int _start_memory; 175 : 176 : /// Number of times this node has been called 177 : long unsigned int _num_calls; 178 : 179 : /// The total memory added while this node is active 180 : long unsigned int _total_memory; 181 : 182 : /// Timers that are directly underneath this node 183 : std::map<PerfID, std::unique_ptr<PerfNode>> _children; 184 : 185 : friend void dataStore(std::ostream &, const std::unique_ptr<PerfNode> &, void *); 186 : friend void dataLoad(std::istream &, const std::unique_ptr<PerfNode> &, void *); 187 : }; 188 : 189 : void dataStore(std::ostream & stream, const std::unique_ptr<PerfNode> & node, void * context); 190 : void dataLoad(std::istream & stream, const std::unique_ptr<PerfNode> & node, void * context);