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. 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< 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.
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.
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.
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 }
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.
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().
|
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().
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.
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().
|
private |
Definition at line 32 of file IODebugTrack.hpp.
Referenced by all_reduce(), record_io(), and ~IODebugTrack().
|
private |
Definition at line 30 of file IODebugTrack.hpp.
Referenced by all_reduce(), record_io(), and ~IODebugTrack().
|
private |
Definition at line 36 of file IODebugTrack.hpp.
Referenced by all_reduce(), and IODebugTrack().
|
private |
Definition at line 34 of file IODebugTrack.hpp.
Referenced by record_io(), and ~IODebugTrack().
|
private |
Definition at line 35 of file IODebugTrack.hpp.
Referenced by all_reduce(), IODebugTrack(), record_io(), and ~IODebugTrack().
|
private |
Definition at line 33 of file IODebugTrack.hpp.
Referenced by record_io(), and ~IODebugTrack().
|
private |
Definition at line 31 of file IODebugTrack.hpp.
Referenced by record_io(), and ~IODebugTrack().