This source file includes following definitions.
- ompi_datatype_set_args
- ompi_datatype_print_args
- ompi_datatype_get_args
- ompi_datatype_copy_args
- ompi_datatype_release_args
- __ompi_datatype_pack_description
- ompi_datatype_get_pack_description
- ompi_datatype_pack_description_length
- __ompi_datatype_create_from_packed_description
- __ompi_datatype_create_from_args
- ompi_datatype_create_from_packed_description
- ompi_datatype_get_single_predefined_type_from_args
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include "ompi_config.h"
27
28 #include <stddef.h>
29
30 #include "opal/align.h"
31 #include "opal/types.h"
32 #include "opal/util/arch.h"
33 #include "opal/datatype/opal_datatype.h"
34 #include "opal/datatype/opal_datatype_internal.h"
35 #include "ompi/constants.h"
36 #include "ompi/datatype/ompi_datatype.h"
37 #include "ompi/datatype/ompi_datatype_internal.h"
38 #include "ompi/proc/proc.h"
39
40 static inline int
41 __ompi_datatype_pack_description( ompi_datatype_t* datatype,
42 void** packed_buffer, int* next_index );
43 static ompi_datatype_t*
44 __ompi_datatype_create_from_args( int32_t* i, ptrdiff_t * a,
45 ompi_datatype_t** d, int32_t type );
46
47 typedef struct __dt_args {
48 opal_atomic_int32_t ref_count;
49 int32_t create_type;
50 size_t total_pack_size;
51 int32_t ci;
52 int32_t ca;
53 int32_t cd;
54 int* i;
55 ptrdiff_t* a;
56 ompi_datatype_t** d;
57 } ompi_datatype_args_t;
58
59
60
61
62
63
64
65
66
67 #if OPAL_ALIGN_WORD_SIZE_INTEGERS
68 #define OMPI_DATATYPE_ALIGN_PTR(PTR, TYPE) \
69 (PTR) = OPAL_ALIGN_PTR((PTR), sizeof(ptrdiff_t), TYPE)
70 #else
71 #define OMPI_DATATYPE_ALIGN_PTR(PTR, TYPE)
72 #endif
73
74
75
76
77
78
79
80
81 #define ALLOC_ARGS(PDATA, IC, AC, DC) \
82 do { \
83 int length = sizeof(ompi_datatype_args_t) + (IC) * sizeof(int) + \
84 (AC) * sizeof(ptrdiff_t) + (DC) * sizeof(MPI_Datatype); \
85 char* buf = (char*)malloc( length ); \
86 ompi_datatype_args_t* pArgs = (ompi_datatype_args_t*)buf; \
87 pArgs->ci = (IC); \
88 pArgs->ca = (AC); \
89 pArgs->cd = (DC); \
90 buf += sizeof(ompi_datatype_args_t); \
91 if( pArgs->ca == 0 ) pArgs->a = NULL; \
92 else { \
93 pArgs->a = (ptrdiff_t*)buf; \
94 buf += pArgs->ca * sizeof(ptrdiff_t); \
95 } \
96 if( pArgs->cd == 0 ) pArgs->d = NULL; \
97 else { \
98 pArgs->d = (ompi_datatype_t**)buf; \
99 buf += pArgs->cd * sizeof(MPI_Datatype); \
100 } \
101 if( pArgs->ci == 0 ) pArgs->i = NULL; \
102 else pArgs->i = (int*)buf; \
103 pArgs->ref_count = 1; \
104 pArgs->total_pack_size = (4 + (IC) + (DC)) * sizeof(int) + \
105 (AC) * sizeof(ptrdiff_t); \
106 (PDATA)->args = (void*)pArgs; \
107 (PDATA)->packed_description = 0; \
108 } while(0)
109
110
111 int32_t ompi_datatype_set_args( ompi_datatype_t* pData,
112 int32_t ci, const int32_t** i,
113 int32_t ca, const ptrdiff_t* a,
114 int32_t cd, ompi_datatype_t* const * d, int32_t type)
115 {
116 int pos;
117 ompi_datatype_args_t* pArgs;
118
119 assert( NULL == pData->args );
120 ALLOC_ARGS( pData, ci, ca, cd );
121
122 pArgs = (ompi_datatype_args_t*)pData->args;
123 pArgs->create_type = type;
124
125 switch(type) {
126
127 case MPI_COMBINER_DUP:
128 pArgs->total_pack_size = 0;
129 break;
130
131 case MPI_COMBINER_CONTIGUOUS:
132 pArgs->i[0] = i[0][0];
133 break;
134
135 case MPI_COMBINER_VECTOR:
136 pArgs->i[0] = i[0][0];
137 pArgs->i[1] = i[1][0];
138 pArgs->i[2] = i[2][0];
139 break;
140
141 case MPI_COMBINER_HVECTOR_INTEGER:
142 case MPI_COMBINER_HVECTOR:
143 pArgs->i[0] = i[0][0];
144 pArgs->i[1] = i[1][0];
145 break;
146
147 case MPI_COMBINER_INDEXED:
148 pos = 1;
149 pArgs->i[0] = i[0][0];
150 memcpy( pArgs->i + pos, i[1], i[0][0] * sizeof(int) );
151 pos += i[0][0];
152 memcpy( pArgs->i + pos, i[2], i[0][0] * sizeof(int) );
153 break;
154
155 case MPI_COMBINER_HINDEXED_INTEGER:
156 case MPI_COMBINER_HINDEXED:
157 pArgs->i[0] = i[0][0];
158 memcpy( pArgs->i + 1, i[1], i[0][0] * sizeof(int) );
159 break;
160
161 case MPI_COMBINER_INDEXED_BLOCK:
162 pArgs->i[0] = i[0][0];
163 pArgs->i[1] = i[1][0];
164 memcpy( pArgs->i + 2, i[2], i[0][0] * sizeof(int) );
165 break;
166
167 case MPI_COMBINER_STRUCT_INTEGER:
168 case MPI_COMBINER_STRUCT:
169 pArgs->i[0] = i[0][0];
170 memcpy( pArgs->i + 1, i[1], i[0][0] * sizeof(int) );
171 break;
172
173 case MPI_COMBINER_SUBARRAY:
174 pos = 1;
175 pArgs->i[0] = i[0][0];
176 memcpy( pArgs->i + pos, i[1], pArgs->i[0] * sizeof(int) );
177 pos += pArgs->i[0];
178 memcpy( pArgs->i + pos, i[2], pArgs->i[0] * sizeof(int) );
179 pos += pArgs->i[0];
180 memcpy( pArgs->i + pos, i[3], pArgs->i[0] * sizeof(int) );
181 pos += pArgs->i[0];
182 pArgs->i[pos] = i[4][0];
183 break;
184
185 case MPI_COMBINER_DARRAY:
186 pos = 3;
187 pArgs->i[0] = i[0][0];
188 pArgs->i[1] = i[1][0];
189 pArgs->i[2] = i[2][0];
190
191 memcpy( pArgs->i + pos, i[3], i[2][0] * sizeof(int) );
192 pos += i[2][0];
193 memcpy( pArgs->i + pos, i[4], i[2][0] * sizeof(int) );
194 pos += i[2][0];
195 memcpy( pArgs->i + pos, i[5], i[2][0] * sizeof(int) );
196 pos += i[2][0];
197 memcpy( pArgs->i + pos, i[6], i[2][0] * sizeof(int) );
198 pos += i[2][0];
199 pArgs->i[pos] = i[7][0];
200 break;
201
202 case MPI_COMBINER_F90_REAL:
203 case MPI_COMBINER_F90_COMPLEX:
204 pArgs->i[0] = i[0][0];
205 pArgs->i[1] = i[1][0];
206 break;
207
208 case MPI_COMBINER_F90_INTEGER:
209 pArgs->i[0] = i[0][0];
210 break;
211
212 case MPI_COMBINER_RESIZED:
213 break;
214
215 case MPI_COMBINER_HINDEXED_BLOCK:
216 pArgs->i[0] = i[0][0];
217 pArgs->i[1] = i[1][0];
218 break;
219
220 default:
221 break;
222 }
223
224
225 if( pArgs->a != NULL )
226 memcpy( pArgs->a, a, ca * sizeof(ptrdiff_t) );
227
228 for( pos = 0; pos < cd; pos++ ) {
229 pArgs->d[pos] = d[pos];
230 if( !(ompi_datatype_is_predefined(d[pos])) ) {
231
232
233
234
235
236
237
238 OBJ_RETAIN( d[pos] );
239 pArgs->total_pack_size += ((ompi_datatype_args_t*)d[pos]->args)->total_pack_size;
240 } else {
241 pArgs->total_pack_size += sizeof(int);
242 }
243 pArgs->total_pack_size += sizeof(int);
244 }
245
246 return OMPI_SUCCESS;
247 }
248
249
250 int32_t ompi_datatype_print_args( const ompi_datatype_t* pData )
251 {
252 int32_t i;
253 ompi_datatype_args_t* pArgs = (ompi_datatype_args_t*)pData->args;
254
255 if( ompi_datatype_is_predefined(pData) ) {
256
257 return OMPI_SUCCESS;
258 }
259
260 if( pArgs == NULL ) return MPI_ERR_INTERN;
261
262 printf( "type %d count ints %d count disp %d count datatype %d\n",
263 pArgs->create_type, pArgs->ci, pArgs->ca, pArgs->cd );
264 if( pArgs->i != NULL ) {
265 printf( "ints: " );
266 for( i = 0; i < pArgs->ci; i++ ) {
267 printf( "%d ", pArgs->i[i] );
268 }
269 printf( "\n" );
270 }
271 if( pArgs->a != NULL ) {
272 printf( "MPI_Aint: " );
273 for( i = 0; i < pArgs->ca; i++ ) {
274 printf( "%ld ", (long)pArgs->a[i] );
275 }
276 printf( "\n" );
277 }
278 if( pArgs->d != NULL ) {
279 int count = 1;
280 ompi_datatype_t *temp, *old;
281
282 printf( "types: " );
283 old = pArgs->d[0];
284 for( i = 1; i < pArgs->cd; i++ ) {
285 temp = pArgs->d[i];
286 if( old == temp ) {
287 count++;
288 continue;
289 }
290 if( count <= 1 ) {
291 if( ompi_datatype_is_predefined(old) )
292 printf( "%s ", old->name );
293 else
294 printf( "%p ", (void*)old );
295 } else {
296 if( ompi_datatype_is_predefined(old) )
297 printf( "(%d * %s) ", count, old->name );
298 else
299 printf( "(%d * %p) ", count, (void*)old );
300 }
301 count = 1;
302 old = temp;
303 }
304 if( count <= 1 ) {
305 if( ompi_datatype_is_predefined(old) )
306 printf( "%s ", old->name );
307 else
308 printf( "%p ", (void*)old );
309 } else {
310 if( ompi_datatype_is_predefined(old) )
311 printf( "(%d * %s) ", count, old->name );
312 else
313 printf( "(%d * %p) ", count, (void*)old );
314 }
315 printf( "\n" );
316 }
317 return OMPI_SUCCESS;
318 }
319
320
321 int32_t ompi_datatype_get_args( const ompi_datatype_t* pData, int32_t which,
322 int32_t* ci, int32_t* i,
323 int32_t* ca, ptrdiff_t* a,
324 int32_t* cd, ompi_datatype_t** d, int32_t* type)
325 {
326 ompi_datatype_args_t* pArgs = (ompi_datatype_args_t*)pData->args;
327
328 if( NULL == pArgs ) {
329 if( ompi_datatype_is_predefined(pData) ) {
330 switch(which){
331 case 0:
332 *ci = 0;
333 *ca = 0;
334 *cd = 0;
335 *type = MPI_COMBINER_NAMED;
336 break;
337 default:
338 return MPI_ERR_INTERN;
339 }
340 return OMPI_SUCCESS;
341 }
342 return MPI_ERR_INTERN;
343 }
344
345 switch(which){
346 case 0:
347 *ci = pArgs->ci;
348 *ca = pArgs->ca;
349 *cd = pArgs->cd;
350 *type = pArgs->create_type;
351 break;
352 case 1:
353 if(*ci < pArgs->ci || *ca < pArgs->ca || *cd < pArgs->cd) {
354 return MPI_ERR_ARG;
355 }
356 if( (NULL != i) && (NULL != pArgs->i) ) {
357 memcpy( i, pArgs->i, pArgs->ci * sizeof(int) );
358 }
359 if( (NULL != a) && (NULL != pArgs->a) ) {
360 memcpy( a, pArgs->a, pArgs->ca * sizeof(ptrdiff_t) );
361 }
362 if( (NULL != d) && (NULL != pArgs->d) ) {
363 memcpy( d, pArgs->d, pArgs->cd * sizeof(MPI_Datatype) );
364 }
365 break;
366 default:
367 return MPI_ERR_INTERN;
368 }
369 return OMPI_SUCCESS;
370 }
371
372
373 int32_t ompi_datatype_copy_args( const ompi_datatype_t* source_data,
374 ompi_datatype_t* dest_data )
375 {
376 ompi_datatype_args_t* pArgs = (ompi_datatype_args_t*)source_data->args;
377
378
379
380
381
382 if( NULL != pArgs ) {
383 OPAL_THREAD_ADD_FETCH32(&pArgs->ref_count, 1);
384 dest_data->args = pArgs;
385 }
386 return OMPI_SUCCESS;
387 }
388
389
390
391
392
393
394
395 int32_t ompi_datatype_release_args( ompi_datatype_t* pData )
396 {
397 int i;
398 ompi_datatype_args_t* pArgs = (ompi_datatype_args_t*)pData->args;
399
400 assert( 0 < pArgs->ref_count );
401 OPAL_THREAD_ADD_FETCH32(&pArgs->ref_count, -1);
402 if( 0 == pArgs->ref_count ) {
403
404
405
406 for( i = 0; i < pArgs->cd; i++ ) {
407 if( !(ompi_datatype_is_predefined(pArgs->d[i])) ) {
408 OBJ_RELEASE( pArgs->d[i] );
409 }
410 }
411 free( pData->args );
412 }
413 pData->args = NULL;
414
415 return OMPI_SUCCESS;
416 }
417
418
419 static inline int __ompi_datatype_pack_description( ompi_datatype_t* datatype,
420 void** packed_buffer, int* next_index )
421 {
422 int i, *position = (int*)*packed_buffer;
423 ompi_datatype_args_t* args = (ompi_datatype_args_t*)datatype->args;
424 char* next_packed = (char*)*packed_buffer;
425
426 if( ompi_datatype_is_predefined(datatype) ) {
427 position[0] = MPI_COMBINER_NAMED;
428 position[1] = datatype->id;
429 next_packed += (2 * sizeof(int));
430 *packed_buffer = next_packed;
431 return OMPI_SUCCESS;
432 }
433
434 if( MPI_COMBINER_DUP == args->create_type ) {
435 ompi_datatype_t* temp_data = args->d[0];
436 return __ompi_datatype_pack_description(temp_data,
437 packed_buffer,
438 next_index );
439 }
440 position[0] = args->create_type;
441 position[1] = args->ci;
442 position[2] = args->ca;
443 position[3] = args->cd;
444 next_packed += (4 * sizeof(int));
445
446
447
448
449
450
451 if( 0 < args->ca ) {
452
453 OMPI_DATATYPE_ALIGN_PTR(next_packed, char*);
454
455 memcpy( next_packed, args->a, sizeof(ptrdiff_t) * args->ca );
456 next_packed += sizeof(ptrdiff_t) * args->ca;
457 }
458 position = (int*)next_packed;
459 next_packed += sizeof(int) * args->cd;
460
461
462 memcpy( next_packed, args->i, sizeof(int) * args->ci );
463 next_packed += args->ci * sizeof(int);
464
465
466 for( i = 0; i < args->cd; i++ ) {
467 ompi_datatype_t* temp_data = args->d[i];
468 if( ompi_datatype_is_predefined(temp_data) ) {
469 position[i] = temp_data->id;
470 } else {
471 position[i] = *next_index;
472 (*next_index)++;
473 __ompi_datatype_pack_description( temp_data,
474 (void**)&next_packed,
475 next_index );
476 }
477 }
478 *packed_buffer = next_packed;
479 return OMPI_SUCCESS;
480 }
481
482
483 int ompi_datatype_get_pack_description( ompi_datatype_t* datatype,
484 const void** packed_buffer )
485 {
486 ompi_datatype_args_t* args = (ompi_datatype_args_t*)datatype->args;
487 int next_index = OMPI_DATATYPE_MAX_PREDEFINED;
488 void *packed_description = (void *) datatype->packed_description;
489 void* recursive_buffer;
490
491 if (NULL == packed_description) {
492 void *_tmp_ptr = NULL;
493 if (opal_atomic_compare_exchange_strong_ptr (&datatype->packed_description, (intptr_t *) &_tmp_ptr, 1)) {
494 if( ompi_datatype_is_predefined(datatype) ) {
495 packed_description = malloc(2 * sizeof(int));
496 } else if( NULL == args ) {
497 return OMPI_ERROR;
498 } else {
499 packed_description = malloc(args->total_pack_size);
500 }
501 recursive_buffer = packed_description;
502 __ompi_datatype_pack_description( datatype, &recursive_buffer, &next_index );
503
504 if (!ompi_datatype_is_predefined(datatype)) {
505
506
507
508
509
510 assert(args->total_pack_size >= (uintptr_t)((char*)recursive_buffer - (char *) packed_description));
511 args->total_pack_size = (uintptr_t)((char*)recursive_buffer - (char *) packed_description);
512 }
513
514 opal_atomic_wmb ();
515 datatype->packed_description = (intptr_t) packed_description;
516 } else {
517
518 packed_description = (void *) datatype->packed_description;
519 }
520 }
521
522 if ((void *) 1 == packed_description) {
523 struct timespec interval = {.tv_sec = 0, .tv_nsec = 1000};
524
525
526 while (1 == datatype->packed_description) {
527 nanosleep (&interval, NULL);
528 }
529
530 packed_description = (void *) datatype->packed_description;
531 }
532
533 *packed_buffer = (const void *) packed_description;
534 return OMPI_SUCCESS;
535 }
536
537 size_t ompi_datatype_pack_description_length( ompi_datatype_t* datatype )
538 {
539 void *packed_description = (void *) datatype->packed_description;
540
541 if( ompi_datatype_is_predefined(datatype) ) {
542 return 2 * sizeof(int);
543 }
544 if( NULL == packed_description || (void *) 1 == packed_description) {
545 const void* buf;
546 int rc;
547
548 rc = ompi_datatype_get_pack_description(datatype, &buf);
549 if( OMPI_SUCCESS != rc ) {
550 return 0;
551 }
552 }
553 assert( NULL != (ompi_datatype_args_t*)datatype->args );
554 assert( NULL != (ompi_datatype_args_t*)datatype->packed_description );
555 return ((ompi_datatype_args_t*)datatype->args)->total_pack_size;
556 }
557
558 static ompi_datatype_t* __ompi_datatype_create_from_packed_description( void** packed_buffer,
559 const struct ompi_proc_t* remote_processor )
560 {
561 int* position;
562 ompi_datatype_t* datatype = NULL;
563 ompi_datatype_t** array_of_datatype;
564 ptrdiff_t* array_of_disp;
565 int* array_of_length;
566 int number_of_length, number_of_disp, number_of_datatype, data_id;
567 int create_type, i;
568 char* next_buffer;
569
570 #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
571 bool need_swap = false;
572
573 if( (remote_processor->super.proc_arch ^ ompi_proc_local()->super.proc_arch) &
574 OPAL_ARCH_ISBIGENDIAN ) {
575 need_swap = true;
576 }
577 #endif
578
579 next_buffer = (char*)*packed_buffer;
580 position = (int*)next_buffer;
581
582 create_type = position[0];
583 #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
584 if (need_swap) {
585 create_type = opal_swap_bytes4(create_type);
586 }
587 #endif
588 if( MPI_COMBINER_NAMED == create_type ) {
589
590 data_id = position[1];
591 #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
592 if (need_swap) {
593 data_id = opal_swap_bytes4(data_id);
594 }
595 #endif
596 assert( data_id < OMPI_DATATYPE_MAX_PREDEFINED );
597 *packed_buffer = position + 2;
598 return (ompi_datatype_t*)ompi_datatype_basicDatatypes[data_id];
599 }
600
601 number_of_length = position[1];
602 number_of_disp = position[2];
603 number_of_datatype = position[3];
604 #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
605 if (need_swap) {
606 number_of_length = opal_swap_bytes4(number_of_length);
607 number_of_disp = opal_swap_bytes4(number_of_disp);
608 number_of_datatype = opal_swap_bytes4(number_of_datatype);
609 }
610 #endif
611 array_of_datatype = (ompi_datatype_t**)malloc( sizeof(ompi_datatype_t*) *
612 number_of_datatype );
613 next_buffer += (4 * sizeof(int));
614
615
616
617 if (number_of_disp > 0) {
618 OMPI_DATATYPE_ALIGN_PTR(next_buffer, char*);
619 }
620
621 array_of_disp = (ptrdiff_t*)next_buffer;
622 next_buffer += number_of_disp * sizeof(ptrdiff_t);
623
624 position = (int*)next_buffer;
625 next_buffer += number_of_datatype * sizeof(int);
626
627 array_of_length = (int*)next_buffer;
628 next_buffer += (number_of_length * sizeof(int));
629
630 for( i = 0; i < number_of_datatype; i++ ) {
631 data_id = position[i];
632 #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
633 if (need_swap) {
634 data_id = opal_swap_bytes4(data_id);
635 }
636 #endif
637 if( data_id < OMPI_DATATYPE_MAX_PREDEFINED ) {
638 array_of_datatype[i] = (ompi_datatype_t*)ompi_datatype_basicDatatypes[data_id];
639 continue;
640 }
641 array_of_datatype[i] =
642 __ompi_datatype_create_from_packed_description( (void**)&next_buffer,
643 remote_processor );
644 if( NULL == array_of_datatype[i] ) {
645
646
647
648
649 array_of_datatype[i] = (ompi_datatype_t*)ompi_datatype_basicDatatypes[OPAL_DATATYPE_INT1];
650 number_of_datatype = i;
651 goto cleanup_and_exit;
652 }
653 }
654
655 #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
656 if (need_swap) {
657 for (i = 0 ; i < number_of_length ; ++i) {
658 array_of_length[i] = opal_swap_bytes4(array_of_length[i]);
659 }
660 for (i = 0 ; i < number_of_disp ; ++i) {
661 #if SIZEOF_PTRDIFF_T == 4
662 array_of_disp[i] = opal_swap_bytes4(array_of_disp[i]);
663 #elif SIZEOF_PTRDIFF_T == 8
664 array_of_disp[i] = (MPI_Aint)opal_swap_bytes8(array_of_disp[i]);
665 #else
666 #error "Unknown size of ptrdiff_t"
667 #endif
668 }
669 }
670 #endif
671 datatype = __ompi_datatype_create_from_args( array_of_length, array_of_disp,
672 array_of_datatype, create_type );
673 *packed_buffer = next_buffer;
674 cleanup_and_exit:
675 for( i = 0; i < number_of_datatype; i++ ) {
676 if( !(ompi_datatype_is_predefined(array_of_datatype[i])) ) {
677 OBJ_RELEASE(array_of_datatype[i]);
678 }
679 }
680 free( array_of_datatype );
681 return datatype;
682 }
683
684 static ompi_datatype_t* __ompi_datatype_create_from_args( int32_t* i, MPI_Aint* a,
685 ompi_datatype_t** d, int32_t type )
686 {
687 ompi_datatype_t* datatype = NULL;
688
689 switch(type){
690
691 case MPI_COMBINER_DUP:
692
693
694 assert(0);
695 break;
696
697 case MPI_COMBINER_CONTIGUOUS:
698 ompi_datatype_create_contiguous( i[0], d[0], &datatype );
699 ompi_datatype_set_args( datatype, 1, (const int **) &i, 0, NULL, 1, d, MPI_COMBINER_CONTIGUOUS );
700 break;
701
702 case MPI_COMBINER_VECTOR:
703 ompi_datatype_create_vector( i[0], i[1], i[2], d[0], &datatype );
704 {
705 const int* a_i[3] = {&i[0], &i[1], &i[2]};
706 ompi_datatype_set_args( datatype, 3, a_i, 0, NULL, 1, d, MPI_COMBINER_VECTOR );
707 }
708 break;
709
710 case MPI_COMBINER_HVECTOR_INTEGER:
711 case MPI_COMBINER_HVECTOR:
712 ompi_datatype_create_hvector( i[0], i[1], a[0], d[0], &datatype );
713 {
714 const int* a_i[2] = {&i[0], &i[1]};
715 ompi_datatype_set_args( datatype, 2, a_i, 1, a, 1, d, MPI_COMBINER_HVECTOR );
716 }
717 break;
718
719 case MPI_COMBINER_INDEXED:
720 ompi_datatype_create_indexed( i[0], &(i[1]), &(i[1+i[0]]), d[0], &datatype );
721 {
722 const int* a_i[3] = {&i[0], &i[1], &(i[1+i[0]])};
723 ompi_datatype_set_args( datatype, 2 * i[0] + 1, a_i, 0, NULL, 1, d, MPI_COMBINER_INDEXED );
724 }
725 break;
726
727 case MPI_COMBINER_HINDEXED_INTEGER:
728 case MPI_COMBINER_HINDEXED:
729 ompi_datatype_create_hindexed( i[0], &(i[1]), a, d[0], &datatype );
730 {
731 const int* a_i[2] = {&i[0], &i[1]};
732 ompi_datatype_set_args( datatype, i[0] + 1, a_i, i[0], a, 1, d, MPI_COMBINER_HINDEXED );
733 }
734 break;
735
736 case MPI_COMBINER_INDEXED_BLOCK:
737 ompi_datatype_create_indexed_block( i[0], i[1], &(i[2]), d[0], &datatype );
738 {
739 const int* a_i[3] = {&i[0], &i[1], &i[2]};
740 ompi_datatype_set_args( datatype, i[0] + 2, a_i, 0, NULL, 1, d, MPI_COMBINER_INDEXED_BLOCK );
741 }
742 break;
743
744 case MPI_COMBINER_STRUCT_INTEGER:
745 case MPI_COMBINER_STRUCT:
746 ompi_datatype_create_struct( i[0], &(i[1]), a, d, &datatype );
747 {
748 const int* a_i[2] = {&i[0], &i[1]};
749 ompi_datatype_set_args( datatype, i[0] + 1, a_i, i[0], a, i[0], d, MPI_COMBINER_STRUCT );
750 }
751 break;
752
753 case MPI_COMBINER_SUBARRAY:
754 ompi_datatype_create_subarray( i[0], &i[1 + 0 * i[0]], &i[1 + 1 * i[0]],
755 &i[1 + 2 * i[0]], i[1 + 3 * i[0]],
756 d[0], &datatype );
757 {
758 const int* a_i[5] = {&i[0], &i[1 + 0 * i[0]], &i[1 + 1 * i[0]], &i[1 + 2 * i[0]], &i[1 + 3 * i[0]]};
759 ompi_datatype_set_args( datatype, 3 * i[0] + 2, a_i, 0, NULL, 1, d, MPI_COMBINER_SUBARRAY);
760 }
761 break;
762
763 case MPI_COMBINER_DARRAY:
764 ompi_datatype_create_darray( i[0] , i[1] , i[2] ,
765 &i[3 + 0 * i[2]], &i[3 + 1 * i[2]],
766 &i[3 + 2 * i[2]], &i[3 + 3 * i[2]],
767 i[3 + 4 * i[2]], d[0], &datatype );
768 {
769 const int* a_i[8] = {&i[0], &i[1], &i[2], &i[3 + 0 * i[2]], &i[3 + 1 * i[2]], &i[3 + 2 * i[2]],
770 &i[3 + 3 * i[2]], &i[3 + 4 * i[2]]};
771 ompi_datatype_set_args( datatype, 4 * i[2] + 4, a_i, 0, NULL, 1, d, MPI_COMBINER_DARRAY);
772 }
773 break;
774
775 case MPI_COMBINER_F90_REAL:
776 case MPI_COMBINER_F90_COMPLEX:
777
778
779
780 break;
781
782 case MPI_COMBINER_F90_INTEGER:
783
784 break;
785
786 case MPI_COMBINER_RESIZED:
787 ompi_datatype_create_resized(d[0], a[0], a[1], &datatype);
788 ompi_datatype_set_args( datatype, 0, NULL, 2, a, 1, d, MPI_COMBINER_RESIZED );
789 break;
790
791 case MPI_COMBINER_HINDEXED_BLOCK:
792 ompi_datatype_create_hindexed_block( i[0], i[1], a, d[0], &datatype );
793 {
794 const int* a_i[2] = {&i[0], &i[1]};
795 ompi_datatype_set_args( datatype, 2, a_i, i[0], a, 1, d, MPI_COMBINER_HINDEXED_BLOCK );
796 }
797 break;
798
799 default:
800 break;
801 }
802
803 return datatype;
804 }
805
806 ompi_datatype_t* ompi_datatype_create_from_packed_description( void** packed_buffer,
807 struct ompi_proc_t* remote_processor )
808 {
809 ompi_datatype_t* datatype;
810
811 datatype = __ompi_datatype_create_from_packed_description( packed_buffer,
812 remote_processor );
813 if( NULL == datatype ) {
814 return NULL;
815 }
816 ompi_datatype_commit( &datatype );
817 return datatype;
818 }
819
820
821
822
823
824
825 ompi_datatype_t* ompi_datatype_get_single_predefined_type_from_args( ompi_datatype_t* type )
826 {
827 ompi_datatype_t *predef = NULL, *current_type, *current_predef;
828 ompi_datatype_args_t* args = (ompi_datatype_args_t*)type->args;
829 int i;
830
831 if( ompi_datatype_is_predefined(type) )
832 return type;
833
834 for( i = 0; i < args->cd; i++ ) {
835 current_type = args->d[i];
836 if( ompi_datatype_is_predefined(current_type) ) {
837 current_predef = current_type;
838 } else {
839 current_predef = ompi_datatype_get_single_predefined_type_from_args(current_type);
840 if( NULL == current_predef ) {
841 return NULL;
842 }
843 }
844 if( NULL == predef ) {
845 predef = current_predef;
846 } else {
847
848
849
850
851
852
853 if( predef != current_predef ) {
854 return NULL;
855 }
856 }
857 }
858 return predef;
859 }