LCOV - code coverage report
Current view: top level - include/utils - PerfNode.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 24 25 96.0 %
Date: 2025-07-17 01:28:37 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             :  * 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);

Generated by: LCOV version 1.14