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__COMMON__DEBUG_ID_H
34 : #define __H__UG__COMMON__DEBUG_ID_H
35 : #include <vector>
36 : #include <map>
37 : #include <string>
38 : #include "common/util/crc32.h"
39 : #include <sstream>
40 :
41 : namespace ug{
42 :
43 : /// \addtogroup ugbase_common
44 : /// \{
45 :
46 : class DebugIDManager;
47 :
48 :
49 :
50 : // DebugID
51 : /**
52 : * A DebugID is an object to control the debug level of parts of the code.
53 : * It can be used in
54 : * - UG_SET_DEBUG_LEVEL
55 : * - UG_DEBUG_BEGIN/END (debugID, level)
56 : * - IF_DEBUG
57 : * - UG_DLOG(debugID, level, msg)
58 : *
59 : * ug4's standard DebugIDs are
60 : * APP, LIB_GRID, LIB_GRID_REFINER, LIB_DISC, LIB_DISC_ASSEMBLE, LIB_DISC_D3F,
61 : * LIB_DISC_MULTIGRID, LIB_DISC_NEWTON, LIB_DISC_LINKER, LIB_DISC_TRANSFER,
62 : * LIB_DISC_DISCRETE_FUNCTION, LIB_DISC_OUTPUT, LIB_DISC_OPERATOR_INVERSE,
63 : * LIB_ALG_LINEAR_OPERATOR, LIB_ALG_LINEAR_SOLVER, LIB_ALG_VECTOR,
64 : * LIB_ALG_MATRIX, LIB_ALG_AMG, LIB_PCL
65 : *
66 : * They are managed with \sa DebugIDManager.
67 : * You can define your own DebugID the following way:
68 : * In a cpp file:
69 : *
70 : \code{.cpp}
71 : DebugID DID_MYAPP("MyApp")
72 : DebugID DID_MYAPP_PARALLELIZATION("MyApp.Parallelization")
73 : \endcode{.cpp}
74 : *
75 : * Now to use it in other files you need to add there
76 : *
77 : \code{.cpp}
78 : extern DebugID DID_MYAPP, DID_MYAPP_PARALLELIZATION;
79 : ...
80 : UG_DLOG(DID_MYAPP, 3, "bla");
81 : \endcode{.cpp}
82 : *
83 : * Note that the DebugID OBJECT is called DID_MYAPP, but its string identifier
84 : * is "MyApp" (this is used in the script system). In LUA script you can do
85 : *
86 : * GetLogAssistant():set_debug_level("MyApp", 3)
87 : * or, with completion (UGIDE)
88 : * SetDebugLevel(debugID.MyApp, 3)
89 : *
90 : * \note The actual DebugID level is stored in DebugIDManager.
91 : *
92 : */
93 : class DebugID
94 : {
95 : public:
96 : /// registers the DebugID at DebugIDManager
97 : DebugID(const char *str);
98 :
99 :
100 : DebugID(uint32 hash) { m_hash = hash; }
101 : /// returns the debug level via GetDebugIDManager.
102 : inline int get_debug_level() const;
103 :
104 : /// sets the debug level via GetDebugIDManager.
105 : inline bool set_debug_level(int level);
106 :
107 : friend class DebugIDManager;
108 : private:
109 : uint32 m_hash;
110 : };
111 :
112 : // the list of ug4's standard DebugIDs.
113 : extern DebugID MAIN,
114 : APP,
115 : LIB_GRID,
116 : LIB_GRID_REFINER,
117 : LIB_DISC,
118 : LIB_DISC_ASSEMBLE,
119 : LIB_DISC_D3F,
120 : LIB_DISC_MULTIGRID,
121 : LIB_DISC_NEWTON,
122 : LIB_DISC_LINKER,
123 : LIB_DISC_TRANSFER,
124 : LIB_DISC_DISCRETE_FUNCTION,
125 : LIB_DISC_OUTPUT,
126 : LIB_DISC_OPERATOR_INVERSE,
127 : LIB_ALG_LINEAR_OPERATOR,
128 : LIB_ALG_LINEAR_SOLVER,
129 : LIB_ALG_VECTOR,
130 : LIB_ALG_MATRIX,
131 : LIB_ALG_AMG,
132 : LIB_PCL;
133 :
134 :
135 : /**
136 : * The DebugIDManager.
137 : * get, set debug level, get a list of available DebugIDs etc.
138 : */
139 : class DebugIDManager
140 : {
141 : private:
142 : /// returns the debug level of debugIDhash, -1 if not found
143 : inline int get_debug_level(uint32 debugIDhash) const
144 : {
145 : std::map<uint32, int>::const_iterator it = m_dbgLevels.find(debugIDhash);
146 0 : if(it == m_dbgLevels.end()) return -1;
147 0 : else return (*it).second;
148 : }
149 :
150 : /// sets the debug level of debugIDhash if registered to 'level'
151 : inline bool set_debug_level(uint32 debugIDhash, int level)
152 : {
153 : std::map<uint32, int>::iterator it = m_dbgLevels.find(debugIDhash);
154 0 : if(it == m_dbgLevels.end()) return false;
155 : else
156 : {
157 0 : (*it).second = level;
158 0 : return true;
159 : }
160 : }
161 : public:
162 : /// returns a reference to the single instance of LogAssistant
163 : static DebugIDManager& instance();
164 :
165 : /// returns true if there is a DebugID with name debugIDname
166 30 : inline bool debug_id_registered(const char *debugIDname) const
167 : {
168 30 : return m_dbgLevels.find(crc32(debugIDname)) != m_dbgLevels.end();
169 : }
170 : /// returns the debug level of debugID, -1 if not found
171 : inline int get_debug_level(const DebugID &debugID) const
172 : {
173 : return get_debug_level(debugID.m_hash);
174 : }
175 : /// returns the debug level of debugID, -1 if not found
176 0 : inline int get_debug_level(const char *debugID) const
177 : {
178 0 : return get_debug_level(crc32(debugID));
179 : }
180 :
181 : ///
182 : inline DebugID get_debug_id(const char *debugID) const
183 : {
184 : return DebugID(crc32(debugID));
185 : }
186 :
187 : inline DebugID get_or_create_debug_id(const char *debugID)
188 : {
189 : if(debug_id_registered(debugID)==false)
190 : register_debug_id(debugID);
191 : return DebugID(crc32(debugID));
192 : }
193 :
194 :
195 : /// sets the debug level of debugID if registered to 'level'
196 : inline bool set_debug_level(DebugID &debugID, int level)
197 : {
198 : return set_debug_level(debugID.m_hash, level);
199 : }
200 : /// sets the debug level of debugID if registered to 'level'
201 : bool set_debug_level(const char *debugID, int level);
202 :
203 :
204 : /// sets the debug level of all registered debugIDs to 'lev'
205 : bool set_debug_levels(int lev);
206 :
207 : /// returns a string describing all registered debugIDs.
208 0 : std::string get_registered_debug_IDs() const
209 : {
210 0 : std::stringstream str;
211 0 : str << "DebugIDs:\n";
212 0 : for(size_t i=0; i<m_dbgLevelIdentifiers.size(); i++)
213 0 : str << m_dbgLevelIdentifiers[i] << " : Level " << get_debug_level(m_dbgLevelIdentifiers[i].c_str()) << "\n";
214 0 : return str.str();
215 0 : }
216 :
217 : const std::vector<std::string> &get_registered_debug_IDs_arr() const
218 : {
219 : return m_dbgLevelIdentifiers;
220 : }
221 :
222 :
223 :
224 : bool register_debug_id(const char *debugID);
225 :
226 : private:
227 : std::vector<std::string> m_dbgLevelIdentifiers;
228 : std::map<uint32, int> m_dbgLevels;
229 : };
230 :
231 : inline DebugIDManager& GetDebugIDManager()
232 : {
233 31 : return DebugIDManager::instance();
234 : }
235 :
236 : inline int DebugID::get_debug_level() const
237 : {
238 : return GetDebugIDManager().get_debug_level(*this);
239 : }
240 : inline bool DebugID::set_debug_level(int level)
241 : {
242 : return GetDebugIDManager().set_debug_level(*this, level);
243 : }
244 :
245 : // TemporaryDebugLevel
246 : /// a helper object to temporary set debug levels in a given scope
247 : /**
248 : * A object of this class can be used to change a DebugID. The DebugID will
249 : * be re-set to the value before at destruction of the object.
250 : * This is especially useful if algorithms are calling other functions which
251 : * also have special DebugIDs levels. And you want to do a "debug debug".
252 : * example:
253 : \code{.cpp}
254 : UG_SET_DEBUG_LEVEL(LIB_GRID, 1);
255 :
256 : // DebugID LIB_GRID is now at level 1
257 : {
258 : TemporaryDebugLevel tdl(LIB_GRID, 5);
259 :
260 : // DebugID LIB_GRID is now at level 5
261 : MyFunction();
262 : }
263 :
264 : // DebugID LIB_GRID is now again at 1.
265 : \endcode
266 : * You can also specify differences:
267 : *
268 : \code{.cpp}
269 : TemporaryDebugLevel tdl(LIB_GRID, MY_DEBUG_ID, +1);
270 : // now LIB_GRID has the temporary debug level of MY_DEBUG_ID +1.
271 : */
272 : #ifdef UG_ENABLE_DEBUG_LOGS
273 : class TemporaryDebugLevel
274 : {
275 : DebugID &did;
276 :
277 : int m_prevDebugLevel;
278 : public:
279 : TemporaryDebugLevel(DebugID &debugID) : did(debugID)
280 : {
281 : m_prevDebugLevel = did.get_debug_level();
282 : }
283 :
284 : /// change the debugID level in this scope
285 : TemporaryDebugLevel(DebugID &debugID, int temporaryDebugLevel) : did(debugID)
286 : {
287 : m_prevDebugLevel = did.get_debug_level();
288 : did.set_debug_level(temporaryDebugLevel);
289 : }
290 :
291 : /// change the debugID level in this scope to another debugID plus some diff.
292 : TemporaryDebugLevel(DebugID &debugID, DebugID &debugSrc, int diff=0) : did(debugID)
293 : {
294 : m_prevDebugLevel = did.get_debug_level();
295 : did.set_debug_level(debugSrc.get_debug_level()+diff);
296 : }
297 :
298 : /// resets the debugID to the previous value.
299 : ~TemporaryDebugLevel()
300 : {
301 : did.set_debug_level(m_prevDebugLevel);
302 : }
303 :
304 : void set(int temporaryDebugLevel)
305 : {
306 : did.set_debug_level(temporaryDebugLevel);
307 : }
308 : };
309 : #else
310 : class TemporaryDebugLevel
311 : {
312 :
313 : public:
314 : TemporaryDebugLevel(DebugID &debugID){}
315 : /// change the debugID level in this scope
316 : TemporaryDebugLevel(DebugID &debugID, int temporaryDebugLevel){}
317 : /// change the debugID level in this scope to another debugID plus some diff.
318 : TemporaryDebugLevel(DebugID &debugID, DebugID &debugSrc, int diff=0){}
319 : /// resets the debugID to the previous value.
320 : ~TemporaryDebugLevel(){}
321 : void set(int temporaryDebugLevel){}
322 : };
323 : #endif
324 :
325 : // end group ugbase_common
326 : /// \}
327 :
328 : } // end namespace ug
329 : #endif /* __H__UG__COMMON__DEBUG_ID_H */
330 :
|