LCOV - code coverage report
Current view: top level - include/utils - PerfNode.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 24 25 96.0 %
Date: 2026-05-29 20:35:17 Functions: 14 15 93.3 %
Legend: Lines: hit not hit

          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);

Generated by: LCOV version 1.14