Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
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 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 29 of file IODebugTrack.cpp.

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

Member Function Documentation

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.

Parameters:
beginFirst table row being read/written
countNum 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 );
    }
}

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