LCOV - code coverage report
Current view: top level - src/io - IODebugTrack.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 19 88 21.6 %
Date: 2020-12-16 07:07:30 Functions: 6 8 75.0 %
Branches: 12 212 5.7 %

           Branch data     Line data    Source code
       1                 :            : #include "IODebugTrack.hpp"
       2                 :            : #include "moab/Range.hpp"
       3                 :            : #include <iostream>
       4                 :            : #include <vector>
       5                 :            : #include <assert.h>
       6                 :            : 
       7                 :            : #ifdef MOAB_HAVE_MPI
       8                 :            : #include "moab_mpi.h"
       9                 :            : #endif
      10                 :            : 
      11                 :            : const char PFX[] = ">>> ";
      12                 :            : 
      13                 :            : namespace moab
      14                 :            : {
      15                 :            : 
      16                 :          0 : IODebugTrack::IODebugTrack( bool enabled, const std::string& name, std::ostream& output_stream,
      17                 :            :                             unsigned long table_size )
      18         [ #  # ]:          0 :     : enableOutput( enabled ), tableName( name ), ostr( output_stream ), maxSize( table_size ), haveMPI( false )
      19                 :            : {
      20                 :            : #ifdef MOAB_HAVE_MPI
      21         [ #  # ]:          0 :     MPI_Comm_rank( MPI_COMM_WORLD, &mpiRank );
      22                 :            : #else
      23                 :            :     mpiRank = 0;
      24                 :            : #endif
      25                 :          0 : }
      26                 :            : 
      27                 :        565 : IODebugTrack::IODebugTrack( bool enabled, const std::string& name, unsigned long table_size )
      28         [ +  - ]:        565 :     : enableOutput( enabled ), tableName( name ), ostr( std::cerr ), maxSize( table_size )
      29                 :            : {
      30                 :        565 :     mpiRank = 0;
      31                 :        565 :     haveMPI = false;
      32                 :            : #ifdef MOAB_HAVE_MPI
      33                 :        565 :     int have_init = 0;
      34         [ +  - ]:        565 :     MPI_Initialized( &have_init );
      35         [ +  + ]:        565 :     if( have_init )
      36                 :            :     {
      37                 :        284 :         haveMPI = true;
      38         [ +  - ]:        284 :         MPI_Comm_rank( MPI_COMM_WORLD, &mpiRank );
      39                 :            :     }
      40                 :            : #endif
      41                 :        565 : }
      42                 :            : 
      43 [ -  + ][ -  + ]:       1130 : IODebugTrack::~IODebugTrack()
      44                 :            : {
      45 [ -  + ][ #  # ]:        565 :     if( !enableOutput || mpiRank )  // only root prints gap summary
      46                 :            :         return;
      47                 :            : 
      48         [ #  # ]:          0 :     if( dataSet.empty() )
      49                 :            :     {
      50                 :          0 :         ostr << PFX << tableName << " : No Data Written!!!!" << std::endl;
      51                 :        565 :         return;
      52                 :            :     }
      53                 :            : 
      54                 :          0 :     std::list< DRange >::const_iterator i;
      55         [ #  # ]:          0 :     if( !maxSize )
      56                 :            :     {
      57         [ #  # ]:          0 :         for( i = dataSet.begin(); i != dataSet.end(); ++i )
      58         [ #  # ]:          0 :             if( i->end >= maxSize ) maxSize = i->end + 1;
      59                 :            :     }
      60                 :          0 :     Range processed;
      61                 :          0 :     Range::iterator h = processed.begin();
      62                 :          0 :     bool wrote_zero   = false;
      63         [ #  # ]:          0 :     for( i = dataSet.begin(); i != dataSet.end(); ++i )
      64                 :            :     {
      65                 :            :         // ranges cannot contain zero
      66         [ #  # ]:          0 :         assert( i->begin <= i->end );
      67         [ #  # ]:          0 :         if( i->begin )
      68                 :          0 :             h = processed.insert( h, i->begin, i->end );
      69                 :            :         else
      70                 :            :         {
      71                 :          0 :             wrote_zero = true;
      72         [ #  # ]:          0 :             if( i->end ) h = processed.insert( h, i->begin + 1, i->end );
      73                 :            :         }
      74                 :            :     }
      75                 :            : 
      76                 :            :     // ranges cannot contain zero
      77         [ #  # ]:          0 :     Range unprocessed;
      78         [ #  # ]:          0 :     if( maxSize > 1 ) unprocessed.insert( 1, maxSize - 1 );
      79                 :          0 :     unprocessed = subtract( unprocessed, processed );
      80         [ #  # ]:          0 :     if( unprocessed.empty() ) return;
      81                 :            : 
      82                 :          0 :     Range::const_pair_iterator j;
      83 [ #  # ][ #  # ]:          0 :     for( j = unprocessed.const_pair_begin(); j != unprocessed.const_pair_end(); ++j )
      84                 :            :     {
      85                 :          0 :         unsigned long b = j->first;
      86                 :          0 :         unsigned long e = j->second;
      87 [ #  # ][ #  # ]:          0 :         if( b == 1 && !wrote_zero ) b = 0;
      88                 :            : 
      89                 :          0 :         ostr << PFX << tableName << " : range not read/written: [" << b << "," << e << "]" << std::endl;
      90                 :          0 :         ostr.flush();
      91                 :          0 :     }
      92                 :          0 : }
      93                 :            : 
      94                 :        563 : void IODebugTrack::record_io( unsigned long begin, unsigned long count )
      95                 :            : {
      96 [ -  + ][ #  # ]:        563 :     if( enableOutput && count )
      97                 :            :     {
      98                 :          0 :         DRange ins = { begin, begin + count - 1, static_cast< long unsigned >( mpiRank ) };
      99         [ #  # ]:          0 :         record_io( ins );
     100                 :            :     }
     101                 :        563 : }
     102                 :            : 
     103                 :          0 : void IODebugTrack::record_io( DRange ins )
     104                 :            : {
     105         [ #  # ]:          0 :     if( !enableOutput ) return;
     106                 :            : 
     107                 :            :     // only root should get non-local data
     108 [ #  # ][ #  # ]:          0 :     assert( !mpiRank || ins.rank == (unsigned)mpiRank );
     109         [ #  # ]:          0 :     assert( ins.begin <= ins.end );
     110                 :            : 
     111                 :            :     // test for out-of-bounds write
     112 [ #  # ][ #  # ]:          0 :     if( maxSize && ins.end >= maxSize )
     113 [ #  # ][ #  # ]:          0 :         ostr << ": Out of bounds write on rank " << mpiRank << ": [" << ins.begin << "," << ins.end
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     114 [ #  # ][ #  # ]:          0 :              << "] >= " << maxSize << std::endl;
                 [ #  # ]
     115                 :            : 
     116                 :            :     // test for overlap with all existing ranges
     117         [ #  # ]:          0 :     std::list< DRange >::iterator i;
     118 [ #  # ][ #  # ]:          0 :     for( i = dataSet.begin(); i != dataSet.end(); ++i )
                 [ #  # ]
     119                 :            :     {
     120 [ #  # ][ #  # ]:          0 :         if( i->end >= ins.begin && i->begin <= ins.end )
         [ #  # ][ #  # ]
                 [ #  # ]
     121                 :            :         {  // if overlap
     122 [ #  # ][ #  # ]:          0 :             ostr << PFX << tableName;
     123 [ #  # ][ #  # ]:          0 :             if( i->rank == ins.rank )
     124                 :            :             {
     125 [ #  # ][ #  # ]:          0 :                 if( mpiRank == (int)ins.rank ) ostr << ": Local overwrite on rank " << mpiRank;
                 [ #  # ]
     126                 :            : 
     127                 :            :                 // otherwise should have been logged on remote proc, do nothing here
     128                 :            :             }
     129                 :            :             else
     130 [ #  # ][ #  # ]:          0 :                 ostr << ": Conflicting write for ranks " << i->rank << " and " << ins.rank;
         [ #  # ][ #  # ]
                 [ #  # ]
     131                 :            : 
     132 [ #  # ][ #  # ]:          0 :             ostr << ": [" << i->begin << "," << i->end << "] and [" << ins.begin << "," << ins.end << "]" << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     133         [ #  # ]:          0 :             ostr.flush();
     134                 :            :         }
     135                 :            :     }
     136                 :            : 
     137         [ #  # ]:          0 :     dataSet.push_back( ins );
     138                 :            : }
     139                 :            : 
     140                 :        660 : void IODebugTrack::all_reduce()
     141                 :            : {
     142                 :            : #ifdef MOAB_HAVE_MPI
     143 [ -  + ][ #  # ]:        660 :     if( !enableOutput || !haveMPI ) return;
     144                 :            : 
     145                 :            :     int commsize;
     146         [ #  # ]:          0 :     MPI_Comm_size( MPI_COMM_WORLD, &commsize );
     147                 :          0 :     int count = 3 * dataSet.size();
     148 [ #  # ][ #  # ]:          0 :     std::vector< int > displs( commsize ), counts( commsize );
     149 [ #  # ][ #  # ]:          0 :     MPI_Gather( &count, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, MPI_COMM_WORLD );
     150         [ #  # ]:          0 :     displs[0] = 0;
     151         [ #  # ]:          0 :     for( int i = 1; i < commsize; ++i )
     152 [ #  # ][ #  # ]:          0 :         displs[i] = displs[i - 1] + counts[i - 1];
                 [ #  # ]
     153 [ #  # ][ #  # ]:          0 :     int total = ( displs.back() + counts.back() ) / 3;
     154                 :          0 :     count /= 3;
     155                 :            : 
     156 [ #  # ][ #  # ]:          0 :     std::vector< DRange > send( dataSet.size() ), recv( total );
     157         [ #  # ]:          0 :     std::copy( dataSet.begin(), dataSet.end(), send.begin() );
     158 [ #  # ][ #  # ]:          0 :     MPI_Gatherv( (void*)&send[0], 3 * send.size(), MPI_UNSIGNED_LONG, (void*)&recv[0], &counts[0], &displs[0],
         [ #  # ][ #  # ]
     159         [ #  # ]:          0 :                  MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD );
     160                 :            : 
     161         [ #  # ]:          0 :     if( 0 == mpiRank )
     162                 :            :     {
     163         [ #  # ]:          0 :         for( int i = count; i < total; ++i )
     164 [ #  # ][ #  # ]:          0 :             record_io( recv[i] );
     165                 :            :     }
     166                 :            :     else
     167                 :            :     {
     168                 :          0 :         dataSet.clear();
     169                 :          0 :     }
     170                 :            : #endif
     171                 :            : }
     172                 :            : 
     173 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11