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 : #include "GeneralRegistry.h" 13 : #include "MooseTypes.h" 14 : 15 : #include <mutex> 16 : 17 : // Forward Declarations 18 : class PerfGraph; 19 : class PerfGraphLivePrint; 20 : class PerfNode; 21 : void dataStore(std::ostream &, PerfGraph &, void *); 22 : 23 : namespace moose 24 : { 25 : namespace internal 26 : { 27 : class PerfGraphRegistry; 28 : class PerfGraphSectionInfo; 29 : } 30 : } 31 : 32 : namespace moose 33 : { 34 : namespace internal 35 : { 36 : 37 : /** 38 : * Used to hold metadata about the registered sections 39 : * Note: this is a class instead of a struct because structs 40 : * are not able to be created in place using emplace_back in 41 : * C++11. This will be fixed in C++20. 42 : */ 43 : class PerfGraphSectionInfo 44 : { 45 : public: 46 2037711 : PerfGraphSectionInfo() = default; 47 6624535 : PerfGraphSectionInfo(const PerfID id, 48 : const std::string & name, 49 : const unsigned int level, 50 : const std::string & live_message, 51 : const bool print_dots) 52 6624535 : : _id(id), _name(name), _level(level), _live_message(live_message), _print_dots(print_dots) 53 : { 54 6624535 : } 55 : 56 : /// Unique ID 57 : PerfID _id; 58 : 59 : /// The name 60 : std::string _name; 61 : 62 : /// Print level (verbosity level) 63 : unsigned int _level; 64 : 65 : /// Message to print while the section is running 66 : std::string _live_message; 67 : 68 : /// Whether or not to print dots while this section runs 69 : bool _print_dots; 70 : }; 71 : 72 : /** 73 : * Get the global PerfGraphRegistry singleton. 74 : */ 75 : PerfGraphRegistry & getPerfGraphRegistry(); 76 : 77 : /** 78 : * The place where all timed sections will be stored 79 : */ 80 : class PerfGraphRegistry : private GeneralRegistry<std::string, PerfGraphSectionInfo> 81 : { 82 : public: 83 : /** 84 : * Call to register a named section for timing. 85 : * 86 : * @param section_name The name of the code section to be timed 87 : * @param level The importance of the timer - lower is more important (0 will always come out) 88 : * @return The ID of the section - use when starting timing 89 : */ 90 : PerfID registerSection(const std::string & section_name, const unsigned int level); 91 : 92 : /** 93 : * Call to register a named section for timing. 94 : * 95 : * @param section_name The name of the code section to be timed 96 : * @param level The importance of the timer - lower is more important (0 will always come out) 97 : * @param live_message The message to be printed to the screen during execution 98 : * @param print_dots Whether or not progress dots should be printed for this section 99 : * @return The ID of the section - use when starting timing 100 : */ 101 : PerfID registerSection(const std::string & section_name, 102 : const unsigned int level, 103 : const std::string & live_message, 104 : const bool print_dots = true); 105 : 106 : /** 107 : * Given a name return the PerfID 108 : * @section_name The name of the section 109 : * @return the ID 110 : */ 111 99912052 : PerfID sectionID(const std::string & section_name) const { return id(section_name); } 112 : 113 : /** 114 : * Given a PerfID return the PerfGraphSectionInfo 115 : * @section_id The ID 116 : * @return The PerfGraphSectionInfo 117 : */ 118 6227252 : const PerfGraphSectionInfo & sectionInfo(const PerfID section_id) const 119 : { 120 6227252 : return item(section_id); 121 : } 122 : 123 : /** 124 : * Whether or not a section with that name has been registered 125 : * @section_name The name of the section 126 : * @return Whether or not it exists 127 : */ 128 91080830 : bool sectionExists(const std::string & section_name) const { return keyExists(section_name); } 129 : 130 : /** 131 : * Whether or not a section with that id has been registered 132 : * @section_id The ID 133 : * @return Whether or not it exists 134 : */ 135 : bool sectionExists(const PerfID section_id) const { return idExists(section_id); } 136 : 137 : /** 138 : * @return number of registered sections 139 : */ 140 103063 : std::size_t numSections() const { return size(); } 141 : 142 : private: 143 : PerfGraphRegistry(); 144 : 145 : /** 146 : * The internal function that actually carries out the registration 147 : */ 148 : PerfID actuallyRegisterSection(const std::string & section_name, 149 : const unsigned int level, 150 : const std::string & live_message, 151 : const bool print_dots = true); 152 : 153 : /** 154 : * Special accessor just for PerfGraph so that 155 : * no locking is needed in PerfGraph. This could 156 : * probably be removed once we have C++17 with shared_mutex 157 : * 158 : * This function is NOT threadsafe - but it is ok 159 : * for PerfGraph to call it because only the main 160 : * thread will be registering sections and only 161 : * the main thread will be running PerfGraph routines 162 : * 163 : * @return the PerfGraphSectionInfo associated with the section_id 164 : */ 165 158798652 : const PerfGraphSectionInfo & readSectionInfo(PerfID section_id) const 166 : { 167 158798652 : return itemNonLocking(section_id); 168 : }; 169 : 170 : /// So it can be constructed 171 : friend PerfGraphRegistry & getPerfGraphRegistry(); 172 : /// This is only here so that PerfGraph can access readSectionInfo 173 : friend PerfGraph; 174 : // For accessing _id_to_section_info when storing the PerfGraph 175 : friend void ::dataStore(std::ostream &, PerfGraph &, void *); 176 : }; 177 : 178 : } 179 : } 180 : 181 : void dataStore(std::ostream & stream, moose::internal::PerfGraphSectionInfo & info, void * context); 182 : void dataLoad(std::istream & stream, moose::internal::PerfGraphSectionInfo & info, void * context);