root/ompi/datatype/ompi_datatype.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ompi_datatype_is_committed
  2. ompi_datatype_is_overlapped
  3. ompi_datatype_is_valid
  4. ompi_datatype_is_predefined
  5. ompi_datatype_is_contiguous_memory_layout
  6. ompi_datatype_is_monotonic
  7. ompi_datatype_commit
  8. ompi_datatype_add
  9. ompi_datatype_create_resized
  10. ompi_datatype_type_lb
  11. ompi_datatype_type_ub
  12. ompi_datatype_type_size
  13. ompi_datatype_type_extent
  14. ompi_datatype_get_extent
  15. ompi_datatype_get_true_extent
  16. ompi_datatype_get_element_count
  17. ompi_datatype_set_element_count
  18. ompi_datatype_copy_content_same_ddt

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2009-2013 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) 2010-2017 Cisco Systems, Inc.  All rights reserved
   8  * Copyright (c) 2013      Los Alamos National Security, LLC.  All rights
   9  *                         reserved.
  10  * Copyright (c) 2015-2018 Research Organization for Information Science
  11  *                         and Technology (RIST). All rights reserved.
  12  * Copyright (c) 2018      FUJITSU LIMITED.  All rights reserved.
  13  * $COPYRIGHT$
  14  *
  15  * Additional copyrights may follow
  16  *
  17  * $HEADER$
  18  */
  19 
  20 /**
  21  * ompi_datatype_t interface for OMPI internal data type representation
  22  *
  23  * ompi_datatype_t is a class which represents contiguous or
  24  * non-contiguous data together with constituent type-related
  25  * information.
  26  */
  27 
  28 #ifndef OMPI_DATATYPE_H_HAS_BEEN_INCLUDED
  29 #define OMPI_DATATYPE_H_HAS_BEEN_INCLUDED
  30 
  31 #include "ompi_config.h"
  32 
  33 #include <stddef.h>
  34 #include <stdint.h>
  35 #include <string.h>
  36 #include <limits.h>
  37 
  38 #include "ompi/constants.h"
  39 #include "opal/datatype/opal_convertor.h"
  40 #include "opal/util/output.h"
  41 #include "mpi.h"
  42 
  43 BEGIN_C_DECLS
  44 
  45 /* These flags are on top of the flags in opal_datatype.h */
  46 /* Is the datatype predefined as MPI type (not necessarily as OPAL type, e.g. struct/block types) */
  47 #define OMPI_DATATYPE_FLAG_PREDEFINED    0x0200
  48 #define OMPI_DATATYPE_FLAG_ANALYZED      0x0400
  49 #define OMPI_DATATYPE_FLAG_MONOTONIC     0x0800
  50 /* Keep trace of the type of the predefined datatypes */
  51 #define OMPI_DATATYPE_FLAG_DATA_INT      0x1000
  52 #define OMPI_DATATYPE_FLAG_DATA_FLOAT    0x2000
  53 #define OMPI_DATATYPE_FLAG_DATA_COMPLEX  0x3000
  54 #define OMPI_DATATYPE_FLAG_DATA_TYPE     0x3000
  55 /* In which language the datatype is intended for to be used */
  56 #define OMPI_DATATYPE_FLAG_DATA_C        0x4000
  57 #define OMPI_DATATYPE_FLAG_DATA_CPP      0x8000
  58 #define OMPI_DATATYPE_FLAG_DATA_FORTRAN  0xC000
  59 #define OMPI_DATATYPE_FLAG_DATA_LANGUAGE 0xC000
  60 
  61 #define OMPI_DATATYPE_MAX_PREDEFINED 50
  62 
  63 #if OMPI_DATATYPE_MAX_PREDEFINED > OPAL_DATATYPE_MAX_SUPPORTED
  64 #error Need to increase the number of supported dataypes by OPAL (value OPAL_DATATYPE_MAX_SUPPORTED).
  65 #endif
  66 
  67 
  68 /* the data description.
  69  */
  70 struct ompi_datatype_t {
  71     opal_datatype_t    super;                    /**< Base opal_datatype_t superclass */
  72     /* --- cacheline 5 boundary (320 bytes) was 32 bytes ago --- */
  73 
  74     int32_t            id;                       /**< OMPI-layers unique id of the type */
  75     int32_t            d_f_to_c_index;           /**< Fortran index for this datatype */
  76     struct opal_hash_table_t *d_keyhash;         /**< Attribute fields */
  77 
  78     void*              args;                     /**< Data description for the user */
  79     opal_atomic_intptr_t packed_description;       /**< Packed description of the datatype */
  80     uint64_t           pml_data;                 /**< PML-specific information */
  81     /* --- cacheline 6 boundary (384 bytes) --- */
  82     char               name[MPI_MAX_OBJECT_NAME];/**< Externally visible name */
  83     /* --- cacheline 7 boundary (448 bytes) --- */
  84 
  85     /* size: 448, cachelines: 7, members: 7 */
  86 };
  87 
  88 typedef struct ompi_datatype_t ompi_datatype_t;
  89 
  90 OMPI_DECLSPEC OBJ_CLASS_DECLARATION(ompi_datatype_t);
  91 
  92 /**
  93  * Padded struct to maintain back compatibiltiy.
  94  * See opal/communicator/communicator.h comments with struct opal_communicator_t
  95  * for full explanation why we chose the following padding construct for predefines.
  96  */
  97 
  98 /* Using set constant for padding of the DATATYPE handles because the size of
  99  * base structure is very close to being the same no matter the bitness.
 100  */
 101 #define PREDEFINED_DATATYPE_PAD 512
 102 
 103 struct ompi_predefined_datatype_t {
 104     struct ompi_datatype_t dt;
 105     char padding[PREDEFINED_DATATYPE_PAD - sizeof(ompi_datatype_t)];
 106 };
 107 
 108 typedef struct ompi_predefined_datatype_t ompi_predefined_datatype_t;
 109 
 110 /*
 111  * The list of predefined datatypes is specified in ompi/include/mpi.h.in
 112  */
 113 
 114 /* Base convertor for all external32 operations */
 115 OMPI_DECLSPEC extern opal_convertor_t* ompi_mpi_external32_convertor;
 116 OMPI_DECLSPEC extern opal_convertor_t* ompi_mpi_local_convertor;
 117 extern struct opal_pointer_array_t ompi_datatype_f_to_c_table;
 118 
 119 OMPI_DECLSPEC int32_t ompi_datatype_init( void );
 120 OMPI_DECLSPEC int32_t ompi_datatype_finalize( void );
 121 
 122 OMPI_DECLSPEC int32_t ompi_datatype_default_convertors_init( void );
 123 OMPI_DECLSPEC int32_t ompi_datatype_default_convertors_fini( void );
 124 
 125 OMPI_DECLSPEC void ompi_datatype_dump (const ompi_datatype_t* pData);
 126 OMPI_DECLSPEC ompi_datatype_t* ompi_datatype_create( int32_t expectedSize );
 127 
 128 static inline int32_t
 129 ompi_datatype_is_committed( const ompi_datatype_t* type )
 130 {
 131     return opal_datatype_is_committed(&type->super);
 132 }
 133 
 134 static inline int32_t
 135 ompi_datatype_is_overlapped( const ompi_datatype_t* type )
 136 {
 137     return opal_datatype_is_overlapped(&type->super);
 138 }
 139 
 140 static inline int32_t
 141 ompi_datatype_is_valid( const ompi_datatype_t* type )
 142 {
 143     return opal_datatype_is_valid(&type->super);
 144 }
 145 
 146 static inline int32_t
 147 ompi_datatype_is_predefined( const ompi_datatype_t* type )
 148 {
 149     return (type->super.flags & OMPI_DATATYPE_FLAG_PREDEFINED);
 150 }
 151 
 152 static inline int32_t
 153 ompi_datatype_is_contiguous_memory_layout( const ompi_datatype_t* type, int32_t count )
 154 {
 155     return opal_datatype_is_contiguous_memory_layout(&type->super, count);
 156 }
 157 
 158 static inline int32_t
 159 ompi_datatype_is_monotonic( ompi_datatype_t * type ) {
 160     if (!(type->super.flags & OMPI_DATATYPE_FLAG_ANALYZED)) {
 161         if (opal_datatype_is_monotonic(&type->super)) {
 162             type->super.flags |= OMPI_DATATYPE_FLAG_MONOTONIC;
 163         }
 164         type->super.flags |= OMPI_DATATYPE_FLAG_ANALYZED;
 165     }
 166     return type->super.flags & OMPI_DATATYPE_FLAG_MONOTONIC;
 167 }
 168 
 169 static inline int32_t
 170 ompi_datatype_commit( ompi_datatype_t ** type )
 171 {
 172     return opal_datatype_commit ( (opal_datatype_t*)*type );
 173 }
 174 
 175 OMPI_DECLSPEC int32_t ompi_datatype_destroy( ompi_datatype_t** type);
 176 
 177 
 178 /*
 179  * Datatype creation functions
 180  */
 181 static inline int32_t
 182 ompi_datatype_add( ompi_datatype_t* pdtBase, const ompi_datatype_t* pdtAdd, size_t count,
 183                    ptrdiff_t disp, ptrdiff_t extent )
 184 {
 185     return opal_datatype_add( &pdtBase->super, &pdtAdd->super, count, disp, extent );
 186 }
 187 
 188 OMPI_DECLSPEC int32_t
 189 ompi_datatype_duplicate( const ompi_datatype_t* oldType, ompi_datatype_t** newType );
 190 
 191 OMPI_DECLSPEC int32_t ompi_datatype_create_contiguous( int count, const ompi_datatype_t* oldType, ompi_datatype_t** newType );
 192 OMPI_DECLSPEC int32_t ompi_datatype_create_vector( int count, int bLength, int stride,
 193                                                    const ompi_datatype_t* oldType, ompi_datatype_t** newType );
 194 OMPI_DECLSPEC int32_t ompi_datatype_create_hvector( int count, int bLength, ptrdiff_t stride,
 195                                                     const ompi_datatype_t* oldType, ompi_datatype_t** newType );
 196 OMPI_DECLSPEC int32_t ompi_datatype_create_indexed( int count, const int* pBlockLength, const int* pDisp,
 197                                                     const ompi_datatype_t* oldType, ompi_datatype_t** newType );
 198 OMPI_DECLSPEC int32_t ompi_datatype_create_hindexed( int count, const int* pBlockLength, const ptrdiff_t* pDisp,
 199                                                      const ompi_datatype_t* oldType, ompi_datatype_t** newType );
 200 OMPI_DECLSPEC int32_t ompi_datatype_create_indexed_block( int count, int bLength, const int* pDisp,
 201                                                           const ompi_datatype_t* oldType, ompi_datatype_t** newType );
 202 OMPI_DECLSPEC int32_t ompi_datatype_create_hindexed_block( int count, int bLength, const ptrdiff_t* pDisp,
 203                                                            const ompi_datatype_t* oldType, ompi_datatype_t** newType );
 204 OMPI_DECLSPEC int32_t ompi_datatype_create_struct( int count, const int* pBlockLength, const ptrdiff_t* pDisp,
 205                                                    ompi_datatype_t* const* pTypes, ompi_datatype_t** newType );
 206 OMPI_DECLSPEC int32_t ompi_datatype_create_darray( int size, int rank, int ndims, int const* gsize_array,
 207                                                    int const* distrib_array, int const* darg_array,
 208                                                    int const* psize_array, int order, const ompi_datatype_t* oldtype,
 209                                                    ompi_datatype_t** newtype);
 210 OMPI_DECLSPEC int32_t ompi_datatype_create_subarray(int ndims, int const* size_array, int const* subsize_array,
 211                                                     int const* start_array, int order,
 212                                                     const ompi_datatype_t* oldtype, ompi_datatype_t** newtype);
 213 static inline int32_t
 214 ompi_datatype_create_resized( const ompi_datatype_t* oldType,
 215                               ptrdiff_t lb,
 216                               ptrdiff_t extent,
 217                               ompi_datatype_t** newType )
 218 {
 219     ompi_datatype_t * type;
 220     ompi_datatype_duplicate( oldType, &type );
 221     if ( NULL == type) {
 222         return OMPI_ERR_OUT_OF_RESOURCE;
 223     }
 224     opal_datatype_resize ( &type->super, lb, extent );
 225     *newType = type;
 226     return OMPI_SUCCESS;
 227 }
 228 
 229 static inline int32_t
 230 ompi_datatype_type_lb( const ompi_datatype_t* type, ptrdiff_t* disp )
 231 {
 232     return opal_datatype_type_lb(&type->super, disp);
 233 }
 234 
 235 static inline int32_t
 236 ompi_datatype_type_ub( const ompi_datatype_t* type, ptrdiff_t* disp )
 237 {
 238     return opal_datatype_type_ub( &type->super, disp);
 239 }
 240 
 241 static inline int32_t
 242 ompi_datatype_type_size ( const ompi_datatype_t* type, size_t *size )
 243 {
 244     return opal_datatype_type_size( &type->super, size);
 245 }
 246 
 247 static inline int32_t
 248 ompi_datatype_type_extent( const ompi_datatype_t* type, ptrdiff_t* extent )
 249 {
 250     return opal_datatype_type_extent( &type->super, extent);
 251 }
 252 
 253 static inline int32_t
 254 ompi_datatype_get_extent( const ompi_datatype_t* type, ptrdiff_t* lb, ptrdiff_t* extent)
 255 {
 256     return opal_datatype_get_extent( &type->super, lb, extent);
 257 }
 258 
 259 static inline int32_t
 260 ompi_datatype_get_true_extent( const ompi_datatype_t* type, ptrdiff_t* true_lb, ptrdiff_t* true_extent)
 261 {
 262     return opal_datatype_get_true_extent( &type->super, true_lb, true_extent);
 263 }
 264 
 265 static inline ssize_t
 266 ompi_datatype_get_element_count( const ompi_datatype_t* type, size_t iSize )
 267 {
 268     return opal_datatype_get_element_count( &type->super, iSize );
 269 }
 270 
 271 static inline int32_t
 272 ompi_datatype_set_element_count( const ompi_datatype_t* type, size_t count, size_t* length )
 273 {
 274     return opal_datatype_set_element_count( &type->super, count, length );
 275 }
 276 
 277 static inline int32_t
 278 ompi_datatype_copy_content_same_ddt( const ompi_datatype_t* type, size_t count,
 279                                      char* pDestBuf, char* pSrcBuf )
 280 {
 281     int32_t length, rc;
 282     ptrdiff_t extent;
 283 
 284     ompi_datatype_type_extent( type, &extent );
 285     while( 0 != count ) {
 286         length = INT_MAX;
 287         if( ((size_t)length) > count ) length = (int32_t)count;
 288         rc = opal_datatype_copy_content_same_ddt( &type->super, length,
 289                                                   pDestBuf, pSrcBuf );
 290         if( 0 != rc ) return rc;
 291         pDestBuf += ((ptrdiff_t)length) * extent;
 292         pSrcBuf  += ((ptrdiff_t)length) * extent;
 293         count -= (size_t)length;
 294     }
 295     return 0;
 296 }
 297 
 298 OMPI_DECLSPEC const ompi_datatype_t* ompi_datatype_match_size( int size, uint16_t datakind, uint16_t datalang );
 299 
 300 /*
 301  *
 302  */
 303 OMPI_DECLSPEC int32_t ompi_datatype_sndrcv( const void *sbuf, int32_t scount, const ompi_datatype_t* sdtype,
 304                                             void *rbuf, int32_t rcount, const ompi_datatype_t* rdtype);
 305 
 306 /*
 307  *
 308  */
 309 OMPI_DECLSPEC int32_t ompi_datatype_get_args( const ompi_datatype_t* pData, int32_t which,
 310                                               int32_t * ci, int32_t * i,
 311                                               int32_t * ca, ptrdiff_t* a,
 312                                               int32_t * cd, ompi_datatype_t** d, int32_t * type);
 313 OMPI_DECLSPEC int32_t ompi_datatype_set_args( ompi_datatype_t* pData,
 314                                               int32_t ci, const int32_t ** i,
 315                                               int32_t ca, const ptrdiff_t* a,
 316                                               int32_t cd, ompi_datatype_t* const * d,int32_t type);
 317 OMPI_DECLSPEC int32_t ompi_datatype_copy_args( const ompi_datatype_t* source_data,
 318                                                ompi_datatype_t* dest_data );
 319 OMPI_DECLSPEC int32_t ompi_datatype_release_args( ompi_datatype_t* pData );
 320 OMPI_DECLSPEC ompi_datatype_t* ompi_datatype_get_single_predefined_type_from_args( ompi_datatype_t* type );
 321 
 322 /**
 323  * Return the amount of buffer necessary to pack the entire description of
 324  * the datatype. This value is computed once per datatype, and it is stored
 325  * in the datatype structure together with the packed description. As a side
 326  * note special care is taken to align the amount of data on void* for
 327  * architectures that require it.
 328  */
 329 OMPI_DECLSPEC size_t ompi_datatype_pack_description_length( ompi_datatype_t* datatype );
 330 
 331 /**
 332  * Return a pointer to the constant packed representation of the datatype.
 333  * The length can be retrieved with the ompi_datatype_pack_description_length,
 334  * and it is quarantee this is exactly the amount to be copied and not an
 335  * upper bound. Additionally, the packed representation is slightly optimized
 336  * compared with the get_content function, as all combiner_dup have been replaced
 337  * directly with the target type.
 338  */
 339 OMPI_DECLSPEC int ompi_datatype_get_pack_description( ompi_datatype_t* datatype,
 340                                                       const void** packed_buffer );
 341 
 342 /**
 343  * Extract a fully-fledged datatype from the packed representation. This datatype
 344  * is ready to be used in communications (it is automatically committed). However,
 345  * this datatype does not have an internal representation, so it might not be
 346  * repacked. Read the comment for the ompi_datatype_get_pack_description function
 347  * for extra information.
 348  */
 349 struct ompi_proc_t;
 350 OMPI_DECLSPEC ompi_datatype_t*
 351 ompi_datatype_create_from_packed_description( void** packed_buffer,
 352                                               struct ompi_proc_t* remote_processor );
 353 
 354 /**
 355  * Auxiliary function providing a pretty print for the packed data description.
 356  */
 357 OMPI_DECLSPEC int32_t ompi_datatype_print_args( const ompi_datatype_t* pData );
 358 
 359 
 360 /**
 361  * Get the number of basic elements of the datatype in ucount
 362  *
 363  * @returns OMPI_SUCCESS if the count is valid
 364  * @returns OMPI_ERR_VALUE_OUT_OF_BOUNDS if no
 365  */
 366 OMPI_DECLSPEC int ompi_datatype_get_elements (ompi_datatype_t *datatype, size_t ucount,
 367                                               size_t *count);
 368 
 369 #if OPAL_ENABLE_DEBUG
 370 /*
 371  * Set a breakpoint to this function in your favorite debugger
 372  * to make it stop on all pack and unpack errors.
 373  */
 374 OMPI_DECLSPEC int ompi_datatype_safeguard_pointer_debug_breakpoint( const void* actual_ptr, int length,
 375                                                                     const void* initial_ptr,
 376                                                                     const ompi_datatype_t* pData,
 377                                                                     int count );
 378 #endif  /* OPAL_ENABLE_DEBUG */
 379 
 380 OMPI_DECLSPEC int ompi_datatype_pack_external( const char datarep[], const void *inbuf, int incount,
 381                                                ompi_datatype_t *datatype, void *outbuf,
 382                                                MPI_Aint outsize, MPI_Aint *position);
 383 
 384 OMPI_DECLSPEC int ompi_datatype_unpack_external( const char datarep[], const void *inbuf, MPI_Aint insize,
 385                                                  MPI_Aint *position, void *outbuf, int outcount,
 386                                                  ompi_datatype_t *datatype);
 387 
 388 OMPI_DECLSPEC int ompi_datatype_pack_external_size( const char datarep[], int incount,
 389                                                     ompi_datatype_t *datatype, MPI_Aint *size);
 390 
 391 #define OMPI_DATATYPE_RETAIN(ddt)                                       \
 392     {                                                                   \
 393         if( !ompi_datatype_is_predefined((ddt)) ) {                     \
 394             OBJ_RETAIN((ddt));                                          \
 395             OPAL_OUTPUT_VERBOSE((0, 100, "Datatype %p [%s] refcount %d in file %s:%d\n",     \
 396                                 (void*)(ddt), (ddt)->name, (ddt)->super.super.obj_reference_count, \
 397                                 __FILE__, __LINE__));                   \
 398         }                                                               \
 399     }
 400 
 401 #define OMPI_DATATYPE_RELEASE(ddt)                                      \
 402     {                                                                   \
 403         if( !ompi_datatype_is_predefined((ddt)) ) {                     \
 404             OPAL_OUTPUT_VERBOSE((0, 100, "Datatype %p [%s] refcount %d in file %s:%d\n",     \
 405                                 (void*)(ddt), (ddt)->name, (ddt)->super.super.obj_reference_count, \
 406                                 __func__, __LINE__));                   \
 407             OBJ_RELEASE((ddt));                                         \
 408         }                                                               \
 409     }
 410 
 411 END_C_DECLS
 412 #endif  /* OMPI_DATATYPE_H_HAS_BEEN_INCLUDED */

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