[MOAB-dev] r3067 - in MOAB/trunk: . parallel

kraftche at cae.wisc.edu kraftche at cae.wisc.edu
Tue Jul 28 17:07:30 CDT 2009


Author: kraftche
Date: 2009-07-28 17:07:30 -0500 (Tue, 28 Jul 2009)
New Revision: 3067

Modified:
   MOAB/trunk/WriteHDF5.cpp
   MOAB/trunk/parallel/WriteHDF5Parallel.cpp
   MOAB/trunk/parallel/crystal.c
   MOAB/trunk/parallel/gs.c
Log:
Add explicit valgrind calls to check more than valgrind would be able
to otherwise check.  Instrumentation is minimal when not running in
valgrind (a few no-op instructions here and there) and is removed
entirely if MOAB is configured without --enable-debug.  Do things like
 - if re-using a buffer for multiple iterations, at the beginning of
   each iteration tell valgrind to treat the buffer as uninitialized
   data
 - for a few places where valgrind reports errors within MPI calls,
   ask valgrind to check that data we pass to the MPI calls is
   initialized so we know that the issue is in the MPI library
   rather than MOAB code
 - when creating std::vectors, work around the C++ standard requiring
   that the contents be zero-ed by explicitly telling valgrind that
   the contents should be treated as uninitialized
   
Still haven't found the memory issue with parallel writes, but the
above a) narrows down the search a bit and b) is useful to have
anyway.



Modified: MOAB/trunk/WriteHDF5.cpp
===================================================================
--- MOAB/trunk/WriteHDF5.cpp	2009-07-28 18:14:51 UTC (rev 3066)
+++ MOAB/trunk/WriteHDF5.cpp	2009-07-28 22:07:30 UTC (rev 3067)
@@ -77,6 +77,26 @@
 # define myassert(A)
 #endif
 
+
+#ifdef VALGRIND
+#  include <valgrind/memcheck.h>
+#else
+#  ifndef VALGRIND_CHECK_MEM_IS_DEFINED
+#    define VALGRIND_CHECK_MEM_IS_DEFINED
+#  endif
+#  ifndef VALGRIND_CHECK_MEM_IS_ADDRESSABLE
+#    define VALGRIND_CHECK_MEM_IS_ADDRESSABLE
+#  endif
+#  ifndef VALGRIND_MAKE_MEM_UNDEFINED
+#    define VALGRIND_MAKE_MEM_UNDEFINED
+#  endif
+#endif
+
+template <typename T> inline 
+void VALGRIND_MAKE_VEC_UNDEFINED( std::vector<T>& v ) {
+    VALGRIND_MAKE_MEM_UNDEFINED( &v[0], v.size() * sizeof(T) );
+}
+
 #define WRITE_HDF5_BUFFER_SIZE (40*1024*1024)
 
 static hid_t get_id_type()
@@ -424,6 +444,7 @@
   else
   {
     std::vector<MBEntityHandle> passed_export_list(set_array, set_array+num_sets);
+    VALGRIND_MAKE_VEC_UNDEFINED( passed_export_list );
     result = gather_mesh_info( passed_export_list );
     if (MB_SUCCESS != result) 
       return result;
@@ -731,6 +752,7 @@
   MBRange::const_iterator iter = nodeSet.range.begin();
   while (remaining)
   {
+    VALGRIND_MAKE_MEM_UNDEFINED( dataBuffer, bufferSize );
     long count = chunk_size < remaining ? chunk_size : remaining;
     remaining -= count;
     MBRange::const_iterator end = iter;
@@ -805,6 +827,7 @@
   
   while (remaining)
   {
+    VALGRIND_MAKE_MEM_UNDEFINED( dataBuffer, bufferSize );
     long count = chunk_size < remaining ? chunk_size : remaining;
     remaining -= count;
   
@@ -892,6 +915,7 @@
   const unsigned long buffer_size = bufferSize / sizeof(id_t);
   unsigned long offset = children ? setChildrenOffset : setParentsOffset;
   unsigned long count = 0;
+  VALGRIND_MAKE_MEM_UNDEFINED( dataBuffer, bufferSize );
   for (iter = setSet.range.begin(); iter != end; ++iter)
   {
     handle_list.clear();
@@ -909,12 +933,15 @@
     CHK_MB_ERR_1(rval, table, status);
 
     if (id_list.size() + count > buffer_size) {
+        // buffer is full, flush it
       mhdf_writeSetParentsChildren( table, offset, count, id_type, buffer, &status );
       CHK_MHDF_ERR_1(status, table);
       offset += count;
       count = 0;
+      VALGRIND_MAKE_MEM_UNDEFINED( dataBuffer, bufferSize );
 
-
+        // If id_list still doesn't it in empty buffer, write it
+        // directly rather than trying to buffer it
       if (id_list.size() > buffer_size) {
         mhdf_writeSetParentsChildren( table, offset, id_list.size(), id_type, &id_list[0], &status );
         CHK_MHDF_ERR_1(status, table);
@@ -981,6 +1008,7 @@
     content_chunk_size = (bufferSize - 4*sizeof(long)*chunk_size)/sizeof(id_t);
     assert(content_chunk_size>0);
     content_buffer = reinterpret_cast<id_t*>(buffer+4*chunk_size);
+    VALGRIND_MAKE_MEM_UNDEFINED( content_buffer, content_chunk_size*sizeof(content_buffer[0]) );
   }
     
   MBRange set_contents;
@@ -997,6 +1025,10 @@
     long* set_data = buffer;
     long count = remaining < chunk_size ? remaining : chunk_size;
     remaining -= count;
+      // tell valgrind that buffer portion used for set descriptions
+      // is uninitialized (as it is garbage data from the last iteration)
+    VALGRIND_MAKE_MEM_UNDEFINED( buffer, 4*sizeof(buffer[0])*chunk_size );
+
     for (long i = 0; i < count; ++i, ++iter, set_data += 4) {
     
       rval = get_set_info( *iter, content_size, child_size, parent_size, flags );
@@ -1040,6 +1072,8 @@
       if (id_list.size())
       {
         if (data_count + id_list.size() > content_chunk_size) {
+            // If there isn't enough space remaining in the buffer,
+            // flush the buffer.
           mhdf_writeSetData( content_table, 
                              content_buffer_offset,
                              data_count,
@@ -1049,7 +1083,11 @@
           CHK_MHDF_ERR_2C(status, set_table, writeSetContents, content_table );
           content_buffer_offset += data_count;
           data_count = 0;
+          VALGRIND_MAKE_MEM_UNDEFINED( content_buffer, content_chunk_size*sizeof(content_buffer[0]) );
         
+            // If there still isn't enough space in the buffer because
+            // the size of id_list is bigger than the entire buffer,
+            // write id_list directly.
           if (id_list.size() > content_chunk_size) {
             mhdf_writeSetData( content_table, 
                                content_buffer_offset,
@@ -1261,6 +1299,7 @@
 MBErrorCode WriteHDF5::range_to_id_list( const MBRange& range,
                                          id_t* array )
 {
+  VALGRIND_MAKE_MEM_UNDEFINED( array, sizeof(id_t)*range.size() );
   MBErrorCode rval = MB_SUCCESS;
   RangeMap<MBEntityHandle,id_t>::iterator ri = idMap.begin();
   MBRange::const_pair_iterator pi;
@@ -1299,6 +1338,7 @@
   std::vector<MBEntityHandle>::const_iterator i_iter = input.begin();
   const std::vector<MBEntityHandle>::const_iterator i_end = input.end();
   output.resize(input.size());
+  VALGRIND_MAKE_VEC_UNDEFINED( output );
   std::vector<id_t>::iterator o_iter = output.begin();
   for (; i_iter != i_end; ++i_iter) {
     id_t id = idMap.find( *i_iter );
@@ -1368,6 +1408,7 @@
   id_t* buffer = (id_t*)dataBuffer;
   long chunk_size = bufferSize / sizeof(id_t); 
   long num_writes = (elements.max_num_adjs + chunk_size - 1)/chunk_size;
+  VALGRIND_MAKE_MEM_UNDEFINED( dataBuffer, bufferSize );
   count = 0;
   for (iter = elements.range.begin(); iter != end; ++iter)
   {
@@ -1377,10 +1418,12 @@
     if (adj_list.size() == 0)
       continue;
     
+      // If buffer is full, flush it
     if (count + adj_list.size() + 2 > (unsigned long)chunk_size)
     {
       mhdf_writeAdjacencyWithOpt( table, offset, count, id_type, buffer, writeProp, &status );
       CHK_MHDF_ERR_1(status, table);
+      VALGRIND_MAKE_MEM_UNDEFINED( dataBuffer, bufferSize );
       
       offset += count;
       count = 0;
@@ -1632,6 +1675,8 @@
   MBRange::const_iterator iter = tag_data.range.begin();
   while (remaining)
   {
+    VALGRIND_MAKE_MEM_UNDEFINED( dataBuffer, bufferSize );
+
       // write "chunk_size" blocks of data
     long count = (unsigned long)remaining > chunk_size ? chunk_size : remaining;
     remaining -= count;
@@ -1741,6 +1786,8 @@
   }
   while (remaining)
   {
+    VALGRIND_MAKE_MEM_UNDEFINED( dataBuffer, bufferSize );
+ 
       // write "chunk_size" blocks of data
     long count = (unsigned long)remaining > chunk_size ? chunk_size : remaining;
     remaining -= count;
@@ -1873,6 +1920,7 @@
   char* const data_buffer = reinterpret_cast<char*>(size_buffer + num_entities);
   assert( data_buffer < bufferSize + dataBuffer );
   const size_t data_buffer_size = dataBuffer + bufferSize - data_buffer;
+  VALGRIND_MAKE_MEM_UNDEFINED( data_buffer, data_buffer_size );
   
     // offsets into tables
   long offset_offset = tag_data.offset;      // offset at which to write indices
@@ -1884,6 +1932,10 @@
   size_t remaining = tag_data.range.size();
   MBRange::const_iterator i = tag_data.range.begin();
   while (remaining) {
+    VALGRIND_MAKE_MEM_UNDEFINED( pointer_buffer, num_entities*sizeof(pointer_buffer[0]) );
+    VALGRIND_MAKE_MEM_UNDEFINED( offset_buffer,  num_entities*sizeof(offset_buffer[0]) );
+    VALGRIND_MAKE_MEM_UNDEFINED( size_buffer   , num_entities*sizeof(size_buffer[0]) );
+  
     const size_t count = remaining < num_entities ? remaining : num_entities;
     remaining -= count;
     
@@ -1917,6 +1969,7 @@
           CHK_MHDF_ERR_2(status, tables + 1);
           data_offset += bytes / type_size;
           bytes = 0;
+          VALGRIND_MAKE_MEM_UNDEFINED( data_buffer, data_buffer_size );
         }
       }
       
@@ -1924,6 +1977,7 @@
       if (size > data_buffer_size) {
         if (mb_data_type == MB_TYPE_HANDLE) {
           std::vector<MBEntityHandle> tmp_storage(size/sizeof(MBEntityHandle));
+          VALGRIND_MAKE_VEC_UNDEFINED( tmp_storage );
           convert_handle_tag( reinterpret_cast<const MBEntityHandle*>(ptr),
                               &tmp_storage[0], tmp_storage.size() );
           ptr = &tmp_storage[0];

Modified: MOAB/trunk/parallel/WriteHDF5Parallel.cpp
===================================================================
--- MOAB/trunk/parallel/WriteHDF5Parallel.cpp	2009-07-28 18:14:51 UTC (rev 3066)
+++ MOAB/trunk/parallel/WriteHDF5Parallel.cpp	2009-07-28 22:07:30 UTC (rev 3067)
@@ -50,8 +50,27 @@
   writeUtil->report_error( "MHDF Failure at " __FILE__ ":%d : %s\n", \
     __LINE__, mhdf_message(&(A)) ); \
   return MB_FAILURE; } } while(false)
-  
 
+
+#ifdef VALGRIND
+#  include <valgrind/memcheck.h>
+#else
+#  ifndef VALGRIND_CHECK_MEM_IS_DEFINED
+#    define VALGRIND_CHECK_MEM_IS_DEFINED
+#  endif
+#  ifndef VALGRIND_CHECK_MEM_IS_ADDRESSABLE
+#    define VALGRIND_CHECK_MEM_IS_ADDRESSABLE
+#  endif
+#  ifndef VALGRIND_MAKE_MEM_UNDEFINED
+#    define VALGRIND_MAKE_MEM_UNDEFINED
+#  endif
+#endif
+
+template <typename T> inline 
+void VALGRIND_MAKE_VEC_UNDEFINED( std::vector<T>& v ) {
+    VALGRIND_MAKE_MEM_UNDEFINED( &v[0], v.size() * sizeof(T) );
+}
+
 #define TPRINT(A)
 //#define TPRINT(A) tprint( (A) )
 static void tprint(const char* A) 
@@ -517,6 +536,8 @@
 TPRINT("communicating tag metadata");
   printdebug("Exchanging tag data for %d tags.\n", num_tags);
   std::vector<unsigned long> proc_tag_offsets(2*num_tags*myPcomm->proc_config().proc_size());
+  VALGRIND_CHECK_MEM_IS_DEFINED( &tag_counts[0], 2*num_tags*sizeof(long) );
+  VALGRIND_MAKE_VEC_UNDEFINED( proc_tag_offsets );
   result = MPI_Gather( &tag_counts[0], 2*num_tags, MPI_UNSIGNED_LONG,
                  &proc_tag_offsets[0], 2*num_tags, MPI_UNSIGNED_LONG,
                        0, myPcomm->proc_config().proc_comm() );
@@ -567,10 +588,16 @@
   
     // Send total counts to all processors.  This is necessary because all 
     // processors need to know if we are not writing anything for the tag (count == 0).  
+  if (myPcomm->rank() == 0) {
+    VALGRIND_CHECK_MEM_IS_DEFINED( &tag_counts[0], 2*num_tags*sizeof(long) );
+  }
   result = MPI_Bcast( &tag_counts[0], 2*num_tags, MPI_UNSIGNED_LONG, 0, myPcomm->proc_config().proc_comm() );
   CHECK_MPI(result);
   
     // Send to each processor its per-tag offset values.
+  if (myPcomm->rank() == 0) {
+    VALGRIND_CHECK_MEM_IS_DEFINED(  &proc_tag_offsets[0], proc_tag_offsets.size()*sizeof(long) );
+  }
   result = MPI_Scatter( &proc_tag_offsets[0], 2*num_tags, MPI_UNSIGNED_LONG,
                              &tag_offsets[0], 2*num_tags, MPI_UNSIGNED_LONG,
                              0, myPcomm->proc_config().proc_comm() );
@@ -631,6 +658,7 @@
     // gather node counts for each processor
   std::vector<long> node_counts(myPcomm->proc_config().proc_size());
   long num_nodes = nodeSet.range.size();
+  VALGRIND_CHECK_MEM_IS_DEFINED( &num_nodes, sizeof(long) );
   result = MPI_Gather( &num_nodes, 1, MPI_LONG, &node_counts[0], 1, MPI_LONG, 0, myPcomm->proc_config().proc_comm() );
   CHECK_MPI(result);
   
@@ -667,6 +695,9 @@
   
     // send each proc it's offset in the node table
   long offset;
+  if (myPcomm->rank() == 0) {
+    VALGRIND_CHECK_MEM_IS_DEFINED( &node_counts[0], sizeof(long) );
+  }
   result = MPI_Scatter( &node_counts[0], 1, MPI_LONG, 
                         &offset, 1, MPI_LONG,
                         0, myPcomm->proc_config().proc_comm() );
@@ -719,6 +750,7 @@
   
     // Get list of types on this processor
   std::vector<int> my_types(num_types);
+  VALGRIND_MAKE_VEC_UNDEFINED( my_types );
   std::vector<int>::iterator viter = my_types.begin();
   for (std::list<ExportSet>::iterator eiter = exportList.begin();
        eiter != exportList.end(); ++eiter)
@@ -742,11 +774,14 @@
 
     // Get list of types from each processor
   std::vector<int> displs(myPcomm->proc_config().proc_size() + 1);
+  VALGRIND_MAKE_VEC_UNDEFINED( displs );
   displs[0] = 0;
   for (unsigned long i = 1; i <= myPcomm->proc_config().proc_size(); ++i)
     displs[i] = displs[i-1] + counts[i-1];
   int total = displs[myPcomm->proc_config().proc_size()];
   std::vector<int> alltypes(total);
+  VALGRIND_MAKE_VEC_UNDEFINED( alltypes );
+  VALGRIND_CHECK_MEM_IS_DEFINED( &my_types[0], my_types.size()*sizeof(int) );
   result = MPI_Gatherv( &my_types[0], my_types.size(), MPI_INT,
                         &alltypes[0], &counts[0], &displs[0], MPI_INT,
                         0, myPcomm->proc_config().proc_comm() );
@@ -777,6 +812,7 @@
   
     // Send list of types to each processor
   std::vector<int> intlist(total * 2);
+  VALGRIND_MAKE_VEC_UNDEFINED( intlist );
   viter = intlist.begin();
   for (liter = type_list.begin(); liter != type_list.end(); ++liter)
   {
@@ -845,10 +881,13 @@
   const int numtypes = exportList.size();
   std::vector<long> my_counts(numtypes);
   std::vector<long> counts(numtypes * myPcomm->proc_config().proc_size() + numtypes);
+  VALGRIND_MAKE_VEC_UNDEFINED( my_counts );
+  VALGRIND_MAKE_VEC_UNDEFINED( counts );
   viter = my_counts.begin();
   for (ex_iter = exportList.begin(); ex_iter != exportList.end(); ++ex_iter)
     { *viter = ex_iter->range.size(); ++viter; }
   
+  VALGRIND_CHECK_MEM_IS_DEFINED( &my_counts[0], numtypes*sizeof(long) );
   result = MPI_Gather( &my_counts[0], numtypes, MPI_LONG,
                        &counts[0],    numtypes, MPI_LONG, 0, myPcomm->proc_config().proc_comm() );
   CHECK_MPI(result);
@@ -866,6 +905,9 @@
   }
   
     // Send offsets to each processor
+  if (myPcomm->rank() == 0) {
+    VALGRIND_CHECK_MEM_IS_DEFINED( &counts[0], counts.size()*sizeof(long) );
+  }
   result = MPI_Scatter( &counts[0],    numtypes, MPI_LONG,
                         &my_counts[0], numtypes, MPI_LONG,
                         0, myPcomm->proc_config().proc_comm() );
@@ -878,6 +920,7 @@
   
     // Create element tables
   std::vector<long> start_ids(numtypes);
+  VALGRIND_MAKE_VEC_UNDEFINED( start_ids );
   if (myPcomm->proc_config().proc_rank() == 0)
   {
     viter = start_ids.begin();
@@ -928,6 +971,8 @@
   std::vector<long>::iterator viter;
   std::list<ExportSet>::iterator ex_iter;
   std::vector<long> local(numtypes), all(myPcomm->proc_config().proc_size() * numtypes + numtypes);
+  VALGRIND_MAKE_VEC_UNDEFINED( local );
+  VALGRIND_MAKE_VEC_UNDEFINED( all );
   
     // Get adjacency counts for local processor
   viter = local.begin();
@@ -947,30 +992,34 @@
   }
   
     // Send local adjacency counts to root processor
+  VALGRIND_CHECK_MEM_IS_DEFINED( &local[0], numtypes*sizeof(long) );
   result = MPI_Gather( &local[0], numtypes, MPI_LONG,
                        &all[0],   numtypes, MPI_LONG, 
                        0, myPcomm->proc_config().proc_comm() );
   CHECK_MPI(result);
   
-    // Convert counts to offsets
-  for (i = 0; i < numtypes; i++) 
-  {
-    long prev = 0;
-    for (unsigned j = 0; j <= myPcomm->proc_config().proc_size(); j++)
+  
+  if (myPcomm->rank() == 0) {
+      // Convert counts to offsets
+    for (i = 0; i < numtypes; i++) 
     {
-      long tmp = all[j*numtypes + i];
-      all[j*numtypes+i] = prev;
-      prev += tmp;
+      long prev = 0;
+      for (unsigned j = 0; j <= myPcomm->proc_config().proc_size(); j++)
+      {
+        long tmp = all[j*numtypes + i];
+        all[j*numtypes+i] = prev;
+        prev += tmp;
+      }
     }
+
+      // For each element type for which there is no adjacency data,
+      // send -1 to all processors as the offset
+    for (i = 0; i < numtypes; ++i)
+      if (all[numtypes*myPcomm->proc_config().proc_size()+i] == 0)
+        for (j = 0; j < myPcomm->proc_config().proc_size(); ++j)
+          all[j*numtypes+i] = -1;
   }
   
-    // For each element type for which there is no adjacency data,
-    // send -1 to all processors as the offset
-  for (i = 0; i < numtypes; ++i)
-    if (all[numtypes*myPcomm->proc_config().proc_size()+i] == 0)
-      for (j = 0; j < myPcomm->proc_config().proc_size(); ++j)
-        all[j*numtypes+i] = -1;
-  
     // Send offsets back to each processor
   result = MPI_Scatter( &all[0],   numtypes, MPI_LONG,
                         &local[0], numtypes, MPI_LONG,
@@ -1136,6 +1185,7 @@
 
     // Exchange number of sets with tag between all processors
   data.counts.resize(myPcomm->proc_config().proc_size());
+  VALGRIND_MAKE_VEC_UNDEFINED( data.counts );
   int count = data.range.size();
   result = MPI_Allgather( &count,          1, MPI_INT, 
                           &data.counts[0], 1, MPI_INT,
@@ -1144,15 +1194,19 @@
 
     // Exchange tag values for sets between all processors
   data.displs.resize(myPcomm->proc_config().proc_size()+1);
+  VALGRIND_MAKE_VEC_UNDEFINED( data.displs );
   data.displs[0] = 0;
   for (unsigned int j = 1; j <= myPcomm->proc_config().proc_size(); j++)
     data.displs[j] = data.displs[j-1] + data.counts[j-1];
   int total = data.displs[myPcomm->proc_config().proc_size()];
   data.all_values.resize(total);
+  VALGRIND_MAKE_VEC_UNDEFINED( data.all_values );
   data.local_values.resize(count);
+  VALGRIND_MAKE_VEC_UNDEFINED( data.local_values );
   rval = iFace->tag_get_data( data.data_tag, data.range, &data.local_values[0] );
   if (MB_SUCCESS != rval)
     return rval;
+  VALGRIND_CHECK_MEM_IS_DEFINED( &data.local_values[0], count*sizeof(int) );
   result = MPI_Allgatherv( &data.local_values[0], count, MPI_INT,
                            &data.all_values[0], &data.counts[0], &data.displs[0], MPI_INT,
                            myPcomm->proc_config().proc_comm() );
@@ -1301,6 +1355,7 @@
     // Gather counts of non-shared sets from each proc
     // to determine total table size.
   std::vector<long> set_offsets(myPcomm->proc_config().proc_size() + 1);
+  VALGRIND_MAKE_VEC_UNDEFINED( set_offsets );
   long local_count = setSet.range.size();
   result = MPI_Gather( &local_count,    1, MPI_LONG,
                        &set_offsets[0], 1, MPI_LONG,
@@ -1372,6 +1427,7 @@
   if (MB_SUCCESS != rval) 
     return rval;
   std::vector<long> set_counts(3*myPcomm->proc_config().proc_size());
+  VALGRIND_MAKE_VEC_UNDEFINED( set_counts );
   result = MPI_Gather( data_counts,    3, MPI_LONG,
                        &set_counts[0], 3, MPI_LONG,
                        0, myPcomm->proc_config().proc_comm() );
@@ -1533,6 +1589,7 @@
 
     // Calculate counts for each meshset
   std::vector<long> local_sizes(3*count);
+  VALGRIND_MAKE_VEC_UNDEFINED( local_sizes );
   std::vector<long>::iterator sizes_iter = local_sizes.begin();
   MBRange tmp_range;
   std::vector<MBEntityHandle> child_list;
@@ -1579,12 +1636,16 @@
   
     // Exchange sizes for sets between all processors.
   std::vector<long> all_sizes(3*total);
+  VALGRIND_MAKE_VEC_UNDEFINED( all_sizes );
   std::vector<int> counts(myPcomm->proc_config().proc_size()), displs(myPcomm->proc_config().proc_size());
+  VALGRIND_MAKE_VEC_UNDEFINED( counts );
+  VALGRIND_MAKE_VEC_UNDEFINED( displs );
   for (i = 0; i < (unsigned)myPcomm->proc_config().proc_size(); i++)
     counts[i] = 3 * data.counts[i];
   displs[0] = 0;
   for (i = 1; i < (unsigned)myPcomm->proc_config().proc_size(); i++)
     displs[i] = displs[i-1] + counts[i-1];
+  VALGRIND_CHECK_MEM_IS_DEFINED( &local_sizes[0], 3*count*sizeof(long) );
   result = MPI_Allgatherv( &local_sizes[0], 3*count, MPI_LONG,
                            &all_sizes[0], &counts[0], &displs[0], MPI_LONG,
                            myPcomm->proc_config().proc_comm() );
@@ -1602,6 +1663,7 @@
     // on this processor for the set *relative* to the start of the
     // data of *the set*.
   std::vector<long> local_offsets(3*count);
+  VALGRIND_MAKE_VEC_UNDEFINED( local_offsets );
   std::map<int,int> tagsort;  // Map of {tag value, index of first set w/ value}
   for (i = 0; i < total; ++i)
   {
@@ -1959,6 +2021,7 @@
   MBRange::const_iterator i;
   const MBRange& imesh = interfaceMesh[myPcomm->proc_config().proc_rank()];
   std::vector<MBEntityHandle> file_id_vect( imesh.size() );
+  VALGRIND_MAKE_VEC_UNDEFINED( file_id_vect );
   std::vector<MBEntityHandle>::iterator j = file_id_vect.begin();
   for (i = imesh.begin(); i != imesh.end(); ++i, ++j) {
     *j = idMap.find( *i );
@@ -1992,6 +2055,7 @@
       continue;
 
     file_id_vect.resize( p->second.size() );
+    VALGRIND_MAKE_VEC_UNDEFINED( file_id_vect );
     rval = iFace->tag_get_data( file_id_tag, p->second, &file_id_vect[0] );
     if (MB_SUCCESS != rval) {
       iFace->tag_delete( file_id_tag );

Modified: MOAB/trunk/parallel/crystal.c
===================================================================
--- MOAB/trunk/parallel/crystal.c	2009-07-28 18:14:51 UTC (rev 3066)
+++ MOAB/trunk/parallel/crystal.c	2009-07-28 22:07:30 UTC (rev 3067)
@@ -53,6 +53,12 @@
 #include "errmem.h"
 #include "types.h"
 
+#ifdef VALGRIND
+#  include <valgrind/memcheck.h>
+#elif !defined(VALGRIND_CHECK_MEM_IS_DEFINED)
+#  define VALGRIND_CHECK_MEM_IS_DEFINED
+#endif
+
 typedef struct { uint n; buffer buf; } crystal_buf;
 
 typedef struct {
@@ -110,6 +116,7 @@
   crystal_buf *t;
   int i;
   
+  VALGRIND_CHECK_MEM_IS_DEFINED( &p->send->n, sizeof(uint) );
   MPI_Isend(&p->send->n,sizeof(uint),MPI_UNSIGNED_CHAR,
             target  ,p->id   ,p->comm,&req[  0]);
   for(i=0;i<recvn;++i)
@@ -124,6 +131,7 @@
   recv[1]=recv[0]+count[0];
   p->keep->n=sum;
 
+  VALGRIND_CHECK_MEM_IS_DEFINED( p->send->buf.ptr,p->send->n*sizeof(uint) );
   MPI_Isend(p->send->buf.ptr,p->send->n*sizeof(uint),
             MPI_UNSIGNED_CHAR,target,p->id,p->comm,&req[0]);
   if(recvn) {

Modified: MOAB/trunk/parallel/gs.c
===================================================================
--- MOAB/trunk/parallel/gs.c	2009-07-28 18:14:51 UTC (rev 3066)
+++ MOAB/trunk/parallel/gs.c	2009-07-28 22:07:30 UTC (rev 3067)
@@ -83,6 +83,13 @@
 #  include "crystal.h"  
 #  include "transfer.h"
 
+
+#ifdef VALGRIND
+#  include <valgrind/memcheck.h>
+#elif !defined(VALGRIND_CHECK_MEM_IS_DEFINED)
+#  define VALGRIND_CHECK_MEM_IS_DEFINED
+#endif
+
 typedef struct {
   uint np;           /* number of processors to communicate with          */
   uint *target;      /* int target[np]: array of processor ids to comm w/ */
@@ -412,6 +419,8 @@
 #else
   buffer buf;
 #endif
+  VALGRIND_CHECK_MEM_IS_DEFINED(  label, nlabels * sizeof( long) );
+  VALGRIND_CHECK_MEM_IS_DEFINED( ulabel, nlabels * sizeof(ulong) );
 #ifdef USE_MPI
   MPI_Comm_dup(crystal->comm,&data->comm);
 #else



More information about the moab-dev mailing list