Branch data Line data Source code
1 : : #include "ReadParallel.hpp"
2 : : #include "moab/Core.hpp"
3 : : #include "moab/ProcConfig.hpp"
4 : : #include "moab/FileOptions.hpp"
5 : : #include "moab/Error.hpp"
6 : : #include "moab/ReaderWriterSet.hpp"
7 : : #include "moab/ReadUtilIface.hpp"
8 : : #include "moab/ParallelComm.hpp"
9 : : #include "MBParallelConventions.h"
10 : :
11 : : #include <iostream>
12 : : #include <iomanip>
13 : : #include <iterator>
14 : : #include <sstream>
15 : : #include <algorithm>
16 : : #include <assert.h>
17 : :
18 : : namespace moab
19 : : {
20 : :
21 : : const bool debug = false;
22 : :
23 : : const char* ReadParallel::ParallelActionsNames[] = { "PARALLEL READ",
24 : : "PARALLEL READ PART",
25 : : "PARALLEL BROADCAST",
26 : : "PARALLEL DELETE NONLOCAL",
27 : : "PARALLEL CHECK_GIDS_SERIAL",
28 : : "PARALLEL GET_FILESET_ENTS",
29 : : "PARALLEL RESOLVE_SHARED_ENTS",
30 : : "PARALLEL EXCHANGE_GHOSTS",
31 : : "PARALLEL RESOLVE_SHARED_SETS",
32 : : "PARALLEL_AUGMENT_SETS_WITH_GHOSTS",
33 : : "PARALLEL PRINT_PARALLEL",
34 : : "PARALLEL_CREATE_TRIVIAL_PARTITION",
35 : : "PARALLEL_CORRECT_THIN_GHOST_LAYERS" };
36 : :
37 : : const char* ReadParallel::parallelOptsNames[] = { "NONE", "BCAST", "BCAST_DELETE", "READ_DELETE", "READ_PART", "", 0 };
38 : :
39 : 21 : ReadParallel::ReadParallel( Interface* impl, ParallelComm* pc )
40 : 21 : : mbImpl( impl ), myPcomm( pc ), myDebug( "ReadPara", std::cerr )
41 : : {
42 [ + + ]: 21 : if( !myPcomm )
43 : : {
44 [ + - ]: 2 : myPcomm = ParallelComm::get_pcomm( mbImpl, 0 );
45 [ - + ][ # # ]: 2 : if( NULL == myPcomm ) myPcomm = new ParallelComm( mbImpl, MPI_COMM_WORLD );
[ # # ]
46 : : }
47 [ + - ][ + - ]: 21 : myDebug.set_rank( myPcomm->proc_config().proc_rank() );
[ + - ]
48 : : if( debug ) // For backwards compatibility, enable all debug output if constant is true
49 : : myDebug.set_verbosity( 10 );
50 : :
51 [ + - ]: 21 : impl->query_interface( mError );
52 : 21 : }
53 : :
54 : 21 : ErrorCode ReadParallel::load_file( const char** file_names, const int num_files, const EntityHandle* file_set,
55 : : const FileOptions& opts, const ReaderIface::SubsetList* subset_list,
56 : : const Tag* file_id_tag )
57 : : {
58 : : int tmpval;
59 [ + - ][ - + ]: 21 : if( MB_SUCCESS == opts.get_int_option( "DEBUG_PIO", 1, tmpval ) )
60 : : {
61 [ # # ]: 0 : myDebug.set_verbosity( tmpval );
62 [ # # ]: 0 : myPcomm->set_debug_verbosity( tmpval );
63 : : }
64 [ + - ]: 21 : myDebug.tprint( 1, "Setting up...\n" );
65 : :
66 : : // Get parallel settings
67 : : int parallel_mode;
68 [ + - ]: 21 : ErrorCode result = opts.match_option( "PARALLEL", parallelOptsNames, parallel_mode );
69 [ - + ][ # # ]: 21 : if( MB_FAILURE == result ) { MB_SET_ERR( MB_FAILURE, "Unexpected value for 'PARALLEL' option" ); }
[ # # ][ # # ]
[ # # ][ # # ]
70 [ - + ]: 21 : else if( MB_ENTITY_NOT_FOUND == result )
71 : : {
72 : 0 : parallel_mode = 0;
73 : : }
74 : :
75 : : // Get partition setting
76 : : bool distrib;
77 [ + - ]: 21 : std::string partition_tag_name;
78 [ + - ]: 21 : result = opts.get_option( "PARTITION", partition_tag_name );
79 [ - + ]: 21 : if( MB_ENTITY_NOT_FOUND == result )
80 : : {
81 : 0 : distrib = false;
82 [ # # ]: 0 : partition_tag_name = "";
83 : : }
84 : : else
85 : : {
86 : 21 : distrib = true;
87 [ - + ][ # # ]: 21 : if( partition_tag_name.empty() ) partition_tag_name = PARALLEL_PARTITION_TAG_NAME;
88 : :
89 : : // Also get deprecated PARTITION_DISTRIBUTE option
90 : : // so that higher-level code doesn't return an error
91 : : // due to an unrecognized option
92 [ + - ]: 21 : opts.get_null_option( "PARTITION_DISTRIBUTE" );
93 : : }
94 : :
95 : : // Get partition tag value(s), if any, and whether they're to be
96 : : // distributed or assigned
97 [ + - ]: 42 : std::vector< int > partition_tag_vals;
98 [ + - ]: 21 : opts.get_ints_option( "PARTITION_VAL", partition_tag_vals );
99 : :
100 : : // see if partition tag name is "TRIVIAL", if the tag exists
101 : 21 : bool create_trivial_partition = false;
102 [ + - ][ + - ]: 21 : if( partition_tag_name == std::string( "TRIVIAL" ) )
[ - + ]
103 : : {
104 : : Tag ttag; // see if the trivial tag exists
105 [ # # ]: 0 : result = mbImpl->tag_get_handle( partition_tag_name.c_str(), ttag );
106 [ # # ]: 0 : if( MB_TAG_NOT_FOUND == result ) create_trivial_partition = true;
107 : : }
108 : : // See if we need to report times
109 : 21 : bool cputime = false;
110 [ + - ]: 21 : result = opts.get_null_option( "CPUTIME" );
111 [ - + ]: 21 : if( MB_SUCCESS == result ) cputime = true;
112 : :
113 : : // See if we need to report times
114 : 21 : bool print_parallel = false;
115 [ + - ]: 21 : result = opts.get_null_option( "PRINT_PARALLEL" );
116 [ - + ]: 21 : if( MB_SUCCESS == result ) print_parallel = true;
117 : :
118 : : // Get ghosting options
119 [ + - ]: 42 : std::string ghost_str;
120 : 21 : int bridge_dim, ghost_dim = -1, num_layers, addl_ents = 0;
121 [ + - ]: 21 : result = opts.get_str_option( "PARALLEL_GHOSTS", ghost_str );
122 [ - + ]: 21 : if( MB_TYPE_OUT_OF_RANGE == result )
123 : : {
124 : 0 : ghost_dim = 3;
125 : 0 : bridge_dim = 0;
126 : 0 : num_layers = 1;
127 : : }
128 [ - + ]: 21 : else if( MB_SUCCESS == result )
129 : : {
130 : 0 : int num_fields = sscanf( ghost_str.c_str(), "%d.%d.%d.%d", &ghost_dim, &bridge_dim, &num_layers, &addl_ents );
131 [ # # ][ # # ]: 0 : if( 3 > num_fields ) { MB_SET_ERR( MB_FAILURE, "Didn't read 3 fields from PARALLEL_GHOSTS string" ); }
[ # # ][ # # ]
[ # # ][ # # ]
132 : : }
133 : :
134 : : // Get resolve_shared_ents option
135 [ + - ]: 42 : std::string shared_str;
136 : 21 : int resolve_dim = -2, shared_dim = -1;
137 [ + - ]: 21 : result = opts.get_str_option( "PARALLEL_RESOLVE_SHARED_ENTS", shared_str );
138 [ + - ]: 21 : if( MB_TYPE_OUT_OF_RANGE == result )
139 : : {
140 : 21 : resolve_dim = -1;
141 : 21 : shared_dim = -1;
142 : : }
143 [ # # ]: 0 : else if( MB_SUCCESS == result )
144 : : {
145 : 0 : int num_fields = sscanf( shared_str.c_str(), "%d.%d", &resolve_dim, &shared_dim );
146 [ # # ]: 0 : if( 2 != num_fields )
147 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Didn't read 2 fields from PARALLEL_RESOLVE_SHARED_ENTS string" ); }
[ # # ][ # # ]
[ # # ]
148 : : }
149 : :
150 : : // Get skip augmenting with ghosts option
151 : 21 : bool skip_augment = false;
152 [ + - ]: 21 : result = opts.get_null_option( "SKIP_AUGMENT_WITH_GHOSTS" );
153 [ - + ]: 21 : if( MB_SUCCESS == result ) skip_augment = true;
154 : :
155 : 21 : bool correct_thin_ghosts = false;
156 [ + - ]: 21 : result = opts.get_null_option( "PARALLEL_THIN_GHOST_LAYER" );
157 [ - + ]: 21 : if( MB_SUCCESS == result ) correct_thin_ghosts = true;
158 : :
159 : : // Get MPI IO processor rank
160 : : int reader_rank;
161 [ + - ]: 21 : result = opts.get_int_option( "MPI_IO_RANK", reader_rank );
162 [ + - ]: 21 : if( MB_ENTITY_NOT_FOUND == result )
163 : 21 : reader_rank = 0;
164 [ # # ]: 0 : else if( MB_SUCCESS != result )
165 : : {
166 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Unexpected value for 'MPI_IO_RANK' option" );
[ # # ][ # # ]
[ # # ]
167 : : }
168 : :
169 : : // Now that we've parsed all the parallel options, make an instruction queue
170 [ + - ]: 42 : std::vector< int > pa_vec;
171 [ + - ][ + - ]: 21 : bool is_reader = ( reader_rank == (int)myPcomm->proc_config().proc_rank() );
172 : :
173 : 21 : bool partition_by_rank = false;
174 [ + - ][ - + ]: 21 : if( MB_SUCCESS == opts.get_null_option( "PARTITION_BY_RANK" ) )
175 : : {
176 : 0 : partition_by_rank = true;
177 [ # # ]: 0 : if( !partition_tag_vals.empty() )
178 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FAILURE, "Cannot specify both PARTITION_VALS and PARTITION_BY_RANK" ); }
[ # # ][ # # ]
[ # # ]
179 : : }
180 : :
181 : : double factor_seq;
182 [ + - ][ - + ]: 21 : if( MB_SUCCESS == opts.get_real_option( "PARALLEL_SEQUENCE_FACTOR", factor_seq ) )
183 : : {
184 [ # # ][ # # ]: 0 : if( factor_seq < 1. ) MB_SET_ERR( MB_FAILURE, "cannot have sequence factor less than 1." );
[ # # ][ # # ]
[ # # ][ # # ]
185 [ # # ]: 0 : mbImpl->set_sequence_multiplier( factor_seq );
186 : : }
187 [ - - + + : 21 : switch( parallel_mode )
- ]
188 : : {
189 : : case POPT_BCAST:
190 [ # # ]: 0 : myDebug.print( 1, "Read mode is BCAST\n" );
191 [ # # ]: 0 : if( is_reader )
192 : : {
193 [ # # ]: 0 : pa_vec.push_back( PA_READ );
194 [ # # ]: 0 : pa_vec.push_back( PA_CHECK_GIDS_SERIAL );
195 [ # # ]: 0 : pa_vec.push_back( PA_GET_FILESET_ENTS );
196 : : }
197 [ # # ]: 0 : pa_vec.push_back( PA_BROADCAST );
198 [ # # ][ # # ]: 0 : if( !is_reader ) pa_vec.push_back( PA_GET_FILESET_ENTS );
199 : 0 : break;
200 : :
201 : : case POPT_BCAST_DELETE:
202 [ # # ]: 0 : myDebug.print( 1, "Read mode is BCAST_DELETE\n" );
203 [ # # ]: 0 : if( is_reader )
204 : : {
205 [ # # ]: 0 : pa_vec.push_back( PA_READ );
206 [ # # ]: 0 : pa_vec.push_back( PA_CHECK_GIDS_SERIAL );
207 [ # # ]: 0 : pa_vec.push_back( PA_GET_FILESET_ENTS );
208 [ # # ][ # # ]: 0 : if( create_trivial_partition ) pa_vec.push_back( PA_CREATE_TRIVIAL_PARTITION );
209 : : }
210 [ # # ]: 0 : pa_vec.push_back( PA_BROADCAST );
211 [ # # ][ # # ]: 0 : if( !is_reader ) pa_vec.push_back( PA_GET_FILESET_ENTS );
212 [ # # ]: 0 : pa_vec.push_back( PA_DELETE_NONLOCAL );
213 : 0 : break;
214 : :
215 : : case POPT_DEFAULT:
216 : : case POPT_READ_DELETE:
217 [ + - ]: 19 : myDebug.print( 1, "Read mode is READ_DELETE\n" );
218 [ + - ]: 19 : pa_vec.push_back( PA_READ );
219 [ + - ]: 19 : pa_vec.push_back( PA_CHECK_GIDS_SERIAL );
220 [ + - ]: 19 : pa_vec.push_back( PA_GET_FILESET_ENTS );
221 [ + - ]: 19 : pa_vec.push_back( PA_DELETE_NONLOCAL );
222 : 19 : break;
223 : :
224 : : case POPT_READ_PART:
225 [ + - ]: 2 : myDebug.print( 1, "Read mode is READ_PART\n" );
226 [ + - ]: 2 : pa_vec.push_back( PA_READ_PART );
227 : 2 : break;
228 : :
229 : : default:
230 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Unexpected parallel read mode" );
[ # # ][ # # ]
[ # # ]
231 : : }
232 : :
233 [ + - ][ + - ]: 21 : if( -2 != resolve_dim ) pa_vec.push_back( PA_RESOLVE_SHARED_ENTS );
234 : :
235 [ - + ][ # # ]: 21 : if( -1 != ghost_dim ) pa_vec.push_back( PA_EXCHANGE_GHOSTS );
236 : :
237 [ + - ]: 21 : if( -2 != resolve_dim )
238 : : {
239 [ + - ]: 21 : pa_vec.push_back( PA_RESOLVE_SHARED_SETS );
240 [ - + ][ # # ]: 21 : if( -1 != ghost_dim && !skip_augment ) pa_vec.push_back( PA_AUGMENT_SETS_WITH_GHOSTS );
[ # # ]
241 [ - + ][ # # ]: 21 : if( -1 != ghost_dim && correct_thin_ghosts ) pa_vec.push_back( PA_CORRECT_THIN_GHOSTS );
[ # # ]
242 : : }
243 : :
244 [ - + ][ # # ]: 21 : if( print_parallel ) pa_vec.push_back( PA_PRINT_PARALLEL );
245 : :
246 : : result = load_file( file_names, num_files, file_set, parallel_mode, partition_tag_name, partition_tag_vals, distrib,
247 : : partition_by_rank, pa_vec, opts, subset_list, file_id_tag, reader_rank, cputime, resolve_dim,
248 [ + - ][ + + ]: 21 : shared_dim, ghost_dim, bridge_dim, num_layers, addl_ents );MB_CHK_ERR( result );
[ + - ][ + - ]
249 : :
250 [ - + ][ # # ]: 19 : if( parallel_mode == POPT_BCAST_DELETE && !is_reader ) opts.mark_all_seen();
[ # # ]
251 : :
252 : 40 : return MB_SUCCESS;
253 : : }
254 : :
255 : 21 : ErrorCode ReadParallel::load_file( const char** file_names, const int num_files, const EntityHandle* file_set_ptr,
256 : : int /*parallel_mode*/, std::string& partition_tag_name,
257 : : std::vector< int >& partition_tag_vals, bool distrib, bool partition_by_rank,
258 : : std::vector< int >& pa_vec, const FileOptions& opts,
259 : : const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag,
260 : : const int reader_rank, const bool cputime, const int resolve_dim,
261 : : const int shared_dim, const int ghost_dim, const int bridge_dim,
262 : : const int num_layers, const int addl_ents )
263 : : {
264 : 21 : ErrorCode result = MB_SUCCESS;
265 [ - + ][ # # ]: 21 : if( myPcomm == NULL ) myPcomm = new ParallelComm( mbImpl, MPI_COMM_WORLD );
[ # # ]
266 : :
267 [ + - ]: 21 : Range entities;
268 : 21 : Tag file_set_tag = 0;
269 : 21 : int other_sets = 0;
270 [ + - ]: 21 : ReaderWriterSet::iterator iter;
271 [ + - ][ + - ]: 42 : Range other_file_sets, file_sets;
272 [ - + ]: 21 : Core* impl = dynamic_cast< Core* >( mbImpl );
273 : :
274 [ + - ]: 42 : std::vector< double > act_times( pa_vec.size() + 1 );
275 : 21 : std::vector< int >::iterator vit;
276 : : int i, j;
277 [ + - ][ + - ]: 21 : act_times[0] = MPI_Wtime();
278 : :
279 : : // Make a new set for the parallel read
280 : : EntityHandle file_set;
281 [ + + ][ - + ]: 21 : if( !file_set_ptr || !( *file_set_ptr ) )
282 : : {
283 [ + - ][ - + ]: 19 : result = mbImpl->create_meshset( MESHSET_SET, file_set );MB_CHK_SET_ERR( result, "Trouble creating file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
284 : : }
285 : : else
286 : 2 : file_set = *file_set_ptr;
287 : :
288 : 21 : bool i_read = false;
289 : 21 : Tag id_tag = 0;
290 : 21 : bool use_id_tag = false;
291 [ + - ]: 42 : Range ents;
292 : :
293 [ + - ][ + - ]: 135 : for( i = 1, vit = pa_vec.begin(); vit != pa_vec.end(); ++vit, i++ )
[ + + ]
294 : : {
295 : 116 : ErrorCode tmp_result = MB_SUCCESS;
296 [ + - ][ + + : 116 : switch( *vit )
+ - - + +
+ - + - -
- - ]
297 : : {
298 : : //==================
299 : : case PA_READ:
300 : 19 : i_read = true;
301 : :
302 [ + + ]: 38 : for( j = 0; j < num_files; j++ )
303 : : {
304 [ + - ]: 19 : myDebug.tprintf( 1, "Reading file: \"%s\"\n", file_names[j] );
305 : :
306 : : EntityHandle new_file_set;
307 [ + - ][ - + ]: 19 : result = mbImpl->create_meshset( MESHSET_SET, new_file_set );MB_CHK_SET_ERR( result, "Trouble creating file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
308 [ + - ]: 19 : tmp_result = impl->serial_load_file( file_names[j], &new_file_set, opts, subset_list, file_id_tag );
309 [ - + ]: 19 : if( MB_SUCCESS != tmp_result ) break;
310 : :
311 : : // Put the contents of each file set for the reader into the
312 : : // file set for the parallel read
313 [ - + ]: 19 : assert( 0 != new_file_set );
314 [ + - ]: 19 : Range all_ents;
315 [ + - ]: 19 : tmp_result = mbImpl->get_entities_by_handle( new_file_set, all_ents );
316 [ - + ]: 19 : if( MB_SUCCESS != tmp_result ) break;
317 [ + - ]: 19 : all_ents.insert( new_file_set );
318 [ + - ]: 19 : tmp_result = mbImpl->add_entities( file_set, all_ents );
319 [ - + ][ + - ]: 19 : if( MB_SUCCESS != tmp_result ) break;
320 : 19 : }
321 [ - + ]: 19 : if( MB_SUCCESS != tmp_result ) break;
322 : :
323 : : // Mark the file set for this parallel reader
324 : : tmp_result = mbImpl->tag_get_handle( "__file_set", 1, MB_TYPE_INTEGER, file_set_tag,
325 [ + - ]: 19 : MB_TAG_SPARSE | MB_TAG_CREAT );
326 [ - + ]: 19 : if( MB_SUCCESS != tmp_result ) break;
327 : :
328 [ + - ]: 19 : tmp_result = mbImpl->tag_set_data( file_set_tag, &file_set, 1, &other_sets );
329 : 19 : break;
330 : :
331 : : //==================
332 : : case PA_READ_PART: {
333 [ + - ]: 2 : myDebug.tprintf( 1, "Reading file: \"%s\"\n", file_names[0] );
334 : :
335 : 2 : i_read = true;
336 [ - + ]: 2 : if( num_files != 1 )
337 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_NOT_IMPLEMENTED, "Multiple file read not supported for READ_PART" ); }
[ # # ][ # # ]
[ # # ]
338 : :
339 : : // If we're going to resolve shared entities, then we need
340 : : // to ask the file reader to populate a tag with unique ids
341 : : // (typically file ids/indices/whatever.)
342 [ + - ][ + - ]: 2 : if( std::find( pa_vec.begin(), pa_vec.end(), PA_RESOLVE_SHARED_ENTS ) != pa_vec.end() )
[ + - ]
343 : : {
344 : 2 : use_id_tag = true;
345 [ + - ]: 2 : if( !file_id_tag )
346 : : {
347 : : // This tag is really used for resolving shared entities with crystal router
348 : : // In the end, this is an identifier that gets converted to long
349 : : // In hdf5 file reader, we also convert from hdf5 file id type to long
350 : : tmp_result = mbImpl->tag_get_handle( "", sizeof( long ), MB_TYPE_OPAQUE, id_tag,
351 [ + - ]: 2 : MB_TAG_DENSE | MB_TAG_CREAT );
352 [ - + ]: 4 : if( MB_SUCCESS != tmp_result ) break;
353 : 2 : file_id_tag = &id_tag;
354 : : }
355 : : }
356 : :
357 : 2 : ReaderIface::IDTag parts = { partition_tag_name.c_str(), 0, 0 };
358 : : ReaderIface::SubsetList sl;
359 : 2 : sl.num_parts = 0;
360 [ + - ]: 2 : int rank = myPcomm->rank();
361 [ - + ]: 2 : if( partition_by_rank )
362 : : {
363 [ # # ]: 0 : assert( partition_tag_vals.empty() );
364 : 0 : parts.tag_values = &rank;
365 : 0 : parts.num_tag_values = 1;
366 : : }
367 : : else
368 : : {
369 [ + - ]: 2 : sl.num_parts = myPcomm->size();
370 [ + - ]: 2 : sl.part_number = myPcomm->rank();
371 [ - + ]: 2 : if( !partition_tag_vals.empty() )
372 : : {
373 [ # # ]: 0 : parts.tag_values = &partition_tag_vals[0];
374 : 0 : parts.num_tag_values = partition_tag_vals.size();
375 : : }
376 : : }
377 [ + - ]: 2 : std::vector< ReaderIface::IDTag > subset;
378 [ - + ]: 2 : if( subset_list )
379 : : {
380 : : std::vector< ReaderIface::IDTag > tmplist( subset_list->tag_list,
381 [ # # ]: 0 : subset_list->tag_list + subset_list->tag_list_length );
382 [ # # ]: 0 : tmplist.push_back( parts );
383 : 0 : subset.swap( tmplist );
384 [ # # ]: 0 : sl.tag_list = &subset[0];
385 : 0 : sl.tag_list_length = subset.size();
386 : : }
387 : : else
388 : : {
389 : 2 : sl.tag_list = &parts;
390 : 2 : sl.tag_list_length = 1;
391 : : }
392 [ + - ]: 2 : tmp_result = impl->serial_load_file( *file_names, &file_set, opts, &sl, file_id_tag );
393 [ + - ]: 2 : if( MB_SUCCESS != tmp_result ) break;
394 : :
395 [ # # ]: 0 : if( !partition_tag_name.empty() )
396 : : {
397 : : Tag part_tag;
398 [ # # ]: 0 : tmp_result = impl->tag_get_handle( partition_tag_name.c_str(), 1, MB_TYPE_INTEGER, part_tag );
399 [ # # ]: 0 : if( MB_SUCCESS != tmp_result ) break;
400 : :
401 : : tmp_result = impl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &part_tag, 0, 1,
402 [ # # ][ # # ]: 2 : myPcomm->partition_sets() );
[ - + ]
403 : 0 : }
404 : : }
405 : 0 : break;
406 : :
407 : : //==================
408 : : case PA_GET_FILESET_ENTS:
409 [ + - ]: 19 : myDebug.tprint( 1, "Getting fileset entities.\n" );
410 : :
411 : : // Get entities in the file set, and add actual file set to it;
412 : : // mark the file set to make sure any receiving procs know which it is
413 [ + - ]: 19 : tmp_result = mbImpl->get_entities_by_handle( file_set, entities );
414 [ - + ]: 19 : if( MB_SUCCESS != tmp_result )
415 : : {
416 [ # # ]: 0 : entities.clear();
417 : 0 : break;
418 : : }
419 : :
420 : : // Add actual file set to entities too
421 [ + - ]: 19 : entities.insert( file_set );
422 : 19 : break;
423 : : //==================
424 : : case PA_CREATE_TRIVIAL_PARTITION: {
425 [ # # ]: 0 : myDebug.tprint( 1, "create trivial partition, for higher dim entities.\n" );
426 : : // get high dim entities (2 or 3)
427 [ # # ]: 0 : Range hi_dim_ents = entities.subset_by_dimension( 3 );
428 [ # # ][ # # ]: 0 : if( hi_dim_ents.empty() ) hi_dim_ents = entities.subset_by_dimension( 2 );
[ # # ][ # # ]
429 [ # # ][ # # ]: 0 : if( hi_dim_ents.empty() ) hi_dim_ents = entities.subset_by_dimension( 1 );
[ # # ][ # # ]
430 [ # # ][ # # ]: 0 : if( hi_dim_ents.empty() ) MB_SET_ERR( MB_FAILURE, "there are no elements of dim 1-3" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
431 : :
432 [ # # ]: 0 : size_t num_hi_ents = hi_dim_ents.size();
433 [ # # ]: 0 : unsigned int num_parts = myPcomm->size();
434 : :
435 : : // create first the trivial partition tag
436 : 0 : int dum_id = -1;
437 : : Tag ttag; // trivial tag
438 : : tmp_result = mbImpl->tag_get_handle( partition_tag_name.c_str(), 1, MB_TYPE_INTEGER, ttag,
439 [ # # ][ # # ]: 0 : MB_TAG_CREAT | MB_TAG_SPARSE, &dum_id );MB_CHK_SET_ERR( tmp_result, "Can't create trivial partition tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
440 : :
441 : : // Compute the number of high dim entities on each part
442 : 0 : size_t nPartEnts = num_hi_ents / num_parts;
443 : :
444 : : // Number of extra entities after equal split over parts
445 : 0 : int iextra = num_hi_ents % num_parts;
446 [ # # ]: 0 : Range::iterator itr = hi_dim_ents.begin();
447 [ # # ][ # # ]: 0 : for( int k = 0; k < (int)num_parts; k++ )
448 : : {
449 : : // create a mesh set, insert a subrange of entities
450 : : EntityHandle part_set;
451 [ # # ][ # # ]: 0 : tmp_result = mbImpl->create_meshset( MESHSET_SET, part_set );MB_CHK_SET_ERR( tmp_result, "Can't create part set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
452 [ # # ]: 0 : entities.insert( part_set );
453 : :
454 [ # # ][ # # ]: 0 : tmp_result = mbImpl->tag_set_data( ttag, &part_set, 1, &k );MB_CHK_SET_ERR( tmp_result, "Can't set trivial partition tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
455 [ # # ]: 0 : Range subrange;
456 : 0 : size_t num_ents_in_part = nPartEnts;
457 [ # # ]: 0 : if( i < iextra ) num_ents_in_part++;
458 [ # # ][ # # ]: 0 : for( size_t i1 = 0; i1 < num_ents_in_part; i1++, itr++ )
459 [ # # ][ # # ]: 0 : subrange.insert( *itr );
460 [ # # ][ # # ]: 0 : tmp_result = mbImpl->add_entities( part_set, subrange );MB_CHK_SET_ERR( tmp_result, "Can't add entities to trivial part " << k );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
461 [ # # ]: 0 : myDebug.tprintf( 1, "create trivial part %d with %lu entities \n", k, num_ents_in_part );
462 [ # # ][ # # ]: 0 : tmp_result = mbImpl->add_entities( file_set, &part_set, 1 );MB_CHK_SET_ERR( tmp_result, "Can't add trivial part to file set " << k );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
463 : 0 : }
464 : : }
465 : :
466 : 0 : break;
467 : : //==================
468 : : case PA_BROADCAST:
469 : : // Do the actual broadcast; if single-processor, ignore error
470 [ # # ]: 0 : myDebug.tprint( 1, "Broadcasting mesh.\n" );
471 : :
472 [ # # ][ # # ]: 0 : if( myPcomm->proc_config().proc_size() > 1 )
[ # # ]
473 : : {
474 [ # # ]: 0 : tmp_result = myPcomm->broadcast_entities( reader_rank, entities );
475 [ # # ]: 0 : if( MB_SUCCESS != tmp_result ) break;
476 : : }
477 : :
478 : : if( debug )
479 : : {
480 : : std::cerr << "Bcast done; entities:" << std::endl;
481 : : mbImpl->list_entities( 0, 0 );
482 : : }
483 : :
484 : : // Add the received entities to this fileset if I wasn't the reader
485 [ # # ][ # # ]: 0 : if( !i_read && MB_SUCCESS == tmp_result ) tmp_result = mbImpl->add_entities( file_set, entities );
[ # # ]
486 : :
487 : 0 : break;
488 : :
489 : : //==================
490 : : case PA_DELETE_NONLOCAL:
491 [ + - ]: 19 : myDebug.tprint( 1, "Deleting nonlocal entities.\n" );
492 : :
493 [ + - ]: 19 : tmp_result = delete_nonlocal_entities( partition_tag_name, partition_tag_vals, distrib, file_set );
494 : : if( debug )
495 : : {
496 : : std::cerr << "Delete nonlocal done; entities:" << std::endl;
497 : : mbImpl->list_entities( 0, 0 );
498 : : }
499 : :
500 [ + - ][ + - ]: 19 : if( MB_SUCCESS == tmp_result ) tmp_result = create_partition_sets( partition_tag_name, file_set );
501 : :
502 : 19 : break;
503 : :
504 : : //==================
505 : : case PA_CHECK_GIDS_SERIAL:
506 [ + - ]: 19 : myDebug.tprint( 1, "Checking global IDs.\n" );
507 : :
508 [ + - ]: 19 : tmp_result = myPcomm->check_global_ids( file_set, 0, 1, true, false );
509 : 19 : break;
510 : :
511 : : //==================
512 : : case PA_RESOLVE_SHARED_ENTS:
513 [ + - ]: 19 : myDebug.tprint( 1, "Resolving shared entities.\n" );
514 : :
515 [ + - ][ + - ]: 19 : if( 1 == myPcomm->size() )
516 : 19 : tmp_result = MB_SUCCESS;
517 : : else
518 : : tmp_result =
519 [ # # ][ # # ]: 0 : myPcomm->resolve_shared_ents( file_set, resolve_dim, shared_dim, use_id_tag ? file_id_tag : 0 );
520 [ - + ]: 19 : if( MB_SUCCESS != tmp_result ) break;
521 : :
522 : : #ifndef NDEBUG
523 : : // check number of owned vertices through pcomm's public interface
524 [ + - ]: 19 : tmp_result = mbImpl->get_entities_by_type( 0, MBVERTEX, ents );
525 [ + - ]: 19 : if( MB_SUCCESS == tmp_result )
526 [ + - ]: 19 : tmp_result = myPcomm->filter_pstatus( ents, PSTATUS_NOT_OWNED, PSTATUS_NOT );
527 [ + - ]: 19 : if( MB_SUCCESS == tmp_result )
528 [ + - ]: 19 : myDebug.tprintf( 1, "Proc %u reports %lu owned vertices.\n", myPcomm->proc_config().proc_rank(),
529 [ + - ][ + - ]: 38 : ents.size() );
[ + - ]
530 : : #endif
531 : 19 : break;
532 : :
533 : : //==================
534 : : case PA_EXCHANGE_GHOSTS:
535 [ # # ]: 0 : myDebug.tprint( 1, "Exchanging ghost entities.\n" );
536 : :
537 : : tmp_result = myPcomm->exchange_ghost_cells( ghost_dim, bridge_dim, num_layers, addl_ents, true, true,
538 [ # # ]: 0 : &file_set );
539 : 0 : break;
540 : :
541 : : //==================
542 : : case PA_RESOLVE_SHARED_SETS:
543 [ + - ]: 19 : myDebug.tprint( 1, "Resolving shared sets.\n" );
544 : :
545 [ + - ][ + - ]: 19 : if( 1 == myPcomm->size() )
546 : 19 : tmp_result = MB_SUCCESS;
547 : : else
548 [ # # ][ # # ]: 0 : tmp_result = myPcomm->resolve_shared_sets( file_set, use_id_tag ? file_id_tag : 0 );
549 : 19 : break;
550 : :
551 : : //==================
552 : : case PA_AUGMENT_SETS_WITH_GHOSTS:
553 [ # # ]: 0 : myDebug.tprint( 1, "Augmenting sets with ghost entities.\n" );
554 : :
555 [ # # ][ # # ]: 0 : if( 1 == myPcomm->size() )
556 : 0 : tmp_result = MB_SUCCESS;
557 : : else
558 [ # # ]: 0 : tmp_result = myPcomm->augment_default_sets_with_ghosts( file_set );
559 : 0 : break;
560 : : //==================
561 : : case PA_CORRECT_THIN_GHOSTS:
562 [ # # ]: 0 : myDebug.tprint( 1, "correcting thin ghost layers.\n" );
563 [ # # ][ # # ]: 0 : if( 2 >= myPcomm->size() ) // it is a problem only for multi-shared entities
564 : 0 : tmp_result = MB_SUCCESS;
565 : : else
566 [ # # ]: 0 : tmp_result = myPcomm->correct_thin_ghost_layers();
567 : 0 : break;
568 : : case PA_PRINT_PARALLEL:
569 [ # # ]: 0 : myDebug.tprint( 1, "Printing parallel information.\n" );
570 : :
571 [ # # ]: 0 : tmp_result = myPcomm->list_entities( 0, -1 );
572 : 0 : break;
573 : :
574 : : //==================
575 : : default:
576 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Unexpected parallel action" );
[ # # ][ # # ]
[ # # ]
577 : : } // switch (*vit)
578 : :
579 [ + + ][ + - ]: 116 : if( MB_SUCCESS != tmp_result ) { MB_SET_ERR( MB_FAILURE, "Failed in step " << ParallelActionsNames[*vit] ); }
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
580 : :
581 [ - + ][ # # ]: 114 : if( cputime ) act_times[i] = MPI_Wtime();
[ # # ]
582 : : } // for (i = 1, vit = pa_vec.begin(); vit != pa_vec.end(); ++vit, i++)
583 : :
584 [ - + ]: 19 : if( use_id_tag )
585 : : {
586 [ # # ][ # # ]: 0 : result = mbImpl->tag_delete( id_tag );MB_CHK_SET_ERR( result, "Trouble deleting id tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
587 : : }
588 : :
589 [ - + ]: 19 : if( cputime )
590 : : {
591 [ # # ]: 0 : for( i = pa_vec.size(); i > 0; i-- )
592 [ # # ][ # # ]: 0 : act_times[i] -= act_times[i - 1];
593 : :
594 : : // Replace initial time with overall time
595 [ # # ][ # # ]: 0 : act_times[0] = MPI_Wtime() - act_times[0];
[ # # ]
596 : : // Get the maximum over all procs
597 [ # # ][ # # ]: 0 : if( 0 != myPcomm->proc_config().proc_rank() )
[ # # ]
598 : : {
599 [ # # ]: 0 : MPI_Reduce( &act_times[0], 0, pa_vec.size() + 1, MPI_DOUBLE, MPI_MAX, 0,
600 [ # # ][ # # ]: 0 : myPcomm->proc_config().proc_comm() );
[ # # ]
601 : : }
602 : : else
603 : : {
604 : : #if( MPI_VERSION >= 2 )
605 [ # # ]: 0 : MPI_Reduce( MPI_IN_PLACE, &act_times[0], pa_vec.size() + 1, MPI_DOUBLE, MPI_MAX, 0,
606 [ # # ][ # # ]: 0 : myPcomm->proc_config().proc_comm() );
[ # # ]
607 : : #else
608 : : // Note, extra comm-size allocation is required
609 : : std::vector< double > act_times_tmp( pa_vec.size() + 1 );
610 : : MPI_Reduce( &act_times[0], &act_times_tmp[0], pa_vec.size() + 1, MPI_DOUBLE, MPI_MAX, 0,
611 : : myPcomm->proc_config().proc_comm() );
612 : : act_times = act_times_tmp; // extra copy here too
613 : : #endif
614 [ # # ][ # # ]: 0 : std::cout << "Parallel Read times: " << std::endl;
615 [ # # ][ # # ]: 0 : for( i = 1, vit = pa_vec.begin(); vit != pa_vec.end(); ++vit, i++ )
[ # # ]
616 [ # # ][ # # ]: 0 : std::cout << " " << act_times[i] << " " << ParallelActionsNames[*vit] << std::endl;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
617 [ # # ][ # # ]: 0 : std::cout << " " << act_times[0] << " PARALLEL TOTAL" << std::endl;
[ # # ][ # # ]
[ # # ]
618 : : }
619 : : }
620 : :
621 : 40 : return MB_SUCCESS;
622 : : }
623 : :
624 : 19 : ErrorCode ReadParallel::delete_nonlocal_entities( std::string& ptag_name, std::vector< int >& ptag_vals,
625 : : bool distribute, EntityHandle file_set )
626 : : {
627 [ + - ]: 19 : Range partition_sets;
628 : :
629 : : Tag ptag;
630 [ + - ][ - + ]: 19 : ErrorCode result = mbImpl->tag_get_handle( ptag_name.c_str(), 1, MB_TYPE_INTEGER, ptag );MB_CHK_SET_ERR( result, "Failed getting tag handle in delete_nonlocal_entities" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
631 : :
632 [ + - ][ + - ]: 19 : result = mbImpl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &ptag, NULL, 1, myPcomm->partition_sets() );MB_CHK_SET_ERR( result, "Failed to get sets with partition-type tag" );
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
633 : :
634 [ + - ][ + - ]: 19 : int proc_sz = myPcomm->proc_config().proc_size();
635 [ + - ][ + - ]: 19 : int proc_rk = myPcomm->proc_config().proc_rank();
636 : :
637 [ - + ]: 19 : if( !ptag_vals.empty() )
638 : : {
639 : : // Values input, get sets with those values
640 [ # # ]: 0 : Range tmp_sets;
641 [ # # ][ # # ]: 0 : std::vector< int > tag_vals( myPcomm->partition_sets().size() );
[ # # ][ # # ]
642 [ # # ][ # # ]: 0 : result = mbImpl->tag_get_data( ptag, myPcomm->partition_sets(), &tag_vals[0] );MB_CHK_SET_ERR( result, "Failed to get tag data for partition vals tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
643 [ # # ][ # # ]: 0 : for( std::vector< int >::iterator pit = tag_vals.begin(); pit != tag_vals.end(); ++pit )
[ # # ]
644 : : {
645 [ # # ][ # # ]: 0 : std::vector< int >::iterator pit2 = std::find( ptag_vals.begin(), ptag_vals.end(), *pit );
646 [ # # ][ # # ]: 0 : if( pit2 != ptag_vals.end() ) tmp_sets.insert( myPcomm->partition_sets()[pit - tag_vals.begin()] );
[ # # ][ # # ]
[ # # ][ # # ]
647 : : }
648 : :
649 [ # # ][ # # ]: 0 : myPcomm->partition_sets().swap( tmp_sets );
[ # # ]
650 : : }
651 : :
652 [ + - ]: 19 : if( distribute )
653 : : {
654 : : // For now, require that number of partition sets be greater
655 : : // than number of procs
656 [ + - ][ + - ]: 19 : if( myPcomm->partition_sets().size() < (unsigned int)proc_sz )
[ - + ]
657 : : {
658 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Too few parts; P = " << proc_rk << ", tag = " << ptag
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
659 : : << ", # sets = " << myPcomm->partition_sets().size() );
660 : : }
661 : :
662 [ + - ]: 19 : Range tmp_sets;
663 : : // Distribute the partition sets
664 [ + - ][ + - ]: 19 : unsigned int num_sets = myPcomm->partition_sets().size() / proc_sz;
665 [ + - ][ + - ]: 19 : unsigned int num_leftover = myPcomm->partition_sets().size() % proc_sz;
666 : 19 : int begin_set = 0;
667 [ - + ]: 19 : if( proc_rk < (int)num_leftover )
668 : : {
669 : 0 : num_sets++;
670 : 0 : begin_set = num_sets * proc_rk;
671 : : }
672 : : else
673 : 19 : begin_set = proc_rk * num_sets + num_leftover;
674 : :
675 [ + + ]: 38 : for( unsigned int i = 0; i < num_sets; i++ )
676 [ + - ][ + - ]: 19 : tmp_sets.insert( myPcomm->partition_sets()[begin_set + i] );
[ + - ]
677 : :
678 [ + - ][ + - ]: 19 : myPcomm->partition_sets().swap( tmp_sets );
679 : : }
680 : :
681 [ + - ][ + - ]: 19 : myDebug.print( 1, "My partition sets: ", myPcomm->partition_sets() );
682 : :
683 [ + - ][ - + ]: 19 : result = delete_nonlocal_entities( file_set );MB_CHK_ERR( result );
[ # # ][ # # ]
684 : :
685 : 19 : return MB_SUCCESS;
686 : : }
687 : :
688 : 19 : ErrorCode ReadParallel::create_partition_sets( std::string& ptag_name, EntityHandle file_set )
689 : : {
690 [ + - ][ + - ]: 19 : int proc_rk = myPcomm->proc_config().proc_rank();
691 : 19 : ErrorCode result = MB_SUCCESS;
692 : :
693 : : Tag ptag;
694 : :
695 : : // Tag the partition sets with a standard tag name
696 [ - + ][ # # ]: 19 : if( ptag_name.empty() ) ptag_name = PARALLEL_PARTITION_TAG_NAME;
697 : 19 : bool tag_created = false;
698 : : result = mbImpl->tag_get_handle( ptag_name.c_str(), 1, MB_TYPE_INTEGER, ptag, MB_TAG_SPARSE | MB_TAG_CREAT, 0,
699 [ + - ][ - + ]: 19 : &tag_created );MB_CHK_SET_ERR( result, "Trouble getting PARALLEL_PARTITION tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
700 : :
701 [ + - ]: 19 : if( !tag_created )
702 : : {
703 : : // This tag already exists; better check to see that tagged sets
704 : : // agree with this partition
705 [ + - ]: 19 : Range tagged_sets;
706 : 19 : int* proc_rk_ptr = &proc_rk;
707 : : result = mbImpl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &ptag, (const void* const*)&proc_rk_ptr,
708 [ + - ][ - + ]: 19 : 1, tagged_sets );MB_CHK_SET_ERR( result, "Trouble getting tagged sets" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
709 [ + - ][ + - ]: 19 : if( !tagged_sets.empty() && tagged_sets != myPcomm->partition_sets() )
[ + - ][ + - ]
[ - + ][ - + ]
710 : : {
711 [ # # ][ # # ]: 0 : result = mbImpl->tag_delete_data( ptag, tagged_sets );MB_CHK_SET_ERR( result, "Trouble deleting data of PARALLEL_PARTITION tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
712 : : }
713 [ + - ][ + - ]: 19 : else if( tagged_sets == myPcomm->partition_sets() )
[ + - ]
714 [ - + ]: 19 : return MB_SUCCESS;
715 : : }
716 : :
717 : : // If we get here, we need to assign the tag
718 [ # # ][ # # ]: 0 : std::vector< int > values( myPcomm->partition_sets().size() );
[ # # ]
719 [ # # ][ # # ]: 0 : for( unsigned int i = 0; i < myPcomm->partition_sets().size(); i++ )
[ # # ]
720 [ # # ]: 0 : values[i] = proc_rk;
721 [ # # ][ # # ]: 0 : result = mbImpl->tag_set_data( ptag, myPcomm->partition_sets(), &values[0] );MB_CHK_SET_ERR( result, "Trouble setting data to PARALLEL_PARTITION tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
722 : :
723 : 19 : return MB_SUCCESS;
724 : : }
725 : :
726 : 19 : ErrorCode ReadParallel::delete_nonlocal_entities( EntityHandle file_set )
727 : : {
728 : : // Get partition entities and ents related to/used by those
729 : : // get ents in the partition
730 : : ReadUtilIface* read_iface;
731 [ + - ]: 19 : mbImpl->query_interface( read_iface );
732 [ + - ][ + - ]: 38 : Range partition_ents, all_sets;
733 : :
734 [ + - ]: 19 : myDebug.tprint( 2, "Gathering related entities.\n" );
735 : :
736 [ + - ][ + - ]: 19 : ErrorCode result = read_iface->gather_related_ents( myPcomm->partition_sets(), partition_ents, &file_set );MB_CHK_SET_ERR( result, "Failure gathering related entities" );
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
737 : :
738 : : // Get pre-existing entities
739 [ + - ]: 38 : Range file_ents;
740 [ + - ][ - + ]: 19 : result = mbImpl->get_entities_by_handle( file_set, file_ents );MB_CHK_SET_ERR( result, "Couldn't get pre-existing entities" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
741 : :
742 [ + - ][ + - ]: 19 : if( 0 == myPcomm->proc_config().proc_rank() ) { myDebug.print( 2, "File entities: ", file_ents ); }
[ + - ][ + - ]
743 : :
744 : : // Get deletable entities by subtracting partition ents from file ents
745 [ + - ]: 38 : Range deletable_ents = subtract( file_ents, partition_ents );
746 : :
747 : : // Cache deletable vs. keepable sets
748 [ + - ]: 38 : Range deletable_sets = deletable_ents.subset_by_type( MBENTITYSET );
749 [ + - ][ + - ]: 38 : Range keepable_sets = subtract( file_ents.subset_by_type( MBENTITYSET ), deletable_sets );
750 : :
751 [ + - ]: 19 : myDebug.tprint( 2, "Removing deletable entities from keepable sets.\n" );
752 : :
753 : : // Remove deletable ents from all keepable sets
754 [ + - ][ + - ]: 76 : for( Range::iterator rit = keepable_sets.begin(); rit != keepable_sets.end(); ++rit )
[ + - ][ + - ]
[ + + ]
755 : : {
756 [ + - ][ + - ]: 57 : result = mbImpl->remove_entities( *rit, deletable_ents );MB_CHK_SET_ERR( result, "Failure removing deletable entities" );
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
757 : : }
758 [ + - ][ - + ]: 19 : result = mbImpl->remove_entities( file_set, deletable_ents );MB_CHK_SET_ERR( result, "Failure removing deletable entities" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
759 : :
760 [ + - ]: 19 : myDebug.tprint( 2, "Deleting deletable entities.\n" );
761 : :
762 [ + - ][ + - ]: 19 : if( 0 == myPcomm->proc_config().proc_rank() ) { myDebug.print( 2, "Deletable sets: ", deletable_sets ); }
[ + - ][ + - ]
763 : :
764 : : // Delete sets, then ents
765 [ + - ][ - + ]: 19 : if( !deletable_sets.empty() )
766 : : {
767 [ # # ][ # # ]: 0 : result = mbImpl->delete_entities( deletable_sets );MB_CHK_SET_ERR( result, "Failure deleting sets in delete_nonlocal_entities" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
768 : : }
769 : :
770 [ + - ]: 19 : deletable_ents -= deletable_sets;
771 : :
772 [ + - ][ + - ]: 19 : if( 0 == myPcomm->proc_config().proc_rank() ) { myDebug.print( 2, "Deletable entities: ", deletable_ents ); }
[ + - ][ + - ]
773 : :
774 [ + - ][ - + ]: 19 : if( !deletable_ents.empty() )
775 : : {
776 [ # # ][ # # ]: 0 : result = mbImpl->delete_entities( deletable_ents );MB_CHK_SET_ERR( result, "Failure deleting entities in delete_nonlocal_entities" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
777 : : }
778 : :
779 : 38 : return MB_SUCCESS;
780 : : }
781 : :
782 [ + - ][ + - ]: 228 : } // namespace moab
|