Blame src/mpi/datatype/typeutil.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
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
#include "mpiimpl.h"
Packit Service c5cf8c
#include "datatype.h"
Packit Service c5cf8c
Packit Service c5cf8c
/* This is the utility file for datatypes that contains the basic datatype
Packit Service c5cf8c
   items and storage management.  It also contains a temporary routine
Packit Service c5cf8c
   that is used by ROMIO to test to see if datatypes are contiguous */
Packit Service c5cf8c
Packit Service c5cf8c
/* Preallocated datatype objects */
Packit Service c5cf8c
MPIR_Datatype MPIR_Datatype_builtin[MPIR_DATATYPE_N_BUILTIN] = { {0}
Packit Service c5cf8c
};
Packit Service c5cf8c
MPIR_Datatype MPIR_Datatype_direct[MPIR_DATATYPE_PREALLOC] = { {0}
Packit Service c5cf8c
};
Packit Service c5cf8c
Packit Service c5cf8c
MPIR_Object_alloc_t MPIR_Datatype_mem = { 0, 0, 0, 0, MPIR_DATATYPE,
Packit Service c5cf8c
    sizeof(MPIR_Datatype), MPIR_Datatype_direct,
Packit Service c5cf8c
    MPIR_DATATYPE_PREALLOC
Packit Service c5cf8c
};
Packit Service c5cf8c
Packit Service c5cf8c
static int MPIR_Datatype_finalize(void *dummy);
Packit Service c5cf8c
static int datatype_attr_finalize_cb(void *dummy);
Packit Service c5cf8c
Packit Service c5cf8c
/* Call this routine to associate a MPIR_Datatype with each predefined
Packit Service c5cf8c
   datatype.  We do this with lazy initialization because many MPI
Packit Service c5cf8c
   programs do not require anything except the predefined datatypes, and
Packit Service c5cf8c
   all of the necessary information about those is stored within the
Packit Service c5cf8c
   MPI_Datatype handle.  However, if the user wants to change the name
Packit Service c5cf8c
   (character string, set with MPI_Type_set_name) associated with a
Packit Service c5cf8c
   predefined name, then the structures must be allocated.
Packit Service c5cf8c
*/
Packit Service c5cf8c
/* FIXME does the order of this list need to correspond to anything in
Packit Service c5cf8c
   particular?  There are several lists of predefined types sprinkled throughout
Packit Service c5cf8c
   the codebase and it's unclear which (if any) of them must match exactly.
Packit Service c5cf8c
   [goodell@ 2009-03-17] */
Packit Service c5cf8c
static MPI_Datatype mpi_dtypes[] = {
Packit Service c5cf8c
    MPI_CHAR,
Packit Service c5cf8c
    MPI_UNSIGNED_CHAR,
Packit Service c5cf8c
    MPI_SIGNED_CHAR,
Packit Service c5cf8c
    MPI_BYTE,
Packit Service c5cf8c
    MPI_WCHAR,
Packit Service c5cf8c
    MPI_SHORT,
Packit Service c5cf8c
    MPI_UNSIGNED_SHORT,
Packit Service c5cf8c
    MPI_INT,
Packit Service c5cf8c
    MPI_UNSIGNED,
Packit Service c5cf8c
    MPI_LONG,
Packit Service c5cf8c
    MPI_UNSIGNED_LONG,
Packit Service c5cf8c
    MPI_FLOAT,
Packit Service c5cf8c
    MPI_DOUBLE,
Packit Service c5cf8c
    MPI_LONG_DOUBLE,
Packit Service c5cf8c
    MPI_LONG_LONG,
Packit Service c5cf8c
    MPI_UNSIGNED_LONG_LONG,
Packit Service c5cf8c
    MPI_PACKED,
Packit Service c5cf8c
    MPI_LB,
Packit Service c5cf8c
    MPI_UB,
Packit Service c5cf8c
    MPI_2INT,
Packit Service c5cf8c
Packit Service c5cf8c
    /* C99 types */
Packit Service c5cf8c
    MPI_INT8_T,
Packit Service c5cf8c
    MPI_INT16_T,
Packit Service c5cf8c
    MPI_INT32_T,
Packit Service c5cf8c
    MPI_INT64_T,
Packit Service c5cf8c
    MPI_UINT8_T,
Packit Service c5cf8c
    MPI_UINT16_T,
Packit Service c5cf8c
    MPI_UINT32_T,
Packit Service c5cf8c
    MPI_UINT64_T,
Packit Service c5cf8c
    MPI_C_BOOL,
Packit Service c5cf8c
    MPI_C_FLOAT_COMPLEX,
Packit Service c5cf8c
    MPI_C_DOUBLE_COMPLEX,
Packit Service c5cf8c
    MPI_C_LONG_DOUBLE_COMPLEX,
Packit Service c5cf8c
Packit Service c5cf8c
    /* address/offset/count types */
Packit Service c5cf8c
    MPI_AINT,
Packit Service c5cf8c
    MPI_OFFSET,
Packit Service c5cf8c
    MPI_COUNT,
Packit Service c5cf8c
Packit Service c5cf8c
    /* Fortran types */
Packit Service c5cf8c
    MPI_COMPLEX,
Packit Service c5cf8c
    MPI_DOUBLE_COMPLEX,
Packit Service c5cf8c
    MPI_LOGICAL,
Packit Service c5cf8c
    MPI_REAL,
Packit Service c5cf8c
    MPI_DOUBLE_PRECISION,
Packit Service c5cf8c
    MPI_INTEGER,
Packit Service c5cf8c
    MPI_2INTEGER,
Packit Service c5cf8c
#ifdef MPICH_DEFINE_2COMPLEX
Packit Service c5cf8c
    MPI_2COMPLEX,
Packit Service c5cf8c
    MPI_2DOUBLE_COMPLEX,
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    MPI_2REAL,
Packit Service c5cf8c
    MPI_2DOUBLE_PRECISION,
Packit Service c5cf8c
    MPI_CHARACTER,
Packit Service c5cf8c
#ifdef HAVE_FORTRAN_BINDING
Packit Service c5cf8c
    /* Size-specific types; these are in section 10.2.4 (Extended Fortran
Packit Service c5cf8c
     * Support) as well as optional in MPI-1
Packit Service c5cf8c
     */
Packit Service c5cf8c
    MPI_REAL4,
Packit Service c5cf8c
    MPI_REAL8,
Packit Service c5cf8c
    MPI_REAL16,
Packit Service c5cf8c
    MPI_COMPLEX8,
Packit Service c5cf8c
    MPI_COMPLEX16,
Packit Service c5cf8c
    MPI_COMPLEX32,
Packit Service c5cf8c
    MPI_INTEGER1,
Packit Service c5cf8c
    MPI_INTEGER2,
Packit Service c5cf8c
    MPI_INTEGER4,
Packit Service c5cf8c
    MPI_INTEGER8,
Packit Service c5cf8c
    MPI_INTEGER16,
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    /* This entry is a guaranteed end-of-list item */
Packit Service c5cf8c
    (MPI_Datatype) - 1,
Packit Service c5cf8c
};
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
  MPIR_Datatype_init()
Packit Service c5cf8c
Packit Service c5cf8c
  Main purpose of this function is to set up the following pair types:
Packit Service c5cf8c
  - MPI_FLOAT_INT
Packit Service c5cf8c
  - MPI_DOUBLE_INT
Packit Service c5cf8c
  - MPI_LONG_INT
Packit Service c5cf8c
  - MPI_SHORT_INT
Packit Service c5cf8c
  - MPI_LONG_DOUBLE_INT
Packit Service c5cf8c
Packit Service c5cf8c
  The assertions in this code ensure that:
Packit Service c5cf8c
  - this function is called before other types are allocated
Packit Service c5cf8c
  - there are enough spaces in the direct block to hold our types
Packit Service c5cf8c
  - we actually get the values we expect (otherwise errors regarding
Packit Service c5cf8c
    these types could be terribly difficult to track down!)
Packit Service c5cf8c
Packit Service c5cf8c
 */
Packit Service c5cf8c
static MPI_Datatype mpi_pairtypes[] = {
Packit Service c5cf8c
    MPI_FLOAT_INT,
Packit Service c5cf8c
    MPI_DOUBLE_INT,
Packit Service c5cf8c
    MPI_LONG_INT,
Packit Service c5cf8c
    MPI_SHORT_INT,
Packit Service c5cf8c
    MPI_LONG_DOUBLE_INT,
Packit Service c5cf8c
    (MPI_Datatype) - 1
Packit Service c5cf8c
};
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPIR_Datatype_init
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPIR_Datatype_init(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i;
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_Datatype *ptr;
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_Assert(MPIR_Datatype_mem.initialized == 0);
Packit Service c5cf8c
    MPIR_Assert(MPIR_DATATYPE_PREALLOC >= 5);
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; mpi_pairtypes[i] != (MPI_Datatype) - 1; ++i) {
Packit Service c5cf8c
        /* types based on 'long long' and 'long double', may be disabled at
Packit Service c5cf8c
         * configure time, and their values set to MPI_DATATYPE_NULL.  skip any
Packit Service c5cf8c
         * such types. */
Packit Service c5cf8c
        if (mpi_pairtypes[i] == MPI_DATATYPE_NULL)
Packit Service c5cf8c
            continue;
Packit Service c5cf8c
        /* XXX: this allocation strategy isn't right if one or more of the
Packit Service c5cf8c
         * pairtypes is MPI_DATATYPE_NULL.  in fact, the assert below will
Packit Service c5cf8c
         * fail if any type other than the las in the list is equal to
Packit Service c5cf8c
         * MPI_DATATYPE_NULL.  obviously, this should be fixed, but I need
Packit Service c5cf8c
         * to talk to Rob R. first. -- BRT */
Packit Service c5cf8c
        /* XXX DJG it does work, but only because MPI_LONG_DOUBLE_INT is the
Packit Service c5cf8c
         * only one that is ever optional and it comes last */
Packit Service c5cf8c
Packit Service c5cf8c
        /* we use the _unsafe version because we are still in MPI_Init, before
Packit Service c5cf8c
         * multiple threads are permitted and possibly before support for
Packit Service c5cf8c
         * critical sections is entirely setup */
Packit Service c5cf8c
        ptr = (MPIR_Datatype *) MPIR_Handle_obj_alloc_unsafe(&MPIR_Datatype_mem);
Packit Service c5cf8c
Packit Service c5cf8c
        MPIR_Assert(ptr);
Packit Service c5cf8c
        MPIR_Assert(ptr->handle == mpi_pairtypes[i]);
Packit Service c5cf8c
        /* this is a redundant alternative to the previous statement */
Packit Service c5cf8c
        MPIR_Assert((void *) ptr ==
Packit Service c5cf8c
                    (void *) (MPIR_Datatype_direct + HANDLE_INDEX(mpi_pairtypes[i])));
Packit Service c5cf8c
Packit Service c5cf8c
        mpi_errno = MPIR_Type_create_pairtype(mpi_pairtypes[i], (MPIR_Datatype *) ptr);
Packit Service c5cf8c
        if (mpi_errno)
Packit Service c5cf8c
            MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_Add_finalize(MPIR_Datatype_finalize, 0, MPIR_FINALIZE_CALLBACK_PRIO - 1);
Packit Service c5cf8c
Packit Service c5cf8c
  fn_fail:
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPIR_Datatype_finalize
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
static int MPIR_Datatype_finalize(void *dummy ATTRIBUTE((unused)))
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i;
Packit Service c5cf8c
    MPIR_Datatype *dptr;
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; mpi_pairtypes[i] != (MPI_Datatype) - 1; i++) {
Packit Service c5cf8c
        if (mpi_pairtypes[i] != MPI_DATATYPE_NULL) {
Packit Service c5cf8c
            MPIR_Datatype_get_ptr(mpi_pairtypes[i], dptr);
Packit Service c5cf8c
            MPIR_Datatype_ptr_release(dptr);
Packit Service c5cf8c
            mpi_pairtypes[i] = MPI_DATATYPE_NULL;
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Called ONLY from MPIR_Datatype_init_names (type_get_name.c).
Packit Service c5cf8c
   That routine calls it from within a single-init section to
Packit Service c5cf8c
   ensure thread-safety. */
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPIR_Datatype_builtin_fillin
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPIR_Datatype_builtin_fillin(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    unsigned int i;
Packit Service c5cf8c
    MPIR_Datatype *dptr;
Packit Service c5cf8c
    MPI_Datatype d = MPI_DATATYPE_NULL;
Packit Service c5cf8c
    static int is_init = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    /* FIXME: This is actually an error, since this routine
Packit Service c5cf8c
     * should only be called once */
Packit Service c5cf8c
    if (is_init) {
Packit Service c5cf8c
        return MPI_SUCCESS;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if (!is_init) {
Packit Service c5cf8c
        /* If the datatype is -1, we're at the end of mpi_dtypes */
Packit Service c5cf8c
        for (i = 0; i < MPIR_DATATYPE_N_BUILTIN && mpi_dtypes[i] != -1; i++) {
Packit Service c5cf8c
            /* Compute the index from the value of the handle */
Packit Service c5cf8c
            d = mpi_dtypes[i];
Packit Service c5cf8c
Packit Service c5cf8c
            /* Some of the size-specific types may be null, as might be types
Packit Service c5cf8c
             * based on 'long long' and 'long double' if those types were
Packit Service c5cf8c
             * disabled at configure time.  skip those cases. */
Packit Service c5cf8c
            if (d == MPI_DATATYPE_NULL)
Packit Service c5cf8c
                continue;
Packit Service c5cf8c
Packit Service c5cf8c
            MPIR_Datatype_get_ptr(d, dptr);
Packit Service c5cf8c
            /* --BEGIN ERROR HANDLING-- */
Packit Service c5cf8c
            if (dptr < MPIR_Datatype_builtin ||
Packit Service c5cf8c
                dptr > MPIR_Datatype_builtin + MPIR_DATATYPE_N_BUILTIN) {
Packit Service c5cf8c
                mpi_errno = MPIR_Err_create_code(MPI_SUCCESS,
Packit Service c5cf8c
                                                 MPIR_ERR_FATAL, FCNAME,
Packit Service c5cf8c
                                                 __LINE__, MPI_ERR_INTERN,
Packit Service c5cf8c
                                                 "**typeinitbadmem", "**typeinitbadmem %d", i);
Packit Service c5cf8c
                return mpi_errno;
Packit Service c5cf8c
            }
Packit Service c5cf8c
            /* --END ERROR HANDLING-- */
Packit Service c5cf8c
Packit Service c5cf8c
            /* dptr will point into MPIR_Datatype_builtin */
Packit Service c5cf8c
            dptr->handle = d;
Packit Service c5cf8c
            dptr->is_permanent = 1;
Packit Service c5cf8c
            dptr->is_contig = 1;
Packit Service c5cf8c
            MPIR_Object_set_ref(dptr, 1);
Packit Service c5cf8c
            MPIR_Datatype_get_size_macro(mpi_dtypes[i], dptr->size);
Packit Service c5cf8c
            dptr->extent = dptr->size;
Packit Service c5cf8c
            dptr->ub = dptr->size;
Packit Service c5cf8c
            dptr->true_ub = dptr->size;
Packit Service c5cf8c
            dptr->contents = NULL;      /* should never get referenced? */
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* --BEGIN ERROR HANDLING-- */
Packit Service c5cf8c
        if (d != -1 && i < sizeof(mpi_dtypes) / sizeof(*mpi_dtypes) && mpi_dtypes[i] != -1) {
Packit Service c5cf8c
            /* We did not hit the end-of-list */
Packit Service c5cf8c
            mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
Packit Service c5cf8c
                                             FCNAME, __LINE__,
Packit Service c5cf8c
                                             MPI_ERR_INTERN, "**typeinitfail",
Packit Service c5cf8c
                                             "**typeinitfail %d", i - 1);
Packit Service c5cf8c
            return mpi_errno;
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* --END ERROR HANDLING-- */
Packit Service c5cf8c
        is_init = 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* This will eventually be removed once ROMIO knows more about MPICH */
Packit Service c5cf8c
void MPIR_Datatype_iscontig(MPI_Datatype datatype, int *flag)
Packit Service c5cf8c
{
Packit Service c5cf8c
    if (HANDLE_GET_KIND(datatype) == HANDLE_KIND_BUILTIN)
Packit Service c5cf8c
        *flag = 1;
Packit Service c5cf8c
    else {
Packit Service c5cf8c
        MPIR_Datatype_is_contig(datatype, flag);
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* If an attribute is added to a predefined type, we free the attributes
Packit Service c5cf8c
   in Finalize */
Packit Service c5cf8c
static int datatype_attr_finalize_cb(void *dummy ATTRIBUTE((unused)))
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPIR_Datatype *dtype;
Packit Service c5cf8c
    int i, mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < MPIR_DATATYPE_N_BUILTIN; i++) {
Packit Service c5cf8c
        dtype = &MPIR_Datatype_builtin[i];
Packit Service c5cf8c
        if (dtype && MPIR_Process.attr_free && dtype->attributes) {
Packit Service c5cf8c
            mpi_errno = MPIR_Process.attr_free(dtype->handle, &dtype->attributes);
Packit Service c5cf8c
            /* During finalize, we ignore error returns from the free */
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void MPII_Datatype_attr_finalize(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    static int called = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    /* FIXME: This needs to be make thread safe */
Packit Service c5cf8c
    if (!called) {
Packit Service c5cf8c
        called = 1;
Packit Service c5cf8c
        MPIR_Add_finalize(datatype_attr_finalize_cb, 0, MPIR_FINALIZE_CALLBACK_PRIO - 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/*@
Packit Service c5cf8c
  MPII_Type_zerolen - create an empty datatype
Packit Service c5cf8c
Packit Service c5cf8c
Input Parameters:
Packit Service c5cf8c
. none
Packit Service c5cf8c
Packit Service c5cf8c
Output Parameters:
Packit Service c5cf8c
. newtype - handle of new contiguous datatype
Packit Service c5cf8c
Packit Service c5cf8c
  Return Value:
Packit Service c5cf8c
  MPI_SUCCESS on success, MPI error code on failure.
Packit Service c5cf8c
@*/
Packit Service c5cf8c
Packit Service c5cf8c
int MPII_Type_zerolen(MPI_Datatype * newtype)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno;
Packit Service c5cf8c
    MPIR_Datatype *new_dtp;
Packit Service c5cf8c
Packit Service c5cf8c
    /* allocate new datatype object and handle */
Packit Service c5cf8c
    new_dtp = (MPIR_Datatype *) MPIR_Handle_obj_alloc(&MPIR_Datatype_mem);
Packit Service c5cf8c
    /* --BEGIN ERROR HANDLING-- */
Packit Service c5cf8c
    if (!new_dtp) {
Packit Service c5cf8c
        mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
Packit Service c5cf8c
                                         "MPII_Type_zerolen",
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
    /* handle is filled in by MPIR_Handle_obj_alloc() */
Packit Service c5cf8c
    MPIR_Object_set_ref(new_dtp, 1);
Packit Service c5cf8c
    new_dtp->is_permanent = 0;
Packit Service c5cf8c
    new_dtp->is_committed = 0;
Packit Service c5cf8c
    new_dtp->attributes = NULL;
Packit Service c5cf8c
    new_dtp->cache_id = 0;
Packit Service c5cf8c
    new_dtp->name[0] = 0;
Packit Service c5cf8c
    new_dtp->contents = NULL;
Packit Service c5cf8c
Packit Service c5cf8c
    new_dtp->dataloop = NULL;
Packit Service c5cf8c
    new_dtp->dataloop_size = -1;
Packit Service c5cf8c
    new_dtp->dataloop_depth = -1;
Packit Service c5cf8c
Packit Service c5cf8c
    new_dtp->size = 0;
Packit Service c5cf8c
    new_dtp->has_sticky_ub = 0;
Packit Service c5cf8c
    new_dtp->has_sticky_lb = 0;
Packit Service c5cf8c
    new_dtp->lb = 0;
Packit Service c5cf8c
    new_dtp->ub = 0;
Packit Service c5cf8c
    new_dtp->true_lb = 0;
Packit Service c5cf8c
    new_dtp->true_ub = 0;
Packit Service c5cf8c
    new_dtp->extent = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    new_dtp->alignsize = 0;
Packit Service c5cf8c
    new_dtp->builtin_element_size = 0;
Packit Service c5cf8c
    new_dtp->basic_type = 0;
Packit Service c5cf8c
    new_dtp->n_builtin_elements = 0;
Packit Service c5cf8c
    new_dtp->is_contig = 1;
Packit Service c5cf8c
Packit Service c5cf8c
    *newtype = new_dtp->handle;
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void MPII_Datatype_get_contents_ints(MPIR_Datatype_contents * cp, int *user_ints)
Packit Service c5cf8c
{
Packit Service c5cf8c
    char *ptr;
Packit Service c5cf8c
    int align_sz, epsilon;
Packit Service c5cf8c
    int struct_sz, types_sz;
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 = cp->nr_types * sizeof(MPI_Datatype);
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
Packit Service c5cf8c
    ptr = ((char *) cp) + struct_sz + types_sz;
Packit Service c5cf8c
    MPIR_Memcpy(user_ints, ptr, cp->nr_ints * sizeof(int));
Packit Service c5cf8c
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void MPII_Datatype_get_contents_aints(MPIR_Datatype_contents * cp, MPI_Aint * user_aints)
Packit Service c5cf8c
{
Packit Service c5cf8c
    char *ptr;
Packit Service c5cf8c
    int align_sz = 8, epsilon;
Packit Service c5cf8c
    int struct_sz, ints_sz, types_sz;
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 = cp->nr_types * sizeof(MPI_Datatype);
Packit Service c5cf8c
    ints_sz = cp->nr_ints * sizeof(int);
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
    ptr = ((char *) cp) + struct_sz + types_sz + ints_sz;
Packit Service c5cf8c
    MPIR_Memcpy(user_aints, ptr, cp->nr_aints * sizeof(MPI_Aint));
Packit Service c5cf8c
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void MPII_Datatype_get_contents_types(MPIR_Datatype_contents * cp, MPI_Datatype * user_types)
Packit Service c5cf8c
{
Packit Service c5cf8c
    char *ptr;
Packit Service c5cf8c
    int align_sz = 8, epsilon;
Packit Service c5cf8c
    int struct_sz;
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
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
Packit Service c5cf8c
    ptr = ((char *) cp) + struct_sz;
Packit Service c5cf8c
    MPIR_Memcpy(user_types, ptr, cp->nr_types * sizeof(MPI_Datatype));
Packit Service c5cf8c
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}