This source file includes following definitions.
- ADIOI_Type_get_envelope
- ADIOI_Type_get_contents
- ADIOI_Flatten_datatype
- ADIOI_Flatten
- ADIOI_Count_contiguous_blocks
- ADIOI_Optimize_flattened
- ADIOI_Delete_flattened
- ADIOI_Flatten_and_find
1
2
3
4
5
6
7 #include "adio.h"
8 #include "adio_extern.h"
9
10
11
12
13 #ifdef USE_DBG_LOGGING
14 #define FLATTEN_DEBUG 1
15 #endif
16
17 struct adio_short_int {
18 short elem_s;
19 int elem_i;
20 };
21
22 struct adio_double_int {
23 double elem_d;
24 int elem_i;
25 };
26
27 struct adio_long_int {
28 long elem_l;
29 int elem_i;
30 };
31
32 struct adio_long_double_int {
33 long double elem_ld;
34 int elem_i;
35 };
36
37 int ADIOI_Type_get_envelope (MPI_Datatype datatype, int *num_integers,
38 int *num_addresses, int *num_datatypes, int *combiner)
39 {
40 int rc, is_contig;
41
42 ADIOI_Datatype_iscontig(datatype, &is_contig);
43
44 rc = MPI_Type_get_envelope (datatype, num_integers, num_addresses, num_datatypes, combiner);
45 if (MPI_SUCCESS != rc || MPI_COMBINER_NAMED != *combiner || is_contig) {
46 return rc;
47 }
48
49 if (MPI_SHORT_INT == datatype || MPI_DOUBLE_INT == datatype || MPI_LONG_DOUBLE_INT == datatype ||
50 MPI_LONG_INT == datatype) {
51 *num_integers = 2;
52 *num_addresses = 2;
53 *num_datatypes = 2;
54 *combiner = MPI_COMBINER_STRUCT;
55 }
56
57 return rc;
58 }
59
60 int ADIOI_Type_get_contents (MPI_Datatype datatype, int max_integers,
61 int max_addresses, int max_datatypes, int array_of_integers[],
62 MPI_Aint array_of_addresses[], MPI_Datatype array_of_datatypes[])
63 {
64 int dontcare, combiner;
65 int rc;
66
67 rc = MPI_Type_get_envelope (datatype, &dontcare, &dontcare, &dontcare, &combiner);
68 if (MPI_SUCCESS != rc) {
69 return rc;
70 }
71
72 if (MPI_COMBINER_NAMED != combiner) {
73 return MPI_Type_get_contents (datatype, max_integers, max_addresses, max_datatypes,
74 array_of_integers, array_of_addresses, array_of_datatypes);
75 }
76
77 array_of_integers[0] = 1;
78 array_of_integers[1] = 1;
79 array_of_addresses[0] = 0;
80 array_of_datatypes[1] = MPI_INT;
81
82 if (MPI_SHORT_INT == datatype) {
83 array_of_datatypes[0] = MPI_SHORT;
84 array_of_addresses[1] = offsetof (struct adio_short_int, elem_i);
85 } else if (MPI_DOUBLE_INT == datatype) {
86 array_of_datatypes[0] = MPI_DOUBLE;
87 array_of_addresses[1] = offsetof (struct adio_double_int, elem_i);
88 } else if (MPI_LONG_DOUBLE_INT == datatype) {
89 array_of_datatypes[0] = MPI_LONG_DOUBLE;
90 array_of_addresses[1] = offsetof (struct adio_long_double_int, elem_i);
91 } else if (MPI_LONG_INT == datatype) {
92 array_of_datatypes[0] = MPI_LONG;
93 array_of_addresses[1] = offsetof (struct adio_long_int, elem_i);
94 } else {
95 rc = MPI_ERR_TYPE;
96 }
97
98 return rc;
99 }
100
101 void ADIOI_Optimize_flattened(ADIOI_Flatlist_node *flat_type);
102
103 void ADIOI_Flatten_datatype(MPI_Datatype datatype)
104 {
105 #ifdef HAVE_MPIR_TYPE_FLATTEN
106 MPI_Aint flatten_idx;
107 #endif
108 MPI_Count curr_index=0;
109 int is_contig;
110 ADIOI_Flatlist_node *flat, *prev=0;
111
112
113
114
115 ADIOI_Datatype_iscontig(datatype, &is_contig);
116 #ifdef FLATTEN_DEBUG
117 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: is_contig %#X\n",is_contig);
118 #endif
119 if (is_contig) return;
120
121
122 flat = ADIOI_Flatlist;
123 while (flat) {
124 if (flat->type == datatype) {
125 #ifdef FLATTEN_DEBUG
126 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: found datatype %#X\n", datatype);
127 #endif
128 return;
129 }
130 else {
131 prev = flat;
132 flat = flat->next;
133 }
134 }
135
136
137 flat = prev;
138 flat->next = (ADIOI_Flatlist_node *)ADIOI_Malloc(sizeof(ADIOI_Flatlist_node));
139 flat = flat->next;
140
141 flat->type = datatype;
142 flat->next = NULL;
143 flat->blocklens = NULL;
144 flat->indices = NULL;
145 flat->lb_idx = flat->ub_idx = -1;
146
147 flat->count = ADIOI_Count_contiguous_blocks(datatype, &curr_index);
148 #ifdef FLATTEN_DEBUG
149 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: count %llX, cur_idx = %#llX\n",flat->count,curr_index);
150 #endif
151
152
153 if (flat->count) {
154 flat->blocklens = (ADIO_Offset *) ADIOI_Malloc(flat->count * sizeof(ADIO_Offset));
155 flat->indices = (ADIO_Offset *) ADIOI_Malloc(flat->count * sizeof(ADIO_Offset));
156 }
157
158 curr_index = 0;
159 #ifdef HAVE_MPIR_TYPE_FLATTEN
160 flatten_idx = (MPI_Aint) flat->count;
161 MPIR_Type_flatten(datatype, flat->indices, flat->blocklens, &flatten_idx);
162 #ifdef FLATTEN_DEBUG
163 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: MPIR_Type_flatten\n");
164 #endif
165 #else
166 ADIOI_Flatten(datatype, flat, 0, &curr_index);
167 #ifdef FLATTEN_DEBUG
168 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: ADIOI_Flatten\n");
169 #endif
170
171 ADIOI_Optimize_flattened(flat);
172 #endif
173
174 #ifdef FLATTEN_DEBUG
175 {
176 int i;
177 for (i=0; i<flat->count; i++)
178 DBG_FPRINTF(stderr,"ADIOI_Flatten_datatype:: i %#X, blocklens %#llX, indices %#llX\n",
179 i,
180 flat->blocklens[i],
181 flat->indices[i]
182 );
183 }
184 #endif
185 }
186
187
188
189
190
191 void ADIOI_Flatten(MPI_Datatype datatype, ADIOI_Flatlist_node *flat,
192 ADIO_Offset st_offset, MPI_Count *curr_index)
193 {
194 int k, m, n, is_hindexed_block=0;
195 int lb_updated=0;
196 int combiner, old_combiner, old_is_contig;
197 int nints, nadds, ntypes, old_nints, old_nadds, old_ntypes;
198
199
200 ADIO_Offset top_count;
201 MPI_Count i, j, old_size, prev_index, basic_num, num, nonzeroth;
202 MPI_Aint old_extent, lb;
203 int *ints;
204 MPI_Aint *adds;
205 MPI_Datatype *types;
206 ADIOI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner);
207 if (combiner == MPI_COMBINER_NAMED) {
208 return;
209
210 }
211 ints = (int *) ADIOI_Malloc((nints+1)*sizeof(int));
212 adds = (MPI_Aint *) ADIOI_Malloc((nadds+1)*sizeof(MPI_Aint));
213 types = (MPI_Datatype *) ADIOI_Malloc((ntypes+1)*sizeof(MPI_Datatype));
214 ADIOI_Type_get_contents(datatype, nints, nadds, ntypes, ints, adds, types);
215
216 #ifdef FLATTEN_DEBUG
217 DBG_FPRINTF(stderr,"ADIOI_Flatten:: st_offset %#llX, curr_index %#llX\n",st_offset,*curr_index);
218 DBG_FPRINTF(stderr,"ADIOI_Flatten:: nints %#X, nadds %#X, ntypes %#X\n",nints, nadds, ntypes);
219 for(i=0; i< nints; ++i)
220 {
221 DBG_FPRINTF(stderr,"ADIOI_Flatten:: ints[%lld]=%#X\n",i,ints[i]);
222 }
223 for(i=0; i< nadds; ++i)
224 {
225 DBG_FPRINTF(stderr,"ADIOI_Flatten:: adds[%lld]="MPI_AINT_FMT_HEX_SPEC"\n",i,adds[i]);
226 }
227 for(i=0; i< ntypes; ++i)
228 {
229 DBG_FPRINTF(stderr,"ADIOI_Flatten:: types[%lld]=%#llX\n",i,(unsigned long long)(unsigned long)types[i]);
230 }
231 #endif
232
233
234
235
236
237
238
239 switch (combiner) {
240 #ifdef MPIIMPL_HAVE_MPI_COMBINER_DUP
241 case MPI_COMBINER_DUP:
242 #ifdef FLATTEN_DEBUG
243 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DUP\n");
244 #endif
245 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
246 &old_ntypes, &old_combiner);
247 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
248 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
249 ADIOI_Flatten(types[0], flat, st_offset, curr_index);
250 break;
251 #endif
252 #ifdef MPIIMPL_HAVE_MPI_COMBINER_SUBARRAY
253 case MPI_COMBINER_SUBARRAY:
254 {
255 int dims = ints[0];
256 MPI_Datatype stype;
257 #ifdef FLATTEN_DEBUG
258 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_SUBARRAY\n");
259 #endif
260
261 ADIO_Type_create_subarray(dims,
262 &ints[1],
263 &ints[dims+1],
264 &ints[2*dims+1],
265 ints[3*dims+1],
266 types[0],
267 &stype);
268 ADIOI_Flatten(stype, flat, st_offset, curr_index);
269 MPI_Type_free(&stype);
270 }
271 break;
272 #endif
273 #ifdef MPIIMPL_HAVE_MPI_COMBINER_DARRAY
274 case MPI_COMBINER_DARRAY:
275 {
276 int dims = ints[2];
277 MPI_Datatype dtype;
278 #ifdef FLATTEN_DEBUG
279 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DARRAY\n");
280 #endif
281
282 ADIO_Type_create_darray(ints[0],
283 ints[1],
284 dims,
285 &ints[3],
286 &ints[dims+3],
287 &ints[2*dims+3],
288 &ints[3*dims+3],
289 ints[4*dims+3],
290 types[0],
291 &dtype);
292 #ifdef FLATTEN_DEBUG
293 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DARRAY <ADIOI_Flatten(dtype, flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX, st_offset %#llX, curr_index %#llX);\n",
294 0, flat->indices[0], 0, flat->blocklens[0], st_offset, *curr_index);
295 #endif
296 ADIOI_Flatten(dtype, flat, st_offset, curr_index);
297 #ifdef FLATTEN_DEBUG
298 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_DARRAY >ADIOI_Flatten(dtype, flat->indices[%#X] %#llX, flat->blocklens[%#X] %#llX, st_offset %#llX, curr_index %#llX);\n",
299 0, flat->indices[0], 0, flat->blocklens[0], st_offset, *curr_index);
300 #endif
301 MPI_Type_free(&dtype);
302 }
303 break;
304 #endif
305 case MPI_COMBINER_CONTIGUOUS:
306 #ifdef FLATTEN_DEBUG
307 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_CONTIGUOUS\n");
308 #endif
309 top_count = ints[0];
310 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
311 &old_ntypes, &old_combiner);
312 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
313
314 prev_index = *curr_index;
315 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
316 ADIOI_Flatten(types[0], flat, st_offset, curr_index);
317
318 if (prev_index == *curr_index) {
319
320 j = *curr_index;
321 flat->indices[j] = st_offset;
322 MPI_Type_size_x(types[0], &old_size);
323 flat->blocklens[j] = top_count * old_size;
324 #ifdef FLATTEN_DEBUG
325 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n",j, flat->indices[j], j, flat->blocklens[j]);
326 #endif
327 (*curr_index)++;
328 }
329 else {
330
331 j = *curr_index;
332 num = *curr_index - prev_index;
333
334
335 MPI_Type_get_extent(types[0], &lb, &old_extent);
336 for (m=1; m<top_count; m++) {
337 for (i=0; i<num; i++) {
338 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
339 flat->blocklens[j] = flat->blocklens[j-num];
340 #ifdef FLATTEN_DEBUG
341 DBG_FPRINTF(stderr,"ADIOI_Flatten:: derived flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n",j, flat->indices[j], j, flat->blocklens[j]);
342 #endif
343 j++;
344 }
345 }
346 *curr_index = j;
347 }
348 break;
349
350 case MPI_COMBINER_VECTOR:
351 #ifdef FLATTEN_DEBUG
352 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_VECTOR\n");
353 #endif
354 top_count = ints[0];
355 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
356 &old_ntypes, &old_combiner);
357 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
358
359 prev_index = *curr_index;
360 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
361 ADIOI_Flatten(types[0], flat, st_offset, curr_index);
362
363 if (prev_index == *curr_index) {
364
365
366
367 ADIO_Offset blocklength = ints[1], stride = ints[2];
368 j = *curr_index;
369 flat->indices[j] = st_offset;
370 MPI_Type_size_x(types[0], &old_size);
371 flat->blocklens[j] = blocklength * old_size;
372 for (i=j+1; i<j+top_count; i++) {
373 flat->indices[i] = flat->indices[i-1] + stride * old_size;
374 flat->blocklens[i] = flat->blocklens[j];
375 }
376 *curr_index = i;
377 }
378 else {
379
380
381
382 ADIO_Offset blocklength = ints[1], stride = ints[2];
383
384 j = *curr_index;
385 num = *curr_index - prev_index;
386
387
388
389 MPI_Type_get_extent(types[0], &lb, &old_extent);
390 for (m=1; m<blocklength; m++) {
391 for (i=0; i<num; i++) {
392 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
393 flat->blocklens[j] = flat->blocklens[j-num];
394 j++;
395 }
396 }
397 *curr_index = j;
398
399
400 num = *curr_index - prev_index;
401 for (i=1; i<top_count; i++) {
402 for (m=0; m<num; m++) {
403 flat->indices[j] = flat->indices[j-num] + stride * ADIOI_AINT_CAST_TO_OFFSET old_extent;
404 flat->blocklens[j] = flat->blocklens[j-num];
405 j++;
406 }
407 }
408 *curr_index = j;
409 }
410 break;
411
412 case MPI_COMBINER_HVECTOR:
413 case MPI_COMBINER_HVECTOR_INTEGER:
414 #ifdef FLATTEN_DEBUG
415 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_HVECTOR_INTEGER\n");
416 #endif
417 top_count = ints[0];
418 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
419 &old_ntypes, &old_combiner);
420 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
421
422 prev_index = *curr_index;
423 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
424 ADIOI_Flatten(types[0], flat, st_offset, curr_index);
425
426 if (prev_index == *curr_index) {
427
428
429
430 ADIO_Offset blocklength = ints[1];
431 j = *curr_index;
432 flat->indices[j] = st_offset;
433 MPI_Type_size_x(types[0], &old_size);
434 flat->blocklens[j] = blocklength * old_size;
435 for (i=j+1; i<j+top_count; i++) {
436 flat->indices[i] = flat->indices[i-1] + adds[0];
437 flat->blocklens[i] = flat->blocklens[j];
438 }
439 *curr_index = i;
440 }
441 else {
442
443
444
445 ADIO_Offset blocklength = ints[1];
446
447 j = *curr_index;
448 num = *curr_index - prev_index;
449
450
451
452 MPI_Type_get_extent(types[0], &lb, &old_extent);
453 for (m=1; m<blocklength; m++) {
454 for (i=0; i<num; i++) {
455 flat->indices[j] = flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
456 flat->blocklens[j] = flat->blocklens[j-num];
457 j++;
458 }
459 }
460 *curr_index = j;
461
462
463 num = *curr_index - prev_index;
464 for (i=1; i<top_count; i++) {
465 for (m=0; m<num; m++) {
466 flat->indices[j] = flat->indices[j-num] + adds[0];
467 flat->blocklens[j] = flat->blocklens[j-num];
468 j++;
469 }
470 }
471 *curr_index = j;
472 }
473 break;
474
475 case MPI_COMBINER_INDEXED:
476 #ifdef FLATTEN_DEBUG
477 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_INDEXED\n");
478 #endif
479 top_count = ints[0];
480 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
481 &old_ntypes, &old_combiner);
482 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
483 MPI_Type_get_extent(types[0], &lb, &old_extent);
484
485 prev_index = *curr_index;
486 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
487 {
488
489
490 ADIO_Offset stride = ints[top_count+1];
491 ADIOI_Flatten(types[0], flat,
492 st_offset+stride* ADIOI_AINT_CAST_TO_OFFSET old_extent, curr_index);
493 }
494
495 if (prev_index == *curr_index) {
496
497 j = *curr_index;
498 for (i=j, nonzeroth=i; i<j+top_count; i++) {
499
500
501 ADIO_Offset blocklength = ints[1+i-j], stride = ints[top_count+1+i-j];
502 if (blocklength > 0) {
503 flat->indices[nonzeroth] =
504 st_offset + stride* ADIOI_AINT_CAST_TO_OFFSET old_extent;
505 flat->blocklens[nonzeroth] =
506 blocklength* ADIOI_AINT_CAST_TO_OFFSET old_extent;
507 nonzeroth++;
508 } else {
509 flat->count--;
510 }
511 }
512 *curr_index = i;
513 }
514 else {
515
516
517 j = *curr_index;
518 num = *curr_index - prev_index;
519 basic_num = num;
520
521
522
523 for (m=1; m<ints[1]; m++) {
524 for (i=0, nonzeroth = j; i<num; i++) {
525 if (flat->blocklens[j-num] > 0) {
526 flat->indices[nonzeroth] =
527 flat->indices[nonzeroth-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
528 flat->blocklens[nonzeroth] =
529 flat->blocklens[nonzeroth-num];
530 j++;
531 nonzeroth++;
532 } else {
533 flat->count --;
534 }
535 }
536 }
537 *curr_index = j;
538
539
540 for (i=1; i<top_count; i++) {
541 num = *curr_index - prev_index;
542 prev_index = *curr_index;
543 for (m=0, nonzeroth=j; m<basic_num; m++) {
544
545
546 ADIO_Offset stride = ints[top_count+1+i]-ints[top_count+i];
547 if (flat->blocklens[j-num] > 0 ) {
548 flat->indices[nonzeroth] =
549 flat->indices[j-num] + stride* ADIOI_AINT_CAST_TO_OFFSET old_extent;
550 flat->blocklens[nonzeroth] = flat->blocklens[j-num];
551 j++;
552 nonzeroth++;
553 } else {
554 flat->count--;
555 }
556 }
557 *curr_index = j;
558 for (m=1; m<ints[1+i]; m++) {
559 for (k=0, nonzeroth=j; k<basic_num; k++) {
560 if (flat->blocklens[j-basic_num] > 0) {
561 flat->indices[nonzeroth] =
562 flat->indices[j-basic_num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
563 flat->blocklens[nonzeroth] = flat->blocklens[j-basic_num];
564 j++;
565 nonzeroth++;
566 } else {
567 flat->count --;
568 }
569 }
570 }
571 *curr_index = j;
572 }
573 }
574 break;
575
576 #if defined HAVE_DECL_MPI_COMBINER_HINDEXED_BLOCK && HAVE_DECL_MPI_COMBINER_HINDEXED_BLOCK
577 case MPI_COMBINER_HINDEXED_BLOCK:
578 is_hindexed_block=1;
579
580 #endif
581 case MPI_COMBINER_INDEXED_BLOCK:
582 #ifdef FLATTEN_DEBUG
583 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_INDEXED_BLOCK\n");
584 #endif
585 top_count = ints[0];
586 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
587 &old_ntypes, &old_combiner);
588 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
589 MPI_Type_get_extent(types[0], &lb, &old_extent);
590
591 prev_index = *curr_index;
592 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
593 {
594
595
596 ADIO_Offset stride = ints[1+1];
597 if (is_hindexed_block) {
598 ADIOI_Flatten(types[0], flat,
599 st_offset+adds[0], curr_index);
600 } else {
601 ADIOI_Flatten(types[0], flat,
602 st_offset+stride* ADIOI_AINT_CAST_TO_OFFSET old_extent, curr_index);
603 }
604 }
605
606 if (prev_index == *curr_index) {
607
608 j = *curr_index;
609 for (i=j; i<j+top_count; i++) {
610
611
612 ADIO_Offset blocklength = ints[1];
613 if (is_hindexed_block) {
614 flat->indices[i] = st_offset + adds[i-j];
615 } else {
616 ADIO_Offset stride = ints[1+1+i-j];
617 flat->indices[i] = st_offset +
618 stride* ADIOI_AINT_CAST_TO_OFFSET old_extent;
619 }
620 flat->blocklens[i] = blocklength* ADIOI_AINT_CAST_TO_OFFSET old_extent;
621 }
622 *curr_index = i;
623 }
624 else {
625
626
627 j = *curr_index;
628 num = *curr_index - prev_index;
629
630
631
632 for (m=1; m<ints[1]; m++) {
633 for (i=0; i<num; i++) {
634 if (is_hindexed_block) {
635
636
637 MPI_Type_get_extent(types[0], &lb, &old_extent);
638 }
639 flat->indices[j] = flat->indices[j-num] +
640 ADIOI_AINT_CAST_TO_OFFSET old_extent;
641 flat->blocklens[j] = flat->blocklens[j-num];
642 j++;
643 }
644 }
645 *curr_index = j;
646
647
648 num = *curr_index - prev_index;
649 for (i=1; i<top_count; i++) {
650 for (m=0; m<num; m++) {
651 if (is_hindexed_block) {
652 flat->indices[j] = flat->indices[j-num] +
653 adds[i] - adds[i-1];
654 } else {
655
656
657 ADIO_Offset stride = ints[2+i]-ints[1+i];
658 flat->indices[j] = flat->indices[j-num] +
659 stride* ADIOI_AINT_CAST_TO_OFFSET old_extent;
660 }
661 flat->blocklens[j] = flat->blocklens[j-num];
662 j++;
663 }
664 }
665 *curr_index = j;
666 }
667 break;
668
669 case MPI_COMBINER_HINDEXED:
670 case MPI_COMBINER_HINDEXED_INTEGER:
671 #ifdef FLATTEN_DEBUG
672 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_HINDEXED_INTEGER\n");
673 #endif
674 top_count = ints[0];
675 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
676 &old_ntypes, &old_combiner);
677 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
678
679 prev_index = *curr_index;
680 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
681 {
682 ADIOI_Flatten(types[0], flat, st_offset+adds[0], curr_index);
683 }
684
685 if (prev_index == *curr_index) {
686
687 j = *curr_index;
688 MPI_Type_size_x(types[0], &old_size);
689 for (i=j, nonzeroth=j; i<j+top_count; i++) {
690 if (ints[1+i-j] > 0) {
691
692
693 ADIO_Offset blocklength = ints[1+i-j];
694 flat->indices[nonzeroth] = st_offset + adds[i-j];
695 flat->blocklens[nonzeroth] = blocklength*old_size;
696 nonzeroth++;
697 } else {
698 flat->count--;
699 }
700 }
701 *curr_index = i;
702 }
703 else {
704
705
706 j = *curr_index;
707 num = *curr_index - prev_index;
708 basic_num = num;
709
710
711
712 MPI_Type_get_extent(types[0], &lb, &old_extent);
713 for (m=1; m<ints[1]; m++) {
714 for (i=0, nonzeroth=j; i<num; i++) {
715 if (flat->blocklens[j-num] > 0) {
716 flat->indices[nonzeroth] =
717 flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
718 flat->blocklens[nonzeroth] = flat->blocklens[j-num];
719 j++;
720 nonzeroth++;
721 } else {
722 flat->count--;
723 }
724 }
725 }
726 *curr_index = j;
727
728
729 for (i=1; i<top_count; i++) {
730 num = *curr_index - prev_index;
731 prev_index = *curr_index;
732 for (m=0, nonzeroth=j; m<basic_num; m++) {
733 if (flat->blocklens[j-num] > 0) {
734 flat->indices[nonzeroth] =
735 flat->indices[j-num] + adds[i] - adds[i-1];
736 flat->blocklens[nonzeroth] = flat->blocklens[j-num];
737 j++;
738 nonzeroth++;
739 } else {
740 flat->count--;
741 }
742 }
743 *curr_index = j;
744 for (m=1; m<ints[1+i]; m++) {
745 for (k=0,nonzeroth=j; k<basic_num; k++) {
746 if (flat->blocklens[j-basic_num] >0) {
747 flat->indices[nonzeroth] =
748 flat->indices[j-basic_num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
749 flat->blocklens[nonzeroth] = flat->blocklens[j-basic_num];
750 j++;
751 nonzeroth++;
752 }
753 }
754 }
755 *curr_index = j;
756 }
757 }
758 break;
759
760 case MPI_COMBINER_STRUCT:
761 case MPI_COMBINER_STRUCT_INTEGER:
762 #ifdef FLATTEN_DEBUG
763 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_STRUCT_INTEGER\n");
764 #endif
765 top_count = ints[0];
766 for (n=0; n<top_count; n++) {
767 ADIOI_Type_get_envelope(types[n], &old_nints, &old_nadds,
768 &old_ntypes, &old_combiner);
769 ADIOI_Datatype_iscontig(types[n], &old_is_contig);
770
771 prev_index = *curr_index;
772 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
773 ADIOI_Flatten(types[n], flat, st_offset+adds[n], curr_index);
774
775 if (prev_index == *curr_index) {
776
777
778
779 if (ints[1+n] > 0) {
780 ADIO_Offset blocklength = ints[1+n];
781 j = *curr_index;
782 flat->indices[j] = st_offset + adds[n];
783 MPI_Type_size_x(types[n], &old_size);
784 flat->blocklens[j] = blocklength * old_size;
785 #ifdef FLATTEN_DEBUG
786 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]);
787 #endif
788 (*curr_index)++;
789 }
790 }
791 else {
792
793
794 j = *curr_index;
795 num = *curr_index - prev_index;
796
797
798 MPI_Type_get_extent(types[n], &lb, &old_extent);
799 for (m=1; m<ints[1+n]; m++) {
800 for (i=0; i<num; i++) {
801 flat->indices[j] =
802 flat->indices[j-num] + ADIOI_AINT_CAST_TO_OFFSET old_extent;
803 flat->blocklens[j] = flat->blocklens[j-num];
804 #ifdef FLATTEN_DEBUG
805 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple old_extent "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n",old_extent,j, flat->indices[j], j, flat->blocklens[j]);
806 #endif
807 j++;
808 }
809 }
810 *curr_index = j;
811 }
812 }
813 break;
814
815 case MPI_COMBINER_RESIZED:
816 #ifdef FLATTEN_DEBUG
817 DBG_FPRINTF(stderr,"ADIOI_Flatten:: MPI_COMBINER_RESIZED\n");
818 #endif
819
820
821
822
823 j = *curr_index;
824
825
826
827
828
829 if (flat->lb_idx == -1 && flat->ub_idx == -1) {
830 flat->indices[j] = st_offset + adds[0];
831
832
833
834 flat->blocklens[j] = 0;
835 flat->lb_idx = *curr_index;
836 lb_updated=1;
837
838 #ifdef FLATTEN_DEBUG
839 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple adds[%#X] "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n",0,adds[0],j, flat->indices[j], j, flat->blocklens[j]);
840 #endif
841
842 (*curr_index)++;
843 } else {
844
845
846 flat->count--;
847 st_offset -= adds[0];
848 }
849
850
851
852 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
853 &old_ntypes, &old_combiner);
854 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
855
856 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig)) {
857 ADIOI_Flatten(types[0], flat, st_offset+adds[0], curr_index);
858 }
859 else {
860
861 j = *curr_index;
862 flat->indices[j] = st_offset;
863 MPI_Type_size_x(types[0], &old_size);
864 flat->blocklens[j] = old_size;
865
866 #ifdef FLATTEN_DEBUG
867 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple adds[%#X] "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n",0,adds[0],j, flat->indices[j], j, flat->blocklens[j]);
868 #endif
869
870 (*curr_index)++;
871 }
872
873
874
875 if ((flat->lb_idx == -1 && flat->ub_idx == -1) || lb_updated) {
876 j = *curr_index;
877 flat->indices[j] = st_offset + adds[0] + adds[1];
878
879
880 flat->blocklens[j] = 0;
881 flat->ub_idx = *curr_index;
882 } else {
883
884
885 flat->count--;
886 (*curr_index)--;
887 }
888
889 #ifdef FLATTEN_DEBUG
890 DBG_FPRINTF(stderr,"ADIOI_Flatten:: simple adds[%#X] "MPI_AINT_FMT_HEX_SPEC", flat->indices[%#llX] %#llX, flat->blocklens[%#llX] %#llX\n",1,adds[1],j, flat->indices[j], j, flat->blocklens[j]);
891 #endif
892
893 (*curr_index)++;
894
895 break;
896
897 default:
898
899 DBG_FPRINTF(stderr, "Error: Unsupported datatype passed to ADIOI_Flatten\n");
900 MPI_Abort(MPI_COMM_WORLD, 1);
901 }
902
903 #ifndef MPISGI
904
905
906 for (i=0; i<ntypes; i++) {
907 MPI_Type_get_envelope(types[i], &old_nints, &old_nadds, &old_ntypes,
908 &old_combiner);
909 if (old_combiner != MPI_COMBINER_NAMED) MPI_Type_free(types+i);
910 }
911 #endif
912
913 ADIOI_Free(ints);
914 ADIOI_Free(adds);
915 ADIOI_Free(types);
916
917 #ifdef FLATTEN_DEBUG
918 DBG_FPRINTF(stderr,"ADIOI_Flatten:: return st_offset %#llX, curr_index %#llX\n",st_offset,*curr_index);
919 #endif
920
921 }
922
923
924
925
926
927
928
929
930
931
932 MPI_Count ADIOI_Count_contiguous_blocks(MPI_Datatype datatype, MPI_Count *curr_index)
933 {
934 int i, n;
935 MPI_Count count=0, prev_index, num, basic_num;
936 int top_count, combiner, old_combiner, old_is_contig;
937 int nints, nadds, ntypes, old_nints, old_nadds, old_ntypes;
938 int *ints;
939 MPI_Aint *adds;
940 MPI_Datatype *types;
941
942 ADIOI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner);
943 if (combiner == MPI_COMBINER_NAMED) {
944 return 1;
945
946 }
947 ints = (int *) ADIOI_Malloc((nints+1)*sizeof(int));
948 adds = (MPI_Aint *) ADIOI_Malloc((nadds+1)*sizeof(MPI_Aint));
949 types = (MPI_Datatype *) ADIOI_Malloc((ntypes+1)*sizeof(MPI_Datatype));
950 MPI_Type_get_contents(datatype, nints, nadds, ntypes, ints, adds, types);
951
952 switch (combiner) {
953 #ifdef MPIIMPL_HAVE_MPI_COMBINER_DUP
954 case MPI_COMBINER_DUP:
955 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
956 &old_ntypes, &old_combiner);
957 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
958 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
959 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
960 else {
961 count = 1;
962 (*curr_index)++;
963 }
964 break;
965 #endif
966 #ifdef MPIIMPL_HAVE_MPI_COMBINER_SUBARRAY
967 case MPI_COMBINER_SUBARRAY:
968 {
969 int dims = ints[0];
970 MPI_Datatype stype;
971
972 ADIO_Type_create_subarray(dims,
973 &ints[1],
974 &ints[dims+1],
975 &ints[2*dims+1],
976 ints[3*dims+1],
977 types[0],
978 &stype);
979 count = ADIOI_Count_contiguous_blocks(stype, curr_index);
980
981
982
983 MPI_Type_free(&stype);
984
985 }
986 break;
987 #endif
988 #ifdef MPIIMPL_HAVE_MPI_COMBINER_DARRAY
989 case MPI_COMBINER_DARRAY:
990 {
991 int dims = ints[2];
992 MPI_Datatype dtype;
993
994 ADIO_Type_create_darray(ints[0],
995 ints[1],
996 dims,
997 &ints[3],
998 &ints[dims+3],
999 &ints[2*dims+3],
1000 &ints[3*dims+3],
1001 ints[4*dims+3],
1002 types[0],
1003 &dtype);
1004 count = ADIOI_Count_contiguous_blocks(dtype, curr_index);
1005
1006
1007
1008 MPI_Type_free(&dtype);
1009 }
1010 break;
1011 #endif
1012 case MPI_COMBINER_CONTIGUOUS:
1013 top_count = ints[0];
1014 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
1015 &old_ntypes, &old_combiner);
1016 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
1017
1018 prev_index = *curr_index;
1019 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
1020 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
1021 else count = 1;
1022
1023 if (prev_index == *curr_index)
1024
1025 (*curr_index)++;
1026 else {
1027
1028 num = *curr_index - prev_index;
1029 count *= top_count;
1030 *curr_index += (top_count - 1)*num;
1031 }
1032 break;
1033
1034 case MPI_COMBINER_VECTOR:
1035 case MPI_COMBINER_HVECTOR:
1036 case MPI_COMBINER_HVECTOR_INTEGER:
1037 top_count = ints[0];
1038 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
1039 &old_ntypes, &old_combiner);
1040 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
1041
1042 prev_index = *curr_index;
1043 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
1044 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
1045 else count = 1;
1046
1047 if (prev_index == *curr_index) {
1048
1049 count = top_count;
1050 *curr_index += count;
1051 }
1052 else {
1053
1054 num = *curr_index - prev_index;
1055
1056
1057
1058 count *= ints[1] * top_count;
1059
1060
1061 *curr_index += (ints[1] - 1)*num;
1062
1063
1064 num = *curr_index - prev_index;
1065 *curr_index += (top_count - 1)*num;
1066 }
1067 break;
1068
1069 case MPI_COMBINER_INDEXED:
1070 case MPI_COMBINER_HINDEXED:
1071 case MPI_COMBINER_HINDEXED_INTEGER:
1072 top_count = ints[0];
1073 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
1074 &old_ntypes, &old_combiner);
1075 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
1076
1077 prev_index = *curr_index;
1078 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
1079 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
1080 else count = 1;
1081
1082 if (prev_index == *curr_index) {
1083
1084 count = top_count;
1085 *curr_index += count;
1086 }
1087 else {
1088
1089 basic_num = *curr_index - prev_index;
1090
1091
1092
1093 *curr_index += (ints[1]-1) * basic_num;
1094 count *= ints[1];
1095
1096
1097 for (i=1; i<top_count; i++) {
1098 count += ints[1+i] * basic_num;
1099 *curr_index += ints[1+i] * basic_num;
1100 }
1101 }
1102 break;
1103
1104 #if defined HAVE_DECL_MPI_COMBINER_HINDEXED_BLOCK && HAVE_DECL_MPI_COMBINER_HINDEXED_BLOCK
1105 case MPI_COMBINER_HINDEXED_BLOCK:
1106 #endif
1107 case MPI_COMBINER_INDEXED_BLOCK:
1108 top_count = ints[0];
1109 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
1110 &old_ntypes, &old_combiner);
1111 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
1112
1113 prev_index = *curr_index;
1114 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
1115 count = ADIOI_Count_contiguous_blocks(types[0], curr_index);
1116 else count = 1;
1117
1118 if (prev_index == *curr_index) {
1119
1120 count = top_count;
1121 *curr_index += count;
1122 }
1123 else {
1124
1125 basic_num = *curr_index - prev_index;
1126
1127
1128
1129 *curr_index += (ints[1]-1) * basic_num;
1130 count *= ints[1];
1131
1132
1133 *curr_index += (top_count-1) * count;
1134 count *= top_count;
1135 }
1136 break;
1137
1138 case MPI_COMBINER_STRUCT:
1139 case MPI_COMBINER_STRUCT_INTEGER:
1140 top_count = ints[0];
1141 count = 0;
1142 for (n=0; n<top_count; n++) {
1143 ADIOI_Type_get_envelope(types[n], &old_nints, &old_nadds,
1144 &old_ntypes, &old_combiner);
1145 ADIOI_Datatype_iscontig(types[n], &old_is_contig);
1146
1147 prev_index = *curr_index;
1148 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig))
1149 count += ADIOI_Count_contiguous_blocks(types[n], curr_index);
1150
1151 if (prev_index == *curr_index) {
1152
1153 count++;
1154 (*curr_index)++;
1155 }
1156 else {
1157
1158
1159
1160 num = *curr_index - prev_index;
1161 count += (ints[1+n]-1)*num;
1162 (*curr_index) += (ints[1+n]-1)*num;
1163 }
1164 }
1165 break;
1166
1167 case MPI_COMBINER_RESIZED:
1168
1169
1170
1171 (*curr_index) += 2;
1172 count += 2;
1173
1174
1175 ADIOI_Type_get_envelope(types[0], &old_nints, &old_nadds,
1176 &old_ntypes, &old_combiner);
1177 ADIOI_Datatype_iscontig(types[0], &old_is_contig);
1178
1179 if ((old_combiner != MPI_COMBINER_NAMED) && (!old_is_contig)) {
1180 count += ADIOI_Count_contiguous_blocks(types[0], curr_index);
1181 }
1182 else {
1183
1184 count++;
1185 (*curr_index)++;
1186 }
1187 break;
1188
1189 default:
1190
1191 DBG_FPRINTF(stderr, "Error: Unsupported datatype passed to ADIOI_Count_contiguous_blocks, combiner = %d\n", combiner);
1192 MPI_Abort(MPI_COMM_WORLD, 1);
1193 }
1194
1195 #ifndef MPISGI
1196
1197
1198 for (i=0; i<ntypes; i++) {
1199 MPI_Type_get_envelope(types[i], &old_nints, &old_nadds, &old_ntypes,
1200 &old_combiner);
1201 if (old_combiner != MPI_COMBINER_NAMED) MPI_Type_free(types+i);
1202 }
1203 #endif
1204
1205 ADIOI_Free(ints);
1206 ADIOI_Free(adds);
1207 ADIOI_Free(types);
1208 return count;
1209 }
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226 void ADIOI_Optimize_flattened(ADIOI_Flatlist_node *flat_type)
1227 {
1228 int i, j, opt_blocks;
1229 ADIO_Offset *opt_blocklens;
1230 ADIO_Offset *opt_indices;
1231
1232 opt_blocks = 1;
1233
1234
1235 for (i=0; i < (flat_type->count - 1); i++) {
1236 if ((flat_type->indices[i] + flat_type->blocklens[i] !=
1237 flat_type->indices[i + 1]))
1238 opt_blocks++;
1239 }
1240
1241
1242 if (opt_blocks == flat_type->count) return;
1243
1244 opt_blocklens = (ADIO_Offset *) ADIOI_Malloc(opt_blocks * sizeof(ADIO_Offset));
1245 opt_indices = (ADIO_Offset *)ADIOI_Malloc(opt_blocks*sizeof(ADIO_Offset));
1246
1247
1248 opt_blocklens[0] = flat_type->blocklens[0];
1249 opt_indices[0] = flat_type->indices[0];
1250 j = 0;
1251 for (i=0; i < (flat_type->count - 1); i++) {
1252 if ((flat_type->indices[i] + flat_type->blocklens[i] ==
1253 flat_type->indices[i + 1]))
1254 opt_blocklens[j] += flat_type->blocklens[i + 1];
1255 else {
1256 j++;
1257 opt_indices[j] = flat_type->indices[i + 1];
1258 opt_blocklens[j] = flat_type->blocklens[i + 1];
1259 }
1260 }
1261 flat_type->count = opt_blocks;
1262 ADIOI_Free(flat_type->blocklens);
1263 ADIOI_Free(flat_type->indices);
1264 flat_type->blocklens = opt_blocklens;
1265 flat_type->indices = opt_indices;
1266 return;
1267 }
1268
1269 void ADIOI_Delete_flattened(MPI_Datatype datatype)
1270 {
1271 ADIOI_Flatlist_node *flat, *prev;
1272
1273 prev = flat = ADIOI_Flatlist;
1274 while (flat && (flat->type != datatype)) {
1275 prev = flat;
1276 flat = flat->next;
1277 }
1278 if (flat) {
1279 prev->next = flat->next;
1280 if (flat->blocklens) ADIOI_Free(flat->blocklens);
1281 if (flat->indices) ADIOI_Free(flat->indices);
1282 ADIOI_Free(flat);
1283 }
1284 }
1285
1286 ADIOI_Flatlist_node * ADIOI_Flatten_and_find(MPI_Datatype datatype)
1287 {
1288 ADIOI_Flatlist_node *node;
1289 ADIOI_Flatten_datatype(datatype);
1290 node = ADIOI_Flatlist;
1291 while (node->type != datatype) node = node->next;
1292 return node;
1293 }