[MOAB-dev] r1659 - in MOAB/trunk: . parallel test/h5file
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Fri Mar 14 09:17:31 CDT 2008
Author: kraftche
Date: 2008-03-14 09:17:31 -0500 (Fri, 14 Mar 2008)
New Revision: 1659
Modified:
MOAB/trunk/MBReaderWriterSet.cpp
MOAB/trunk/WriteHDF5.cpp
MOAB/trunk/WriteHDF5.hpp
MOAB/trunk/configure.in
MOAB/trunk/parallel/WriteHDF5Parallel.cpp
MOAB/trunk/parallel/WriteHDF5Parallel.hpp
MOAB/trunk/test/h5file/varlen_ll.cpp
Log:
o Make "PARALLEL=FORMAT" option work (use WriteHDF5Parallel)
o Clean up code for error handling and resource cleanup in WriteHDF5
o If writing fails, WriteHDF5 will remove any invalid file it created
unless the "KEEP" option is specified.
Modified: MOAB/trunk/MBReaderWriterSet.cpp
===================================================================
--- MOAB/trunk/MBReaderWriterSet.cpp 2008-03-14 14:15:30 UTC (rev 1658)
+++ MOAB/trunk/MBReaderWriterSet.cpp 2008-03-14 14:17:31 UTC (rev 1659)
@@ -39,7 +39,11 @@
#ifdef HDF5_FILE
# include "ReadHDF5.hpp"
-# include "WriteHDF5.hpp"
+# ifdef HDF5_PARALLEL
+# include "WriteHDF5Parallel.hpp"
+# else
+# include "WriteHDF5.hpp"
+# endif
#endif
#include <algorithm>
@@ -49,8 +53,14 @@
{
#ifdef HDF5_FILE
const char* hdf5_sufxs[] = { "h5m", "mhdf", NULL };
- register_factory( ReadHDF5::factory, WriteHDF5::factory, "MOAB native (HDF5)", hdf5_sufxs, "MOAB" );
+#ifdef HDF5_PARALLEL
+ register_factory( ReadHDF5::factory, WriteHDF5Parallel::factory,
+ "MOAB native (HDF5)", hdf5_sufxs, "MOAB" );
+#else
+ register_factory( ReadHDF5::factory, WriteHDF5::factory,
+ "MOAB native (HDF5)", hdf5_sufxs, "MOAB" );
#endif
+#endif
#ifdef NETCDF_FILE
const char* exo_sufxs[] = { "exo", "exoII", "exo2", "g", "gen", NULL };
Modified: MOAB/trunk/WriteHDF5.cpp
===================================================================
--- MOAB/trunk/WriteHDF5.cpp 2008-03-14 14:15:30 UTC (rev 1658)
+++ MOAB/trunk/WriteHDF5.cpp 2008-03-14 14:17:31 UTC (rev 1659)
@@ -45,6 +45,7 @@
#include "MBCN.hpp"
#include "WriteHDF5.hpp"
#include "MBWriteUtilIface.hpp"
+#include "FileOptions.hpp"
#include "mhdf.h"
/* Access HDF5 file handle for debugging
#include <H5Fpublic.h>
@@ -335,17 +336,72 @@
MBErrorCode WriteHDF5::write_file( const char* filename,
bool overwrite,
- const FileOptions& ,
+ const FileOptions& opts,
const MBEntityHandle* set_array,
const int num_sets,
std::vector<std::string>& qa_records,
int user_dimension )
{
+ mhdf_Status status;
+
+ // Allocate internal buffer to use when gathering data to write.
+ dataBuffer = (char*)malloc( bufferSize );
+ if (!dataBuffer)
+ return MB_MEMORY_ALLOCATION_FAILED;
+
+ // Clear filePtr so we know if it is open upon failure
+ filePtr = 0;
+
+ // Do actual write.
+ MBErrorCode result = write_file_impl( filename, overwrite, opts,
+ set_array, num_sets,
+ qa_records, user_dimension );
+
+ // Free memory buffer
+ free( dataBuffer );
+ dataBuffer = 0;
+
+ // Close file
+ bool created_file = false;
+ if (filePtr) {
+ created_file = true;
+ mhdf_closeFile( filePtr, &status );
+ filePtr = 0;
+ if (mhdf_isError( &status )) {
+ writeUtil->report_error( "%s\n", mhdf_message( &status ) );
+ if (MB_SUCCESS == result)
+ result = MB_FAILURE;
+ }
+ }
+
+ // Release other resources
+ if (MB_SUCCESS == result)
+ result = write_finished();
+ else
+ write_finished();
+
+ // If write failed, remove file unless KEEP option was specified
+ if (MB_SUCCESS != result && created_file &&
+ MB_ENTITY_NOT_FOUND == opts.get_null_option( "KEEP" ))
+ remove( filename );
+
+ return result;
+}
+
+
+MBErrorCode WriteHDF5::write_file_impl( const char* filename,
+ bool overwrite,
+ const FileOptions& opts,
+ const MBEntityHandle* set_array,
+ const int num_sets,
+ std::vector<std::string>& qa_records,
+ int user_dimension )
+{
MBErrorCode result;
- mhdf_Status rval;
std::list<SparseTag>::const_iterator t_itor;
std::list<ExportSet>::iterator ex_itor;
MBEntityHandle elem_count, max_id;
+ bool parallel = false;
if (MB_SUCCESS != init())
return MB_FAILURE;
@@ -364,7 +420,8 @@
std::vector<MBEntityHandle> passed_export_list(num_sets);
memcpy( &passed_export_list[0], set_array, sizeof(MBEntityHandle)*num_sets );
result = gather_mesh_info( passed_export_list );
- if (MB_SUCCESS != result) goto write_fail;
+ if (MB_SUCCESS != result)
+ return result;
// Mark all entities invalid. Later the ones we are
// exporting will be marked valid. This way we can
@@ -373,11 +430,11 @@
// 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) goto write_fail;
+ //if (MB_SUCCESS != result) return result;
}
//if (nodeSet.range.size() == 0)
- // goto write_fail;
+ // return MB_ENTITY_NOT_FOUND;
DEBUGOUT("Checking ID space\n");
@@ -389,7 +446,7 @@
if (elem_count > max_id)
{
writeUtil->report_error("ID space insufficient for mesh size.\n");
- goto write_fail;
+ return MB_FAILURE;
}
DEBUGOUT( "Creating File\n" );
@@ -403,47 +460,52 @@
user_dimension = mesh_dim;
user_dimension = user_dimension > mesh_dim ? mesh_dim : user_dimension;
- // Allocate internal buffer to use when gathering data to write.
- dataBuffer = (char*)malloc( bufferSize );
- if (!dataBuffer)
- goto write_fail;
-
// Create the file layout, including all tables (zero-ed) and
// all structure and meta information.
- result = create_file( filename, overwrite, qa_records, user_dimension );
+ parallel = (MB_SUCCESS == opts.match_option( "PARALLEL", "FORMAT" ));
+ result = create_file( filename, overwrite, qa_records, user_dimension, parallel );
if (MB_SUCCESS != result)
- goto write_fail;
+ return result;
DEBUGOUT("Writing Nodes.\n");
// Write node coordinates
- if (!nodeSet.range.empty() && write_nodes() != MB_SUCCESS)
- goto write_fail;
+ if (!nodeSet.range.empty()) {
+ result = write_nodes();
+ if (MB_SUCCESS != result)
+ return result;
+ }
DEBUGOUT("Writing connectivity.\n");
// Write element connectivity
- for (ex_itor = exportList.begin(); ex_itor != exportList.end(); ++ex_itor)
- if (MB_SUCCESS != write_elems( *ex_itor ))
- goto write_fail;
+ for (ex_itor = exportList.begin(); ex_itor != exportList.end(); ++ex_itor) {
+ result = write_elems( *ex_itor );
+ if (MB_SUCCESS != result)
+ return result;
+ }
DEBUGOUT("Writing sets.\n");
// Write meshsets
- if (write_sets() != MB_SUCCESS)
- goto write_fail;
+ result = write_sets();
+ if (MB_SUCCESS != result)
+ return result;
DEBUGOUT("Writing adjacencies.\n");
// Write adjacencies
// Tim says don't save node adjacencies!
#ifdef WRITE_NODE_ADJACENCIES
- if (write_adjacencies( nodeSet ) != MB_SUCCESS)
- goto write_fail;
+ result = write_adjacencies( nodeSet );
+ if (MB_SUCCESS != result)
+ return result;
#endif
- for (ex_itor = exportList.begin(); ex_itor != exportList.end(); ++ex_itor)
- if (write_adjacencies( *ex_itor ) != MB_SUCCESS)
- goto write_fail;
+ for (ex_itor = exportList.begin(); ex_itor != exportList.end(); ++ex_itor) {
+ result = write_adjacencies( *ex_itor );
+ if (MB_SUCCESS != result)
+ return result;
+ }
DEBUGOUT("Writing tags.\n");
@@ -457,31 +519,10 @@
else
result = write_sparse_tag( *t_itor );
if (MB_SUCCESS != result)
- goto write_fail;
+ return result;
}
-
-DEBUGOUT("Closing file.\n");
-
- // Clean up and exit.
- free( dataBuffer );
- dataBuffer = 0;
- mhdf_closeFile( filePtr, &rval );
- filePtr = 0;
- result = write_finished();
- CHK_MHDF_ERR_0( rval );
- return result;
-write_fail:
-
- if (dataBuffer)
- {
- free( dataBuffer );
- dataBuffer = 0;
- }
- mhdf_closeFile( filePtr, &rval );
- filePtr = 0;
- write_finished();
- return MB_FAILURE;
+ return MB_SUCCESS;
}
// Initialize all file ids to -1. We do this so that
@@ -1824,7 +1865,8 @@
MBErrorCode WriteHDF5::create_file( const char* filename,
bool overwrite,
std::vector<std::string>& qa_records,
- int dimension )
+ int dimension,
+ bool parallel )
{
long first_id;
mhdf_Status status;
@@ -1832,6 +1874,13 @@
std::list<ExportSet>::iterator ex_itor;
MBErrorCode rval;
+ // If we support paralle, then this function will have been
+ // overridden with an alternate version in WriteHDF5Parallel
+ // that supports parallel I/O. If we're here and parallel == true,
+ // then MOAB was not built with support for parallel HDF5 I/O.
+ if (parallel)
+ return MB_NOT_IMPLEMENTED;
+
const char* type_names[MBMAXTYPE];
memset( type_names, 0, MBMAXTYPE * sizeof(char*) );
for (MBEntityType i = MBEDGE; i < MBENTITYSET; ++i)
Modified: MOAB/trunk/WriteHDF5.hpp
===================================================================
--- MOAB/trunk/WriteHDF5.hpp 2008-03-14 14:15:30 UTC (rev 1658)
+++ MOAB/trunk/WriteHDF5.hpp 2008-03-14 14:17:31 UTC (rev 1659)
@@ -80,7 +80,8 @@
virtual MBErrorCode create_file( const char* filename,
bool overwrite,
std::vector<std::string>& qa_records,
- int dimension = 3 );
+ int dimension = 3,
+ bool parallel = false );
/** Functions that the parallel version overrides*/
@@ -236,6 +237,17 @@
std::list<SparseTag> tagList;
private:
+
+ //! Do the actual work of write_file. Separated from write_file
+ //! for easier resource cleanup.
+ MBErrorCode write_file_impl( const char* filename,
+ const bool overwrite,
+ const FileOptions& opts,
+ const MBEntityHandle* export_sets,
+ const int export_set_count,
+ std::vector<std::string>& qa_records,
+ int user_dimension = 3 );
+
MBErrorCode init();
//! Zero the ID tag on all entities in the mesh.
Modified: MOAB/trunk/configure.in
===================================================================
--- MOAB/trunk/configure.in 2008-03-14 14:15:30 UTC (rev 1658)
+++ MOAB/trunk/configure.in 2008-03-14 14:17:31 UTC (rev 1659)
@@ -125,6 +125,9 @@
fi
fi
AM_CONDITIONAL(PARALLEL_HDF5, [test "xno" != "x$HAVE_HDF5_PARALLEL"])
+if test "xno" != "x$HAVE_HDF5_PARALLEL"; then
+ DEFINES="$DEFINES -DHDF5_PARALLEL"
+fi
################################################################################
# NetCDF OPTIONS
Modified: MOAB/trunk/parallel/WriteHDF5Parallel.cpp
===================================================================
--- MOAB/trunk/parallel/WriteHDF5Parallel.cpp 2008-03-14 14:15:30 UTC (rev 1658)
+++ MOAB/trunk/parallel/WriteHDF5Parallel.cpp 2008-03-14 14:17:31 UTC (rev 1659)
@@ -209,6 +209,9 @@
}
}
+MBWriterIface* WriteHDF5Parallel::factory( MBInterface* iface )
+ { return new WriteHDF5Parallel( iface ); }
+
void WriteHDF5Parallel::MultiProcSetTags::add( const std::string& name )
{ list.push_back( Data(name) ); }
@@ -426,8 +429,12 @@
MBErrorCode WriteHDF5Parallel::create_file( const char* filename,
bool overwrite,
std::vector<std::string>& qa_records,
- int dimension )
+ int dimension,
+ bool parallel )
{
+ if (!parallel)
+ return WriteHDF5::create_file(filename, overwrite, qa_records, dimension, false );
+
MBErrorCode rval;
int result;
mhdf_Status status;
Modified: MOAB/trunk/parallel/WriteHDF5Parallel.hpp
===================================================================
--- MOAB/trunk/parallel/WriteHDF5Parallel.hpp 2008-03-14 14:15:30 UTC (rev 1658)
+++ MOAB/trunk/parallel/WriteHDF5Parallel.hpp 2008-03-14 14:17:31 UTC (rev 1659)
@@ -16,6 +16,8 @@
class MB_DLL_EXPORT WriteHDF5Parallel : public WriteHDF5
{
public:
+
+ static MBWriterIface* factory( MBInterface* );
/** Consturctor
*
@@ -97,7 +99,8 @@
virtual MBErrorCode create_file( const char* filename,
bool overwrite,
std::vector<std::string>& qa_records,
- int dimension = 3 );
+ int dimension = 3,
+ bool parallel = false );
//! Figure out which mesh local mesh is duplicated on
//! remote processors and which processor will write
Modified: MOAB/trunk/test/h5file/varlen_ll.cpp
===================================================================
--- MOAB/trunk/test/h5file/varlen_ll.cpp 2008-03-14 14:15:30 UTC (rev 1658)
+++ MOAB/trunk/test/h5file/varlen_ll.cpp 2008-03-14 14:17:31 UTC (rev 1659)
@@ -4,12 +4,11 @@
*/
#include "MBCore.hpp"
-#define TEST_WITH_MPI
#include "TestUtil.hpp"
-#include "WriteHDF5Parallel.hpp"
-#include "FileOptions.hpp"
#include "MBParallelConventions.h"
+#include <mpi.h>
+
bool keep_files = false; // controllable with -k flag
bool wait_on_start = false; // start all procs and wait for input on root node
@@ -95,14 +94,7 @@
CHECK_ERR(rval);
// Write file
- WriteHDF5Parallel writer( &mb );
- FileOptions opts("");
- std::vector<std::string> qa_records;
- rval = writer.write_file( filename,
- true,
- opts,
- 0, 0,
- qa_records );
+ rval = mb.write_file( filename, "MOAB", "PARALLEL=FORMAT" );
CHECK_ERR(rval);
// Read file. We only reset and re-read the file on the
More information about the moab-dev
mailing list