[MOAB-dev] r1683 - in MOAB/trunk: . parallel
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Mon Mar 24 12:21:58 CDT 2008
Author: kraftche
Date: 2008-03-24 12:21:57 -0500 (Mon, 24 Mar 2008)
New Revision: 1683
Modified:
MOAB/trunk/MBWriteUtil.cpp
MOAB/trunk/MBWriteUtil.hpp
MOAB/trunk/MBWriteUtilIface.hpp
MOAB/trunk/RangeMap.hpp
MOAB/trunk/WriteHDF5.cpp
MOAB/trunk/WriteHDF5.hpp
MOAB/trunk/parallel/WriteHDF5Parallel.cpp
Log:
Use RangeMap rather than tag data for mapping from entity handles to file
IDs when writing .H5M files. For most cases, this will result in a substantial
reduction in the memory required to write .h5m files. It also removes the
limitation of 2M entities being written to a file that resuled from using
4-byte signed integer tag values for file IDs.*
For a large kD-tree decomposition of a triangle mesh, write speed increased
by about 4%. For a large tet mesh (3.3 M tet block w/ skin triangles),
the write speed is 40% faster.
* Some portions of the parallel writer still have 2M limits because
MPI uses 'int' for sizes in calls such as MPI_Allgatherv and the
code does not chunk data to work around this limitation.
Modified: MOAB/trunk/MBWriteUtil.cpp
===================================================================
--- MOAB/trunk/MBWriteUtil.cpp 2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/MBWriteUtil.cpp 2008-03-24 17:21:57 UTC (rev 1683)
@@ -404,6 +404,84 @@
return MB_SUCCESS;
}
+MBErrorCode MBWriteUtil::get_element_array(
+ MBRange::const_iterator iter,
+ const MBRange::const_iterator end,
+ const int vertices_per_elem,
+ const size_t elem_array_size,
+ MBEntityHandle *const element_array )
+{
+ // check the data we got
+ if(iter == end)
+ return MB_FAILURE;
+ if(vertices_per_elem < 1)
+ return MB_FAILURE;
+ if(!element_array || elem_array_size < (unsigned)vertices_per_elem)
+ return MB_FAILURE;
+
+ // Sequence iterators
+ TypeSequenceManager::const_iterator seq_iter, seq_end;
+
+ // loop over range, getting coordinate value
+ MBEntityType current_type = MBMAXTYPE;
+ MBEntityHandle* output_iter = element_array;
+ MBEntityHandle*const output_end = element_array + elem_array_size;
+ while (iter != end)
+ {
+ // Make sure we have the right sequence list (and get the sequence
+ // list for the first iteration.)
+ MBEntityType type = TYPE_FROM_HANDLE(*iter);
+ if (type != current_type)
+ {
+ if (type >= MBENTITYSET || type < MBEDGE)
+ return MB_FAILURE;
+ seq_iter = mMB->sequence_manager()->entity_map(type).begin();
+ seq_end = mMB->sequence_manager()->entity_map(type).end();
+ current_type = type;
+ }
+
+ // Find the sqeuence containing the current handle
+ while (seq_iter != seq_end && (*seq_iter)->end_handle() < *iter)
+ ++seq_iter;
+ if (seq_iter == seq_end || *iter < (*seq_iter)->start_handle())
+ return MB_FAILURE;
+
+ // get the connectivity array
+ MBEntityHandle* conn_array = NULL;
+ int conn_size = static_cast<ElementSequence*>(*seq_iter)->nodes_per_element();
+ if (conn_size != vertices_per_elem)
+ return MB_FAILURE;
+ conn_array = static_cast<ElementSequence*>(*seq_iter)->get_connectivity_array();
+
+ // Determine how much of the sequence we want.
+ MBRange::pair_iterator pair(iter);
+ MBRange::const_iterator prev(end);
+ --prev;
+ MBEntityHandle range_end = pair->second;
+ MBEntityHandle sequence_end = (*seq_iter)->end_handle();
+ MBEntityHandle end_handle = range_end > sequence_end ? sequence_end : range_end;
+ if (end_handle > *prev)
+ end_handle = *prev;
+ MBEntityHandle count = end_handle - *iter + 1;
+
+ // Get offset in sequence to start at
+ assert( *iter >= (*seq_iter)->start_handle() );
+ MBEntityHandle offset = *iter - (*seq_iter)->start_handle();
+
+ // Make sure sufficient space in output array
+ if (output_iter + (count * conn_size) > output_end)
+ return MB_FAILURE;
+
+ // Copy connectivity into output array
+ conn_array += (conn_size * offset);
+ memcpy( output_iter, conn_array, count * conn_size * sizeof(MBEntityHandle));
+ output_iter += count * conn_size;
+ iter += count;
+ }
+
+ return MB_SUCCESS;
+}
+
MBErrorCode MBWriteUtil::get_poly_array_size(
MBRange::const_iterator ,
const MBRange::const_iterator ,
@@ -638,3 +716,9 @@
return MB_SUCCESS;
}
+MBErrorCode MBWriteUtil::get_adjacencies( MBEntityHandle entity,
+ const MBEntityHandle*& adj_array,
+ int& num_adj )
+{
+ return mMB->a_entity_factory()->get_adjacencies( entity, adj_array, num_adj );
+}
Modified: MOAB/trunk/MBWriteUtil.hpp
===================================================================
--- MOAB/trunk/MBWriteUtil.hpp 2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/MBWriteUtil.hpp 2008-03-24 17:21:57 UTC (rev 1683)
@@ -128,6 +128,39 @@
int *const element_array
);
+ /** Get connectivity for elements
+ *
+ * Get the connectivity list for a range of elements.
+ *
+ * Failure cases:
+ * - Passed range is empty (<code>begin == end</code>).
+ * - <code>vertices_per_elem</code> is less than one
+ * - <code>element_array</code> is null.
+ * - The range contains invalid handles (non-existant entities,
+ * not an element, etc.)
+ * - Insufficient space in passed array.
+ *
+ *\param begin The first element handle
+ *\param end One past the last element handle
+ *\param vertices_per_elem Number of vertices to retreive for each
+ * element. If the element has more vertices, the
+ * element connectivity will be truncated. If
+ * <code>vertices_per_elem</code> is greater than the
+ * number of nodes for an eleement, the data will be
+ * padded with zeros.
+ *\param array_size The length of <code>element_array</code>
+ *\param element_array The memory location at which to store the
+ * connectivity list.
+ *\author Jason Kraftcheck
+ */
+ virtual MBErrorCode get_element_array(
+ MBRange::const_iterator begin,
+ const MBRange::const_iterator end,
+ const int vertices_per_elem,
+ const size_t array_size,
+ MBEntityHandle *const element_array
+ );
+
/** Get poly (polygon or polyhedron) connectivity size
*\param begin First iterator in range of poly
*\param end One past last in range of poly.
@@ -210,6 +243,9 @@
std::vector<int>& adj
);
+ MBErrorCode get_adjacencies( MBEntityHandle entity,
+ const MBEntityHandle*& adj_array,
+ int& num_adj );
//! tell MB there was an error when writing the mesh
Modified: MOAB/trunk/MBWriteUtilIface.hpp
===================================================================
--- MOAB/trunk/MBWriteUtilIface.hpp 2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/MBWriteUtilIface.hpp 2008-03-24 17:21:57 UTC (rev 1683)
@@ -140,7 +140,40 @@
int *const element_array
) = 0;
+ /** Get connectivity for elements
+ *
+ * Get the connectivity list for a range of elements.
+ *
+ * Failure cases:
+ * - Passed range is empty (<code>begin == end</code>).
+ * - <code>vertices_per_elem</code> is less than one
+ * - <code>element_array</code> is null.
+ * - The range contains invalid handles (non-existant entities,
+ * not an element, etc.)
+ * - Insufficient space in passed array.
+ *
+ *\param begin The first element handle
+ *\param end One past the last element handle
+ *\param vertices_per_elem Number of vertices to retreive for each
+ * element. If the element has more vertices, the
+ * element connectivity will be truncated. If
+ * <code>vertices_per_elem</code> is greater than the
+ * number of nodes for an eleement, the data will be
+ * padded with zeros.
+ *\param array_size The length of <code>element_array</code>
+ *\param element_array The memory location at which to store the
+ * connectivity list.
+ *\author Jason Kraftcheck
+ */
+ virtual MBErrorCode get_element_array(
+ MBRange::const_iterator begin,
+ const MBRange::const_iterator end,
+ const int vertices_per_elem,
+ const size_t array_size,
+ MBEntityHandle *const element_array
+ ) = 0;
+
/** Get poly (polygon or polyhedron) connectivity size
*\param begin First iterator in range of poly
*\param end One past last in range of poly.
@@ -245,6 +278,10 @@
std::vector<int>& adj
) = 0;
+
+ virtual MBErrorCode get_adjacencies( MBEntityHandle entity,
+ const MBEntityHandle*& adj_array,
+ int& num_adj ) = 0;
//! if an error occured when reading the mesh, report it to MB
//! it makes sense to have this as long as MBInterface has a write_mesh function
Modified: MOAB/trunk/RangeMap.hpp
===================================================================
--- MOAB/trunk/RangeMap.hpp 2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/RangeMap.hpp 2008-03-24 17:21:57 UTC (rev 1683)
@@ -31,7 +31,7 @@
* for use in situations where there are relatively few insertions
* of large contiguous ranges of values.
*/
-template <typename KeyType, typename ValType, ValType NullVal>
+template <typename KeyType, typename ValType, ValType NullVal = 0>
class RangeMap
{
public:
@@ -49,7 +49,7 @@
* Insert mapping from [first_key, first_key+count) to [first_val, first_val+count)
*
* Input range of keys many not overlap any other input range. If it does overlap
- * an existing range, false is returned and the internal map is not changed.
+ * an existing range, end() is returned and the internal map is not changed.
*/
inline iterator insert( KeyType first_key, ValType first_val, KeyType count );
@@ -68,11 +68,21 @@
Range b = { key, 1, NullVal };
return std::lower_bound( begin(), end(), b );
}
+ static inline iterator lower_bound( iterator s, iterator e, KeyType key )
+ {
+ Range b = { key, 1, NullVal };
+ return std::lower_bound( s, e, b );
+ }
inline iterator upper_bound( KeyType key ) const
{
Range b = { key, 1, NullVal };
return std::upper_bound( begin(), end(), b );
}
+ static inline iterator upper_bound( iterator s, iterator e, KeyType key )
+ {
+ Range b = { key, 1, NullVal };
+ return std::upper_bound( s, e, b );
+ }
inline std::pair<iterator,iterator>
equal_range( KeyType key ) const
{
Modified: MOAB/trunk/WriteHDF5.cpp
===================================================================
--- MOAB/trunk/WriteHDF5.cpp 2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/WriteHDF5.cpp 2008-03-24 17:21:57 UTC (rev 1683)
@@ -76,12 +76,28 @@
#define WRITE_HDF5_BUFFER_SIZE (40*1024*1024)
- // This is the tag used to store file offsets (file ids)
- // during export. It is temporary data.
-#define HDF5_ID_TAG_NAME "hdf5_id"
+static hid_t get_id_type()
+{
+ if (8 == sizeof(WriteHDF5::id_t)) {
+ if (8 == sizeof(long))
+ return H5T_NATIVE_ULONG;
+ else
+ return H5T_NATIVE_UINT64;
+ }
+ else if (4 == sizeof(WriteHDF5::id_t)) {
+ if (4 == sizeof(int))
+ return H5T_NATIVE_UINT;
+ else
+ return H5T_NATIVE_UINT32;
+ }
+ else {
+ assert(0);
+ return (hid_t)-1;
+ }
+}
- // This is the HDF5 type for the data of the "hdf5_id" tag.
-const hid_t WriteHDF5::id_type = H5T_NATIVE_INT;
+ // This is the HDF5 type used to store file IDs
+const hid_t WriteHDF5::id_type = get_id_type();
// Some macros to handle error checking. The
// CHK_MHDF__ERR* macros check the value of an mhdf_Status
@@ -176,65 +192,30 @@
return (A); \
} while(false)
-/** When writing tags containing MBEntityHandles to file, need to convert tag
- * data from MBEntityHandles to file IDs. This function does that.
- *
- * If the handle is not valid or does not correspond to an entity that will
- * be written to the file, the file ID is set to zero.
- *\param iface MOAB instance
- *\param tag The TAG containing file IDs for entities
- *\param data The data buffer. As input, an array of MBEntityHandles. As
- * output an array of file IDS, where the size of each integral
- * file ID is the same as the size of MBEntityHandle.
- *\param count The number of handles in the buffer.
- *\return true if at least one of the handles is valid and will be written to
- * the file or at least one of the handles is NULL (zero). false
- * otherwise
- */
-static bool convert_handle_tag( MBInterface* iface, MBTag tag, void* data, size_t count )
+bool WriteHDF5::convert_handle_tag( MBEntityHandle* data, size_t count )
{
+ assert( sizeof(MBEntityHandle) == sizeof(id_t) );
bool some_valid = false;
- MBErrorCode rval;
-
- // if same saize
- MBEntityHandle *buffer, *end;
- WriteHDF5::id_t* witer;
- int step;
- if (sizeof(MBEntityHandle) >= sizeof(WriteHDF5::id_t)) {
- buffer = (MBEntityHandle*)data;
- end = buffer + count;
- witer = (WriteHDF5::id_t*)data;
- step = 1;
- }
- else {
- // iterate in reverse order if sizeof(id_t) > sizeof(MBEntityHandle)
- buffer = (MBEntityHandle*)data + count - 1;
- end = (MBEntityHandle*)data - 1;
- witer = (WriteHDF5::id_t*)data + count - 1;
- step = -1;
- }
- for ( ; buffer != end; buffer += step, witer += step) {
- if (!*buffer) {
+ for (size_t i = 0; i < count; ++i) {
+ data[i] = idMap.find( data[i] );
+ if (data[i])
some_valid = true;
- *witer = 0;
- }
- else {
- int id;
- rval = iface->tag_get_data( tag, buffer, 1, &id );
- if (MB_SUCCESS == rval && id > 0) {
- some_valid = true;
- *witer = id;
- }
- else {
- *buffer = 0;
- *witer = 0;
- }
- }
}
-
return some_valid;
}
+MBErrorCode WriteHDF5::assign_ids( const MBRange& entities, id_t id )
+{
+ MBRange::const_pair_iterator pi;
+ for (pi = entities.const_pair_begin(); pi != entities.const_pair_end(); ++pi) {
+ const MBEntityHandle n = pi->second - pi->first + 1;
+ if (idMap.end() == idMap.insert( pi->first, id, n ))
+ return MB_FAILURE;
+ id += n;
+ }
+ return MB_SUCCESS;
+}
+
const char* WriteHDF5::ExportSet::name() const
{
static char buffer[32];
@@ -259,8 +240,6 @@
iFace( iface ),
writeUtil( 0 ),
filePtr( 0 ),
- createdIdTag(false),
- idTag( 0 ),
setContentsOffset( 0 ),
setChildrenOffset( 0 ),
setParentsOffset( 0 ),
@@ -274,7 +253,6 @@
MBErrorCode WriteHDF5::init()
{
MBErrorCode rval;
- id_t zero_int = -1;
if (writeUtil) // init has already been called
return MB_SUCCESS;
@@ -290,17 +268,9 @@
// Get the util interface
rval = iFace->query_interface( "MBWriteUtilIface", (void**)&writeUtil );
CHK_MB_ERR_0(rval);
+
+ idMap.clear();
- // Get the file id tag if it exists or create it otherwise.
- rval = iFace->tag_get_handle( HDF5_ID_TAG_NAME, idTag );
- if (MB_TAG_NOT_FOUND == rval)
- {
- rval = iFace->tag_create( HDF5_ID_TAG_NAME, sizeof(id_t),
- MB_TAG_DENSE, idTag, &zero_int );
- if (MB_SUCCESS == rval)
- createdIdTag = true;
- }
-
if (MB_SUCCESS != rval)
{
iFace->release_interface( "MBWriteUtilIFace", writeUtil );
@@ -319,6 +289,7 @@
setSet.range.clear();
rangeSets.clear();
tagList.clear();
+ idMap.clear();
return MB_SUCCESS;
}
@@ -329,8 +300,6 @@
return;
iFace->release_interface( "MBWriteUtilIface", writeUtil );
- if (createdIdTag)
- iFace->tag_delete( idTag );
}
@@ -422,15 +391,6 @@
result = gather_mesh_info( passed_export_list );
if (MB_SUCCESS != result)
return result;
-
- // Mark all entities invalid. Later the ones we are
- // exporting will be marked valid. This way we can
- // distinguish adjacent entities and such that aren't
- // being exported.
- // Don't to this, just set the default value to -1 when
- // the tag is created in the init() function.
- //result = clear_all_id_tags();
- //if (MB_SUCCESS != result) return result;
}
//if (nodeSet.range.size() == 0)
@@ -525,30 +485,6 @@
return MB_SUCCESS;
}
- // Initialize all file ids to -1. We do this so that
- // if we are writing only a part of the mesh, we can
- // easily identify adjacencies, set contents, etc. which
- // are not in the mesh we are writing.
-MBErrorCode WriteHDF5::clear_all_id_tags()
-{
- id_t cleared_value = -1;
- MBRange range;
- for (MBEntityType type = MBVERTEX; type < MBMAXTYPE; ++type)
- {
- range.clear();
- MBErrorCode rval = iFace->get_entities_by_type( 0, type, range, false );
- CHK_MB_ERR_0(rval);
-
- for (MBRange::iterator itor = range.begin(); itor != range.end(); ++itor)
- {
- MBEntityHandle handle = *itor;
- rval = iFace->tag_set_data( idTag, &handle, 1, &cleared_value );
- CHK_MB_ERR_0(rval);
- }
- }
- return MB_SUCCESS;
-}
-
MBErrorCode WriteHDF5::initialize_mesh( const MBRange ranges[5] )
{
MBErrorCode rval;
@@ -786,11 +722,11 @@
&status );
CHK_MHDF_ERR_0(status);
- assert (first_id <= elems.first_id);
+ assert ((unsigned long)first_id <= elems.first_id);
assert ((unsigned long)table_size >= elems.offset + elems.range.size());
- id_t* buffer = (id_t*)dataBuffer;
+ MBEntityHandle* buffer = (MBEntityHandle*)dataBuffer;
int chunk_size = bufferSize / (elems.num_nodes * sizeof(id_t));
long offset = elems.offset;
long remaining = elems.range.size();
@@ -804,10 +740,13 @@
MBRange::iterator next = iter;
next += count;
rval = writeUtil->get_element_array( iter, next, elems.num_nodes,
- idTag, count * elems.num_nodes, buffer );
+ count * elems.num_nodes, buffer );
CHK_MB_ERR_1(rval, elem_table, status);
iter = next;
+ for (long i = 0; i < count*nodes_per_elem; ++i)
+ buffer[i] = idMap.find( buffer[i] );
+
mhdf_writeConnectivity( elem_table, offset, count,
id_type, buffer, &status );
CHK_MHDF_ERR_1(status, elem_table);
@@ -901,7 +840,7 @@
rval = iFace->get_entities_by_handle( *iter, set_contents, false );
CHK_MB_ERR_2C(rval, set_table, writeSetContents, content_table, status);
- rval = range_to_id_list( set_contents, id_list );
+ rval = range_to_blocked_list( set_contents, id_list );
CHK_MB_ERR_2C(rval, set_table, writeSetContents, content_table, status);
assert (id_list.size() < (unsigned long)data_size);
@@ -1031,9 +970,9 @@
return MB_SUCCESS;
}
-
-MBErrorCode WriteHDF5::range_to_id_list( const MBRange& input_range,
- std::vector<id_t>& output_id_list )
+/*
+MBErrorCode WriteHDF5::range_to_blocked_list( const MBRange& input_range,
+ std::vector<id_t>& output_id_list )
{
MBRange::const_iterator r_iter;
MBRange::const_iterator const r_end = input_range.end();
@@ -1042,16 +981,9 @@
// Get file IDs from handles
output_id_list.resize( input_range.size() );
- rval = iFace->tag_get_data( idTag, input_range, &output_id_list[0] );
- if (MB_ENTITY_NOT_FOUND == rval) { // ignore stale handles
- MBRange::const_iterator i;
- std::vector<id_t>::iterator j = output_id_list.begin();
- for (i = input_range.begin(); i != input_range.end(); ++i, ++j)
- if (MB_SUCCESS != iFace->tag_get_data( idTag, &*i, 1, &*j ))
- *j = 0;
- }
- else
- CHK_MB_ERR_0(rval);
+ w_iter = output_id_list.begin();
+ for (r_iter = input_range.begin(); r_iter != r_end; ++r_iter, ++w_iter)
+ *w_iter = idMap.find( *r_iter );
std::sort( output_id_list.begin(), output_id_list.end() );
// Count the number of ranges in the id list
@@ -1104,72 +1036,140 @@
return MB_SUCCESS;
}
-
-MBErrorCode WriteHDF5::vector_to_id_list(
- const std::vector<MBEntityHandle>& input,
- std::vector<id_t>& output )
+*/
+MBErrorCode WriteHDF5::range_to_blocked_list( const MBRange& input_range,
+ std::vector<id_t>& output_id_list )
{
- id_t id;
- MBErrorCode rval;
- MBEntityHandle handle;
- std::vector<MBEntityHandle>::const_iterator i_iter = input.begin();
- const std::vector<MBEntityHandle>::const_iterator i_end = input.end();
- output.resize(input.size());
- std::vector<id_t>::iterator o_iter = output.begin();
-
- while (i_iter != i_end)
- {
- handle = *i_iter;
- rval = iFace->tag_get_data( idTag, &handle, 1, &id );
- if (MB_ENTITY_NOT_FOUND == rval) // ignore stale handles
- id = 0;
- else
- CHK_MB_ERR_0(rval);
- *o_iter = id;
- ++o_iter;
- ++i_iter;
+ if (input_range.empty()) {
+ output_id_list.clear();
+ return MB_SUCCESS;
}
- return MB_SUCCESS;
-}
+ // first try ranged format, but give up if we reach the
+ // non-range format size.
+ RangeMap<MBEntityHandle,id_t>::iterator ri = idMap.begin();
+ MBRange::const_pair_iterator pi;
+ output_id_list.resize( input_range.size() );
+ std::vector<id_t>::iterator i = output_id_list.begin();
+ for (pi = input_range.const_pair_begin(); pi != input_range.const_pair_end(); ++pi) {
+ MBEntityHandle h = pi->first;
+ while (h <= pi->second) {
+ ri = idMap.lower_bound( ri, idMap.end(), h );
+ if (ri == idMap.end())
+ continue;
+ id_t n = pi->second - pi->first + 1;
+ if (n > ri->count)
+ n = ri->count;
+
+ if (output_id_list.end() - i < 2)
+ break;
-template <class T> static void
-erase_from_vector( std::vector<T>& vector, T value )
-{
- typename std::vector<T>::iterator r_itor, w_itor;
- const typename std::vector<T>::iterator end = vector.end();
- unsigned count = 0;
+ id_t id = ri->value + (h - ri->begin);
+ *i = id; ++i;
+ *i = n; ++i;
+ h += n;
+ }
+ }
- for (r_itor = vector.begin();
- r_itor != end && *r_itor != value;
- ++r_itor)
- count++;
+ // if we ran out of space, just do list format
+ if (output_id_list.end() - i < 2) {
+ range_to_id_list( input_range, &output_id_list[0] );
+ return MB_SUCCESS;
+ }
- w_itor = r_itor;
- for ( ; r_itor != end; ++r_itor)
- {
- if (*r_itor != value)
- {
- *w_itor = *r_itor;
- ++w_itor;
- count++;
+ // otherwise check if we can compact the list further
+ size_t r, w = 2;
+ const size_t e = i - output_id_list.begin() - 1;
+ for (r = 2; r < e; r += 2) {
+ if (output_id_list[w-2] + output_id_list[w-1] == output_id_list[r])
+ output_id_list[w-1] += output_id_list[r+1];
+ else {
+ if (w != r) {
+ output_id_list[w] = output_id_list[r];
+ output_id_list[w+1] = output_id_list[r+1];
+ }
+ w += 2;
}
}
+ output_id_list.resize( w );
+ assert(output_id_list.size() % 2 == 0);
- vector.resize( count );
+ return MB_SUCCESS;
}
+
+
+MBErrorCode WriteHDF5::range_to_id_list( const MBRange& range,
+ id_t* array )
+{
+ MBErrorCode rval = MB_SUCCESS;
+ RangeMap<MBEntityHandle,id_t>::iterator ri = idMap.begin();
+ MBRange::const_pair_iterator pi;
+ id_t* i = array;
+ for (pi = range.const_pair_begin(); pi != range.const_pair_end(); ++pi) {
+ MBEntityHandle h = pi->first;
+ while (h <= pi->second) {
+ ri = idMap.lower_bound( ri, idMap.end(), h );
+ if (ri == idMap.end()) {
+ rval = MB_ENTITY_NOT_FOUND;
+ *i = 0;
+ ++i;
+ ++h;
+ }
+
+ id_t n = pi->second - pi->first + 1;
+ if (n > ri->count)
+ n = ri->count;
+
+ id_t id = ri->value - (h - ri->begin);
+ for (id_t j = 0; j < n; ++i, ++j)
+ *i = id + j;
+ h += n;
+ }
+ }
+ assert( i == array + range.size() );
+ return rval;
+}
+MBErrorCode WriteHDF5::vector_to_id_list(
+ const std::vector<MBEntityHandle>& input,
+ std::vector<id_t>& output,
+ bool remove_zeros )
+{
+ std::vector<MBEntityHandle>::const_iterator i_iter = input.begin();
+ const std::vector<MBEntityHandle>::const_iterator i_end = input.end();
+ output.resize(input.size());
+ std::vector<id_t>::iterator o_iter = output.begin();
+ for (; i_iter != i_end; ++i_iter) {
+ id_t id = idMap.find( *i_iter );
+ if (!remove_zeros || id != 0) {
+ *o_iter = id;
+ ++o_iter;
+ }
+ }
+ output.erase( o_iter, output.end() );
+
+ return MB_SUCCESS;
+}
-
+
inline MBErrorCode WriteHDF5::get_adjacencies( MBEntityHandle entity,
std::vector<id_t>& adj )
{
- MBErrorCode rval = writeUtil->get_adjacencies( entity, idTag, adj );
- //erase_from_vector( adj, (id_t)0 );
- erase_from_vector( adj, (id_t)-1 );
- return rval;
+ const MBEntityHandle* adj_array;
+ int num_adj;
+ MBErrorCode rval = writeUtil->get_adjacencies( entity, adj_array, num_adj );
+ if (MB_SUCCESS != rval)
+ return rval;
+
+ size_t j = 0;
+ adj.resize( num_adj );
+ for (int i = 0; i < num_adj; ++i)
+ if (id_t id = idMap.find( adj_array[i] ))
+ adj[j++] = id;
+ adj.resize( j );
+ return MB_SUCCESS;
}
@@ -1179,7 +1179,7 @@
mhdf_Status status;
MBRange::const_iterator iter;
const MBRange::const_iterator end = elements.range.end();
- std::vector<int> adj_list;
+ std::vector<id_t> adj_list;
/* Count Adjacencies */
long count = 0;
@@ -1225,14 +1225,8 @@
count = 0;
}
- rval = iFace->tag_get_data( idTag, &*iter, 1, buffer + count );
- if (MB_SUCCESS != rval || buffer[count] < 1)
- {
- mhdf_closeData( filePtr, table, &status );
- return MB_FAILURE;
- }
- buffer[++count] = adj_list.size();
- ++count;
+ buffer[count++] = idMap.find( *iter );
+ buffer[count++] = adj_list.size();
assert (adj_list.size()+2 < (unsigned long)chunk_size);
memcpy( buffer + count, &adj_list[0], adj_list.size() * sizeof(id_t) );
@@ -1473,7 +1467,7 @@
iter = stop;
assert(range.size() == (unsigned)count);
- rval = iFace->tag_get_data( idTag, range, id_buffer );
+ rval = range_to_id_list( range, id_buffer );
CHK_MB_ERR_0( rval );
// write the data
@@ -1589,7 +1583,8 @@
// Convert MBEntityHandles to file ids
if (mb_data_type == MB_TYPE_HANDLE)
- convert_handle_tag( iFace, idTag, tag_buffer, count * mb_size / sizeof(MBEntityHandle) );
+ convert_handle_tag( reinterpret_cast<MBEntityHandle*>(tag_buffer),
+ count * mb_size / sizeof(MBEntityHandle) );
// write the data
mhdf_writeSparseTagValues( tables[1], offset, count,
@@ -1673,7 +1668,8 @@
if (mb_data_type == MB_TYPE_HANDLE) {
assert( size < bufferSize );
memcpy( dataBuffer, ptr, size );
- convert_handle_tag( iFace, idTag, dataBuffer, size / sizeof(MBEntityHandle) );
+ convert_handle_tag( reinterpret_cast<MBEntityHandle*>(dataBuffer),
+ size / sizeof(MBEntityHandle) );
ptr = dataBuffer;
}
@@ -1799,10 +1795,6 @@
// Get list of tags
for (t_itor = tag_list.begin(); t_itor != tag_list.end(); ++t_itor)
{
- // Don't write global ID tag
- if (*t_itor == idTag)
- continue;
-
// Don't write tags that have name beginning with "__"
result = iFace->tag_get_name( *t_itor, tagname );
if (MB_SUCCESS != result)
@@ -1876,7 +1868,7 @@
result = iFace->tag_get_data( handle, &*i, 1, &values[0] );
CHK_MB_ERR_0(result);
- if (convert_handle_tag( iFace, idTag, &values[0], values.size() ))
+ if (convert_handle_tag( &values[0], values.size() ))
++i;
else
i = td_iter->range.erase( i );
@@ -1927,8 +1919,9 @@
CHK_MHDF_ERR_0(status);
mhdf_closeData( filePtr, handle, &status );
CHK_MHDF_ERR_0(status);
- writeUtil->assign_ids( nodeSet.range, idTag, (id_t)first_id );
nodeSet.first_id = (id_t)first_id;
+ rval = assign_ids( nodeSet.range, nodeSet.first_id );
+ CHK_MB_ERR_0(rval);
}
else {
nodeSet.first_id = std::numeric_limits<id_t>::max();
@@ -1944,9 +1937,10 @@
first_id );
CHK_MB_ERR_0(rval);
- writeUtil->assign_ids( ex_itor->range, idTag, (id_t)first_id );
ex_itor->first_id = (id_t)first_id;
ex_itor->offset = 0;
+ rval = assign_ids( ex_itor->range, ex_itor->first_id );
+ CHK_MB_ERR_0(rval);
}
// create node adjacency table
@@ -1996,7 +1990,11 @@
writeSets = true;
rval = create_set_meta( setSet.range.size(), first_id );
- writeUtil->assign_ids( setSet.range, idTag, (id_t)first_id );
+ CHK_MB_ERR_0(rval);
+
+ setSet.first_id = (id_t)first_id;
+ rval = assign_ids( setSet.range, setSet.first_id );
+ CHK_MB_ERR_0(rval);
rval = count_set_size( setSet.range, rangeSets, contents_len, children_len, parents_len );
CHK_MB_ERR_0(rval);
@@ -2004,7 +2002,6 @@
rval = create_set_tables( contents_len, children_len, parents_len );
CHK_MB_ERR_0(rval);
- setSet.first_id = (id_t)first_id;
setSet.offset = 0;
setContentsOffset = 0;
setChildrenOffset = 0;
@@ -2043,7 +2040,7 @@
MBErrorCode WriteHDF5::count_adjacencies( const MBRange& set, id_t& result )
{
MBErrorCode rval;
- std::vector<int> adj_list;
+ std::vector<id_t> adj_list;
MBRange::const_iterator iter = set.begin();
const MBRange::const_iterator end = set.end();
result = 0;
@@ -2117,7 +2114,7 @@
rval = iFace->get_entities_by_handle( *iter, set_contents, false );
CHK_MB_ERR_0(rval);
- rval = range_to_id_list( set_contents, set_contents_ids );
+ rval = range_to_blocked_list( set_contents, set_contents_ids );
CHK_MB_ERR_0(rval);
if (set_contents_ids.size() < (unsigned long)contents_length_set)
@@ -2367,7 +2364,8 @@
// convert default value
if (def_value) {
memcpy( dataBuffer, def_value, def_val_len );
- if (convert_handle_tag( iFace, idTag, dataBuffer, def_val_len / sizeof(MBEntityHandle) ))
+ if (convert_handle_tag( reinterpret_cast<MBEntityHandle*>(dataBuffer),
+ def_val_len / sizeof(MBEntityHandle) ))
def_value = dataBuffer;
else
def_value = 0;
@@ -2377,7 +2375,7 @@
if (mesh_value) {
MBEntityHandle* ptr = reinterpret_cast<MBEntityHandle*>(dataBuffer + def_val_len);
memcpy( ptr, mesh_value, mesh_val_len );
- if (convert_handle_tag( iFace, idTag, ptr, mesh_val_len / sizeof(MBEntityHandle) ))
+ if (convert_handle_tag( ptr, mesh_val_len / sizeof(MBEntityHandle) ))
mesh_value = ptr;
else
mesh_value = 0;
Modified: MOAB/trunk/WriteHDF5.hpp
===================================================================
--- MOAB/trunk/WriteHDF5.hpp 2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/WriteHDF5.hpp 2008-03-24 17:21:57 UTC (rev 1683)
@@ -28,6 +28,7 @@
#include "MBForward.hpp"
#include "MBRange.hpp"
#include "MBWriterIface.hpp"
+#include "RangeMap.hpp"
class MBWriteUtilIface;
@@ -40,12 +41,12 @@
static MBWriterIface* factory( MBInterface* );
- /** The type of the global ID tag data
+ /** The type to use for entity IDs w/in the file.
*
* NOTE: If this is changed, the value of id_type
* MUST be changed accordingly.
*/
- typedef int id_t;
+ typedef MBEntityHandle id_t;
/** HDF5 type corresponding to type of id_t */
static const hid_t id_type;
@@ -206,10 +207,8 @@
//! The file handle from the mhdf library
mhdf_FileHandle filePtr;
- //! True if created the ID tag in init()
- bool createdIdTag;
- //! Handle for the ID tag.
- MBTag idTag;
+ //! Map from entity handles to file IDs
+ RangeMap<MBEntityHandle,id_t> idMap;
//! The list elements to export.
std::list<ExportSet> exportList;
@@ -250,9 +249,6 @@
MBErrorCode init();
- //! Zero the ID tag on all entities in the mesh.
- MBErrorCode clear_all_id_tags();
-
//! Get information about a meshset
MBErrorCode get_set_info( MBEntityHandle set,
long& num_entities,
@@ -274,6 +270,9 @@
unsigned long num_entities,
unsigned long var_len_total );
+ /**\brief add entities to idMap */
+ MBErrorCode assign_ids( const MBRange& entities, id_t first_id );
+
/** Get possibly compacted list of IDs for passed entities
*
* For the passed range of entities, determine if IDs
@@ -288,13 +287,32 @@
* If the ID list is compacted, the length will be less than
* range.size().
*/
+ MBErrorCode range_to_blocked_list( const MBRange& input_range,
+ std::vector<id_t>& output_id_list );
+
+
MBErrorCode range_to_id_list( const MBRange& input_range,
- std::vector<id_t>& output_id_list );
-
+ id_t* array );
//! Get IDs for entities
MBErrorCode vector_to_id_list( const std::vector<MBEntityHandle>& input,
- std::vector<id_t>& output );
+ std::vector<id_t>& output,
+ bool remove_non_written = false );
+ /** When writing tags containing MBEntityHandles to file, need to convert tag
+ * data from MBEntityHandles to file IDs. This function does that.
+ *
+ * If the handle is not valid or does not correspond to an entity that will
+ * be written to the file, the file ID is set to zero.
+ *\param data The data buffer. As input, an array of MBEntityHandles. As
+ * output an array of file IDS, where the size of each integral
+ * file ID is the same as the size of MBEntityHandle.
+ *\param count The number of handles in the buffer.
+ *\return true if at least one of the handles is valid and will be written to
+ * the file or at least one of the handles is NULL (zero). false
+ * otherwise
+ */
+ bool convert_handle_tag( MBEntityHandle* data, size_t count );
+
/** Get IDs of adjacent entities.
*
* For all entities adjacent to the passed entity, if the
Modified: MOAB/trunk/parallel/WriteHDF5Parallel.cpp
===================================================================
--- MOAB/trunk/parallel/WriteHDF5Parallel.cpp 2008-03-24 14:54:42 UTC (rev 1682)
+++ MOAB/trunk/parallel/WriteHDF5Parallel.cpp 2008-03-24 17:21:57 UTC (rev 1683)
@@ -376,16 +376,14 @@
// For all remote mesh entities, remove them from the
- // lists of local mesh to be exported and give them a
- // junk file Id of 1. Need to specify a file ID greater
- // than zero so the code that gathers adjacencies and
- // such doesn't think that the entities aren't being
- // exported.
+ // lists of local mesh to be exported and the ID map
+ // (they will be put back into the ID map with different
+ // IDs later.)
for (i = 0; i < numProc; i++)
{
if (i == myRank) continue;
- MBRange& range = remoteMesh[i];
+ const MBRange& range = remoteMesh[i];
range_remove( nodeSet.range, range );
//range_remove( setSet.range, range );
@@ -393,14 +391,9 @@
eiter != exportList.end(); ++eiter )
range_remove( eiter->range, range );
- int id = 1;
- for (MBRange::iterator riter = remoteMesh[i].begin();
- riter != remoteMesh[i].end() && iFace->type_from_handle(*riter) != MBENTITYSET;
- ++riter)
- {
- result = iFace->tag_set_data( idTag, &*riter, 1, &id );
- if (MB_SUCCESS != result) return result;
- }
+ //for (MBRange::const_pair_iterator pi = range.const_pair_begin();
+ // pi != range.const_pair_end(); ++pi)
+ // idMap.erase( pi->first, pi->second - pi->first + 1 );
}
// print some debug output summarizing what we've accomplished
@@ -473,19 +466,15 @@
rval = create_node_table( dimension );
if (MB_SUCCESS != rval) return rval;
+ rval = communicate_remote_ids( MBVERTEX );
+ if (MB_SUCCESS != rval) return rval;
-
/**************** Create element tables ***************/
rval = negotiate_type_list();
if (MB_SUCCESS != rval) return rval;
rval = create_element_tables();
if (MB_SUCCESS != rval) return rval;
-
-
- /**************** Comminucate all remote IDs ***********************/
-
- rval = communicate_remote_ids( MBVERTEX );
for (std::list<ExportSet>::iterator ex_itor = exportList.begin();
ex_itor != exportList.end(); ++ex_itor)
{
@@ -658,9 +647,9 @@
mhdf_Status status;
// gather node counts for each processor
- std::vector<int> node_counts(numProc);
- int num_nodes = nodeSet.range.size();
- result = MPI_Gather( &num_nodes, 1, MPI_INT, &node_counts[0], 1, MPI_INT, 0, MPI_COMM_WORLD );
+ std::vector<long> node_counts(numProc);
+ long num_nodes = nodeSet.range.size();
+ result = MPI_Gather( &num_nodes, 1, MPI_LONG, &node_counts[0], 1, MPI_LONG, 0, MPI_COMM_WORLD );
assert(MPI_SUCCESS == result);
// create node data in file
@@ -706,9 +695,7 @@
assert(MPI_SUCCESS == result);
nodeSet.offset = offset;
- writeUtil->assign_ids( nodeSet.range, idTag, (id_t)(nodeSet.first_id + nodeSet.offset) );
-
- return MB_SUCCESS;
+ return assign_ids( nodeSet.range(), nodeSet.first_id + nodeSet.offset );
}
@@ -747,14 +734,14 @@
exportList.sort();
// Get number of types each processor has
- int num_types = 2*exportList.size();
- std::vector<int> counts(numProc);
- result = MPI_Gather( &num_types, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, MPI_COMM_WORLD );
+ long num_types = 2*exportList.size();
+ std::vector<long> counts(numProc);
+ result = MPI_Gather( &num_types, 1, MPI_LONG, &counts[0], 1, MPI_LONG, 0, MPI_COMM_WORLD );
assert(MPI_SUCCESS == result);
// Get list of types on this processor
- std::vector<int> my_types(num_types);
- std::vector<int>::iterator viter = my_types.begin();
+ std::vector<long> my_types(num_types);
+ std::vector<long>::iterator viter = my_types.begin();
for (std::list<ExportSet>::iterator eiter = exportList.begin();
eiter != exportList.end(); ++eiter)
{
@@ -768,22 +755,22 @@
viter = my_types.begin();
while (viter != my_types.end())
{
- int type = *viter; ++viter;
- int count = *viter; ++viter;
+ long type = *viter; ++viter;
+ long count = *viter; ++viter;
printdebug(" %s : %d\n", MBCN::EntityTypeName((MBEntityType)type), count);
}
END_SERIAL;
#endif
// Get list of types from each processor
- std::vector<int> displs(numProc + 1);
+ std::vector<long> displs(numProc + 1);
displs[0] = 0;
- for (int i = 1; i <= numProc; ++i)
+ for (long i = 1; i <= numProc; ++i)
displs[i] = displs[i-1] + counts[i-1];
- int total = displs[numProc];
- std::vector<int> alltypes(total);
- result = MPI_Gatherv( &my_types[0], my_types.size(), MPI_INT,
- &alltypes[0], &counts[0], &displs[0], MPI_INT,
+ long total = displs[numProc];
+ std::vector<long> alltypes(total);
+ result = MPI_Gatherv( &my_types[0], my_types.size(), MPI_LONG,
+ &alltypes[0], &counts[0], &displs[0], MPI_LONG,
0, MPI_COMM_WORLD );
assert(MPI_SUCCESS == result);
@@ -807,18 +794,18 @@
// Send total number of types to each processor
total = type_list.size();
- result = MPI_Bcast( &total, 1, MPI_INT, 0, MPI_COMM_WORLD );
+ result = MPI_Bcast( &total, 1, MPI_LONG, 0, MPI_COMM_WORLD );
assert(MPI_SUCCESS == result);
// Send list of types to each processor
- std::vector<int> intlist(total * 2);
+ std::vector<long> intlist(total * 2);
viter = intlist.begin();
for (liter = type_list.begin(); liter != type_list.end(); ++liter)
{
*viter = liter->mbtype; ++viter;
*viter = liter->numnode; ++viter;
}
- result = MPI_Bcast( &intlist[0], 2*total, MPI_INT, 0, MPI_COMM_WORLD );
+ result = MPI_Bcast( &intlist[0], 2*total, MPI_LONG, 0, MPI_COMM_WORLD );
assert(MPI_SUCCESS == result);
#ifdef DEBUG
@@ -827,8 +814,8 @@
viter = intlist.begin();
while (viter != intlist.end())
{
- int type = *viter; ++viter;
- int count = *viter; ++viter;
+ long type = *viter; ++viter;
+ long count = *viter; ++viter;
printdebug(" %s : %d\n", MBCN::EntityTypeName((MBEntityType)type), count);
}
END_SERIAL;
@@ -838,10 +825,10 @@
// range of entities to export.
std::list<ExportSet>::iterator ex_iter = exportList.begin();
viter = intlist.begin();
- for (int i = 0; i < total; ++i)
+ for (long i = 0; i < total; ++i)
{
- int mbtype = *viter; ++viter;
- int numnode = *viter; ++viter;
+ long mbtype = *viter; ++viter;
+ long numnode = *viter; ++viter;
while (ex_iter != exportList.end() && ex_iter->type < mbtype)
++ex_iter;
@@ -939,7 +926,7 @@
{
ex_iter->first_id = *(viter++);
id_t myfirst = (id_t)(ex_iter->first_id + ex_iter->offset);
- rval = writeUtil->assign_ids( ex_iter->range, idTag, myfirst );
+ rval = assign_ids( ex_iter->range, myfirst );
assert(MB_SUCCESS == rval);
}
@@ -1097,12 +1084,19 @@
}
*/
-
+/** Working data for group of global sets identified by an ID tag */
struct RemoteSetData {
- MBTag data_tag, filter_tag;
- int filter_value;
- MBRange range;
- std::vector<int> counts, displs, all_values, local_values;
+ MBTag data_tag; //!< The ID tag for matching sets across processors
+ MBTag filter_tag; //!< Optional tag to filter on (e.g. geometric dimension)
+ int filter_value; //!< Value of filter_tag for this group
+ MBRange range; //!< Set handles with data_tag set (and optionally filter_tag == filter_value)
+ std::vector<int> counts; //!< Number of sets with tag on each proc, indexed by MPI rank
+ std::vector<int> displs; //!< Offset in all_values at which the data_tag values for
+ //!< each processor begin. displs[n] = sum(i from 0 to n-1)(counts[i])
+ std::vector<int> all_values; //!< data_tag values for sets on all processors,
+ //!< counts[0] values for proc 0, then counts[1] values for proc
+ //!< 1, etc.
+ std::vector<int> local_values; //!< data_tag values for sets that exist on this processor
};
MBErrorCode WriteHDF5Parallel::get_remote_set_data(
@@ -1157,7 +1151,7 @@
2,
data.range );
if (rval != MB_SUCCESS) return rval;
- data.range = data.range.intersect( setSet.range );
+ data.range.swap( data.range.intersect( setSet.range ) );
range_remove( setSet.range, data.range );
}
@@ -1235,7 +1229,8 @@
assert( count == w );
data.local_values.resize( count );
sorted.clear(); // release storage
- // recalculate displacements
+
+ // recalculate displacements for updated counts
data.displs[0] = 0;
for (i = 1; i <= numProc; i++)
data.displs[i] = data.displs[i-1] + data.counts[i-1];
@@ -1249,7 +1244,7 @@
//
// Identify which meshsets will be managed by this processor and
// the corresponding offset in the set description table.
- std::map<int,int> val_id_map;
+ std::map<int,int> val_id_map; // Map from tag value to file ID for set
int cpu = 0;
for (i = 0; i < total; ++i)
{
@@ -1285,7 +1280,7 @@
std::map<int,int>::iterator p = val_id_map.find( data.local_values[i] );
assert( p != val_id_map.end() );
int id = p->second;
- rval = iFace->tag_set_data( idTag, &*riter, 1, &id );
+ rval = idMap.insert( *riter, id, 1 );
assert(MB_SUCCESS == rval);
}
@@ -1369,7 +1364,7 @@
return MB_SUCCESS;
// Assign set IDs
- writeUtil->assign_ids( setSet.range, idTag, (id_t)(setSet.first_id + setSet.offset) );
+ assign_ids( setSet.range, setSet.first_id + setSet.offset );
for (i = 0; i < (int)remote_set_data.size(); ++i)
fix_remote_set_ids( remote_set_data[i], setSet.first_id );
@@ -1788,16 +1783,21 @@
const id_t id_diff = (id_t)(first_id - 1);
id_t file_id;
MBErrorCode rval;
-
- for (MBRange::iterator iter = data.range.begin(); iter != data.range.end(); ++iter)
- {
- rval = iFace->tag_get_data( idTag, &*iter, 1, &file_id );
- assert( MB_SUCCESS == rval );
- file_id += id_diff;
- rval = iFace->tag_set_data( idTag, &*iter, 1, &file_id );
- assert( MB_SUCCESS == rval );
- }
+ MBRange::const_iterator i;
+ std::vector<id_t> ids(data.range.size());
+ std::vector<id_t>::iterator j = ids.begin();
+ for (i = data.range.begin(); i != data.range.end(); ++i, ++j)
+ *j = idMap.find( *i ) + id_diff;
+
+ for (MBRange::const_pair_iterator pi = data.range.const_pair_begin();
+ pi != data.range.const_pair_end(); ++pi)
+ idMap.erase( pi->first, pi->second - pi_first + 1);
+
+ j = ids.begin();
+ for (i = data.range.begin(); i != data.range.end(); ++i)
+ idMap.insert( *i, *j, 1 );
+
return MB_SUCCESS;
}
@@ -1815,8 +1815,8 @@
continue; // handled by a different processor
// Get offset in table at which to write data
- int file_id;
- rval = iFace->tag_get_data( idTag, &(iter->handle), 1, &file_id );
+ id_t file_id = idMap.find( iter->handle );
+ assert( file_id >= start_id );
file_id -= start_id;
// Get flag data
@@ -1855,15 +1855,7 @@
remove_remote_entities( iter->handle, handle_list );
id_list.clear();
- for (unsigned int i = 0; i < handle_list.size(); ++i)
- {
- int id;
- rval = iFace->tag_get_data( idTag, &handle_list[i], 1, &id );
- assert( MB_SUCCESS == rval );
- if (id > 0)
- id_list.push_back(id);
- }
-
+ vector_to_id_list( handle_list, id_list, true );
if (id_list.empty())
continue;
@@ -1897,15 +1889,7 @@
remove_remote_sets( iter->handle, handle_list );
id_list.clear();
- for (unsigned int i = 0; i < handle_list.size(); ++i)
- {
- int id;
- rval = iFace->tag_get_data( idTag, &handle_list[i], 1, &id );
- assert( MB_SUCCESS == rval );
- if (id > 0)
- id_list.push_back(id);
- }
-
+ vector_to_id_list( handle_list, id_list, true );
if (!id_list.empty())
{
mhdf_writeSetParentsChildren( table,
@@ -1939,15 +1923,7 @@
remove_remote_sets( iter->handle, handle_list );
id_list.clear();
- for (unsigned int i = 0; i < handle_list.size(); ++i)
- {
- int id;
- rval = iFace->tag_get_data( idTag, &handle_list[i], 1, &id );
- assert( MB_SUCCESS == rval );
- if (id > 0)
- id_list.push_back(id);
- }
-
+ vector_to_id_list( handle_list, id_list, true );
if (!id_list.empty())
{
mhdf_writeSetParentsChildren( table,
@@ -2030,7 +2006,7 @@
START_SERIAL;
printdebug("%s ranges to communicate:\n", MBCN::EntityTypeName(type));
- for (unsigned int xx = 0; xx != myranges.size(); xx+=2)
+ for (unsigned long xx = 0; xx != myranges.size(); xx+=2)
printdebug(" %lu - %lu\n", myranges[xx], myranges[xx+1] );
END_SERIAL;
@@ -2110,8 +2086,8 @@
}
assert(j < count);
int fileid = offset + steps + (global - low);
- rval = iFace->tag_set_data( idTag, &entity, 1, &fileid );
- assert(MB_SUCCESS == rval);
+ RangeMap<MBEntityHandle,id_t>::iterator ri = idMap.insert( entity, fileid, 1 );
+ assert( ri != idMap.end() );
} // for(r_iter->range)
} // for(each processor)
More information about the moab-dev
mailing list