root/opal/datatype/opal_copy_functions.c

/* [<][>][^][v][top][bottom][index][help] */
   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) 2015-2018 Research Organization for Information Science
   8  *                         and Technology (RIST).  All rights reserved.
   9  * Copyright (c) 2015      Cisco Systems, Inc.  All rights reserved.
  10  * Copyright (c) 2018      FUJITSU LIMITED.  All rights reserved.
  11  * $COPYRIGHT$
  12  *
  13  * Additional copyrights may follow
  14  *
  15  * $HEADER$
  16  */
  17 
  18 #include "opal_config.h"
  19 
  20 #include <stddef.h>
  21 
  22 #include "opal/datatype/opal_datatype.h"
  23 #include "opal/datatype/opal_convertor.h"
  24 #include "opal/datatype/opal_datatype_internal.h"
  25 #include "opal/datatype/opal_datatype_checksum.h"
  26 #include "opal/datatype/opal_convertor_internal.h"
  27 
  28 /*
  29  * This function is used to copy data from one buffer to another.  The assumption
  30  *     is that the number of bytes per element to copy at the source and destination
  31  *     are the same.
  32  *   count - number of instances of a given data-type to copy
  33  *   from - point to the source buffer
  34  *   to - pointer to the destination buffer
  35  *   from_len - length of source buffer (in bytes)
  36  *   to_len - length of destination buffer (in bytes)
  37  *   from_extent - extent of the source data type (in bytes)
  38  *   to_extent - extent of the destination data type (in bytes)
  39  *
  40  * Return value: Number of elements of type TYPE copied
  41  */
  42 #define COPY_TYPE( TYPENAME, TYPE, COUNT )                                              \
  43 static int copy_##TYPENAME( opal_convertor_t *pConvertor, size_t count,                 \
  44                             char* from, size_t from_len, ptrdiff_t from_extent,         \
  45                             char* to, size_t to_len, ptrdiff_t to_extent,               \
  46                             ptrdiff_t *advance)                                         \
  47 {                                                                                       \
  48     size_t remote_TYPE_size = sizeof(TYPE) * (COUNT); /* TODO */                        \
  49     size_t local_TYPE_size = (COUNT) * sizeof(TYPE);                                    \
  50                                                                                         \
  51     /* make sure the remote buffer is large enough to hold the data */                  \
  52     if( (remote_TYPE_size * count) > from_len ) {                                       \
  53         count = from_len / remote_TYPE_size;                                            \
  54         if( (count * remote_TYPE_size) != from_len ) {                                  \
  55             DUMP( "oops should I keep this data somewhere (excedent %d bytes)?\n",      \
  56                   from_len - (count * remote_TYPE_size) );                              \
  57         }                                                                               \
  58         DUMP( "correct: copy %s count %d from buffer %p with length %d to %p space %d\n", \
  59               #TYPE, count, from, from_len, to, to_len );                               \
  60     } else                                                                              \
  61         DUMP( "         copy %s count %d from buffer %p with length %d to %p space %d\n", \
  62               #TYPE, count, from, from_len, to, to_len );                               \
  63                                                                                         \
  64     if( (from_extent == (ptrdiff_t)local_TYPE_size) &&                          \
  65         (to_extent == (ptrdiff_t)remote_TYPE_size) ) {                          \
  66         /* copy of contigous data at both source and destination */                     \
  67         MEMCPY( to, from, count * local_TYPE_size );                                    \
  68     } else {                                                                            \
  69         /* source or destination are non-contigous */                                   \
  70         for(size_t i = 0; i < count; i++ ) {                                            \
  71             MEMCPY( to, from, local_TYPE_size );                                        \
  72             to += to_extent;                                                            \
  73             from += from_extent;                                                        \
  74         }                                                                               \
  75     }                                                                                   \
  76     *advance = count * from_extent;                                                     \
  77     return count;                                                                       \
  78 }
  79 
  80 /*
  81  * This function is used to copy data from one buffer to another.  The assumption
  82  *     is that the number of bytes per element to copy at the source and destination
  83  *     are the same.
  84  *   count - number of instances of a given data-type to copy
  85  *   from - point to the source buffer
  86  *   to - pointer to the destination buffer
  87  *   from_len - length of source buffer (in bytes)
  88  *   to_len - length of destination buffer (in bytes)
  89  *   from_extent - extent of the source data type (in bytes)
  90  *   to_extent - extent of the destination data type (in bytes)
  91  *
  92  * Return value: Number of elements of type TYPE copied
  93  */
  94 #define COPY_CONTIGUOUS_BYTES( TYPENAME, COUNT )                                          \
  95 static size_t copy_##TYPENAME##_##COUNT( opal_convertor_t *pConvertor, size_t count,         \
  96                                          char* from, size_t from_len, ptrdiff_t from_extent, \
  97                                          char* to, size_t to_len, ptrdiff_t to_extent,       \
  98                                          ptrdiff_t *advance )              \
  99 {                                                                               \
 100     size_t remote_TYPE_size = (size_t)(COUNT); /* TODO */                       \
 101     size_t local_TYPE_size = (size_t)(COUNT);                                   \
 102                                                                                 \
 103     if( (remote_TYPE_size * count) > from_len ) {                               \
 104         count = from_len / remote_TYPE_size;                                    \
 105         if( (count * remote_TYPE_size) != from_len ) {                          \
 106             DUMP( "oops should I keep this data somewhere (excedent %d bytes)?\n", \
 107                   from_len - (count * remote_TYPE_size) );                      \
 108         }                                                                       \
 109         DUMP( "correct: copy %s count %d from buffer %p with length %d to %p space %d\n", \
 110               #TYPENAME, count, from, from_len, to, to_len );                   \
 111     } else                                                                      \
 112         DUMP( "         copy %s count %d from buffer %p with length %d to %p space %d\n", \
 113               #TYPENAME, count, from, from_len, to, to_len );                   \
 114                                                                                 \
 115     if( (from_extent == (ptrdiff_t)local_TYPE_size) &&                  \
 116         (to_extent == (ptrdiff_t)remote_TYPE_size) ) {                  \
 117         MEMCPY( to, from, count * local_TYPE_size );                            \
 118     } else {                                                                    \
 119         for(size_t i = 0; i < count; i++ ) {                                    \
 120             MEMCPY( to, from, local_TYPE_size );                                \
 121             to += to_extent;                                                    \
 122             from += from_extent;                                                \
 123         }                                                                       \
 124     }                                                                           \
 125     *advance = count * from_extent;                                             \
 126     return count;                                                               \
 127 }
 128 
 129 /* set up copy functions for the basic C MPI data types */
 130 /* per default, select all of them */
 131 #define REQUIRE_COPY_BYTES_1 1
 132 #define REQUIRE_COPY_BYTES_2 1
 133 #define REQUIRE_COPY_BYTES_4 1
 134 #define REQUIRE_COPY_BYTES_8 1
 135 #define REQUIRE_COPY_BYTES_16 1
 136 
 137 #if REQUIRE_COPY_BYTES_1
 138 COPY_CONTIGUOUS_BYTES( bytes, 1 )
 139 #endif
 140 #if REQUIRE_COPY_BYTES_2
 141 COPY_CONTIGUOUS_BYTES( bytes, 2 )
 142 #endif
 143 #if REQUIRE_COPY_BYTES_4
 144 COPY_CONTIGUOUS_BYTES( bytes, 4 )
 145 #endif
 146 #if REQUIRE_COPY_BYTES_8
 147 COPY_CONTIGUOUS_BYTES( bytes, 8 )
 148 #endif
 149 #if REQUIRE_COPY_BYTES_16
 150 COPY_CONTIGUOUS_BYTES( bytes, 16 )
 151 #endif
 152 
 153 #if defined(HAVE_SHORT_FLOAT) && SIZEOF_SHORT_FLOAT == 2
 154 COPY_TYPE( float_2, short float, 1 )
 155 #elif SIZEOF_FLOAT == 2
 156 COPY_TYPE( float_2, float, 1 )
 157 #elif SIZEOF_DOUBLE == 2
 158 COPY_TYPE( float_2, double, 1 )
 159 #elif SIZEOF_LONG_DOUBLE == 2
 160 COPY_TYPE( float_2, long double, 1 )
 161 #elif defined(HAVE_OPAL_SHORT_FLOAT_T) && SIZEOF_OPAL_SHORT_FLOAT_T == 2
 162 COPY_TYPE( float_2, opal_short_float_t, 1 )
 163 #else
 164 /* #error No basic type for copy function for opal_datatype_float2 found */
 165 #define copy_float_2 NULL
 166 #endif
 167 
 168 #if defined(HAVE_SHORT_FLOAT) && SIZEOF_SHORT_FLOAT == 4
 169 COPY_TYPE( float_4, short float, 1 )
 170 #elif SIZEOF_FLOAT == 4
 171 COPY_TYPE( float_4, float, 1 )
 172 #elif SIZEOF_DOUBLE == 4
 173 COPY_TYPE( float_4, double, 1 )
 174 #elif SIZEOF_LONG_DOUBLE == 4
 175 COPY_TYPE( float_4, long double, 1 )
 176 #elif defined(HAVE_OPAL_SHORT_FLOAT_T) && SIZEOF_OPAL_SHORT_FLOAT_T == 4
 177 COPY_TYPE( float_4, opal_short_float_t, 1 )
 178 #else
 179 #error No basic type for copy function for opal_datatype_float4 found
 180 #endif
 181 
 182 #if defined(HAVE_SHORT_FLOAT) && SIZEOF_SHORT_FLOAT == 8
 183 COPY_TYPE( float_8, short float, 1 )
 184 #elif SIZEOF_FLOAT == 8
 185 COPY_TYPE( float_8, float, 1 )
 186 #elif SIZEOF_DOUBLE == 8
 187 COPY_TYPE( float_8, double, 1 )
 188 #elif SIZEOF_LONG_DOUBLE == 8
 189 COPY_TYPE( float_8, long double, 1 )
 190 #elif defined(HAVE_OPAL_SHORT_FLOAT_T) && SIZEOF_OPAL_SHORT_FLOAT_T == 8
 191 COPY_TYPE( float_8, opal_short_float_t, 1 )
 192 #else
 193 #error No basic type for copy function for opal_datatype_float8 found
 194 #endif
 195 
 196 #if defined(HAVE_SHORT_FLOAT) && SIZEOF_SHORT_FLOAT == 12
 197 COPY_TYPE( float_12, short float, 1 )
 198 #elif SIZEOF_FLOAT == 12
 199 COPY_TYPE( float_12, float, 1 )
 200 #elif SIZEOF_DOUBLE == 12
 201 COPY_TYPE( float_12, double, 1 )
 202 #elif SIZEOF_LONG_DOUBLE == 12
 203 COPY_TYPE( float_12, long double, 1 )
 204 #elif defined(HAVE_OPAL_SHORT_FLOAT_T) && SIZEOF_OPAL_SHORT_FLOAT_T == 12
 205 COPY_TYPE( float_12, opal_short_float_t, 1 )
 206 #else
 207 /* #error No basic type for copy function for opal_datatype_float12 found */
 208 #define copy_float_12 NULL
 209 #endif
 210 
 211 #if defined(HAVE_SHORT_FLOAT) && SIZEOF_SHORT_FLOAT == 16
 212 COPY_TYPE( float_16, short float, 1 )
 213 #elif SIZEOF_FLOAT == 16
 214 COPY_TYPE( float_16, float, 1 )
 215 #elif SIZEOF_DOUBLE == 16
 216 COPY_TYPE( float_16, double, 1 )
 217 #elif SIZEOF_LONG_DOUBLE == 16
 218 COPY_TYPE( float_16, long double, 1 )
 219 #elif defined(HAVE_OPAL_SHORT_FLOAT_T) && SIZEOF_OPAL_SHORT_FLOAT_T == 16
 220 COPY_TYPE( float_16, opal_short_float_t, 1 )
 221 #else
 222 /* #error No basic type for copy function for opal_datatype_float16 found */
 223 #define copy_float_16 NULL
 224 #endif
 225 
 226 #if defined(HAVE_SHORT_FLOAT__COMPLEX)
 227 COPY_TYPE ( short_float_complex, short float _Complex, 1)
 228 #elif defined(HAVE_OPAL_SHORT_FLOAT_COMPLEX_T)
 229 COPY_TYPE ( short_float_complex, opal_short_float_complex_t, 1)
 230 #else
 231 /* #error No basic type for copy function for opal_datatype_short_float_complex found */
 232 #define copy_short_float_complex NULL
 233 #endif
 234 
 235 COPY_TYPE ( float_complex, float _Complex, 1)
 236 
 237 COPY_TYPE ( double_complex, double _Complex, 1)
 238 
 239 COPY_TYPE ( long_double_complex, long double _Complex, 1)
 240 
 241 #if SIZEOF__BOOL == SIZEOF_CHAR
 242 COPY_TYPE (bool, char, 1)
 243 #elif SIZEOF__BOOL == SIZEOF_SHORT
 244 COPY_TYPE (bool, short, 1)
 245 #elif SIZEOF__BOOL == SIZEOF_INT
 246 COPY_TYPE (bool, int, 1)
 247 #elif SIZEOF__BOOL == SIZEOF_LONG
 248 COPY_TYPE (bool, long, 1)
 249 #else
 250 #error No basic type for copy function for opal_datatype_bool found
 251 #endif
 252 
 253 COPY_TYPE (wchar, wchar_t, 1)
 254 
 255 
 256 /* Table of predefined copy functions - one for each OPAL type */
 257 /* NOTE: The order of this array *MUST* match the order in opal_datatype_basicDatatypes */
 258 conversion_fct_t opal_datatype_copy_functions[OPAL_DATATYPE_MAX_PREDEFINED] = {
 259     (conversion_fct_t)NULL,                      /* OPAL_DATATYPE_LOOP         */
 260     (conversion_fct_t)NULL,                      /* OPAL_DATATYPE_END_LOOP     */
 261     (conversion_fct_t)NULL,                      /* OPAL_DATATYPE_LB           */
 262     (conversion_fct_t)NULL,                      /* OPAL_DATATYPE_UB           */
 263     (conversion_fct_t)copy_bytes_1,              /* OPAL_DATATYPE_INT1         */
 264     (conversion_fct_t)copy_bytes_2,              /* OPAL_DATATYPE_INT2         */
 265     (conversion_fct_t)copy_bytes_4,              /* OPAL_DATATYPE_INT4         */
 266     (conversion_fct_t)copy_bytes_8,              /* OPAL_DATATYPE_INT8         */
 267     (conversion_fct_t)copy_bytes_16,             /* OPAL_DATATYPE_INT16        */
 268     (conversion_fct_t)copy_bytes_1,              /* OPAL_DATATYPE_UINT1        */
 269     (conversion_fct_t)copy_bytes_2,              /* OPAL_DATATYPE_UINT2        */
 270     (conversion_fct_t)copy_bytes_4,              /* OPAL_DATATYPE_UINT4        */
 271     (conversion_fct_t)copy_bytes_8,              /* OPAL_DATATYPE_UINT8        */
 272     (conversion_fct_t)copy_bytes_16,             /* OPAL_DATATYPE_UINT16       */
 273     (conversion_fct_t)copy_float_2,              /* OPAL_DATATYPE_FLOAT2       */
 274     (conversion_fct_t)copy_float_4,              /* OPAL_DATATYPE_FLOAT4       */
 275     (conversion_fct_t)copy_float_8,              /* OPAL_DATATYPE_FLOAT8       */
 276     (conversion_fct_t)copy_float_12,             /* OPAL_DATATYPE_FLOAT12       */
 277     (conversion_fct_t)copy_float_16,             /* OPAL_DATATYPE_FLOAT16      */
 278     (conversion_fct_t)copy_short_float_complex,  /* OPAL_DATATYPE_SHORT_FLOAT_COMPLEX */
 279     (conversion_fct_t)copy_float_complex,        /* OPAL_DATATYPE_FLOAT_COMPLEX */
 280     (conversion_fct_t)copy_double_complex,       /* OPAL_DATATYPE_DOUBLE_COMPLEX */
 281     (conversion_fct_t)copy_long_double_complex,  /* OPAL_DATATYPE_LONG_DOUBLE_COMPLEX */
 282     (conversion_fct_t)copy_bool,                 /* OPAL_DATATYPE_BOOL         */
 283     (conversion_fct_t)copy_wchar,                /* OPAL_DATATYPE_WCHAR        */
 284     (conversion_fct_t)NULL                       /* OPAL_DATATYPE_UNAVAILABLE  */
 285 };

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