1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
3 * Copyright (c) 2004-2006 The University of Tennessee and The University
4 * of Tennessee Research Foundation. All rights
8 * Additional copyrights may follow
13 #include "ompi_config.h"
14 #include "ompi/datatype/datatype.h"
15 #include "ompi/datatype/convertor.h"
16 #include "ompi/datatype/datatype_internal.h"
22 /* Get the number of elements from the data-type that can be
23 * retrieved from a received buffer with the size iSize.
24 * To speed-up this function you should use it with a iSize == to the modulo
25 * of the original size and the size of the data.
27 * positive = number of basic elements inside
28 * negative = some error occurs
30 int32_t ompi_ddt_get_element_count( const ompi_datatype_t
* datatype
, int32_t iSize
)
32 dt_stack_t
* pStack
; /* pointer to the position on the stack */
33 uint32_t pos_desc
; /* actual position in the description of the derived datatype */
36 dt_elem_desc_t
* pElems
;
38 /* Normally the size should be less or equal to the size of the datatype.
39 * This function does not support a iSize bigger than the size of the datatype.
41 assert( (uint32_t)iSize
<= datatype
->size
);
42 DUMP( "dt_count_elements( %p, %d )\n", (void*)datatype
, iSize
);
43 pStack
= alloca( sizeof(dt_stack_t
) * (datatype
->btypes
[DT_LOOP
] + 2) );
47 pElems
= datatype
->desc
.desc
;
48 pStack
->end_loop
= datatype
->desc
.used
;
51 while( 1 ) { /* loop forever the exit condition is on the last DT_END_LOOP */
52 if( DT_END_LOOP
== pElems
[pos_desc
].elem
.common
.type
) { /* end of the current loop */
53 if( --(pStack
->count
) == 0 ) { /* end of loop */
57 return nbElems
; /* completed */
59 if( pStack
->index
== -1 ) {
60 pStack
->disp
+= (datatype
->ub
- datatype
->lb
);
62 assert( DT_LOOP
== pElems
[pStack
->index
].elem
.common
.type
);
63 pStack
->disp
+= pElems
[pStack
->index
].loop
.extent
;
65 pos_desc
= pStack
->index
+ 1;
68 if( DT_LOOP
== pElems
[pos_desc
].elem
.common
.type
) {
69 ddt_loop_desc_t
* loop
= &(pElems
[pos_desc
].loop
);
71 PUSH_STACK( pStack
, stack_pos
, pos_desc
, DT_LOOP
, loop
->loops
,
72 0, pos_desc
+ loop
->items
);
74 } while( DT_LOOP
== pElems
[pos_desc
].elem
.common
.type
); /* let's start another loop */
75 DDT_DUMP_STACK( pStack
, stack_pos
, pElems
, "advance loops" );
78 while( pElems
[pos_desc
].elem
.common
.flags
& DT_FLAG_DATA
) {
79 /* now here we have a basic datatype */
80 const ompi_datatype_t
* basic_type
= BASIC_DDT_FROM_ELEM(pElems
[pos_desc
]);
81 rc
= pElems
[pos_desc
].elem
.count
* basic_type
->size
;
83 rc
= iSize
/ basic_type
->size
;
85 iSize
-= rc
* basic_type
->size
;
86 return (iSize
== 0 ? nbElems
: -1);
88 nbElems
+= pElems
[pos_desc
].elem
.count
;
90 pos_desc
++; /* advance to the next data */