LCOV - code coverage report
Current view: top level - src - DebugOutput.hpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 26 49 53.1 %
Date: 2020-12-16 07:07:30 Functions: 10 15 66.7 %
Branches: 6 18 33.3 %

           Branch data     Line data    Source code
       1                 :            : #ifndef moab_DEBUG_OUTPUT_HPP
       2                 :            : #define moab_DEBUG_OUTPUT_HPP
       3                 :            : 
       4                 :            : #include <stdarg.h>
       5                 :            : #include <stdio.h>
       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                 :          0 :     bool have_rank() const
     132                 :            :     {
     133                 :          0 :         return mpiRank >= 0;
     134                 :            :     }
     135                 :            :     //!\brief Get MPI rank.
     136                 :          0 :     int get_rank() const
     137                 :            :     {
     138                 :          0 :         return mpiRank;
     139                 :            :     }
     140                 :            :     //!\brief Set MPI rank.
     141                 :         66 :     void set_rank( int rank )
     142                 :            :     {
     143                 :         66 :         mpiRank = rank;
     144                 :         66 :     }
     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                 :         69 :     void limit_output_to_first_N_procs( int N )
     151                 :            :     {
     152         [ -  + ]:         69 :         if( mpiRank >= N ) verbosityLimit = 0;
     153                 :         69 :     }
     154                 :            : 
     155                 :            :     //!\brief Get verbosity limit
     156                 :         20 :     unsigned get_verbosity() const
     157                 :            :     {
     158                 :         20 :         return verbosityLimit;
     159                 :            :     }
     160                 :            :     //!\brief Set verbosity limit
     161                 :          0 :     void set_verbosity( unsigned val )
     162                 :            :     {
     163                 :          0 :         verbosityLimit = val;
     164                 :          0 :     }
     165                 :            : 
     166                 :            :     //!\brief Get line prefix
     167                 :            :     const std::string& get_prefix() const
     168                 :            :     {
     169                 :            :         return linePfx;
     170                 :            :     }
     171                 :            :     //!\brief Set line prefix
     172                 :          0 :     void set_prefix( const std::string& str )
     173                 :            :     {
     174                 :          0 :         linePfx = str;
     175                 :          0 :     }
     176                 :            : 
     177                 :            :     //!\brief Output the specified string iff output is enabled.
     178                 :        576 :     void print( int verbosity, const char* str )
     179                 :            :     {
     180         [ -  + ]:        576 :         if( check( verbosity ) ) print_real( str );
     181                 :        576 :     }
     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                 :       1073 :     void tprint( int verbosity, const char* str )
     196                 :            :     {
     197         [ -  + ]:       1073 :         if( check( verbosity ) ) tprint_real( str );
     198                 :       1073 :     }
     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                 :        245 :     void print( int verbosity, const char* pfx, const Range& range )
     216                 :            :     {
     217         [ -  + ]:        245 :         if( check( verbosity ) ) list_range_real( pfx, range );
     218                 :        245 :     }
     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                 :          0 :     void print_ints( int verbosity, const char* pfx, const Range& range )
     228                 :            :     {
     229         [ #  # ]:          0 :         if( check( verbosity ) ) list_ints_real( pfx, range );
     230                 :          0 :     }
     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                 :       8843 :     inline bool check( unsigned verbosity )
     264                 :            :     {
     265                 :       8843 :         return verbosity <= verbosityLimit;
     266                 :            :     }
     267                 :            : };
     268                 :            : 
     269                 :            : class DebugOutputStream
     270                 :            : {
     271                 :            :   protected:
     272                 :            :     friend class DebugOutput;
     273                 :            :     int referenceCount;
     274                 :            : 
     275                 :            :   public:
     276                 :        175 :     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                 :       5749 : void DebugOutput::printf( int verbosity, const char* fmt, ... )
     283                 :            : {
     284         [ -  + ]:       5749 :     if( check( verbosity ) )
     285                 :            :     {
     286                 :            :         va_list args1, args2;
     287                 :          0 :         va_start( args1, fmt );
     288                 :          0 :         va_start( args2, fmt );
     289         [ #  # ]:          0 :         print_real( fmt, args1, args2 );
     290                 :          0 :         va_end( args2 );
     291                 :          0 :         va_end( args1 );
     292                 :            :     }
     293                 :       5749 : }
     294                 :            : 
     295                 :       1200 : void DebugOutput::tprintf( int verbosity, const char* fmt, ... )
     296                 :            : {
     297         [ -  + ]:       1200 :     if( check( verbosity ) )
     298                 :            :     {
     299                 :            :         va_list args1, args2;
     300                 :          0 :         va_start( args1, fmt );
     301                 :          0 :         va_start( args2, fmt );
     302         [ #  # ]:          0 :         tprint_real( fmt, args1, args2 );
     303                 :          0 :         va_end( args2 );
     304                 :          0 :         va_end( args1 );
     305                 :            :     }
     306                 :       1200 : }
     307                 :            : 
     308                 :            : }  // namespace moab
     309                 :            : 
     310                 :            : #endif

Generated by: LCOV version 1.11