1
15
16
17
18
19
20
21
22
23
24
25
26 #include <cassert>
27 #include "moab/MOABConfig.h"
28
30 #ifdef MOAB_HAVE_MPI
31 #include "moab_mpi.h"
32 #include "moab/ParallelComm.hpp"
33 #endif
34 #include <H5Tpublic.h>
35 #include <H5Ppublic.h>
36 #include <H5Epublic.h>
37 #include "moab/Interface.hpp"
38 #include "Internals.hpp"
39 #include "MBTagConventions.hpp"
40 #include "ReadHDF5.hpp"
41 #include "moab/CN.hpp"
42 #include "moab/FileOptions.hpp"
43 #include "moab/CpuTimer.hpp"
44 #ifdef MOAB_HAVE_HDF5_PARALLEL
45 #include <H5FDmpi.h>
46 #include <H5FDmpio.h>
47 #endif
48
49
50 #include <cstdlib>
51 #include <cstring>
52 #include <limits>
53 #include <functional>
54 #include <iostream>
55
56 #include "IODebugTrack.hpp"
57 #include "ReadHDF5Dataset.hpp"
58 #include "ReadHDF5VarLen.hpp"
59 #include "moab_mpe.h"
60
61 namespace moab
62 {
63
64
68 const bool DEFAULT_BLOCKED_COORDINATE_IO = false;
69
70
75 const bool DEFAULT_BCAST_SUMMARY = true;
76
77
81 const bool DEFAULT_BCAST_DUPLICATE_READS = true;
82
83 #define READ_HDF5_BUFFER_SIZE ( 128 * 1024 * 1024 )
84
85 #define assert_range( PTR, CNT ) \
86 assert( ( PTR ) >= (void*)dataBuffer ); \
87 assert( ( ( PTR ) + ( CNT ) ) <= (void*)( dataBuffer + bufferSize ) );
88
89
90
91
92
93
94 #if defined( H5E_auto_t_vers ) && H5E_auto_t_vers > 1
95 static herr_t handle_hdf5_error( hid_t stack, void* data )
96 {
97 ReadHDF5::HDF5ErrorHandler* h = reinterpret_cast< ReadHDF5::HDF5ErrorHandler* >( data );
98 herr_t result = 0;
99 if( h->func ) result = ( *h->func )( stack, h->data );MB_CHK_ERR_CONT( MB_FAILURE );
100 return result;
101 }
102 #else
103 static herr_t handle_hdf5_error( void* data )
104 {
105 ReadHDF5::HDF5ErrorHandler* h = reinterpret_cast< ReadHDF5::HDF5ErrorHandler* >( data );
106 herr_t result = 0;
107 if( h->func ) result = ( *h->func )( h->data );MB_CHK_ERR_CONT( MB_FAILURE );
108 return result;
109 }
110 #endif
111
112 static void copy_sorted_file_ids( const EntityHandle* sorted_ids, long num_ids, Range& results )
113 {
114 Range::iterator hint = results.begin();
115 long i = 0;
116 while( i < num_ids )
117 {
118 EntityHandle start = sorted_ids[i];
119 for( ++i; i < num_ids && sorted_ids[i] == 1 + sorted_ids[i - 1]; ++i )
120 ;
121 hint = results.insert( hint, start, sorted_ids[i - 1] );
122 }
123 }
124
125 static void intersect( const mhdf_EntDesc& group, const Range& range, Range& result )
126 {
127 Range::const_iterator s, e;
128 s = Range::lower_bound( range.begin(), range.end(), group.start_id );
129 e = Range::lower_bound( s, range.end(), group.start_id + group.count );
130 result.merge( s, e );
131 }
132
133 #define debug_barrier() debug_barrier_line( __LINE__ )
134 void ReadHDF5::debug_barrier_line( int lineno )
135 {
136 #ifdef MOAB_HAVE_MPI
137 if( mpiComm )
138 {
139 const unsigned threshold = 2;
140 static unsigned long count = 0;
141 if( dbgOut.get_verbosity() >= threshold )
142 {
143 dbgOut.printf( threshold, "*********** Debug Barrier %lu (@%d)***********\n", ++count, lineno );
144 MPI_Barrier( *mpiComm );
145 }
146 }
147 #else
148 if( lineno )
149 {
150 }
151 #endif
152 }
153
154 class CheckOpenReadHDF5Handles
155 {
156 int fileline;
157 mhdf_FileHandle handle;
158 int enter_count;
159
160 public:
161 CheckOpenReadHDF5Handles( mhdf_FileHandle file, int line )
162 : fileline( line ), handle( file ), enter_count( mhdf_countOpenHandles( file ) )
163 {
164 }
165 ~CheckOpenReadHDF5Handles()
166 {
167 int new_count = mhdf_countOpenHandles( handle );
168 if( new_count != enter_count )
169 {
170 std::cout << "Leaked HDF5 object handle in function at " << __FILE__ << ":" << fileline << std::endl
171 << "Open at entrance: " << enter_count << std::endl
172 << "Open at exit: " << new_count << std::endl;
173 }
174 }
175 };
176
177 #ifdef NDEBUG
178 #define CHECK_OPEN_HANDLES
179 #else
180 #define CHECK_OPEN_HANDLES CheckOpenReadHDF5Handles check_open_handles_( filePtr, __LINE__ )
181 #endif
182
183 ReaderIface* ReadHDF5::factory( Interface* iface )
184 {
185 return new ReadHDF5( iface );
186 }
187
188 ReadHDF5::ReadHDF5( Interface* iface )
189 : bufferSize( READ_HDF5_BUFFER_SIZE ), dataBuffer( NULL ), iFace( iface ), filePtr( 0 ), fileInfo( NULL ),
190 readUtil( NULL ), handleType( 0 ), indepIO( H5P_DEFAULT ), collIO( H5P_DEFAULT ), myPcomm( NULL ),
191 debugTrack( false ), dbgOut( stderr ), nativeParallel( false ), mpiComm( NULL ),
192 blockedCoordinateIO( DEFAULT_BLOCKED_COORDINATE_IO ), bcastSummary( DEFAULT_BCAST_SUMMARY ),
193 bcastDuplicateReads( DEFAULT_BCAST_DUPLICATE_READS ), setMeta( 0 ), timer( NULL ), cputime( false )
194 {
195 }
196
197 ErrorCode ReadHDF5::init()
198 {
199 ErrorCode rval;
200
201 if( readUtil ) return MB_SUCCESS;
202
203 indepIO = collIO = H5P_DEFAULT;
204
205
206 handleType = H5Tcopy( H5T_NATIVE_ULONG );
207 if( handleType < 0 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
208
209 if( H5Tset_size( handleType, sizeof( EntityHandle ) ) < 0 )
210 {
211 H5Tclose( handleType );
212 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
213 }
214
215 rval = iFace->query_interface( readUtil );
216 if( MB_SUCCESS != rval )
217 {
218 H5Tclose( handleType );
219 MB_SET_ERR( rval, "ReadHDF5 Failure" );
220 }
221
222 idMap.clear();
223 fileInfo = 0;
224 debugTrack = false;
225 myPcomm = 0;
226
227 return MB_SUCCESS;
228 }
229
230 ReadHDF5::~ReadHDF5()
231 {
232 if( !readUtil )
233 return;
234
235 delete[] setMeta;
236 setMeta = 0;
237 iFace->release_interface( readUtil );
238 H5Tclose( handleType );
239 }
240
241 ErrorCode ReadHDF5::set_up_read( const char* filename, const FileOptions& opts )
242 {
243 ErrorCode rval;
244 mhdf_Status status;
245 indepIO = collIO = H5P_DEFAULT;
246 mpiComm = 0;
247
248 if( MB_SUCCESS != init() ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
249
250 #if defined( H5Eget_auto_vers ) && H5Eget_auto_vers > 1
251 herr_t err = H5Eget_auto( H5E_DEFAULT, &errorHandler.func, &errorHandler.data );
252 #else
253 herr_t err = H5Eget_auto( &errorHandler.func, &errorHandler.data );
254 #endif
255 if( err < 0 )
256 {
257 errorHandler.func = 0;
258 errorHandler.data = 0;
259 }
260 else
261 {
262 #if defined( H5Eset_auto_vers ) && H5Eset_auto_vers > 1
263 err = H5Eset_auto( H5E_DEFAULT, &handle_hdf5_error, &errorHandler );
264 #else
265 err = H5Eset_auto( &handle_hdf5_error, &errorHandler );
266 #endif
267 if( err < 0 )
268 {
269 errorHandler.func = 0;
270 errorHandler.data = 0;
271 }
272 }
273
274
275 int tmpval;
276 if( MB_SUCCESS == opts.get_int_option( "DEBUG_IO", 1, tmpval ) )
277 {
278 dbgOut.set_verbosity( tmpval );
279 dbgOut.set_prefix( "H5M " );
280 }
281 dbgOut.limit_output_to_first_N_procs( 32 );
282
283
284
285
286 debugTrack = ( MB_SUCCESS == opts.get_null_option( "DEBUG_BINIO" ) );
287
288 opts.get_toggle_option( "BLOCKED_COORDINATE_IO", DEFAULT_BLOCKED_COORDINATE_IO, blockedCoordinateIO );
289 opts.get_toggle_option( "BCAST_SUMMARY", DEFAULT_BCAST_SUMMARY, bcastSummary );
290 opts.get_toggle_option( "BCAST_DUPLICATE_READS", DEFAULT_BCAST_DUPLICATE_READS, bcastDuplicateReads );
291
292
293 bool use_mpio = ( MB_SUCCESS == opts.get_null_option( "USE_MPIO" ) );
294 rval = opts.match_option( "PARALLEL", "READ_PART" );
295 bool parallel = ( rval != MB_ENTITY_NOT_FOUND );
296 nativeParallel = ( rval == MB_SUCCESS );
297 if( use_mpio && !parallel )
298 {
299 MB_SET_ERR( MB_NOT_IMPLEMENTED, "'USE_MPIO' option specified w/out 'PARALLEL' option" );
300 }
301
302
303
304
305
306 rval = opts.get_int_option( "BUFFER_SIZE", bufferSize );
307 if( MB_SUCCESS != rval )
308 {
309 bufferSize = READ_HDF5_BUFFER_SIZE;
310 }
311 else if( bufferSize < (int)std::max( sizeof( EntityHandle ), sizeof( void* ) ) )
312 {
313 MB_CHK_ERR( MB_INVALID_SIZE );
314 }
315
316 dataBuffer = (char*)malloc( bufferSize );
317 if( !dataBuffer ) MB_CHK_ERR( MB_MEMORY_ALLOCATION_FAILED );
318
319 if( use_mpio || nativeParallel )
320 {
321
322 #ifndef MOAB_HAVE_HDF5_PARALLEL
323 free( dataBuffer );
324 dataBuffer = NULL;
325 MB_SET_ERR( MB_NOT_IMPLEMENTED, "MOAB not configured with parallel HDF5 support" );
326 #else
327 MPI_Info info = MPI_INFO_NULL;
328 std::string cb_size;
329 rval = opts.get_str_option( "CB_BUFFER_SIZE", cb_size );
330 if( MB_SUCCESS == rval )
331 {
332 MPI_Info_create( &info );
333 MPI_Info_set( info, const_cast< char* >( "cb_buffer_size" ), const_cast< char* >( cb_size.c_str() ) );
334 }
335
336 int pcomm_no = 0;
337 rval = opts.get_int_option( "PARALLEL_COMM", pcomm_no );
338 if( rval == MB_TYPE_OUT_OF_RANGE )
339 {
340 MB_SET_ERR( rval, "Invalid value for PARALLEL_COMM option" );
341 }
342 myPcomm = ParallelComm::get_pcomm( iFace, pcomm_no );
343 if( 0 == myPcomm )
344 {
345 myPcomm = new ParallelComm( iFace, MPI_COMM_WORLD );
346 }
347 const int rank = myPcomm->proc_config().proc_rank();
348 dbgOut.set_rank( rank );
349 dbgOut.limit_output_to_first_N_procs( 32 );
350 mpiComm = new MPI_Comm( myPcomm->proc_config().proc_comm() );
351
352 #ifndef H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS
353 dbgOut.print( 1, "H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS is not defined\n" );
354 #endif
355
356
357 dbgOut.tprint( 1, "Getting file summary\n" );
358 fileInfo = 0;
359
360 hid_t file_prop;
361 if( bcastSummary )
362 {
363 unsigned long size = 0;
364 if( rank == 0 )
365 {
366 file_prop = H5Pcreate( H5P_FILE_ACCESS );
367 err = H5Pset_fapl_mpio( file_prop, MPI_COMM_SELF, MPI_INFO_NULL );
368 assert( file_prop >= 0 );
369 assert( err >= 0 );
370 filePtr = mhdf_openFileWithOpt( filename, 0, NULL, handleType, file_prop, &status );
371 H5Pclose( file_prop );
372
373 if( filePtr )
374 {
375 fileInfo = mhdf_getFileSummary( filePtr, handleType, &status,
376 0 );
377 if( !is_error( status ) )
378 {
379 size = fileInfo->total_size;
380 fileInfo->offset = (unsigned char*)fileInfo;
381 }
382 }
383 mhdf_closeFile( filePtr, &status );
384 if( fileInfo && mhdf_isError( &status ) )
385 {
386 free( fileInfo );
387 fileInfo = NULL;
388 }
389 }
390
391 dbgOut.tprint( 1, "Communicating file summary\n" );
392 int mpi_err = MPI_Bcast( &size, 1, MPI_UNSIGNED_LONG, 0, myPcomm->proc_config().proc_comm() );
393 if( mpi_err || !size ) return MB_FAILURE;
394
395 if( rank != 0 ) fileInfo = reinterpret_cast< mhdf_FileDesc* >( malloc( size ) );
396
397 MPI_Bcast( fileInfo, size, MPI_BYTE, 0, myPcomm->proc_config().proc_comm() );
398
399 if( rank != 0 ) mhdf_fixFileDesc( fileInfo, reinterpret_cast< mhdf_FileDesc* >( fileInfo->offset ) );
400 }
401
402 file_prop = H5Pcreate( H5P_FILE_ACCESS );
403 err = H5Pset_fapl_mpio( file_prop, myPcomm->proc_config().proc_comm(), info );
404 assert( file_prop >= 0 );
405 assert( err >= 0 );
406
407 collIO = H5Pcreate( H5P_DATASET_XFER );
408 assert( collIO > 0 );
409 err = H5Pset_dxpl_mpio( collIO, H5FD_MPIO_COLLECTIVE );
410 assert( err >= 0 );
411 indepIO = nativeParallel ? H5P_DEFAULT : collIO;
412
413
414 dbgOut.tprintf( 1, "Opening \"%s\" for parallel IO\n", filename );
415 filePtr = mhdf_openFileWithOpt( filename, 0, NULL, handleType, file_prop, &status );
416
417 H5Pclose( file_prop );
418 if( !filePtr )
419 {
420 free( dataBuffer );
421 dataBuffer = NULL;
422 H5Pclose( indepIO );
423 if( collIO != indepIO ) H5Pclose( collIO );
424 collIO = indepIO = H5P_DEFAULT;
425 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
426 }
427
428 if( !bcastSummary )
429 {
430 fileInfo = mhdf_getFileSummary( filePtr, handleType, &status, 0 );
431 if( is_error( status ) )
432 {
433 free( dataBuffer );
434 dataBuffer = NULL;
435 mhdf_closeFile( filePtr, &status );
436 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
437 }
438 }
439 #endif
440 }
441 else
442 {
443
444 filePtr = mhdf_openFile( filename, 0, NULL, handleType, &status );
445 if( !filePtr )
446 {
447 free( dataBuffer );
448 dataBuffer = NULL;
449 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
450 }
451
452
453 fileInfo = mhdf_getFileSummary( filePtr, handleType, &status, 0 );
454 if( is_error( status ) )
455 {
456 free( dataBuffer );
457 dataBuffer = NULL;
458 mhdf_closeFile( filePtr, &status );
459 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
460 }
461 }
462
463 ReadHDF5Dataset::default_hyperslab_selection_limit();
464 int hslimit;
465 rval = opts.get_int_option( "HYPERSLAB_SELECT_LIMIT", hslimit );
466 if( MB_SUCCESS == rval && hslimit > 0 )
467 ReadHDF5Dataset::set_hyperslab_selection_limit( hslimit );
468 else
469 ReadHDF5Dataset::default_hyperslab_selection_limit();
470 if( MB_SUCCESS != opts.get_null_option( "HYPERSLAB_OR" ) &&
471 ( MB_SUCCESS == opts.get_null_option( "HYPERSLAB_APPEND" ) || HDF5_can_append_hyperslabs() ) )
472 {
473 ReadHDF5Dataset::append_hyperslabs();
474 if( MB_SUCCESS != opts.get_int_option( "HYPERSLAB_SELECT_LIMIT", hslimit ) )
475 ReadHDF5Dataset::set_hyperslab_selection_limit( std::numeric_limits< int >::max() );
476 dbgOut.print( 1, "Using H5S_APPEND for hyperslab selection\n" );
477 }
478
479 return MB_SUCCESS;
480 }
481
482 ErrorCode ReadHDF5::clean_up_read( const FileOptions& )
483 {
484 HDF5ErrorHandler handler;
485 #if defined( H5Eget_auto_vers ) && H5Eget_auto_vers > 1
486 herr_t err = H5Eget_auto( H5E_DEFAULT, &handler.func, &handler.data );
487 #else
488 herr_t err = H5Eget_auto( &handler.func, &handler.data );
489 #endif
490 if( err >= 0 && handler.func == &handle_hdf5_error )
491 {
492 assert( handler.data == &errorHandler );
493 #if defined( H5Eget_auto_vers ) && H5Eget_auto_vers > 1
494 H5Eset_auto( H5E_DEFAULT, errorHandler.func, errorHandler.data );
495 #else
496 H5Eset_auto( errorHandler.func, errorHandler.data );
497 #endif
498 }
499
500 free( dataBuffer );
501 dataBuffer = NULL;
502 free( fileInfo );
503 fileInfo = NULL;
504 delete mpiComm;
505 mpiComm = 0;
506
507 if( indepIO != H5P_DEFAULT ) H5Pclose( indepIO );
508 if( collIO != indepIO ) H5Pclose( collIO );
509 collIO = indepIO = H5P_DEFAULT;
510
511 delete[] setMeta;
512 setMeta = 0;
513
514 mhdf_Status status;
515 mhdf_closeFile( filePtr, &status );
516 filePtr = 0;
517 return is_error( status ) ? MB_FAILURE : MB_SUCCESS;
518 }
519
520 ErrorCode ReadHDF5::load_file( const char* filename,
521 const EntityHandle* file_set,
522 const FileOptions& opts,
523 const ReaderIface::SubsetList* subset_list,
524 const Tag* file_id_tag )
525 {
526 ErrorCode rval;
527
528 rval = set_up_read( filename, opts );
529 if( MB_SUCCESS != rval )
530 {
531 clean_up_read( opts );
532 return rval;
533 }
534
535
536 rval = opts.get_null_option( "CPUTIME" );
537 if( MB_SUCCESS == rval )
538 {
539 cputime = true;
540 timer = new CpuTimer;
541 for( int i = 0; i < NUM_TIMES; i++ )
542 _times[i] = 0;
543 }
544
545
546
547 rval = read_all_set_meta();
548
549 if( cputime ) _times[SET_META_TIME] = timer->time_elapsed();
550 if( subset_list && MB_SUCCESS == rval )
551 rval = load_file_partial( subset_list->tag_list, subset_list->tag_list_length, subset_list->num_parts,
552 subset_list->part_number, opts );
553 else
554 rval = load_file_impl( opts );
555
556 if( MB_SUCCESS == rval && file_id_tag )
557 {
558 dbgOut.tprint( 1, "Storing file IDs in tag\n" );
559 rval = store_file_ids( *file_id_tag );
560 }
561 ErrorCode rval3 = opts.get_null_option( "STORE_SETS_FILEIDS" );
562 if( MB_SUCCESS == rval3 )
563 {
564 rval = store_sets_file_ids();
565 if( MB_SUCCESS != rval ) return rval;
566 }
567
568 if( cputime ) _times[STORE_FILE_IDS_TIME] = timer->time_elapsed();
569
570 if( MB_SUCCESS == rval && 0 != file_set )
571 {
572 dbgOut.tprint( 1, "Reading QA records\n" );
573 rval = read_qa( *file_set );
574 }
575
576 if( cputime ) _times[READ_QA_TIME] = timer->time_elapsed();
577 dbgOut.tprint( 1, "Cleaning up\n" );
578 ErrorCode rval2 = clean_up_read( opts );
579 if( rval == MB_SUCCESS && rval2 != MB_SUCCESS ) rval = rval2;
580
581 if( MB_SUCCESS == rval )
582 dbgOut.tprint( 1, "Read finished.\n" );
583 else
584 {
585 std::string msg;
586 iFace->get_last_error( msg );
587 dbgOut.tprintf( 1, "READ FAILED (ERROR CODE %s): %s\n", ErrorCodeStr[rval], msg.c_str() );
588 }
589
590 if( cputime )
591 {
592 _times[TOTAL_TIME] = timer->time_since_birth();
593 print_times();
594 delete timer;
595 }
596 if( H5P_DEFAULT != collIO ) H5Pclose( collIO );
597 if( H5P_DEFAULT != indepIO ) H5Pclose( indepIO );
598 collIO = indepIO = H5P_DEFAULT;
599
600 return rval;
601 }
602
603 ErrorCode ReadHDF5::load_file_impl( const FileOptions& )
604 {
605 ErrorCode rval;
606 mhdf_Status status;
607 int i;
608
609 CHECK_OPEN_HANDLES;
610
611 dbgOut.tprint( 1, "Reading all nodes...\n" );
612 Range ids;
613 if( fileInfo->nodes.count )
614 {
615 ids.insert( fileInfo->nodes.start_id, fileInfo->nodes.start_id + fileInfo->nodes.count - 1 );
616 rval = read_nodes( ids );
617 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
618 }
619
620 dbgOut.tprint( 1, "Reading all element connectivity...\n" );
621 std::vector< int > polyhedra;
622 for( i = 0; i < fileInfo->num_elem_desc; ++i )
623 {
624 if( CN::EntityTypeFromName( fileInfo->elems[i].type ) == MBPOLYHEDRON )
625 {
626 polyhedra.push_back( i );
627 continue;
628 }
629
630 rval = read_elems( i );
631 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
632 }
633 for( std::vector< int >::iterator it = polyhedra.begin(); it != polyhedra.end(); ++it )
634 {
635 rval = read_elems( *it );
636 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
637 }
638
639 dbgOut.tprint( 1, "Reading all sets...\n" );
640 ids.clear();
641 if( fileInfo->sets.count )
642 {
643 ids.insert( fileInfo->sets.start_id, fileInfo->sets.start_id + fileInfo->sets.count - 1 );
644 rval = read_sets( ids );
645 if( rval != MB_SUCCESS )
646 {
647 MB_SET_ERR( rval, "ReadHDF5 Failure" );
648 }
649 }
650
651 dbgOut.tprint( 1, "Reading all adjacencies...\n" );
652 for( i = 0; i < fileInfo->num_elem_desc; ++i )
653 {
654 if( !fileInfo->elems[i].have_adj ) continue;
655
656 long table_len;
657 hid_t table = mhdf_openAdjacency( filePtr, fileInfo->elems[i].handle, &table_len, &status );
658 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
659
660 rval = read_adjacencies( table, table_len );
661 mhdf_closeData( filePtr, table, &status );
662 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
663 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
664 }
665
666 dbgOut.tprint( 1, "Reading all tags...\n" );
667 for( i = 0; i < fileInfo->num_tag_desc; ++i )
668 {
669 rval = read_tag( i );
670 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
671 }
672
673 dbgOut.tprint( 1, "Core read finished. Cleaning up...\n" );
674 return MB_SUCCESS;
675 }
676
677 ErrorCode ReadHDF5::find_int_tag( const char* name, int& index )
678 {
679 for( index = 0; index < fileInfo->num_tag_desc; ++index )
680 if( !strcmp( name, fileInfo->tags[index].name ) ) break;
681
682 if( index == fileInfo->num_tag_desc )
683 {
684 MB_SET_ERR( MB_TAG_NOT_FOUND, "File does not contain subset tag '" << name << "'" );
685 }
686
687 if( fileInfo->tags[index].type != mhdf_INTEGER || fileInfo->tags[index].size != 1 )
688 {
689 MB_SET_ERR( MB_TAG_NOT_FOUND, "Tag ' " << name << "' does not contain single integer value" );
690 }
691
692 return MB_SUCCESS;
693 }
694
695 ErrorCode ReadHDF5::get_subset_ids( const ReaderIface::IDTag* subset_list, int subset_list_length, Range& file_ids )
696 {
697 ErrorCode rval;
698
699 for( int i = 0; i < subset_list_length; ++i )
700 {
701 int tag_index;
702 rval = find_int_tag( subset_list[i].tag_name, tag_index );
703 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
704
705 Range tmp_file_ids;
706 if( !subset_list[i].num_tag_values )
707 {
708 rval = get_tagged_entities( tag_index, tmp_file_ids );
709 }
710 else
711 {
712 std::vector< int > ids( subset_list[i].tag_values,
713 subset_list[i].tag_values + subset_list[i].num_tag_values );
714 std::sort( ids.begin(), ids.end() );
715 rval = search_tag_values( tag_index, ids, tmp_file_ids );
716 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
717 }
718
719 if( tmp_file_ids.empty() ) MB_CHK_ERR( MB_ENTITY_NOT_FOUND );
720
721 if( i == 0 )
722 file_ids.swap( tmp_file_ids );
723 else
724 file_ids = intersect( tmp_file_ids, file_ids );
725 }
726
727 return MB_SUCCESS;
728 }
729
730 ErrorCode ReadHDF5::get_partition( Range& tmp_file_ids, int num_parts, int part_number )
731 {
732 CHECK_OPEN_HANDLES;
733
734
735 if( (unsigned long)fileInfo->sets.start_id > tmp_file_ids.front() )
736 {
737 dbgOut.print( 2, "Ignoring non-set entities with partition set tag\n" );
738 tmp_file_ids.erase( tmp_file_ids.begin(), tmp_file_ids.lower_bound( (EntityHandle)fileInfo->sets.start_id ) );
739 }
740 unsigned long set_end = (unsigned long)fileInfo->sets.start_id + fileInfo->sets.count;
741 if( tmp_file_ids.back() >= set_end )
742 {
743 dbgOut.print( 2, "Ignoring non-set entities with partition set tag\n" );
744 tmp_file_ids.erase( tmp_file_ids.upper_bound( (EntityHandle)set_end ), tmp_file_ids.end() );
745 }
746
747 Range::iterator s = tmp_file_ids.begin();
748 size_t num_per_proc = tmp_file_ids.size() / num_parts;
749 size_t num_extra = tmp_file_ids.size() % num_parts;
750 Range::iterator e;
751 if( part_number < (long)num_extra )
752 {
753 s += ( num_per_proc + 1 ) * part_number;
754 e = s;
755 e += ( num_per_proc + 1 );
756 }
757 else
758 {
759 s += num_per_proc * part_number + num_extra;
760 e = s;
761 e += num_per_proc;
762 }
763 tmp_file_ids.erase( e, tmp_file_ids.end() );
764 tmp_file_ids.erase( tmp_file_ids.begin(), s );
765
766 return MB_SUCCESS;
767 }
768
769 ErrorCode ReadHDF5::load_file_partial( const ReaderIface::IDTag* subset_list,
770 int subset_list_length,
771 int num_parts,
772 int part_number,
773 const FileOptions& opts )
774 {
775 mhdf_Status status;
776
777 static MPEState mpe_event( "ReadHDF5", "yellow" );
778
779 mpe_event.start( "gather parts" );
780
781 CHECK_OPEN_HANDLES;
782
783 for( int i = 0; i < subset_list_length; ++i )
784 {
785 dbgOut.printf( 2, "Select by \"%s\" with num_tag_values = %d\n", subset_list[i].tag_name,
786 subset_list[i].num_tag_values );
787 if( subset_list[i].num_tag_values )
788 {
789 assert( 0 != subset_list[i].tag_values );
790 dbgOut.printf( 2, " \"%s\" values = { %d", subset_list[i].tag_name, subset_list[i].tag_values[0] );
791 for( int j = 1; j < subset_list[i].num_tag_values; ++j )
792 dbgOut.printf( 2, ", %d", subset_list[i].tag_values[j] );
793 dbgOut.printf( 2, " }\n" );
794 }
795 }
796 if( num_parts ) dbgOut.printf( 2, "Partition with num_parts = %d and part_number = %d\n", num_parts, part_number );
797
798 dbgOut.tprint( 1, "RETRIEVING TAGGED ENTITIES\n" );
799
800 Range file_ids;
801 ErrorCode rval = get_subset_ids( subset_list, subset_list_length, file_ids );
802 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
803
804 if( cputime ) _times[SUBSET_IDS_TIME] = timer->time_elapsed();
805
806 if( num_parts )
807 {
808
813 rval = get_partition( file_ids, num_parts, part_number );
814 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
815 }
816
817 if( cputime ) _times[GET_PARTITION_TIME] = timer->time_elapsed();
818
819 dbgOut.print_ints( 4, "Set file IDs for partial read: ", file_ids );
820 mpe_event.end();
821 mpe_event.start( "gather related sets" );
822 dbgOut.tprint( 1, "GATHERING ADDITIONAL ENTITIES\n" );
823
824 enum RecusiveSetMode
825 {
826 RSM_NONE,
827 RSM_SETS,
828 RSM_CONTENTS
829 };
830 const char* const set_opts[] = { "NONE", "SETS", "CONTENTS", NULL };
831 int child_mode;
832 rval = opts.match_option( "CHILDREN", set_opts, child_mode );
833 if( MB_ENTITY_NOT_FOUND == rval )
834 child_mode = RSM_CONTENTS;
835 else if( MB_SUCCESS != rval )
836 {
837 MB_SET_ERR( rval, "Invalid value for 'CHILDREN' option" );
838 }
839 int content_mode;
840 rval = opts.match_option( "SETS", set_opts, content_mode );
841 if( MB_ENTITY_NOT_FOUND == rval )
842 content_mode = RSM_CONTENTS;
843 else if( MB_SUCCESS != rval )
844 {
845 MB_SET_ERR( rval, "Invalid value for 'SETS' option" );
846 }
847
848
849
850
851 Range sets;
852 intersect( fileInfo->sets, file_ids, sets );
853 if( content_mode == RSM_CONTENTS || child_mode == RSM_CONTENTS )
854 {
855 dbgOut.tprint( 1, " doing read_set_ids_recursive\n" );
856 rval = read_set_ids_recursive( sets, content_mode == RSM_CONTENTS, child_mode == RSM_CONTENTS );
857 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
858 }
859
860 if( cputime ) _times[GET_SET_IDS_TIME] = timer->time_elapsed();
861 debug_barrier();
862
863
864 dbgOut.tprint( 1, " doing get_set_contents\n" );
865 rval = get_set_contents( sets, file_ids );
866 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
867
868 if( cputime ) _times[GET_SET_CONTENTS_TIME] = timer->time_elapsed();
869
870 dbgOut.print_ints( 5, "File IDs for partial read: ", file_ids );
871 debug_barrier();
872 mpe_event.end();
873 dbgOut.tprint( 1, "GATHERING NODE IDS\n" );
874
875
876 int max_dim = 0;
877 for( int i = 0; i < fileInfo->num_elem_desc; ++i )
878 {
879 EntityType type = CN::EntityTypeFromName( fileInfo->elems[i].type );
880 if( type <= MBVERTEX || type >= MBENTITYSET )
881 {
882 assert( false );
883 continue;
884 }
885 int dim = CN::Dimension( type );
886 if( dim > max_dim )
887 {
888 Range subset;
889 intersect( fileInfo->elems[i].desc, file_ids, subset );
890 if( !subset.empty() ) max_dim = dim;
891 }
892 }
893 #ifdef MOAB_HAVE_MPI
894 if( nativeParallel )
895 {
896 int send = max_dim;
897 MPI_Allreduce( &send, &max_dim, 1, MPI_INT, MPI_MAX, *mpiComm );
898 }
899 #endif
900
901
902
903
904 for( int i = 0; i < fileInfo->num_elem_desc; ++i )
905 {
906 EntityType type = CN::EntityTypeFromName( fileInfo->elems[i].type );
907 if( type != MBPOLYHEDRON ) continue;
908
909 debug_barrier();
910 dbgOut.print( 2, " Getting polyhedra faces\n" );
911 mpe_event.start( "reading connectivity for ", fileInfo->elems[i].handle );
912
913 Range polyhedra;
914 intersect( fileInfo->elems[i].desc, file_ids, polyhedra );
915 rval = read_elems( i, polyhedra, &file_ids );
916 mpe_event.end( rval );
917 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
918 }
919
920 if( cputime ) _times[GET_POLYHEDRA_TIME] = timer->time_elapsed();
921
922 Range nodes;
923 intersect( fileInfo->nodes, file_ids, nodes );
924 for( int i = 0; i < fileInfo->num_elem_desc; ++i )
925 {
926 EntityType type = CN::EntityTypeFromName( fileInfo->elems[i].type );
927 if( type <= MBVERTEX || type >= MBENTITYSET )
928 {
929 assert( false );
930 continue;
931 }
932 if( MBPOLYHEDRON == type ) continue;
933
934 debug_barrier();
935 dbgOut.printf( 2, " Getting element node IDs for: %s\n", fileInfo->elems[i].handle );
936
937 Range subset;
938 intersect( fileInfo->elems[i].desc, file_ids, subset );
939 mpe_event.start( "reading connectivity for ", fileInfo->elems[i].handle );
940
941
942
943
944
945
946
947
948 if( CN::Dimension( type ) == max_dim )
949 rval = read_elems( i, subset, &nodes );
950 else
951 rval = read_elems( i, subset, nodes );
952 mpe_event.end( rval );
953 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
954 }
955 if( cputime ) _times[GET_ELEMENTS_TIME] = timer->time_elapsed();
956 debug_barrier();
957 mpe_event.start( "read coords" );
958 dbgOut.tprintf( 1, "READING NODE COORDINATES (%lu nodes in %lu selects)\n", (unsigned long)nodes.size(),
959 (unsigned long)nodes.psize() );
960
961
962
963
964 rval = read_nodes( nodes );
965 mpe_event.end( rval );
966 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
967
968 if( cputime ) _times[GET_NODES_TIME] = timer->time_elapsed();
969
970 debug_barrier();
971 dbgOut.tprint( 1, "READING ELEMENTS\n" );
972
973
974 enum SideMode
975 {
976 SM_EXPLICIT,
977 SM_NODES,
978 SM_SIDES
979 };
980 int side_mode;
981 const char* const options[] = { "EXPLICIT", "NODES", "SIDES", 0 };
982 rval = opts.match_option( "ELEMENTS", options, side_mode );
983 if( MB_ENTITY_NOT_FOUND == rval )
984 {
985
986
987 if( 0 == max_dim )
988 side_mode = SM_NODES;
989 else
990 side_mode = SM_SIDES;
991 }
992 else if( MB_SUCCESS != rval )
993 {
994 MB_SET_ERR( rval, "Invalid value for 'ELEMENTS' option" );
995 }
996
997 if( side_mode == SM_SIDES && max_dim == 0 )
998 {
999
1000
1001
1002
1003 for( int dim = 3; dim >= max_dim; --dim )
1004 {
1005 for( int i = 0; i < fileInfo->num_elem_desc; ++i )
1006 {
1007 EntityType type = CN::EntityTypeFromName( fileInfo->elems[i].type );
1008 if( CN::Dimension( type ) == dim )
1009 {
1010 debug_barrier();
1011 dbgOut.tprintf( 2, " Reading node-adjacent elements for: %s\n", fileInfo->elems[i].handle );
1012 mpe_event.start( "reading connectivity for ", fileInfo->elems[i].handle );
1013 Range ents;
1014 rval = read_node_adj_elems( fileInfo->elems[i] );
1015 mpe_event.end( rval );
1016 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1017 if( !ents.empty() ) max_dim = 3;
1018 }
1019 }
1020 }
1021 }
1022
1023 if( cputime ) _times[GET_NODEADJ_TIME] = timer->time_elapsed();
1024 Range side_entities;
1025 if( side_mode != SM_EXPLICIT )
1026 {
1027 if( 0 == max_dim ) max_dim = 4;
1028
1029
1030 for( int dim = max_dim - 1; dim > 0; --dim )
1031 {
1032 for( int i = 0; i < fileInfo->num_elem_desc; ++i )
1033 {
1034 EntityType type = CN::EntityTypeFromName( fileInfo->elems[i].type );
1035 if( CN::Dimension( type ) == dim )
1036 {
1037 debug_barrier();
1038 dbgOut.tprintf( 2, " Reading node-adjacent elements for: %s\n", fileInfo->elems[i].handle );
1039 mpe_event.start( "reading connectivity for ", fileInfo->elems[i].handle );
1040 rval = read_node_adj_elems( fileInfo->elems[i], &side_entities );
1041 mpe_event.end( rval );
1042 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1043 }
1044 }
1045 }
1046 }
1047
1048
1049
1050
1051
1052 if( cputime ) _times[GET_SIDEELEM_TIME] = timer->time_elapsed();
1053
1054 debug_barrier();
1055 dbgOut.tprint( 1, "UPDATING CONNECTIVITY ARRAYS FOR READ ELEMENTS\n" );
1056 mpe_event.start( "updating connectivity for elements read before vertices" );
1057 rval = update_connectivity();
1058 mpe_event.end();
1059 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1060
1061 if( cputime ) _times[UPDATECONN_TIME] = timer->time_elapsed();
1062
1063 dbgOut.tprint( 1, "READING ADJACENCIES\n" );
1064 for( int i = 0; i < fileInfo->num_elem_desc; ++i )
1065 {
1066 if (fileInfo->elems[i].have_adj )
1068 {
1069 mpe_event.start( "reading adjacencies for ", fileInfo->elems[i].handle );
1070 long len;
1071 hid_t th = mhdf_openAdjacency( filePtr, fileInfo->elems[i].handle, &len, &status );
1072 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1073
1074 rval = read_adjacencies( th, len );
1075 mhdf_closeData( filePtr, th, &status );
1076 mpe_event.end( rval );
1077 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1078 }
1079 }
1080
1081 if( cputime ) _times[ADJACENCY_TIME] = timer->time_elapsed();
1082
1083
1084
1085
1086
1087
1088 if( side_mode == SM_SIDES )
1089 {
1090 debug_barrier();
1091 mpe_event.start( "cleaning up non-side lower-dim elements" );
1092 dbgOut.tprint( 1, "CHECKING FOR AND DELETING NON-SIDE ELEMENTS\n" );
1093 rval = delete_non_side_elements( side_entities );
1094 mpe_event.end( rval );
1095 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1096 }
1097
1098 if( cputime ) _times[DELETE_NON_SIDEELEM_TIME] = timer->time_elapsed();
1099
1100 debug_barrier();
1101 dbgOut.tprint( 1, "READING SETS\n" );
1102
1103
1104
1105
1106 if( content_mode == RSM_SETS || child_mode == RSM_SETS )
1107 {
1108 dbgOut.tprint( 1, " doing read_set_ids_recursive\n" );
1109 mpe_event.start( "finding recursively contained sets" );
1110 rval = read_set_ids_recursive( sets, content_mode == RSM_SETS, child_mode == RSM_SETS );
1111 mpe_event.end( rval );
1112 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1113 }
1114
1115 if( cputime ) _times[READ_SET_IDS_RECURS_TIME] = timer->time_elapsed();
1116
1117 dbgOut.tprint( 1, " doing find_sets_containing\n" );
1118 mpe_event.start( "finding sets containing any read entities" );
1119
1120
1121 bool read_set_containing_parents = true;
1122 std::string tmp_opt;
1123 rval = opts.get_option( "NO_SET_CONTAINING_PARENTS", tmp_opt );
1124 if( MB_SUCCESS == rval ) read_set_containing_parents = false;
1125
1126
1127
1128 rval = find_sets_containing( sets, read_set_containing_parents );
1129 mpe_event.end( rval );
1130 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1131
1132 if( cputime ) _times[FIND_SETS_CONTAINING_TIME] = timer->time_elapsed();
1133
1134
1135
1136 mpe_event.start( "reading set contents/parents/children" );
1137 EntityHandle first_set = fileInfo->sets.start_id;
1138 sets.merge( file_ids.lower_bound( first_set ), file_ids.lower_bound( first_set + fileInfo->sets.count ) );
1139 dbgOut.tprint( 1, " doing read_sets\n" );
1140 rval = read_sets( sets );
1141 mpe_event.end( rval );
1142 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1143
1144 if( cputime ) _times[READ_SETS_TIME] = timer->time_elapsed();
1145
1146 dbgOut.tprint( 1, "READING TAGS\n" );
1147
1148 for( int i = 0; i < fileInfo->num_tag_desc; ++i )
1149 {
1150 mpe_event.start( "reading tag: ", fileInfo->tags[i].name );
1151 rval = read_tag( i );
1152 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1153 }
1154
1155 if( cputime ) _times[READ_TAGS_TIME] = timer->time_elapsed();
1156
1157 dbgOut.tprint( 1, "PARTIAL READ COMPLETE.\n" );
1158
1159 return MB_SUCCESS;
1160 }
1161
1162 ErrorCode ReadHDF5::search_tag_values( int tag_index,
1163 const std::vector< int >& sorted_values,
1164 Range& file_ids,
1165 bool sets_only )
1166 {
1167 ErrorCode rval;
1168 mhdf_Status status;
1169 std::vector< EntityHandle >::iterator iter;
1170 const mhdf_TagDesc& tag = fileInfo->tags[tag_index];
1171 long size;
1172 long start_id;
1173
1174 CHECK_OPEN_HANDLES;
1175
1176 debug_barrier();
1177
1178
1179
1180 hid_t table;
1181 const char* name;
1182 std::vector< EntityHandle > indices;
1183
1184
1185 std::vector< int > grp_indices( tag.dense_elem_indices, tag.dense_elem_indices + tag.num_dense_indices );
1186 for( std::vector< int >::reverse_iterator i = grp_indices.rbegin(); i != grp_indices.rend(); ++i )
1187 {
1188 int idx = *i;
1189 if( idx == -2 )
1190 {
1191 name = mhdf_set_type_handle();
1192 start_id = fileInfo->sets.start_id;
1193 }
1194 else if( sets_only )
1195 {
1196 continue;
1197 }
1198 else if( idx == -1 )
1199 {
1200 name = mhdf_node_type_handle();
1201 start_id = fileInfo->nodes.start_id;
1202 }
1203 else
1204 {
1205 if( idx < 0 || idx >= fileInfo->num_elem_desc ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1206 name = fileInfo->elems[idx].handle;
1207 start_id = fileInfo->elems[idx].desc.start_id;
1208 }
1209 table = mhdf_openDenseTagData( filePtr, tag.name, name, &size, &status );
1210 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1211 rval = search_tag_values( table, size, sorted_values, indices );
1212 mhdf_closeData( filePtr, table, &status );
1213 if( MB_SUCCESS != rval || is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1214
1215 std::sort( indices.begin(), indices.end(), std::greater< EntityHandle >() );
1216 std::transform( indices.begin(), indices.end(), range_inserter( file_ids ),
1217
1218 std::bind( std::plus< long >(), start_id, std::placeholders::_1 ) );
1219 indices.clear();
1220 }
1221
1222 if( !tag.have_sparse ) return MB_SUCCESS;
1223
1224
1225
1226 hid_t tables[2];
1227 long junk;
1228 mhdf_openSparseTagData( filePtr, tag.name, &size, &junk, tables, &status );
1229 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1230 rval = search_tag_values( tables[1], size, sorted_values, indices );
1231 mhdf_closeData( filePtr, tables[1], &status );
1232 if( MB_SUCCESS != rval || is_error( status ) )
1233 {
1234 mhdf_closeData( filePtr, tables[0], &status );
1235 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1236 }
1237
1238 std::sort( indices.begin(), indices.end() );
1239 std::vector< EntityHandle > ranges;
1240 iter = indices.begin();
1241 while( iter != indices.end() )
1242 {
1243 ranges.push_back( *iter );
1244 EntityHandle last = *iter;
1245 for( ++iter; iter != indices.end() && ( last + 1 ) == *iter; ++iter, ++last )
1246 ;
1247 ranges.push_back( last );
1248 }
1249
1250 iter = ranges.begin();
1251 unsigned long offset = 0;
1252 while( iter != ranges.end() )
1253 {
1254 long begin = *iter;
1255 ++iter;
1256 long end = *iter;
1257 ++iter;
1258 mhdf_readSparseTagEntitiesWithOpt( tables[0], begin, end - begin + 1, handleType, &indices[offset], indepIO,
1259 &status );
1260 if( is_error( status ) )
1261 {
1262 mhdf_closeData( filePtr, tables[0], &status );
1263 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1264 }
1265 offset += end - begin + 1;
1266 }
1267 mhdf_closeData( filePtr, tables[0], &status );
1268 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1269 assert( offset == indices.size() );
1270 std::sort( indices.begin(), indices.end() );
1271
1272 if( sets_only )
1273 {
1274 iter = std::lower_bound( indices.begin(), indices.end(),
1275 (EntityHandle)( fileInfo->sets.start_id + fileInfo->sets.count ) );
1276 indices.erase( iter, indices.end() );
1277 iter = std::lower_bound( indices.begin(), indices.end(), fileInfo->sets.start_id );
1278 indices.erase( indices.begin(), iter );
1279 }
1280 copy_sorted_file_ids( &indices[0], indices.size(), file_ids );
1281
1282 return MB_SUCCESS;
1283 }
1284
1285 ErrorCode ReadHDF5::get_tagged_entities( int tag_index, Range& file_ids )
1286 {
1287 const mhdf_TagDesc& tag = fileInfo->tags[tag_index];
1288
1289 CHECK_OPEN_HANDLES;
1290
1291
1292 Range::iterator hint = file_ids.begin();
1293 for( int i = 0; i < tag.num_dense_indices; ++i )
1294 {
1295 int idx = tag.dense_elem_indices[i];
1296 mhdf_EntDesc* ents;
1297 if( idx == -2 )
1298 ents = &fileInfo->sets;
1299 else if( idx == -1 )
1300 ents = &fileInfo->nodes;
1301 else
1302 {
1303 if( idx < 0 || idx >= fileInfo->num_elem_desc ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1304 ents = &( fileInfo->elems[idx].desc );
1305 }
1306
1307 EntityHandle h = (EntityHandle)ents->start_id;
1308 hint = file_ids.insert( hint, h, h + ents->count - 1 );
1309 }
1310
1311 if( !tag.have_sparse ) return MB_SUCCESS;
1312
1313
1314
1315 mhdf_Status status;
1316 hid_t tables[2];
1317 long size, junk;
1318 mhdf_openSparseTagData( filePtr, tag.name, &size, &junk, tables, &status );
1319 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1320 mhdf_closeData( filePtr, tables[1], &status );
1321 if( is_error( status ) )
1322 {
1323 mhdf_closeData( filePtr, tables[0], &status );
1324 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1325 }
1326
1327 hid_t file_type = H5Dget_type( tables[0] );
1328 if( file_type < 0 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1329
1330 hint = file_ids.begin();
1331 EntityHandle* buffer = reinterpret_cast< EntityHandle* >( dataBuffer );
1332 const long buffer_size = bufferSize / std::max( sizeof( EntityHandle ), H5Tget_size( file_type ) );
1333 long remaining = size, offset = 0;
1334 while( remaining )
1335 {
1336 long count = std::min( buffer_size, remaining );
1337 assert_range( buffer, count );
1338 mhdf_readSparseTagEntitiesWithOpt( *tables, offset, count, file_type, buffer, collIO, &status );
1339 if( is_error( status ) )
1340 {
1341 H5Tclose( file_type );
1342 mhdf_closeData( filePtr, *tables, &status );
1343 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1344 }
1345 H5Tconvert( file_type, handleType, count, buffer, NULL, H5P_DEFAULT );
1346
1347 std::sort( buffer, buffer + count );
1348 for( long i = 0; i < count; ++i )
1349 hint = file_ids.insert( hint, buffer[i], buffer[i] );
1350
1351 remaining -= count;
1352 offset += count;
1353 }
1354
1355 H5Tclose( file_type );
1356 mhdf_closeData( filePtr, *tables, &status );
1357 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1358
1359 return MB_SUCCESS;
1360 }
1361
1362 ErrorCode ReadHDF5::search_tag_values( hid_t tag_table,
1363 unsigned long table_size,
1364 const std::vector< int >& sorted_values,
1365 std::vector< EntityHandle >& value_indices )
1366 {
1367 debug_barrier();
1368
1369 CHECK_OPEN_HANDLES;
1370
1371 mhdf_Status status;
1372 size_t chunk_size = bufferSize / sizeof( int );
1373 int* buffer = reinterpret_cast< int* >( dataBuffer );
1374 size_t remaining = table_size, offset = 0;
1375 while( remaining )
1376 {
1377
1378 size_t count = std::min( chunk_size, remaining );
1379 assert_range( buffer, count );
1380 mhdf_readTagValuesWithOpt( tag_table, offset, count, H5T_NATIVE_INT, buffer, collIO, &status );
1381 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1382
1383
1384 for( size_t i = 0; i < count; ++i )
1385 if( std::binary_search( sorted_values.begin(), sorted_values.end(), (int)buffer[i] ) )
1386 value_indices.push_back( i + offset );
1387
1388 offset += count;
1389 remaining -= count;
1390 }
1391
1392 return MB_SUCCESS;
1393 }
1394
1395 ErrorCode ReadHDF5::read_nodes( const Range& node_file_ids )
1396 {
1397 ErrorCode rval;
1398 mhdf_Status status;
1399 const int dim = fileInfo->nodes.vals_per_ent;
1400 Range range;
1401
1402 CHECK_OPEN_HANDLES;
1403
1404 if( node_file_ids.empty() && !nativeParallel ) return MB_SUCCESS;
1405
1406 int cdim;
1407 rval = iFace->get_dimension( cdim );
1408 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1409
1410 if( cdim < dim )
1411 {
1412 rval = iFace->set_dimension( dim );
1413 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1414 }
1415
1416 hid_t data_id = mhdf_openNodeCoordsSimple( filePtr, &status );
1417 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1418
1419 EntityHandle handle;
1420 std::vector< double* > arrays( dim );
1421 const size_t num_nodes = node_file_ids.size();
1422 if( num_nodes > 0 )
1423 {
1424 rval = readUtil->get_node_coords( dim, (int)num_nodes, 0, handle, arrays );
1425 if( MB_SUCCESS != rval )
1426 {
1427 mhdf_closeData( filePtr, data_id, &status );
1428 MB_SET_ERR( rval, "ReadHDF5 Failure" );
1429 }
1430 }
1431
1432 if( blockedCoordinateIO )
1433 {
1434 try
1435 {
1436 for( int d = 0; d < dim; ++d )
1437 {
1438 ReadHDF5Dataset reader( "blocked coords", data_id, nativeParallel, mpiComm, false );
1439 reader.set_column( d );
1440 reader.set_file_ids( node_file_ids, fileInfo->nodes.start_id, num_nodes, H5T_NATIVE_DOUBLE );
1441 dbgOut.printf( 3, "Reading %lu chunks for coordinate dimension %d\n", reader.get_read_count(), d );
1442
1443
1444 size_t count, offset = 0;
1445 int nn = 0;
1446 while( !reader.done() )
1447 {
1448 dbgOut.printf( 3, "Reading chunk %d for dimension %d\n", ++nn, d );
1449 reader.read( arrays[d] + offset, count );
1450 offset += count;
1451 }
1452 if( offset != num_nodes )
1453 {
1454 mhdf_closeData( filePtr, data_id, &status );
1455 assert( false );
1456 return MB_FAILURE;
1457 }
1458 }
1459 }
1460 catch( ReadHDF5Dataset::Exception )
1461 {
1462 mhdf_closeData( filePtr, data_id, &status );
1463 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1464 }
1465 }
1466 else
1467 {
1468 double* buffer = (double*)dataBuffer;
1469 long chunk_size = bufferSize / ( 3 * sizeof( double ) );
1470 long coffset = 0;
1471 int nn = 0;
1472 try
1473 {
1474 ReadHDF5Dataset reader( "interleaved coords", data_id, nativeParallel, mpiComm, false );
1475 reader.set_file_ids( node_file_ids, fileInfo->nodes.start_id, chunk_size, H5T_NATIVE_DOUBLE );
1476 dbgOut.printf( 3, "Reading %lu chunks for coordinate coordinates\n", reader.get_read_count() );
1477 while( !reader.done() )
1478 {
1479 dbgOut.tprintf( 3, "Reading chunk %d of node coords\n", ++nn );
1480
1481 size_t count;
1482 reader.read( buffer, count );
1483
1484 for( size_t i = 0; i < count; ++i )
1485 for( int d = 0; d < dim; ++d )
1486 arrays[d][coffset + i] = buffer[dim * i + d];
1487 coffset += count;
1488 }
1489 }
1490 catch( ReadHDF5Dataset::Exception )
1491 {
1492 mhdf_closeData( filePtr, data_id, &status );
1493 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1494 }
1495 }
1496
1497 dbgOut.print( 3, "Closing node coordinate table\n" );
1498 mhdf_closeData( filePtr, data_id, &status );
1499 for( int d = dim; d < cdim; ++d )
1500 memset( arrays[d], 0, num_nodes * sizeof( double ) );
1501
1502 dbgOut.printf( 3, "Updating ID to handle map for %lu nodes\n", (unsigned long)node_file_ids.size() );
1503 return insert_in_id_map( node_file_ids, handle );
1504 }
1505
1506 ErrorCode ReadHDF5::read_elems( int i )
1507 {
1508 Range ids;
1509 ids.insert( fileInfo->elems[i].desc.start_id,
1510 fileInfo->elems[i].desc.start_id + fileInfo->elems[i].desc.count - 1 );
1511 return read_elems( i, ids );
1512 }
1513
1514 ErrorCode ReadHDF5::read_elems( int i, const Range& file_ids, Range* node_ids )
1515 {
1516 if( fileInfo->elems[i].desc.vals_per_ent < 0 )
1517 {
1518 if( node_ids != 0 )
1519 MB_CHK_ERR( MB_TYPE_OUT_OF_RANGE );
1520 return read_poly( fileInfo->elems[i], file_ids );
1521 }
1522 else
1523 return read_elems( fileInfo->elems[i], file_ids, node_ids );
1524 }
1525
1526 ErrorCode ReadHDF5::read_elems( const mhdf_ElemDesc& elems, const Range& file_ids, Range* node_ids )
1527 {
1528 CHECK_OPEN_HANDLES;
1529
1530 debug_barrier();
1531 dbgOut.tprintf( 1, "READING %s CONNECTIVITY (%lu elems in %lu selects)\n", elems.handle,
1532 (unsigned long)file_ids.size(), (unsigned long)file_ids.psize() );
1533
1534 ErrorCode rval = MB_SUCCESS;
1535 mhdf_Status status;
1536
1537 EntityType type = CN::EntityTypeFromName( elems.type );
1538 if( type == MBMAXTYPE )
1539 {
1540 MB_SET_ERR( MB_FAILURE, "Unknown element type: \"" << elems.type << "\"" );
1541 }
1542
1543 const int nodes_per_elem = elems.desc.vals_per_ent;
1544 const size_t count = file_ids.size();
1545 hid_t data_id = mhdf_openConnectivitySimple( filePtr, elems.handle, &status );
1546 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1547
1548 EntityHandle handle;
1549 EntityHandle* array = 0;
1550 if( count > 0 ) rval = readUtil->get_element_connect( count, nodes_per_elem, type, 0, handle, array );
1551 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1552
1553 try
1554 {
1555 EntityHandle* buffer = reinterpret_cast< EntityHandle* >( dataBuffer );
1556 const size_t buffer_size = bufferSize / ( sizeof( EntityHandle ) * nodes_per_elem );
1557 ReadHDF5Dataset reader( elems.handle, data_id, nativeParallel, mpiComm );
1558 reader.set_file_ids( file_ids, elems.desc.start_id, buffer_size, handleType );
1559 dbgOut.printf( 3, "Reading connectivity in %lu chunks for element group \"%s\"\n", reader.get_read_count(),
1560 elems.handle );
1561 EntityHandle* iter = array;
1562 int nn = 0;
1563 while( !reader.done() )
1564 {
1565 dbgOut.printf( 3, "Reading chunk %d for \"%s\"\n", ++nn, elems.handle );
1566
1567 size_t num_read;
1568 reader.read( buffer, num_read );
1569 iter = std::copy( buffer, buffer + num_read * nodes_per_elem, iter );
1570
1571 if( node_ids )
1572 {
1573 std::sort( buffer, buffer + num_read * nodes_per_elem );
1574 num_read = std::unique( buffer, buffer + num_read * nodes_per_elem ) - buffer;
1575 copy_sorted_file_ids( buffer, num_read, *node_ids );
1576 }
1577 }
1578 assert( iter - array == (ptrdiff_t)count * nodes_per_elem );
1579 }
1580 catch( ReadHDF5Dataset::Exception )
1581 {
1582 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1583 }
1584
1585 if( !node_ids )
1586 {
1587 rval = convert_id_to_handle( array, count * nodes_per_elem );
1588 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1589
1590 rval = readUtil->update_adjacencies( handle, count, nodes_per_elem, array );
1591 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1592 }
1593 else
1594 {
1595 IDConnectivity t;
1596 t.handle = handle;
1597 t.count = count;
1598 t.nodes_per_elem = nodes_per_elem;
1599 t.array = array;
1600 idConnectivityList.push_back( t );
1601 }
1602
1603 return insert_in_id_map( file_ids, handle );
1604 }
1605
1606 ErrorCode ReadHDF5::update_connectivity()
1607 {
1608 ErrorCode rval;
1609 std::vector< IDConnectivity >::iterator i;
1610 for( i = idConnectivityList.begin(); i != idConnectivityList.end(); ++i )
1611 {
1612 rval = convert_id_to_handle( i->array, i->count * i->nodes_per_elem );
1613 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1614
1615 rval = readUtil->update_adjacencies( i->handle, i->count, i->nodes_per_elem, i->array );
1616 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1617 }
1618 idConnectivityList.clear();
1619
1620 return MB_SUCCESS;
1621 }
1622
1623 ErrorCode ReadHDF5::read_node_adj_elems( const mhdf_ElemDesc& group, Range* handles_out )
1624 {
1625 mhdf_Status status;
1626 ErrorCode rval;
1627
1628 CHECK_OPEN_HANDLES;
1629
1630 hid_t table = mhdf_openConnectivitySimple( filePtr, group.handle, &status );
1631 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1632
1633 rval = read_node_adj_elems( group, table, handles_out );
1634
1635 mhdf_closeData( filePtr, table, &status );
1636 if( MB_SUCCESS == rval && is_error( status ) ) MB_SET_ERR_RET_VAL( "ReadHDF5 Failure", MB_FAILURE );
1637
1638 return rval;
1639 }
1640
1641 ErrorCode ReadHDF5::read_node_adj_elems( const mhdf_ElemDesc& group, hid_t table_handle, Range* handles_out )
1642 {
1643 CHECK_OPEN_HANDLES;
1644
1645 debug_barrier();
1646
1647 mhdf_Status status;
1648 ErrorCode rval;
1649 IODebugTrack debug_track( debugTrack, std::string( group.handle ) );
1650
1651
1652 const int node_per_elem = group.desc.vals_per_ent;
1653 long start_id = group.desc.start_id;
1654 long remaining = group.desc.count;
1655 const EntityType type = CN::EntityTypeFromName( group.type );
1656
1657
1658 long* const buffer = reinterpret_cast< long* >( dataBuffer );
1659 const long buffer_size = bufferSize / ( node_per_elem * sizeof( buffer[0] ) );
1660
1661 long offset = 0;
1662 dbgOut.printf( 3, "Reading node-adjacent elements from \"%s\" in %ld chunks\n", group.handle,
1663 ( remaining + buffer_size - 1 ) / buffer_size );
1664 int nn = 0;
1665 Range::iterator hint;
1666 if( handles_out ) hint = handles_out->begin();
1667 while( remaining )
1668 {
1669 dbgOut.printf( 3, "Reading chunk %d of connectivity data for \"%s\"\n", ++nn, group.handle );
1670
1671
1672 const long count = std::min( remaining, buffer_size );
1673 debug_track.record_io( offset, count );
1674 assert_range( buffer, count * node_per_elem );
1675 mhdf_readConnectivityWithOpt( table_handle, offset, count, H5T_NATIVE_LONG, buffer, collIO, &status );
1676 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1677 offset += count;
1678 remaining -= count;
1679
1680
1681
1682 long num_elem = 0;
1683 long* iter = buffer;
1684 for( long i = 0; i < count; ++i )
1685 {
1686 for( int j = 0; j < node_per_elem; ++j )
1687 {
1688 iter[j] = (long)idMap.find( iter[j] );
1689 if( !iter[j] )
1690 {
1691 iter[0] = 0;
1692 break;
1693 }
1694 }
1695 if( iter[0] ) ++num_elem;
1696 iter += node_per_elem;
1697 }
1698
1699 if( !num_elem )
1700 {
1701 start_id += count;
1702 continue;
1703 }
1704
1705
1706 EntityHandle handle;
1707 EntityHandle* array;
1708 rval = readUtil->get_element_connect( (int)num_elem, node_per_elem, type, 0, handle, array );
1709 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1710
1711
1712 iter = buffer;
1713 EntityHandle* iter2 = array;
1714 EntityHandle h = handle;
1715 for( long i = 0; i < count; ++i )
1716 {
1717 if( !*iter )
1718 {
1719 iter += node_per_elem;
1720 continue;
1721 }
1722 if( !idMap.insert( start_id + i, h++, 1 ).second ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1723
1724 long* const end = iter + node_per_elem;
1725 for( ; iter != end; ++iter, ++iter2 )
1726 *iter2 = (EntityHandle)*iter;
1727 }
1728 assert( iter2 - array == num_elem * node_per_elem );
1729 start_id += count;
1730
1731 rval = readUtil->update_adjacencies( handle, num_elem, node_per_elem, array );
1732 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1733 if( handles_out ) hint = handles_out->insert( hint, handle, handle + num_elem - 1 );
1734 }
1735
1736 debug_track.all_reduce();
1737 return MB_SUCCESS;
1738 }
1739
1740 ErrorCode ReadHDF5::read_elems( int i, const Range& elems_in, Range& nodes )
1741 {
1742 CHECK_OPEN_HANDLES;
1743
1744 debug_barrier();
1745 dbgOut.tprintf( 1, "READING %s CONNECTIVITY (%lu elems in %lu selects)\n", fileInfo->elems[i].handle,
1746 (unsigned long)elems_in.size(), (unsigned long)elems_in.psize() );
1747
1748 EntityHandle* const buffer = reinterpret_cast< EntityHandle* >( dataBuffer );
1749 const int node_per_elem = fileInfo->elems[i].desc.vals_per_ent;
1750 const size_t buffer_size = bufferSize / ( node_per_elem * sizeof( EntityHandle ) );
1751
1752 if( elems_in.empty() ) return MB_SUCCESS;
1753
1754 assert( (long)elems_in.front() >= fileInfo->elems[i].desc.start_id );
1755 assert( (long)elems_in.back() - fileInfo->elems[i].desc.start_id < fileInfo->elems[i].desc.count );
1756
1757
1758 if( fileInfo->elems[i].desc.vals_per_ent <= 0 ) MB_CHK_ERR( MB_TYPE_OUT_OF_RANGE );
1759
1760 mhdf_Status status;
1761 hid_t table = mhdf_openConnectivitySimple( filePtr, fileInfo->elems[i].handle, &status );
1762 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1763
1764 try
1765 {
1766 ReadHDF5Dataset reader( fileInfo->elems[i].handle, table, nativeParallel, mpiComm );
1767 reader.set_file_ids( elems_in, fileInfo->elems[i].desc.start_id, buffer_size, handleType );
1768 dbgOut.printf( 3, "Reading node list in %lu chunks for \"%s\"\n", reader.get_read_count(),
1769 fileInfo->elems[i].handle );
1770 int nn = 0;
1771 while( !reader.done() )
1772 {
1773 dbgOut.printf( 3, "Reading chunk %d of \"%s\" connectivity\n", ++nn, fileInfo->elems[i].handle );
1774 size_t num_read;
1775 reader.read( buffer, num_read );
1776 std::sort( buffer, buffer + num_read * node_per_elem );
1777 num_read = std::unique( buffer, buffer + num_read * node_per_elem ) - buffer;
1778 copy_sorted_file_ids( buffer, num_read, nodes );
1779 }
1780 }
1781 catch( ReadHDF5Dataset::Exception )
1782 {
1783 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1784 }
1785
1786 return MB_SUCCESS;
1787 }
1788
1789 ErrorCode ReadHDF5::read_poly( const mhdf_ElemDesc& elems, const Range& file_ids )
1790 {
1791 class PolyReader : public ReadHDF5VarLen
1792 {
1793 private:
1794 const EntityType type;
1795 ReadHDF5* readHDF5;
1796
1797 public:
1798 PolyReader( EntityType elem_type, void* buffer, size_t buffer_size, ReadHDF5* owner, DebugOutput& dbg )
1799 : ReadHDF5VarLen( dbg, buffer, buffer_size ), type( elem_type ), readHDF5( owner )
1800 {
1801 }
1802 virtual ~PolyReader() {}
1803 ErrorCode store_data( EntityHandle file_id, void* data, long len, bool )
1804 {
1805 size_t valid;
1806 EntityHandle* conn = reinterpret_cast< EntityHandle* >( data );
1807 readHDF5->convert_id_to_handle( conn, len, valid );
1808 if( valid != (size_t)len ) MB_CHK_ERR( MB_ENTITY_NOT_FOUND );
1809 EntityHandle handle;
1810 ErrorCode rval = readHDF5->moab()->create_element( type, conn, len, handle );
1811 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1812
1813 rval = readHDF5->insert_in_id_map( file_id, handle );
1814 return rval;
1815 }
1816 };
1817
1818 CHECK_OPEN_HANDLES;
1819
1820 debug_barrier();
1821
1822 EntityType type = CN::EntityTypeFromName( elems.type );
1823 if( type == MBMAXTYPE )
1824 {
1825 MB_SET_ERR( MB_FAILURE, "Unknown element type: \"" << elems.type << "\"" );
1826 }
1827
1828 hid_t handles[2];
1829 mhdf_Status status;
1830 long num_poly, num_conn, first_id;
1831 mhdf_openPolyConnectivity( filePtr, elems.handle, &num_poly, &num_conn, &first_id, handles, &status );
1832 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1833
1834 std::string nm( elems.handle );
1835 ReadHDF5Dataset offset_reader( ( nm + " offsets" ).c_str(), handles[0], nativeParallel, mpiComm, true );
1836 ReadHDF5Dataset connect_reader( ( nm + " data" ).c_str(), handles[1], nativeParallel, mpiComm, true );
1837
1838 PolyReader tool( type, dataBuffer, bufferSize, this, dbgOut );
1839 return tool.read( offset_reader, connect_reader, file_ids, first_id, handleType );
1840 }
1841
1842 ErrorCode ReadHDF5::delete_non_side_elements( const Range& side_ents )
1843 {
1844 ErrorCode rval;
1845
1846
1847 Range explicit_ents;
1848 Range::iterator hint = explicit_ents.begin();
1849 for( IDMap::iterator i = idMap.begin(); i != idMap.end(); ++i )
1850 {
1851 EntityHandle start = i->value;
1852 EntityHandle end = i->value + i->count - 1;
1853 EntityType type = TYPE_FROM_HANDLE( start );
1854 assert( type == TYPE_FROM_HANDLE( end ) );
1855 if( type != MBVERTEX && type != MBENTITYSET ) hint = explicit_ents.insert( hint, start, end );
1856 }
1857 explicit_ents = subtract( explicit_ents, side_ents );
1858
1859
1860 Range dead_ents( side_ents );
1861 Range::iterator ds, de, es;
1862 ds = dead_ents.lower_bound( CN::TypeDimensionMap[1].first );
1863 de = dead_ents.lower_bound( CN::TypeDimensionMap[2].first, ds );
1864 if( ds != de )
1865 {
1866
1867 es = explicit_ents.lower_bound( CN::TypeDimensionMap[2].first );
1868 Range subset, adj;
1869 subset.insert( es, explicit_ents.end() );
1870 rval = iFace->get_adjacencies( subset, 1, false, adj, Interface::UNION );
1871 if( MB_SUCCESS != rval ) return rval;
1872 dead_ents = subtract( dead_ents, adj );
1873 }
1874 ds = dead_ents.lower_bound( CN::TypeDimensionMap[2].first );
1875 de = dead_ents.lower_bound( CN::TypeDimensionMap[3].first, ds );
1876 assert( de == dead_ents.end() );
1877 if( ds != de )
1878 {
1879
1880 es = explicit_ents.lower_bound( CN::TypeDimensionMap[3].first );
1881 Range subset, adj;
1882 subset.insert( es, explicit_ents.end() );
1883 rval = iFace->get_adjacencies( subset, 2, false, adj, Interface::UNION );
1884 if( MB_SUCCESS != rval ) return rval;
1885 dead_ents = subtract( dead_ents, adj );
1886 }
1887
1888
1889 dbgOut.printf( 2, "Deleting %lu elements\n", (unsigned long)dead_ents.size() );
1890 dbgOut.print( 4, "\tDead entities: ", dead_ents );
1891 rval = iFace->delete_entities( dead_ents );
1892 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1893
1894
1895 while( !dead_ents.empty() )
1896 {
1897 EntityHandle start = dead_ents.front();
1898 EntityID count = dead_ents.const_pair_begin()->second - start + 1;
1899 IDMap::iterator rit;
1900 for( rit = idMap.begin(); rit != idMap.end(); ++rit )
1901 if( rit->value <= start && (EntityID)( start - rit->value ) < rit->count ) break;
1902 if( rit == idMap.end() ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1903
1904 EntityID offset = start - rit->value;
1905 EntityID avail = rit->count - offset;
1906 if( avail < count ) count = avail;
1907
1908 dead_ents.erase( dead_ents.begin(), dead_ents.begin() + count );
1909 idMap.erase( rit->begin + offset, count );
1910 }
1911
1912 return MB_SUCCESS;
1913 }
1914
1915 ErrorCode ReadHDF5::read_sets( const Range& file_ids )
1916 {
1917 CHECK_OPEN_HANDLES;
1918
1919 debug_barrier();
1920
1921 mhdf_Status status;
1922 ErrorCode rval;
1923
1924 const size_t num_sets = fileInfo->sets.count;
1925 if( !num_sets )
1926 return MB_SUCCESS;
1927
1928
1929 std::vector< unsigned > flags( file_ids.size() );
1930 Range::iterator si = file_ids.begin();
1931 for( size_t i = 0; i < flags.size(); ++i, ++si )
1932 flags[i] = setMeta[*si - fileInfo->sets.start_id][3] & ~(long)mhdf_SET_RANGE_BIT;
1933 EntityHandle start_handle;
1934
1935 if( !file_ids.empty() )
1936 {
1937 rval = readUtil->create_entity_sets( flags.size(), &flags[0], 0, start_handle );
1938 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1939 rval = insert_in_id_map( file_ids, start_handle );
1940 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1941 }
1942
1943
1944 if( fileInfo->have_set_contents )
1945 {
1946 long len = 0;
1947 hid_t handle = mhdf_openSetData( filePtr, &len, &status );
1948 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1949
1950 ReadHDF5Dataset dat( "set contents", handle, nativeParallel, mpiComm, true );
1951 rval = read_set_data( file_ids, start_handle, dat, CONTENT );
1952 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1953 }
1954
1955
1956 if( fileInfo->have_set_children )
1957 {
1958 long len = 0;
1959 hid_t handle = mhdf_openSetChildren( filePtr, &len, &status );
1960 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1961
1962 ReadHDF5Dataset dat( "set children", handle, nativeParallel, mpiComm, true );
1963 rval = read_set_data( file_ids, start_handle, dat, CHILD );
1964 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1965 }
1966
1967
1968 if( fileInfo->have_set_parents )
1969 {
1970 long len = 0;
1971 hid_t handle = mhdf_openSetParents( filePtr, &len, &status );
1972 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1973
1974 ReadHDF5Dataset dat( "set parents", handle, nativeParallel, mpiComm, true );
1975 rval = read_set_data( file_ids, start_handle, dat, PARENT );
1976 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
1977 }
1978
1979 return MB_SUCCESS;
1980 }
1981
1982 ErrorCode ReadHDF5::read_all_set_meta()
1983 {
1984 CHECK_OPEN_HANDLES;
1985
1986 assert( !setMeta );
1987 const long num_sets = fileInfo->sets.count;
1988 if( !num_sets ) return MB_SUCCESS;
1989
1990 mhdf_Status status;
1991 hid_t handle = mhdf_openSetMetaSimple( filePtr, &status );
1992 if( is_error( status ) )
1993 {
1994 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
1995 }
1996
1997
1998 hid_t meta_type = H5Dget_type( handle );
1999 size_t size = H5Tget_size( meta_type );
2000 if( size > sizeof( long ) )
2001 setMeta = new long[( num_sets * size + ( sizeof( long ) - 1 ) ) / sizeof( long )][4];
2002 else
2003 setMeta = new long[num_sets][4];
2004
2005
2006
2007 int rank = 0;
2008 bool bcast = false;
2009 hid_t ioprop = H5P_DEFAULT;
2010 #ifdef MOAB_HAVE_MPI
2011 MPI_Comm comm = 0;
2012 if( nativeParallel )
2013 {
2014 rank = myPcomm->proc_config().proc_rank();
2015 comm = myPcomm->proc_config().proc_comm();
2016 bcast = bcastDuplicateReads;
2017 if( !bcast ) ioprop = collIO;
2018 }
2019 #endif
2020
2021 if( !bcast || 0 == rank )
2022 {
2023 mhdf_readSetMetaWithOpt( handle, 0, num_sets, meta_type, setMeta, ioprop, &status );
2024 if( is_error( status ) )
2025 {
2026 H5Tclose( meta_type );
2027 mhdf_closeData( filePtr, handle, &status );
2028 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2029 }
2030
2031 H5Tconvert( meta_type, H5T_NATIVE_LONG, num_sets * 4, setMeta, 0, H5P_DEFAULT );
2032 }
2033 mhdf_closeData( filePtr, handle, &status );
2034 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2035 H5Tclose( meta_type );
2036
2037 if( bcast )
2038 {
2039 #ifdef MOAB_HAVE_MPI
2040 int ierr = MPI_Bcast( (void*)setMeta, num_sets * 4, MPI_LONG, 0, comm );
2041 if( MPI_SUCCESS != ierr ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2042 #else
2043 assert( rank == 0 );
2044 #endif
2045 }
2046
2047 return MB_SUCCESS;
2048 }
2049
2050 ErrorCode ReadHDF5::read_set_ids_recursive( Range& sets_in_out, bool contained_sets, bool child_sets )
2051 {
2052 CHECK_OPEN_HANDLES;
2053 mhdf_Status status;
2054
2055 if( !fileInfo->have_set_children ) child_sets = false;
2056 if( !fileInfo->have_set_contents ) contained_sets = false;
2057 if( !child_sets && !contained_sets ) return MB_SUCCESS;
2058
2059
2060 if( fileInfo->sets.count == 0 )
2061 {
2062 assert( sets_in_out.empty() );
2063 return MB_SUCCESS;
2064 }
2065
2066 if( !contained_sets && !child_sets ) return MB_SUCCESS;
2067
2068 ReadHDF5Dataset cont( "set contents", false, mpiComm );
2069 ReadHDF5Dataset child( "set children", false, mpiComm );
2070
2071 if( contained_sets )
2072 {
2073 long content_len = 0;
2074 hid_t content_handle = mhdf_openSetData( filePtr, &content_len, &status );
2075 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2076 try
2077 {
2078 cont.init( content_handle, true );
2079 }
2080 catch( ReadHDF5Dataset::Exception )
2081 {
2082 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2083 }
2084 }
2085
2086 if( child_sets )
2087 {
2088 long child_len = 0;
2089 hid_t child_handle = mhdf_openSetChildren( filePtr, &child_len, &status );
2090 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2091 try
2092 {
2093 child.init( child_handle, true );
2094 }
2095 catch( ReadHDF5Dataset::Exception )
2096 {
2097 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2098 }
2099 }
2100
2101 ErrorCode rval = MB_SUCCESS;
2102 Range children, new_children( sets_in_out );
2103 int iteration_count = 0;
2104 do
2105 {
2106 ++iteration_count;
2107 dbgOut.tprintf( 2, "Iteration %d of read_set_ids_recursive\n", iteration_count );
2108 children.clear();
2109 if( child_sets )
2110 {
2111 rval = read_set_data( new_children, 0, child, CHILD, &children );
2112 if( MB_SUCCESS != rval ) break;
2113 }
2114 if( contained_sets )
2115 {
2116 rval = read_set_data( new_children, 0, cont, CONTENT, &children );
2117
2118 Range::iterator it = children.lower_bound( fileInfo->sets.start_id );
2119 children.erase( children.begin(), it );
2120 it = children.lower_bound( fileInfo->sets.start_id + fileInfo->sets.count );
2121 children.erase( it, children.end() );
2122 if( MB_SUCCESS != rval ) break;
2123 }
2124 new_children = subtract( children, sets_in_out );
2125 dbgOut.print_ints( 2, "Adding additional contained/child sets", new_children );
2126 sets_in_out.merge( new_children );
2127 } while( !new_children.empty() );
2128
2129 return MB_SUCCESS;
2130 }
2131
2132 ErrorCode ReadHDF5::find_sets_containing( Range& sets_out, bool read_set_containing_parents )
2133 {
2134 ErrorCode rval;
2135 mhdf_Status status;
2136
2137 CHECK_OPEN_HANDLES;
2138
2139 if( !fileInfo->have_set_contents ) return MB_SUCCESS;
2140 assert( fileInfo->sets.count );
2141
2142
2143 long content_len = 0;
2144 hid_t content_handle = mhdf_openSetData( filePtr, &content_len, &status );
2145 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2146
2147 hid_t data_type = H5Dget_type( content_handle );
2148
2149 rval = find_sets_containing( content_handle, data_type, content_len, read_set_containing_parents, sets_out );
2150
2151 H5Tclose( data_type );
2152
2153 mhdf_closeData( filePtr, content_handle, &status );
2154 if( MB_SUCCESS == rval && is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2155
2156 return rval;
2157 }
2158
2159 static bool set_map_intersect( bool ranged,
2160 const long* contents,
2161 int content_len,
2162 const RangeMap< long, EntityHandle >& id_map )
2163 {
2164 if( ranged )
2165 {
2166 if( !content_len || id_map.empty() ) return false;
2167
2168 const long* j = contents;
2169 const long* const end = contents + content_len;
2170 assert( content_len % 2 == 0 );
2171 while( j != end )
2172 {
2173 long start = *( j++ );
2174 long count = *( j++ );
2175 if( id_map.intersects( start, count ) ) return true;
2176 }
2177 }
2178 else
2179 {
2180 const long* const end = contents + content_len;
2181 for( const long* i = contents; i != end; ++i )
2182 if( id_map.exists( *i ) ) return true;
2183 }
2184
2185 return false;
2186 }
2187
2188 struct SetContOffComp
2189 {
2190 bool operator()( const long a1[4], const long a2[4] )
2191 {
2192 return a1[ReadHDF5::CONTENT] < a2[0];
2193 }
2194 };
2195
2196 ErrorCode ReadHDF5::find_sets_containing( hid_t contents_handle,
2197 hid_t content_type,
2198 long contents_len,
2199 bool read_set_containing_parents,
2200 Range& file_ids )
2201 {
2202 CHECK_OPEN_HANDLES;
2203
2204
2205
2206 const size_t content_size = H5Tget_size( content_type );
2207 const long num_sets = fileInfo->sets.count;
2208 dbgOut.printf( 2, "Searching contents of %ld\n", num_sets );
2209 mhdf_Status status;
2210
2211 int rank = 0;
2212 bool bcast = false;
2213 #ifdef MOAB_HAVE_MPI
2214 MPI_Comm comm = 0;
2215 if( nativeParallel )
2216 {
2217 rank = myPcomm->proc_config().proc_rank();
2218 comm = myPcomm->proc_config().proc_comm();
2219 bcast = bcastDuplicateReads;
2220 }
2221 #endif
2222
2223
2224
2225 long prev = -1;
2226 for( long i = 0; i < num_sets; ++i )
2227 {
2228 if( setMeta[i][CONTENT] < prev )
2229 {
2230 std::cerr << "Invalid data in set contents offsets at position " << i << ": index " << setMeta[i][CONTENT]
2231 << " is less than previous index " << prev << std::endl;
2232 std::cerr.flush();
2233 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2234 }
2235 prev = setMeta[i][CONTENT];
2236 }
2237 if( setMeta[num_sets - 1][CONTENT] >= contents_len )
2238 {
2239 std::cerr << "Maximum set content index " << setMeta[num_sets - 1][CONTENT]
2240 << " exceeds contents table length of " << contents_len << std::endl;
2241 std::cerr.flush();
2242 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2243 }
2244
2245
2246 long* const content_buffer = (long*)dataBuffer;
2247 const long content_len = bufferSize / std::max( content_size, sizeof( long ) );
2248
2249
2250 Range::iterator hint = file_ids.begin();
2251 Range tmp_range;
2252 long prev_idx = -1;
2253 int mm = 0;
2254 long sets_offset = 0;
2255 long temp_content[4];
2256 while( sets_offset < num_sets )
2257 {
2258 temp_content[0] = content_len + prev_idx;
2259 long sets_count =
2260 std::lower_bound( setMeta + sets_offset, setMeta + num_sets, temp_content, SetContOffComp() ) - setMeta -
2261 sets_offset;
2262 assert( sets_count >= 0 && sets_offset + sets_count <= num_sets );
2263 if( !sets_count )
2264 {
2265 long content_remaining = setMeta[sets_offset][CONTENT] - prev_idx;
2266 long content_offset = prev_idx + 1;
2267 while( content_remaining )
2268 {
2269 long content_count = content_len < content_remaining ? 2 * ( content_len / 2 ) : content_remaining;
2270 assert_range( content_buffer, content_count );
2271 dbgOut.printf( 3, "Reading chunk %d (%ld values) from set contents table\n", ++mm, content_count );
2272 if( !bcast || 0 == rank )
2273 {
2274 if( !bcast )
2275 mhdf_readSetDataWithOpt( contents_handle, content_offset, content_count, content_type,
2276 content_buffer, collIO, &status );
2277 else
2278 mhdf_readSetData( contents_handle, content_offset, content_count, content_type, content_buffer,
2279 &status );
2280 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2281
2282 H5Tconvert( content_type, H5T_NATIVE_LONG, content_count, content_buffer, 0, H5P_DEFAULT );
2283 }
2284 if( bcast )
2285 {
2286 #ifdef MOAB_HAVE_MPI
2287 int ierr = MPI_Bcast( content_buffer, content_count, MPI_LONG, 0, comm );
2288 if( MPI_SUCCESS != ierr ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2289 #else
2290 assert( rank == 0 );
2291 #endif
2292 }
2293
2294 if( read_set_containing_parents )
2295 {
2296 tmp_range.clear();
2297 if( setMeta[sets_offset][3] & mhdf_SET_RANGE_BIT )
2298 tmp_range.insert( *content_buffer, *( content_buffer + 1 ) );
2299 else
2300 std::copy( content_buffer, content_buffer + content_count, range_inserter( tmp_range ) );
2301 tmp_range = intersect( tmp_range, file_ids );
2302 }
2303
2304 if( !tmp_range.empty() || set_map_intersect( setMeta[sets_offset][3] & mhdf_SET_RANGE_BIT,
2305 content_buffer, content_count, idMap ) )
2306 {
2307 long id = fileInfo->sets.start_id + sets_offset;
2308 hint = file_ids.insert( hint, id, id );
2309 if( !nativeParallel )
2310
2311 break;
2312 }
2313 content_remaining -= content_count;
2314 content_offset += content_count;
2315 }
2316 prev_idx = setMeta[sets_offset][CONTENT];
2317 sets_count = 1;
2318 }
2319 else if( long read_num = setMeta[sets_offset + sets_count - 1][CONTENT] - prev_idx )
2320 {
2321 assert( sets_count > 0 );
2322 assert_range( content_buffer, read_num );
2323 dbgOut.printf( 3, "Reading chunk %d (%ld values) from set contents table\n", ++mm, read_num );
2324 if( !bcast || 0 == rank )
2325 {
2326 if( !bcast )
2327 mhdf_readSetDataWithOpt( contents_handle, prev_idx + 1, read_num, content_type, content_buffer,
2328 collIO, &status );
2329 else
2330 mhdf_readSetData( contents_handle, prev_idx + 1, read_num, content_type, content_buffer, &status );
2331 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2332
2333 H5Tconvert( content_type, H5T_NATIVE_LONG, read_num, content_buffer, 0, H5P_DEFAULT );
2334 }
2335 if( bcast )
2336 {
2337 #ifdef MOAB_HAVE_MPI
2338 int ierr = MPI_Bcast( content_buffer, read_num, MPI_LONG, 0, comm );
2339 if( MPI_SUCCESS != ierr ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2340 #else
2341 assert( rank == 0 );
2342 #endif
2343 }
2344
2345 long* buff_iter = content_buffer;
2346 for( long i = 0; i < sets_count; ++i )
2347 {
2348 long set_size = setMeta[i + sets_offset][CONTENT] - prev_idx;
2349 prev_idx += set_size;
2350
2351
2352 if( read_set_containing_parents )
2353 {
2354 tmp_range.clear();
2355 if( setMeta[sets_offset + i][3] & mhdf_SET_RANGE_BIT )
2356 {
2357
2358
2359 const long* j = buff_iter;
2360 const long* const end = buff_iter + set_size;
2361 assert( set_size % 2 == 0 );
2362 while( j != end )
2363 {
2364 long start = *( j++ );
2365 long count = *( j++ );
2366 tmp_range.insert( start, start + count - 1 );
2367 }
2368 }
2369 else
2370 std::copy( buff_iter, buff_iter + set_size, range_inserter( tmp_range ) );
2371 tmp_range = intersect( tmp_range, file_ids );
2372 }
2373
2374 if( !tmp_range.empty() ||
2375 set_map_intersect( setMeta[sets_offset + i][3] & mhdf_SET_RANGE_BIT, buff_iter, set_size, idMap ) )
2376 {
2377 long id = fileInfo->sets.start_id + sets_offset + i;
2378 hint = file_ids.insert( hint, id, id );
2379 }
2380 buff_iter += set_size;
2381 }
2382 }
2383
2384 sets_offset += sets_count;
2385 }
2386
2387 return MB_SUCCESS;
2388 }
2389
2390 static Range::iterator copy_set_contents( Range::iterator hint,
2391 int ranged,
2392 EntityHandle* contents,
2393 long length,
2394 Range& results )
2395 {
2396 if( ranged )
2397 {
2398 assert( length % 2 == 0 );
2399 for( long i = 0; i < length; i += 2 )
2400 hint = results.insert( hint, contents[i], contents[i] + contents[i + 1] - 1 );
2401 }
2402 else
2403 {
2404 std::sort( contents, contents + length );
2405 for( long i = 0; i < length; ++i )
2406 hint = results.insert( hint, contents[i] );
2407 }
2408 return hint;
2409 }
2410
2411 ErrorCode ReadHDF5::read_set_data( const Range& set_file_ids,
2412 EntityHandle start_handle,
2413 ReadHDF5Dataset& data,
2414 SetMode mode,
2415 Range* file_ids_out )
2416 {
2417 ErrorCode rval;
2418 Range::const_pair_iterator pi;
2419 Range::iterator out_hint;
2420 if( file_ids_out ) out_hint = file_ids_out->begin();
2421
2422
2423
2424
2425 const long TWEAK = 1;
2426 Range data_offsets;
2427 Range::iterator hint = data_offsets.begin();
2428 pi = set_file_ids.const_pair_begin();
2429 if( (long)pi->first == fileInfo->sets.start_id )
2430 {
2431 long second = pi->second - fileInfo->sets.start_id;
2432 if( setMeta[second][mode] >= 0 ) hint = data_offsets.insert( hint, TWEAK, setMeta[second][mode] + TWEAK );
2433 ++pi;
2434 }
2435 for( ; pi != set_file_ids.const_pair_end(); ++pi )
2436 {
2437 long first = pi->first - fileInfo->sets.start_id;
2438 long second = pi->second - fileInfo->sets.start_id;
2439 long idx1 = setMeta[first - 1][mode] + 1;
2440 long idx2 = setMeta[second][mode];
2441 if( idx2 >= idx1 ) hint = data_offsets.insert( hint, idx1 + TWEAK, idx2 + TWEAK );
2442 }
2443 try
2444 {
2445 data.set_file_ids( data_offsets, TWEAK, bufferSize / sizeof( EntityHandle ), handleType );
2446 }
2447 catch( ReadHDF5Dataset::Exception )
2448 {
2449 return MB_FAILURE;
2450 }
2451
2452
2453
2454 EntityHandle h = start_handle;
2455
2456 const long ranged_flag = ( mode == CONTENT ) ? mhdf_SET_RANGE_BIT : 0;
2457
2458 std::vector< EntityHandle > partial;
2459 Range::const_iterator fileid_iter = set_file_ids.begin();
2460 EntityHandle* buffer = reinterpret_cast< EntityHandle* >( dataBuffer );
2461 size_t count, offset;
2462
2463 int nn = 0;
2464
2475 if( ( 1 >= set_file_ids.size() ) && ( data.done() ) && moab::ReadHDF5::CONTENT == mode )
2476
2477 data.null_read();
2478
2479 while( !data.done() )
2480 {
2481 dbgOut.printf( 3, "Reading chunk %d of %s\n", ++nn, data.get_debug_desc() );
2482 try
2483 {
2484 data.read( buffer, count );
2485 }
2486 catch( ReadHDF5Dataset::Exception )
2487 {
2488 return MB_FAILURE;
2489 }
2490
2491
2492
2493
2494
2495
2496
2497 offset = 0;
2498 if( !partial.empty() )
2499 {
2500 assert( fileid_iter != set_file_ids.end() );
2501 size_t num_prev = partial.size();
2502 size_t idx = *fileid_iter - fileInfo->sets.start_id;
2503 size_t len = idx ? setMeta[idx][mode] - setMeta[idx - 1][mode] : setMeta[idx][mode] + 1;
2504 offset = len - num_prev;
2505 if( offset > count )
2506 {
2507 partial.insert( partial.end(), buffer, buffer + count );
2508 continue;
2509 }
2510
2511 partial.insert( partial.end(), buffer, buffer + offset );
2512 if( file_ids_out )
2513 {
2514 out_hint = copy_set_contents( out_hint, setMeta[idx][3] & ranged_flag, &partial[0], partial.size(),
2515 *file_ids_out );
2516 }
2517 else
2518 {
2519 switch( mode )
2520 {
2521 size_t valid;
2522 case CONTENT:
2523 if( setMeta[idx][3] & ranged_flag )
2524 {
2525 if( len % 2 ) MB_CHK_ERR( MB_INDEX_OUT_OF_RANGE );
2526 Range range;
2527 convert_range_to_handle( &partial[0], len / 2, range );
2528 rval = moab()->add_entities( h, range );
2529 }
2530 else
2531 {
2532 convert_id_to_handle( &partial[0], len, valid );
2533 rval = moab()->add_entities( h, &partial[0], valid );
2534 }
2535 break;
2536 case CHILD:
2537 convert_id_to_handle( &partial[0], len, valid );
2538 rval = moab()->add_child_meshsets( h, &partial[0], valid );
2539 break;
2540 case PARENT:
2541 convert_id_to_handle( &partial[0], len, valid );
2542 rval = moab()->add_parent_meshsets( h, &partial[0], valid );
2543 break;
2544 default:
2545 break;
2546 }
2547 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
2548 }
2549
2550 ++fileid_iter;
2551 ++h;
2552 partial.clear();
2553 }
2554
2555
2556
2557 while( offset < count )
2558 {
2559 assert( fileid_iter != set_file_ids.end() );
2560 size_t idx = *fileid_iter - fileInfo->sets.start_id;
2561 size_t len = idx ? setMeta[idx][mode] - setMeta[idx - 1][mode] : setMeta[idx][mode] + 1;
2562
2563
2564
2565 if( offset + len > count )
2566 {
2567 partial.insert( partial.end(), buffer + offset, buffer + count );
2568 break;
2569 }
2570
2571 if( file_ids_out )
2572 {
2573 out_hint =
2574 copy_set_contents( out_hint, setMeta[idx][3] & ranged_flag, buffer + offset, len, *file_ids_out );
2575 }
2576 else
2577 {
2578 switch( mode )
2579 {
2580 size_t valid;
2581 case CONTENT:
2582 if( setMeta[idx][3] & ranged_flag )
2583 {
2584 if( len % 2 ) MB_CHK_ERR( MB_INDEX_OUT_OF_RANGE );
2585 Range range;
2586 convert_range_to_handle( buffer + offset, len / 2, range );
2587 rval = moab()->add_entities( h, range );
2588 }
2589 else
2590 {
2591 convert_id_to_handle( buffer + offset, len, valid );
2592 rval = moab()->add_entities( h, buffer + offset, valid );
2593 }
2594 break;
2595 case CHILD:
2596 convert_id_to_handle( buffer + offset, len, valid );
2597 rval = moab()->add_child_meshsets( h, buffer + offset, valid );
2598 break;
2599 case PARENT:
2600 convert_id_to_handle( buffer + offset, len, valid );
2601 rval = moab()->add_parent_meshsets( h, buffer + offset, valid );
2602 break;
2603 default:
2604 break;
2605 }
2606 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
2607 }
2608
2609 ++fileid_iter;
2610 ++h;
2611 offset += len;
2612 }
2613 }
2614
2615 return MB_SUCCESS;
2616 }
2617
2618 ErrorCode ReadHDF5::get_set_contents( const Range& sets, Range& file_ids )
2619 {
2620 CHECK_OPEN_HANDLES;
2621
2622 if( !fileInfo->have_set_contents ) return MB_SUCCESS;
2623 dbgOut.tprint( 2, "Reading set contained file IDs\n" );
2624 try
2625 {
2626 mhdf_Status status;
2627 long content_len;
2628 hid_t contents = mhdf_openSetData( filePtr, &content_len, &status );
2629 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2630 ReadHDF5Dataset data( "set contents", contents, nativeParallel, mpiComm, true );
2631
2632 return read_set_data( sets, 0, data, CONTENT, &file_ids );
2633 }
2634 catch( ReadHDF5Dataset::Exception )
2635 {
2636 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2637 }
2638 }
2639
2640 ErrorCode ReadHDF5::read_adjacencies( hid_t table, long table_len )
2641 {
2642 CHECK_OPEN_HANDLES;
2643
2644 ErrorCode rval;
2645 mhdf_Status status;
2646
2647 debug_barrier();
2648
2649 hid_t read_type = H5Dget_type( table );
2650 if( read_type < 0 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2651 const bool convert = !H5Tequal( read_type, handleType );
2652
2653 EntityHandle* buffer = (EntityHandle*)dataBuffer;
2654 size_t chunk_size = bufferSize / H5Tget_size( read_type );
2655 size_t remaining = table_len;
2656 size_t left_over = 0;
2657 size_t offset = 0;
2658 dbgOut.printf( 3, "Reading adjacency list in %lu chunks\n",
2659 (unsigned long)( remaining + chunk_size - 1 ) / chunk_size );
2660 int nn = 0;
2661 while( remaining )
2662 {
2663 dbgOut.printf( 3, "Reading chunk %d of adjacency list\n", ++nn );
2664
2665 size_t count = std::min( chunk_size, remaining );
2666 count -= left_over;
2667 remaining -= count;
2668
2669 assert_range( buffer + left_over, count );
2670 mhdf_readAdjacencyWithOpt( table, offset, count, read_type, buffer + left_over, collIO, &status );
2671 if( is_error( status ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2672
2673 if( convert )
2674 {
2675 herr_t err = H5Tconvert( read_type, handleType, count, buffer + left_over, 0, H5P_DEFAULT );
2676 if( err < 0 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2677 }
2678
2679 EntityHandle* iter = buffer;
2680 EntityHandle* end = buffer + count + left_over;
2681 while( end - iter >= 3 )
2682 {
2683 EntityHandle h = idMap.find( *iter++ );
2684 EntityHandle count2 = *iter++;
2685 if( !h )
2686 {
2687 iter += count2;
2688 continue;
2689 }
2690
2691 if( count2 < 1 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2692
2693 if( end < count2 + iter )
2694 {
2695 iter -= 2;
2696 break;
2697 }
2698
2699 size_t valid;
2700 convert_id_to_handle( iter, count2, valid, idMap );
2701 rval = iFace->add_adjacencies( h, iter, valid, false );
2702 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
2703
2704 iter += count2;
2705 }
2706
2707 left_over = end - iter;
2708 assert_range( (char*)buffer, left_over );
2709 assert_range( (char*)iter, left_over );
2710 memmove( buffer, iter, left_over );
2711 }
2712
2713 assert( !left_over );
2714
2715 return MB_SUCCESS;
2716 }
2717
2718 ErrorCode ReadHDF5::read_tag( int tag_index )
2719 {
2720 CHECK_OPEN_HANDLES;
2721
2722 dbgOut.tprintf( 2, "Reading tag \"%s\"\n", fileInfo->tags[tag_index].name );
2723
2724 debug_barrier();
2725
2726 ErrorCode rval;
2727 mhdf_Status status;
2728 Tag tag = 0;
2729 hid_t read_type = -1;
2730 bool table_type;
2731 rval = create_tag( fileInfo->tags[tag_index], tag, read_type );
2732 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
2733
2734 if( fileInfo->tags[tag_index].have_sparse )
2735 {
2736 hid_t handles[3];
2737 long num_ent, num_val;
2738 mhdf_openSparseTagData( filePtr, fileInfo->tags[tag_index].name, &num_ent, &num_val, handles, &status );
2739 if( is_error( status ) )
2740 {
2741 if( read_type ) H5Tclose( read_type );
2742 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2743 }
2744
2745 table_type = false;
2746 if( read_type == 0 )
2747 {
2748 read_type = H5Dget_type( handles[1] );
2749 if( read_type == 0 )
2750 {
2751 mhdf_closeData( filePtr, handles[0], &status );
2752 mhdf_closeData( filePtr, handles[0], &status );
2753 if( fileInfo->tags[tag_index].size <= 0 ) mhdf_closeData( filePtr, handles[2], &status );
2754 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2755 }
2756 table_type = true;
2757 }
2758
2759 if( fileInfo->tags[tag_index].size > 0 )
2760 {
2761 dbgOut.printf( 2, "Reading sparse data for tag \"%s\"\n", fileInfo->tags[tag_index].name );
2762 rval = read_sparse_tag( tag, read_type, handles[0], handles[1], num_ent );
2763 }
2764 else
2765 {
2766 dbgOut.printf( 2, "Reading var-len sparse data for tag \"%s\"\n", fileInfo->tags[tag_index].name );
2767 rval = read_var_len_tag( tag, read_type, handles[0], handles[1], handles[2], num_ent, num_val );
2768 }
2769
2770 if( table_type )
2771 {
2772 H5Tclose( read_type );
2773 read_type = 0;
2774 }
2775
2776 mhdf_closeData( filePtr, handles[0], &status );
2777 if( MB_SUCCESS == rval && is_error( status ) ) rval = MB_FAILURE;
2778 mhdf_closeData( filePtr, handles[1], &status );
2779 if( MB_SUCCESS == rval && is_error( status ) ) rval = MB_FAILURE;
2780 if( fileInfo->tags[tag_index].size <= 0 )
2781 {
2782 mhdf_closeData( filePtr, handles[2], &status );
2783 if( MB_SUCCESS == rval && is_error( status ) ) rval = MB_FAILURE;
2784 }
2785 if( MB_SUCCESS != rval )
2786 {
2787 if( read_type ) H5Tclose( read_type );
2788 MB_SET_ERR( rval, "ReadHDF5 Failure" );
2789 }
2790 }
2791
2792 for( int j = 0; j < fileInfo->tags[tag_index].num_dense_indices; ++j )
2793 {
2794 long count;
2795 const char* name = 0;
2796 mhdf_EntDesc* desc;
2797 int elem_idx = fileInfo->tags[tag_index].dense_elem_indices[j];
2798 if( elem_idx == -2 )
2799 {
2800 desc = &fileInfo->sets;
2801 name = mhdf_set_type_handle();
2802 }
2803 else if( elem_idx == -1 )
2804 {
2805 desc = &fileInfo->nodes;
2806 name = mhdf_node_type_handle();
2807 }
2808 else if( elem_idx >= 0 && elem_idx < fileInfo->num_elem_desc )
2809 {
2810 desc = &fileInfo->elems[elem_idx].desc;
2811 name = fileInfo->elems[elem_idx].handle;
2812 }
2813 else
2814 {
2815 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2816 }
2817
2818 dbgOut.printf( 2, "Read dense data block for tag \"%s\" on \"%s\"\n", fileInfo->tags[tag_index].name, name );
2819
2820 hid_t handle = mhdf_openDenseTagData( filePtr, fileInfo->tags[tag_index].name, name, &count, &status );
2821 if( is_error( status ) )
2822 {
2823 rval = MB_FAILURE;
2824 break;
2825 }
2826
2827 if( count > desc->count )
2828 {
2829 mhdf_closeData( filePtr, handle, &status );
2830 MB_SET_ERR( MB_FAILURE,
2831 "Invalid data length for dense tag data: " << name << "/" << fileInfo->tags[tag_index].name );
2832 }
2833
2834 table_type = false;
2835 if( read_type == 0 )
2836 {
2837 read_type = H5Dget_type( handle );
2838 if( read_type == 0 )
2839 {
2840 mhdf_closeData( filePtr, handle, &status );
2841 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2842 }
2843 table_type = true;
2844 }
2845
2846 rval = read_dense_tag( tag, name, read_type, handle, desc->start_id, count );
2847
2848 if( table_type )
2849 {
2850 H5Tclose( read_type );
2851 read_type = 0;
2852 }
2853
2854 mhdf_closeData( filePtr, handle, &status );
2855 if( MB_SUCCESS != rval ) break;
2856 if( is_error( status ) )
2857 {
2858 rval = MB_FAILURE;
2859 break;
2860 }
2861 }
2862
2863 if( read_type ) H5Tclose( read_type );
2864 return rval;
2865 }
2866
2867 ErrorCode ReadHDF5::create_tag( const mhdf_TagDesc& info, Tag& handle, hid_t& hdf_type )
2868 {
2869 CHECK_OPEN_HANDLES;
2870
2871 ErrorCode rval;
2872 mhdf_Status status;
2873 TagType storage;
2874 DataType mb_type;
2875 bool re_read_default = false;
2876
2877 switch( info.storage )
2878 {
2879 case mhdf_DENSE_TYPE:
2880 storage = MB_TAG_DENSE;
2881 break;
2882 case mhdf_SPARSE_TYPE:
2883 storage = MB_TAG_SPARSE;
2884 break;
2885 case mhdf_BIT_TYPE:
2886 storage = MB_TAG_BIT;
2887 break;
2888 case mhdf_MESH_TYPE:
2889 storage = MB_TAG_MESH;
2890 break;
2891 default:
2892 MB_SET_ERR( MB_FAILURE, "Invalid storage type for tag '" << info.name << "': " << info.storage );
2893 }
2894
2895
2896 if( info.type == mhdf_BITFIELD )
2897 {
2898 if( info.size < 1 || info.size > 8 )
2899 {
2900 MB_SET_ERR( MB_FAILURE, "Invalid bit tag: class is MB_TAG_BIT, num bits = " << info.size );
2901 }
2902 hdf_type = H5Tcopy( H5T_NATIVE_B8 );
2903 mb_type = MB_TYPE_BIT;
2904 if( hdf_type < 0 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2905 }
2906 else if( info.type == mhdf_OPAQUE )
2907 {
2908 mb_type = MB_TYPE_OPAQUE;
2909
2910
2911 Tag type_handle;
2912 std::string tag_type_name = "__hdf5_tag_type_";
2913 tag_type_name += info.name;
2914 rval = iFace->tag_get_handle( tag_type_name.c_str(), sizeof( hid_t ), MB_TYPE_OPAQUE, type_handle );
2915 if( MB_SUCCESS == rval )
2916 {
2917 EntityHandle root = 0;
2918 rval = iFace->tag_get_data( type_handle, &root, 1, &hdf_type );
2919 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
2920 hdf_type = H5Tcopy( hdf_type );
2921 re_read_default = true;
2922 }
2923 else if( MB_TAG_NOT_FOUND == rval )
2924 {
2925 hdf_type = 0;
2926 }
2927 else
2928 MB_SET_ERR( rval, "ReadHDF5 Failure" );
2929
2930 if( hdf_type < 0 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2931 }
2932 else
2933 {
2934 switch( info.type )
2935 {
2936 case mhdf_INTEGER:
2937 hdf_type = H5T_NATIVE_INT;
2938 mb_type = MB_TYPE_INTEGER;
2939 break;
2940 case mhdf_FLOAT:
2941 hdf_type = H5T_NATIVE_DOUBLE;
2942 mb_type = MB_TYPE_DOUBLE;
2943 break;
2944 case mhdf_BOOLEAN:
2945 hdf_type = H5T_NATIVE_UINT;
2946 mb_type = MB_TYPE_INTEGER;
2947 break;
2948 case mhdf_ENTITY_ID:
2949 hdf_type = handleType;
2950 mb_type = MB_TYPE_HANDLE;
2951 break;
2952 default:
2953 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2954 }
2955
2956 if( info.size > 1 )
2957 {
2958 hsize_t tmpsize = info.size;
2959 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
2960 hdf_type = H5Tarray_create2( hdf_type, 1, &tmpsize );
2961 #else
2962 hdf_type = H5Tarray_create( hdf_type, 1, &tmpsize, NULL );
2963 #endif
2964 }
2965 else
2966 {
2967 hdf_type = H5Tcopy( hdf_type );
2968 }
2969 if( hdf_type < 0 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
2970 }
2971
2972
2973 if( info.default_value || info.global_value )
2974 {
2975 if( re_read_default )
2976 {
2977 mhdf_getTagValues( filePtr, info.name, hdf_type, info.default_value, info.global_value, &status );
2978 if( mhdf_isError( &status ) )
2979 {
2980 if( hdf_type ) H5Tclose( hdf_type );
2981 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
2982 }
2983 }
2984
2985 if( MB_TYPE_HANDLE == mb_type )
2986 {
2987 if( info.default_value )
2988 {
2989 rval = convert_id_to_handle( (EntityHandle*)info.default_value, info.default_value_size );
2990 if( MB_SUCCESS != rval )
2991 {
2992 if( hdf_type ) H5Tclose( hdf_type );
2993 MB_SET_ERR( rval, "ReadHDF5 Failure" );
2994 }
2995 }
2996 if( info.global_value )
2997 {
2998 rval = convert_id_to_handle( (EntityHandle*)info.global_value, info.global_value_size );
2999 if( MB_SUCCESS != rval )
3000 {
3001 if( hdf_type ) H5Tclose( hdf_type );
3002 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3003 }
3004 }
3005 }
3006 }
3007
3008
3009 if( info.size < 0 )
3010 rval = iFace->tag_get_handle( info.name, info.default_value_size, mb_type, handle,
3011 storage | MB_TAG_CREAT | MB_TAG_VARLEN | MB_TAG_DFTOK, info.default_value );
3012 else
3013 rval = iFace->tag_get_handle( info.name, info.size, mb_type, handle, storage | MB_TAG_CREAT | MB_TAG_DFTOK,
3014 info.default_value );
3015 if( MB_SUCCESS != rval )
3016 {
3017 if( hdf_type ) H5Tclose( hdf_type );
3018 MB_SET_ERR( MB_FAILURE, "Tag type in file does not match type in database for \"" << info.name << "\"" );
3019 }
3020
3021 if( info.global_value )
3022 {
3023 EntityHandle root = 0;
3024 if( info.size > 0 )
3025 {
3026 rval = iFace->tag_set_data( handle, &root, 1, info.global_value );
3027 }
3028 else
3029 {
3030 int tag_size = info.global_value_size;
3031 rval = iFace->tag_set_by_ptr( handle, &root, 1, &info.global_value, &tag_size );
3032 }
3033 if( MB_SUCCESS != rval )
3034 {
3035 if( hdf_type ) H5Tclose( hdf_type );
3036 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3037 }
3038 }
3039
3040 return MB_SUCCESS;
3041 }
3042
3043 ErrorCode ReadHDF5::read_dense_tag( Tag tag_handle,
3044 const char* ent_name,
3045 hid_t hdf_read_type,
3046 hid_t data,
3047 long start_id,
3048 long num_values )
3049 {
3050 CHECK_OPEN_HANDLES;
3051
3052 ErrorCode rval;
3053 DataType mb_type;
3054
3055 rval = iFace->tag_get_data_type( tag_handle, mb_type );
3056 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3057
3058 int read_size;
3059 rval = iFace->tag_get_bytes( tag_handle, read_size );
3060 if( MB_SUCCESS != rval )
3061 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3062
3063
3064
3065 if( hdf_read_type )
3066 {
3067 hsize_t hdf_size = H5Tget_size( hdf_read_type );
3068 if( hdf_size != (hsize_t)read_size ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3069 }
3070
3071
3072 Range file_ids, handles;
3073 Range::iterator f_ins = file_ids.begin(), h_ins = handles.begin();
3074 IDMap::iterator l, u;
3075 l = idMap.lower_bound( start_id );
3076 u = idMap.lower_bound( start_id + num_values - 1 );
3077 if( l != idMap.end() && start_id + num_values > l->begin )
3078 {
3079 if( l == u )
3080 {
3081 size_t beg = std::max( start_id, l->begin );
3082 size_t end = std::min( start_id + num_values, u->begin + u->count ) - 1;
3083 f_ins = file_ids.insert( f_ins, beg, end );
3084 h_ins = handles.insert( h_ins, l->value + ( beg - l->begin ), l->value + ( end - l->begin ) );
3085 }
3086 else
3087 {
3088 size_t beg = std::max( start_id, l->begin );
3089 f_ins = file_ids.insert( f_ins, beg, l->begin + l->count - 1 );
3090 h_ins = handles.insert( h_ins, l->value + ( beg - l->begin ), l->value + l->count - 1 );
3091 for( ++l; l != u; ++l )
3092 {
3093 f_ins = file_ids.insert( f_ins, l->begin, l->begin + l->count - 1 );
3094 h_ins = handles.insert( h_ins, l->value, l->value + l->count - 1 );
3095 }
3096 if( u != idMap.end() && u->begin < start_id + num_values )
3097 {
3098 size_t end = std::min( start_id + num_values, u->begin + u->count - 1 );
3099 f_ins = file_ids.insert( f_ins, u->begin, end );
3100 h_ins = handles.insert( h_ins, u->value, u->value + end - u->begin );
3101 }
3102 }
3103 }
3104
3105
3106
3107
3108
3109
3110
3111
3112 std::string tn( "<error>" );
3113 iFace->tag_get_name( tag_handle, tn );
3114 tn += " data for ";
3115 tn += ent_name;
3116 try
3117 {
3118 h_ins = handles.begin();
3119 ReadHDF5Dataset reader( tn.c_str(), data, nativeParallel, mpiComm, false );
3120 long buffer_size = bufferSize / read_size;
3121 reader.set_file_ids( file_ids, start_id, buffer_size, hdf_read_type );
3122 dbgOut.printf( 3, "Reading dense data for tag \"%s\" and group \"%s\" in %lu chunks\n", tn.c_str(), ent_name,
3123 reader.get_read_count() );
3124 int nn = 0;
3125 while( !reader.done() )
3126 {
3127 dbgOut.printf( 3, "Reading chunk %d of \"%s\" data\n", ++nn, tn.c_str() );
3128
3129 size_t count;
3130 reader.read( dataBuffer, count );
3131
3132 if( MB_TYPE_HANDLE == mb_type )
3133 {
3134 rval = convert_id_to_handle( (EntityHandle*)dataBuffer, count * read_size / sizeof( EntityHandle ) );
3135 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3136 }
3137
3138 Range ents;
3139 Range::iterator end = h_ins;
3140 end += count;
3141 ents.insert( h_ins, end );
3142 h_ins = end;
3143
3144 rval = iFace->tag_set_data( tag_handle, ents, dataBuffer );
3145 if( MB_SUCCESS != rval )
3146 {
3147 dbgOut.printf( 1, "Internal error setting data for tag \"%s\"\n", tn.c_str() );
3148 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3149 }
3150 }
3151 }
3152 catch( ReadHDF5Dataset::Exception )
3153 {
3154 dbgOut.printf( 1, "Internal error reading dense data for tag \"%s\"\n", tn.c_str() );
3155 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3156 }
3157
3158 return MB_SUCCESS;
3159 }
3160
3161
3162
3163
3164
3165 ErrorCode ReadHDF5::read_sparse_tag_indices( const char* name,
3166 hid_t id_table,
3167 EntityHandle start_offset,
3168 Range& offset_range,
3169 Range& handle_range,
3170 std::vector< EntityHandle >& handle_vect )
3171 {
3172 CHECK_OPEN_HANDLES;
3173
3174 offset_range.clear();
3175 handle_range.clear();
3176 handle_vect.clear();
3177
3178 ErrorCode rval;
3179 Range::iterator handle_hint = handle_range.begin();
3180 Range::iterator offset_hint = offset_range.begin();
3181
3182 EntityHandle* idbuf = (EntityHandle*)dataBuffer;
3183 size_t idbuf_size = bufferSize / sizeof( EntityHandle );
3184
3185 std::string tn( name );
3186 tn += " indices";
3187
3188 assert( start_offset > 0 );
3189 try
3190 {
3191 ReadHDF5Dataset id_reader( tn.c_str(), id_table, nativeParallel, mpiComm, false );
3192 id_reader.set_all_file_ids( idbuf_size, handleType );
3193 size_t offset = start_offset;
3194 dbgOut.printf( 3, "Reading file ids for sparse tag \"%s\" in %lu chunks\n", name, id_reader.get_read_count() );
3195 int nn = 0;
3196 while( !id_reader.done() )
3197 {
3198 dbgOut.printf( 3, "Reading chunk %d of \"%s\" IDs\n", ++nn, name );
3199 size_t count;
3200 id_reader.read( idbuf, count );
3201
3202 rval = convert_id_to_handle( idbuf, count );
3203 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3204
3205
3206
3207
3208 for( size_t i = 0; i < count; ++i )
3209 {
3210 if( idbuf[i] )
3211 {
3212 offset_hint = offset_range.insert( offset_hint, offset + i );
3213 if( !handle_vect.empty() )
3214 {
3215 handle_vect.push_back( idbuf[i] );
3216 }
3217 else if( handle_range.empty() || idbuf[i] > handle_range.back() )
3218 {
3219 handle_hint = handle_range.insert( handle_hint, idbuf[i] );
3220 }
3221 else
3222 {
3223 handle_vect.resize( handle_range.size() );
3224 std::copy( handle_range.begin(), handle_range.end(), handle_vect.begin() );
3225 handle_range.clear();
3226 handle_vect.push_back( idbuf[i] );
3227 dbgOut.print( 2, "Switching to unordered list for tag handle list\n" );
3228 }
3229 }
3230 }
3231
3232 offset += count;
3233 }
3234 }
3235 catch( ReadHDF5Dataset::Exception )
3236 {
3237 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3238 }
3239
3240 return MB_SUCCESS;
3241 }
3242
3243 ErrorCode ReadHDF5::read_sparse_tag( Tag tag_handle,
3244 hid_t hdf_read_type,
3245 hid_t id_table,
3246 hid_t value_table,
3247 long )
3248 {
3249 CHECK_OPEN_HANDLES;
3250
3251
3252
3253
3254
3255 const EntityHandle base_offset = 1;
3256 std::vector< EntityHandle > handle_vect;
3257 Range handle_range, offset_range;
3258 std::string tn( "<error>" );
3259 iFace->tag_get_name( tag_handle, tn );
3260 ErrorCode rval =
3261 read_sparse_tag_indices( tn.c_str(), id_table, base_offset, offset_range, handle_range, handle_vect );
3262 if( MB_SUCCESS != rval ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3263
3264 DataType mbtype;
3265 rval = iFace->tag_get_data_type( tag_handle, mbtype );
3266 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3267
3268 int read_size;
3269 rval = iFace->tag_get_bytes( tag_handle, read_size );
3270 if( MB_SUCCESS != rval )
3271 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3272
3273
3274
3275 if( hdf_read_type )
3276 {
3277 hsize_t hdf_size = H5Tget_size( hdf_read_type );
3278 if( hdf_size != (hsize_t)read_size ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3279 }
3280
3281 const int handles_per_tag = read_size / sizeof( EntityHandle );
3282
3283
3284 size_t chunk_size = bufferSize / read_size;
3285 try
3286 {
3287 ReadHDF5Dataset val_reader( ( tn + " values" ).c_str(), value_table, nativeParallel, mpiComm, false );
3288 val_reader.set_file_ids( offset_range, base_offset, chunk_size, hdf_read_type );
3289 dbgOut.printf( 3, "Reading sparse values for tag \"%s\" in %lu chunks\n", tn.c_str(),
3290 val_reader.get_read_count() );
3291 int nn = 0;
3292 size_t offset = 0;
3293 while( !val_reader.done() )
3294 {
3295 dbgOut.printf( 3, "Reading chunk %d of \"%s\" values\n", ++nn, tn.c_str() );
3296 size_t count;
3297 val_reader.read( dataBuffer, count );
3298 if( MB_TYPE_HANDLE == mbtype )
3299 {
3300 rval = convert_id_to_handle( (EntityHandle*)dataBuffer, count * handles_per_tag );
3301 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3302 }
3303
3304 if( !handle_vect.empty() )
3305 {
3306 rval = iFace->tag_set_data( tag_handle, &handle_vect[offset], count, dataBuffer );
3307 offset += count;
3308 }
3309 else
3310 {
3311 Range r;
3312 r.merge( handle_range.begin(), handle_range.begin() + count );
3313 handle_range.erase( handle_range.begin(), handle_range.begin() + count );
3314 rval = iFace->tag_set_data( tag_handle, r, dataBuffer );
3315 }
3316 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3317 }
3318 }
3319 catch( ReadHDF5Dataset::Exception )
3320 {
3321 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3322 }
3323
3324 return MB_SUCCESS;
3325 }
3326
3327 ErrorCode ReadHDF5::read_var_len_tag( Tag tag_handle,
3328 hid_t hdf_read_type,
3329 hid_t ent_table,
3330 hid_t val_table,
3331 hid_t off_table,
3332 long ,
3333 long )
3334 {
3335 CHECK_OPEN_HANDLES;
3336
3337 ErrorCode rval;
3338 DataType mbtype;
3339
3340 rval = iFace->tag_get_data_type( tag_handle, mbtype );
3341 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3342
3343
3344 if( MB_TYPE_BIT == mbtype ) MB_CHK_ERR( MB_VARIABLE_DATA_LENGTH );
3345
3346
3347 int mbsize;
3348 if( MB_VARIABLE_DATA_LENGTH != iFace->tag_get_bytes( tag_handle, mbsize ) )
3349 {
3350 assert( false );MB_CHK_ERR( MB_VARIABLE_DATA_LENGTH );
3351 }
3352
3353 int read_size;
3354 if( hdf_read_type )
3355 {
3356 hsize_t hdf_size = H5Tget_size( hdf_read_type );
3357 if( hdf_size < 1 ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3358 read_size = hdf_size;
3359 }
3360 else
3361 {
3362
3363 read_size = 1;
3364 }
3365
3366 std::string tn( "<error>" );
3367 iFace->tag_get_name( tag_handle, tn );
3368
3369
3370
3371
3372
3373 const EntityHandle base_offset = 1;
3374 std::vector< EntityHandle > handle_vect;
3375 Range handle_range, offset_range;
3376 rval = read_sparse_tag_indices( tn.c_str(), ent_table, base_offset, offset_range, handle_range, handle_vect );
3377
3378
3379
3380
3381
3382 if( !handle_vect.empty() )
3383 {
3384 MB_SET_ERR( MB_FAILURE, "Unordered file ids for variable length tag not supported" );
3385 }
3386
3387 class VTReader : public ReadHDF5VarLen
3388 {
3389 Tag tagHandle;
3390 bool isHandle;
3391 size_t readSize;
3392 ReadHDF5* readHDF5;
3393
3394 public:
3395 ErrorCode store_data( EntityHandle file_id, void* data, long count, bool )
3396 {
3397 ErrorCode rval1;
3398 if( isHandle )
3399 {
3400 if( readSize != sizeof( EntityHandle ) ) MB_CHK_SET_ERR( MB_FAILURE, "Invalid read size" );
3401 rval1 = readHDF5->convert_id_to_handle( (EntityHandle*)data, count );MB_CHK_ERR( rval1 );
3402 }
3403 int n = count;
3404 return readHDF5->moab()->tag_set_by_ptr( tagHandle, &file_id, 1, &data, &n );
3405 }
3406 VTReader( DebugOutput& debug_output,
3407 void* buffer,
3408 size_t buffer_size,
3409 Tag tag,
3410 bool is_handle_tag,
3411 size_t read_size1,
3412 ReadHDF5* owner )
3413 : ReadHDF5VarLen( debug_output, buffer, buffer_size ), tagHandle( tag ), isHandle( is_handle_tag ),
3414 readSize( read_size1 ), readHDF5( owner )
3415 {
3416 }
3417 };
3418
3419 VTReader tool( dbgOut, dataBuffer, bufferSize, tag_handle, MB_TYPE_HANDLE == mbtype, read_size, this );
3420 try
3421 {
3422
3423 std::vector< unsigned > counts;
3424 Range offsets;
3425 ReadHDF5Dataset off_reader( ( tn + " offsets" ).c_str(), off_table, nativeParallel, mpiComm, false );
3426 rval = tool.read_offsets( off_reader, offset_range, base_offset, base_offset, offsets, counts );
3427 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3428
3429
3430 Range empty;
3431 ReadHDF5Dataset val_reader( ( tn + " values" ).c_str(), val_table, nativeParallel, mpiComm, false );
3432 rval = tool.read_data( val_reader, offsets, base_offset, hdf_read_type, handle_range, counts, empty );
3433 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3434 }
3435 catch( ReadHDF5Dataset::Exception )
3436 {
3437 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3438 }
3439
3440 return MB_SUCCESS;
3441 }
3442
3443 ErrorCode ReadHDF5::convert_id_to_handle( EntityHandle* array, size_t size )
3444 {
3445 convert_id_to_handle( array, size, idMap );
3446 return MB_SUCCESS;
3447 }
3448
3449 void ReadHDF5::convert_id_to_handle( EntityHandle* array, size_t size, const RangeMap< long, EntityHandle >& id_map )
3450 {
3451 for( EntityHandle* const end = array + size; array != end; ++array )
3452 *array = id_map.find( *array );
3453 }
3454
3455 void ReadHDF5::convert_id_to_handle( EntityHandle* array,
3456 size_t size,
3457 size_t& new_size,
3458 const RangeMap< long, EntityHandle >& id_map )
3459 {
3460 RangeMap< long, EntityHandle >::const_iterator it;
3461 new_size = 0;
3462 for( size_t i = 0; i < size; ++i )
3463 {
3464 it = id_map.lower_bound( array[i] );
3465 if( it != id_map.end() && it->begin <= (long)array[i] )
3466 array[new_size++] = it->value + ( array[i] - it->begin );
3467 }
3468 }
3469
3470 void ReadHDF5::convert_range_to_handle( const EntityHandle* ranges,
3471 size_t num_ranges,
3472 const RangeMap< long, EntityHandle >& id_map,
3473 Range& merge )
3474 {
3475 RangeMap< long, EntityHandle >::iterator it = id_map.begin();
3476 Range::iterator hint = merge.begin();
3477 for( size_t i = 0; i < num_ranges; ++i )
3478 {
3479 long id = ranges[2 * i];
3480 const long end = id + ranges[2 * i + 1];
3481
3482 if( it == id_map.end() || it->begin > id ) it = id_map.begin();
3483 it = id_map.lower_bound( it, id_map.end(), id );
3484 if( it == id_map.end() ) continue;
3485 if( id < it->begin ) id = it->begin;
3486 while( id < end )
3487 {
3488 if( id < it->begin ) id = it->begin;
3489 const long off = id - it->begin;
3490 long count = std::min( it->count - off, end - id );
3491
3492
3493
3494 if( count <= 0 ) break;
3495 hint = merge.insert( hint, it->value + off, it->value + off + count - 1 );
3496 id += count;
3497 if( id < end )
3498 {
3499 if( ++it == id_map.end() ) break;
3500 if( it->begin > end ) break;
3501 }
3502 }
3503 }
3504 }
3505
3506 ErrorCode ReadHDF5::convert_range_to_handle( const EntityHandle* array, size_t num_ranges, Range& range )
3507 {
3508 convert_range_to_handle( array, num_ranges, idMap, range );
3509 return MB_SUCCESS;
3510 }
3511
3512 ErrorCode ReadHDF5::insert_in_id_map( const Range& file_ids, EntityHandle start_id )
3513 {
3514 IDMap tmp_map;
3515 bool merge = !idMap.empty() && !file_ids.empty() && idMap.back().begin > (long)file_ids.front();
3516 IDMap& map = merge ? tmp_map : idMap;
3517 Range::const_pair_iterator p;
3518 for( p = file_ids.const_pair_begin(); p != file_ids.const_pair_end(); ++p )
3519 {
3520 size_t count = p->second - p->first + 1;
3521 if( !map.insert( p->first, start_id, count ).second ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3522 start_id += count;
3523 }
3524 if( merge && !idMap.merge( tmp_map ) ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3525
3526 return MB_SUCCESS;
3527 }
3528
3529 ErrorCode ReadHDF5::insert_in_id_map( long file_id, EntityHandle handle )
3530 {
3531 if( !idMap.insert( file_id, handle, 1 ).second ) MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3532 return MB_SUCCESS;
3533 }
3534
3535 ErrorCode ReadHDF5::read_qa( EntityHandle )
3536 {
3537 CHECK_OPEN_HANDLES;
3538
3539 mhdf_Status status;
3540
3541
3542 int qa_len;
3543 char** qa = mhdf_readHistory( filePtr, &qa_len, &status );
3544 if( mhdf_isError( &status ) )
3545 {
3546 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
3547 }
3548
3549 for( int i = 0; i < qa_len; i++ )
3550 {
3551
3552 free( qa[i] );
3553 }
3554 free( qa );
3555
3556
3557
3558 return MB_SUCCESS;
3559 }
3560
3561 ErrorCode ReadHDF5::store_file_ids( Tag tag )
3562 {
3563 CHECK_OPEN_HANDLES;
3564
3565
3566 typedef long tag_type;
3567
3568
3569 tag_type* buffer = reinterpret_cast< tag_type* >( dataBuffer );
3570 const long buffer_size = bufferSize / sizeof( tag_type );
3571 for( IDMap::iterator i = idMap.begin(); i != idMap.end(); ++i )
3572 {
3573 IDMap::Range range = *i;
3574
3575
3576 IDMap::key_type rv = range.begin + ( range.count - 1 );
3577 tag_type tv = (tag_type)rv;
3578 if( (IDMap::key_type)tv != rv )
3579 {
3580 assert( false );
3581 return MB_INDEX_OUT_OF_RANGE;
3582 }
3583
3584 while( range.count )
3585 {
3586 long count = buffer_size < range.count ? buffer_size : range.count;
3587
3588 Range handles;
3589 handles.insert( range.value, range.value + count - 1 );
3590 range.value += count;
3591 range.count -= count;
3592 for( long j = 0; j < count; ++j )
3593 buffer[j] = (tag_type)range.begin++;
3594
3595 ErrorCode rval = iFace->tag_set_data( tag, handles, buffer );
3596 if( MB_SUCCESS != rval ) return rval;
3597 }
3598 }
3599
3600 return MB_SUCCESS;
3601 }
3602
3603 ErrorCode ReadHDF5::store_sets_file_ids()
3604 {
3605 CHECK_OPEN_HANDLES;
3606
3607
3608
3609
3610 Tag setFileIdTag;
3611 long default_val = 0;
3612 ErrorCode rval = iFace->tag_get_handle( "__FILE_ID_FOR_SETS", sizeof( long ), MB_TYPE_OPAQUE, setFileIdTag,
3613 ( MB_TAG_DENSE | MB_TAG_CREAT ), &default_val );
3614
3615 if( MB_SUCCESS != rval || 0 == setFileIdTag ) return rval;
3616
3617 typedef long tag_type;
3618
3619
3620 tag_type* buffer = reinterpret_cast< tag_type* >( dataBuffer );
3621 const long buffer_size = bufferSize / sizeof( tag_type );
3622 for( IDMap::iterator i = idMap.begin(); i != idMap.end(); ++i )
3623 {
3624 IDMap::Range range = *i;
3625 EntityType htype = iFace->type_from_handle( range.value );
3626 if( MBENTITYSET != htype ) continue;
3627
3628
3629 IDMap::key_type rv = range.begin + ( range.count - 1 );
3630 tag_type tv = (tag_type)rv;
3631 if( (IDMap::key_type)tv != rv )
3632 {
3633 assert( false );
3634 return MB_INDEX_OUT_OF_RANGE;
3635 }
3636
3637 while( range.count )
3638 {
3639 long count = buffer_size < range.count ? buffer_size : range.count;
3640
3641 Range handles;
3642 handles.insert( range.value, range.value + count - 1 );
3643 range.value += count;
3644 range.count -= count;
3645 for( long j = 0; j < count; ++j )
3646 buffer[j] = (tag_type)range.begin++;
3647
3648 rval = iFace->tag_set_data( setFileIdTag, handles, buffer );
3649 if( MB_SUCCESS != rval ) return rval;
3650 }
3651 }
3652 return MB_SUCCESS;
3653 }
3654
3655 ErrorCode ReadHDF5::read_tag_values( const char* file_name,
3656 const char* tag_name,
3657 const FileOptions& opts,
3658 std::vector< int >& tag_values_out,
3659 const SubsetList* subset_list )
3660 {
3661 ErrorCode rval;
3662
3663 rval = set_up_read( file_name, opts );
3664 if( MB_SUCCESS != rval ) MB_SET_ERR( rval, "ReadHDF5 Failure" );
3665
3666 int tag_index;
3667 rval = find_int_tag( tag_name, tag_index );
3668 if( MB_SUCCESS != rval )
3669 {
3670 clean_up_read( opts );
3671 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3672 }
3673
3674 if( subset_list )
3675 {
3676 Range file_ids;
3677 rval = get_subset_ids( subset_list->tag_list, subset_list->tag_list_length, file_ids );
3678 if( MB_SUCCESS != rval )
3679 {
3680 clean_up_read( opts );
3681 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3682 }
3683
3684 rval = read_tag_values_partial( tag_index, file_ids, tag_values_out );
3685 if( MB_SUCCESS != rval )
3686 {
3687 clean_up_read( opts );
3688 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3689 }
3690 }
3691 else
3692 {
3693 rval = read_tag_values_all( tag_index, tag_values_out );
3694 if( MB_SUCCESS != rval )
3695 {
3696 clean_up_read( opts );
3697 MB_SET_ERR( rval, "ReadHDF5 Failure" );
3698 }
3699 }
3700
3701 return clean_up_read( opts );
3702 }
3703
3704 ErrorCode ReadHDF5::read_tag_values_partial( int tag_index, const Range& file_ids, std::vector< int >& tag_values )
3705 {
3706 CHECK_OPEN_HANDLES;
3707
3708 mhdf_Status status;
3709 const mhdf_TagDesc& tag = fileInfo->tags[tag_index];
3710 long num_ent, num_val;
3711 size_t count;
3712 std::string tn( tag.name );
3713
3714
3715 if( tag.have_sparse )
3716 {
3717 hid_t handles[3];
3718 mhdf_openSparseTagData( filePtr, tag.name, &num_ent, &num_val, handles, &status );
3719 if( mhdf_isError( &status ) )
3720 {
3721 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
3722 }
3723
3724 try
3725 {
3726
3727
3728 Range offsets;
3729 long* buffer = reinterpret_cast< long* >( dataBuffer );
3730 const long buffer_size = bufferSize / sizeof( long );
3731 ReadHDF5Dataset ids( ( tn + " ids" ).c_str(), handles[0], nativeParallel, mpiComm );
3732 ids.set_all_file_ids( buffer_size, H5T_NATIVE_LONG );
3733 size_t offset = 0;
3734 dbgOut.printf( 3, "Reading sparse IDs for tag \"%s\" in %lu chunks\n", tag.name, ids.get_read_count() );
3735 int nn = 0;
3736 while( !ids.done() )
3737 {
3738 dbgOut.printf( 3, "Reading chunk %d of IDs for \"%s\"\n", ++nn, tag.name );
3739 ids.read( buffer, count );
3740
3741 std::sort( buffer, buffer + count );
3742 Range::iterator ins = offsets.begin();
3743 Range::const_iterator i = file_ids.begin();
3744 for( size_t j = 0; j < count; ++j )
3745 {
3746 while( i != file_ids.end() && (long)*i < buffer[j] )
3747 ++i;
3748 if( i == file_ids.end() ) break;
3749 if( (long)*i == buffer[j] )
3750 {
3751 ins = offsets.insert( ins, j + offset, j + offset );
3752 }
3753 }
3754
3755 offset += count;
3756 }
3757
3758 tag_values.clear();
3759 tag_values.reserve( offsets.size() );
3760 const size_t data_buffer_size = bufferSize / sizeof( int );
3761 int* data_buffer = reinterpret_cast< int* >( dataBuffer );
3762 ReadHDF5Dataset vals( ( tn + " sparse vals" ).c_str(), handles[1], nativeParallel, mpiComm );
3763 vals.set_file_ids( offsets, 0, data_buffer_size, H5T_NATIVE_INT );
3764 dbgOut.printf( 3, "Reading sparse values for tag \"%s\" in %lu chunks\n", tag.name, vals.get_read_count() );
3765 nn = 0;
3766
3767
3768 while( !vals.done() )
3769 {
3770 dbgOut.printf( 3, "Reading chunk %d of values for \"%s\"\n", ++nn, tag.name );
3771 vals.read( data_buffer, count );
3772 tag_values.insert( tag_values.end(), data_buffer, data_buffer + count );
3773 }
3774 }
3775 catch( ReadHDF5Dataset::Exception )
3776 {
3777 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3778 }
3779 }
3780
3781 std::sort( tag_values.begin(), tag_values.end() );
3782 tag_values.erase( std::unique( tag_values.begin(), tag_values.end() ), tag_values.end() );
3783
3784
3785 std::vector< int > prev_data, curr_data;
3786 for( int i = 0; i < tag.num_dense_indices; ++i )
3787 {
3788 int grp = tag.dense_elem_indices[i];
3789 const char* gname = 0;
3790 mhdf_EntDesc* desc = 0;
3791 if( grp == -1 )
3792 {
3793 gname = mhdf_node_type_handle();
3794 desc = &fileInfo->nodes;
3795 }
3796 else if( grp == -2 )
3797 {
3798 gname = mhdf_set_type_handle();
3799 desc = &fileInfo->sets;
3800 }
3801 else
3802 {
3803 assert( grp >= 0 && grp < fileInfo->num_elem_desc );
3804 gname = fileInfo->elems[grp].handle;
3805 desc = &fileInfo->elems[grp].desc;
3806 }
3807
3808 Range::iterator s = file_ids.lower_bound( (EntityHandle)( desc->start_id ) );
3809 Range::iterator e = Range::lower_bound( s, file_ids.end(), (EntityHandle)( desc->start_id ) + desc->count );
3810 Range subset;
3811 subset.merge( s, e );
3812
3813 hid_t handle = mhdf_openDenseTagData( filePtr, tag.name, gname, &num_val, &status );
3814 if( mhdf_isError( &status ) )
3815 {
3816 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
3817 }
3818
3819 try
3820 {
3821 curr_data.clear();
3822 tag_values.reserve( subset.size() );
3823 const size_t data_buffer_size = bufferSize / sizeof( int );
3824 int* data_buffer = reinterpret_cast< int* >( dataBuffer );
3825
3826 ReadHDF5Dataset reader( ( tn + " dense vals" ).c_str(), handle, nativeParallel, mpiComm );
3827 reader.set_file_ids( subset, desc->start_id, data_buffer_size, H5T_NATIVE_INT );
3828 dbgOut.printf( 3, "Reading dense data for tag \"%s\" and group \"%s\" in %lu chunks\n", tag.name,
3829 fileInfo->elems[grp].handle, reader.get_read_count() );
3830 int nn = 0;
3831
3832
3833 while( !reader.done() )
3834 {
3835 dbgOut.printf( 3, "Reading chunk %d of \"%s\"/\"%s\"\n", ++nn, tag.name, fileInfo->elems[grp].handle );
3836 reader.read( data_buffer, count );
3837 curr_data.insert( curr_data.end(), data_buffer, data_buffer + count );
3838 }
3839 }
3840 catch( ReadHDF5Dataset::Exception )
3841 {
3842 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3843 }
3844
3845 std::sort( curr_data.begin(), curr_data.end() );
3846 curr_data.erase( std::unique( curr_data.begin(), curr_data.end() ), curr_data.end() );
3847 prev_data.clear();
3848 tag_values.swap( prev_data );
3849 std::set_union( prev_data.begin(), prev_data.end(), curr_data.begin(), curr_data.end(),
3850 std::back_inserter( tag_values ) );
3851 }
3852
3853 return MB_SUCCESS;
3854 }
3855
3856 ErrorCode ReadHDF5::read_tag_values_all( int tag_index, std::vector< int >& tag_values )
3857 {
3858 CHECK_OPEN_HANDLES;
3859
3860 mhdf_Status status;
3861 const mhdf_TagDesc& tag = fileInfo->tags[tag_index];
3862 long junk, num_val;
3863
3864
3865 if( tag.have_sparse )
3866 {
3867 hid_t handles[3];
3868 mhdf_openSparseTagData( filePtr, tag.name, &junk, &num_val, handles, &status );
3869 if( mhdf_isError( &status ) )
3870 {
3871 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
3872 }
3873
3874 mhdf_closeData( filePtr, handles[0], &status );
3875 if( mhdf_isError( &status ) )
3876 {
3877 MB_SET_ERR_CONT( mhdf_message( &status ) );
3878 mhdf_closeData( filePtr, handles[1], &status );
3879 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3880 }
3881
3882 hid_t file_type = H5Dget_type( handles[1] );
3883 tag_values.resize( num_val );
3884 mhdf_readTagValuesWithOpt( handles[1], 0, num_val, file_type, &tag_values[0], collIO, &status );
3885 if( mhdf_isError( &status ) )
3886 {
3887 MB_SET_ERR_CONT( mhdf_message( &status ) );
3888 H5Tclose( file_type );
3889 mhdf_closeData( filePtr, handles[1], &status );
3890 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3891 }
3892 H5Tconvert( file_type, H5T_NATIVE_INT, num_val, &tag_values[0], 0, H5P_DEFAULT );
3893 H5Tclose( file_type );
3894
3895 mhdf_closeData( filePtr, handles[1], &status );
3896 if( mhdf_isError( &status ) )
3897 {
3898 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
3899 }
3900 }
3901
3902 std::sort( tag_values.begin(), tag_values.end() );
3903 tag_values.erase( std::unique( tag_values.begin(), tag_values.end() ), tag_values.end() );
3904
3905
3906 std::vector< int > prev_data, curr_data;
3907 for( int i = 0; i < tag.num_dense_indices; ++i )
3908 {
3909 int grp = tag.dense_elem_indices[i];
3910 const char* gname = 0;
3911 if( grp == -1 )
3912 gname = mhdf_node_type_handle();
3913 else if( grp == -2 )
3914 gname = mhdf_set_type_handle();
3915 else
3916 gname = fileInfo->elems[grp].handle;
3917 hid_t handle = mhdf_openDenseTagData( filePtr, tag.name, gname, &num_val, &status );
3918 if( mhdf_isError( &status ) )
3919 {
3920 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
3921 }
3922
3923 hid_t file_type = H5Dget_type( handle );
3924 curr_data.resize( num_val );
3925 mhdf_readTagValuesWithOpt( handle, 0, num_val, file_type, &curr_data[0], collIO, &status );
3926 if( mhdf_isError( &status ) )
3927 {
3928 MB_SET_ERR_CONT( mhdf_message( &status ) );
3929 H5Tclose( file_type );
3930 mhdf_closeData( filePtr, handle, &status );
3931 MB_SET_ERR( MB_FAILURE, "ReadHDF5 Failure" );
3932 }
3933
3934 H5Tconvert( file_type, H5T_NATIVE_INT, num_val, &curr_data[0], 0, H5P_DEFAULT );
3935 H5Tclose( file_type );
3936 mhdf_closeData( filePtr, handle, &status );
3937 if( mhdf_isError( &status ) )
3938 {
3939 MB_SET_ERR( MB_FAILURE, mhdf_message( &status ) );
3940 }
3941
3942 std::sort( curr_data.begin(), curr_data.end() );
3943 curr_data.erase( std::unique( curr_data.begin(), curr_data.end() ), curr_data.end() );
3944
3945 prev_data.clear();
3946 tag_values.swap( prev_data );
3947 std::set_union( prev_data.begin(), prev_data.end(), curr_data.begin(), curr_data.end(),
3948 std::back_inserter( tag_values ) );
3949 }
3950
3951 return MB_SUCCESS;
3952 }
3953 void ReadHDF5::print_times()
3954 {
3955 #ifdef MOAB_HAVE_MPI
3956 if( !myPcomm )
3957 {
3958 double recv[NUM_TIMES];
3959 MPI_Reduce( (void*)_times, recv, NUM_TIMES, MPI_DOUBLE, MPI_MAX, 0, myPcomm->proc_config().proc_comm() );
3960 for( int i = 0; i < NUM_TIMES; i++ )
3961 _times[i] = recv[i];
3962 }
3963 if( 0 == myPcomm->proc_config().proc_rank() )
3964 {
3965 #endif
3966
3967 std::cout << "ReadHDF5: " << _times[TOTAL_TIME] << std::endl
3968 << " get set meta " << _times[SET_META_TIME] << std::endl
3969 << " partial subsets " << _times[SUBSET_IDS_TIME] << std::endl
3970 << " partition time " << _times[GET_PARTITION_TIME] << std::endl
3971 << " get set ids " << _times[GET_SET_IDS_TIME] << std::endl
3972 << " set contents " << _times[GET_SET_CONTENTS_TIME] << std::endl
3973 << " polyhedra " << _times[GET_POLYHEDRA_TIME] << std::endl
3974 << " elements " << _times[GET_ELEMENTS_TIME] << std::endl
3975 << " nodes " << _times[GET_NODES_TIME] << std::endl
3976 << " node adjacency " << _times[GET_NODEADJ_TIME] << std::endl
3977 << " side elements " << _times[GET_SIDEELEM_TIME] << std::endl
3978 << " update connectivity " << _times[UPDATECONN_TIME] << std::endl
3979 << " adjacency " << _times[ADJACENCY_TIME] << std::endl
3980 << " delete non_adj " << _times[DELETE_NON_SIDEELEM_TIME] << std::endl
3981 << " recursive sets " << _times[READ_SET_IDS_RECURS_TIME] << std::endl
3982 << " find contain_sets " << _times[FIND_SETS_CONTAINING_TIME] << std::endl
3983 << " read sets " << _times[READ_SETS_TIME] << std::endl
3984 << " read tags " << _times[READ_TAGS_TIME] << std::endl
3985 << " store file ids " << _times[STORE_FILE_IDS_TIME] << std::endl
3986 << " read qa records " << _times[READ_QA_TIME] << std::endl;
3987
3988 #ifdef MOAB_HAVE_MPI
3989 }
3990 #endif
3991 }
3992
3993 }