root/opal/datatype/opal_datatype_fake_stack.c

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

DEFINITIONS

This source file includes following definitions.
  1. opal_convertor_create_stack_with_pos_general

   1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
   2 /*
   3  * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2017 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2017 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2006 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2009      Oak Ridge National Labs.  All rights reserved.
  14  * Copyright (c) 2017-2018 Research Organization for Information Science
  15  *                         and Technology (RIST).  All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 #include "opal_config.h"
  24 
  25 #include <stddef.h>
  26 #include <stdlib.h>
  27 
  28 #ifdef HAVE_ALLOCA_H
  29 #include <alloca.h>
  30 #endif
  31 
  32 #include "opal/datatype/opal_datatype.h"
  33 #include "opal/datatype/opal_convertor.h"
  34 #include "opal/datatype/opal_datatype_internal.h"
  35 
  36 
  37 extern int opal_convertor_create_stack_with_pos_general( opal_convertor_t* convertor,
  38                                                          size_t starting_point, const size_t* sizes );
  39 
  40 int opal_convertor_create_stack_with_pos_general( opal_convertor_t* pConvertor,
  41                                                   size_t starting_point, const size_t* sizes )
  42 {
  43     dt_stack_t* pStack;   /* pointer to the position on the stack */
  44     int pos_desc;         /* actual position in the description of the derived datatype */
  45     size_t lastLength = 0;
  46     const opal_datatype_t* pData = pConvertor->pDesc;
  47         size_t loop_length, *remoteLength, remote_size;
  48     size_t resting_place = starting_point;
  49     dt_elem_desc_t* pElems;
  50     size_t count;
  51 
  52     assert( 0 != starting_point );
  53     assert( pConvertor->bConverted != starting_point );
  54     assert( starting_point <=(pConvertor->count * pData->size) );
  55 
  56     /*opal_output( 0, "Data extent %d size %d count %d total_size %d starting_point %d\n",
  57                  pData->ub - pData->lb, pData->size, pConvertor->count,
  58                  pConvertor->local_size, starting_point );*/
  59     pConvertor->stack_pos = 0;
  60     pStack = pConvertor->pStack;
  61     /* Fill the first position on the stack. This one correspond to the
  62      * last fake OPAL_DATATYPE_END_LOOP that we add to the data representation and
  63      * allow us to move quickly inside the datatype when we have a count.
  64      */
  65     pElems = pConvertor->use_desc->desc;
  66 
  67     if( (pConvertor->flags & CONVERTOR_HOMOGENEOUS) && (pData->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS) ) {
  68         /* Special case for contiguous datatypes */
  69         int32_t cnt = (int32_t)(starting_point / pData->size);
  70         ptrdiff_t extent = pData->ub - pData->lb;
  71 
  72         loop_length = GET_FIRST_NON_LOOP( pElems );
  73         pStack[0].disp  = pElems[loop_length].elem.disp;
  74         pStack[0].type  = OPAL_DATATYPE_LOOP;
  75         pStack[0].count = pConvertor->count - cnt;
  76         cnt = (int32_t)(starting_point - cnt * pData->size);  /* number of bytes after the loop */
  77         pStack[1].index    = 0;
  78         pStack[1].type     = OPAL_DATATYPE_UINT1;
  79         pStack[1].disp     = pStack[0].disp;
  80         pStack[1].count    = pData->size - cnt;
  81 
  82         if( (ptrdiff_t)pData->size == extent ) { /* all elements are contiguous */
  83             pStack[1].disp += starting_point;
  84         } else {  /* each is contiguous but there are gaps inbetween */
  85             pStack[1].disp += (pConvertor->count - pStack[0].count) * extent + cnt;
  86         }
  87 
  88         pConvertor->bConverted = starting_point;
  89         pConvertor->stack_pos = 1;
  90         return OPAL_SUCCESS;
  91     }
  92 
  93     /* remove from the main loop all the complete datatypes */
  94     assert (! (pConvertor->flags & CONVERTOR_SEND));
  95     remote_size    = opal_convertor_compute_remote_size( pConvertor );
  96     count          = starting_point / remote_size;
  97     resting_place -= (remote_size * count);
  98     pStack->count  = pConvertor->count - count;
  99     pStack->index  = -1;
 100 
 101     loop_length = GET_FIRST_NON_LOOP( pElems );
 102     pStack->disp = count * (pData->ub - pData->lb) + pElems[loop_length].elem.disp;
 103 
 104     pos_desc  = 0;
 105     remoteLength = (size_t*)alloca( sizeof(size_t) * (pConvertor->pDesc->loops + 1));
 106     remoteLength[0] = 0;  /* initial value set to ZERO */
 107     loop_length = 0;
 108 
 109     /* The only way to get out of this loop is when we reach the desired position or
 110      * when we finish the whole datatype.
 111      */
 112     while( pos_desc < (int32_t)pConvertor->use_desc->used ) {
 113         if( OPAL_DATATYPE_END_LOOP == pElems->elem.common.type ) { /* end of the current loop */
 114             ddt_endloop_desc_t* end_loop = (ddt_endloop_desc_t*)pElems;
 115             ptrdiff_t extent;
 116 
 117             if( (loop_length * pStack->count) > resting_place ) {
 118                 /* We will stop somewhere on this loop. To avoid moving inside the loop
 119                  * multiple times, we can compute the index of the loop where we will
 120                  * stop. Once this index is computed we can then reparse the loop once
 121                  * until we find the correct position.
 122                  */
 123                 int32_t cnt = (int32_t)(resting_place / loop_length);
 124                 if( pStack->index == -1 ) {
 125                     extent = pData->ub - pData->lb;
 126                 } else {
 127                     assert( OPAL_DATATYPE_LOOP == (pElems - end_loop->items)->loop.common.type );
 128                     extent = ((ddt_loop_desc_t*)(pElems - end_loop->items))->extent;
 129                 }
 130                 pStack->count -= (cnt + 1);
 131                 resting_place -= cnt * loop_length;
 132                 pStack->disp += (cnt + 1) * extent;
 133                 /* reset the remoteLength as we act as restarting the last loop */
 134                 pos_desc -= (end_loop->items - 1);  /* go back to the first element in the loop */
 135                 pElems -= (end_loop->items - 1);
 136                 remoteLength[pConvertor->stack_pos] = 0;
 137                 loop_length = 0;
 138                 continue;
 139             }
 140             /* Not in this loop. Cleanup the stack and advance to the
 141              * next data description.
 142              */
 143             resting_place -= (loop_length * (pStack->count - 1));  /* update the resting place */
 144             pStack--;
 145             pConvertor->stack_pos--;
 146             pos_desc++;
 147             pElems++;
 148             remoteLength[pConvertor->stack_pos] += (loop_length * pStack->count);
 149             loop_length = remoteLength[pConvertor->stack_pos];
 150             continue;
 151         }
 152         if( OPAL_DATATYPE_LOOP == pElems->elem.common.type ) {
 153             remoteLength[pConvertor->stack_pos] += loop_length;
 154             PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, OPAL_DATATYPE_LOOP,
 155                                         pElems->loop.loops, pStack->disp );
 156             pos_desc++;
 157             pElems++;
 158             remoteLength[pConvertor->stack_pos] = 0;
 159             loop_length = 0;  /* starting a new loop */
 160         }
 161         while( pElems->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
 162             /* now here we have a basic datatype */
 163             const opal_datatype_t* basic_type = BASIC_DDT_FROM_ELEM( (*pElems) );
 164             lastLength = pElems->elem.count * basic_type->size;
 165             if( resting_place < lastLength ) {
 166                 int32_t cnt = (int32_t)(resting_place / basic_type->size);
 167                 loop_length += (cnt * basic_type->size);
 168                 resting_place -= (cnt * basic_type->size);
 169                 PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, pElems->elem.common.type,
 170                             pElems->elem.count - cnt,
 171                             pElems->elem.disp + cnt * pElems->elem.extent );
 172                 pConvertor->bConverted = starting_point - resting_place;
 173                 DDT_DUMP_STACK( pConvertor->pStack, pConvertor->stack_pos,
 174                                 pConvertor->pDesc->desc.desc, pConvertor->pDesc->name );
 175                 return OPAL_SUCCESS;
 176             }
 177             loop_length += lastLength;
 178             resting_place -= lastLength;
 179             pos_desc++;  /* advance to the next data */
 180             pElems++;
 181         }
 182     }
 183 
 184     /* Correctly update the bConverted field */
 185     pConvertor->flags |= CONVERTOR_COMPLETED;
 186     pConvertor->bConverted = pConvertor->local_size;
 187     return OPAL_SUCCESS;
 188 }

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