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