OpenMPI  0.1.1
ompi_datatype.h
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  * Copyright (c) 2009-2012 The University of Tennessee and The University
4  * of Tennessee Research Foundation. All rights
5  * reserved.
6  * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
7  * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
8  * $COPYRIGHT$
9  *
10  * Additional copyrights may follow
11  *
12  * $HEADER$
13  */
14 
15 /**
16  * ompi_datatype_t interface for OMPI internal data type representation
17  *
18  * ompi_datatype_t is a class which represents contiguous or
19  * non-contiguous data together with constituent type-related
20  * information.
21  */
22 
23 #ifndef OMPI_DATATYPE_H_HAS_BEEN_INCLUDED
24 #define OMPI_DATATYPE_H_HAS_BEEN_INCLUDED
25 
26 #include "ompi_config.h"
27 
28 #include <stddef.h>
29 #ifdef HAVE_STDINT_H
30 #include <stdint.h>
31 #endif
32 #ifdef HAVE_STRING_H
33 #include <string.h>
34 #endif
35 
36 #include "ompi/constants.h"
39 #include "opal/datatype/opal_convertor.h"
40 #include "opal/datatype/opal_datatype.h"
41 #include "mpi.h"
42 
43 BEGIN_C_DECLS
44 
45 /* These flags are on top of the flags in opal_datatype.h */
46 /* Is the datatype predefined as MPI type (not necessarily as OPAL type, e.g. struct/block types) */
47 #define OMPI_DATATYPE_FLAG_PREDEFINED 0x0200
48 /* Keep trace of the type of the predefined datatypes */
49 #define OMPI_DATATYPE_FLAG_DATA_INT 0x1000
50 #define OMPI_DATATYPE_FLAG_DATA_FLOAT 0x2000
51 #define OMPI_DATATYPE_FLAG_DATA_COMPLEX 0x3000
52 #define OMPI_DATATYPE_FLAG_DATA_TYPE 0x3000
53 /* In which language the datatype is intended for to be used */
54 #define OMPI_DATATYPE_FLAG_DATA_C 0x4000
55 #define OMPI_DATATYPE_FLAG_DATA_CPP 0x8000
56 #define OMPI_DATATYPE_FLAG_DATA_FORTRAN 0xC000
57 #define OMPI_DATATYPE_FLAG_DATA_LANGUAGE 0xC000
58 
59 #define OMPI_DATATYPE_MAX_PREDEFINED 45
60 
61 #if OMPI_DATATYPE_MAX_PREDEFINED > OPAL_DATATYPE_MAX_SUPPORTED
62 #error Need to increase the number of supported dataypes by OPAL (value OPAL_DATATYPE_MAX_SUPPORTED).
63 #endif
64 
65 
66 /* the data description.
67  */
69  opal_datatype_t super; /**< Base opal_datatype_t superclass */
70  /* --- cacheline 5 boundary (320 bytes) was 32 bytes ago --- */
71 
72  int32_t id; /**< OMPI-layers unique id of the type */
73  int32_t d_f_to_c_index; /**< Fortran index for this datatype */
74  struct opal_hash_table_t *d_keyhash; /**< Attribute fields */
75 
76  void* args; /**< Data description for the user */
77  void* packed_description; /**< Packed description of the datatype */
78  /* --- cacheline 6 boundary (384 bytes) --- */
79  char name[MPI_MAX_OBJECT_NAME];/**< Externally visible name */
80  /* --- cacheline 7 boundary (448 bytes) --- */
81 
82  /* size: 448, cachelines: 7, members: 7 */
83 };
84 
85 typedef struct ompi_datatype_t ompi_datatype_t;
86 
88 
89 /**
90  * Padded struct to maintain back compatibiltiy.
91  * See opal/communicator/communicator.h comments with struct opal_communicator_t
92  * for full explanation why we chose the following padding construct for predefines.
93  */
94 
95 /* Using set constant for padding of the DATATYPE handles because the size of
96  * base structure is very close to being the same no matter the bitness.
97  */
98 #define PREDEFINED_DATATYPE_PAD (512)
99 
101  struct ompi_datatype_t dt;
102  char padding[PREDEFINED_DATATYPE_PAD - sizeof(ompi_datatype_t)];
103 };
104 
106 
107 /*
108  * The list of predefined datatypes is specified in ompi/include/mpi.h.in
109  */
110 
111 /* Base convertor for all external32 operations */
112 OMPI_DECLSPEC extern opal_convertor_t* ompi_mpi_external32_convertor;
113 OMPI_DECLSPEC extern opal_convertor_t* ompi_mpi_local_convertor;
114 extern struct opal_pointer_array_t ompi_datatype_f_to_c_table;
115 
116 OMPI_DECLSPEC int32_t ompi_datatype_init( void );
117 OMPI_DECLSPEC int32_t ompi_datatype_finalize( void );
118 
119 OMPI_DECLSPEC int32_t ompi_datatype_default_convertors_init( void );
120 OMPI_DECLSPEC int32_t ompi_datatype_default_convertors_fini( void );
121 
122 OMPI_DECLSPEC void ompi_datatype_dump (const ompi_datatype_t* pData);
123 OMPI_DECLSPEC ompi_datatype_t* ompi_datatype_create( int32_t expectedSize );
124 
125 static inline int32_t
126 ompi_datatype_is_committed( const ompi_datatype_t* type )
127 {
128  return opal_datatype_is_committed(&type->super);
129 }
130 
131 static inline int32_t
132 ompi_datatype_is_overlapped( const ompi_datatype_t* type )
133 {
134  return opal_datatype_is_overlapped(&type->super);
135 }
136 
137 static inline int32_t
138 ompi_datatype_is_valid( const ompi_datatype_t* type )
139 {
140  return opal_datatype_is_valid(&type->super);
141 }
142 
143 static inline int32_t
144 ompi_datatype_is_predefined( const ompi_datatype_t* type )
145 {
146  return (type->super.flags & OMPI_DATATYPE_FLAG_PREDEFINED);
147 }
148 
149 static inline int32_t
150 ompi_datatype_is_contiguous_memory_layout( const ompi_datatype_t* type, int32_t count )
151 {
152  return opal_datatype_is_contiguous_memory_layout(&type->super, count);
153 }
154 
155 static inline int32_t
156 ompi_datatype_commit( ompi_datatype_t ** type )
157 {
158  return opal_datatype_commit ( (opal_datatype_t*)*type );
159 }
160 
161 
162 OMPI_DECLSPEC int32_t ompi_datatype_destroy( ompi_datatype_t** type);
163 
164 
165 /*
166  * Datatype creation functions
167  */
168 static inline int32_t
169 ompi_datatype_add( ompi_datatype_t* pdtBase, const ompi_datatype_t* pdtAdd, uint32_t count,
170  OPAL_PTRDIFF_TYPE disp, OPAL_PTRDIFF_TYPE extent )
171 {
172  return opal_datatype_add( &pdtBase->super, &pdtAdd->super, count, disp, extent );
173 }
174 
175 
176 static inline int32_t
177 ompi_datatype_duplicate( const ompi_datatype_t* oldType, ompi_datatype_t** newType )
178 {
179  ompi_datatype_t * new_ompi_datatype = ompi_datatype_create( oldType->super.desc.used + 2 );
180 
181  *newType = new_ompi_datatype;
182  if( NULL == new_ompi_datatype ) {
183  return OMPI_ERR_OUT_OF_RESOURCE;
184  }
185  opal_datatype_clone( &oldType->super, &new_ompi_datatype->super);
186  /* Strip the predefined flag at the OMPI level. */
187  new_ompi_datatype->super.flags &= ~OMPI_DATATYPE_FLAG_PREDEFINED;
188 
189  /* Set the keyhash to NULL -- copying attributes is *only* done at
190  the top level (specifically, MPI_TYPE_DUP). */
191  new_ompi_datatype->d_keyhash = NULL;
192  new_ompi_datatype->args = NULL;
193  snprintf (new_ompi_datatype->name, MPI_MAX_OBJECT_NAME, "Dup %s",
194  oldType->name);
195 
196  return OMPI_SUCCESS;
197 }
198 
199 OMPI_DECLSPEC int32_t ompi_datatype_create_contiguous( int count, const ompi_datatype_t* oldType, ompi_datatype_t** newType );
200 OMPI_DECLSPEC int32_t ompi_datatype_create_vector( int count, int bLength, int stride,
201  const ompi_datatype_t* oldType, ompi_datatype_t** newType );
202 OMPI_DECLSPEC int32_t ompi_datatype_create_hvector( int count, int bLength, OPAL_PTRDIFF_TYPE stride,
203  const ompi_datatype_t* oldType, ompi_datatype_t** newType );
204 OMPI_DECLSPEC int32_t ompi_datatype_create_indexed( int count, const int* pBlockLength, const int* pDisp,
205  const ompi_datatype_t* oldType, ompi_datatype_t** newType );
206 OMPI_DECLSPEC int32_t ompi_datatype_create_hindexed( int count, const int* pBlockLength, const OPAL_PTRDIFF_TYPE* pDisp,
207  const ompi_datatype_t* oldType, ompi_datatype_t** newType );
208 OMPI_DECLSPEC int32_t ompi_datatype_create_indexed_block( int count, int bLength, const int* pDisp,
209  const ompi_datatype_t* oldType, ompi_datatype_t** newType );
210 OMPI_DECLSPEC int32_t ompi_datatype_create_struct( int count, const int* pBlockLength, const OPAL_PTRDIFF_TYPE* pDisp,
211  ompi_datatype_t* const* pTypes, ompi_datatype_t** newType );
212 OMPI_DECLSPEC int32_t ompi_datatype_create_darray( int size, int rank, int ndims, int const* gsize_array,
213  int const* distrib_array, int const* darg_array,
214  int const* psize_array, int order, const ompi_datatype_t* oldtype,
215  ompi_datatype_t** newtype);
216 OMPI_DECLSPEC int32_t ompi_datatype_create_subarray(int ndims, int const* size_array, int const* subsize_array,
217  int const* start_array, int order,
218  const ompi_datatype_t* oldtype, ompi_datatype_t** newtype);
219 static inline int32_t
220 ompi_datatype_create_resized( const ompi_datatype_t* oldType, OPAL_PTRDIFF_TYPE lb, OPAL_PTRDIFF_TYPE extent, ompi_datatype_t** newType )
221 {
222  ompi_datatype_t * type;
223  ompi_datatype_duplicate( oldType, &type );
224  if ( NULL == type) {
225  return OMPI_ERR_OUT_OF_RESOURCE;
226  }
227  opal_datatype_resize ( &type->super, lb, extent );
228  *newType = type;
229  return OMPI_SUCCESS;
230 }
231 
232 static inline int32_t
233 ompi_datatype_type_lb( const ompi_datatype_t* type, OPAL_PTRDIFF_TYPE* disp )
234 {
235  return opal_datatype_type_lb(&type->super, disp);
236 }
237 
238 static inline int32_t
239 ompi_datatype_type_ub( const ompi_datatype_t* type, OPAL_PTRDIFF_TYPE* disp )
240 {
241  return opal_datatype_type_ub( &type->super, disp);
242 }
243 
244 static inline int32_t
245 ompi_datatype_type_size ( const ompi_datatype_t* type, size_t *size )
246 {
247  return opal_datatype_type_size( &type->super, size);
248 }
249 
250 static inline int32_t
251 ompi_datatype_type_extent( const ompi_datatype_t* type, OPAL_PTRDIFF_TYPE* extent )
252 {
253  return opal_datatype_type_extent( &type->super, extent);
254 }
255 
256 static inline int32_t
257 ompi_datatype_get_extent( const ompi_datatype_t* type, OPAL_PTRDIFF_TYPE* lb, OPAL_PTRDIFF_TYPE* extent)
258 {
259  return opal_datatype_get_extent( &type->super, lb, extent);
260 }
261 
262 static inline int32_t
263 ompi_datatype_get_true_extent( const ompi_datatype_t* type, OPAL_PTRDIFF_TYPE* true_lb, OPAL_PTRDIFF_TYPE* true_extent)
264 {
265  return opal_datatype_get_true_extent( &type->super, true_lb, true_extent);
266 }
267 
268 static inline int32_t
269 ompi_datatype_get_element_count( const ompi_datatype_t* type, size_t iSize )
270 {
271  return opal_datatype_get_element_count( &type->super, iSize );
272 }
273 
274 static inline int32_t
275 ompi_datatype_set_element_count( const ompi_datatype_t* type, uint32_t count, size_t* length )
276 {
277  return opal_datatype_set_element_count( &type->super, count, length );
278 }
279 
280 static inline int32_t
281 ompi_datatype_copy_content_same_ddt( const ompi_datatype_t* type, size_t count,
282  void* pDestBuf, void* pSrcBuf )
283 {
284  int32_t length, rc;
285 
286  while( 0 != count ) {
287  length = INT_MAX;
288  if( ((size_t)length) > count ) length = (int32_t)count;
289  rc = opal_datatype_copy_content_same_ddt( &type->super, count, (char*)pDestBuf, (char*)pSrcBuf );
290  if( 0 != rc ) return rc;
291  count -= (size_t)length;
292  }
293  return 0;
294 }
295 
296 OMPI_DECLSPEC const ompi_datatype_t* ompi_datatype_match_size( int size, uint16_t datakind, uint16_t datalang );
297 
298 /*
299  *
300  */
301 OMPI_DECLSPEC int32_t ompi_datatype_sndrcv( void *sbuf, int32_t scount, const ompi_datatype_t* sdtype,
302  void *rbuf, int32_t rcount, const ompi_datatype_t* rdtype);
303 
304 /*
305  *
306  */
307 OMPI_DECLSPEC int32_t ompi_datatype_get_args( const ompi_datatype_t* pData, int32_t which,
308  int32_t * ci, int32_t * i,
309  int32_t * ca, OPAL_PTRDIFF_TYPE* a,
310  int32_t * cd, ompi_datatype_t** d, int32_t * type);
311 OMPI_DECLSPEC int32_t ompi_datatype_set_args( ompi_datatype_t* pData,
312  int32_t ci, int32_t ** i,
313  int32_t ca, OPAL_PTRDIFF_TYPE* a,
314  int32_t cd, ompi_datatype_t** d,int32_t type);
315 OMPI_DECLSPEC int32_t ompi_datatype_copy_args( const ompi_datatype_t* source_data,
316  ompi_datatype_t* dest_data );
317 OMPI_DECLSPEC int32_t ompi_datatype_release_args( ompi_datatype_t* pData );
318 OMPI_DECLSPEC ompi_datatype_t* ompi_datatype_get_single_predefined_type_from_args( ompi_datatype_t* type );
319 
320 /*
321  *
322  */
323 OMPI_DECLSPEC size_t ompi_datatype_pack_description_length( const ompi_datatype_t* datatype );
324 
325 /*
326  *
327  */
328 OMPI_DECLSPEC int ompi_datatype_get_pack_description( ompi_datatype_t* datatype,
329  const void** packed_buffer );
330 
331 /*
332  *
333  */
334 struct ompi_proc_t;
335 OMPI_DECLSPEC ompi_datatype_t* ompi_datatype_create_from_packed_description( void** packed_buffer,
336  struct ompi_proc_t* remote_processor );
337 
338 OMPI_DECLSPEC int32_t ompi_datatype_print_args( const ompi_datatype_t* pData );
339 
340 #if OPAL_ENABLE_DEBUG
341 /*
342  * Set a breakpoint to this function in your favorite debugger
343  * to make it stop on all pack and unpack errors.
344  */
345 OMPI_DECLSPEC int ompi_datatype_safeguard_pointer_debug_breakpoint( const void* actual_ptr, int length,
346  const void* initial_ptr,
347  const ompi_datatype_t* pData,
348  int count );
349 #endif /* OPAL_ENABLE_DEBUG */
350 
351 END_C_DECLS
352 #endif /* OMPI_DATATYPE_H_HAS_BEEN_INCLUDED */
uint16_t flags
the flags
Definition: opal_datatype.h:105
Definition: opal_hash_table.h:42
void * args
Data description for the user.
Definition: ompi_datatype.h:76
dynamic pointer array
Definition: opal_pointer_array.h:45
Definition: ompi_datatype.h:68
dt_type_desc_t desc
the data description
Definition: opal_datatype.h:121
See opal_bitmap.h for an explanation of why there is a split between OPAL and ORTE for this generic c...
Remote Open MPI process structure.
Definition: proc.h:56
int size
size of list, i.e.
Definition: opal_pointer_array.h:58
opal_datatype_t super
Base opal_datatype_t superclass.
Definition: ompi_datatype.h:69
struct opal_hash_table_t * d_keyhash
Attribute fields.
Definition: ompi_datatype.h:74
void * packed_description
Packed description of the datatype.
Definition: ompi_datatype.h:77
A hash table that may be indexed with either fixed length (e.g.
Definition: opal_datatype.h:103
char name[MPI_MAX_OBJECT_NAME]
Externally visible name.
Definition: ompi_datatype.h:79
Definition: opal_convertor.h:90
opal_datatype_count_t used
the number of used elements in the description array
Definition: opal_datatype.h:94
int32_t d_f_to_c_index
Fortran index for this datatype.
Definition: ompi_datatype.h:73
Definition: ompi_datatype.h:100
int32_t id
OMPI-layers unique id of the type.
Definition: ompi_datatype.h:72
#define OBJ_CLASS_DECLARATION(NAME)
Declaration for class descriptor.
Definition: opal_object.h:236