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
moab::IODebugTrack Class Reference

Tool for debugging binary IO. More...

#include <IODebugTrack.hpp>

+ Collaboration diagram for moab::IODebugTrack:

Classes

struct  DRange
 

Public Member Functions

 IODebugTrack (bool enable, const std::string &table_name, std::ostream &output_stream, unsigned long table_size=0)
 Constuctor requires stream to which to log errors. More...
 
 IODebugTrack (bool enable, const std::string &table_name, unsigned long table_size=0)
 Constuctor requires stream to which to log errors. More...
 
 ~IODebugTrack ()
 Destructor prints errors about unaccessed ranges. More...
 
void record_io (unsigned long begin, unsigned long count)
 Notify of IO request. More...
 
void all_reduce ()
 Push all data to root process. More...
 

Private Member Functions

void record_io (DRange data)
 

Private Attributes

bool enableOutput
 
std::string tableName
 
std::list< DRangedataSet
 
std::ostream & ostr
 
unsigned long maxSize
 
int mpiRank
 
bool haveMPI
 

Detailed Description

Tool for debugging binary IO.

Track which ranges of a table of data have been read/written, watching for overlapping IO requests and ranges of unaccessed data.

Notes: This class assumes MPI_COMM_WORLD is the communicator for parallel.

Definition at line 20 of file IODebugTrack.hpp.

Constructor & Destructor Documentation

◆ IODebugTrack() [1/2]

moab::IODebugTrack::IODebugTrack ( bool  enable,
const std::string &  table_name,
std::ostream &  output_stream,
unsigned long  table_size = 0 
)

Constuctor requires stream to which to log errors.

Parameters
table_nameUsed to tag output
output_streamStream to which to print error messages
table_sizeMax table size. No limit if unspecified

Definition at line 16 of file IODebugTrack.cpp.

20  : enableOutput( enabled ), tableName( name ), ostr( output_stream ), maxSize( table_size ), haveMPI( false ) 21 { 22 #ifdef MOAB_HAVE_MPI 23  MPI_Comm_rank( MPI_COMM_WORLD, &mpiRank ); 24 #else 25  mpiRank = 0; 26 #endif 27 }

References mpiRank.

◆ IODebugTrack() [2/2]

moab::IODebugTrack::IODebugTrack ( bool  enable,
const std::string &  table_name,
unsigned long  table_size = 0 
)

Constuctor requires stream to which to log errors.

Parameters
table_nameUsed to tag output
table_sizeMax table size. No limit if unspecified

Definition at line 29 of file IODebugTrack.cpp.

30  : enableOutput( enabled ), tableName( name ), ostr( std::cerr ), maxSize( table_size ) 31 { 32  mpiRank = 0; 33  haveMPI = false; 34 #ifdef MOAB_HAVE_MPI 35  int have_init = 0; 36  MPI_Initialized( &have_init ); 37  if( have_init ) 38  { 39  haveMPI = true; 40  MPI_Comm_rank( MPI_COMM_WORLD, &mpiRank ); 41  } 42 #endif 43 }

References haveMPI, and mpiRank.

◆ ~IODebugTrack()

moab::IODebugTrack::~IODebugTrack ( )

Destructor prints errors about unaccessed ranges.

Definition at line 45 of file IODebugTrack.cpp.

46 { 47  if( !enableOutput || mpiRank ) // only root prints gap summary 48  return; 49  50  if( dataSet.empty() ) 51  { 52  ostr << PFX << tableName << " : No Data Written!!!!" << std::endl; 53  return; 54  } 55  56  std::list< DRange >::const_iterator i; 57  if( !maxSize ) 58  { 59  for( i = dataSet.begin(); i != dataSet.end(); ++i ) 60  if( i->end >= maxSize ) maxSize = i->end + 1; 61  } 62  Range processed; 63  Range::iterator h = processed.begin(); 64  bool wrote_zero = false; 65  for( i = dataSet.begin(); i != dataSet.end(); ++i ) 66  { 67  // ranges cannot contain zero 68  assert( i->begin <= i->end ); 69  if( i->begin ) 70  h = processed.insert( h, i->begin, i->end ); 71  else 72  { 73  wrote_zero = true; 74  if( i->end ) h = processed.insert( h, i->begin + 1, i->end ); 75  } 76  } 77  78  // ranges cannot contain zero 79  Range unprocessed; 80  if( maxSize > 1 ) unprocessed.insert( 1, maxSize - 1 ); 81  unprocessed = subtract( unprocessed, processed ); 82  if( unprocessed.empty() ) return; 83  84  Range::const_pair_iterator j; 85  for( j = unprocessed.const_pair_begin(); j != unprocessed.const_pair_end(); ++j ) 86  { 87  unsigned long b = j->first; 88  unsigned long e = j->second; 89  if( b == 1 && !wrote_zero ) b = 0; 90  91  ostr << PFX << tableName << " : range not read/written: [" << b << "," << e << "]" << std::endl; 92  ostr.flush(); 93  } 94 }

References moab::Range::begin(), moab::Range::const_pair_begin(), moab::Range::const_pair_end(), dataSet, moab::Range::empty(), enableOutput, moab::Range::insert(), maxSize, mpiRank, ostr, PFX, moab::subtract(), and tableName.

Member Function Documentation

◆ all_reduce()

void moab::IODebugTrack::all_reduce ( )

Push all data to root process.

Does nothing if MPI support is not enabled

Definition at line 142 of file IODebugTrack.cpp.

143 { 144 #ifdef MOAB_HAVE_MPI 145  if( !enableOutput || !haveMPI ) return; 146  147  int commsize; 148  MPI_Comm_size( MPI_COMM_WORLD, &commsize ); 149  int count = 3 * dataSet.size(); 150  std::vector< int > displs( commsize ), counts( commsize ); 151  MPI_Gather( &count, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, MPI_COMM_WORLD ); 152  displs[0] = 0; 153  for( int i = 1; i < commsize; ++i ) 154  displs[i] = displs[i - 1] + counts[i - 1]; 155  int total = ( displs.back() + counts.back() ) / 3; 156  count /= 3; 157  158  std::vector< DRange > send( dataSet.size() ), recv( total ); 159  std::copy( dataSet.begin(), dataSet.end(), send.begin() ); 160  MPI_Gatherv( (void*)&send[0], 3 * send.size(), MPI_UNSIGNED_LONG, (void*)&recv[0], &counts[0], &displs[0], 161  MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD ); 162  163  if( 0 == mpiRank ) 164  { 165  for( int i = count; i < total; ++i ) 166  record_io( recv[i] ); 167  } 168  else 169  { 170  dataSet.clear(); 171  } 172 #endif 173 }

References dataSet, enableOutput, haveMPI, mpiRank, and record_io().

Referenced by moab::ReadHDF5::read_node_adj_elems(), moab::WriteHDF5::write_adjacencies(), moab::WriteHDF5::write_elems(), moab::WriteHDF5::write_nodes(), moab::WriteHDF5::write_sets(), moab::WriteHDF5::write_sparse_ids(), moab::WriteHDF5::write_sparse_tag(), moab::WriteHDF5::write_tag_values(), moab::WriteHDF5::write_var_len_data(), and moab::WriteHDF5::write_var_len_indices().

◆ record_io() [1/2]

void moab::IODebugTrack::record_io ( DRange  data)
private

Definition at line 105 of file IODebugTrack.cpp.

106 { 107  if( !enableOutput ) return; 108  109  // only root should get non-local data 110  assert( !mpiRank || ins.rank == (unsigned)mpiRank ); 111  assert( ins.begin <= ins.end ); 112  113  // test for out-of-bounds write 114  if( maxSize && ins.end >= maxSize ) 115  ostr << ": Out of bounds write on rank " << mpiRank << ": [" << ins.begin << "," << ins.end 116  << "] >= " << maxSize << std::endl; 117  118  // test for overlap with all existing ranges 119  std::list< DRange >::iterator i; 120  for( i = dataSet.begin(); i != dataSet.end(); ++i ) 121  { 122  if( i->end >= ins.begin && i->begin <= ins.end ) 123  { // if overlap 124  ostr << PFX << tableName; 125  if( i->rank == ins.rank ) 126  { 127  if( mpiRank == (int)ins.rank ) ostr << ": Local overwrite on rank " << mpiRank; 128  129  // otherwise should have been logged on remote proc, do nothing here 130  } 131  else 132  ostr << ": Conflicting write for ranks " << i->rank << " and " << ins.rank; 133  134  ostr << ": [" << i->begin << "," << i->end << "] and [" << ins.begin << "," << ins.end << "]" << std::endl; 135  ostr.flush(); 136  } 137  } 138  139  dataSet.push_back( ins ); 140 }

References moab::IODebugTrack::DRange::begin, dataSet, enableOutput, moab::IODebugTrack::DRange::end, maxSize, mpiRank, ostr, PFX, moab::IODebugTrack::DRange::rank, and tableName.

Referenced by all_reduce(), moab::ReadHDF5::read_node_adj_elems(), record_io(), moab::WriteHDF5::write_adjacencies(), moab::WriteHDF5::write_elems(), moab::WriteHDF5::write_nodes(), moab::WriteHDF5::write_set_data(), moab::WriteHDF5::write_sets(), moab::WriteHDF5::write_sparse_ids(), moab::WriteHDF5::write_tag_values(), moab::WriteHDF5::write_var_len_data(), and moab::WriteHDF5::write_var_len_indices().

◆ record_io() [2/2]

void moab::IODebugTrack::record_io ( unsigned long  begin,
unsigned long  count 
)

Notify of IO request.

Parameters
beginFirst table row being read/written
countNum consecutive table rows being read/written

Definition at line 96 of file IODebugTrack.cpp.

97 { 98  if( enableOutput && count ) 99  { 100  DRange ins = { begin, begin + count - 1, static_cast< long unsigned >( mpiRank ) }; 101  record_io( ins ); 102  } 103 }

References enableOutput, mpiRank, and record_io().

Member Data Documentation

◆ dataSet

std::list< DRange > moab::IODebugTrack::dataSet
private

Definition at line 32 of file IODebugTrack.hpp.

Referenced by all_reduce(), record_io(), and ~IODebugTrack().

◆ enableOutput

bool moab::IODebugTrack::enableOutput
private

Definition at line 30 of file IODebugTrack.hpp.

Referenced by all_reduce(), record_io(), and ~IODebugTrack().

◆ haveMPI

bool moab::IODebugTrack::haveMPI
private

Definition at line 36 of file IODebugTrack.hpp.

Referenced by all_reduce(), and IODebugTrack().

◆ maxSize

unsigned long moab::IODebugTrack::maxSize
private

Definition at line 34 of file IODebugTrack.hpp.

Referenced by record_io(), and ~IODebugTrack().

◆ mpiRank

int moab::IODebugTrack::mpiRank
private

Definition at line 35 of file IODebugTrack.hpp.

Referenced by all_reduce(), IODebugTrack(), record_io(), and ~IODebugTrack().

◆ ostr

std::ostream& moab::IODebugTrack::ostr
private

Definition at line 33 of file IODebugTrack.hpp.

Referenced by record_io(), and ~IODebugTrack().

◆ tableName

std::string moab::IODebugTrack::tableName
private

Definition at line 31 of file IODebugTrack.hpp.

Referenced by record_io(), and ~IODebugTrack().


The documentation for this class was generated from the following files: