MOAB: Mesh Oriented datABase  (version 5.2.1)
WriteHDF5Parallel.hpp
Go to the documentation of this file.
00001 #ifndef WRITE_HDF5_PARALLEL_HPP
00002 #define WRITE_HDF5_PARALLEL_HPP
00003 
00004 #include "WriteHDF5.hpp"
00005 #include <H5Spublic.h>
00006 #include <map>
00007 
00008 namespace moab
00009 {
00010 
00011 struct RemoteSetData;
00012 class ParallelComm;
00013 class IODebugTrack;
00014 
00015 /**
00016  * \brief Write MOAB HDF5 file in parallel.
00017  * \author Jason Kraftcheck
00018  * \data   22 July 2004
00019  */
00020 class WriteHDF5Parallel : public WriteHDF5
00021 {
00022   public:
00023     static WriterIface* factory( Interface* );
00024 
00025     /** Consturctor
00026      */
00027     WriteHDF5Parallel( Interface* iface );
00028 
00029     virtual ~WriteHDF5Parallel();
00030 
00031   protected:
00032     virtual void debug_barrier_line( int lineno );
00033 
00034     virtual void print_times( const double* times ) const;
00035 
00036     //! Called by normal (non-parallel) writer.  Sets up
00037     //! necessary data for parallel write.
00038     virtual ErrorCode parallel_create_file( const char* filename, bool overwrite,
00039                                             const std::vector< std::string >& qa_records, const FileOptions& opts,
00040                                             const Tag* user_tag_list = 0, int user_tag_count = 0, int dimension = 3,
00041                                             double* times = 0 );
00042 
00043     //! Figure out which mesh local mesh is duplicated on
00044     //! remote processors and which processor will write
00045     //! that mesh.
00046     //!\param non_local_ents Output list of entities that are not to
00047     //!                  be written by this processor but are
00048     //!                  referenced by other entities that are
00049     //!                  to be written.
00050     ErrorCode gather_interface_meshes( Range& non_local_ents );
00051 
00052     //! For entities that will be written by another
00053     //! processor but are referenced by entities on this
00054     //! processor, get the file Ids that will be assigned
00055     //! to those so they can be referenced by
00056     //! entities to be written on this processor.
00057     //!\param non_local_ents List of entities that are not to
00058     //!                  be written by this processor but are
00059     //!                  referenced by other entities that are
00060     //!                  to be written.
00061     ErrorCode exchange_file_ids( const Range& non_local_ents );
00062 
00063     //! Get remote ids for shared sets
00064     ErrorCode communicate_shared_set_ids( const Range& owned, const Range& remote );
00065 
00066     //! Pack set data for communication.
00067     //!
00068     //! If set_data_length is insufficient for the set data,
00069     //! the length entries at indices 1, 2, and 3 of set_data
00070     //! will be set with the necessary lengths, but no data will
00071     //! be written to set_data beyond that.
00072     ErrorCode pack_set( Range::const_iterator set, unsigned long* set_data, size_t set_data_length );
00073 
00074     //! Unpack set data from communication
00075     ErrorCode unpack_set( EntityHandle set, const unsigned long* set_data, size_t set_data_length );
00076 
00077     //! Communicate set contents between processors such that each
00078     //! owner knows the contents, parents, & child lists from all
00079     //! processors that have a copy of the set.
00080     ErrorCode communicate_shared_set_data( const Range& owned, const Range& remote );
00081 
00082     //! Create the node table in the file.
00083     ErrorCode create_node_table( int dimension );
00084 
00085     //! Communicate with other processors to negotiate
00086     //! the types of elements that will be written
00087     //! (the union of the types defined on each proc.)
00088     ErrorCode negotiate_type_list();
00089 
00090     //! Create tables to hold element connectivity
00091     ErrorCode create_element_tables();
00092 
00093     //! Create tables to hold element adjacencies.
00094     ErrorCode create_adjacency_tables();
00095 
00096     //! Create tables for mesh sets
00097     ErrorCode create_meshset_tables( double* times );
00098 
00099     //! Write tag descriptions and create tables to hold tag data.
00100     ErrorCode create_tag_tables();
00101 
00102     //! Remove any remote mesh entities from the passed range.
00103     void remove_remote_entities( EntityHandle relative, Range& range );
00104     void remove_remote_entities( EntityHandle relative, std::vector< EntityHandle >& vect );
00105     void remove_remote_sets( EntityHandle relative, Range& range );
00106     void remove_remote_sets( EntityHandle relative, std::vector< EntityHandle >& vect );
00107 
00108     //! get any existing tags which aren't excluded and add to shared set tags
00109     ErrorCode get_sharedset_tags();
00110 
00111     ErrorCode append_serial_tag_data( std::vector< unsigned char >& buffer, const WriteHDF5::TagDesc& tag );
00112 
00113     //! helper function for create_tag_tables
00114     ErrorCode check_serial_tag_data( const std::vector< unsigned char >& buffer, std::vector< TagDesc* >* missing = 0,
00115                                      std::vector< TagDesc* >* newlist = 0 );
00116 
00117     /**\brief Argument ot create_dataset */
00118     struct DataSetCreator
00119     {
00120         virtual ErrorCode operator()( WriteHDF5* writer, long data_set_size, const ExportSet* group,
00121                                       long& start_id_out ) const = 0;
00122     };
00123     struct NoopDescCreator : public DataSetCreator
00124     {
00125         ErrorCode operator()( WriteHDF5*, long, const ExportSet*, long& start_id ) const
00126         {
00127             start_id = -1;
00128             return MB_SUCCESS;
00129         }
00130     };
00131 
00132     /**\brief Do typical communication for dataset creation
00133      *
00134      * Given the number of entities each processor intends to write,
00135      * do necessary communication and create dataset on root, passing
00136      * back misc info to each proc.
00137      *
00138      *\param creator             Functor to do actual dataset creation.  Used
00139      *                           only on root process.
00140      *\param num_datasets        The number of datasets to create.
00141      *\param groups              Third argument passed to DataSetCreator.
00142      *                           Array of length \c num_datasets pr NULL.
00143      *\param num_owned_entities  The number of entities this proc will write.
00144      *                           Array of length \c num_datasets .
00145      *\param offsets_out         Output: The offset in the dataset at which
00146      *                           this process should write.
00147      *                           Array of length \c num_datasets .
00148      *\param max_proc_ents_out   Output: The maximun number of entities that
00149      *                           any proc will write
00150      *                           Array of length \c num_datasets .
00151      *\param total_ents_out      Output: The size of the created dataset (sum
00152      *                           of counts over all procs)
00153      *                           Array of length \c num_datasets .
00154      *\param first_ids_out       Output: The first ID of the first entity in the
00155      *                           data set.  First ID for this proc's entities is
00156      *                           first_id_out+offset_out
00157      *                           Array of length \c num_datasets or NULL.
00158      */
00159     ErrorCode create_dataset( int num_datasets, const long* num_owned_entities, long* offsets_out,
00160                               long* max_proc_ents_out, long* total_ents_out,
00161                               const DataSetCreator& creator = NoopDescCreator(), ExportSet* groups[] = 0,
00162                               wid_t* first_ids_out = NULL );
00163 
00164     void print_shared_sets();
00165     void print_set_sharing_data( const Range& range, const char* label, Tag idt );
00166 
00167   private:
00168     //! pcomm controlling parallel nature of mesh
00169     ParallelComm* myPcomm;
00170 
00171     //! whether this instance allocated (and dtor should delete) the pcomm
00172     bool pcommAllocated;
00173 
00174     //! Operation to use to append hyperslab selections
00175     H5S_seloper_t hslabOp;
00176 };
00177 
00178 }  // namespace moab
00179 
00180 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines