Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
Tool for debugging binary IO. More...
#include <IODebugTrack.hpp>
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. | |
IODebugTrack (bool enable, const std::string &table_name, unsigned long table_size=0) | |
Constuctor requires stream to which to log errors. | |
~IODebugTrack () | |
Destructor prints errors about unaccessed ranges. | |
void | record_io (unsigned long begin, unsigned long count) |
Notify of IO request. | |
void | all_reduce () |
Push all data to root process. | |
Private Member Functions | |
void | record_io (DRange data) |
Private Attributes | |
bool | enableOutput |
std::string | tableName |
std::list< DRange > | dataSet |
std::ostream & | ostr |
unsigned long | maxSize |
int | mpiRank |
bool | haveMPI |
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.
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.
table_name | Used to tag output |
output_stream | Stream to which to print error messages |
table_size | Max table size. No limit if unspecified |
Definition at line 16 of file IODebugTrack.cpp.
References mpiRank.
moab::IODebugTrack::IODebugTrack | ( | bool | enable, |
const std::string & | table_name, | ||
unsigned long | table_size = 0 |
||
) |
Constuctor requires stream to which to log errors.
table_name | Used to tag output |
table_size | Max table size. No limit if unspecified |
Definition at line 29 of file IODebugTrack.cpp.
Destructor prints errors about unaccessed ranges.
Definition at line 45 of file IODebugTrack.cpp.
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.
{ if( !enableOutput || mpiRank ) // only root prints gap summary return; if( dataSet.empty() ) { ostr << PFX << tableName << " : No Data Written!!!!" << std::endl; return; } std::list< DRange >::const_iterator i; if( !maxSize ) { for( i = dataSet.begin(); i != dataSet.end(); ++i ) if( i->end >= maxSize ) maxSize = i->end + 1; } Range processed; Range::iterator h = processed.begin(); bool wrote_zero = false; for( i = dataSet.begin(); i != dataSet.end(); ++i ) { // ranges cannot contain zero assert( i->begin <= i->end ); if( i->begin ) h = processed.insert( h, i->begin, i->end ); else { wrote_zero = true; if( i->end ) h = processed.insert( h, i->begin + 1, i->end ); } } // ranges cannot contain zero Range unprocessed; if( maxSize > 1 ) unprocessed.insert( 1, maxSize - 1 ); unprocessed = subtract( unprocessed, processed ); if( unprocessed.empty() ) return; Range::const_pair_iterator j; for( j = unprocessed.const_pair_begin(); j != unprocessed.const_pair_end(); ++j ) { unsigned long b = j->first; unsigned long e = j->second; if( b == 1 && !wrote_zero ) b = 0; ostr << PFX << tableName << " : range not read/written: [" << b << "," << e << "]" << std::endl; ostr.flush(); } }
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.
References dataSet, enableOutput, haveMPI, mpiRank, and record_io().
Referenced by moab::ReadHDF5::read_node_adj_elems(), moab::WriteHDF5::write_adjacencies(), 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().
{ #ifdef MOAB_HAVE_MPI if( !enableOutput || !haveMPI ) return; int commsize; MPI_Comm_size( MPI_COMM_WORLD, &commsize ); int count = 3 * dataSet.size(); std::vector< int > displs( commsize ), counts( commsize ); MPI_Gather( &count, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, MPI_COMM_WORLD ); displs[0] = 0; for( int i = 1; i < commsize; ++i ) displs[i] = displs[i - 1] + counts[i - 1]; int total = ( displs.back() + counts.back() ) / 3; count /= 3; std::vector< DRange > send( dataSet.size() ), recv( total ); std::copy( dataSet.begin(), dataSet.end(), send.begin() ); MPI_Gatherv( (void*)&send[0], 3 * send.size(), MPI_UNSIGNED_LONG, (void*)&recv[0], &counts[0], &displs[0], MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD ); if( 0 == mpiRank ) { for( int i = count; i < total; ++i ) record_io( recv[i] ); } else { dataSet.clear(); } #endif }
void moab::IODebugTrack::record_io | ( | DRange | data | ) | [private] |
Definition at line 105 of file IODebugTrack.cpp.
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_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().
{ if( !enableOutput ) return; // only root should get non-local data assert( !mpiRank || ins.rank == (unsigned)mpiRank ); assert( ins.begin <= ins.end ); // test for out-of-bounds write if( maxSize && ins.end >= maxSize ) ostr << ": Out of bounds write on rank " << mpiRank << ": [" << ins.begin << "," << ins.end << "] >= " << maxSize << std::endl; // test for overlap with all existing ranges std::list< DRange >::iterator i; for( i = dataSet.begin(); i != dataSet.end(); ++i ) { if( i->end >= ins.begin && i->begin <= ins.end ) { // if overlap ostr << PFX << tableName; if( i->rank == ins.rank ) { if( mpiRank == (int)ins.rank ) ostr << ": Local overwrite on rank " << mpiRank; // otherwise should have been logged on remote proc, do nothing here } else ostr << ": Conflicting write for ranks " << i->rank << " and " << ins.rank; ostr << ": [" << i->begin << "," << i->end << "] and [" << ins.begin << "," << ins.end << "]" << std::endl; ostr.flush(); } } dataSet.push_back( ins ); }
void moab::IODebugTrack::record_io | ( | unsigned long | begin, |
unsigned long | count | ||
) |
Notify of IO request.
begin | First table row being read/written |
count | Num consecutive table rows being read/written |
Definition at line 96 of file IODebugTrack.cpp.
References enableOutput, mpiRank, and record_io().
{ if( enableOutput && count ) { DRange ins = { begin, begin + count - 1, static_cast< long unsigned >( mpiRank ) }; record_io( ins ); } }
std::list< DRange > moab::IODebugTrack::dataSet [private] |
Definition at line 32 of file IODebugTrack.hpp.
Referenced by all_reduce(), record_io(), and ~IODebugTrack().
bool moab::IODebugTrack::enableOutput [private] |
Definition at line 30 of file IODebugTrack.hpp.
Referenced by all_reduce(), record_io(), and ~IODebugTrack().
bool moab::IODebugTrack::haveMPI [private] |
Definition at line 36 of file IODebugTrack.hpp.
Referenced by all_reduce(), and IODebugTrack().
unsigned long moab::IODebugTrack::maxSize [private] |
Definition at line 34 of file IODebugTrack.hpp.
Referenced by record_io(), and ~IODebugTrack().
int moab::IODebugTrack::mpiRank [private] |
Definition at line 35 of file IODebugTrack.hpp.
Referenced by all_reduce(), IODebugTrack(), record_io(), and ~IODebugTrack().
std::ostream& moab::IODebugTrack::ostr [private] |
Definition at line 33 of file IODebugTrack.hpp.
Referenced by record_io(), and ~IODebugTrack().
std::string moab::IODebugTrack::tableName [private] |
Definition at line 31 of file IODebugTrack.hpp.
Referenced by record_io(), and ~IODebugTrack().