@@ -168,6 +168,16 @@ void ADIOI_Flatten_datatype(MPI_Datatype datatype)
168168 DBG_FPRINTF (stderr ,"ADIOI_Flatten_datatype:: ADIOI_Flatten\n" );
169169 #endif
170170
171+ /*
172+ * Setting flat->count to curr_index, since curr_index is the most fundamentally
173+ * correct updated value that represents what's in the indices/blocklens arrays.
174+ * It would be nice if the counter function and the flatten function were in sync,
175+ * but the numerous cases that decrement flat->count in the flatten function show
176+ * that syncing them is a hack, and as long as the counter doesn't under-count
177+ * it's good enough.
178+ */
179+ flat -> count = curr_index ;
180+
171181 ADIOI_Optimize_flattened (flat );
172182#endif
173183/* debug */
@@ -184,6 +194,36 @@ void ADIOI_Flatten_datatype(MPI_Datatype datatype)
184194#endif
185195}
186196
197+ /*
198+ * I don't really expect this to ever trigger, but without the below safety
199+ * valve, the design relies on the Count function coming out >= whatever
200+ * the Flatten function comes up with. There are enough differences between
201+ * the two that it's hard to be positive this will always be true. So every
202+ * time something's added to flat's arrays, let's make sure they're big enough
203+ * and re-alloc if not.
204+ */
205+ #define FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (idx ) \
206+ do { \
207+ if (idx >= flat->count) { \
208+ int new_count = (flat->count * 1.25 + 4); \
209+ ADIO_Offset *new_blocklens = (ADIO_Offset *) \
210+ ADIOI_Malloc(new_count * sizeof(ADIO_Offset)); \
211+ ADIO_Offset *new_indices = (ADIO_Offset *) \
212+ ADIOI_Malloc(new_count * sizeof(ADIO_Offset)); \
213+ if (flat->count) { \
214+ memcpy(new_blocklens, flat->blocklens, \
215+ flat->count * sizeof(ADIO_Offset)); \
216+ memcpy(new_indices, flat->indices, \
217+ flat->count * sizeof(ADIO_Offset)); \
218+ ADIOI_Free(flat->blocklens); \
219+ ADIOI_Free(flat->indices); \
220+ } \
221+ flat->blocklens = new_blocklens; \
222+ flat->indices = new_indices; \
223+ flat->count = new_count; \
224+ } \
225+ } while (0)
226+
187227/* ADIOI_Flatten()
188228 *
189229 * Assumption: input datatype is not a basic!!!!
@@ -318,6 +358,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
318358 if (prev_index == * curr_index ) {
319359/* simplest case, made up of basic or contiguous types */
320360 j = * curr_index ;
361+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
321362 flat -> indices [j ] = st_offset ;
322363 MPI_Type_size_x (types [0 ], & old_size );
323364 flat -> blocklens [j ] = top_count * old_size ;
@@ -335,6 +376,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
335376 MPI_Type_get_extent (types [0 ], & lb , & old_extent );
336377 for (m = 1 ; m < top_count ; m ++ ) {
337378 for (i = 0 ; i < num ; i ++ ) {
379+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
338380 flat -> indices [j ] = flat -> indices [j - num ] + ADIOI_AINT_CAST_TO_OFFSET old_extent ;
339381 flat -> blocklens [j ] = flat -> blocklens [j - num ];
340382 #ifdef FLATTEN_DEBUG
@@ -366,10 +408,12 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
366408 avoid >2G integer arithmetic problems */
367409 ADIO_Offset blocklength = ints [1 ], stride = ints [2 ];
368410 j = * curr_index ;
411+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
369412 flat -> indices [j ] = st_offset ;
370413 MPI_Type_size_x (types [0 ], & old_size );
371414 flat -> blocklens [j ] = blocklength * old_size ;
372415 for (i = j + 1 ; i < j + top_count ; i ++ ) {
416+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (i );
373417 flat -> indices [i ] = flat -> indices [i - 1 ] + stride * old_size ;
374418 flat -> blocklens [i ] = flat -> blocklens [j ];
375419 }
@@ -389,6 +433,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
389433 MPI_Type_get_extent (types [0 ], & lb , & old_extent );
390434 for (m = 1 ; m < blocklength ; m ++ ) {
391435 for (i = 0 ; i < num ; i ++ ) {
436+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
392437 flat -> indices [j ] = flat -> indices [j - num ] + ADIOI_AINT_CAST_TO_OFFSET old_extent ;
393438 flat -> blocklens [j ] = flat -> blocklens [j - num ];
394439 j ++ ;
@@ -400,6 +445,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
400445 num = * curr_index - prev_index ;
401446 for (i = 1 ; i < top_count ; i ++ ) {
402447 for (m = 0 ; m < num ; m ++ ) {
448+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
403449 flat -> indices [j ] = flat -> indices [j - num ] + stride * ADIOI_AINT_CAST_TO_OFFSET old_extent ;
404450 flat -> blocklens [j ] = flat -> blocklens [j - num ];
405451 j ++ ;
@@ -429,10 +475,12 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
429475 avoid >2G integer arithmetic problems */
430476 ADIO_Offset blocklength = ints [1 ];
431477 j = * curr_index ;
478+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
432479 flat -> indices [j ] = st_offset ;
433480 MPI_Type_size_x (types [0 ], & old_size );
434481 flat -> blocklens [j ] = blocklength * old_size ;
435482 for (i = j + 1 ; i < j + top_count ; i ++ ) {
483+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (i );
436484 flat -> indices [i ] = flat -> indices [i - 1 ] + adds [0 ];
437485 flat -> blocklens [i ] = flat -> blocklens [j ];
438486 }
@@ -452,6 +500,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
452500 MPI_Type_get_extent (types [0 ], & lb , & old_extent );
453501 for (m = 1 ; m < blocklength ; m ++ ) {
454502 for (i = 0 ; i < num ; i ++ ) {
503+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
455504 flat -> indices [j ] = flat -> indices [j - num ] + ADIOI_AINT_CAST_TO_OFFSET old_extent ;
456505 flat -> blocklens [j ] = flat -> blocklens [j - num ];
457506 j ++ ;
@@ -463,6 +512,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
463512 num = * curr_index - prev_index ;
464513 for (i = 1 ; i < top_count ; i ++ ) {
465514 for (m = 0 ; m < num ; m ++ ) {
515+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
466516 flat -> indices [j ] = flat -> indices [j - num ] + adds [0 ];
467517 flat -> blocklens [j ] = flat -> blocklens [j - num ];
468518 j ++ ;
@@ -500,16 +550,15 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
500550 avoid >2G integer arithmetic problems */
501551 ADIO_Offset blocklength = ints [1 + i - j ], stride = ints [top_count + 1 + i - j ];
502552 if (blocklength > 0 ) {
553+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (nonzeroth );
503554 flat -> indices [nonzeroth ] =
504555 st_offset + stride * ADIOI_AINT_CAST_TO_OFFSET old_extent ;
505556 flat -> blocklens [nonzeroth ] =
506557 blocklength * ADIOI_AINT_CAST_TO_OFFSET old_extent ;
507558 nonzeroth ++ ;
508- } else {
509- flat -> count -- ; /* don't count/consider any zero-length blocklens */
510559 }
511560 }
512- * curr_index = i ;
561+ * curr_index = nonzeroth ;
513562 }
514563 else {
515564/* indexed type made up of noncontiguous derived types */
@@ -523,14 +572,13 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
523572 for (m = 1 ; m < ints [1 ]; m ++ ) {
524573 for (i = 0 , nonzeroth = j ; i < num ; i ++ ) {
525574 if (flat -> blocklens [j - num ] > 0 ) {
575+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (nonzeroth );
526576 flat -> indices [nonzeroth ] =
527577 flat -> indices [nonzeroth - num ] + ADIOI_AINT_CAST_TO_OFFSET old_extent ;
528578 flat -> blocklens [nonzeroth ] =
529579 flat -> blocklens [nonzeroth - num ];
530580 j ++ ;
531581 nonzeroth ++ ;
532- } else {
533- flat -> count -- ;
534582 }
535583 }
536584 }
@@ -545,26 +593,24 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
545593 avoid >2G integer arithmetic problems */
546594 ADIO_Offset stride = ints [top_count + 1 + i ]- ints [top_count + i ];
547595 if (flat -> blocklens [j - num ] > 0 ) {
596+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (nonzeroth );
548597 flat -> indices [nonzeroth ] =
549598 flat -> indices [j - num ] + stride * ADIOI_AINT_CAST_TO_OFFSET old_extent ;
550599 flat -> blocklens [nonzeroth ] = flat -> blocklens [j - num ];
551600 j ++ ;
552601 nonzeroth ++ ;
553- } else {
554- flat -> count -- ;
555602 }
556603 }
557604 * curr_index = j ;
558605 for (m = 1 ; m < ints [1 + i ]; m ++ ) {
559606 for (k = 0 , nonzeroth = j ; k < basic_num ; k ++ ) {
560607 if (flat -> blocklens [j - basic_num ] > 0 ) {
608+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (nonzeroth );
561609 flat -> indices [nonzeroth ] =
562610 flat -> indices [j - basic_num ] + ADIOI_AINT_CAST_TO_OFFSET old_extent ;
563611 flat -> blocklens [nonzeroth ] = flat -> blocklens [j - basic_num ];
564612 j ++ ;
565613 nonzeroth ++ ;
566- } else {
567- flat -> count -- ;
568614 }
569615 }
570616 }
@@ -610,6 +656,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
610656 /* By using ADIO_Offset we preserve +/- sign and
611657 avoid >2G integer arithmetic problems */
612658 ADIO_Offset blocklength = ints [1 ];
659+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (i );
613660 if (is_hindexed_block ) {
614661 flat -> indices [i ] = st_offset + adds [i - j ];
615662 } else {
@@ -636,6 +683,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
636683 * extent of a type */
637684 MPI_Type_get_extent (types [0 ], & lb , & old_extent );
638685 }
686+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
639687 flat -> indices [j ] = flat -> indices [j - num ] +
640688 ADIOI_AINT_CAST_TO_OFFSET old_extent ;
641689 flat -> blocklens [j ] = flat -> blocklens [j - num ];
@@ -648,6 +696,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
648696 num = * curr_index - prev_index ;
649697 for (i = 1 ; i < top_count ; i ++ ) {
650698 for (m = 0 ; m < num ; m ++ ) {
699+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
651700 if (is_hindexed_block ) {
652701 flat -> indices [j ] = flat -> indices [j - num ] +
653702 adds [i ] - adds [i - 1 ];
@@ -691,14 +740,13 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
691740 /* By using ADIO_Offset we preserve +/- sign and
692741 avoid >2G integer arithmetic problems */
693742 ADIO_Offset blocklength = ints [1 + i - j ];
743+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (nonzeroth );
694744 flat -> indices [nonzeroth ] = st_offset + adds [i - j ];
695745 flat -> blocklens [nonzeroth ] = blocklength * old_size ;
696746 nonzeroth ++ ;
697- } else {
698- flat -> count -- ;
699747 }
700748 }
701- * curr_index = i ;
749+ * curr_index = nonzeroth ;
702750 }
703751 else {
704752/* indexed type made up of noncontiguous derived types */
@@ -713,13 +761,12 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
713761 for (m = 1 ; m < ints [1 ]; m ++ ) {
714762 for (i = 0 , nonzeroth = j ; i < num ; i ++ ) {
715763 if (flat -> blocklens [j - num ] > 0 ) {
764+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (nonzeroth );
716765 flat -> indices [nonzeroth ] =
717766 flat -> indices [j - num ] + ADIOI_AINT_CAST_TO_OFFSET old_extent ;
718767 flat -> blocklens [nonzeroth ] = flat -> blocklens [j - num ];
719768 j ++ ;
720769 nonzeroth ++ ;
721- } else {
722- flat -> count -- ;
723770 }
724771 }
725772 }
@@ -731,19 +778,19 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
731778 prev_index = * curr_index ;
732779 for (m = 0 , nonzeroth = j ; m < basic_num ; m ++ ) {
733780 if (flat -> blocklens [j - num ] > 0 ) {
781+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (nonzeroth );
734782 flat -> indices [nonzeroth ] =
735783 flat -> indices [j - num ] + adds [i ] - adds [i - 1 ];
736784 flat -> blocklens [nonzeroth ] = flat -> blocklens [j - num ];
737785 j ++ ;
738786 nonzeroth ++ ;
739- } else {
740- flat -> count -- ;
741787 }
742788 }
743789 * curr_index = j ;
744790 for (m = 1 ; m < ints [1 + i ]; m ++ ) {
745791 for (k = 0 ,nonzeroth = j ; k < basic_num ; k ++ ) {
746792 if (flat -> blocklens [j - basic_num ] > 0 ) {
793+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (nonzeroth );
747794 flat -> indices [nonzeroth ] =
748795 flat -> indices [j - basic_num ] + ADIOI_AINT_CAST_TO_OFFSET old_extent ;
749796 flat -> blocklens [nonzeroth ] = flat -> blocklens [j - basic_num ];
@@ -781,6 +828,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
781828 j = * curr_index ;
782829 flat -> indices [j ] = st_offset + adds [n ];
783830 MPI_Type_size_x (types [n ], & old_size );
831+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
784832 flat -> blocklens [j ] = blocklength * old_size ;
785833#ifdef FLATTEN_DEBUG
786834 DBG_FPRINTF (stderr ,"ADIOI_Flatten:: simple adds[%#X] " MPI_AINT_FMT_HEX_SPEC ", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n" ,n ,adds [n ],j , flat -> indices [j ], j , flat -> blocklens [j ]);
@@ -798,6 +846,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
798846 MPI_Type_get_extent (types [n ], & lb , & old_extent );
799847 for (m = 1 ; m < ints [1 + n ]; m ++ ) {
800848 for (i = 0 ; i < num ; i ++ ) {
849+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
801850 flat -> indices [j ] =
802851 flat -> indices [j - num ] + ADIOI_AINT_CAST_TO_OFFSET old_extent ;
803852 flat -> blocklens [j ] = flat -> blocklens [j - num ];
@@ -827,6 +876,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
827876 * bound based on the inner type, but the lower bound based on the
828877 * upper type. check both lb and ub to prevent mixing updates */
829878 if (flat -> lb_idx == -1 && flat -> ub_idx == -1 ) {
879+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
830880 flat -> indices [j ] = st_offset + adds [0 ];
831881 /* this zero-length blocklens[] element, unlike eleswhere in the
832882 * flattening code, is correct and is used to indicate a lower bound
@@ -843,7 +893,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
843893 } else {
844894 /* skipped over this chunk because something else higher-up in the
845895 * type construction set this for us already */
846- flat -> count -- ;
847896 st_offset -= adds [0 ];
848897 }
849898
@@ -859,6 +908,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
859908 else {
860909 /* current type is basic or contiguous */
861910 j = * curr_index ;
911+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
862912 flat -> indices [j ] = st_offset ;
863913 MPI_Type_size_x (types [0 ], & old_size );
864914 flat -> blocklens [j ] = old_size ;
@@ -874,6 +924,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
874924 /* see note above about mixing updates for why we check lb and ub */
875925 if ((flat -> lb_idx == -1 && flat -> ub_idx == -1 ) || lb_updated ) {
876926 j = * curr_index ;
927+ FIX_ARRAYS_IN_CASE_OF_WRONG_COUNT (j );
877928 flat -> indices [j ] = st_offset + adds [0 ] + adds [1 ];
878929 /* again, zero-element ok: an upper-bound marker explicitly set by the
879930 * constructor of this resized type */
@@ -882,7 +933,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
882933 } else {
883934 /* skipped over this chunk because something else higher-up in the
884935 * type construction set this for us already */
885- flat -> count -- ;
886936 (* curr_index )-- ;
887937 }
888938
0 commit comments