root/ompi/datatype/ompi_datatype_module.c

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

DEFINITIONS

This source file includes following definitions.
  1. ompi_datatype_init
  2. ompi_datatype_finalize
  3. ompi_datatype_safeguard_pointer_debug_breakpoint
  4. _ompi_dump_data_flags
  5. ompi_datatype_dump

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   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-2019 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) 2007-2018 Cisco Systems, Inc.  All rights reserved
  14  * Copyright (c) 2009      Sun Microsystems, Inc.  All rights reserved.
  15  * Copyright (c) 2009      Oak Ridge National Labs.  All rights reserved.
  16  * Copyright (c) 2013      Los Alamos National Security, LLC. All rights
  17  *                         reserved.
  18  * Copyright (c) 2015-2018 Research Organization for Information Science
  19  *                         and Technology (RIST). All rights reserved.
  20  * Copyright (c) 2016-2018 FUJITSU LIMITED.  All rights reserved.
  21  * $COPYRIGHT$
  22  *
  23  * Additional copyrights may follow
  24  *
  25  * $HEADER$
  26  */
  27 
  28 #include "ompi_config.h"
  29 
  30 #include <stddef.h>
  31 #include <stdio.h>
  32 
  33 #include "opal/datatype/opal_convertor_internal.h"
  34 #include "opal/util/output.h"
  35 #include "opal/util/string_copy.h"
  36 #include "opal/class/opal_pointer_array.h"
  37 #include "ompi/datatype/ompi_datatype.h"
  38 #include "ompi/datatype/ompi_datatype_internal.h"
  39 
  40 #include "mpi.h"
  41 
  42 /**
  43  * This is the number of predefined datatypes. It is different than the MAX_PREDEFINED
  44  * as it include all the optional datatypes (such as MPI_INTEGER?, MPI_REAL?).
  45  */
  46 int32_t ompi_datatype_number_of_predefined_data = 0;
  47 
  48 /*
  49  * The following initialization of C, C++ and Fortran types is fairly complex,
  50  * based on the OPAL-datatypes.
  51  *   ompi_datatypes.h
  52  *       \-------> ompi_datatypes_internal.h   (Macros defining type-number and initialization)
  53  *   opal_datatypes.h
  54  *       \-------> opal_datatypes_internal.h   (Macros defining type-number and initialization)
  55  *
  56  * The Macros in the OMPI Layer differ in that:
  57  *   Additionally to OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE, we have a OMPI_DATATYPE_INIT_PREDEFINED,
  58  *   for all available types (getting rid of duplication of the name.
  59  */
  60 ompi_predefined_datatype_t ompi_mpi_datatype_null =
  61     {
  62         {
  63             OPAL_DATATYPE_INITIALIZER_EMPTY(OMPI_DATATYPE_FLAG_PREDEFINED),
  64             OMPI_DATATYPE_EMPTY_DATA(EMPTY),
  65         },
  66         {0, } /* padding */
  67     };
  68 
  69 ompi_predefined_datatype_t ompi_mpi_unavailable =    OMPI_DATATYPE_INIT_PREDEFINED (UNAVAILABLE, 0);
  70 
  71 ompi_predefined_datatype_t ompi_mpi_lb =             OMPI_DATATYPE_INIT_PREDEFINED (LB, 0);
  72 ompi_predefined_datatype_t ompi_mpi_ub =             OMPI_DATATYPE_INIT_PREDEFINED (UB, 0);
  73 ompi_predefined_datatype_t ompi_mpi_char =           OMPI_DATATYPE_INIT_PREDEFINED (CHAR, OMPI_DATATYPE_FLAG_DATA_C);
  74 ompi_predefined_datatype_t ompi_mpi_signed_char =    OMPI_DATATYPE_INIT_PREDEFINED (SIGNED_CHAR, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  75 ompi_predefined_datatype_t ompi_mpi_unsigned_char =  OMPI_DATATYPE_INIT_PREDEFINED (UNSIGNED_CHAR, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  76 ompi_predefined_datatype_t ompi_mpi_byte =           OMPI_DATATYPE_INIT_PREDEFINED (BYTE, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  77 ompi_predefined_datatype_t ompi_mpi_short =          OMPI_DATATYPE_INIT_PREDEFINED (SHORT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  78 ompi_predefined_datatype_t ompi_mpi_unsigned_short = OMPI_DATATYPE_INIT_PREDEFINED (UNSIGNED_SHORT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  79 ompi_predefined_datatype_t ompi_mpi_int =            OMPI_DATATYPE_INIT_PREDEFINED (INT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  80 ompi_predefined_datatype_t ompi_mpi_unsigned =       OMPI_DATATYPE_INIT_PREDEFINED (UNSIGNED, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  81 ompi_predefined_datatype_t ompi_mpi_long =           OMPI_DATATYPE_INIT_PREDEFINED (LONG, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  82 ompi_predefined_datatype_t ompi_mpi_unsigned_long =  OMPI_DATATYPE_INIT_PREDEFINED (UNSIGNED_LONG, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  83 ompi_predefined_datatype_t ompi_mpi_long_long_int =  OMPI_DATATYPE_INIT_PREDEFINED (LONG_LONG_INT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  84 ompi_predefined_datatype_t ompi_mpi_unsigned_long_long = OMPI_DATATYPE_INIT_PREDEFINED (UNSIGNED_LONG_LONG, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
  85 #if defined(HAVE_SHORT_FLOAT) || defined(HAVE_OPAL_SHORT_FLOAT_T)
  86 ompi_predefined_datatype_t ompi_mpi_short_float =    OMPI_DATATYPE_INIT_PREDEFINED (SHORT_FLOAT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_FLOAT );
  87 #else
  88 ompi_predefined_datatype_t ompi_mpi_short_float =    OMPI_DATATYPE_INIT_UNAVAILABLE (SHORT_FLOAT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_FLOAT );
  89 #endif  /* HAVE_SHORT_FLOAT */
  90 ompi_predefined_datatype_t ompi_mpi_float =          OMPI_DATATYPE_INIT_PREDEFINED (FLOAT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_FLOAT );
  91 ompi_predefined_datatype_t ompi_mpi_double =         OMPI_DATATYPE_INIT_PREDEFINED (DOUBLE, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_FLOAT );
  92 ompi_predefined_datatype_t ompi_mpi_long_double =    OMPI_DATATYPE_INIT_PREDEFINED (LONG_DOUBLE, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_FLOAT );
  93 #if defined(OPAL_ALIGNMENT_WCHAR) && OPAL_ALIGNMENT_WCHAR != 0
  94 ompi_predefined_datatype_t ompi_mpi_wchar =          OMPI_DATATYPE_INIT_PREDEFINED (WCHAR, OMPI_DATATYPE_FLAG_DATA_C );
  95 #else
  96 ompi_predefined_datatype_t ompi_mpi_wchar =          OMPI_DATATYPE_INIT_UNAVAILABLE (WCHAR, OMPI_DATATYPE_FLAG_DATA_C );
  97 #endif /* OPAL_ALIGNMENT_WCHAR */
  98 ompi_predefined_datatype_t ompi_mpi_packed =         OMPI_DATATYPE_INIT_PREDEFINED (PACKED, 0 );
  99 
 100 /*
 101  * C++ / C99 datatypes
 102  */
 103 ompi_predefined_datatype_t ompi_mpi_c_bool =         OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (BOOL, C_BOOL, OMPI_DATATYPE_FLAG_DATA_C);
 104 ompi_predefined_datatype_t ompi_mpi_cxx_bool =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (BOOL, CXX_BOOL, OMPI_DATATYPE_FLAG_DATA_CPP);
 105 
 106 /*
 107  * Complex datatypes for C (base types), C++, and fortran
 108  */
 109 #if defined(HAVE_SHORT_FLOAT__COMPLEX) || defined(HAVE_OPAL_SHORT_FLOAT_COMPLEX_T)
 110 ompi_predefined_datatype_t ompi_mpi_c_short_float_complex = OMPI_DATATYPE_INIT_PREDEFINED (C_SHORT_FLOAT_COMPLEX, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 111 #else
 112 ompi_predefined_datatype_t ompi_mpi_c_short_float_complex = OMPI_DATATYPE_INIT_UNAVAILABLE (C_SHORT_FLOAT_COMPLEX, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 113 #endif  /* HAVE_SHORT_FLOAT__COMPLEX */
 114 ompi_predefined_datatype_t ompi_mpi_c_float_complex =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (C_FLOAT_COMPLEX, C_COMPLEX, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 115 ompi_predefined_datatype_t ompi_mpi_c_complex =             OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (C_FLOAT_COMPLEX, C_COMPLEX, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 116 ompi_predefined_datatype_t ompi_mpi_c_double_complex =      OMPI_DATATYPE_INIT_PREDEFINED (C_DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 117 ompi_predefined_datatype_t ompi_mpi_c_long_double_complex = OMPI_DATATYPE_INIT_PREDEFINED (C_LONG_DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 118 
 119 /* The C++ complex datatypes are the same as the C datatypes */
 120 #if defined(HAVE_SHORT_FLOAT__COMPLEX) || defined(HAVE_OPAL_SHORT_FLOAT_COMPLEX_T)
 121 ompi_predefined_datatype_t ompi_mpi_cxx_sfltcplex =  OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (C_SHORT_FLOAT_COMPLEX, CXX_SHORT_FLOAT_COMPLEX, OMPI_DATATYPE_FLAG_DATA_CPP | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 122 #else
 123 ompi_predefined_datatype_t ompi_mpi_cxx_sfltcplex =  OMPI_DATATYPE_INIT_UNAVAILABLE (CXX_SHORT_FLOAT_COMPLEX, OMPI_DATATYPE_FLAG_DATA_CPP | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 124 #endif  /* HAVE_SHORT_FLOAT__COMPLEX */
 125 ompi_predefined_datatype_t ompi_mpi_cxx_cplex =      OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (C_FLOAT_COMPLEX, CXX_FLOAT_COMPLEX, OMPI_DATATYPE_FLAG_DATA_CPP | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 126 ompi_predefined_datatype_t ompi_mpi_cxx_dblcplex =   OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (C_DOUBLE_COMPLEX, CXX_DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_CPP | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 127 ompi_predefined_datatype_t ompi_mpi_cxx_ldblcplex =  OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (C_LONG_DOUBLE_COMPLEX, CXX_LONG_DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_CPP | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 128 
 129 #if OMPI_HAVE_FORTRAN_COMPLEX
 130 ompi_predefined_datatype_t ompi_mpi_cplex =          OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (OMPI_KIND_FORTRAN_COMPLEX, COMPLEX, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 131 #else
 132 ompi_predefined_datatype_t ompi_mpi_cplex =          OMPI_DATATYPE_INIT_UNAVAILABLE (COMPLEX, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 133 #endif
 134 
 135 #if OMPI_HAVE_FORTRAN_DOUBLE_COMPLEX
 136 ompi_predefined_datatype_t ompi_mpi_dblcplex =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (OMPI_KIND_FORTRAN_DOUBLE_COMPLEX, DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 137 #else
 138 ompi_predefined_datatype_t ompi_mpi_dblcplex =       OMPI_DATATYPE_INIT_UNAVAILABLE (DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 139 #endif
 140 
 141 /* In Fortran, there does not exist a type LONG DOUBLE COMPLEX, but DOUBLE COMPLEX(KIND=8) may require this */
 142 #if OMPI_HAVE_FORTRAN_DOUBLE_COMPLEX
 143 ompi_predefined_datatype_t ompi_mpi_ldblcplex =      OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (C_LONG_DOUBLE_COMPLEX, LONG_DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 144 #else
 145 ompi_predefined_datatype_t ompi_mpi_ldblcplex =      OMPI_DATATYPE_INIT_UNAVAILABLE (LONG_DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 146 #endif
 147 
 148 #if OMPI_HAVE_FORTRAN_COMPLEX4
 149 ompi_predefined_datatype_t ompi_mpi_complex4 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (OMPI_KIND_FORTRAN_COMPLEX4, COMPLEX4, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 150 #else
 151 ompi_predefined_datatype_t ompi_mpi_complex4 =       OMPI_DATATYPE_INIT_UNAVAILABLE (COMPLEX4, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX);
 152 #endif
 153 
 154 #if OMPI_HAVE_FORTRAN_COMPLEX8
 155 ompi_predefined_datatype_t ompi_mpi_complex8 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (OMPI_KIND_FORTRAN_COMPLEX8, COMPLEX8, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 156 #else
 157 ompi_predefined_datatype_t ompi_mpi_complex8 =       OMPI_DATATYPE_INIT_UNAVAILABLE (COMPLEX8, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX);
 158 #endif
 159 
 160 #if OMPI_HAVE_FORTRAN_COMPLEX16
 161 ompi_predefined_datatype_t ompi_mpi_complex16 =      OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (OMPI_KIND_FORTRAN_COMPLEX16, COMPLEX16, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 162 #else
 163 ompi_predefined_datatype_t ompi_mpi_complex16 =      OMPI_DATATYPE_INIT_UNAVAILABLE (COMPLEX16, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX);
 164 #endif
 165 
 166 #if OMPI_HAVE_FORTRAN_COMPLEX32
 167 ompi_predefined_datatype_t ompi_mpi_complex32 =      OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE (OMPI_KIND_FORTRAN_COMPLEX32, COMPLEX32, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 168 #else
 169 ompi_predefined_datatype_t ompi_mpi_complex32 =      OMPI_DATATYPE_INIT_UNAVAILABLE (COMPLEX32, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX);
 170 #endif
 171 
 172 /*
 173  * Fortran datatypes
 174  */
 175 ompi_predefined_datatype_t ompi_mpi_logical =        OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, LOGICAL, OMPI_SIZEOF_FORTRAN_LOGICAL, OMPI_ALIGNMENT_FORTRAN_LOGICAL, 0 );
 176 ompi_predefined_datatype_t ompi_mpi_character =      OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, CHARACTER, 1, OPAL_ALIGNMENT_CHAR, 0 );
 177 ompi_predefined_datatype_t ompi_mpi_integer =        OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, INTEGER, OMPI_SIZEOF_FORTRAN_INTEGER, OMPI_ALIGNMENT_FORTRAN_INTEGER, OMPI_DATATYPE_FLAG_DATA_INT );
 178 ompi_predefined_datatype_t ompi_mpi_real =           OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (FLOAT, REAL, OMPI_SIZEOF_FORTRAN_REAL, OMPI_ALIGNMENT_FORTRAN_REAL, OMPI_DATATYPE_FLAG_DATA_FLOAT );
 179 ompi_predefined_datatype_t ompi_mpi_dblprec =        OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (FLOAT, DOUBLE_PRECISION, OMPI_SIZEOF_FORTRAN_DOUBLE_PRECISION, OMPI_ALIGNMENT_FORTRAN_DOUBLE_PRECISION, OMPI_DATATYPE_FLAG_DATA_FLOAT );
 180 
 181 
 182 /* Aggregate struct datatypes are not const */
 183 ompi_predefined_datatype_t ompi_mpi_float_int =      OMPI_DATATYPE_INIT_DEFER (FLOAT_INT, OMPI_DATATYPE_FLAG_DATA_C );
 184 ompi_predefined_datatype_t ompi_mpi_double_int =     OMPI_DATATYPE_INIT_DEFER (DOUBLE_INT, OMPI_DATATYPE_FLAG_DATA_C );
 185 ompi_predefined_datatype_t ompi_mpi_longdbl_int =    OMPI_DATATYPE_INIT_DEFER (LONG_DOUBLE_INT, OMPI_DATATYPE_FLAG_DATA_C );
 186 
 187 ompi_predefined_datatype_t ompi_mpi_2int =           OMPI_DATATYPE_INIT_DEFER (2INT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
 188 ompi_predefined_datatype_t ompi_mpi_short_int =      OMPI_DATATYPE_INIT_DEFER (SHORT_INT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
 189 ompi_predefined_datatype_t ompi_mpi_long_int =       OMPI_DATATYPE_INIT_DEFER (LONG_INT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
 190 
 191 ompi_predefined_datatype_t ompi_mpi_2integer =       OMPI_DATATYPE_INIT_DEFER (2INTEGER, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_INT );
 192 ompi_predefined_datatype_t ompi_mpi_2real =          OMPI_DATATYPE_INIT_DEFER (2REAL, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_FLOAT );
 193 ompi_predefined_datatype_t ompi_mpi_2dblprec =       OMPI_DATATYPE_INIT_DEFER (2DBLPREC, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_FLOAT );
 194 
 195 ompi_predefined_datatype_t ompi_mpi_2cplex =         OMPI_DATATYPE_INIT_DEFER (2COMPLEX, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 196 ompi_predefined_datatype_t ompi_mpi_2dblcplex =      OMPI_DATATYPE_INIT_DEFER (2DOUBLE_COMPLEX, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 197 
 198 /* For each of these we figure out, whether it is available -- otherwise it's set to unavailable */
 199 #if OMPI_HAVE_FORTRAN_LOGICAL1
 200 ompi_predefined_datatype_t ompi_mpi_logical1 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, LOGICAL1, OMPI_SIZEOF_FORTRAN_LOGICAL1, OMPI_ALIGNMENT_FORTRAN_LOGICAL1, 0);
 201 #else
 202 ompi_predefined_datatype_t ompi_mpi_logical1 =       OMPI_DATATYPE_INIT_UNAVAILABLE (LOGICAL1, OMPI_DATATYPE_FLAG_DATA_FORTRAN );
 203 #endif
 204 #if OMPI_HAVE_FORTRAN_LOGICAL2
 205 ompi_predefined_datatype_t ompi_mpi_logical2 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, LOGICAL2, OMPI_SIZEOF_FORTRAN_LOGICAL2, OMPI_ALIGNMENT_FORTRAN_LOGICAL2, 0);
 206 #else
 207 ompi_predefined_datatype_t ompi_mpi_logical2 =       OMPI_DATATYPE_INIT_UNAVAILABLE (LOGICAL2, OMPI_DATATYPE_FLAG_DATA_FORTRAN );
 208 #endif
 209 #if OMPI_HAVE_FORTRAN_LOGICAL4
 210 ompi_predefined_datatype_t ompi_mpi_logical4 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, LOGICAL4, OMPI_SIZEOF_FORTRAN_LOGICAL4, OMPI_ALIGNMENT_FORTRAN_LOGICAL4, 0);
 211 #else
 212 ompi_predefined_datatype_t ompi_mpi_logical4 =       OMPI_DATATYPE_INIT_UNAVAILABLE (LOGICAL4, OMPI_DATATYPE_FLAG_DATA_FORTRAN );
 213 #endif
 214 #if OMPI_HAVE_FORTRAN_LOGICAL8
 215 ompi_predefined_datatype_t ompi_mpi_logical8 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, LOGICAL8, OMPI_SIZEOF_FORTRAN_LOGICAL8, OMPI_ALIGNMENT_FORTRAN_LOGICAL8, 0);
 216 #else
 217 ompi_predefined_datatype_t ompi_mpi_logical8 =       OMPI_DATATYPE_INIT_UNAVAILABLE (LOGICAL8, OMPI_DATATYPE_FLAG_DATA_FORTRAN );
 218 #endif
 219 #if OMPI_HAVE_FORTRAN_REAL2
 220 ompi_predefined_datatype_t ompi_mpi_real2 =          OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (FLOAT, REAL2, OMPI_SIZEOF_FORTRAN_REAL2, OMPI_ALIGNMENT_FORTRAN_REAL2, OMPI_DATATYPE_FLAG_DATA_FLOAT);
 221 #else
 222 ompi_predefined_datatype_t ompi_mpi_real2 =          OMPI_DATATYPE_INIT_UNAVAILABLE (REAL2, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_FLOAT);
 223 #endif
 224 #if OMPI_HAVE_FORTRAN_REAL4
 225 ompi_predefined_datatype_t ompi_mpi_real4 =          OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (FLOAT, REAL4, OMPI_SIZEOF_FORTRAN_REAL4, OMPI_ALIGNMENT_FORTRAN_REAL4, OMPI_DATATYPE_FLAG_DATA_FLOAT);
 226 #else
 227 ompi_predefined_datatype_t ompi_mpi_real4 =          OMPI_DATATYPE_INIT_UNAVAILABLE (REAL4, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_FLOAT);
 228 #endif
 229 #if OMPI_HAVE_FORTRAN_REAL8
 230 ompi_predefined_datatype_t ompi_mpi_real8 =          OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (FLOAT, REAL8, OMPI_SIZEOF_FORTRAN_REAL8, OMPI_ALIGNMENT_FORTRAN_REAL8, OMPI_DATATYPE_FLAG_DATA_FLOAT);
 231 #else
 232 ompi_predefined_datatype_t ompi_mpi_real8 =          OMPI_DATATYPE_INIT_UNAVAILABLE (REAL8, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_FLOAT);
 233 #endif
 234 #if OMPI_HAVE_FORTRAN_REAL16
 235 ompi_predefined_datatype_t ompi_mpi_real16 =         OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (FLOAT, REAL16, OMPI_SIZEOF_FORTRAN_REAL16, OMPI_ALIGNMENT_FORTRAN_REAL16, OMPI_DATATYPE_FLAG_DATA_FLOAT);
 236 #else
 237 ompi_predefined_datatype_t ompi_mpi_real16 =         OMPI_DATATYPE_INIT_UNAVAILABLE (REAL16, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_FLOAT);
 238 #endif
 239 
 240 #if OMPI_HAVE_FORTRAN_INTEGER1
 241 ompi_predefined_datatype_t ompi_mpi_integer1 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, INTEGER1, OMPI_SIZEOF_FORTRAN_INTEGER1, OMPI_ALIGNMENT_FORTRAN_INTEGER1, OMPI_DATATYPE_FLAG_DATA_INT);
 242 #else
 243 ompi_predefined_datatype_t ompi_mpi_integer1 =       OMPI_DATATYPE_INIT_UNAVAILABLE (INTEGER1, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_INT);
 244 #endif
 245 #if OMPI_HAVE_FORTRAN_INTEGER2
 246 ompi_predefined_datatype_t ompi_mpi_integer2 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, INTEGER2, OMPI_SIZEOF_FORTRAN_INTEGER2, OMPI_ALIGNMENT_FORTRAN_INTEGER2, OMPI_DATATYPE_FLAG_DATA_INT);
 247 #else
 248 ompi_predefined_datatype_t ompi_mpi_integer2 =       OMPI_DATATYPE_INIT_UNAVAILABLE (INTEGER2, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_INT);
 249 #endif
 250 #if OMPI_HAVE_FORTRAN_INTEGER4
 251 ompi_predefined_datatype_t ompi_mpi_integer4 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, INTEGER4, OMPI_SIZEOF_FORTRAN_INTEGER4, OMPI_ALIGNMENT_FORTRAN_INTEGER4, OMPI_DATATYPE_FLAG_DATA_INT);
 252 #else
 253 ompi_predefined_datatype_t ompi_mpi_integer4 =       OMPI_DATATYPE_INIT_UNAVAILABLE (INTEGER4, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_INT);
 254 #endif
 255 #if OMPI_HAVE_FORTRAN_INTEGER8
 256 ompi_predefined_datatype_t ompi_mpi_integer8 =       OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, INTEGER8, OMPI_SIZEOF_FORTRAN_INTEGER8, OMPI_ALIGNMENT_FORTRAN_INTEGER8, OMPI_DATATYPE_FLAG_DATA_INT);
 257 #else
 258 ompi_predefined_datatype_t ompi_mpi_integer8 =       OMPI_DATATYPE_INIT_UNAVAILABLE (INTEGER8, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_INT);
 259 #endif
 260 #if OMPI_HAVE_FORTRAN_INTEGER16
 261 ompi_predefined_datatype_t ompi_mpi_integer16 =      OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE_FORTRAN (INT, INTEGER16, OMPI_SIZEOF_FORTRAN_INTEGER16, OMPI_ALIGNMENT_FORTRAN_INTEGER16, OMPI_DATATYPE_FLAG_DATA_INT);
 262 #else
 263 ompi_predefined_datatype_t ompi_mpi_integer16 =      OMPI_DATATYPE_INIT_UNAVAILABLE (INTEGER16, OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_INT);
 264 #endif
 265 
 266 /*
 267  * MPI 2.2 Datatypes
 268  */
 269 ompi_predefined_datatype_t ompi_mpi_int8_t   = OMPI_DATATYPE_INIT_PREDEFINED(  INT8_T, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 270 ompi_predefined_datatype_t ompi_mpi_uint8_t  = OMPI_DATATYPE_INIT_PREDEFINED( UINT8_T, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 271 ompi_predefined_datatype_t ompi_mpi_int16_t  = OMPI_DATATYPE_INIT_PREDEFINED( INT16_T, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 272 ompi_predefined_datatype_t ompi_mpi_uint16_t = OMPI_DATATYPE_INIT_PREDEFINED(UINT16_T, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 273 ompi_predefined_datatype_t ompi_mpi_int32_t  = OMPI_DATATYPE_INIT_PREDEFINED( INT32_T, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 274 ompi_predefined_datatype_t ompi_mpi_uint32_t = OMPI_DATATYPE_INIT_PREDEFINED(UINT32_T, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 275 ompi_predefined_datatype_t ompi_mpi_int64_t  = OMPI_DATATYPE_INIT_PREDEFINED( INT64_T, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 276 ompi_predefined_datatype_t ompi_mpi_uint64_t = OMPI_DATATYPE_INIT_PREDEFINED(UINT64_T, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 277 
 278 #if SIZEOF_PTRDIFF_T == 4
 279 ompi_predefined_datatype_t ompi_mpi_aint = OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE(INT32_T, AINT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 280 #elif SIZEOF_PTRDIFF_T == 8
 281 ompi_predefined_datatype_t ompi_mpi_aint = OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE(INT64_T, AINT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 282 #else
 283 ompi_predefined_datatype_t ompi_mpi_aint = OMPI_DATATYPE_INIT_UNAVAILABLE_BASIC_TYPE(INT64_T, AINT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 284 #endif  /* SIZEOF_PTRDIFF_T == SIZEOF_LONG */
 285 
 286 #if OMPI_MPI_OFFSET_SIZE == 4
 287 ompi_predefined_datatype_t ompi_mpi_offset = OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE(UINT32_T, OFFSET, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 288 #elif OMPI_MPI_OFFSET_SIZE == 8
 289 ompi_predefined_datatype_t ompi_mpi_offset = OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE(UINT64_T, OFFSET, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 290 #else
 291 ompi_predefined_datatype_t ompi_mpi_offset = OMPI_DATATYPE_INIT_UNAVAILABLE_BASIC_TYPE(UINT64_T, OFFSET, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 292 #endif  /* OMPI_MPI_OFFSET_SIZE == SIZEOF_INT */
 293 
 294 /*
 295  * MPI 3.0 Datatypes
 296  */
 297 #if OMPI_MPI_COUNT_SIZE == 4
 298 ompi_predefined_datatype_t ompi_mpi_count = OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE(INT32_T, COUNT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 299 #elif OMPI_MPI_COUNT_SIZE == 8
 300 ompi_predefined_datatype_t ompi_mpi_count = OMPI_DATATYPE_INIT_PREDEFINED_BASIC_TYPE(INT64_T, COUNT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 301 #else
 302 ompi_predefined_datatype_t ompi_mpi_count = OMPI_DATATYPE_INIT_UNAVAILABLE_BASIC_TYPE(INT64_T, COUNT, OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT);
 303 #endif
 304 
 305 
 306 /*
 307  * NOTE: The order of this array *MUST* match what is listed in
 308  * opal_datatype_internal.h and ompi_datatype_internal.h
 309  * Everything referring to types/ids should be ORDERED as in ompi_datatype_basicDatatypes array.
 310  */
 311 const ompi_datatype_t* ompi_datatype_basicDatatypes[OMPI_DATATYPE_MPI_MAX_PREDEFINED] = {
 312     [OMPI_DATATYPE_MPI_EMPTY] = &ompi_mpi_datatype_null.dt,
 313     [OMPI_DATATYPE_MPI_INT8_T] = &ompi_mpi_int8_t.dt,
 314     [OMPI_DATATYPE_MPI_UINT8_T] = &ompi_mpi_uint8_t.dt,
 315     [OMPI_DATATYPE_MPI_INT16_T] = &ompi_mpi_int16_t.dt,
 316     [OMPI_DATATYPE_MPI_UINT16_T] = &ompi_mpi_uint16_t.dt,
 317     [OMPI_DATATYPE_MPI_INT32_T] = &ompi_mpi_int32_t.dt,
 318     [OMPI_DATATYPE_MPI_UINT32_T] = &ompi_mpi_uint32_t.dt,
 319     [OMPI_DATATYPE_MPI_INT64_T] = &ompi_mpi_int64_t.dt,
 320     [OMPI_DATATYPE_MPI_UINT64_T] = &ompi_mpi_uint64_t.dt,
 321     [OMPI_DATATYPE_MPI_FLOAT] = &ompi_mpi_float.dt,
 322     [OMPI_DATATYPE_MPI_DOUBLE] = &ompi_mpi_double.dt,
 323     [OMPI_DATATYPE_MPI_LONG_DOUBLE] = &ompi_mpi_long_double.dt,
 324     [OMPI_DATATYPE_MPI_COMPLEX4] = &ompi_mpi_complex4.dt,
 325     [OMPI_DATATYPE_MPI_COMPLEX8] = &ompi_mpi_complex8.dt,
 326     [OMPI_DATATYPE_MPI_COMPLEX16] = &ompi_mpi_complex16.dt,
 327     [OMPI_DATATYPE_MPI_COMPLEX32] = &ompi_mpi_complex32.dt,
 328     [OMPI_DATATYPE_MPI_WCHAR] = &ompi_mpi_wchar.dt,
 329     [OMPI_DATATYPE_MPI_PACKED] = &ompi_mpi_packed.dt,
 330 
 331     /* C++ / C99 datatypes */
 332     [OMPI_DATATYPE_MPI_BOOL] = &ompi_mpi_cxx_bool.dt,
 333 
 334     /* Fortran datatypes */
 335     [OMPI_DATATYPE_MPI_LOGICAL] = &ompi_mpi_logical.dt,
 336     [OMPI_DATATYPE_MPI_CHARACTER] = &ompi_mpi_character.dt,
 337     [OMPI_DATATYPE_MPI_INTEGER] = &ompi_mpi_integer.dt,
 338     [OMPI_DATATYPE_MPI_REAL] = &ompi_mpi_real.dt,
 339     [OMPI_DATATYPE_MPI_DOUBLE_PRECISION] = &ompi_mpi_dblprec.dt,
 340 
 341     [OMPI_DATATYPE_MPI_COMPLEX] = &ompi_mpi_cplex.dt,
 342     [OMPI_DATATYPE_MPI_DOUBLE_COMPLEX] = &ompi_mpi_dblcplex.dt,
 343     [OMPI_DATATYPE_MPI_LONG_DOUBLE_COMPLEX] = &ompi_mpi_ldblcplex.dt,
 344     [OMPI_DATATYPE_MPI_2INT] = &ompi_mpi_2int.dt,
 345     [OMPI_DATATYPE_MPI_2INTEGER] = &ompi_mpi_2integer.dt,
 346     [OMPI_DATATYPE_MPI_2REAL] = &ompi_mpi_2real.dt,
 347     [OMPI_DATATYPE_MPI_2DBLPREC] = &ompi_mpi_2dblprec.dt,
 348     [OMPI_DATATYPE_MPI_2COMPLEX] = &ompi_mpi_2cplex.dt,
 349     [OMPI_DATATYPE_MPI_2DOUBLE_COMPLEX] = &ompi_mpi_2dblcplex.dt,
 350 
 351     [OMPI_DATATYPE_MPI_FLOAT_INT] = &ompi_mpi_float_int.dt,
 352     [OMPI_DATATYPE_MPI_DOUBLE_INT] = &ompi_mpi_double_int.dt,
 353     [OMPI_DATATYPE_MPI_LONG_DOUBLE_INT] = &ompi_mpi_longdbl_int.dt,
 354     [OMPI_DATATYPE_MPI_LONG_INT] = &ompi_mpi_long_int.dt,
 355     [OMPI_DATATYPE_MPI_SHORT_INT] = &ompi_mpi_short_int.dt,
 356 
 357     /* MPI 2.2 types */
 358     [OMPI_DATATYPE_MPI_AINT] = &ompi_mpi_aint.dt,
 359     [OMPI_DATATYPE_MPI_OFFSET] = &ompi_mpi_offset.dt,
 360     [OMPI_DATATYPE_MPI_C_BOOL] = &ompi_mpi_c_bool.dt,
 361     [OMPI_DATATYPE_MPI_C_COMPLEX] = &ompi_mpi_c_complex.dt,
 362     [OMPI_DATATYPE_MPI_C_FLOAT_COMPLEX] = &ompi_mpi_c_float_complex.dt,
 363     [OMPI_DATATYPE_MPI_C_DOUBLE_COMPLEX] = &ompi_mpi_c_double_complex.dt,
 364     [OMPI_DATATYPE_MPI_C_LONG_DOUBLE_COMPLEX] = &ompi_mpi_c_long_double_complex.dt,
 365 
 366     [OMPI_DATATYPE_MPI_LB] = &ompi_mpi_lb.dt,
 367     [OMPI_DATATYPE_MPI_UB] = &ompi_mpi_ub.dt,
 368 
 369     /* MPI 3.0 types */
 370     [OMPI_DATATYPE_MPI_COUNT] = &ompi_mpi_count.dt,
 371 
 372     /* Datatypes proposed to the MPI Forum in June 2017 for proposal in
 373      * the MPI 4.0 standard. As of February 2019, it is not accepted yet.
 374      * See https://github.com/mpi-forum/mpi-issues/issues/65 */
 375     [OMPI_DATATYPE_MPI_SHORT_FLOAT] = &ompi_mpi_short_float.dt,
 376     [OMPI_DATATYPE_MPI_C_SHORT_FLOAT_COMPLEX] = &ompi_mpi_c_short_float_complex.dt,
 377 
 378     [OMPI_DATATYPE_MPI_UNAVAILABLE] = &ompi_mpi_unavailable.dt,
 379 };
 380 
 381 opal_pointer_array_t ompi_datatype_f_to_c_table = {{0}};
 382 
 383 #define COPY_DATA_DESC( PDST, PSRC )                                                 \
 384     do {                                                                             \
 385         (PDST)->super.flags    = (PSRC)->super.flags;                                \
 386         (PDST)->super.id       = (PSRC)->super.id;                                   \
 387         (PDST)->super.bdt_used = (PSRC)->super.bdt_used;                             \
 388         (PDST)->super.size     = (PSRC)->super.size;                                 \
 389         (PDST)->super.true_lb  = (PSRC)->super.true_lb;                              \
 390         (PDST)->super.true_ub  = (PSRC)->super.true_ub;                              \
 391         (PDST)->super.lb       = (PSRC)->super.lb;                                   \
 392         (PDST)->super.ub       = (PSRC)->super.ub;                                   \
 393         (PDST)->super.align    = (PSRC)->super.align;                                \
 394         (PDST)->super.nbElems  = (PSRC)->super.nbElems;                              \
 395         (PDST)->super.desc     = (PSRC)->super.desc;                                 \
 396         (PDST)->super.opt_desc = (PSRC)->super.opt_desc;                             \
 397         (PDST)->packed_description = (PSRC)->packed_description;                     \
 398         (PSRC)->packed_description = 0;                                              \
 399         /* transfer the ptypes */                                                    \
 400         (PDST)->super.ptypes = (PSRC)->super.ptypes;                                 \
 401         (PSRC)->super.ptypes = NULL;                                                 \
 402     } while(0)
 403 
 404 #define DECLARE_MPI2_COMPOSED_STRUCT_DDT( PDATA, MPIDDT, MPIDDTNAME, type1, type2, MPIType1, MPIType2, FLAGS) \
 405     do {                                                                             \
 406         struct { type1 v1; type2 v2; } s[2];                                         \
 407         ompi_datatype_t *types[2], *ptype;                                           \
 408         int bLength[2] = {1, 1};                                                     \
 409         ptrdiff_t base, displ[2];                                                    \
 410                                                                                      \
 411         types[0] = (ompi_datatype_t*)ompi_datatype_basicDatatypes[MPIType1];         \
 412         types[1] = (ompi_datatype_t*)ompi_datatype_basicDatatypes[MPIType2];         \
 413         base = (ptrdiff_t)(&(s[0]));                                                 \
 414         displ[0] = (ptrdiff_t)(&(s[0].v1));                                          \
 415         displ[0] -= base;                                                            \
 416         displ[1] = (ptrdiff_t)(&(s[0].v2));                                          \
 417         displ[1] -= base;                                                            \
 418                                                                                      \
 419         ompi_datatype_create_struct( 2, bLength, displ, types, &ptype );             \
 420         displ[0] = (ptrdiff_t)(&(s[1]));                                             \
 421         displ[0] -= base;                                                            \
 422         if( displ[0] != (displ[1] + (ptrdiff_t)sizeof(type2)) )                      \
 423             ptype->super.ub = displ[0];  /* force a new extent for the datatype */   \
 424         ptype->super.flags |= (FLAGS);                                               \
 425         ptype->id = MPIDDT;                                                          \
 426         ompi_datatype_commit( &ptype );                                              \
 427         COPY_DATA_DESC( PDATA, ptype );                                              \
 428         (PDATA)->super.flags &= ~OPAL_DATATYPE_FLAG_PREDEFINED;                      \
 429         (PDATA)->super.flags |= OMPI_DATATYPE_FLAG_PREDEFINED |                      \
 430                                 OMPI_DATATYPE_FLAG_ANALYZED   |                      \
 431                                 OMPI_DATATYPE_FLAG_MONOTONIC;                        \
 432         ptype->super.desc.desc = NULL;                                               \
 433         ptype->super.opt_desc.desc = NULL;                                           \
 434         OBJ_RELEASE( ptype );                                                        \
 435         opal_string_copy( (PDATA)->name, MPIDDTNAME, MPI_MAX_OBJECT_NAME );          \
 436     } while(0)
 437 
 438 #define DECLARE_MPI2_COMPOSED_BLOCK_DDT( PDATA, MPIDDT, MPIDDTNAME, MPIType, FLAGS ) \
 439     do {                                                                             \
 440         ompi_datatype_t *ptype;                                                      \
 441         ompi_datatype_create_contiguous( 2, ompi_datatype_basicDatatypes[MPIType], &ptype );   \
 442         ptype->super.flags |= (FLAGS);                                               \
 443         ptype->super.id = (MPIDDT);                                                  \
 444         ompi_datatype_commit( &ptype );                                              \
 445         COPY_DATA_DESC( (PDATA), ptype );                                            \
 446         (PDATA)->super.flags &= ~OPAL_DATATYPE_FLAG_PREDEFINED;                      \
 447         (PDATA)->super.flags |= OMPI_DATATYPE_FLAG_PREDEFINED |                      \
 448                                 OMPI_DATATYPE_FLAG_ANALYZED   |                      \
 449                                 OMPI_DATATYPE_FLAG_MONOTONIC;                        \
 450         ptype->super.desc.desc = NULL;                                               \
 451         ptype->super.opt_desc.desc = NULL;                                           \
 452         OBJ_RELEASE( ptype );                                                        \
 453         opal_string_copy( (PDATA)->name, (MPIDDTNAME), MPI_MAX_OBJECT_NAME );        \
 454     } while(0)
 455 
 456 #define DECLARE_MPI_SYNONYM_DDT( PDATA, MPIDDTNAME, PORIGDDT)                        \
 457     do {                                                                             \
 458         /* just memcpy as it's easier this way */                                    \
 459         memcpy( (PDATA), (PORIGDDT), sizeof(ompi_datatype_t) );                      \
 460         opal_string_copy( (PDATA)->name, MPIDDTNAME, MPI_MAX_OBJECT_NAME );          \
 461         /* forget the language flag */                                               \
 462         (PDATA)->super.flags &= ~OMPI_DATATYPE_FLAG_DATA_LANGUAGE;                   \
 463         (PDATA)->super.flags &= ~OPAL_DATATYPE_FLAG_PREDEFINED;                      \
 464         (PDATA)->super.flags |= OMPI_DATATYPE_FLAG_PREDEFINED |                      \
 465                                 OMPI_DATATYPE_FLAG_ANALYZED   |                      \
 466                                 OMPI_DATATYPE_FLAG_MONOTONIC;                        \
 467     } while(0)
 468 
 469 
 470 int32_t ompi_datatype_init( void )
 471 {
 472     int32_t i;
 473 
 474     opal_datatype_init();
 475 
 476     /* Create the f2c translation table */
 477     OBJ_CONSTRUCT(&ompi_datatype_f_to_c_table, opal_pointer_array_t);
 478     if( OPAL_SUCCESS != opal_pointer_array_init(&ompi_datatype_f_to_c_table,
 479                                                 64, OMPI_FORTRAN_HANDLE_MAX, 32)) {
 480         return OMPI_ERROR;
 481     }
 482     /* All temporary datatypes created on the following statement will get registered
 483      * on the f2c table. But as they get destroyed they will (hopefully) get unregistered
 484      * so later when we start registering the real datatypes they will get the index
 485      * in mpif.h
 486      */
 487 
 488 
 489     /* Now the predefined MPI2 datatypes (they should last forever!) */
 490     DECLARE_MPI2_COMPOSED_BLOCK_DDT( &ompi_mpi_2int.dt, OMPI_DATATYPE_2INT, "MPI_2INT",
 491                                      OMPI_DATATYPE_MPI_INT,
 492                                      OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
 493     DECLARE_MPI2_COMPOSED_BLOCK_DDT( &ompi_mpi_2integer.dt, OMPI_DATATYPE_2INTEGER, "MPI_2INTEGER",
 494                                      OMPI_DATATYPE_MPI_INTEGER,
 495                                      OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_INT);
 496     DECLARE_MPI2_COMPOSED_BLOCK_DDT( &ompi_mpi_2real.dt, OMPI_DATATYPE_2REAL, "MPI_2REAL",
 497                                      OMPI_DATATYPE_MPI_FLOAT,
 498                                      OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_FLOAT );
 499     DECLARE_MPI2_COMPOSED_BLOCK_DDT( &ompi_mpi_2dblprec.dt, OMPI_DATATYPE_2DBLPREC, "MPI_2DOUBLE_PRECISION",
 500                                      OMPI_DATATYPE_MPI_DOUBLE,
 501                                      OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_FLOAT );
 502     DECLARE_MPI2_COMPOSED_BLOCK_DDT( &ompi_mpi_2cplex.dt, OMPI_DATATYPE_2COMPLEX, "MPI_2COMPLEX",
 503                                      OMPI_DATATYPE_MPI_COMPLEX,
 504                                      OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 505     DECLARE_MPI2_COMPOSED_BLOCK_DDT( &ompi_mpi_2dblcplex.dt, OMPI_DATATYPE_2DOUBLE_COMPLEX, "MPI_2DOUBLE_COMPLEX",
 506                                      OMPI_DATATYPE_MPI_DOUBLE_COMPLEX,
 507                                      OMPI_DATATYPE_FLAG_DATA_FORTRAN | OMPI_DATATYPE_FLAG_DATA_COMPLEX );
 508 
 509     DECLARE_MPI2_COMPOSED_STRUCT_DDT( &ompi_mpi_float_int.dt, OMPI_DATATYPE_FLOAT_INT, "MPI_FLOAT_INT",
 510                                       float, int,
 511                                       OMPI_DATATYPE_MPI_FLOAT, OMPI_DATATYPE_MPI_INT,
 512                                       OMPI_DATATYPE_FLAG_DATA_C );
 513     DECLARE_MPI2_COMPOSED_STRUCT_DDT( &ompi_mpi_double_int.dt, OMPI_DATATYPE_DOUBLE_INT, "MPI_DOUBLE_INT",
 514                                       double, int,
 515                                       OMPI_DATATYPE_MPI_DOUBLE, OMPI_DATATYPE_MPI_INT,
 516                                       OMPI_DATATYPE_FLAG_DATA_C );
 517     DECLARE_MPI2_COMPOSED_STRUCT_DDT( &ompi_mpi_long_int.dt, OMPI_DATATYPE_LONG_INT, "MPI_LONG_INT",
 518                                       long, int,
 519                                       OMPI_DATATYPE_MPI_LONG, OMPI_DATATYPE_MPI_INT,
 520                                       OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
 521     DECLARE_MPI2_COMPOSED_STRUCT_DDT( &ompi_mpi_short_int.dt, OMPI_DATATYPE_SHORT_INT, "MPI_SHORT_INT",
 522                                       short, int,
 523                                       OMPI_DATATYPE_MPI_SHORT, OMPI_DATATYPE_MPI_INT,
 524                                       OMPI_DATATYPE_FLAG_DATA_C | OMPI_DATATYPE_FLAG_DATA_INT );
 525     DECLARE_MPI2_COMPOSED_STRUCT_DDT( &ompi_mpi_longdbl_int.dt, OMPI_DATATYPE_LONG_DOUBLE_INT, "MPI_LONG_DOUBLE_INT",
 526                                       long double, int,
 527                                       OMPI_DATATYPE_MPI_LONG_DOUBLE, OMPI_DATATYPE_MPI_INT,
 528                                       OMPI_DATATYPE_FLAG_DATA_C );
 529 
 530 
 531     /* Copy the desc pointer from the <OMPI_DATATYPE_MPI_MAX_PREDEFINED datatypes to
 532        the synonym types */
 533 
 534     /* Start to populate the f2c index translation table */
 535 
 536     /* The order of the data registration should be the same as the
 537      * one in the mpif.h file. Any modification here should be
 538      * reflected there !!!  Do the Fortran types first so that mpif.h
 539      * can have consecutive, dense numbers. */
 540 
 541     /* This macro makes everything significantly easier to read below.
 542        All hail the moog!  :-) */
 543 
 544 #define MOOG(name, index)                                               \
 545     do {                                                                \
 546         ompi_mpi_##name.dt.d_f_to_c_index =                             \
 547             opal_pointer_array_add(&ompi_datatype_f_to_c_table, &ompi_mpi_##name); \
 548         if( ompi_datatype_number_of_predefined_data < (ompi_mpi_##name).dt.d_f_to_c_index ) \
 549             ompi_datatype_number_of_predefined_data = (ompi_mpi_##name).dt.d_f_to_c_index; \
 550         assert( (index) == ompi_mpi_##name.dt.d_f_to_c_index );         \
 551     } while(0)
 552 
 553     /*
 554      * This MUST match the order of ompi/include/mpif-values.pl
 555      * Any change will break binary compatibility of Fortran programs.
 556      */
 557     MOOG(datatype_null, 0);
 558     MOOG(byte, 1);
 559     MOOG(packed, 2);
 560     MOOG(ub, 3);
 561     MOOG(lb, 4);
 562     MOOG(character, 5);
 563     MOOG(logical, 6);
 564     MOOG(integer, 7);
 565     MOOG(integer1, 8);
 566     MOOG(integer2, 9);
 567     MOOG(integer4, 10);
 568     MOOG(integer8, 11);
 569     MOOG(integer16, 12);
 570     MOOG(real, 13);
 571     MOOG(real4, 14);
 572     MOOG(real8, 15);
 573     MOOG(real16, 16);
 574     MOOG(dblprec, 17);
 575     MOOG(cplex, 18);
 576     MOOG(complex8, 19);
 577     MOOG(complex16, 20);
 578     MOOG(complex32, 21);
 579     MOOG(dblcplex, 22);
 580     MOOG(2real, 23);
 581     MOOG(2dblprec, 24);
 582     MOOG(2integer, 25);
 583     MOOG(2cplex, 26);
 584     MOOG(2dblcplex, 27);
 585     MOOG(real2, 28);
 586     MOOG(logical1, 29);
 587     MOOG(logical2, 30);
 588     MOOG(logical4, 31);
 589     MOOG(logical8, 32);
 590 
 591     /* Now the C types */
 592 
 593     MOOG(wchar, 33);
 594     MOOG(char, 34);
 595     MOOG(unsigned_char, 35);
 596     MOOG(signed_char, 36);
 597     MOOG(short, 37);
 598     MOOG(unsigned_short, 38);
 599     MOOG(int, 39);
 600     MOOG(unsigned, 40);
 601     MOOG(long, 41);
 602     MOOG(unsigned_long, 42);
 603     MOOG(long_long_int, 43);
 604     MOOG(unsigned_long_long, 44);
 605 
 606     MOOG(float, 45);
 607     MOOG(double, 46);
 608     MOOG(long_double, 47);
 609 
 610     MOOG(float_int, 48);
 611     MOOG(double_int, 49);
 612     MOOG(longdbl_int, 50);
 613     MOOG(long_int, 51);
 614     MOOG(2int, 52);
 615     MOOG(short_int, 53);
 616 
 617     /* C++ types */
 618 
 619     MOOG(cxx_bool, 54);
 620     MOOG(cxx_cplex, 55);
 621     MOOG(cxx_dblcplex, 56);
 622     MOOG(cxx_ldblcplex, 57);
 623 
 624     /* MPI 2.2 types */
 625     MOOG(int8_t, 58);
 626     MOOG(uint8_t, 59);
 627     MOOG(int16_t, 60);
 628     MOOG(uint16_t, 61);
 629     MOOG(int32_t, 62);
 630     MOOG(uint32_t, 63);
 631     MOOG(int64_t, 64);
 632     MOOG(uint64_t, 65);
 633     MOOG(aint, 66);
 634     MOOG(offset, 67);
 635     MOOG(c_bool, 68);
 636     MOOG(c_float_complex, 69);
 637     MOOG(c_double_complex, 70);
 638     MOOG(c_long_double_complex, 71);
 639 
 640     /* MPI 3.0 types */
 641     MOOG(count, 72);
 642 
 643     /* Datatype missing in old Open MPI */
 644     MOOG(complex4, 73);
 645 
 646     /* Datatypes proposed to the MPI Forum in June 2017 for proposal in
 647      * the MPI 4.0 standard. As of February 2019, it is not accepted yet.
 648      * See https://github.com/mpi-forum/mpi-issues/issues/65 */
 649     MOOG(short_float, 74);
 650     MOOG(c_short_float_complex, 75);
 651     MOOG(cxx_sfltcplex, 76);
 652 
 653     /**
 654      * Now make sure all non-contiguous types are marked as such.
 655      */
 656     for( i = 0; i < ompi_mpi_count.dt.d_f_to_c_index; i++ ) {
 657         opal_datatype_t* datatype = (opal_datatype_t*)opal_pointer_array_get_item(&ompi_datatype_f_to_c_table, i );
 658 
 659         if( (datatype->ub - datatype->lb) == (ptrdiff_t)datatype->size ) {
 660             datatype->flags |= OPAL_DATATYPE_FLAG_NO_GAPS;
 661         } else {
 662             datatype->flags &= ~OPAL_DATATYPE_FLAG_NO_GAPS;
 663         }
 664     }
 665     ompi_datatype_default_convertors_init();
 666     return OMPI_SUCCESS;
 667 }
 668 
 669 
 670 int32_t ompi_datatype_finalize( void )
 671 {
 672     /* As the synonyms are just copies of the internal data we should not free them.
 673      * Anyway they are over the limit of OMPI_DATATYPE_MPI_MAX_PREDEFINED so they will never get freed.
 674      */
 675 
 676     /* As they are statically allocated they cannot be released.
 677      * But we can call OBJ_DESTRUCT, just to free all internally allocated ressources.
 678      */
 679     for( int i = 0; i < ompi_mpi_count.dt.d_f_to_c_index; i++ ) {
 680         opal_datatype_t* datatype = (opal_datatype_t*)opal_pointer_array_get_item(&ompi_datatype_f_to_c_table, i );
 681         OBJ_DESTRUCT(datatype);
 682     }
 683 
 684     /* Get rid of the Fortran2C translation table */
 685     OBJ_DESTRUCT(&ompi_datatype_f_to_c_table);
 686 
 687     /* release the local convertors (external32 and local) */
 688     ompi_datatype_default_convertors_fini();
 689 
 690     /* don't call opal_datatype_finalize () as it no longer exists. the function will be called
 691      * opal_finalize_util (). */
 692 
 693     return OMPI_SUCCESS;
 694 }
 695 
 696 
 697 #if OPAL_ENABLE_DEBUG
 698 /*
 699  * Set a breakpoint to this function in your favorite debugger
 700  * to make it stop on all pack and unpack errors.
 701  */
 702 int ompi_datatype_safeguard_pointer_debug_breakpoint( const void* actual_ptr, int length,
 703                                                  const void* initial_ptr,
 704                                                  const ompi_datatype_t* pData,
 705                                                  int count )
 706 {
 707     return 0;
 708 }
 709 #endif  /* OPAL_ENABLE_DEBUG */
 710 
 711 
 712 /********************************************************
 713  * Data dumping functions
 714  ********************************************************/
 715 
 716 static int _ompi_dump_data_flags( unsigned short usflags, char* ptr, size_t length )
 717 {
 718     int index = 0;
 719     if( length < 22 ) return 0;
 720     /* The lower-level part is the responsibility of opal_datatype_dump_data_flags */
 721     index += opal_datatype_dump_data_flags (usflags, ptr, length);
 722 
 723     /* Which kind of datatype is that */
 724     switch( usflags & OMPI_DATATYPE_FLAG_DATA_LANGUAGE ) {
 725     case OMPI_DATATYPE_FLAG_DATA_C:
 726         ptr[12] = ' '; ptr[13] = 'C'; ptr[14] = ' '; break;
 727     case OMPI_DATATYPE_FLAG_DATA_CPP:
 728         ptr[12] = 'C'; ptr[13] = 'P'; ptr[14] = 'P'; break;
 729     case OMPI_DATATYPE_FLAG_DATA_FORTRAN:
 730         ptr[12] = 'F'; ptr[13] = '7'; ptr[14] = '7'; break;
 731     default:
 732         if( usflags & OMPI_DATATYPE_FLAG_PREDEFINED ) {
 733             ptr[12] = 'E'; ptr[13] = 'R'; ptr[14] = 'R'; break;
 734         }
 735     }
 736     switch( usflags & OMPI_DATATYPE_FLAG_DATA_TYPE ) {
 737     case OMPI_DATATYPE_FLAG_DATA_INT:
 738         ptr[17] = 'I'; ptr[18] = 'N'; ptr[19] = 'T'; break;
 739     case OMPI_DATATYPE_FLAG_DATA_FLOAT:
 740         ptr[17] = 'F'; ptr[18] = 'L'; ptr[19] = 'T'; break;
 741     case OMPI_DATATYPE_FLAG_DATA_COMPLEX:
 742         ptr[17] = 'C'; ptr[18] = 'P'; ptr[19] = 'L'; break;
 743     default:
 744         if( usflags & OMPI_DATATYPE_FLAG_PREDEFINED ) {
 745             ptr[17] = 'E'; ptr[18] = 'R'; ptr[19] = 'R'; break;
 746         }
 747     }
 748     return index;
 749 }
 750 
 751 
 752 void ompi_datatype_dump( const ompi_datatype_t* pData )
 753 {
 754     size_t length;
 755     int index = 0;
 756     char* buffer;
 757 
 758     length = pData->super.opt_desc.used + pData->super.desc.used;
 759     length = length * 100 + 500;
 760     buffer = (char*)malloc( length );
 761     index += snprintf( buffer, length - index,
 762                        "Datatype %p[%s] id %d size %" PRIsize_t " align %u opal_id %u length %" PRIsize_t " used %" PRIsize_t "\n"
 763                        "true_lb %td true_ub %td (true_extent %td) lb %td ub %td (extent %td)\n"
 764                        "nbElems %" PRIsize_t " loops %u flags %X (",
 765                        (void*)pData, pData->name, pData->id,
 766                        pData->super.size, pData->super.align, (uint32_t)pData->super.id, pData->super.desc.length, pData->super.desc.used,
 767                        pData->super.true_lb, pData->super.true_ub, pData->super.true_ub - pData->super.true_lb,
 768                        pData->super.lb, pData->super.ub, pData->super.ub - pData->super.lb,
 769                        pData->super.nbElems, pData->super.loops, (int)pData->super.flags );
 770     /* dump the flags */
 771     if( ompi_datatype_is_predefined(pData) ) {
 772         index += snprintf( buffer + index, length - index, "predefined " );
 773     } else {
 774         if( pData->super.flags & OPAL_DATATYPE_FLAG_COMMITTED ) index += snprintf( buffer + index, length - index, "committed " );
 775         if( pData->super.flags & OPAL_DATATYPE_FLAG_CONTIGUOUS) index += snprintf( buffer + index, length - index, "contiguous " );
 776     }
 777     index += snprintf( buffer + index, length - index, ")" );
 778     index += _ompi_dump_data_flags( pData->super.flags, buffer + index, length - index );
 779     {
 780         index += snprintf( buffer + index, length - index, "\n   contain " );
 781         index += opal_datatype_contain_basic_datatypes( &pData->super, buffer + index, length - index );
 782         index += snprintf( buffer + index, length - index, "\n" );
 783     }
 784     if( (pData->super.opt_desc.desc != pData->super.desc.desc) && (NULL != pData->super.opt_desc.desc) ) {
 785         /* If the data is already committed print everything including the last
 786          * fake DT_END_LOOP entry.
 787          */
 788         index += opal_datatype_dump_data_desc( pData->super.desc.desc, pData->super.desc.used + 1, buffer + index, length - index );
 789         index += snprintf( buffer + index, length - index, "Optimized description \n" );
 790         index += opal_datatype_dump_data_desc( pData->super.opt_desc.desc, pData->super.opt_desc.used + 1, buffer + index, length - index );
 791     } else {
 792         index += opal_datatype_dump_data_desc( pData->super.desc.desc, pData->super.desc.used, buffer + index, length - index );
 793         index += snprintf( buffer + index, length - index, "No optimized description\n" );
 794     }
 795     buffer[index] = '\0';  /* make sure we end the string with 0 */
 796     opal_output( 0, "%s\n", buffer );
 797 
 798     ompi_datatype_print_args ( pData );
 799 
 800     free(buffer);
 801 }

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