root/opal/datatype/opal_datatype_get_count.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opal_datatype_get_element_count
  2. opal_datatype_set_element_count
  3. opal_datatype_compute_ptypes

   1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
   2 /*
   3  * Copyright (c) 2004-2018 The University of Tennessee and The University
   4  *                         of Tennessee Research Foundation.  All rights
   5  *                         reserved.
   6  * Copyright (c) 2009      Oak Ridge National Labs.  All rights reserved.
   7  * $COPYRIGHT$
   8  *
   9  * Additional copyrights may follow
  10  *
  11  * $HEADER$
  12  */
  13 
  14 #include "opal_config.h"
  15 #include "opal/datatype/opal_datatype.h"
  16 #include "opal/datatype/opal_convertor.h"
  17 #include "opal/datatype/opal_datatype_internal.h"
  18 
  19 #ifdef HAVE_ALLOCA_H
  20 #include <alloca.h>
  21 #endif
  22 
  23 /* Get the number of elements from the data-type that can be
  24  * retrieved from a received buffer with the size iSize.
  25  * To speed-up this function you should use it with a iSize == to the modulo
  26  * of the original size and the size of the data.
  27  * Return value:
  28  *   positive = number of basic elements inside
  29  *   negative = some error occurs
  30  */
  31 ssize_t opal_datatype_get_element_count( const opal_datatype_t* datatype, size_t iSize )
  32 {
  33     dt_stack_t* pStack;   /* pointer to the position on the stack */
  34     uint32_t pos_desc;    /* actual position in the description of the derived datatype */
  35     ssize_t nbElems = 0, stack_pos = 0;
  36     size_t local_size;
  37     dt_elem_desc_t* pElems;
  38 
  39     /* Normally the size should be less or equal to the size of the datatype.
  40      * This function does not support a iSize bigger than the size of the datatype.
  41      */
  42     assert( iSize <= datatype->size );
  43     DUMP( "dt_count_elements( %p, %ul )\n", (void*)datatype, (unsigned long)iSize );
  44     pStack = (dt_stack_t*)alloca( sizeof(dt_stack_t) * (datatype->loops + 2) );
  45     pStack->count    = 1;
  46     pStack->index    = -1;
  47     pStack->disp     = 0;
  48     pElems           = datatype->desc.desc;
  49     pos_desc         = 0;
  50 
  51     while( 1 ) {  /* loop forever the exit condition is on the last OPAL_DATATYPE_END_LOOP */
  52         if( OPAL_DATATYPE_END_LOOP == pElems[pos_desc].elem.common.type ) { /* end of the current loop */
  53             if( --(pStack->count) == 0 ) { /* end of loop */
  54                 stack_pos--; pStack--;
  55                 if( stack_pos == -1 ) return nbElems;  /* completed */
  56                 pos_desc++;  /* advance to the next element after the end loop */
  57             } else {
  58                 pos_desc = pStack->index + 1;  /* go back to the begining of the loop */
  59             }
  60             continue;
  61         }
  62         if( OPAL_DATATYPE_LOOP == pElems[pos_desc].elem.common.type ) {
  63             do {
  64                 PUSH_STACK( pStack, stack_pos, pos_desc, OPAL_DATATYPE_LOOP, pElems[pos_desc].loop.loops, 0 );
  65                 pos_desc++;
  66             } while( OPAL_DATATYPE_LOOP == pElems[pos_desc].elem.common.type ); /* let's start another loop */
  67             DDT_DUMP_STACK( pStack, stack_pos, pElems, "advance loops" );
  68         }
  69         while( pElems[pos_desc].elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
  70             /* now here we have a basic datatype */
  71             const opal_datatype_t* basic_type = BASIC_DDT_FROM_ELEM(pElems[pos_desc]);
  72             local_size = pElems[pos_desc].elem.count * basic_type->size;
  73             if( local_size >= iSize ) {
  74                 local_size = iSize / basic_type->size;
  75                 nbElems += (int32_t)local_size;
  76                 iSize -= local_size * basic_type->size;
  77                 return (iSize == 0 ? nbElems : -1);
  78             }
  79             nbElems += pElems[pos_desc].elem.count;
  80             iSize -= local_size;
  81             pos_desc++;  /* advance to the next data */
  82         }
  83     }
  84 }
  85 
  86 int32_t opal_datatype_set_element_count( const opal_datatype_t* datatype, size_t count, size_t* length )
  87 {
  88     dt_stack_t* pStack;   /* pointer to the position on the stack */
  89     size_t pos_desc;    /* actual position in the description of the derived datatype */
  90     int32_t stack_pos = 0;
  91     size_t local_length = 0;
  92     dt_elem_desc_t* pElems;
  93 
  94     /**
  95      * Handle all complete multiple of the datatype.
  96      */
  97     local_length = datatype->nbElems;
  98     pos_desc = count / local_length;
  99     count = count % local_length;
 100     *length = datatype->size * pos_desc;
 101     if( 0 == count ) {
 102         return 0;
 103     }
 104 
 105     DUMP( "dt_set_element_count( %p, %d )\n", (void*)datatype, count );
 106     pStack = (dt_stack_t*)alloca( sizeof(dt_stack_t) * (datatype->loops + 2) );
 107     pStack->count    = 1;
 108     pStack->index    = -1;
 109     pStack->disp     = 0;
 110     pElems           = datatype->desc.desc;
 111     pos_desc         = 0;
 112 
 113     while( 1 ) {  /* loop forever the exit condition is on the last OPAL_DATATYPE_END_LOOP */
 114         if( OPAL_DATATYPE_END_LOOP == pElems[pos_desc].elem.common.type ) { /* end of the current loop */
 115             if( --(pStack->count) == 0 ) { /* end of loop */
 116                 stack_pos--; pStack--;
 117                 if( stack_pos == -1 ) return 0;
 118                 pos_desc++;  /* advance to the next element after the end loop */
 119             } else {
 120                 pos_desc = pStack->index + 1;  /* go back to the begining of the loop */
 121             }
 122             continue;
 123         }
 124         if( OPAL_DATATYPE_LOOP == pElems[pos_desc].elem.common.type ) {
 125             do {
 126                 PUSH_STACK( pStack, stack_pos, pos_desc, OPAL_DATATYPE_LOOP, pElems[pos_desc].loop.loops, 0 );
 127                 pos_desc++;
 128             } while( OPAL_DATATYPE_LOOP == pElems[pos_desc].elem.common.type ); /* let's start another loop */
 129             DDT_DUMP_STACK( pStack, stack_pos, pElems, "advance loops" );
 130         }
 131         while( pElems[pos_desc].elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
 132             /* now here we have a basic datatype */
 133             const opal_datatype_t* basic_type = BASIC_DDT_FROM_ELEM(pElems[pos_desc]);
 134             local_length = pElems[pos_desc].elem.count;
 135             if( local_length >= count ) {
 136                 *length += count * basic_type->size;
 137                 return 0;
 138             }
 139             *length += local_length * basic_type->size;
 140             count -= local_length;
 141             pos_desc++;  /* advance to the next data */
 142         }
 143     }
 144 }
 145 
 146 /**
 147  * Compute the array of counts of the predefined datatypes contained in
 148  * the datatype. We have no simple way to create this array, as we only
 149  * sporadically need it (when we deal with heterogeneous environments or
 150  * when we use get_element_count). Thus, we will pay the cost once per
 151  * datatype, but we will only update this array if/when needed.
 152  */
 153 int opal_datatype_compute_ptypes( opal_datatype_t* datatype )
 154 {
 155     dt_stack_t* pStack;   /* pointer to the position on the stack */
 156     uint32_t pos_desc;    /* actual position in the description of the derived datatype */
 157     ssize_t nbElems = 0, stack_pos = 0;
 158     dt_elem_desc_t* pElems;
 159 
 160     if( NULL != datatype->ptypes ) return 0;
 161     datatype->ptypes = (size_t*)calloc(OPAL_DATATYPE_MAX_SUPPORTED, sizeof(size_t));
 162 
 163     DUMP( "opal_datatype_compute_ptypes( %p )\n", (void*)datatype );
 164     pStack = (dt_stack_t*)alloca( sizeof(dt_stack_t) * (datatype->loops + 2) );
 165     pStack->count    = 1;
 166     pStack->index    = -1;
 167     pStack->disp     = 0;
 168     pElems           = datatype->desc.desc;
 169     pos_desc         = 0;
 170 
 171     while( 1 ) {  /* loop forever the exit condition is on the last OPAL_DATATYPE_END_LOOP */
 172         if( OPAL_DATATYPE_END_LOOP == pElems[pos_desc].elem.common.type ) { /* end of the current loop */
 173             if( --(pStack->count) == 0 ) { /* end of loop */
 174                 stack_pos--; pStack--;
 175                 if( stack_pos == -1 ) return 0;  /* completed */
 176                 pos_desc++;  /* advance to the next element after the end loop */
 177             } else {
 178                 pos_desc = pStack->index + 1;  /* go back to the begining of the loop */
 179             }
 180             continue;
 181         }
 182         if( OPAL_DATATYPE_LOOP == pElems[pos_desc].elem.common.type ) {
 183             do {
 184                 PUSH_STACK( pStack, stack_pos, pos_desc, OPAL_DATATYPE_LOOP, pElems[pos_desc].loop.loops, 0 );
 185                 pos_desc++;
 186             } while( OPAL_DATATYPE_LOOP == pElems[pos_desc].elem.common.type ); /* let's start another loop */
 187             DDT_DUMP_STACK( pStack, stack_pos, pElems, "advance loops" );
 188         }
 189         while( pElems[pos_desc].elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
 190             /* now here we have a basic datatype */
 191             datatype->ptypes[pElems[pos_desc].elem.common.type] += pElems[pos_desc].elem.count;
 192             nbElems += pElems[pos_desc].elem.count;
 193 
 194             DUMP( "  compute_ptypes-add: type %d count %"PRIsize_t" (total type %"PRIsize_t" total %lld)\n",
 195                   pElems[pos_desc].elem.common.type, datatype->ptypes[pElems[pos_desc].elem.common.type],
 196                   pElems[pos_desc].elem.count, nbElems );
 197             pos_desc++;  /* advance to the next data */
 198         }
 199     }
 200 }

/* [<][>][^][v][top][bottom][index][help] */