Skip to content

Commit 3e7f46b

Browse files
markalleggouaillardet
authored andcommitted
[mpich romio c4b5762] romio flatten has flat->count consistency problems
> Pulled in from mpich romio, branch "main". > Their commit message is below. > > This is part of a batch of commits from the > following set of PRs: > * pmodels/mpich#4943 > -- darray fix which contains a flatten fix > 73a3eba > c4b5762 > * pmodels/mpich#4995 > -- write strided fix > bbb5210 > * pmodels/mpich#5100 > -- build fix for -Wpedantic > ad0e435 > * pmodels/mpich#5099 > -- build fix, they had let file-system=...gpfs bit rot > e1d42af > 313289a > 83bbb82 > * pmodels/mpich#5150 > -- build fix, configure-related _GNU_SOURCE > a712b56 > 5a036e7 > * pmodels/mpich#5184 > -- build fix, continuation of _GNU_SOURCE fix > d97c4ee ADIOI_Count_contiguous_blocks and ADIOI_Flatten are very similar functions, but they diverge a lot around the edges and in degenerate cases. In Spectrum MPI I spent some time making them consistent with each other but found that to be a losing battle. So the approach I used here is to not have Count() be as definitive, and rather let Flatten() have the last word on what the final flat->count really is. Eg Flatten's *curr_index is the real count. The changes I made are 1. Fix a couple places in Flatten where *curr_index was updated out of sync with what was actually being added to flat->indices[] and flat->blocklens[]. That's one of the important book-keeping rules Flatten should follow. There were a couple places (when counts[] arrays have 0s) where that wasn't the case (see the "nonzeroth" var in this commit). 2. The main change I made was to reset flat->count based on Flatten's curr_index. This is because the divergence between the two functions is too great to reliably fix. 3. A third change is just a safety valve, using a flatlist_node_grow() function just in case the Count function returns a smaller value than Flatten ends up trying to write into the array, and related to this I got rid of the various --(flat->count) lines, since that var now represents the allocated size of the array, until right after the Flatten function when it's reset to represent the data written to the array like it used to be. I don't think we even need ADIOI_Count_contiguous_blocks() anymore, but I didn't remove it. Signed-off-by: Mark Allen <[email protected]>
1 parent 57a4e39 commit 3e7f46b

File tree

1 file changed

+55
-21
lines changed

1 file changed

+55
-21
lines changed

3rd-party/romio341/adio/common/flatten.c

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,33 @@ static ADIOI_Flatlist_node *flatlist_node_new(MPI_Datatype datatype, MPI_Count c
2828
return flat;
2929
}
3030

31+
/*
32+
* I don't really expect this to ever trigger, but without the below safety
33+
* valve, the design relies on the Count function coming out >= whatever
34+
* the Flatten function comes up with. There are enough differences between
35+
* the two that it's hard to be positive this will always be true. So every
36+
* time something's added to flat's arrays, let's make sure they're big enough
37+
* and re-alloc if not.
38+
*/
39+
static void flatlist_node_grow(ADIOI_Flatlist_node * flat, int idx)
40+
{
41+
if (idx >= flat->count) {
42+
ADIO_Offset *new_blocklens;
43+
ADIO_Offset *new_indices;
44+
int new_count = (flat->count * 1.25 + 4);
45+
new_blocklens = (ADIO_Offset *) ADIOI_Calloc(new_count * 2, sizeof(ADIO_Offset));
46+
new_indices = new_blocklens + new_count;
47+
if (flat->count) {
48+
memcpy(new_blocklens, flat->blocklens, flat->count * sizeof(ADIO_Offset));
49+
memcpy(new_indices, flat->indices, flat->count * sizeof(ADIO_Offset));
50+
ADIOI_Free(flat->blocklens);
51+
}
52+
flat->blocklens = new_blocklens;
53+
flat->indices = new_indices;
54+
flat->count = new_count;
55+
}
56+
}
57+
3158
void ADIOI_Optimize_flattened(ADIOI_Flatlist_node * flat_type);
3259
/* flatten datatype and add it to Flatlist */
3360
ADIOI_Flatlist_node *ADIOI_Flatten_datatype(MPI_Datatype datatype)
@@ -83,6 +110,16 @@ ADIOI_Flatlist_node *ADIOI_Flatten_datatype(MPI_Datatype datatype)
83110
DBG_FPRINTF(stderr, "ADIOI_Flatten_datatype:: ADIOI_Flatten\n");
84111
#endif
85112

113+
/*
114+
* Setting flat->count to curr_index, since curr_index is the most fundamentally
115+
* correct updated value that represents what's in the indices/blocklens arrays.
116+
* It would be nice if the counter function and the flatten function were in sync,
117+
* but the numerous cases that decrement flat->count in the flatten function show
118+
* that syncing them is a hack, and as long as the counter doesn't under-count
119+
* it's good enough.
120+
*/
121+
flat->count = curr_index;
122+
86123
ADIOI_Optimize_flattened(flat);
87124
/* debug */
88125
#ifdef FLATTEN_DEBUG
@@ -228,6 +265,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
228265
if (prev_index == *curr_index) {
229266
/* simplest case, made up of basic or contiguous types */
230267
j = *curr_index;
268+
flatlist_node_grow(flat, j);
231269
flat->indices[j] = st_offset;
232270
MPI_Type_size_x(types[0], &old_size);
233271
flat->blocklens[j] = top_count * old_size;
@@ -279,10 +317,12 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
279317
* avoid >2G integer arithmetic problems */
280318
ADIO_Offset blocklength = ints[1], stride = ints[2];
281319
j = *curr_index;
320+
flatlist_node_grow(flat, j);
282321
flat->indices[j] = st_offset;
283322
MPI_Type_size_x(types[0], &old_size);
284323
flat->blocklens[j] = blocklength * old_size;
285324
for (i = j + 1; i < j + top_count; i++) {
325+
flatlist_node_grow(flat, i);
286326
flat->indices[i] = flat->indices[i - 1] + stride * old_size;
287327
flat->blocklens[i] = flat->blocklens[j];
288328
}
@@ -342,10 +382,12 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
342382
* avoid >2G integer arithmetic problems */
343383
ADIO_Offset blocklength = ints[1];
344384
j = *curr_index;
385+
flatlist_node_grow(flat, j);
345386
flat->indices[j] = st_offset;
346387
MPI_Type_size_x(types[0], &old_size);
347388
flat->blocklens[j] = blocklength * old_size;
348389
for (i = j + 1; i < j + top_count; i++) {
390+
flatlist_node_grow(flat, i);
349391
flat->indices[i] = flat->indices[i - 1] + adds[0];
350392
flat->blocklens[i] = flat->blocklens[j];
351393
}
@@ -376,6 +418,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
376418
num = *curr_index - prev_index;
377419
for (i = 1; i < top_count; i++) {
378420
for (m = 0; m < num; m++) {
421+
flatlist_node_grow(flat, j);
379422
flat->indices[j] = flat->indices[j - num] + adds[0];
380423
flat->blocklens[j] = flat->blocklens[j - num];
381424
j++;
@@ -417,11 +460,9 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
417460
flat->blocklens[nonzeroth] =
418461
blocklength * ADIOI_AINT_CAST_TO_OFFSET old_extent;
419462
nonzeroth++;
420-
} else {
421-
flat->count--; /* don't count/consider any zero-length blocklens */
422463
}
423464
}
424-
*curr_index = i;
465+
*curr_index = nonzeroth;
425466
} else {
426467
/* indexed type made up of noncontiguous derived types */
427468

@@ -440,8 +481,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
440481
flat->blocklens[nonzeroth] = flat->blocklens[nonzeroth - num];
441482
j++;
442483
nonzeroth++;
443-
} else {
444-
flat->count--;
445484
}
446485
}
447486
}
@@ -462,8 +501,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
462501
flat->blocklens[nonzeroth] = flat->blocklens[j - num];
463502
j++;
464503
nonzeroth++;
465-
} else {
466-
flat->count--;
467504
}
468505
}
469506
*curr_index = j;
@@ -476,8 +513,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
476513
flat->blocklens[nonzeroth] = flat->blocklens[j - basic_num];
477514
j++;
478515
nonzeroth++;
479-
} else {
480-
flat->count--;
481516
}
482517
}
483518
}
@@ -523,9 +558,11 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
523558
* avoid >2G integer arithmetic problems */
524559
ADIO_Offset blocklength = ints[1];
525560
if (is_hindexed_block) {
561+
flatlist_node_grow(flat, i);
526562
flat->indices[i] = st_offset + adds[i - j];
527563
} else {
528564
ADIO_Offset stride = ints[1 + 1 + i - j];
565+
flatlist_node_grow(flat, i);
529566
flat->indices[i] = st_offset +
530567
stride * ADIOI_AINT_CAST_TO_OFFSET old_extent;
531568
}
@@ -547,6 +584,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
547584
* extent of a type */
548585
MPI_Type_get_extent(types[0], &lb, &old_extent);
549586
}
587+
flatlist_node_grow(flat, j);
550588
flat->indices[j] = flat->indices[j - num] +
551589
ADIOI_AINT_CAST_TO_OFFSET old_extent;
552590
flat->blocklens[j] = flat->blocklens[j - num];
@@ -560,11 +598,13 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
560598
for (i = 1; i < top_count; i++) {
561599
for (m = 0; m < num; m++) {
562600
if (is_hindexed_block) {
601+
flatlist_node_grow(flat, j);
563602
flat->indices[j] = flat->indices[j - num] + adds[i] - adds[i - 1];
564603
} else {
565604
/* By using ADIO_Offset we preserve +/- sign and
566605
* avoid >2G integer arithmetic problems */
567606
ADIO_Offset stride = ints[2 + i] - ints[1 + i];
607+
flatlist_node_grow(flat, j);
568608
flat->indices[j] = flat->indices[j - num] +
569609
stride * ADIOI_AINT_CAST_TO_OFFSET old_extent;
570610
}
@@ -599,14 +639,13 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
599639
/* By using ADIO_Offset we preserve +/- sign and
600640
* avoid >2G integer arithmetic problems */
601641
ADIO_Offset blocklength = ints[1 + i - j];
642+
flatlist_node_grow(flat, nonzeroth);
602643
flat->indices[nonzeroth] = st_offset + adds[i - j];
603644
flat->blocklens[nonzeroth] = blocklength * old_size;
604645
nonzeroth++;
605-
} else {
606-
flat->count--;
607646
}
608647
}
609-
*curr_index = i;
648+
*curr_index = nonzeroth;
610649
} else {
611650
/* indexed type made up of noncontiguous derived types */
612651

@@ -625,8 +664,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
625664
flat->blocklens[nonzeroth] = flat->blocklens[j - num];
626665
j++;
627666
nonzeroth++;
628-
} else {
629-
flat->count--;
630667
}
631668
}
632669
}
@@ -643,8 +680,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
643680
flat->blocklens[nonzeroth] = flat->blocklens[j - num];
644681
j++;
645682
nonzeroth++;
646-
} else {
647-
flat->count--;
648683
}
649684
}
650685
*curr_index = j;
@@ -686,6 +721,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
686721
if (ints[1 + n] > 0 || types[n] == MPI_LB || types[n] == MPI_UB) {
687722
ADIO_Offset blocklength = ints[1 + n];
688723
j = *curr_index;
724+
flatlist_node_grow(flat, j);
689725
flat->indices[j] = st_offset + adds[n];
690726
MPI_Type_size_x(types[n], &old_size);
691727
flat->blocklens[j] = blocklength * old_size;
@@ -700,9 +736,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
700736
n, adds[n], j, flat->indices[j], j, flat->blocklens[j]);
701737
#endif
702738
(*curr_index)++;
703-
} else {
704-
flat->count--; /* don't count/consider any zero-length
705-
* blocklens */
706739
}
707740
} else {
708741
/* current type made up of noncontiguous derived types */
@@ -746,6 +779,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
746779
* bound based on the inner type, but the lower bound based on the
747780
* upper type. check both lb and ub to prevent mixing updates */
748781
if (flat->lb_idx == -1 && flat->ub_idx == -1) {
782+
flatlist_node_grow(flat, j);
749783
flat->indices[j] = st_offset + adds[0];
750784
/* this zero-length blocklens[] element, unlike elsewhere in the
751785
* flattening code, is correct and is used to indicate a lower bound
@@ -765,7 +799,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
765799
} else {
766800
/* skipped over this chunk because something else higher-up in the
767801
* type construction set this for us already */
768-
flat->count--;
769802
st_offset -= adds[0];
770803
}
771804

@@ -779,6 +812,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
779812
} else {
780813
/* current type is basic or contiguous */
781814
j = *curr_index;
815+
flatlist_node_grow(flat, j);
782816
flat->indices[j] = st_offset;
783817
MPI_Type_size_x(types[0], &old_size);
784818
flat->blocklens[j] = old_size;
@@ -797,6 +831,7 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
797831
/* see note above about mixing updates for why we check lb and ub */
798832
if ((flat->lb_idx == -1 && flat->ub_idx == -1) || lb_updated) {
799833
j = *curr_index;
834+
flatlist_node_grow(flat, j);
800835
flat->indices[j] = st_offset + adds[0] + adds[1];
801836
/* again, zero-element ok: an upper-bound marker explicitly set by the
802837
* constructor of this resized type */
@@ -805,7 +840,6 @@ void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node * flat,
805840
} else {
806841
/* skipped over this chunk because something else higher-up in the
807842
* type construction set this for us already */
808-
flat->count--;
809843
(*curr_index)--;
810844
}
811845

0 commit comments

Comments
 (0)