|
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 <stdlib.h>
|
|
Packit Service |
c5cf8c |
#include <limits.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* PAIRTYPE_SIZE_EXTENT - calculates size, extent, etc. for pairtype by
|
|
Packit Service |
c5cf8c |
* defining the appropriate C type.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#define PAIRTYPE_SIZE_EXTENT(mt1_,ut1_,mt2_,ut2_, type_size_, type_extent_, \
|
|
Packit Service |
c5cf8c |
el_size_, true_ub_, alignsize_) \
|
|
Packit Service |
c5cf8c |
{ \
|
|
Packit Service |
c5cf8c |
struct { ut1_ a; ut2_ b; } foo; \
|
|
Packit Service |
c5cf8c |
type_size_ = sizeof(foo.a) + sizeof(foo.b); \
|
|
Packit Service |
c5cf8c |
type_extent_ = (MPI_Aint) sizeof(foo); \
|
|
Packit Service |
c5cf8c |
el_size_ = (sizeof(foo.a) == sizeof(foo.b)) ? (int) sizeof(foo.a) : -1; \
|
|
Packit Service |
c5cf8c |
true_ub_ = (MPIR_VOID_PTR_CAST_TO_MPI_AINT ((char *) &foo.b - \
|
|
Packit Service |
c5cf8c |
(char *) &foo.a)) + \
|
|
Packit Service |
c5cf8c |
(MPI_Aint) sizeof(foo.b); \
|
|
Packit Service |
c5cf8c |
alignsize_ = MPL_MAX(MPIR_Datatype_get_basic_size(mt1_), \
|
|
Packit Service |
c5cf8c |
MPIR_Datatype_get_basic_size(mt2_)); \
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*@
|
|
Packit Service |
c5cf8c |
MPIR_Type_create_pairtype - create necessary data structures for certain
|
|
Packit Service |
c5cf8c |
pair types (all but MPI_2INT etc., which never have the size != extent
|
|
Packit Service |
c5cf8c |
issue).
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
This function is different from the other MPIR_Type_create functions in that
|
|
Packit Service |
c5cf8c |
it fills in an already- allocated MPIR_Datatype. This is important for
|
|
Packit Service |
c5cf8c |
allowing configure-time determination of the MPI type values (these types
|
|
Packit Service |
c5cf8c |
are stored in the "direct" space, for those familiar with how MPICH deals
|
|
Packit Service |
c5cf8c |
with type allocation).
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Input Parameters:
|
|
Packit Service |
c5cf8c |
+ type - name of pair type (e.g. MPI_FLOAT_INT)
|
|
Packit Service |
c5cf8c |
- new_dtp - pointer to previously allocated datatype structure, which is
|
|
Packit Service |
c5cf8c |
filled in by this function
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Return Value:
|
|
Packit Service |
c5cf8c |
MPI_SUCCESS on success, MPI errno on failure.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Note:
|
|
Packit Service |
c5cf8c |
Section 4.9.3 (MINLOC and MAXLOC) of the MPI-1 standard specifies that
|
|
Packit Service |
c5cf8c |
these types should be built as if by the following (e.g. MPI_FLOAT_INT):
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
type[0] = MPI_FLOAT
|
|
Packit Service |
c5cf8c |
type[1] = MPI_INT
|
|
Packit Service |
c5cf8c |
disp[0] = 0
|
|
Packit Service |
c5cf8c |
disp[1] = sizeof(float) <---- questionable displacement!
|
|
Packit Service |
c5cf8c |
block[0] = 1
|
|
Packit Service |
c5cf8c |
block[1] = 1
|
|
Packit Service |
c5cf8c |
MPI_TYPE_STRUCT(2, block, disp, type, MPI_FLOAT_INT)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
However, this is a relatively naive approach that does not take struct
|
|
Packit Service |
c5cf8c |
padding into account when setting the displacement of the second element.
|
|
Packit Service |
c5cf8c |
Thus in our implementation we have chosen to instead use the actual
|
|
Packit Service |
c5cf8c |
difference in starting locations of the two types in an actual struct.
|
|
Packit Service |
c5cf8c |
@*/
|
|
Packit Service |
c5cf8c |
int MPIR_Type_create_pairtype(MPI_Datatype type, MPIR_Datatype * new_dtp)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int err, mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
int type_size, alignsize;
|
|
Packit Service |
c5cf8c |
MPI_Aint type_extent, true_ub, el_size;
|
|
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 = 1;
|
|
Packit Service |
c5cf8c |
new_dtp->is_committed = 1; /* predefined types are pre-committed */
|
|
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 |
switch (type) {
|
|
Packit Service |
c5cf8c |
case MPI_FLOAT_INT:
|
|
Packit Service |
c5cf8c |
PAIRTYPE_SIZE_EXTENT(MPI_FLOAT, float, MPI_INT, int,
|
|
Packit Service |
c5cf8c |
type_size, type_extent, el_size, true_ub, alignsize);
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
case MPI_DOUBLE_INT:
|
|
Packit Service |
c5cf8c |
PAIRTYPE_SIZE_EXTENT(MPI_DOUBLE, double, MPI_INT, int,
|
|
Packit Service |
c5cf8c |
type_size, type_extent, el_size, true_ub, alignsize);
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
case MPI_LONG_INT:
|
|
Packit Service |
c5cf8c |
PAIRTYPE_SIZE_EXTENT(MPI_LONG, long, MPI_INT, int,
|
|
Packit Service |
c5cf8c |
type_size, type_extent, el_size, true_ub, alignsize);
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
case MPI_SHORT_INT:
|
|
Packit Service |
c5cf8c |
PAIRTYPE_SIZE_EXTENT(MPI_SHORT, short, MPI_INT, int,
|
|
Packit Service |
c5cf8c |
type_size, type_extent, el_size, true_ub, alignsize);
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
case MPI_LONG_DOUBLE_INT:
|
|
Packit Service |
c5cf8c |
PAIRTYPE_SIZE_EXTENT(MPI_LONG_DOUBLE, long double, MPI_INT, int,
|
|
Packit Service |
c5cf8c |
type_size, type_extent, el_size, true_ub, alignsize);
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
default:
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Err_create_code(MPI_SUCCESS,
|
|
Packit Service |
c5cf8c |
MPIR_ERR_RECOVERABLE,
|
|
Packit Service |
c5cf8c |
"MPIR_Type_create_pairtype",
|
|
Packit Service |
c5cf8c |
__LINE__, MPI_ERR_OTHER, "**dtype", 0);
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
new_dtp->n_builtin_elements = 2;
|
|
Packit Service |
c5cf8c |
new_dtp->builtin_element_size = el_size;
|
|
Packit Service |
c5cf8c |
new_dtp->basic_type = type;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
new_dtp->has_sticky_lb = 0;
|
|
Packit Service |
c5cf8c |
new_dtp->true_lb = 0;
|
|
Packit Service |
c5cf8c |
new_dtp->lb = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
new_dtp->has_sticky_ub = 0;
|
|
Packit Service |
c5cf8c |
new_dtp->true_ub = true_ub;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
new_dtp->size = type_size;
|
|
Packit Service |
c5cf8c |
new_dtp->ub = type_extent; /* possible padding */
|
|
Packit Service |
c5cf8c |
new_dtp->extent = type_extent;
|
|
Packit Service |
c5cf8c |
new_dtp->alignsize = alignsize;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* place maximum on alignment based on padding rules */
|
|
Packit Service |
c5cf8c |
/* There are some really wierd rules for structure alignment;
|
|
Packit Service |
c5cf8c |
* these capture the ones of which we are aware. */
|
|
Packit Service |
c5cf8c |
switch (type) {
|
|
Packit Service |
c5cf8c |
case MPI_SHORT_INT:
|
|
Packit Service |
c5cf8c |
case MPI_LONG_INT:
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_MAX_INTEGER_ALIGNMENT
|
|
Packit Service |
c5cf8c |
new_dtp->alignsize = MPL_MIN(new_dtp->alignsize, HAVE_MAX_INTEGER_ALIGNMENT);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
case MPI_FLOAT_INT:
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_MAX_FP_ALIGNMENT
|
|
Packit Service |
c5cf8c |
new_dtp->alignsize = MPL_MIN(new_dtp->alignsize, HAVE_MAX_FP_ALIGNMENT);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
case MPI_DOUBLE_INT:
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_MAX_DOUBLE_FP_ALIGNMENT
|
|
Packit Service |
c5cf8c |
new_dtp->alignsize = MPL_MIN(new_dtp->alignsize, HAVE_MAX_DOUBLE_FP_ALIGNMENT);
|
|
Packit Service |
c5cf8c |
#elif defined(HAVE_MAX_FP_ALIGNMENT)
|
|
Packit Service |
c5cf8c |
new_dtp->alignsize = MPL_MIN(new_dtp->alignsize, HAVE_MAX_FP_ALIGNMENT);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
case MPI_LONG_DOUBLE_INT:
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_MAX_LONG_DOUBLE_FP_ALIGNMENT
|
|
Packit Service |
c5cf8c |
new_dtp->alignsize = MPL_MIN(new_dtp->alignsize, HAVE_MAX_LONG_DOUBLE_FP_ALIGNMENT);
|
|
Packit Service |
c5cf8c |
#elif defined(HAVE_MAX_FP_ALIGNMENT)
|
|
Packit Service |
c5cf8c |
new_dtp->alignsize = MPL_MIN(new_dtp->alignsize, HAVE_MAX_FP_ALIGNMENT);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
new_dtp->is_contig = (((MPI_Aint) type_size) == type_extent) ? 1 : 0;
|
|
Packit Service |
c5cf8c |
new_dtp->max_contig_blocks = (((MPI_Aint) type_size) == type_extent) ? 1 : 2;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* fill in dataloops -- only case where we precreate dataloops
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* this is necessary because these types aren't committed by the
|
|
Packit Service |
c5cf8c |
* user, which is the other place where we create dataloops. so
|
|
Packit Service |
c5cf8c |
* if the user uses one of these w/out building some more complex
|
|
Packit Service |
c5cf8c |
* type and then committing it, then the dataloop will be missing.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef MPID_NEEDS_DLOOP_ALL_BYTES
|
|
Packit Service |
c5cf8c |
/* If MPID implementation needs use to reduce everything to
|
|
Packit Service |
c5cf8c |
* a byte stream, do that. */
|
|
Packit Service |
c5cf8c |
err = MPIR_Dataloop_create_pairtype(type,
|
|
Packit Service |
c5cf8c |
&(new_dtp->dataloop),
|
|
Packit Service |
c5cf8c |
&(new_dtp->dataloop_size),
|
|
Packit Service |
c5cf8c |
&(new_dtp->dataloop_depth), MPIDU_DATALOOP_ALL_BYTES);
|
|
Packit Service |
c5cf8c |
#else
|
|
Packit Service |
c5cf8c |
err = MPIR_Dataloop_create_pairtype(type,
|
|
Packit Service |
c5cf8c |
&(new_dtp->dataloop),
|
|
Packit Service |
c5cf8c |
&(new_dtp->dataloop_size),
|
|
Packit Service |
c5cf8c |
&(new_dtp->dataloop_depth), MPIR_DATALOOP_DEFAULT);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef MPID_Type_commit_hook
|
|
Packit Service |
c5cf8c |
if (!err) {
|
|
Packit Service |
c5cf8c |
err = MPID_Type_commit_hook(new_dtp);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif /* MPID_Type_commit_hook */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (err) {
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Err_create_code(MPI_SUCCESS,
|
|
Packit Service |
c5cf8c |
MPIR_ERR_RECOVERABLE,
|
|
Packit Service |
c5cf8c |
"MPIR_Dataloop_create_pairtype",
|
|
Packit Service |
c5cf8c |
__LINE__, MPI_ERR_OTHER, "**nomem", 0);
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
}
|