Blame src/include/mpir_datatype.h

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2001 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 *
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#ifndef MPIR_DATATYPE_H_INCLUDED
Packit Service c5cf8c
#define MPIR_DATATYPE_H_INCLUDED
Packit Service c5cf8c
Packit Service c5cf8c
/* This value should be set to greatest value used as the type index suffix in
Packit Service c5cf8c
 * the predefined handles.  That is, look at the last two hex digits of all
Packit Service c5cf8c
 * predefined datatype handles, take the greatest one, and convert it to decimal
Packit Service c5cf8c
 * here. */
Packit Service c5cf8c
/* FIXME calculating this value this way is foolish, we should make this more
Packit Service c5cf8c
 * automatic and less error prone */
Packit Service c5cf8c
/* FIXME: Given that this is relatively static, an adequate alternative is
Packit Service c5cf8c
   to provide a check that this value is valid. */
Packit Service c5cf8c
#define MPIR_DATATYPE_N_BUILTIN 70
Packit Service c5cf8c
#define MPIR_DTYPE_BEGINNING  0
Packit Service c5cf8c
#define MPIR_DTYPE_END       -1
Packit Service c5cf8c
Packit Service c5cf8c
#ifndef MPIR_DATATYPE_PREALLOC
Packit Service c5cf8c
#define MPIR_DATATYPE_PREALLOC 8
Packit Service c5cf8c
#endif /* MPIR_DATATYPE_PREALLOC */
Packit Service c5cf8c
Packit Service c5cf8c
/*S
Packit Service c5cf8c
  MPIR_Datatype_contents - Holds envelope and contents data for a given
Packit Service c5cf8c
                           datatype
Packit Service c5cf8c
Packit Service c5cf8c
  Notes:
Packit Service c5cf8c
  Space is allocated beyond the structure itself in order to hold the
Packit Service c5cf8c
  arrays of types, ints, and aints, in that order.
Packit Service c5cf8c
Packit Service c5cf8c
  S*/
Packit Service c5cf8c
typedef struct MPIR_Datatype_contents {
Packit Service c5cf8c
    int combiner;
Packit Service c5cf8c
    int nr_ints;
Packit Service c5cf8c
    int nr_aints;
Packit Service c5cf8c
    int nr_types;
Packit Service c5cf8c
    /* space allocated beyond structure used to store the types[],
Packit Service c5cf8c
     * ints[], and aints[], in that order.
Packit Service c5cf8c
     */
Packit Service c5cf8c
} MPIR_Datatype_contents;
Packit Service c5cf8c
Packit Service c5cf8c
/* Datatype Structure */
Packit Service c5cf8c
/*S
Packit Service c5cf8c
  MPIR_Datatype - Description of the MPID Datatype structure
Packit Service c5cf8c
Packit Service c5cf8c
  Notes:
Packit Service c5cf8c
  The 'ref_count' is needed for nonblocking operations such as
Packit Service c5cf8c
.vb
Packit Service c5cf8c
   MPI_Type_struct(... , &newtype);
Packit Service c5cf8c
   MPI_Irecv(buf, 1000, newtype, ..., &request);
Packit Service c5cf8c
   MPI_Type_free(&newtype);
Packit Service c5cf8c
   ...
Packit Service c5cf8c
   MPI_Wait(&request, &status);
Packit Service c5cf8c
.ve
Packit Service c5cf8c
Packit Service c5cf8c
  Module:
Packit Service c5cf8c
  Datatype-DS
Packit Service c5cf8c
Packit Service c5cf8c
  Notes:
Packit Service c5cf8c
Packit Service c5cf8c
  Alternatives:
Packit Service c5cf8c
  The following alternatives for the layout of this structure were considered.
Packit Service c5cf8c
  Most were not chosen because any benefit in performance or memory
Packit Service c5cf8c
  efficiency was outweighed by the added complexity of the implementation.
Packit Service c5cf8c
Packit Service c5cf8c
  A number of fields contain only boolean inforation ('is_contig',
Packit Service c5cf8c
  'has_sticky_ub', 'has_sticky_lb', 'is_permanent', 'is_committed').  These
Packit Service c5cf8c
  could be combined and stored in a single bit vector.
Packit Service c5cf8c
Packit Service c5cf8c
  'MPI_Type_dup' could be implemented with a shallow copy, where most of the
Packit Service c5cf8c
  data fields, would not be copied into the new object created by
Packit Service c5cf8c
  'MPI_Type_dup'; instead, the new object could point to the data fields in
Packit Service c5cf8c
  the old object.  However, this requires more code to make sure that fields
Packit Service c5cf8c
  are found in the correct objects and that deleting the old object doesn't
Packit Service c5cf8c
  invalidate the dup'ed datatype.
Packit Service c5cf8c
Packit Service c5cf8c
  Originally we attempted to keep contents/envelope data in a non-optimized
Packit Service c5cf8c
  dataloop.  The subarray and darray types were particularly problematic,
Packit Service c5cf8c
  and eventually we decided it would be simpler to just keep contents/
Packit Service c5cf8c
  envelope data in arrays separately.
Packit Service c5cf8c
Packit Service c5cf8c
  Earlier versions of the ADI used a single API to change the 'ref_count',
Packit Service c5cf8c
  with each MPI object type having a separate routine.  Since reference
Packit Service c5cf8c
  count changes are always up or down one, and since all MPI objects
Packit Service c5cf8c
  are defined to have the 'ref_count' field in the same place, the current
Packit Service c5cf8c
  ADI3 API uses two routines, 'MPIR_Object_add_ref' and
Packit Service c5cf8c
  'MPIR_Object_release_ref', to increment and decrement the reference count.
Packit Service c5cf8c
Packit Service c5cf8c
  S*/
Packit Service c5cf8c
struct MPIR_Datatype {
Packit Service c5cf8c
    /* handle and ref_count are filled in by MPIR_Handle_obj_alloc() */
Packit Service c5cf8c
    MPIR_OBJECT_HEADER;         /* adds handle and ref_count fields */
Packit Service c5cf8c
Packit Service c5cf8c
    /* basic parameters for datatype, accessible via MPI calls */
Packit Service c5cf8c
    MPI_Aint size;              /* MPI_Count could be 128 bits, so use MPI_Aint */
Packit Service c5cf8c
    MPI_Aint extent, ub, lb, true_ub, true_lb;
Packit Service c5cf8c
Packit Service c5cf8c
    /* chars affecting subsequent datatype processing and creation */
Packit Service c5cf8c
    MPI_Aint alignsize;
Packit Service c5cf8c
    int has_sticky_ub, has_sticky_lb;
Packit Service c5cf8c
    int is_permanent;           /* non-zero if datatype is a predefined type */
Packit Service c5cf8c
    int is_committed;
Packit Service c5cf8c
Packit Service c5cf8c
    /* element information; used for accumulate and get elements
Packit Service c5cf8c
     * basic_type: describes basic type (predefined type). If the
Packit Service c5cf8c
     *             type is composed of the same basic type, it is
Packit Service c5cf8c
     *             set to that type, otherwise it is set to MPI_DATATYPE_NULL.
Packit Service c5cf8c
     * n_builtin_elements: refers to the number of builtin type elements.
Packit Service c5cf8c
     * builtin_element_size: refers to the size of builtin type. If the
Packit Service c5cf8c
     *                       type is composed of the same builtin type,
Packit Service c5cf8c
     *                       it is set to size of that type, otherwise it
Packit Service c5cf8c
     *                       is set to -1.
Packit Service c5cf8c
     */
Packit Service c5cf8c
    int basic_type;
Packit Service c5cf8c
    MPI_Aint n_builtin_elements;
Packit Service c5cf8c
    MPI_Aint builtin_element_size;
Packit Service c5cf8c
Packit Service c5cf8c
    /* information on contiguity of type, for processing shortcuts.
Packit Service c5cf8c
     *
Packit Service c5cf8c
     * is_contig is non-zero only if N instances of the type would be
Packit Service c5cf8c
     * contiguous.
Packit Service c5cf8c
     */
Packit Service c5cf8c
    int is_contig;
Packit Service c5cf8c
    /* Upper bound on the number of contig blocks for one instance.
Packit Service c5cf8c
     * It is not trivial to calculate the *real* number of contig
Packit Service c5cf8c
     * blocks in the case where old datatype is non-contiguous
Packit Service c5cf8c
     */
Packit Service c5cf8c
    MPI_Aint max_contig_blocks;
Packit Service c5cf8c
Packit Service c5cf8c
    /* pointer to contents and envelope data for the datatype */
Packit Service c5cf8c
    MPIR_Datatype_contents *contents;
Packit Service c5cf8c
Packit Service c5cf8c
    /* dataloop members, including a pointer to the loop, the size in bytes,
Packit Service c5cf8c
     * and a depth used to verify that we can process it (limited stack depth
Packit Service c5cf8c
     */
Packit Service c5cf8c
    struct MPIR_Dataloop *dataloop;     /* might be optimized for homogenous */
Packit Service c5cf8c
    MPI_Aint dataloop_size;
Packit Service c5cf8c
    int dataloop_depth;
Packit Service c5cf8c
    /* MPI-2 attributes and name */
Packit Service c5cf8c
    struct MPIR_Attribute *attributes;
Packit Service c5cf8c
    char name[MPI_MAX_OBJECT_NAME];
Packit Service c5cf8c
Packit Service c5cf8c
    /* not yet used; will be used to track what processes have cached
Packit Service c5cf8c
     * copies of this type.
Packit Service c5cf8c
     */
Packit Service c5cf8c
    int32_t cache_id;
Packit Service c5cf8c
    /* MPID_Lpidmask mask; */
Packit Service c5cf8c
Packit Service c5cf8c
    /* int (*free_fn)(struct MPIR_Datatype *); *//* Function to free this datatype */
Packit Service c5cf8c
Packit Service c5cf8c
    /* Other, device-specific information */
Packit Service c5cf8c
#ifdef MPID_DEV_DATATYPE_DECL
Packit Service c5cf8c
     MPID_DEV_DATATYPE_DECL
Packit Service c5cf8c
#endif
Packit Service c5cf8c
};
Packit Service c5cf8c
Packit Service c5cf8c
extern MPIR_Datatype MPIR_Datatype_builtin[MPIR_DATATYPE_N_BUILTIN];
Packit Service c5cf8c
extern MPIR_Datatype MPIR_Datatype_direct[];
Packit Service c5cf8c
extern MPIR_Object_alloc_t MPIR_Datatype_mem;
Packit Service c5cf8c
Packit Service c5cf8c
static inline void MPIR_Datatype_free(MPIR_Datatype * ptr);
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_ptr_add_ref(datatype_ptr) MPIR_Object_add_ref((datatype_ptr))
Packit Service c5cf8c
Packit Service c5cf8c
/* to be used only after MPIR_Datatype_valid_ptr(); the check on
Packit Service c5cf8c
 * err == MPI_SUCCESS ensures that we won't try to dereference the
Packit Service c5cf8c
 * pointer if something has already been detected as wrong.
Packit Service c5cf8c
 */
Packit Service c5cf8c
#define MPIR_Datatype_committed_ptr(ptr,err) do {               \
Packit Service c5cf8c
    if ((err == MPI_SUCCESS) && !((ptr)->is_committed))         \
Packit Service c5cf8c
        err = MPIR_Err_create_code(MPI_SUCCESS,                 \
Packit Service c5cf8c
                                   MPIR_ERR_RECOVERABLE,        \
Packit Service c5cf8c
                                   FCNAME,                      \
Packit Service c5cf8c
                                   __LINE__,                    \
Packit Service c5cf8c
                                   MPI_ERR_TYPE,                \
Packit Service c5cf8c
                                   "**dtypecommit",             \
Packit Service c5cf8c
                                   0);                          \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_get_basic_size(a) (((a)&0x0000ff00)>>8)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_get_basic_type(a,basic_type_) do {            \
Packit Service c5cf8c
    void *ptr;                                                      \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                                   \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                                    \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC);  \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);             \
Packit Service c5cf8c
            basic_type_ = ((MPIR_Datatype *) ptr)->basic_type;      \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                                  \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                                \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));   \
Packit Service c5cf8c
            basic_type_ = ((MPIR_Datatype *) ptr)->basic_type;      \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                                   \
Packit Service c5cf8c
            basic_type_ = a;                                        \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                                   \
Packit Service c5cf8c
        default:                                                    \
Packit Service c5cf8c
         basic_type_ = 0;                                           \
Packit Service c5cf8c
         break;                                                     \
Packit Service c5cf8c
                                                                    \
Packit Service c5cf8c
    }                                                               \
Packit Service c5cf8c
    /* This macro returns the builtin type, if 'basic_type' is not  \
Packit Service c5cf8c
     * a builtin type, it must be a pair type composed of different \
Packit Service c5cf8c
     * builtin types, so we return MPI_DATATYPE_NULL here.          \
Packit Service c5cf8c
     */                                                             \
Packit Service c5cf8c
    if (HANDLE_GET_KIND(basic_type_) != HANDLE_KIND_BUILTIN)        \
Packit Service c5cf8c
        basic_type_ = MPI_DATATYPE_NULL;                            \
Packit Service c5cf8c
 } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_get_ptr(a,ptr)   MPIR_Getb_ptr(Datatype,DATATYPE,a,0x000000ff,ptr)
Packit Service c5cf8c
Packit Service c5cf8c
/* Note: Probably there is some clever way to build all of these from a macro.
Packit Service c5cf8c
 */
Packit Service c5cf8c
#define MPIR_Datatype_get_size_macro(a,size_) do {                     \
Packit Service c5cf8c
    void *ptr;                                                          \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                                       \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                                        \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC);      \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);                 \
Packit Service c5cf8c
            size_ = ((MPIR_Datatype *) ptr)->size;                      \
Packit Service c5cf8c
            break;                                                      \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                                      \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                                    \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));       \
Packit Service c5cf8c
            MPIR_Assert(ptr != NULL);                                   \
Packit Service c5cf8c
            size_ = ((MPIR_Datatype *) ptr)->size;                      \
Packit Service c5cf8c
            break;                                                      \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                                       \
Packit Service c5cf8c
            size_ = MPIR_Datatype_get_basic_size(a);                    \
Packit Service c5cf8c
            break;                                                      \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                                       \
Packit Service c5cf8c
        default:                                                        \
Packit Service c5cf8c
         size_ = 0;                                                     \
Packit Service c5cf8c
         break;                                                         \
Packit Service c5cf8c
                                                                        \
Packit Service c5cf8c
    }                                                                   \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_get_extent_macro(a,extent_) do {                  \
Packit Service c5cf8c
    void *ptr;                                                          \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                                       \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                                        \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC);      \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);                 \
Packit Service c5cf8c
            extent_ = ((MPIR_Datatype *) ptr)->extent;                  \
Packit Service c5cf8c
            break;                                                      \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                                      \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                                    \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));       \
Packit Service c5cf8c
            MPIR_Assert(ptr != NULL);                                   \
Packit Service c5cf8c
            extent_ = ((MPIR_Datatype *) ptr)->extent;                  \
Packit Service c5cf8c
            break;                                                      \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                                       \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                                       \
Packit Service c5cf8c
        default:                                                        \
Packit Service c5cf8c
            extent_ = MPIR_Datatype_get_basic_size(a);  /* same as size */  \
Packit Service c5cf8c
            break;                                                      \
Packit Service c5cf8c
    }                                                                   \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
/* helper macro: takes an MPI_Datatype handle value and returns TRUE in
Packit Service c5cf8c
 * (*is_config_) if the type is contiguous */
Packit Service c5cf8c
#define MPIR_Datatype_is_contig(dtype_, is_contig_)                            \
Packit Service c5cf8c
    do {                                                                       \
Packit Service c5cf8c
        if (HANDLE_GET_KIND(dtype_) == HANDLE_KIND_BUILTIN) {                  \
Packit Service c5cf8c
            *(is_contig_) = TRUE;                                              \
Packit Service c5cf8c
        }                                                                      \
Packit Service c5cf8c
        else {                                                                 \
Packit Service c5cf8c
            MPIR_Datatype *dtp_ = NULL;                                        \
Packit Service c5cf8c
            MPIR_Datatype_get_ptr((dtype_), dtp_);                             \
Packit Service c5cf8c
            MPIR_Assert(dtp_ != NULL);                                         \
Packit Service c5cf8c
            *(is_contig_) = dtp_->is_contig;                                   \
Packit Service c5cf8c
        }                                                                      \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
/* MPIR_Datatype_ptr_release decrements the reference count on the MPIR_Datatype
Packit Service c5cf8c
 * and, if the refct is then zero, frees the MPIR_Datatype and associated
Packit Service c5cf8c
 * structures.
Packit Service c5cf8c
 */
Packit Service c5cf8c
#define MPIR_Datatype_ptr_release(datatype_ptr) do {                            \
Packit Service c5cf8c
    int inuse_;                                                             \
Packit Service c5cf8c
                                                                            \
Packit Service c5cf8c
    MPIR_Object_release_ref((datatype_ptr),&inuse_);                        \
Packit Service c5cf8c
    if (!inuse_) {                                                          \
Packit Service c5cf8c
        int lmpi_errno = MPI_SUCCESS;                                       \
Packit Service c5cf8c
     if (MPIR_Process.attr_free && datatype_ptr->attributes) {              \
Packit Service c5cf8c
         lmpi_errno = MPIR_Process.attr_free(datatype_ptr->handle,         \
Packit Service c5cf8c
                               &datatype_ptr->attributes);                 \
Packit Service c5cf8c
     }                                                                      \
Packit Service c5cf8c
     /* LEAVE THIS COMMENTED OUT UNTIL WE HAVE SOME USE FOR THE FREE_FN     \
Packit Service c5cf8c
     if (datatype_ptr->free_fn) {                                           \
Packit Service c5cf8c
         mpi_errno = (datatype_ptr->free_fn)(datatype_ptr);               \
Packit Service c5cf8c
          if (mpi_errno) {                                                  \
Packit Service c5cf8c
           MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_TYPE_FREE);                  \
Packit Service c5cf8c
           return MPIR_Err_return_comm(0, FCNAME, mpi_errno);             \
Packit Service c5cf8c
          }                                                                 \
Packit Service c5cf8c
     } */                                                                   \
Packit Service c5cf8c
        if (lmpi_errno == MPI_SUCCESS) {                                    \
Packit Service c5cf8c
         MPIR_Datatype_free(datatype_ptr);                                 \
Packit Service c5cf8c
        }                                                                   \
Packit Service c5cf8c
    }                                                                       \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
/* helper macro: takes an MPI_Datatype handle value and returns true_lb in
Packit Service c5cf8c
 * (*true_lb_) */
Packit Service c5cf8c
#define MPIR_Datatype_get_true_lb(dtype_, true_lb_)                            \
Packit Service c5cf8c
    do {                                                                       \
Packit Service c5cf8c
        if (HANDLE_GET_KIND(dtype_) == HANDLE_KIND_BUILTIN) {                  \
Packit Service c5cf8c
            *(true_lb_) = 0;                                                   \
Packit Service c5cf8c
        }                                                                      \
Packit Service c5cf8c
        else {                                                                 \
Packit Service c5cf8c
            MPIR_Datatype *dtp_ = NULL;                                        \
Packit Service c5cf8c
            MPIR_Datatype_get_ptr((dtype_), dtp_);                             \
Packit Service c5cf8c
            *(true_lb_) = dtp_->true_lb;                                       \
Packit Service c5cf8c
        }                                                                      \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_valid_ptr(ptr,err) MPIR_Valid_ptr_class(Datatype,ptr,MPI_ERR_TYPE,err)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_get_loopdepth_macro(a,depth_) do {            \
Packit Service c5cf8c
    void *ptr;                                                      \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                                   \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                                    \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC);  \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);             \
Packit Service c5cf8c
            MPIR_DATALOOP_GET_FIELD(depth_,_depth);                 \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                                  \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                                \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));   \
Packit Service c5cf8c
            MPIR_DATALOOP_GET_FIELD(depth_,_depth);                 \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                                   \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                                   \
Packit Service c5cf8c
        default:                                                    \
Packit Service c5cf8c
            depth_ = 0;                                             \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
    }                                                               \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_get_loopptr_macro(a,lptr_) do {         \
Packit Service c5cf8c
    void *ptr;                                    \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                      \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                       \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC);  \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);               \
Packit Service c5cf8c
            MPIR_DATALOOP_GET_FIELD(lptr_,);                             \
Packit Service c5cf8c
            break;                                \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                     \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                        \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));     \
Packit Service c5cf8c
            MPIR_DATALOOP_GET_FIELD(lptr_,);                             \
Packit Service c5cf8c
            break;                                \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                      \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                      \
Packit Service c5cf8c
        default:                                  \
Packit Service c5cf8c
            lptr_ = 0;                                 \
Packit Service c5cf8c
            break;                                \
Packit Service c5cf8c
    }                                             \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_get_loopsize_macro(a,depth_) do {             \
Packit Service c5cf8c
    void *ptr;                                                      \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                                   \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                                    \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC) ; \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);             \
Packit Service c5cf8c
            MPIR_DATALOOP_GET_FIELD(depth_,_size);                  \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                                  \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                                \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));   \
Packit Service c5cf8c
            MPIR_DATALOOP_GET_FIELD(depth_,_size);                  \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                                   \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                                   \
Packit Service c5cf8c
        default:                                                    \
Packit Service c5cf8c
            depth_ = 0;                                             \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
    }                                                               \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_set_loopdepth_macro(a,depth_) do {            \
Packit Service c5cf8c
    void *ptr;                                                      \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                                   \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                                    \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC);  \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);             \
Packit Service c5cf8c
            MPIR_DATALOOP_SET_FIELD(depth_,_depth);                 \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                                  \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                                \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));   \
Packit Service c5cf8c
            MPIR_DATALOOP_SET_FIELD(depth_,_depth);                 \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                                   \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                                   \
Packit Service c5cf8c
        default:                                                    \
Packit Service c5cf8c
            depth_ = 0;                                             \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
    }                                                               \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_set_loopptr_macro(a,lptr_) do {               \
Packit Service c5cf8c
    void *ptr;                                                      \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                                   \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                                    \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC);  \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);             \
Packit Service c5cf8c
            MPIR_DATALOOP_SET_FIELD(lptr_,);                        \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                                  \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                                \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));   \
Packit Service c5cf8c
            MPIR_DATALOOP_SET_FIELD(lptr_,);                        \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                                   \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                                   \
Packit Service c5cf8c
        default:                                                    \
Packit Service c5cf8c
            lptr_ = 0;                                              \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
    }                                                               \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_set_loopsize_macro(a,depth_) do {             \
Packit Service c5cf8c
    void *ptr;                                                      \
Packit Service c5cf8c
    switch (HANDLE_GET_KIND(a)) {                                   \
Packit Service c5cf8c
        case HANDLE_KIND_DIRECT:                                    \
Packit Service c5cf8c
            MPIR_Assert(HANDLE_INDEX(a) < MPIR_DATATYPE_PREALLOC);  \
Packit Service c5cf8c
            ptr = MPIR_Datatype_direct+HANDLE_INDEX(a);             \
Packit Service c5cf8c
            MPIR_DATALOOP_SET_FIELD(depth_,_size);                  \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INDIRECT:                                  \
Packit Service c5cf8c
            ptr = ((MPIR_Datatype *)                                \
Packit Service c5cf8c
             MPIR_Handle_get_ptr_indirect(a,&MPIR_Datatype_mem));   \
Packit Service c5cf8c
            MPIR_DATALOOP_SET_FIELD(depth_,_size);                  \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
        case HANDLE_KIND_INVALID:                                   \
Packit Service c5cf8c
        case HANDLE_KIND_BUILTIN:                                   \
Packit Service c5cf8c
        default:                                                    \
Packit Service c5cf8c
            depth_ = 0;                                             \
Packit Service c5cf8c
            break;                                                  \
Packit Service c5cf8c
    }                                                               \
Packit Service c5cf8c
} while (0)
Packit Service c5cf8c
Packit Service c5cf8c
/* we pessimistically assume that MPI_DATATYPE_NULL may be passed as a "valid" type
Packit Service c5cf8c
 * for send/recv when MPI_PROC_NULL is the destination/src */
Packit Service c5cf8c
#define MPIR_Datatype_add_ref_if_not_builtin(datatype_)             \
Packit Service c5cf8c
    do {                                                            \
Packit Service c5cf8c
    if ((datatype_) != MPI_DATATYPE_NULL &&                         \
Packit Service c5cf8c
        HANDLE_GET_KIND((datatype_)) != HANDLE_KIND_BUILTIN)        \
Packit Service c5cf8c
    {                                                               \
Packit Service c5cf8c
        MPIR_Datatype *dtp_ = NULL;                                 \
Packit Service c5cf8c
        MPIR_Datatype_get_ptr((datatype_), dtp_);                   \
Packit Service c5cf8c
        MPIR_Assert(dtp_ != NULL);                                  \
Packit Service c5cf8c
        MPIR_Datatype_ptr_add_ref(dtp_);                            \
Packit Service c5cf8c
    }                                                               \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_Datatype_release_if_not_builtin(datatype_)             \
Packit Service c5cf8c
    do {                                                            \
Packit Service c5cf8c
    if ((datatype_) != MPI_DATATYPE_NULL &&                         \
Packit Service c5cf8c
        HANDLE_GET_KIND((datatype_)) != HANDLE_KIND_BUILTIN)        \
Packit Service c5cf8c
    {                                                               \
Packit Service c5cf8c
        MPIR_Datatype *dtp_ = NULL;                                 \
Packit Service c5cf8c
        MPIR_Datatype_get_ptr((datatype_), dtp_);                   \
Packit Service c5cf8c
        MPIR_Assert(dtp_ != NULL);                                  \
Packit Service c5cf8c
        MPIR_Datatype_ptr_release(dtp_);                            \
Packit Service c5cf8c
    }                                                               \
Packit Service c5cf8c
    } while (0)
Packit Service c5cf8c
Packit Service c5cf8c
static inline void MPIR_Datatype_free_contents(MPIR_Datatype * dtp)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i, struct_sz = sizeof(MPIR_Datatype_contents);
Packit Service c5cf8c
    int align_sz = 8, epsilon;
Packit Service c5cf8c
    MPIR_Datatype *old_dtp;
Packit Service c5cf8c
    MPI_Datatype *array_of_types;
Packit Service c5cf8c
Packit Service c5cf8c
    if ((epsilon = struct_sz % align_sz)) {
Packit Service c5cf8c
        struct_sz += align_sz - epsilon;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* note: relies on types being first after structure */
Packit Service c5cf8c
    array_of_types = (MPI_Datatype *) ((char *) dtp->contents + struct_sz);
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < dtp->contents->nr_types; i++) {
Packit Service c5cf8c
        if (HANDLE_GET_KIND(array_of_types[i]) != HANDLE_KIND_BUILTIN) {
Packit Service c5cf8c
            MPIR_Datatype_get_ptr(array_of_types[i], old_dtp);
Packit Service c5cf8c
            MPIR_Datatype_ptr_release(old_dtp);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPL_free(dtp->contents);
Packit Service c5cf8c
    dtp->contents = NULL;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/*@
Packit Service c5cf8c
  MPIR_Datatype_free
Packit Service c5cf8c
Packit Service c5cf8c
Input Parameters:
Packit Service c5cf8c
. MPIR_Datatype ptr - pointer to MPID datatype structure that is no longer
Packit Service c5cf8c
  referenced
Packit Service c5cf8c
Packit Service c5cf8c
Output Parameters:
Packit Service c5cf8c
  none
Packit Service c5cf8c
Packit Service c5cf8c
  Return Value:
Packit Service c5cf8c
  none
Packit Service c5cf8c
Packit Service c5cf8c
  This function handles freeing dynamically allocated memory associated with
Packit Service c5cf8c
  the datatype.  In the process MPIR_Datatype_free_contents() is also called,
Packit Service c5cf8c
  which handles decrementing reference counts to constituent types (in
Packit Service c5cf8c
  addition to freeing the space used for contents information).
Packit Service c5cf8c
  MPIR_Datatype_free_contents() will call MPIR_Datatype_free() on constituent
Packit Service c5cf8c
  types that are no longer referenced as well.
Packit Service c5cf8c
Packit Service c5cf8c
  @*/
Packit Service c5cf8c
static inline void MPIR_Datatype_free(MPIR_Datatype * ptr)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPL_DBG_MSG_P(MPIR_DBG_DATATYPE, VERBOSE, "type %x freed.", ptr->handle);
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef MPID_Type_free_hook
Packit Service c5cf8c
    MPID_Type_free_hook(ptr);
Packit Service c5cf8c
#endif /* MPID_Type_free_hook */
Packit Service c5cf8c
Packit Service c5cf8c
    /* before freeing the contents, check whether the pointer is not
Packit Service c5cf8c
     * null because it is null in the case of a datatype shipped to the target
Packit Service c5cf8c
     * for RMA ops */
Packit Service c5cf8c
    if (ptr->contents) {
Packit Service c5cf8c
        MPIR_Datatype_free_contents(ptr);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (ptr->dataloop) {
Packit Service c5cf8c
        MPIR_Dataloop_free(&(ptr->dataloop));
Packit Service c5cf8c
    }
Packit Service c5cf8c
    MPIR_Handle_obj_free(&MPIR_Datatype_mem, ptr);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/*@
Packit Service c5cf8c
  MPIR_Datatype_set_contents - store contents information for use in
Packit Service c5cf8c
  MPI_Type_get_contents.
Packit Service c5cf8c
Packit Service c5cf8c
  Returns MPI_SUCCESS on success, MPI error code on error.
Packit Service c5cf8c
  @*/
Packit Service c5cf8c
static inline int MPIR_Datatype_set_contents(MPIR_Datatype * new_dtp,
Packit Service c5cf8c
                                             int combiner,
Packit Service c5cf8c
                                             int nr_ints,
Packit Service c5cf8c
                                             int nr_aints,
Packit Service c5cf8c
                                             int nr_types,
Packit Service c5cf8c
                                             int array_of_ints[],
Packit Service c5cf8c
                                             const MPI_Aint array_of_aints[],
Packit Service c5cf8c
                                             const MPI_Datatype array_of_types[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i, contents_size, align_sz, epsilon, mpi_errno;
Packit Service c5cf8c
    int struct_sz, ints_sz, aints_sz, types_sz;
Packit Service c5cf8c
    MPIR_Datatype_contents *cp;
Packit Service c5cf8c
    MPIR_Datatype *old_dtp;
Packit Service c5cf8c
    char *ptr;
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef HAVE_MAX_STRUCT_ALIGNMENT
Packit Service c5cf8c
    align_sz = HAVE_MAX_STRUCT_ALIGNMENT;
Packit Service c5cf8c
#else
Packit Service c5cf8c
    align_sz = 8;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
    struct_sz = sizeof(MPIR_Datatype_contents);
Packit Service c5cf8c
    types_sz = nr_types * sizeof(MPI_Datatype);
Packit Service c5cf8c
    ints_sz = nr_ints * sizeof(int);
Packit Service c5cf8c
    aints_sz = nr_aints * sizeof(MPI_Aint);
Packit Service c5cf8c
Packit Service c5cf8c
    /* pad the struct, types, and ints before we allocate.
Packit Service c5cf8c
     *
Packit Service c5cf8c
     * note: it's not necessary that we pad the aints,
Packit Service c5cf8c
     *       because they are last in the region.
Packit Service c5cf8c
     */
Packit Service c5cf8c
    if ((epsilon = struct_sz % align_sz)) {
Packit Service c5cf8c
        struct_sz += align_sz - epsilon;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if ((epsilon = types_sz % align_sz)) {
Packit Service c5cf8c
        types_sz += align_sz - epsilon;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if ((epsilon = ints_sz % align_sz)) {
Packit Service c5cf8c
        ints_sz += align_sz - epsilon;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    contents_size = struct_sz + types_sz + ints_sz + aints_sz;
Packit Service c5cf8c
Packit Service c5cf8c
    cp = (MPIR_Datatype_contents *) MPL_malloc(contents_size, MPL_MEM_DATATYPE);
Packit Service c5cf8c
    /* --BEGIN ERROR HANDLING-- */
Packit Service c5cf8c
    if (cp == NULL) {
Packit Service c5cf8c
        mpi_errno = MPIR_Err_create_code(MPI_SUCCESS,
Packit Service c5cf8c
                                         MPIR_ERR_RECOVERABLE,
Packit Service c5cf8c
                                         "MPIR_Datatype_set_contents",
Packit Service c5cf8c
                                         __LINE__, MPI_ERR_OTHER, "**nomem", 0);
Packit Service c5cf8c
        return mpi_errno;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    /* --END ERROR HANDLING-- */
Packit Service c5cf8c
Packit Service c5cf8c
    cp->combiner = combiner;
Packit Service c5cf8c
    cp->nr_ints = nr_ints;
Packit Service c5cf8c
    cp->nr_aints = nr_aints;
Packit Service c5cf8c
    cp->nr_types = nr_types;
Packit Service c5cf8c
Packit Service c5cf8c
    /* arrays are stored in the following order: types, ints, aints,
Packit Service c5cf8c
     * following the structure itself.
Packit Service c5cf8c
     */
Packit Service c5cf8c
    ptr = ((char *) cp) + struct_sz;
Packit Service c5cf8c
    /* Fortran90 combiner types do not have a "base" type */
Packit Service c5cf8c
    if (nr_types > 0) {
Packit Service c5cf8c
        MPIR_Memcpy(ptr, array_of_types, nr_types * sizeof(MPI_Datatype));
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    ptr = ((char *) cp) + struct_sz + types_sz;
Packit Service c5cf8c
    if (nr_ints > 0) {
Packit Service c5cf8c
        MPIR_Memcpy(ptr, array_of_ints, nr_ints * sizeof(int));
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    ptr = ((char *) cp) + struct_sz + types_sz + ints_sz;
Packit Service c5cf8c
    if (nr_aints > 0) {
Packit Service c5cf8c
        MPIR_Memcpy(ptr, array_of_aints, nr_aints * sizeof(MPI_Aint));
Packit Service c5cf8c
    }
Packit Service c5cf8c
    new_dtp->contents = cp;
Packit Service c5cf8c
Packit Service c5cf8c
    /* increment reference counts on all the derived types used here */
Packit Service c5cf8c
    for (i = 0; i < nr_types; i++) {
Packit Service c5cf8c
        if (HANDLE_GET_KIND(array_of_types[i]) != HANDLE_KIND_BUILTIN) {
Packit Service c5cf8c
            MPIR_Datatype_get_ptr(array_of_types[i], old_dtp);
Packit Service c5cf8c
            MPIR_Datatype_ptr_add_ref(old_dtp);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* contents accessor functions */
Packit Service c5cf8c
void MPIR_Type_access_contents(MPI_Datatype type, int **ints_p, MPI_Aint ** aints_p,
Packit Service c5cf8c
                               MPI_Datatype ** types_p);
Packit Service c5cf8c
void MPIR_Type_release_contents(MPI_Datatype type, int **ints_p, MPI_Aint ** aints_p,
Packit Service c5cf8c
                                MPI_Datatype ** types_p);
Packit Service c5cf8c
Packit Service c5cf8c
/* This routine is used to install an attribute free routine for datatypes
Packit Service c5cf8c
   at finalize-time */
Packit Service c5cf8c
void MPII_Datatype_attr_finalize(void);
Packit Service c5cf8c
int MPII_Type_zerolen(MPI_Datatype * newtype);
Packit Service c5cf8c
Packit Service c5cf8c
#define MPIR_DATATYPE_IS_PREDEFINED(type) \
Packit Service c5cf8c
    ((HANDLE_GET_KIND(type) == HANDLE_KIND_BUILTIN) || \
Packit Service c5cf8c
     (type == MPI_FLOAT_INT) || (type == MPI_DOUBLE_INT) || \
Packit Service c5cf8c
     (type == MPI_LONG_INT) || (type == MPI_SHORT_INT) || \
Packit Service c5cf8c
     (type == MPI_LONG_DOUBLE_INT))
Packit Service c5cf8c
Packit Service c5cf8c
int MPIR_Get_elements_x_impl(MPI_Count * bytes, MPI_Datatype datatype, MPI_Count * elements);
Packit Service c5cf8c
int MPIR_Status_set_elements_x_impl(MPI_Status * status, MPI_Datatype datatype, MPI_Count count);
Packit Service c5cf8c
void MPIR_Type_get_extent_x_impl(MPI_Datatype datatype, MPI_Count * lb, MPI_Count * extent);
Packit Service c5cf8c
void MPIR_Type_get_true_extent_x_impl(MPI_Datatype datatype, MPI_Count * true_lb,
Packit Service c5cf8c
                                      MPI_Count * true_extent);
Packit Service c5cf8c
int MPIR_Type_size_x_impl(MPI_Datatype datatype, MPI_Count * size);
Packit Service c5cf8c
Packit Service c5cf8c
void MPIR_Get_count_impl(const MPI_Status * status, MPI_Datatype datatype, MPI_Aint * count);
Packit Service c5cf8c
int MPIR_Type_commit_impl(MPI_Datatype * datatype);
Packit Service c5cf8c
int MPIR_Type_create_struct_impl(int count,
Packit Service c5cf8c
                                 const int array_of_blocklengths[],
Packit Service c5cf8c
                                 const MPI_Aint array_of_displacements[],
Packit Service c5cf8c
                                 const MPI_Datatype array_of_types[], MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_create_indexed_block_impl(int count,
Packit Service c5cf8c
                                        int blocklength,
Packit Service c5cf8c
                                        const int array_of_displacements[],
Packit Service c5cf8c
                                        MPI_Datatype oldtype, MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_create_hindexed_block_impl(int count, int blocklength,
Packit Service c5cf8c
                                         const MPI_Aint array_of_displacements[],
Packit Service c5cf8c
                                         MPI_Datatype oldtype, MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_contiguous_impl(int count, MPI_Datatype old_type, MPI_Datatype * new_type_p);
Packit Service c5cf8c
int MPIR_Type_contiguous_x_impl(MPI_Count count, MPI_Datatype old_type, MPI_Datatype * new_type_p);
Packit Service c5cf8c
void MPIR_Type_get_extent_impl(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent);
Packit Service c5cf8c
void MPIR_Type_get_true_extent_impl(MPI_Datatype datatype, MPI_Aint * true_lb,
Packit Service c5cf8c
                                    MPI_Aint * true_extent);
Packit Service c5cf8c
void MPIR_Type_get_envelope(MPI_Datatype datatype, int *num_integers, int *num_addresses,
Packit Service c5cf8c
                            int *num_datatypes, int *combiner);
Packit Service c5cf8c
int MPIR_Type_hvector_impl(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type,
Packit Service c5cf8c
                           MPI_Datatype * newtype_p);
Packit Service c5cf8c
int MPIR_Type_indexed_impl(int count, const int blocklens[], const int indices[],
Packit Service c5cf8c
                           MPI_Datatype old_type, MPI_Datatype * newtype);
Packit Service c5cf8c
void MPIR_Type_free_impl(MPI_Datatype * datatype);
Packit Service c5cf8c
int MPIR_Type_vector_impl(int count, int blocklength, int stride, MPI_Datatype old_type,
Packit Service c5cf8c
                          MPI_Datatype * newtype_p);
Packit Service c5cf8c
int MPIR_Type_struct_impl(int count, const int blocklens[], const MPI_Aint indices[],
Packit Service c5cf8c
                          const MPI_Datatype old_types[], MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Pack_impl(const void *inbuf, MPI_Aint incount, MPI_Datatype datatype, void *outbuf,
Packit Service c5cf8c
                   MPI_Aint outcount, MPI_Aint * position);
Packit Service c5cf8c
void MPIR_Pack_size_impl(int incount, MPI_Datatype datatype, MPI_Aint * size);
Packit Service c5cf8c
int MPIR_Unpack_impl(const void *inbuf, MPI_Aint insize, MPI_Aint * position,
Packit Service c5cf8c
                     void *outbuf, int outcount, MPI_Datatype datatype);
Packit Service c5cf8c
void MPIR_Type_lb_impl(MPI_Datatype datatype, MPI_Aint * displacement);
Packit Service c5cf8c
Packit Service c5cf8c
/* Datatype functions */
Packit Service c5cf8c
int MPIR_Type_dup(MPI_Datatype oldtype, MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_struct(int count, const int *blocklength_array, const MPI_Aint * displacement_array,
Packit Service c5cf8c
                     const MPI_Datatype * oldtype_array, MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_indexed(int count, const int *blocklength_array, const void *displacement_array,
Packit Service c5cf8c
                      int dispinbytes, MPI_Datatype oldtype, MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_vector(int count, int blocklength, MPI_Aint stride, int strideinbytes,
Packit Service c5cf8c
                     MPI_Datatype oldtype, MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype * newtype);
Packit Service c5cf8c
int MPII_Type_zerolen(MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_create_resized(MPI_Datatype oldtype, MPI_Aint lb, MPI_Aint extent,
Packit Service c5cf8c
                             MPI_Datatype * newtype);
Packit Service c5cf8c
int MPIR_Type_get_contents(MPI_Datatype datatype, int max_integers, int max_addresses,
Packit Service c5cf8c
                           int max_datatypes, int array_of_integers[],
Packit Service c5cf8c
                           MPI_Aint array_of_addresses[], MPI_Datatype array_of_datatypes[]);
Packit Service c5cf8c
int MPIR_Type_create_pairtype(MPI_Datatype datatype, MPIR_Datatype * new_dtp);
Packit Service c5cf8c
int MPIR_Type_flatten(MPI_Datatype type, MPI_Aint * off_array, DLOOP_Size * size_array,
Packit Service c5cf8c
                      MPI_Aint * array_len_p);
Packit Service c5cf8c
Packit Service c5cf8c
/* debugging helper functions */
Packit Service c5cf8c
char *MPIR_Datatype_builtin_to_string(MPI_Datatype type);
Packit Service c5cf8c
char *MPIR_Datatype_combiner_to_string(int combiner);
Packit Service c5cf8c
void MPIR_Datatype_debug(MPI_Datatype type, int array_ct);
Packit Service c5cf8c
Packit Service c5cf8c
MPI_Aint MPII_Datatype_get_basic_size_external32(MPI_Datatype el_type);
Packit Service c5cf8c
Packit Service c5cf8c
static inline MPI_Aint MPIR_Datatype_size_external32(MPI_Datatype type)
Packit Service c5cf8c
{
Packit Service c5cf8c
    if (HANDLE_GET_KIND(type) == HANDLE_KIND_BUILTIN) {
Packit Service c5cf8c
        return MPII_Datatype_get_basic_size_external32(type);
Packit Service c5cf8c
    } else {
Packit Service c5cf8c
        MPIR_Dataloop *dlp = NULL;
Packit Service c5cf8c
Packit Service c5cf8c
        MPIR_Datatype_get_loopptr_macro(type, dlp);
Packit Service c5cf8c
        MPIR_Assert(dlp != NULL);
Packit Service c5cf8c
Packit Service c5cf8c
        return MPIR_Dataloop_stream_size(dlp, MPII_Datatype_get_basic_size_external32);
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#endif /* MPIR_DATATYPE_H_INCLUDED */