1 #ifndef WRITE_HDF5_PARALLEL_HPP
2 #define WRITE_HDF5_PARALLEL_HPP
3
4 #include "WriteHDF5.hpp"
5 #include <H5Spublic.h>
6 #include <map>
7
8 namespace moab
9 {
10
11 struct RemoteSetData;
12 class ParallelComm;
13 class IODebugTrack;
14
15 /**
16 * \brief Write MOAB HDF5 file in parallel.
17 * \author Jason Kraftcheck
18 * \data 22 July 2004
19 */
20 class WriteHDF5Parallel : public WriteHDF5
21 {
22 public:
23 static WriterIface* factory( Interface* );
24
25 /** Consturctor
26 */
27 WriteHDF5Parallel( Interface* iface );
28
29 virtual ~WriteHDF5Parallel();
30
31 protected:
32 virtual void debug_barrier_line( int lineno );
33
34 virtual void print_times( const double* times ) const;
35
36 //! Called by normal (non-parallel) writer. Sets up
37 //! necessary data for parallel write.
38 virtual ErrorCode parallel_create_file( const char* filename,
39 bool overwrite,
40 const std::vector< std::string >& qa_records,
41 const FileOptions& opts,
42 const Tag* user_tag_list = 0,
43 int user_tag_count = 0,
44 int dimension = 3,
45 double* times = 0 );
46
47 //! Figure out which mesh local mesh is duplicated on
48 //! remote processors and which processor will write
49 //! that mesh.
50 //!\param non_local_ents Output list of entities that are not to
51 //! be written by this processor but are
52 //! referenced by other entities that are
53 //! to be written.
54 ErrorCode gather_interface_meshes( Range& non_local_ents );
55
56 //! For entities that will be written by another
57 //! processor but are referenced by entities on this
58 //! processor, get the file Ids that will be assigned
59 //! to those so they can be referenced by
60 //! entities to be written on this processor.
61 //!\param non_local_ents List of entities that are not to
62 //! be written by this processor but are
63 //! referenced by other entities that are
64 //! to be written.
65 ErrorCode exchange_file_ids( const Range& non_local_ents );
66
67 //! Get remote ids for shared sets
68 ErrorCode communicate_shared_set_ids( const Range& owned, const Range& remote );
69
70 //! Pack set data for communication.
71 //!
72 //! If set_data_length is insufficient for the set data,
73 //! the length entries at indices 1, 2, and 3 of set_data
74 //! will be set with the necessary lengths, but no data will
75 //! be written to set_data beyond that.
76 ErrorCode pack_set( Range::const_iterator set, unsigned long* set_data, size_t set_data_length );
77
78 //! Unpack set data from communication
79 ErrorCode unpack_set( EntityHandle set, const unsigned long* set_data, size_t set_data_length );
80
81 //! Communicate set contents between processors such that each
82 //! owner knows the contents, parents, & child lists from all
83 //! processors that have a copy of the set.
84 ErrorCode communicate_shared_set_data( const Range& owned, const Range& remote );
85
86 //! Create the node table in the file.
87 ErrorCode create_node_table( int dimension );
88
89 //! Communicate with other processors to negotiate
90 //! the types of elements that will be written
91 //! (the union of the types defined on each proc.)
92 ErrorCode negotiate_type_list();
93
94 //! Create tables to hold element connectivity
95 ErrorCode create_element_tables();
96
97 //! Create tables to hold element adjacencies.
98 ErrorCode create_adjacency_tables();
99
100 //! Create tables for mesh sets
101 ErrorCode create_meshset_tables( double* times );
102
103 //! Write tag descriptions and create tables to hold tag data.
104 ErrorCode create_tag_tables();
105
106 //! Remove any remote mesh entities from the passed range.
107 void remove_remote_entities( EntityHandle relative, Range& range );
108 void remove_remote_entities( EntityHandle relative, std::vector< EntityHandle >& vect );
109 void remove_remote_sets( EntityHandle relative, Range& range );
110 void remove_remote_sets( EntityHandle relative, std::vector< EntityHandle >& vect );
111
112 //! get any existing tags which aren't excluded and add to shared set tags
113 ErrorCode get_sharedset_tags();
114
115 ErrorCode append_serial_tag_data( std::vector< unsigned char >& buffer, const WriteHDF5::TagDesc& tag );
116
117 //! helper function for create_tag_tables
118 ErrorCode check_serial_tag_data( const std::vector< unsigned char >& buffer,
119 std::vector< TagDesc* >* missing = 0,
120 std::vector< TagDesc* >* newlist = 0 );
121
122 /**\brief Argument ot create_dataset */
123 struct DataSetCreator
124 {
125 virtual ErrorCode operator()( WriteHDF5* writer,
126 long data_set_size,
127 const ExportSet* group,
128 long& start_id_out ) const = 0;
129 };
130 struct NoopDescCreator : public DataSetCreator
131 {
132 ErrorCode operator()( WriteHDF5*, long, const ExportSet*, long& start_id ) const
133 {
134 start_id = -1;
135 return MB_SUCCESS;
136 }
137 };
138
139 /**\brief Do typical communication for dataset creation
140 *
141 * Given the number of entities each processor intends to write,
142 * do necessary communication and create dataset on root, passing
143 * back misc info to each proc.
144 *
145 *\param creator Functor to do actual dataset creation. Used
146 * only on root process.
147 *\param num_datasets The number of datasets to create.
148 *\param groups Third argument passed to DataSetCreator.
149 * Array of length \c num_datasets pr NULL.
150 *\param num_owned_entities The number of entities this proc will write.
151 * Array of length \c num_datasets .
152 *\param offsets_out Output: The offset in the dataset at which
153 * this process should write.
154 * Array of length \c num_datasets .
155 *\param max_proc_ents_out Output: The maximun number of entities that
156 * any proc will write
157 * Array of length \c num_datasets .
158 *\param total_ents_out Output: The size of the created dataset (sum
159 * of counts over all procs)
160 * Array of length \c num_datasets .
161 *\param first_ids_out Output: The first ID of the first entity in the
162 * data set. First ID for this proc's entities is
163 * first_id_out+offset_out
164 * Array of length \c num_datasets or NULL.
165 */
166 ErrorCode create_dataset( int num_datasets,
167 const long* num_owned_entities,
168 long* offsets_out,
169 long* max_proc_ents_out,
170 long* total_ents_out,
171 const DataSetCreator& creator = NoopDescCreator(),
172 ExportSet* groups[] = 0,
173 wid_t* first_ids_out = NULL );
174
175 void print_shared_sets();
176 void print_set_sharing_data( const Range& range, const char* label, Tag idt );
177
178 private:
179 //! pcomm controlling parallel nature of mesh
180 ParallelComm* myPcomm;
181
182 //! whether this instance allocated (and dtor should delete) the pcomm
183 bool pcommAllocated;
184
185 //! Operation to use to append hyperslab selections
186 H5S_seloper_t hslabOp;
187 };
188
189 } // namespace moab
190
191 #endif