root/ompi/datatype/ompi_datatype_create_subarray.c

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

DEFINITIONS

This source file includes following definitions.
  1. ompi_datatype_create_subarray

   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-2016 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2006 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      Sun Microsystems, Inc. All rights reserved.
  14  * Copyright (c) 2009      Oak Ridge National Labs.  All rights reserved.
  15  * Copyright (c) 2010      Cisco Systems, Inc.  All rights reserved.
  16  * Copyright (c) 2014-2015 Research Organization for Information Science
  17  *                         and Technology (RIST). All rights reserved.
  18  * $COPYRIGHT$
  19  *
  20  * Additional copyrights may follow
  21  *
  22  * $HEADER$
  23  */
  24 
  25 #include "ompi_config.h"
  26 
  27 #include <stddef.h>
  28 
  29 #include "ompi/datatype/ompi_datatype.h"
  30 
  31 int32_t ompi_datatype_create_subarray(int ndims,
  32                                       int const* size_array,
  33                                       int const* subsize_array,
  34                                       int const* start_array,
  35                                       int order,
  36                                       const ompi_datatype_t* oldtype,
  37                                       ompi_datatype_t** newtype)
  38 {
  39     ompi_datatype_t *last_type;
  40     int32_t i, step, end_loop;
  41     MPI_Aint size, displ, extent;
  42 
  43     /**
  44      * If the oldtype contains the original MPI_LB and MPI_UB markers then we
  45      * are forced to follow the MPI standard suggestion and reset these 2
  46      * markers (MPI 3.0 page 96 line 37).  Otherwise we can simply resize the
  47      * datatype.
  48      */
  49     ompi_datatype_type_extent( oldtype, &extent );
  50 
  51     /* If the ndims is zero then return the NULL datatype */
  52     if( ndims < 2 ) {
  53         if( 0 == ndims ) {
  54             ompi_datatype_duplicate(&ompi_mpi_datatype_null.dt, newtype);
  55             return MPI_SUCCESS;
  56         }
  57         ompi_datatype_create_contiguous( subsize_array[0], oldtype, &last_type );
  58         size = size_array[0];
  59         displ = start_array[0];
  60         goto replace_subarray_type;
  61     }
  62 
  63     if( MPI_ORDER_C == order ) {
  64         i = ndims - 1;
  65         step = -1;
  66         end_loop = -1;
  67     } else {
  68         i = 0;
  69         step = 1;
  70         end_loop = ndims;
  71     }
  72 
  73     /* As we know that the ndims is at least 1 we can start by creating the
  74      * first dimension data outside the loop, such that we dont have to create
  75      * a duplicate of the oldtype just to be able to free it.
  76      */
  77     ompi_datatype_create_vector( subsize_array[i+step], subsize_array[i], size_array[i],
  78                                  oldtype, newtype );
  79 
  80     last_type = *newtype;
  81     size = (MPI_Aint)size_array[i] * (MPI_Aint)size_array[i+step];
  82     displ = (MPI_Aint)start_array[i] + (MPI_Aint)start_array[i+step] * (MPI_Aint)size_array[i];
  83     for( i += 2 * step; i != end_loop; i += step ) {
  84         ompi_datatype_create_hvector( subsize_array[i], 1, size * extent,
  85                                       last_type, newtype );
  86         ompi_datatype_destroy( &last_type );
  87 
  88         displ += size * start_array[i];
  89         size *= size_array[i];
  90         last_type = *newtype;
  91     }
  92 
  93  replace_subarray_type:
  94     /**
  95       * We need to shift the content (useful data) of the datatype, so
  96       * we need to force the displacement to be moved. Therefore, we
  97       * cannot use resize as it will only set the soft lb and ub
  98       * markers without moving the data. Instead, we have to create a
  99       * new data, and insert the last_Type with the correct
 100       * displacement.
 101       */
 102     *newtype = ompi_datatype_create( last_type->super.desc.used );
 103     ompi_datatype_add( *newtype, last_type, 1, displ * extent, size * extent);
 104     ompi_datatype_destroy( &last_type );
 105     opal_datatype_resize( &(*newtype)->super, 0, size * extent );
 106 
 107     return OMPI_SUCCESS;
 108 }

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