1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
4  *                         University Research and Technology
5  *                         Corporation.  All rights reserved.
6  * Copyright (c) 2004-2018 The University of Tennessee and The University
7  *                         of Tennessee Research Foundation.  All rights
8  *                         reserved.
9  * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
10  *                         University of Stuttgart.  All rights reserved.
11  * Copyright (c) 2004-2006 The Regents of the University of California.
12  *                         All rights reserved.
13  * Copyright (c) 2009      Oak Ridge National Labs.  All rights reserved.
14  * Copyright (c) 2013      Los Alamos National Security, LLC. All rights
15  *                         reserved.
16  * Copyright (c) 2013      Cisco Systems, Inc.  All rights reserved.
17  * Copyright (c) 2017      Research Organization for Information Science
18  *                         and Technology (RIST). All rights reserved.
19  * $COPYRIGHT$
20  *
21  * Additional copyrights may follow
22  *
23  * $HEADER$
24  */
25 
26 #ifndef OPAL_DATATYPE_INTERNAL_H_HAS_BEEN_INCLUDED
27 #define OPAL_DATATYPE_INTERNAL_H_HAS_BEEN_INCLUDED
28 
29 #include "opal_config.h"
30 
31 #include <stdarg.h>
32 #include <string.h>
33 
34 #if defined(VERBOSE)
35 #include "opal/util/output.h"
36 
37 extern int opal_datatype_dfd;
38 
39 #  define DDT_DUMP_STACK( PSTACK, STACK_POS, PDESC, NAME ) \
40      opal_datatype_dump_stack( (PSTACK), (STACK_POS), (PDESC), (NAME) )
41 #  if defined(ACCEPT_C99)
42 #    define DUMP( ARGS... )          opal_output(opal_datatype_dfd, __VA_ARGS__)
43 #  else
44 #    if defined(__GNUC__) && !defined(__STDC__)
45 #      define DUMP(ARGS...)          opal_output( opal_datatype_dfd, ARGS)
46 #  else
DUMP(char * fmt,...)47 static inline void DUMP( char* fmt, ... )
48 {
49    va_list list;
50 
51    va_start( list, fmt );
52    opal_output_vverbose( 0, opal_datatype_dfd, fmt, list );
53    va_end( list );
54 }
55 #    endif  /* __GNUC__ && !__STDC__ */
56 #  endif  /* ACCEPT_C99 */
57 #else
58 #  define DDT_DUMP_STACK( PSTACK, STACK_POS, PDESC, NAME )
59 #  if defined(ACCEPT_C99)
60 #    define DUMP(ARGS...)
61 #  else
62 #    if defined(__GNUC__) && !defined(__STDC__)
63 #      define DUMP(ARGS...)
64 #    else
65        /* If we do not compile with PGI, mark the parameter as unused */
66 #      if !defined(__PGI)
67 #        define __opal_attribute_unused_tmp__  __opal_attribute_unused__
68 #      else
69 #        define __opal_attribute_unused_tmp__
70 #      endif
DUMP(char * fmt __opal_attribute_unused_tmp__,...)71 static inline void DUMP( char* fmt __opal_attribute_unused_tmp__, ... )
72 {
73 #if defined(__PGI)
74            /* Some compilers complain if we have "..." arguments and no
75               corresponding va_start() */
76            va_list arglist;
77            va_start(arglist, fmt);
78            va_end(arglist);
79 #endif
80 }
81 #         undef __opal_attribute_unused_tmp__
82 #    endif  /* __GNUC__ && !__STDC__ */
83 #  endif  /* ACCEPT_C99 */
84 #endif  /* VERBOSE */
85 
86 
87 /*
88  * There 3 types of predefined data types.
89  * - the basic one composed by just one basic datatype which are
90  *   definitively contiguous
91  * - the derived ones where the same basic type is used multiple times.
92  *   They should be most of the time contiguous.
93  * - and finally the derived one where multiple basic types are used.
94  *   Depending on the architecture they can be contiguous or not.
95  *
96  * At the OPAL-level we do not care from which language the datatype came from
97  * (C, C++ or FORTRAN), we only focus on their internal representation in
98  * the host memory.
99  *
100  * NOTE: This predefined datatype order should be matched by any upper-level
101  * users of the OPAL datatype.
102  */
103 #define OPAL_DATATYPE_LOOP           0
104 #define OPAL_DATATYPE_END_LOOP       1
105 #define OPAL_DATATYPE_LB             2
106 #define OPAL_DATATYPE_UB             3
107 #define OPAL_DATATYPE_FIRST_TYPE     4 /* Number of first real type */
108 #define OPAL_DATATYPE_INT1           4
109 #define OPAL_DATATYPE_INT2           5
110 #define OPAL_DATATYPE_INT4           6
111 #define OPAL_DATATYPE_INT8           7
112 #define OPAL_DATATYPE_INT16          8
113 #define OPAL_DATATYPE_UINT1          9
114 #define OPAL_DATATYPE_UINT2          10
115 #define OPAL_DATATYPE_UINT4          11
116 #define OPAL_DATATYPE_UINT8          12
117 #define OPAL_DATATYPE_UINT16         13
118 #define OPAL_DATATYPE_FLOAT2         14
119 #define OPAL_DATATYPE_FLOAT4         15
120 #define OPAL_DATATYPE_FLOAT8         16
121 #define OPAL_DATATYPE_FLOAT12        17
122 #define OPAL_DATATYPE_FLOAT16        18
123 #define OPAL_DATATYPE_FLOAT_COMPLEX  19
124 #define OPAL_DATATYPE_DOUBLE_COMPLEX 20
125 #define OPAL_DATATYPE_LONG_DOUBLE_COMPLEX 21
126 #define OPAL_DATATYPE_BOOL           22
127 #define OPAL_DATATYPE_WCHAR          23
128 #define OPAL_DATATYPE_UNAVAILABLE    24
129 
130 #ifndef OPAL_DATATYPE_MAX_PREDEFINED
131 #define OPAL_DATATYPE_MAX_PREDEFINED (OPAL_DATATYPE_UNAVAILABLE+1)
132 #elif OPAL_DATATYPE_MAX_PREDEFINED <= OPAL_DATATYPE_UNAVAILABLE
133 /*
134  * If the number of basic datatype should change update
135  * OPAL_DATATYPE_MAX_PREDEFINED in opal_datatype.h
136  */
137 #error OPAL_DATATYPE_MAX_PREDEFINED should be updated to the next value after the OPAL_DATATYPE_UNAVAILABLE define
138 #endif
139 
140 #define DT_INCREASE_STACK     8
141 
142 BEGIN_C_DECLS
143 
144 struct ddt_elem_id_description {
145     uint16_t   flags;  /**< flags for the record */
146     uint16_t   type;   /**< the basic data type id */
147 };
148 typedef struct ddt_elem_id_description ddt_elem_id_description;
149 
150 /**
151  * The data element description. It is similar to a vector type, a contiguous
152  * blocklen number of basic elements, with a displacement for the first element
153  * and then an extent for all the extra count.
154  */
155 struct ddt_elem_desc {
156     ddt_elem_id_description common;           /**< basic data description and flags */
157     uint32_t                blocklen;         /**< number of elements on each block */
158     size_t                  count;            /**< number of blocks */
159     ptrdiff_t               extent;           /**< extent of each block (in bytes) */
160     ptrdiff_t               disp;             /**< displacement of the first block */
161 };
162 typedef struct ddt_elem_desc ddt_elem_desc_t;
163 
164 /**
165  * The loop description, with it's two markers: one for the begining and one for
166  * the end. The initial marker contains the number of repetitions, the number of
167  * elements in the loop, and the extent of each loop. The end marker contains in
168  * addition to the number of elements (so that we can easily pair together the
169  * two markers), the size of the data contained inside and the displacement of
170  * the first element.
171  */
172 struct ddt_loop_desc {
173     ddt_elem_id_description common;           /**< basic data description and flags */
174     uint32_t                items;            /**< number of items in the loop */
175     uint32_t                loops;            /**< number of elements */
176     size_t                  unused;           /**< not used right now */
177     ptrdiff_t               extent;           /**< extent of the whole loop */
178 };
179 typedef struct ddt_loop_desc ddt_loop_desc_t;
180 
181 struct ddt_endloop_desc {
182     ddt_elem_id_description common;           /**< basic data description and flags */
183     uint32_t                items;            /**< number of elements */
184     uint32_t                unused;           /**< not used right now */
185     size_t                  size;             /**< real size of the data in the loop */
186     ptrdiff_t               first_elem_disp;  /**< the displacement of the first block in the loop */
187 };
188 typedef struct ddt_endloop_desc ddt_endloop_desc_t;
189 
190 union dt_elem_desc {
191     ddt_elem_desc_t    elem;
192     ddt_loop_desc_t    loop;
193     ddt_endloop_desc_t end_loop;
194 };
195 
196 #define CREATE_LOOP_START( _place, _count, _items, _extent, _flags )           \
197     do {                                                                       \
198         (_place)->loop.common.type   = OPAL_DATATYPE_LOOP;                     \
199         (_place)->loop.common.flags  = (_flags) & ~OPAL_DATATYPE_FLAG_DATA;    \
200         (_place)->loop.loops         = (_count);                               \
201         (_place)->loop.items         = (_items);                               \
202         (_place)->loop.extent        = (_extent);                              \
203         (_place)->loop.unused        = -1;                                     \
204     } while(0)
205 
206 #define CREATE_LOOP_END( _place, _items, _first_item_disp, _size, _flags )     \
207     do {                                                                       \
208         (_place)->end_loop.common.type = OPAL_DATATYPE_END_LOOP;               \
209         (_place)->end_loop.common.flags = (_flags) & ~OPAL_DATATYPE_FLAG_DATA; \
210         (_place)->end_loop.items = (_items);                                   \
211         (_place)->end_loop.first_elem_disp = (_first_item_disp);               \
212         (_place)->end_loop.size = (_size);  /* the size inside the loop */     \
213         (_place)->end_loop.unused = -1;                                        \
214     } while(0)
215 
216 
217 /**
218  * Create one or more elements depending on the value of _count. If the value
219  * is too large for the type of elem.count then use oth the elem.count and
220  * elem.blocklen to create it. If the number is prime then create a second
221  * element to account for the difference.
222  */
223 #define CREATE_ELEM( _place, _type, _flags, _count, _disp, _extent )           \
224     do {                                                                       \
225         (_place)->elem.common.flags = (_flags) | OPAL_DATATYPE_FLAG_DATA;      \
226         (_place)->elem.common.type  = (_type);                                 \
227         (_place)->elem.disp         = (_disp);                                 \
228         (_place)->elem.extent       = (_extent);                               \
229         (_place)->elem.count        = (_count);                                \
230         (_place)->elem.blocklen     = 1;                                       \
231     } while(0)
232 /*
233  * This array holds the descriptions desc.desc[2] of the predefined basic datatypes.
234  */
235 OPAL_DECLSPEC extern union dt_elem_desc opal_datatype_predefined_elem_desc[2 * OPAL_DATATYPE_MAX_PREDEFINED];
236 struct opal_datatype_t;
237 
238 /* Other fields starting after bdt_used (index of OPAL_DATATYPE_LOOP should be ONE) */
239 /*
240  * NOTE: The order of initialization *MUST* match the order of the OPAL_DATATYPE_-numbers.
241  * Unfortunateley, I don't get the preprocessor to replace
242  *     OPAL_DATATYPE_INIT_BTYPES_ARRAY_ ## OPAL_DATATYPE ## NAME
243  * into
244  *     OPAL_DATATYPE_INIT_BTYPES_ARRAY_[0-21], then order and naming would _not_ matter....
245  */
246 
247 #define OPAL_DATATYPE_INIT_PTYPES_ARRAY_UNAVAILABLE NULL
248 #define OPAL_DATATYPE_INIT_PTYPES_ARRAY(NAME) (size_t[OPAL_DATATYPE_MAX_PREDEFINED]){ [OPAL_DATATYPE_ ## NAME] = 1, [OPAL_DATATYPE_MAX_PREDEFINED-1] = 0 }
249 
250 #define OPAL_DATATYPE_INIT_NAME(NAME) "OPAL_" #NAME
251 
252 /*
253  * Macro to initialize the main description for basic types, setting the pointer
254  * into the array opal_datatype_predefined_type_desc, which is initialized at
255  * runtime in opal_datatype_init(). Each basic type has two desc-elements....
256  */
257 #define OPAL_DATATYPE_INIT_DESC_PREDEFINED(NAME)                                     \
258     {                                                                                \
259         .length = 1, .used = 1,                                                      \
260         .desc = &(opal_datatype_predefined_elem_desc[2 * OPAL_DATATYPE_ ## NAME])    \
261     }
262 #define OPAL_DATATYPE_INIT_DESC_NULL  {.length = 0, .used = 0, .desc = NULL}
263 
264 #define OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( NAME, FLAGS )                   \
265     {                                                                                \
266         .super = OPAL_OBJ_STATIC_INIT(opal_datatype_t),                              \
267         .flags = OPAL_DATATYPE_FLAG_UNAVAILABLE | OPAL_DATATYPE_FLAG_PREDEFINED | (FLAGS), \
268         .id = OPAL_DATATYPE_ ## NAME,                                                \
269         .bdt_used = 0,                                                               \
270         .size = 0,                                                                   \
271         .true_lb = 0, .true_ub = 0, .lb = 0, .ub = 0,                                \
272         .align = 0,                                                                  \
273         .nbElems = 1,                                                                \
274         .name = OPAL_DATATYPE_INIT_NAME(NAME),                                       \
275         .desc = OPAL_DATATYPE_INIT_DESC_PREDEFINED(UNAVAILABLE),                     \
276         .opt_desc = OPAL_DATATYPE_INIT_DESC_PREDEFINED(UNAVAILABLE),                 \
277         .ptypes = OPAL_DATATYPE_INIT_PTYPES_ARRAY_UNAVAILABLE                        \
278     }
279 
280 #define OPAL_DATATYPE_INITIALIZER_UNAVAILABLE( FLAGS )                               \
281     OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( UNAVAILABLE, (FLAGS) )
282 
283 #define OPAL_DATATYPE_INITIALIZER_EMPTY( FLAGS )                        \
284     {                                                                   \
285         .super = OPAL_OBJ_STATIC_INIT(opal_datatype_t),                 \
286         .flags = OPAL_DATATYPE_FLAG_PREDEFINED | (FLAGS),               \
287         .id = 0,                                                        \
288         .bdt_used = 0,                                                  \
289         .size = 0,                                                      \
290         .true_lb = 0, .true_ub = 0, .lb = 0, .ub = 0,                   \
291         .align = 0,                                                     \
292         .nbElems = 1,                                                   \
293         .name = OPAL_DATATYPE_INIT_NAME(EMPTY),                         \
294         .desc = OPAL_DATATYPE_INIT_DESC_NULL,                           \
295         .opt_desc = OPAL_DATATYPE_INIT_DESC_NULL,                       \
296         .ptypes = OPAL_DATATYPE_INIT_PTYPES_ARRAY_UNAVAILABLE           \
297     }
298 
299 #define OPAL_DATATYPE_INIT_BASIC_TYPE( TYPE, NAME, FLAGS )              \
300     {                                                                   \
301         .super = OPAL_OBJ_STATIC_INIT(opal_datatype_t),                 \
302         .flags = OPAL_DATATYPE_FLAG_PREDEFINED | (FLAGS),               \
303         .id = TYPE,                                                     \
304         .bdt_used = (((uint32_t)1)<<(TYPE)),                            \
305         .size = 0,                                                      \
306         .true_lb = 0, .true_ub = 0, .lb = 0, .ub = 0,                   \
307         .align = 0,                                                     \
308         .nbElems = 1,                                                   \
309         .name = OPAL_DATATYPE_INIT_NAME(NAME),                          \
310         .desc = OPAL_DATATYPE_INIT_DESC_NULL,                           \
311         .opt_desc = OPAL_DATATYPE_INIT_DESC_NULL,                       \
312         .ptypes = OPAL_DATATYPE_INIT_PTYPES_ARRAY_UNAVAILABLE           \
313     }
314 
315 #define OPAL_DATATYPE_INIT_BASIC_DATATYPE( TYPE, ALIGN, NAME, FLAGS )                \
316     {                                                                                \
317         .super = OPAL_OBJ_STATIC_INIT(opal_datatype_t),                              \
318         .flags = OPAL_DATATYPE_FLAG_BASIC | (FLAGS),                                 \
319         .id = OPAL_DATATYPE_ ## NAME,                                                \
320         .bdt_used = (((uint32_t)1)<<(OPAL_DATATYPE_ ## NAME)),                       \
321         .size = sizeof(TYPE),                                                        \
322         .true_lb = 0, .true_ub = sizeof(TYPE), .lb = 0, .ub = sizeof(TYPE),          \
323         .align = (ALIGN),                                                            \
324         .nbElems = 1,                                                                \
325         .name = OPAL_DATATYPE_INIT_NAME(NAME),                                       \
326         .desc = OPAL_DATATYPE_INIT_DESC_PREDEFINED(NAME),                            \
327         .opt_desc = OPAL_DATATYPE_INIT_DESC_PREDEFINED(NAME),                        \
328         .ptypes = OPAL_DATATYPE_INIT_PTYPES_ARRAY_UNAVAILABLE                        \
329     }
330 
331 #define OPAL_DATATYPE_INITIALIZER_LOOP(FLAGS)       OPAL_DATATYPE_INIT_BASIC_TYPE( OPAL_DATATYPE_LOOP, LOOP_S, FLAGS )
332 #define OPAL_DATATYPE_INITIALIZER_END_LOOP(FLAGS)   OPAL_DATATYPE_INIT_BASIC_TYPE( OPAL_DATATYPE_END_LOOP, LOOP_E, FLAGS )
333 #define OPAL_DATATYPE_INITIALIZER_LB(FLAGS)         OPAL_DATATYPE_INIT_BASIC_TYPE( OPAL_DATATYPE_LB, LB, FLAGS )
334 #define OPAL_DATATYPE_INITIALIZER_UB(FLAGS)         OPAL_DATATYPE_INIT_BASIC_TYPE( OPAL_DATATYPE_UB, UB, FLAGS )
335 #define OPAL_DATATYPE_INITIALIZER_INT1(FLAGS)       OPAL_DATATYPE_INIT_BASIC_DATATYPE( int8_t, OPAL_ALIGNMENT_INT8, INT1, FLAGS )
336 #define OPAL_DATATYPE_INITIALIZER_INT2(FLAGS)       OPAL_DATATYPE_INIT_BASIC_DATATYPE( int16_t, OPAL_ALIGNMENT_INT16, INT2, FLAGS )
337 #define OPAL_DATATYPE_INITIALIZER_INT4(FLAGS)       OPAL_DATATYPE_INIT_BASIC_DATATYPE( int32_t, OPAL_ALIGNMENT_INT32, INT4, FLAGS )
338 #define OPAL_DATATYPE_INITIALIZER_INT8(FLAGS)       OPAL_DATATYPE_INIT_BASIC_DATATYPE( int64_t, OPAL_ALIGNMENT_INT64, INT8, FLAGS )
339 #ifdef HAVE_INT128_T
340 #define OPAL_DATATYPE_INITIALIZER_INT16(FLAGS)      OPAL_DATATYPE_INIT_BASIC_DATATYPE( int128_t, OPAL_ALIGNMENT_INT128, INT16, FLAGS )
341 #else
342 #define OPAL_DATATYPE_INITIALIZER_INT16(FLAGS)      OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( INT16, FLAGS )
343 #endif
344 #define OPAL_DATATYPE_INITIALIZER_UINT1(FLAGS)      OPAL_DATATYPE_INIT_BASIC_DATATYPE( uint8_t, OPAL_ALIGNMENT_INT8, UINT1, FLAGS )
345 #define OPAL_DATATYPE_INITIALIZER_UINT2(FLAGS)      OPAL_DATATYPE_INIT_BASIC_DATATYPE( uint16_t, OPAL_ALIGNMENT_INT16, UINT2, FLAGS )
346 #define OPAL_DATATYPE_INITIALIZER_UINT4(FLAGS)      OPAL_DATATYPE_INIT_BASIC_DATATYPE( uint32_t, OPAL_ALIGNMENT_INT32, UINT4, FLAGS )
347 #define OPAL_DATATYPE_INITIALIZER_UINT8(FLAGS)      OPAL_DATATYPE_INIT_BASIC_DATATYPE( uint64_t, OPAL_ALIGNMENT_INT64, UINT8, FLAGS )
348 #ifdef HAVE_UINT128_T
349 #define OPAL_DATATYPE_INITIALIZER_UINT16(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( uint128_t, OPAL_ALIGNMENT_INT128, UINT16, FLAGS )
350 #else
351 #define OPAL_DATATYPE_INITIALIZER_UINT16(FLAGS)     OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( INT16, FLAGS )
352 #endif
353 
354 #if SIZEOF_FLOAT == 2
355 #define OPAL_DATATYPE_INITIALIZER_FLOAT2(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( float, OPAL_ALIGNMENT_FLOAT, FLOAT2, FLAGS )
356 #elif SIZEOF_DOUBLE == 2
357 #define OPAL_DATATYPE_INITIALIZER_FLOAT2(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( double, OPAL_ALIGNMENT_DOUBLE, FLOAT2, FLAGS )
358 #elif HAVE_LONG_DOUBLE && SIZEOF_LONG_DOUBLE == 2
359 #define OPAL_DATATYPE_INITIALIZER_FLOAT2(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( long double, OPAL_ALIGNMENT_LONG_DOUBLE, FLOAT2, FLAGS )
360 #else
361 #define OPAL_DATATYPE_INITIALIZER_FLOAT2(FLAGS)     OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( FLOAT2, FLAGS )
362 #endif
363 
364 #if SIZEOF_FLOAT == 4
365 #define OPAL_DATATYPE_INITIALIZER_FLOAT4(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( float, OPAL_ALIGNMENT_FLOAT, FLOAT4, FLAGS )
366 #elif SIZEOF_DOUBLE == 4
367 #define OPAL_DATATYPE_INITIALIZER_FLOAT4(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( double, OPAL_ALIGNMENT_DOUBLE, FLOAT4, FLAGS )
368 #elif HAVE_LONG_DOUBLE && SIZEOF_LONG_DOUBLE == 4
369 #define OPAL_DATATYPE_INITIALIZER_FLOAT4(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( long double, OPAL_ALIGNMENT_LONG_DOUBLE, FLOAT4, FLAGS )
370 #else
371 #define OPAL_DATATYPE_INITIALIZER_FLOAT4(FLAGS)     OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( FLOAT4, FLAGS )
372 #endif
373 
374 #if SIZEOF_FLOAT == 8
375 #define OPAL_DATATYPE_INITIALIZER_FLOAT8(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( float, OPAL_ALIGNMENT_FLOAT, FLOAT8, FLAGS )
376 #elif SIZEOF_DOUBLE == 8
377 #define OPAL_DATATYPE_INITIALIZER_FLOAT8(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( double, OPAL_ALIGNMENT_DOUBLE, FLOAT8, FLAGS )
378 #elif HAVE_LONG_DOUBLE && SIZEOF_LONG_DOUBLE == 8
379 #define OPAL_DATATYPE_INITIALIZER_FLOAT8(FLAGS)     OPAL_DATATYPE_INIT_BASIC_DATATYPE( long double, OPAL_ALIGNMENT_LONG_DOUBLE, FLOAT8, FLAGS )
380 #else
381 #define OPAL_DATATYPE_INITIALIZER_FLOAT8(FLAGS)     OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( FLOAT8, FLAGS )
382 #endif
383 
384 #if SIZEOF_FLOAT == 12
385 #define OPAL_DATATYPE_INITIALIZER_FLOAT12(FLAGS)    OPAL_DATATYPE_INIT_BASIC_DATATYPE( float, OPAL_ALIGNMENT_FLOAT, FLOAT12, FLAGS )
386 #elif SIZEOF_DOUBLE == 12
387 #define OPAL_DATATYPE_INITIALIZER_FLOAT12(FLAGS)    OPAL_DATATYPE_INIT_BASIC_DATATYPE( double, OPAL_ALIGNMENT_DOUBLE, FLOAT12, FLAGS )
388 #elif HAVE_LONG_DOUBLE && SIZEOF_LONG_DOUBLE == 12
389 #define OPAL_DATATYPE_INITIALIZER_FLOAT12(FLAGS)    OPAL_DATATYPE_INIT_BASIC_DATATYPE( long double, OPAL_ALIGNMENT_LONG_DOUBLE, FLOAT12, FLAGS )
390 #else
391 #define OPAL_DATATYPE_INITIALIZER_FLOAT12(FLAGS)    OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( FLOAT12, FLAGS )
392 #endif
393 
394 #if SIZEOF_FLOAT == 16
395 #define OPAL_DATATYPE_INITIALIZER_FLOAT16(FLAGS)    OPAL_DATATYPE_INIT_BASIC_DATATYPE( float, OPAL_ALIGNMENT_FLOAT, FLOAT16, FLAGS )
396 #elif SIZEOF_DOUBLE == 16
397 #define OPAL_DATATYPE_INITIALIZER_FLOAT16(FLAGS)    OPAL_DATATYPE_INIT_BASIC_DATATYPE( double, OPAL_ALIGNMENT_DOUBLE, FLOAT16, FLAGS )
398 #elif HAVE_LONG_DOUBLE && SIZEOF_LONG_DOUBLE == 16
399 #define OPAL_DATATYPE_INITIALIZER_FLOAT16(FLAGS)    OPAL_DATATYPE_INIT_BASIC_DATATYPE( long double, OPAL_ALIGNMENT_LONG_DOUBLE, FLOAT16, FLAGS )
400 #else
401 #define OPAL_DATATYPE_INITIALIZER_FLOAT16(FLAGS)    OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( FLOAT16, FLAGS )
402 #endif
403 
404 #if HAVE_FLOAT__COMPLEX
405 #define OPAL_DATATYPE_INITIALIZER_FLOAT_COMPLEX(FLAGS) OPAL_DATATYPE_INIT_BASIC_DATATYPE( float _Complex, OPAL_ALIGNMENT_FLOAT_COMPLEX, FLOAT_COMPLEX, FLAGS )
406 #else
407 #define OPAL_DATATYPE_INITIALIZER_FLOAT_COMPLEX(FLAGS) OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( FLOAT_COMPLEX, FLAGS)
408 #endif
409 
410 #if HAVE_DOUBLE__COMPLEX
411 #define OPAL_DATATYPE_INITIALIZER_DOUBLE_COMPLEX(FLAGS) OPAL_DATATYPE_INIT_BASIC_DATATYPE( double _Complex, OPAL_ALIGNMENT_DOUBLE_COMPLEX, DOUBLE_COMPLEX, FLAGS )
412 #else
413 #define OPAL_DATATYPE_INITIALIZER_DOUBLE_COMPLEX(FLAGS) OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( DOUBLE_COMPLEX, FLAGS)
414 #endif
415 
416 #if HAVE_LONG_DOUBLE__COMPLEX
417 #define OPAL_DATATYPE_INITIALIZER_LONG_DOUBLE_COMPLEX(FLAGS) OPAL_DATATYPE_INIT_BASIC_DATATYPE( long double _Complex, OPAL_ALIGNMENT_LONG_DOUBLE_COMPLEX, LONG_DOUBLE_COMPLEX, FLAGS )
418 #else
419 #define OPAL_DATATYPE_INITIALIZER_LONG_DOUBLE_COMPLEX(FLAGS) OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( LONG_DOUBLE_COMPLEX, FLAGS)
420 #endif
421 
422 #define OPAL_DATATYPE_INITIALIZER_BOOL(FLAGS)       OPAL_DATATYPE_INIT_BASIC_DATATYPE( _Bool, OPAL_ALIGNMENT_BOOL, BOOL, FLAGS )
423 
424 #if OPAL_ALIGNMENT_WCHAR != 0
425 #define OPAL_DATATYPE_INITIALIZER_WCHAR(FLAGS)      OPAL_DATATYPE_INIT_BASIC_DATATYPE( wchar_t, OPAL_ALIGNMENT_WCHAR, WCHAR, FLAGS )
426 #else
427 #define OPAL_DATATYPE_INITIALIZER_WCHAR(FLAGS)      OPAL_DATATYPE_INITIALIZER_UNAVAILABLE_NAMED( WCHAR, FLAGS )
428 #endif
429 
430 #define BASIC_DDT_FROM_ELEM( ELEM ) (opal_datatype_basicDatatypes[(ELEM).elem.common.type])
431 
432 #define SAVE_STACK( PSTACK, INDEX, TYPE, COUNT, DISP) \
433 do { \
434    (PSTACK)->index    = (INDEX); \
435    (PSTACK)->type     = (TYPE); \
436    (PSTACK)->count    = (COUNT); \
437    (PSTACK)->disp     = (DISP); \
438 } while(0)
439 
440 #define PUSH_STACK( PSTACK, STACK_POS, INDEX, TYPE, COUNT, DISP) \
441 do { \
442    dt_stack_t* pTempStack = (PSTACK) + 1; \
443    SAVE_STACK( pTempStack, (INDEX), (TYPE), (COUNT), (DISP) );  \
444    (STACK_POS)++; \
445    (PSTACK) = pTempStack; \
446 } while(0)
447 
448 #if OPAL_ENABLE_DEBUG
449 #define OPAL_DATATYPE_SAFEGUARD_POINTER( ACTPTR, LENGTH, INITPTR, PDATA, COUNT ) \
450     {                                                                   \
451         unsigned char *__lower_bound = (INITPTR), *__upper_bound;       \
452         assert( ((LENGTH) != 0) && ((COUNT) != 0) );                    \
453         __lower_bound += (PDATA)->true_lb;                              \
454         __upper_bound = (INITPTR) + (PDATA)->true_ub +                  \
455             ((PDATA)->ub - (PDATA)->lb) * ((COUNT) - 1);                \
456         if( ((ACTPTR) < __lower_bound) || ((ACTPTR) >= __upper_bound) ) { \
457             opal_datatype_safeguard_pointer_debug_breakpoint( (ACTPTR), (LENGTH), (INITPTR), (PDATA), (COUNT) ); \
458             opal_output( 0, "%s:%d\n\tPointer %p size %lu is outside [%p,%p] for\n\tbase ptr %p count %lu and data \n", \
459                          __FILE__, __LINE__, (void*)(ACTPTR), (unsigned long)(LENGTH), (void*)__lower_bound, (void*)__upper_bound, \
460                          (void*)(INITPTR), (unsigned long)(COUNT) );    \
461             opal_datatype_dump( (PDATA) );                              \
462         }                                                               \
463     }
464 
465 #else
466 #define OPAL_DATATYPE_SAFEGUARD_POINTER( ACTPTR, LENGTH, INITPTR, PDATA, COUNT )
467 #endif  /* OPAL_ENABLE_DEBUG */
468 
GET_FIRST_NON_LOOP(const union dt_elem_desc * _pElem)469 static inline int GET_FIRST_NON_LOOP( const union dt_elem_desc* _pElem )
470 {
471     int element_index = 0;
472 
473     /* We dont have to check for the end as we always put an END_LOOP
474      * at the end of all datatype descriptions.
475      */
476     while( _pElem->elem.common.type == OPAL_DATATYPE_LOOP ) {
477         ++_pElem; element_index++;
478     }
479     return element_index;
480 }
481 
482 #define UPDATE_INTERNAL_COUNTERS( DESCRIPTION, POSITION, ELEMENT, COUNTER ) \
483     do {                                                                \
484         (ELEMENT) = &((DESCRIPTION)[(POSITION)]);                       \
485         if( OPAL_DATATYPE_LOOP == (ELEMENT)->elem.common.type )         \
486             (COUNTER) = (ELEMENT)->loop.loops;                          \
487         else                                                            \
488             (COUNTER) = (ELEMENT)->elem.count;                          \
489     } while (0)
490 
491 OPAL_DECLSPEC int opal_datatype_contain_basic_datatypes( const struct opal_datatype_t* pData, char* ptr, size_t length );
492 OPAL_DECLSPEC int opal_datatype_dump_data_flags( unsigned short usflags, char* ptr, size_t length );
493 OPAL_DECLSPEC int opal_datatype_dump_data_desc( union dt_elem_desc* pDesc, int nbElems, char* ptr, size_t length );
494 
495 #if OPAL_ENABLE_DEBUG
496 extern bool opal_position_debug;
497 extern bool opal_copy_debug;
498 #endif  /* OPAL_ENABLE_DEBUG */
499 
500 END_C_DECLS
501 #endif  /* OPAL_DATATYPE_INTERNAL_H_HAS_BEEN_INCLUDED */
502