|
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 */
|