|
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 |
}
|