📄 mpid_datatype.h
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */#ifndef MPID_DATATYPE_H#define MPID_DATATYPE_H#include "mpiimpl.h"#include "mpid_dataloop.h"#include "mpihandlemem.h"/* NOTE: * - struct MPID_Dataloop and MPID_Segment are defined in * src/mpid/common/datatype/mpid_dataloop.h (and gen_dataloop.h). * - MPIU_Object_alloc_t is defined in src/include/mpihandle.h */#define MPID_Datatype_get_ptr(a,ptr) MPID_Getb_ptr(Datatype,a,0x000000ff,ptr)/* MPID_Datatype_get_basic_id() is useful for creating and indexing into arrays that store data on a per-basic type basis */#define MPID_Datatype_get_basic_id(a) ((a)&0x000000ff)#define MPID_Datatype_get_basic_size(a) (((a)&0x0000ff00)>>8)#define MPID_Datatype_add_ref(datatype_ptr) MPIU_Object_add_ref((datatype_ptr))#define MPID_Datatype_get_basic_type(a,eltype_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ eltype_ = ((MPID_Datatype *) ptr)->eltype; \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ eltype_ = ((MPID_Datatype *) ptr)->eltype; \ break; \ case HANDLE_KIND_BUILTIN: \ eltype_ = a; \ break; \ case HANDLE_KIND_INVALID: \ default: \ eltype_ = 0; \ break; \ \ } \}/* MPID_Datatype_release decrements the reference count on the MPID_Datatype * and, if the refct is then zero, frees the MPID_Datatype and associated * structures. */#define MPID_Datatype_release(datatype_ptr) \{ \ int inuse; \ \ MPIU_Object_release_ref((datatype_ptr),&inuse); \ if (!inuse) { \ int lmpi_errno = MPI_SUCCESS; \ if (MPIR_Process.attr_free && datatype_ptr->attributes) { \ lmpi_errno = MPIR_Process.attr_free( datatype_ptr->handle, \ datatype_ptr->attributes ); \ } \ /* LEAVE THIS COMMENTED OUT UNTIL WE HAVE SOME USE FOR THE FREE_FN \ if (datatype_ptr->free_fn) { \ mpi_errno = (datatype_ptr->free_fn)( datatype_ptr ); \ if (mpi_errno) { \ MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_TYPE_FREE); \ return MPIR_Err_return_comm( 0, FCNAME, mpi_errno ); \ } \ } */ \ if (lmpi_errno == MPI_SUCCESS) { \ MPID_Datatype_free(datatype_ptr); \ } \ } \}/* Note: Probably there is some clever way to build all of these from a macro. */#define MPID_Datatype_get_size_macro(a,size_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ size_ = ((MPID_Datatype *) ptr)->size; \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ size_ = ((MPID_Datatype *) ptr)->size; \ break; \ case HANDLE_KIND_BUILTIN: \ size_ = MPID_Datatype_get_basic_size(a); \ break; \ case HANDLE_KIND_INVALID: \ default: \ size_ = 0; \ break; \ \ } \}/* * The following macro allows us to reference either the regular or * hetero value for the 3 fields (NULL,_size,_depth) in the * MPID_Datatype structure. This is used in the many * macros that access fields of the datatype. We need this macro * to simplify the definition of the other macros in the case where * MPID_HAS_HETERO is *not* defined. */#if defined(MPID_HAS_HETERO) || 1#define MPID_GET_FIELD(hetero_,value_,fieldname_) \ if (hetero_ == MPID_DATALOOP_HOMOGENEOUS) \ value_ = ((MPID_Datatype *)ptr)->dataloop##fieldname_; \ else value_ = ((MPID_Datatype *) ptr)->hetero_dloop##fieldname_;#else#define MPID_GET_FIELD(hetero_,value_,fieldname_) \ value_ = ((MPID_Datatype *)ptr)->dataloop##fieldname_#endif#if defined(MPID_HAS_HETERO) || 1#define MPID_SET_FIELD(hetero_,value_,fieldname_) \ if (hetero_ == MPID_DATALOOP_HOMOGENEOUS) \ ((MPID_Datatype *)ptr)->dataloop##fieldname_ = value_; \ else ((MPID_Datatype *) ptr)->hetero_dloop##fieldname_ = value_;#else#define MPID_GET_FIELD(hetero_,value_,fieldname_) \ value_ = ((MPID_Datatype *)ptr)->dataloop##fieldname_#endif #define MPID_Datatype_get_loopdepth_macro(a,depth_,hetero_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ MPID_GET_FIELD(hetero_,depth_,_depth); \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ MPID_GET_FIELD(hetero_,depth_,_depth); \ break; \ case HANDLE_KIND_INVALID: \ case HANDLE_KIND_BUILTIN: \ default: \ depth_ = 0; \ break; \ } \}#define MPID_Datatype_get_loopsize_macro(a,depth_,hetero_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ MPID_GET_FIELD(hetero_,depth_,_size); \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ MPID_GET_FIELD(hetero_,depth_,_size); \ break; \ case HANDLE_KIND_INVALID: \ case HANDLE_KIND_BUILTIN: \ default: \ depth_ = 0; \ break; \ } \}#define MPID_Datatype_get_loopptr_macro(a,lptr_,hetero_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ MPID_GET_FIELD(hetero_,lptr_,); \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ MPID_GET_FIELD(hetero_,lptr_,); \ break; \ case HANDLE_KIND_INVALID: \ case HANDLE_KIND_BUILTIN: \ default: \ lptr_ = 0; \ break; \ } \}#define MPID_Datatype_set_loopdepth_macro(a,depth_,hetero_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ MPID_SET_FIELD(hetero_,depth_,_depth); \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ MPID_SET_FIELD(hetero_,depth_,_depth); \ break; \ case HANDLE_KIND_INVALID: \ case HANDLE_KIND_BUILTIN: \ default: \ depth_ = 0; \ break; \ } \}#define MPID_Datatype_set_loopsize_macro(a,depth_,hetero_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ MPID_SET_FIELD(hetero_,depth_,_size); \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ MPID_SET_FIELD(hetero_,depth_,_size); \ break; \ case HANDLE_KIND_INVALID: \ case HANDLE_KIND_BUILTIN: \ default: \ depth_ = 0; \ break; \ } \}#define MPID_Datatype_set_loopptr_macro(a,lptr_,hetero_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ MPID_SET_FIELD(hetero_,lptr_,); \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ MPID_SET_FIELD(hetero_,lptr_,); \ break; \ case HANDLE_KIND_INVALID: \ case HANDLE_KIND_BUILTIN: \ default: \ lptr_ = 0; \ break; \ } \} #define MPID_Datatype_get_extent_macro(a,extent_) \{ \ void *ptr; \ switch (HANDLE_GET_KIND(a)) { \ case HANDLE_KIND_DIRECT: \ ptr = MPID_Datatype_direct+HANDLE_INDEX(a); \ extent_ = ((MPID_Datatype *) ptr)->extent; \ break; \ case HANDLE_KIND_INDIRECT: \ ptr = ((MPID_Datatype *) \ MPIU_Handle_get_ptr_indirect(a,&MPID_Datatype_mem)); \ extent_ = ((MPID_Datatype *) ptr)->extent; \ break; \ case HANDLE_KIND_INVALID: \ case HANDLE_KIND_BUILTIN: \ default: \ extent_ = MPID_Datatype_get_basic_size(a); /* same as size */ \ break; \ } \}#define MPID_Datatype_valid_ptr(ptr,err) MPID_Valid_ptr_class(Datatype,ptr,MPI_ERR_TYPE,err)/* to be used only after MPID_Datatype_valid_ptr(); the check on * err == MPI_SUCCESS ensures that we won't try to dereference the * pointer if something has already been detected as wrong. */#define MPID_Datatype_committed_ptr(ptr,err) \{ \ if ((err == MPI_SUCCESS) && !((ptr)->is_committed)) \ err = MPIR_Err_create_code(MPI_SUCCESS, \ MPIR_ERR_RECOVERABLE, \ FCNAME, \ __LINE__, \ MPI_ERR_TYPE, \ "**dtypecommit", \ 0); \}/*S MPID_Datatype_contents - Holds envelope and contents data for a given datatype Notes: Space is allocated beyond the structure itself in order to hold the arrays of types, ints, and aints, in that order. S*/typedef struct MPID_Datatype_contents { int combiner; int nr_ints; int nr_aints; int nr_types; /* space allocated beyond structure used to store the types[], * ints[], and aints[], in that order. */} MPID_Datatype_contents;/* Datatype Structure *//*S MPID_Datatype - Description of the MPID Datatype structure Notes: The 'ref_count' is needed for nonblocking operations such as.vb MPI_Type_struct( ... , &newtype ); MPI_Irecv( buf, 1000, newtype, ..., &request ); MPI_Type_free( &newtype ); ... MPI_Wait( &request, &status );.ve Module: Datatype-DS Notes: Alternatives: The following alternatives for the layout of this structure were considered. Most were not chosen because any benefit in performance or memory efficiency was outweighed by the added complexity of the implementation. A number of fields contain only boolean inforation ('is_contig', 'has_sticky_ub', 'has_sticky_lb', 'is_permanent', 'is_committed'). These could be combined and stored in a single bit vector. 'MPI_Type_dup' could be implemented with a shallow copy, where most of the data fields, would not be copied into the new object created by 'MPI_Type_dup'; instead, the new object could point to the data fields in the old object. However, this requires more code to make sure that fields are found in the correct objects and that deleting the old object doesn't invalidate the dup'ed datatype. Originally we attempted to keep contents/envelope data in a non-optimized dataloop. The subarray and darray types were particularly problematic, and eventually we decided it would be simpler to just keep contents/ envelope data in arrays separately. Earlier versions of the ADI used a single API to change the 'ref_count', with each MPI object type having a separate routine. Since reference count changes are always up or down one, and since all MPI objects are defined to have the 'ref_count' field in the same place, the current
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -