Line data Source code
1 : /*
2 : * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Martin Rupp
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H_UG__PROFILE_NODE__
34 : #define __H_UG__PROFILE_NODE__
35 :
36 : #include <string>
37 : #include <vector>
38 : #include <sstream>
39 :
40 : namespace ug
41 : {
42 :
43 : /**
44 : * UGProfileNode class for more information about Shiny's ProfileNode.
45 : *
46 : * \note do NOT introduce variables or virtual functions to this class.
47 : * Shiny::ProfileNode are cast directly to UGProfileNode and therefore are
48 : * assumed to have exactly the same size and format.
49 : * If you really need to change that you'd have to change the whole GetProfileNode-process.
50 : */
51 : class UGProfileNode
52 : #if SHINY_PROFILER
53 : : public Shiny::ProfileNode
54 : #endif
55 : {
56 : public:
57 : /// \return number of entries in this profiler node
58 : double get_avg_entry_count() const;
59 :
60 : /// \return time in milliseconds spend in this node excluding subnodes
61 : double get_avg_self_time_ms() const;
62 :
63 : /// \return time in milliseconds spend in this node including subnodes
64 : double get_avg_total_time_ms() const;
65 :
66 : /// \return time in seconds spend in this node excluding subnodes
67 : double get_avg_self_time() const;
68 :
69 : /// \return time in seconds spend in this node including subnodes
70 : double get_avg_total_time() const;
71 :
72 : double get_self_mem() const;
73 : double get_total_mem() const;
74 :
75 : /**
76 : * @param dSkipMarginal nodes with full*dSkipMarginal > node->full[ms or mem] are skipped
77 : * @return call tree profile information
78 : */
79 : std::string call_tree(double dSkipMarginal) const;
80 0 : std::string call_tree() const { return call_tree(0.0); }
81 :
82 : /**
83 : * @param dSkipMarginal nodes with full*dSkipMarginal > node->full[ms or mem] are skipped
84 : * @return a table with all profile nodes information, sorted by self time
85 : */
86 : std::string child_self_time_sorted(double dSkipMarginal) const;
87 0 : std::string child_self_time_sorted() const { return child_self_time_sorted(0.0); }
88 :
89 : /**
90 : * @param dSkipMarginal nodes with full*dSkipMarginal > node->full[ms or mem] are skipped
91 : * @return a table with all profile nodes information, sorted by total time
92 : */
93 : std::string total_time_sorted(double dSkipMarginal) const;
94 0 : std::string total_time_sorted() const { return total_time_sorted(0.0); }
95 :
96 :
97 : /**
98 : * @param dSkipMarginal nodes with full*dSkipMarginal > node->full[ms or mem] are skipped
99 : * @return a table with all profile nodes information, sorted by self memory
100 : */
101 : std::string child_self_memory_sorted(double dSkipMarginal) const;
102 0 : std::string child_self_memory_sorted() const { return child_self_memory_sorted(0.0); }
103 :
104 : /**
105 : * @param dSkipMarginal nodes with full*dSkipMarginal > node->full[ms or mem] are skipped
106 : * @return a table with all profile nodes information, sorted by total memory
107 : */
108 : std::string total_memory_sorted(double dSkipMarginal) const;
109 0 : std::string total_memory_sorted() const { return total_memory_sorted(0.0); }
110 :
111 :
112 : /**
113 : * @param dSkipMarginal nodes with full*dSkipMarginal > node->full[ms or mem] are skipped
114 : * @return a table with all profile nodes information, sorted by entry count
115 : */
116 : std::string entry_count_sorted(double dSkipMarginal) const;
117 0 : std::string entry_count_sorted() const { return entry_count_sorted(0.0); }
118 :
119 : /**
120 : * @return Profiling group information
121 : */
122 : std::string groups() const;
123 :
124 : /// \return true if node has been found
125 : bool valid() const;
126 :
127 : static const UGProfileNode *get_root();
128 :
129 : static void CheckForTooSmallNodes();
130 : #if SHINY_PROFILER
131 :
132 : public:
133 : const UGProfileNode *get_first_child() const;
134 : const UGProfileNode *get_last_child() const;
135 : const UGProfileNode *get_next_sibling() const;
136 : const UGProfileNode *find_next_in_tree() const;
137 :
138 :
139 : /**
140 : * @brief writes this node and its subnodes in PDXML format to an ostream buffer
141 : * @param s ostream buffer
142 : */
143 : void PDXML_rec_write(std::ostream &s) const;
144 :
145 : /**
146 : * @brief prints the node information into a string
147 : * @param fullMs full time to calculate percentage of
148 : * @param fullMem full allocated mem to calculate percentage of
149 : * @param offset number of spaces to add from the left to get a tree-like structure (only applies to the name)
150 : * @return tabular node information
151 : */
152 : std::string print_node(double fullMs, double fullMem, size_t offset=0) const;
153 :
154 : /**
155 : * recursively adds this node and its subnodes to the array 'nodes'
156 : * @param nodes vector to push nodes into
157 : */
158 : void rec_add_nodes(std::vector<const UGProfileNode*> &nodes) const;
159 :
160 : static void log_header(std::stringstream &s, const char *name);
161 : private:
162 : void check_for_too_small_nodes(double fullMs, std::map<std::string, const UGProfileNode *> &list) const;
163 :
164 : /**
165 : * @brief prints the memory information to a node
166 : * @param fullMem full allocated mem to calculate percentage of
167 : */
168 : std::string get_mem_info(double fullMem) const;
169 :
170 :
171 : /**
172 : * @brief recursive print this node and its subnodes into stringstream s
173 : * @param fullMs full time to calculate percentage of
174 : * @param fullMem full allocated mem to calculate percentage of
175 : * @param s stringstream to print information into
176 : * @param offset number of spaces to add from the left to get a tree-like structure (only applies to the name)
177 : * @param dSkipMarginal if != 0.0, only nodes which have full*dSkipMarginal < this->total[ms or mem] are printed
178 : * @return
179 : */
180 : void rec_print(double fullMs, double fullMem, std::stringstream &s, size_t offset, double dSkipMarginal) const;
181 :
182 :
183 : /**
184 : * @param name the name of the table to print
185 : * @param sortFunction how to sort the table
186 : * @param dSkipMarginal if != 0.0, only nodes which have full*dSkipMarginal < this->total[ms or mem] are printed
187 : * @return table with sorted profiling information
188 : * @sa self_time_sort, total_time_sort, entry_count_sort, self_memory_sort, total_memory_sort
189 : */
190 : std::string print_child_sorted(const char *name, bool sortFunction(const UGProfileNode *a, const UGProfileNode *b),
191 : double dSkipMarginal) const;
192 :
193 : // sort functions
194 : static bool self_time_sort(const UGProfileNode *a, const UGProfileNode *b);
195 : static bool total_time_sort(const UGProfileNode *a, const UGProfileNode *b);
196 : static bool self_memory_sort(const UGProfileNode *a, const UGProfileNode *b);
197 : static bool total_memory_sort(const UGProfileNode *a, const UGProfileNode *b);
198 : static bool entry_count_sort(const UGProfileNode *a, const UGProfileNode *b);
199 : #endif
200 :
201 : // do NOT add variables or virtual functions here (see above).
202 : };
203 :
204 :
205 : /// This singleton represents a UGProfileNode that has not been found.
206 : class UGProfileNodeNull
207 : : public UGProfileNode
208 : {
209 : public:
210 0 : static UGProfileNodeNull* getInstance()
211 : {
212 0 : static UGProfileNodeNull instance;
213 0 : return &instance;
214 : }
215 :
216 : private:
217 : UGProfileNodeNull() {};
218 : UGProfileNodeNull(UGProfileNodeNull const&); // do not implement
219 : void operator=(UGProfileNodeNull const&); // do not implement
220 : };
221 :
222 : #define PROFILER_NULL_NODE UGProfileNodeNull::getInstance()
223 :
224 :
225 : const UGProfileNode *GetProfileNode(const char *name);
226 : const UGProfileNode *GetProfileNode(const char *name, const UGProfileNode *node);
227 : bool GetProfilerAvailable();
228 :
229 : /// Writes profile data of process 0 to the specified file
230 : void WriteProfileDataXML(const char *filename);
231 :
232 : /// Writes profile data to the specified file
233 : /** Writes profile data of all procs (procId == -1) or of specified proc
234 : * (procId >= 0) to the specified file
235 : */
236 : void WriteProfileDataXML(const char *filename, int procId);
237 :
238 : void WriteCallLog(const char *filename);
239 : void WriteCallLog(const char *filename, int procId);
240 :
241 : }
242 :
243 :
244 : #endif /* __H_UG__PROFILE_NODE__ */
|