root/opal/datatype/opal_convertor_raw.c

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

DEFINITIONS

This source file includes following definitions.
  1. opal_convertor_raw

   1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
   2 /*
   3  * Copyright (c) 2004-2009 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 (c) 2013      Cisco Systems, Inc.  All rights reserved.
   8  * Copyright (c) 2017-2019 Research Organization for Information Science
   9  *                         and Technology (RIST).  All rights reserved.
  10  * $COPYRIGHT$
  11  *
  12  * Additional copyrights may follow
  13  *
  14  * $HEADER$
  15  */
  16 
  17 #include "opal_config.h"
  18 
  19 #include <stddef.h>
  20 
  21 #include "opal/datatype/opal_convertor_internal.h"
  22 #include "opal/datatype/opal_datatype_internal.h"
  23 #include "opal_stdint.h"
  24 
  25 #if OPAL_ENABLE_DEBUG
  26 #include "opal/util/output.h"
  27 
  28 #define DO_DEBUG(INST)  if( opal_pack_debug ) { INST }
  29 #else
  30 #define DO_DEBUG(INST)
  31 #endif /* OPAL_ENABLE_DEBUG */
  32 
  33 /**
  34  * This function always work in local representation. This means no representation
  35  * conversion (i.e. no heterogeneity) is taken into account, and that all
  36  * length we're working on are local.
  37  */
  38 int32_t
  39 opal_convertor_raw( opal_convertor_t* pConvertor,
  40                     struct iovec* iov, uint32_t* iov_count,
  41                     size_t* length )
  42 {
  43     const opal_datatype_t *pData = pConvertor->pDesc;
  44     dt_stack_t* pStack;       /* pointer to the position on the stack */
  45     uint32_t pos_desc;        /* actual position in the description of the derived datatype */
  46     size_t count_desc;        /* the number of items already done in the actual pos_desc */
  47     dt_elem_desc_t* description, *pElem;
  48     unsigned char *source_base;  /* origin of the data */
  49     size_t raw_data = 0;      /* sum of raw data lengths in the iov_len fields */
  50     uint32_t index = 0;       /* the iov index and a simple counter */
  51 
  52     assert( (*iov_count) > 0 );
  53     if( OPAL_LIKELY(pConvertor->flags & CONVERTOR_COMPLETED) ) {
  54         iov[0].iov_base = NULL;
  55         iov[0].iov_len  = 0;
  56         *iov_count      = 0;
  57         *length         = iov[0].iov_len;
  58         return 1;  /* We're still done */
  59     }
  60     if( OPAL_LIKELY(pConvertor->flags & CONVERTOR_NO_OP) ) {
  61         /* The convertor contain minimal informations, we only use the bConverted
  62          * to manage the conversion. This function work even after the convertor
  63          * was moved to a specific position.
  64          */
  65         opal_convertor_get_current_pointer( pConvertor, (void**)&iov[0].iov_base );
  66         iov[0].iov_len = pConvertor->local_size - pConvertor->bConverted;
  67         *length = iov[0].iov_len;
  68         pConvertor->bConverted = pConvertor->local_size;
  69         pConvertor->flags |= CONVERTOR_COMPLETED;
  70         *iov_count = 1;
  71         return 1;  /* we're done */
  72     }
  73 
  74     DO_DEBUG( opal_output( 0, "opal_convertor_raw( %p, {%p, %" PRIu32 "}, %"PRIsize_t " )\n", (void*)pConvertor,
  75                            (void*)iov, *iov_count, *length ); );
  76 
  77     description = pConvertor->use_desc->desc;
  78 
  79     /* For the first step we have to add both displacement to the source. After in the
  80      * main while loop we will set back the source_base to the correct value. This is
  81      * due to the fact that the convertor can stop in the middle of a data with a count
  82      */
  83     pStack = pConvertor->pStack + pConvertor->stack_pos;
  84     pos_desc     = pStack->index;
  85     source_base  = pConvertor->pBaseBuf + pStack->disp;
  86     count_desc   = pStack->count;
  87     pStack--;
  88     pConvertor->stack_pos--;
  89     pElem = &(description[pos_desc]);
  90     source_base += pStack->disp;
  91     DO_DEBUG( opal_output( 0, "raw start pos_desc %d count_desc %" PRIsize_t " disp %ld\n"
  92                            "stack_pos %d pos_desc %d count_desc %" PRIsize_t " disp %ld\n",
  93                            pos_desc, count_desc, (long)(source_base - pConvertor->pBaseBuf),
  94                            pConvertor->stack_pos, pStack->index, pStack->count, (long)pStack->disp ); );
  95     while( 1 ) {
  96         while( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
  97             size_t blength = opal_datatype_basicDatatypes[pElem->elem.common.type]->size;
  98             source_base += pElem->elem.disp;
  99             if( blength == (size_t)pElem->elem.extent ) { /* no resized data */
 100                 if( index < *iov_count ) {
 101                     blength *= count_desc;
 102                     /* now here we have a basic datatype */
 103                     OPAL_DATATYPE_SAFEGUARD_POINTER( source_base, blength, pConvertor->pBaseBuf,
 104                                                      pConvertor->pDesc, pConvertor->count );
 105                     DO_DEBUG( opal_output( 0, "raw 1. iov[%d] = {base %p, length %" PRIsize_t "}\n",
 106                                            index, (void*)source_base, blength ); );
 107                     iov[index].iov_base = (IOVBASE_TYPE *) source_base;
 108                     iov[index].iov_len  = blength;
 109                     source_base += blength;
 110                     raw_data += blength;
 111                     index++;
 112                     count_desc = 0;
 113                 }
 114             } else {
 115                 for(size_t i = count_desc; (i > 0) && (index < *iov_count); i--, index++ ) {
 116                     OPAL_DATATYPE_SAFEGUARD_POINTER( source_base, blength, pConvertor->pBaseBuf,
 117                                                      pConvertor->pDesc, pConvertor->count );
 118                     DO_DEBUG( opal_output( 0, "raw 2. iov[%d] = {base %p, length %" PRIsize_t "}\n",
 119                                            index, (void*)source_base, blength ); );
 120                     iov[index].iov_base = (IOVBASE_TYPE *) source_base;
 121                     iov[index].iov_len  = blength;
 122                     source_base += pElem->elem.extent;
 123                     raw_data += blength;
 124                     count_desc--;
 125                 }
 126             }
 127             source_base -= pElem->elem.disp;
 128             if( 0 == count_desc ) {  /* completed */
 129                 source_base = pConvertor->pBaseBuf + pStack->disp;
 130                 pos_desc++;  /* advance to the next data */
 131                 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
 132                 continue;
 133             }
 134             goto complete_loop;
 135         }
 136         if( OPAL_DATATYPE_END_LOOP == pElem->elem.common.type ) { /* end of the current loop */
 137             DO_DEBUG( opal_output( 0, "raw end_loop count %" PRIsize_t " stack_pos %d"
 138                                    " pos_desc %d disp %ld space %lu\n",
 139                                    pStack->count, pConvertor->stack_pos,
 140                                    pos_desc, (long)pStack->disp, (unsigned long)raw_data ); );
 141             if( --(pStack->count) == 0 ) { /* end of loop */
 142                 if( pConvertor->stack_pos == 0 ) {
 143                     /* we lie about the size of the next element in order to
 144                      * make sure we exit the main loop.
 145                      */
 146                     *iov_count = index;
 147                     goto complete_loop;  /* completed */
 148                 }
 149                 pConvertor->stack_pos--;
 150                 pStack--;
 151                 pos_desc++;
 152             } else {
 153                 pos_desc = pStack->index + 1;
 154                 if( pStack->index == -1 ) {
 155                     pStack->disp += (pData->ub - pData->lb);
 156                 } else {
 157                     assert( OPAL_DATATYPE_LOOP == description[pStack->index].loop.common.type );
 158                     pStack->disp += description[pStack->index].loop.extent;
 159                 }
 160             }
 161             source_base = pConvertor->pBaseBuf + pStack->disp;
 162             UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
 163             DO_DEBUG( opal_output( 0, "raw new_loop count %" PRIsize_t " stack_pos %d "
 164                                    "pos_desc %d disp %ld space %lu\n",
 165                                    pStack->count, pConvertor->stack_pos,
 166                                    pos_desc, (long)pStack->disp, (unsigned long)raw_data ); );
 167         }
 168         if( OPAL_DATATYPE_LOOP == pElem->elem.common.type ) {
 169             ptrdiff_t local_disp = (ptrdiff_t)source_base;
 170             ddt_endloop_desc_t* end_loop = (ddt_endloop_desc_t*)(pElem + pElem->loop.items);
 171 
 172             if( pElem->loop.common.flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
 173                 ptrdiff_t offset = end_loop->first_elem_disp;
 174                 source_base += offset;
 175                 for(size_t i = MIN(count_desc, *iov_count - index); i > 0; i--, index++ ) {
 176                     OPAL_DATATYPE_SAFEGUARD_POINTER( source_base, end_loop->size, pConvertor->pBaseBuf,
 177                                                      pConvertor->pDesc, pConvertor->count );
 178                     iov[index].iov_base = (IOVBASE_TYPE *) source_base;
 179                     iov[index].iov_len  = end_loop->size;
 180                     source_base += pElem->loop.extent;
 181                     raw_data += end_loop->size;
 182                     count_desc--;
 183                     DO_DEBUG( opal_output( 0, "raw contig loop generate iov[%d] = {base %p, length %" PRIsize_t "}"
 184                                            "space %lu [pos_desc %d]\n",
 185                                            index, iov[index].iov_base, iov[index].iov_len,
 186                                            (unsigned long)raw_data, pos_desc ); );
 187                 }
 188                 source_base -= offset;
 189                 if( 0 == count_desc ) {  /* completed */
 190                     pos_desc += pElem->loop.items + 1;
 191                     goto update_loop_description;
 192                 }
 193             }
 194             if( index == *iov_count ) {  /* all iov have been filled, we need to bail out */
 195                 goto complete_loop;
 196             }
 197             local_disp = (ptrdiff_t)source_base - local_disp;
 198             PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, OPAL_DATATYPE_LOOP, count_desc,
 199                         pStack->disp + local_disp);
 200             pos_desc++;
 201         update_loop_description:  /* update the current state */
 202             source_base = pConvertor->pBaseBuf + pStack->disp;
 203             UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
 204             DDT_DUMP_STACK( pConvertor->pStack, pConvertor->stack_pos, pElem, "advance loop" );
 205             continue;
 206         }
 207     }
 208  complete_loop:
 209     pConvertor->bConverted += raw_data;  /* update the already converted bytes */
 210     *length = raw_data;
 211     *iov_count = index;
 212     if( pConvertor->bConverted == pConvertor->local_size ) {
 213         pConvertor->flags |= CONVERTOR_COMPLETED;
 214         return 1;
 215     }
 216     /* I complete an element, next step I should go to the next one */
 217     PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, OPAL_DATATYPE_UINT1, count_desc,
 218                 source_base - pStack->disp - pConvertor->pBaseBuf );
 219     DO_DEBUG( opal_output( 0, "raw save stack stack_pos %d pos_desc %d count_desc %" PRIsize_t " disp %ld\n",
 220                            pConvertor->stack_pos, pStack->index, pStack->count, (long)pStack->disp ); );
 221     return 0;
 222 }

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