1 /*
2 * Copyright (C) by Argonne National Laboratory
3 * See COPYRIGHT in top-level directory
4 */
5
6 #include "mpiimpl.h"
7 #include <stdlib.h>
8 #include <limits.h>
9 #include "datatype.h"
10
11 /* MPI datatype debugging helper routines.
12 *
13 * The one you want to call is:
14 * MPIR_Datatype_debug(MPI_Datatype type, int array_ct)
15 *
16 * The "array_ct" value tells the call how many array values to print
17 * for struct, indexed, and blockindexed types.
18 *
19 */
20
21 static void contents_printf(MPI_Datatype type, int depth, int acount);
22 static char *depth_spacing(int depth) ATTRIBUTE((unused));
23
24 #define NR_TYPE_CUTOFF 6 /* Number of types to display before truncating
25 * output. 6 picked as arbitrary cutoff */
26
27 /* note: this isn't really "error handling" per se, but leave these comments
28 * because Bill uses them for coverage analysis.
29 */
30
31 /* --BEGIN ERROR HANDLING-- */
32
MPII_Datatype_printf(MPI_Datatype type,int depth,MPI_Aint displacement,int blocklength,int header)33 void MPII_Datatype_printf(MPI_Datatype type,
34 int depth, MPI_Aint displacement, int blocklength, int header)
35 {
36 #ifdef MPL_USE_DBG_LOGGING
37 char *string;
38 MPI_Aint size;
39 MPI_Aint extent, true_lb, true_ub, lb, ub;
40
41 if (HANDLE_IS_BUILTIN(type)) {
42 string = MPIR_Datatype_builtin_to_string(type);
43 MPIR_Assert(string != NULL);
44 } else {
45 MPIR_Datatype *type_ptr;
46
47 MPIR_Datatype_get_ptr(type, type_ptr);
48 MPIR_Assert(type_ptr != NULL);
49 string = MPIR_Datatype_combiner_to_string(type_ptr->contents->combiner);
50 MPIR_Assert(string != NULL);
51 }
52
53 MPIR_Datatype_get_size_macro(type, size);
54 MPIR_Type_get_true_extent_impl(type, &true_lb, &extent);
55 true_ub = extent + true_lb;
56 MPIR_Type_get_extent_impl(type, &lb, &extent);
57 ub = extent + lb;
58
59 if (header == 1) {
60 /* 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 */
61 MPL_DBG_OUT(MPIR_DBG_DATATYPE,
62 "------------------------------------------------------------------------------------------------------------------------------------------\n");
63 MPL_DBG_OUT(MPIR_DBG_DATATYPE,
64 "depth type size extent true_lb true_ub lb ub disp blklen\n");
65 MPL_DBG_OUT(MPIR_DBG_DATATYPE,
66 "------------------------------------------------------------------------------------------------------------------------------------------\n");
67 }
68 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE,
69 (MPL_DBG_FDEST,
70 "%5d %21s %11d " MPI_AINT_FMT_DEC_SPEC " " MPI_AINT_FMT_DEC_SPEC " "
71 MPI_AINT_FMT_DEC_SPEC " " MPI_AINT_FMT_DEC_SPEC " " MPI_AINT_FMT_DEC_SPEC " "
72 MPI_AINT_FMT_DEC_SPEC " %11d", depth, string, (int) size, (MPI_Aint) extent,
73 (MPI_Aint) true_lb, (MPI_Aint) true_ub, (MPI_Aint) lb,
74 (MPI_Aint) ub, (MPI_Aint) displacement, (int) blocklength));
75 #endif
76 return;
77 }
78
79 /* --END ERROR HANDLING-- */
80
81 /* longest string is 21 characters */
MPIR_Datatype_builtin_to_string(MPI_Datatype type)82 char *MPIR_Datatype_builtin_to_string(MPI_Datatype type)
83 {
84 static char t_char[] = "MPI_CHAR";
85 static char t_uchar[] = "MPI_UNSIGNED_CHAR";
86 static char t_byte[] = "MPI_BYTE";
87 static char t_wchar_t[] = "MPI_WCHAR";
88 static char t_short[] = "MPI_SHORT";
89 static char t_ushort[] = "MPI_UNSIGNED_SHORT";
90 static char t_int[] = "MPI_INT";
91 static char t_uint[] = "MPI_UNSIGNED";
92 static char t_long[] = "MPI_LONG";
93 static char t_ulong[] = "MPI_UNSIGNED_LONG";
94 static char t_float[] = "MPI_FLOAT";
95 static char t_double[] = "MPI_DOUBLE";
96 static char t_longdouble[] = "MPI_LONG_DOUBLE";
97 static char t_longlongint[] = "MPI_LONG_LONG_INT";
98 static char t_longlong[] = "MPI_LONG_LONG";
99 static char t_ulonglong[] = "MPI_UNSIGNED_LONG_LONG";
100 static char t_schar[] = "MPI_SIGNED_CHAR";
101
102 static char t_packed[] = "MPI_PACKED";
103 static char t_lb[] = "MPI_LB";
104 static char t_ub[] = "MPI_UB";
105
106 static char t_floatint[] = "MPI_FLOAT_INT";
107 static char t_doubleint[] = "MPI_DOUBLE_INT";
108 static char t_longint[] = "MPI_LONG_INT";
109 static char t_shortint[] = "MPI_SHORT_INT";
110 static char t_2int[] = "MPI_2INT";
111 static char t_longdoubleint[] = "MPI_LONG_DOUBLE_INT";
112
113 static char t_complex[] = "MPI_COMPLEX";
114 static char t_doublecomplex[] = "MPI_DOUBLE_COMPLEX";
115 static char t_logical[] = "MPI_LOGICAL";
116 static char t_real[] = "MPI_REAL";
117 static char t_doubleprecision[] = "MPI_DOUBLE_PRECISION";
118 static char t_integer[] = "MPI_INTEGER";
119 static char t_2integer[] = "MPI_2INTEGER";
120 static char t_2real[] = "MPI_2REAL";
121 static char t_2doubleprecision[] = "MPI_2DOUBLE_PRECISION";
122 static char t_character[] = "MPI_CHARACTER";
123
124 if (type == MPI_CHAR)
125 return t_char;
126 if (type == MPI_UNSIGNED_CHAR)
127 return t_uchar;
128 if (type == MPI_SIGNED_CHAR)
129 return t_schar;
130 if (type == MPI_BYTE)
131 return t_byte;
132 if (type == MPI_WCHAR)
133 return t_wchar_t;
134 if (type == MPI_SHORT)
135 return t_short;
136 if (type == MPI_UNSIGNED_SHORT)
137 return t_ushort;
138 if (type == MPI_INT)
139 return t_int;
140 if (type == MPI_UNSIGNED)
141 return t_uint;
142 if (type == MPI_LONG)
143 return t_long;
144 if (type == MPI_UNSIGNED_LONG)
145 return t_ulong;
146 if (type == MPI_FLOAT)
147 return t_float;
148 if (type == MPI_DOUBLE)
149 return t_double;
150 if (type == MPI_LONG_DOUBLE)
151 return t_longdouble;
152 if (type == MPI_LONG_LONG_INT)
153 return t_longlongint;
154 if (type == MPI_LONG_LONG)
155 return t_longlong;
156 if (type == MPI_UNSIGNED_LONG_LONG)
157 return t_ulonglong;
158
159 if (type == MPI_PACKED)
160 return t_packed;
161 if (type == MPI_LB)
162 return t_lb;
163 if (type == MPI_UB)
164 return t_ub;
165
166 if (type == MPI_FLOAT_INT)
167 return t_floatint;
168 if (type == MPI_DOUBLE_INT)
169 return t_doubleint;
170 if (type == MPI_LONG_INT)
171 return t_longint;
172 if (type == MPI_SHORT_INT)
173 return t_shortint;
174 if (type == MPI_2INT)
175 return t_2int;
176 if (type == MPI_LONG_DOUBLE_INT)
177 return t_longdoubleint;
178
179 if (type == MPI_COMPLEX)
180 return t_complex;
181 if (type == MPI_DOUBLE_COMPLEX)
182 return t_doublecomplex;
183 if (type == MPI_LOGICAL)
184 return t_logical;
185 if (type == MPI_REAL)
186 return t_real;
187 if (type == MPI_DOUBLE_PRECISION)
188 return t_doubleprecision;
189 if (type == MPI_INTEGER)
190 return t_integer;
191 if (type == MPI_2INTEGER)
192 return t_2integer;
193 if (type == MPI_2REAL)
194 return t_2real;
195 if (type == MPI_2DOUBLE_PRECISION)
196 return t_2doubleprecision;
197 if (type == MPI_CHARACTER)
198 return t_character;
199
200 return NULL;
201 }
202
203 /* MPIR_Datatype_combiner_to_string(combiner)
204 *
205 * Converts a numeric combiner into a pointer to a string used for printing.
206 *
207 * longest string is 16 characters.
208 */
MPIR_Datatype_combiner_to_string(int combiner)209 char *MPIR_Datatype_combiner_to_string(int combiner)
210 {
211 static char c_named[] = "named";
212 static char c_contig[] = "contig";
213 static char c_vector[] = "vector";
214 static char c_hvector[] = "hvector";
215 static char c_indexed[] = "indexed";
216 static char c_hindexed[] = "hindexed";
217 static char c_struct[] = "struct";
218 static char c_dup[] = "dup";
219 static char c_hvector_integer[] = "hvector_integer";
220 static char c_hindexed_integer[] = "hindexed_integer";
221 static char c_indexed_block[] = "indexed_block";
222 static char c_hindexed_block[] = "hindexed_block";
223 static char c_struct_integer[] = "struct_integer";
224 static char c_subarray[] = "subarray";
225 static char c_darray[] = "darray";
226 static char c_f90_real[] = "f90_real";
227 static char c_f90_complex[] = "f90_complex";
228 static char c_f90_integer[] = "f90_integer";
229 static char c_resized[] = "resized";
230
231 if (combiner == MPI_COMBINER_NAMED)
232 return c_named;
233 if (combiner == MPI_COMBINER_CONTIGUOUS)
234 return c_contig;
235 if (combiner == MPI_COMBINER_VECTOR)
236 return c_vector;
237 if (combiner == MPI_COMBINER_HVECTOR)
238 return c_hvector;
239 if (combiner == MPI_COMBINER_INDEXED)
240 return c_indexed;
241 if (combiner == MPI_COMBINER_HINDEXED)
242 return c_hindexed;
243 if (combiner == MPI_COMBINER_STRUCT)
244 return c_struct;
245 if (combiner == MPI_COMBINER_DUP)
246 return c_dup;
247 if (combiner == MPI_COMBINER_HVECTOR_INTEGER)
248 return c_hvector_integer;
249 if (combiner == MPI_COMBINER_HINDEXED_INTEGER)
250 return c_hindexed_integer;
251 if (combiner == MPI_COMBINER_INDEXED_BLOCK)
252 return c_indexed_block;
253 if (combiner == MPI_COMBINER_HINDEXED_BLOCK)
254 return c_hindexed_block;
255 if (combiner == MPI_COMBINER_STRUCT_INTEGER)
256 return c_struct_integer;
257 if (combiner == MPI_COMBINER_SUBARRAY)
258 return c_subarray;
259 if (combiner == MPI_COMBINER_DARRAY)
260 return c_darray;
261 if (combiner == MPI_COMBINER_F90_REAL)
262 return c_f90_real;
263 if (combiner == MPI_COMBINER_F90_COMPLEX)
264 return c_f90_complex;
265 if (combiner == MPI_COMBINER_F90_INTEGER)
266 return c_f90_integer;
267 if (combiner == MPI_COMBINER_RESIZED)
268 return c_resized;
269
270 return NULL;
271 }
272
273 /* --BEGIN DEBUG-- */
274 /*
275 * You must configure MPICH2 with the logging option enabled (--enable-g=log)
276 * for these routines to print - in which case, they use the same options
277 * as the logging code, including print to file and control by class (DATATYPE)
278 */
MPIR_Datatype_debug(MPI_Datatype type,int array_ct)279 void MPIR_Datatype_debug(MPI_Datatype type, int array_ct)
280 {
281 #if (defined HAVE_ERROR_CHECKING) || (defined MPL_USE_DBG_LOGGING)
282 const char *string;
283 #endif
284 MPIR_Datatype *dtp ATTRIBUTE((unused));
285
286 /* can get a NULL type a number of different ways, including not having
287 * fortran support included.
288 */
289 if (type == MPI_DATATYPE_NULL) {
290 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE,
291 (MPL_DBG_FDEST, "# MPIU_Datatype_debug: MPI_Datatype = MPI_DATATYPE_NULL"));
292 return;
293 }
294 #if (defined HAVE_ERROR_CHECKING) || (defined MPL_USE_DBG_LOGGING)
295 if (HANDLE_IS_BUILTIN(type)) {
296 string = MPIR_Datatype_builtin_to_string(type);
297 MPIR_Assert(string != NULL);
298 } else {
299 string = "derived";
300 }
301 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST,
302 "# MPIU_Datatype_debug: MPI_Datatype = 0x%0x (%s)", type,
303 string));
304 #endif
305
306 if (HANDLE_IS_BUILTIN(type))
307 return;
308
309 MPIR_Datatype_get_ptr(type, dtp);
310 MPIR_Assert(dtp != NULL);
311
312 #if (defined HAVE_ERROR_CHECKING) || (defined MPL_USE_DBG_LOGGING)
313 string = MPIR_Datatype_builtin_to_string(dtp->basic_type);
314 MPIR_Assert(string != NULL);
315
316 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST,
317 "# Size = " MPI_AINT_FMT_DEC_SPEC ", Extent = "
318 MPI_AINT_FMT_DEC_SPEC ", LB = " MPI_AINT_FMT_DEC_SPEC
319 ", UB = " MPI_AINT_FMT_DEC_SPEC ", Extent = "
320 MPI_AINT_FMT_DEC_SPEC ", Element Size = "
321 MPI_AINT_FMT_DEC_SPEC " (%s), %s", (MPI_Aint) dtp->size,
322 (MPI_Aint) dtp->extent, (MPI_Aint) dtp->lb,
323 (MPI_Aint) dtp->ub, (MPI_Aint) dtp->extent,
324 (MPI_Aint) dtp->builtin_element_size,
325 dtp->builtin_element_size ==
326 -1 ? "multiple types" :
327 string,
328 dtp->is_contig ? "is N contig" : "is not N contig"));
329 #endif
330
331 MPL_DBG_OUT(MPIR_DBG_DATATYPE, "# Contents:");
332 contents_printf(type, 0, array_ct);
333
334 MPL_DBG_OUT(MPIR_DBG_DATATYPE, "# Typerep:");
335 MPIR_Typerep_debug(type);
336 }
337
depth_spacing(int depth)338 static char *depth_spacing(int depth)
339 {
340 static char d0[] = "";
341 static char d1[] = " ";
342 static char d2[] = " ";
343 static char d3[] = " ";
344 static char d4[] = " ";
345 static char d5[] = " ";
346
347 switch (depth) {
348 case 0:
349 return d0;
350 case 1:
351 return d1;
352 case 2:
353 return d2;
354 case 3:
355 return d3;
356 case 4:
357 return d4;
358 default:
359 return d5;
360 }
361 }
362
363 #define MPII_DATATYPE_FREE_AND_RETURN { \
364 if (cp->nr_ints > 0) MPL_free(ints); \
365 if (cp->nr_aints > 0) MPL_free(aints); \
366 if (cp->nr_types > 0) MPL_free(types); \
367 return; }
368
contents_printf(MPI_Datatype type,int depth,int acount)369 static void contents_printf(MPI_Datatype type, int depth, int acount)
370 {
371 int i;
372 MPIR_Datatype *dtp;
373 MPIR_Datatype_contents *cp;
374
375 MPI_Aint *aints = NULL;
376 MPI_Datatype *types = NULL;
377 int *ints = NULL;
378
379 #if (defined HAVE_ERROR_CHECKING) || (defined MPL_USE_DBG_LOGGING)
380 if (HANDLE_IS_BUILTIN(type)) {
381 const char *string = MPIR_Datatype_builtin_to_string(type);
382 MPIR_Assert(string != NULL);
383 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# %stype: %s\n",
384 depth_spacing(depth), string));
385 return;
386 }
387 #endif
388
389 MPIR_Datatype_get_ptr(type, dtp);
390 cp = dtp->contents;
391
392 if (cp == NULL) {
393 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# <NULL>\n"));
394 return;
395 }
396
397 if (cp->nr_ints > 0) {
398 ints = (int *) MPL_malloc(cp->nr_ints * sizeof(int), MPL_MEM_DATATYPE);
399 MPIR_Assert(ints != NULL);
400 MPII_Datatype_get_contents_ints(cp, ints);
401 }
402
403 if (cp->nr_aints > 0) {
404 aints = (MPI_Aint *) MPL_malloc(cp->nr_aints * sizeof(MPI_Aint), MPL_MEM_DATATYPE);
405 MPIR_Assert(aints != NULL);
406 MPII_Datatype_get_contents_aints(cp, aints);
407 }
408
409 if (cp->nr_types > 0) {
410 types = (MPI_Datatype *) MPL_malloc(cp->nr_types * sizeof(MPI_Datatype), MPL_MEM_DATATYPE);
411 MPIR_Assert(types != NULL);
412 MPII_Datatype_get_contents_types(cp, types);
413 }
414 #if (defined HAVE_ERROR_CHECKING) || (defined MPL_USE_DBG_LOGGING)
415 {
416 const char *string = MPIR_Datatype_combiner_to_string(cp->combiner);
417 MPIR_Assert(string != NULL);
418 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# %scombiner: %s",
419 depth_spacing(depth), string));
420 }
421 #endif
422
423 switch (cp->combiner) {
424 case MPI_COMBINER_NAMED:
425 case MPI_COMBINER_DUP:
426 MPII_DATATYPE_FREE_AND_RETURN;
427 /* not done */
428 MPII_DATATYPE_FREE_AND_RETURN;
429 case MPI_COMBINER_CONTIGUOUS:
430 MPIR_Assert((ints != NULL) && (types != NULL));
431 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# %scontig ct = %d\n",
432 depth_spacing(depth), *ints));
433 contents_printf(*types, depth + 1, acount);
434 MPII_DATATYPE_FREE_AND_RETURN;
435 case MPI_COMBINER_VECTOR:
436 MPIR_Assert((ints != NULL) && (types != NULL));
437 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST,
438 "# %svector ct = %d, blk = %d, str = %d\n",
439 depth_spacing(depth), ints[0], ints[1], ints[2]));
440 contents_printf(*types, depth + 1, acount);
441 MPII_DATATYPE_FREE_AND_RETURN;
442 case MPI_COMBINER_HVECTOR:
443 MPIR_Assert((ints != NULL) && (aints != NULL) && (types != NULL));
444 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST,
445 "# %shvector ct = %d, blk = %d, str = "
446 MPI_AINT_FMT_DEC_SPEC "\n",
447 depth_spacing(depth), ints[0],
448 ints[1], (MPI_Aint) aints[0]));
449 contents_printf(*types, depth + 1, acount);
450 MPII_DATATYPE_FREE_AND_RETURN;
451 case MPI_COMBINER_INDEXED:
452 MPIR_Assert((ints != NULL) && (types != NULL));
453 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# %sindexed ct = %d:",
454 depth_spacing(depth), ints[0]));
455 for (i = 0; i < acount && i < ints[0]; i++) {
456 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST,
457 "# %s indexed [%d]: blk = %d, disp = %d\n",
458 depth_spacing(depth),
459 i,
460 ints[i + 1], ints[i + (cp->nr_ints / 2) + 1]));
461 contents_printf(*types, depth + 1, acount);
462 }
463 MPII_DATATYPE_FREE_AND_RETURN;
464 case MPI_COMBINER_HINDEXED:
465 MPIR_Assert((ints != NULL) && (aints != NULL) && (types != NULL));
466 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# %shindexed ct = %d:",
467 depth_spacing(depth), ints[0]));
468 for (i = 0; i < acount && i < ints[0]; i++) {
469 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST,
470 "# %s hindexed [%d]: blk = %d, disp = "
471 MPI_AINT_FMT_DEC_SPEC "\n",
472 depth_spacing(depth), i,
473 (int) ints[i + 1], (MPI_Aint) aints[i]));
474 contents_printf(*types, depth + 1, acount);
475 }
476 MPII_DATATYPE_FREE_AND_RETURN;
477 case MPI_COMBINER_STRUCT:
478 MPIR_Assert((ints != NULL) && (aints != NULL) && (types != NULL));
479 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# %sstruct ct = %d:",
480 depth_spacing(depth), (int) ints[0]));
481 for (i = 0; i < acount && i < ints[0]; i++) {
482 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST,
483 "# %s struct[%d]: blk = %d, disp = "
484 MPI_AINT_FMT_DEC_SPEC "\n",
485 depth_spacing(depth), i,
486 (int) ints[i + 1], (MPI_Aint) aints[i]));
487 contents_printf(types[i], depth + 1, acount);
488 }
489 MPII_DATATYPE_FREE_AND_RETURN;
490 case MPI_COMBINER_SUBARRAY:
491 MPIR_Assert((ints != NULL) && (types != NULL));
492 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# %ssubarray ct = %d:",
493 depth_spacing(depth), (int) ints[0]));
494 for (i = 0; i < acount && i < ints[0]; i++) {
495 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST,
496 "# %s sizes[%d] = %d subsizes[%d] = %d starts[%d] = %d\n",
497 depth_spacing(depth),
498 i, (int) ints[i + 1],
499 i, (int) ints[i + ints[0] + 1],
500 i, (int) ints[2 * ints[0] + 1]));
501 }
502 contents_printf(*types, depth + 1, acount);
503 MPII_DATATYPE_FREE_AND_RETURN;
504
505 case MPI_COMBINER_RESIZED:
506 MPIR_Assert((aints != NULL) && (types != NULL));
507 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE,
508 (MPL_DBG_FDEST,
509 "# %sresized lb = " MPI_AINT_FMT_DEC_SPEC " extent = "
510 MPI_AINT_FMT_DEC_SPEC "\n", depth_spacing(depth), aints[0], aints[1]));
511 contents_printf(*types, depth + 1, acount);
512 MPII_DATATYPE_FREE_AND_RETURN;
513 default:
514 MPL_DBG_OUT_FMT(MPIR_DBG_DATATYPE, (MPL_DBG_FDEST, "# %sunhandled combiner",
515 depth_spacing(depth)));
516 MPII_DATATYPE_FREE_AND_RETURN;
517 }
518 }
519
520 /* --END DEBUG-- */
521