![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef moab_DEBUG_OUTPUT_HPP
00002 #define moab_DEBUG_OUTPUT_HPP
00003
00004 #include
00005 #include
00006 #include
00007 #include
00008 #include
00009
00010 #include "moab/Compiler.hpp"
00011 #include "moab/CpuTimer.hpp"
00012
00013 namespace moab
00014 {
00015
00016 class Range;
00017 class DebugOutputStream;
00018
00019 /**\brief Utility class for printing debug output
00020 *
00021 * This class implements line-oriented output. That is, it buffers
00022 * output data until a newline is encountered, at which point it
00023 * sends the output to the output stream followed by an explicit
00024 * flush, and optionally prefixed with the MPI rank.
00025 *
00026 * This class also implements a verbosity filter for all output.
00027 * The class instance has a verbosity limit. Each request
00028 * for output has an associated verbosity level. If the verbosity
00029 * level for the output is is less greater than the limit then
00030 * the output is discarded. By convetion a verbosity limit
00031 * of zero should indicate no output. Therefore all requests
00032 * for output should have an associated verbosity level greater
00033 * than or equal to one.
00034 *
00035 * \Note Any output not terminated with an newline character or
00036 * followed by later output containing a newline character
00037 * will not be flushed until the destructor is invoked.
00038 * \Note C++-style IO (i.e. std::ostream) is not supported because
00039 * it is necessarily inefficient for debug-type output. All
00040 * formatting (e.g. converting arguments to strings, etc.) must
00041 * be done even when output is disabled.
00042 */
00043 class DebugOutput
00044 {
00045
00046 public:
00047 /**
00048 *\param str Output stream to which to flush output
00049 *\param verbosity Verbosity limit.
00050 */
00051 DebugOutput( DebugOutputStream* str, unsigned verbosity = 0 );
00052 /**
00053 *\param str Output stream to which to flush output
00054 *\param rank MPI rank with which to prefix output.
00055 *\param verbosity Verbosity limit.
00056 */
00057 DebugOutput( DebugOutputStream* str, int rank, unsigned verbosity = 0 );
00058 /**
00059 *\param str Output stream to which to flush output
00060 *\param enabled Enable output: if not true, all output operations to nothing.
00061 */
00062 DebugOutput( FILE* str, unsigned verbosity = 0 );
00063 /**
00064 *\param str Output stream to which to flush output
00065 *\param rank MPI rank with which to prefix output.
00066 *\param verbosity Verbosity limit.
00067 */
00068 DebugOutput( FILE* str, int rank, unsigned verbosity = 0 );
00069 /**
00070 *\param str Output stream to which to flush output
00071 *\param verbosity Verbosity limit.
00072 */
00073 DebugOutput( std::ostream& str, unsigned verbosity = 0 );
00074 /**
00075 *\param str Output stream to which to flush output
00076 *\param rank MPI rank with which to prefix output.
00077 *\param verbosity Verbosity limit.
00078 */
00079 DebugOutput( std::ostream& str, int rank, unsigned verbosity = 0 );
00080
00081 /**
00082 *\param pfx Prefix for output
00083 *\param str Output stream to which to flush output
00084 *\param verbosity Verbosity limit.
00085 */
00086 DebugOutput( const char* pfx, DebugOutputStream* str, unsigned verbosity = 0 );
00087 /**
00088 *\param pfx Prefix for output
00089 *\param str Output stream to which to flush output
00090 *\param rank MPI rank with which to prefix output.
00091 *\param verbosity Verbosity limit.
00092 */
00093 DebugOutput( const char* pfx, DebugOutputStream* str, int rank, unsigned verbosity = 0 );
00094 /**
00095 *\param pfx Prefix for output
00096 *\param str Output stream to which to flush output
00097 *\param enabled Enable output: if not true, all output operations to nothing.
00098 */
00099 DebugOutput( const char* pfx, FILE* str, unsigned verbosity = 0 );
00100 /**
00101 *\param pfx Prefix for output
00102 *\param str Output stream to which to flush output
00103 *\param rank MPI rank with which to prefix output.
00104 *\param verbosity Verbosity limit.
00105 */
00106 DebugOutput( const char* pfx, FILE* str, int rank, unsigned verbosity = 0 );
00107 /**
00108 *\param pfx Prefix for output
00109 *\param str Output stream to which to flush output
00110 *\param verbosity Verbosity limit.
00111 */
00112 DebugOutput( const char* pfx, std::ostream& str, unsigned verbosity = 0 );
00113 /**
00114 *\param pfx Prefix for output
00115 *\param str Output stream to which to flush output
00116 *\param rank MPI rank with which to prefix output.
00117 *\param verbosity Verbosity limit.
00118 */
00119 DebugOutput( const char* pfx, std::ostream& str, int rank, unsigned verbosity = 0 );
00120
00121 DebugOutput( const DebugOutput& copy );
00122 DebugOutput& operator=( const DebugOutput& copy );
00123
00124 /**
00125 * Destructor flushes any remaining output that wasn't followed
00126 * by a newline character.
00127 */
00128 ~DebugOutput();
00129
00130 //!\brief Check if MPI rank has been set.
00131 bool have_rank() const
00132 {
00133 return mpiRank >= 0;
00134 }
00135 //!\brief Get MPI rank.
00136 int get_rank() const
00137 {
00138 return mpiRank;
00139 }
00140 //!\brief Set MPI rank.
00141 void set_rank( int rank )
00142 {
00143 mpiRank = rank;
00144 }
00145 //!\brief Set MPI rank to the rank of this proccess in MPI_COMM_WORLD,
00146 //! or zero if MOAB is build w/out MPI.
00147 void use_world_rank();
00148
00149 //!\brief Only print debug output from N processes
00150 void limit_output_to_first_N_procs( int N )
00151 {
00152 if( mpiRank >= N ) verbosityLimit = 0;
00153 }
00154
00155 //!\brief Get verbosity limit
00156 unsigned get_verbosity() const
00157 {
00158 return verbosityLimit;
00159 }
00160 //!\brief Set verbosity limit
00161 void set_verbosity( unsigned val )
00162 {
00163 verbosityLimit = val;
00164 }
00165
00166 //!\brief Get line prefix
00167 const std::string& get_prefix() const
00168 {
00169 return linePfx;
00170 }
00171 //!\brief Set line prefix
00172 void set_prefix( const std::string& str )
00173 {
00174 linePfx = str;
00175 }
00176
00177 //!\brief Output the specified string iff output is enabled.
00178 void print( int verbosity, const char* str )
00179 {
00180 if( check( verbosity ) ) print_real( str );
00181 }
00182
00183 //!\brief Output the specified string iff output is enabled.
00184 void print( int verbosity, const std::string& str )
00185 {
00186 if( check( verbosity ) ) print_real( str );
00187 }
00188
00189 //!\brief Output the specified printf-formatted output iff output is enabled
00190 inline void printf( int verbosity, const char* fmt, ... ) MB_PRINTF( 2 );
00191
00192 //!\brief Output the specified string iff output is enabled.
00193 //!
00194 //! Include current CPU time (as returned by clock()) in output.
00195 void tprint( int verbosity, const char* str )
00196 {
00197 if( check( verbosity ) ) tprint_real( str );
00198 }
00199
00200 //!\brief Output the specified string iff output is enabled.
00201 //!
00202 //! Include current CPU time (as returned by clock()) in output.
00203 void tprint( int verbosity, const std::string& str )
00204 {
00205 if( check( verbosity ) ) tprint_real( str );
00206 }
00207
00208 //!\brief Output the specified printf-formatted output iff output is enabled
00209 //!
00210 //! Include current CPU time (as returned by clock()) in output.
00211 inline void tprintf( int verbosity, const char* fmt, ... ) MB_PRINTF( 2 );
00212
00213 //!\brief Print the contents of a moab::Range
00214 //!\param pfx String to print after default class prefix and before range contents
00215 void print( int verbosity, const char* pfx, const Range& range )
00216 {
00217 if( check( verbosity ) ) list_range_real( pfx, range );
00218 }
00219 //!\brief Print the contents of a moab::Range
00220 void print( int verbosity, const Range& range )
00221 {
00222 if( check( verbosity ) ) list_range_real( 0, range );
00223 }
00224
00225 //!\brief Print the contents of a moab::Range as numerical values only
00226 //!\param pfx String to print after default class prefix and before range contents
00227 void print_ints( int verbosity, const char* pfx, const Range& range )
00228 {
00229 if( check( verbosity ) ) list_ints_real( pfx, range );
00230 }
00231 //!\brief Print the contents of a moab::Range as numerical values only
00232 void print_ints( int verbosity, const Range& range )
00233 {
00234 if( check( verbosity ) ) list_ints_real( 0, range );
00235 }
00236
00237 private:
00238 std::string linePfx;
00239 DebugOutputStream* outputImpl;
00240 int mpiRank;
00241 unsigned verbosityLimit;
00242 CpuTimer cpuTi;
00243
00244 void tprint();
00245
00246 void list_range_real( const char* pfx, const Range& range );
00247 void list_ints_real( const char* pfx, const Range& range );
00248 void print_real( const char* buffer );
00249 void print_real( const std::string& str );
00250 void tprint_real( const char* buffer );
00251 void tprint_real( const std::string& str );
00252
00253 // Function must be passed to copies of the same va_list because
00254 // a) it might have to call vs(n)printf twice, b) vs(n)printf modifies
00255 // the va_list such that it cannot be reused, and c) va_copy is not
00256 // (yet) portable (c99, no c++ standard).
00257 void print_real( const char* buffer, va_list args1, va_list args2 );
00258 void tprint_real( const char* buffer, va_list args1, va_list args2 );
00259 void process_line_buffer();
00260
00261 std::vector< char > lineBuffer;
00262
00263 inline bool check( unsigned verbosity )
00264 {
00265 return verbosity <= verbosityLimit;
00266 }
00267 };
00268
00269 class DebugOutputStream
00270 {
00271 protected:
00272 friend class DebugOutput;
00273 int referenceCount;
00274
00275 public:
00276 DebugOutputStream() : referenceCount( 1 ) {}
00277 virtual ~DebugOutputStream();
00278 virtual void println( const char* pfx, const char* str ) = 0;
00279 virtual void println( int rank, const char* pfx, const char* str ) = 0;
00280 };
00281
00282 void DebugOutput::printf( int verbosity, const char* fmt, ... )
00283 {
00284 if( check( verbosity ) )
00285 {
00286 va_list args1, args2;
00287 va_start( args1, fmt );
00288 va_start( args2, fmt );
00289 print_real( fmt, args1, args2 );
00290 va_end( args2 );
00291 va_end( args1 );
00292 }
00293 }
00294
00295 void DebugOutput::tprintf( int verbosity, const char* fmt, ... )
00296 {
00297 if( check( verbosity ) )
00298 {
00299 va_list args1, args2;
00300 va_start( args1, fmt );
00301 va_start( args2, fmt );
00302 tprint_real( fmt, args1, args2 );
00303 va_end( args2 );
00304 va_end( args1 );
00305 }
00306 }
00307
00308 } // namespace moab
00309
00310 #endif