MOAB: Mesh Oriented datABase  (version 5.2.1)
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.
 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< 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

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.

References MPI_COMM_WORLD, and mpiRank.

    : enableOutput( enabled ), tableName( name ), ostr( output_stream ), maxSize( table_size ), haveMPI( false )
{
#ifdef MOAB_HAVE_MPI
    MPI_Comm_rank( MPI_COMM_WORLD, &mpiRank );
#else
    mpiRank = 0;
#endif
}
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 27 of file IODebugTrack.cpp.

References haveMPI, MPI_COMM_WORLD, and mpiRank.

    : enableOutput( enabled ), tableName( name ), ostr( std::cerr ), maxSize( table_size )
{
    mpiRank = 0;
    haveMPI = false;
#ifdef MOAB_HAVE_MPI
    int have_init = 0;
    MPI_Initialized( &have_init );
    if( have_init )
    {
        haveMPI = true;
        MPI_Comm_rank( MPI_COMM_WORLD, &mpiRank );
    }
#endif
}

Destructor prints errors about unaccessed ranges.

Definition at line 43 of file IODebugTrack.cpp.

References b, 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();
    }
}

Member Function Documentation

Push all data to root process.

Does nothing if MPI support is not enabled

Definition at line 140 of file IODebugTrack.cpp.

References dataSet, enableOutput, haveMPI, MPI_COMM_WORLD, 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 103 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.

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

Definition at line 94 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 );
    }
}

Member Data Documentation

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

Definition at line 32 of file IODebugTrack.hpp.

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

Definition at line 30 of file IODebugTrack.hpp.

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

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().

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().

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines