changing library to version 1.1.2
[openmpi-llc.git] / ompi / datatype / get_count.c
blob8eccd6f29096aa20cedfc4cb90345d3f53e379e2
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 * Copyright (c) 2004-2006 The University of Tennessee and The University
4 * of Tennessee Research Foundation. All rights
5 * reserved.
6 * $COPYRIGHT$
8 * Additional copyrights may follow
10 * $HEADER$
13 #include "ompi_config.h"
14 #include "ompi/datatype/datatype.h"
15 #include "ompi/datatype/convertor.h"
16 #include "ompi/datatype/datatype_internal.h"
18 #ifdef HAVE_ALLOCA_H
19 #include <alloca.h>
20 #endif
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.
26 * Return value:
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 */
34 int rc, nbElems = 0;
35 int stack_pos = 0;
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) );
44 pStack->count = 1;
45 pStack->index = -1;
46 pStack->disp = 0;
47 pElems = datatype->desc.desc;
48 pStack->end_loop = datatype->desc.used;
49 pos_desc = 0;
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 */
54 stack_pos--;
55 pStack--;
56 if( stack_pos == -1 )
57 return nbElems; /* completed */
59 if( pStack->index == -1 ) {
60 pStack->disp += (datatype->ub - datatype->lb);
61 } else {
62 assert( DT_LOOP == pElems[pStack->index].elem.common.type );
63 pStack->disp += pElems[pStack->index].loop.extent;
65 pos_desc = pStack->index + 1;
66 continue;
68 if( DT_LOOP == pElems[pos_desc].elem.common.type ) {
69 ddt_loop_desc_t* loop = &(pElems[pos_desc].loop);
70 do {
71 PUSH_STACK( pStack, stack_pos, pos_desc, DT_LOOP, loop->loops,
72 0, pos_desc + loop->items );
73 pos_desc++;
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" );
76 continue;
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;
82 if( rc >= iSize ) {
83 rc = iSize / basic_type->size;
84 nbElems += rc;
85 iSize -= rc * basic_type->size;
86 return (iSize == 0 ? nbElems : -1);
88 nbElems += pElems[pos_desc].elem.count;
89 iSize -= rc;
90 pos_desc++; /* advance to the next data */