Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DebugOutput.hpp
Go to the documentation of this file.
1 #ifndef moab_DEBUG_OUTPUT_HPP 2 #define moab_DEBUG_OUTPUT_HPP 3  4 #include <cstdarg> 5 #include <cstdio> 6 #include <vector> 7 #include <iosfwd> 8 #include <string> 9  10 #include "moab/Compiler.hpp" 11 #include "moab/CpuTimer.hpp" 12  13 namespace moab 14 { 15  16 class Range; 17 class DebugOutputStream; 18  19 /**\brief Utility class for printing debug output 20  * 21  * This class implements line-oriented output. That is, it buffers 22  * output data until a newline is encountered, at which point it 23  * sends the output to the output stream followed by an explicit 24  * flush, and optionally prefixed with the MPI rank. 25  * 26  * This class also implements a verbosity filter for all output. 27  * The class instance has a verbosity limit. Each request 28  * for output has an associated verbosity level. If the verbosity 29  * level for the output is is less greater than the limit then 30  * the output is discarded. By convetion a verbosity limit 31  * of zero should indicate no output. Therefore all requests 32  * for output should have an associated verbosity level greater 33  * than or equal to one. 34  * 35  * \Note Any output not terminated with an newline character or 36  * followed by later output containing a newline character 37  * will not be flushed until the destructor is invoked. 38  * \Note C++-style IO (i.e. std::ostream) is not supported because 39  * it is necessarily inefficient for debug-type output. All 40  * formatting (e.g. converting arguments to strings, etc.) must 41  * be done even when output is disabled. 42  */ 43 class DebugOutput 44 { 45  46  public: 47  /** 48  *\param str Output stream to which to flush output 49  *\param verbosity Verbosity limit. 50  */ 51  DebugOutput( DebugOutputStream* str, unsigned verbosity = 0 ); 52  /** 53  *\param str Output stream to which to flush output 54  *\param rank MPI rank with which to prefix output. 55  *\param verbosity Verbosity limit. 56  */ 57  DebugOutput( DebugOutputStream* str, int rank, unsigned verbosity = 0 ); 58  /** 59  *\param str Output stream to which to flush output 60  *\param enabled Enable output: if not true, all output operations to nothing. 61  */ 62  DebugOutput( FILE* str, unsigned verbosity = 0 ); 63  /** 64  *\param str Output stream to which to flush output 65  *\param rank MPI rank with which to prefix output. 66  *\param verbosity Verbosity limit. 67  */ 68  DebugOutput( FILE* str, int rank, unsigned verbosity = 0 ); 69  /** 70  *\param str Output stream to which to flush output 71  *\param verbosity Verbosity limit. 72  */ 73  DebugOutput( std::ostream& str, unsigned verbosity = 0 ); 74  /** 75  *\param str Output stream to which to flush output 76  *\param rank MPI rank with which to prefix output. 77  *\param verbosity Verbosity limit. 78  */ 79  DebugOutput( std::ostream& str, int rank, unsigned verbosity = 0 ); 80  81  /** 82  *\param pfx Prefix for output 83  *\param str Output stream to which to flush output 84  *\param verbosity Verbosity limit. 85  */ 86  DebugOutput( const char* pfx, DebugOutputStream* str, unsigned verbosity = 0 ); 87  /** 88  *\param pfx Prefix for output 89  *\param str Output stream to which to flush output 90  *\param rank MPI rank with which to prefix output. 91  *\param verbosity Verbosity limit. 92  */ 93  DebugOutput( const char* pfx, DebugOutputStream* str, int rank, unsigned verbosity = 0 ); 94  /** 95  *\param pfx Prefix for output 96  *\param str Output stream to which to flush output 97  *\param enabled Enable output: if not true, all output operations to nothing. 98  */ 99  DebugOutput( const char* pfx, FILE* str, unsigned verbosity = 0 ); 100  /** 101  *\param pfx Prefix for output 102  *\param str Output stream to which to flush output 103  *\param rank MPI rank with which to prefix output. 104  *\param verbosity Verbosity limit. 105  */ 106  DebugOutput( const char* pfx, FILE* str, int rank, unsigned verbosity = 0 ); 107  /** 108  *\param pfx Prefix for output 109  *\param str Output stream to which to flush output 110  *\param verbosity Verbosity limit. 111  */ 112  DebugOutput( const char* pfx, std::ostream& str, unsigned verbosity = 0 ); 113  /** 114  *\param pfx Prefix for output 115  *\param str Output stream to which to flush output 116  *\param rank MPI rank with which to prefix output. 117  *\param verbosity Verbosity limit. 118  */ 119  DebugOutput( const char* pfx, std::ostream& str, int rank, unsigned verbosity = 0 ); 120  121  DebugOutput( const DebugOutput& copy ); 122  DebugOutput& operator=( const DebugOutput& copy ); 123  124  /** 125  * Destructor flushes any remaining output that wasn't followed 126  * by a newline character. 127  */ 128  ~DebugOutput(); 129  130  //!\brief Check if MPI rank has been set. 131  bool have_rank() const 132  { 133  return mpiRank >= 0; 134  } 135  //!\brief Get MPI rank. 136  int get_rank() const 137  { 138  return mpiRank; 139  } 140  //!\brief Set MPI rank. 141  void set_rank( int rank ) 142  { 143  mpiRank = rank; 144  } 145  //!\brief Set MPI rank to the rank of this proccess in MPI_COMM_WORLD, 146  //! or zero if MOAB is build w/out MPI. 147  void use_world_rank(); 148  149  //!\brief Only print debug output from N processes 150  void limit_output_to_first_N_procs( int N ) 151  { 152  if( mpiRank >= N ) verbosityLimit = 0; 153  } 154  155  //!\brief Get verbosity limit 156  unsigned get_verbosity() const 157  { 158  return verbosityLimit; 159  } 160  //!\brief Set verbosity limit 161  void set_verbosity( unsigned val ) 162  { 163  verbosityLimit = val; 164  } 165  166  //!\brief Get line prefix 167  const std::string& get_prefix() const 168  { 169  return linePfx; 170  } 171  //!\brief Set line prefix 172  void set_prefix( const std::string& str ) 173  { 174  linePfx = str; 175  } 176  177  //!\brief Output the specified string iff output is enabled. 178  void print( int verbosity, const char* str ) 179  { 180  if( check( verbosity ) ) print_real( str ); 181  } 182  183  //!\brief Output the specified string iff output is enabled. 184  void print( int verbosity, const std::string& str ) 185  { 186  if( check( verbosity ) ) print_real( str ); 187  } 188  189  //!\brief Output the specified printf-formatted output iff output is enabled 190  inline void printf( int verbosity, const char* fmt, ... ) MB_PRINTF( 2 ); 191  192  //!\brief Output the specified string iff output is enabled. 193  //! 194  //! Include current CPU time (as returned by clock()) in output. 195  void tprint( int verbosity, const char* str ) 196  { 197  if( check( verbosity ) ) tprint_real( str ); 198  } 199  200  //!\brief Output the specified string iff output is enabled. 201  //! 202  //! Include current CPU time (as returned by clock()) in output. 203  void tprint( int verbosity, const std::string& str ) 204  { 205  if( check( verbosity ) ) tprint_real( str ); 206  } 207  208  //!\brief Output the specified printf-formatted output iff output is enabled 209  //! 210  //! Include current CPU time (as returned by clock()) in output. 211  inline void tprintf( int verbosity, const char* fmt, ... ) MB_PRINTF( 2 ); 212  213  //!\brief Print the contents of a moab::Range 214  //!\param pfx String to print after default class prefix and before range contents 215  void print( int verbosity, const char* pfx, const Range& range ) 216  { 217  if( check( verbosity ) ) list_range_real( pfx, range ); 218  } 219  //!\brief Print the contents of a moab::Range 220  void print( int verbosity, const Range& range ) 221  { 222  if( check( verbosity ) ) list_range_real( 0, range ); 223  } 224  225  //!\brief Print the contents of a moab::Range as numerical values only 226  //!\param pfx String to print after default class prefix and before range contents 227  void print_ints( int verbosity, const char* pfx, const Range& range ) 228  { 229  if( check( verbosity ) ) list_ints_real( pfx, range ); 230  } 231  //!\brief Print the contents of a moab::Range as numerical values only 232  void print_ints( int verbosity, const Range& range ) 233  { 234  if( check( verbosity ) ) list_ints_real( 0, range ); 235  } 236  237  private: 238  std::string linePfx; 239  DebugOutputStream* outputImpl; 240  int mpiRank; 241  unsigned verbosityLimit; 242  CpuTimer cpuTi; 243  244  void tprint(); 245  246  void list_range_real( const char* pfx, const Range& range ); 247  void list_ints_real( const char* pfx, const Range& range ); 248  void print_real( const char* buffer ); 249  void print_real( const std::string& str ); 250  void tprint_real( const char* buffer ); 251  void tprint_real( const std::string& str ); 252  253  // Function must be passed to copies of the same va_list because 254  // a) it might have to call vs(n)printf twice, b) vs(n)printf modifies 255  // the va_list such that it cannot be reused, and c) va_copy is not 256  // (yet) portable (c99, no c++ standard). 257  void print_real( const char* buffer, va_list args1, va_list args2 ); 258  void tprint_real( const char* buffer, va_list args1, va_list args2 ); 259  void process_line_buffer(); 260  261  std::vector< char > lineBuffer; 262  263  inline bool check( unsigned verbosity ) 264  { 265  return verbosity <= verbosityLimit; 266  } 267 }; 268  269 class DebugOutputStream 270 { 271  protected: 272  friend class DebugOutput; 273  int referenceCount; 274  275  public: 276  DebugOutputStream() : referenceCount( 1 ) {} 277  virtual ~DebugOutputStream(); 278  virtual void println( const char* pfx, const char* str ) = 0; 279  virtual void println( int rank, const char* pfx, const char* str ) = 0; 280 }; 281  282 void DebugOutput::printf( int verbosity, const char* fmt, ... ) 283 { 284  if( check( verbosity ) ) 285  { 286  va_list args1, args2; 287  va_start( args1, fmt ); 288  va_start( args2, fmt ); 289  print_real( fmt, args1, args2 ); 290  va_end( args2 ); 291  va_end( args1 ); 292  } 293 } 294  295 void DebugOutput::tprintf( int verbosity, const char* fmt, ... ) 296 { 297  if( check( verbosity ) ) 298  { 299  va_list args1, args2; 300  va_start( args1, fmt ); 301  va_start( args2, fmt ); 302  tprint_real( fmt, args1, args2 ); 303  va_end( args2 ); 304  va_end( args1 ); 305  } 306 } 307  308 } // namespace moab 309  310 #endif