1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*-------------------------------------------------------------------------
15 *
16 * Created: H5Tdbg.c
17 * Jul 19 2007
18 * Quincey Koziol <koziol@hdfgroup.org>
19 *
20 * Purpose: Dump debugging information about a datatype
21 *
22 *-------------------------------------------------------------------------
23 */
24
25 /****************/
26 /* Module Setup */
27 /****************/
28
29 #include "H5Tmodule.h" /* This source code file is part of the H5T module */
30
31
32 /***********/
33 /* Headers */
34 /***********/
35 #include "H5private.h" /* Generic Functions */
36 #include "H5Eprivate.h" /* Error handling */
37 #include "H5Tpkg.h" /* Datatypes */
38
39
40 /****************/
41 /* Local Macros */
42 /****************/
43
44
45 /******************/
46 /* Local Typedefs */
47 /******************/
48
49
50 /********************/
51 /* Package Typedefs */
52 /********************/
53
54
55 /********************/
56 /* Local Prototypes */
57 /********************/
58
59
60 /*********************/
61 /* Package Variables */
62 /*********************/
63
64
65 /*****************************/
66 /* Library Private Variables */
67 /*****************************/
68
69
70 /*******************/
71 /* Local Variables */
72 /*******************/
73
74
75
76 /*-------------------------------------------------------------------------
77 * Function: H5T__print_stats
78 *
79 * Purpose: Print statistics about a conversion path. Statistics are
80 * printed only if all the following conditions are true:
81 *
82 * 1. The library was compiled with H5T_DEBUG defined.
83 * 2. Data type debugging is turned on at run time.
84 * 3. The path was called at least one time.
85 *
86 * The optional NPRINT argument keeps track of the number of
87 * conversions paths for which statistics have been shown. If
88 * its value is zero then table headers are printed before the
89 * first line of output.
90 *
91 * Return: SUCCEED/FAIL
92 *
93 *-------------------------------------------------------------------------
94 */
95 herr_t
H5T__print_stats(H5T_path_t H5_ATTR_UNUSED * path,int H5_ATTR_UNUSED * nprint)96 H5T__print_stats(H5T_path_t H5_ATTR_UNUSED * path, int H5_ATTR_UNUSED * nprint/*in,out*/)
97 {
98 #ifdef H5T_DEBUG
99 hsize_t nbytes;
100 char bandwidth[32];
101 #endif
102
103 FUNC_ENTER_PACKAGE_NOERR
104
105 #ifdef H5T_DEBUG
106 if (H5DEBUG(T) && path->stats.ncalls > 0) {
107 if (nprint && 0 == (*nprint)++) {
108 HDfprintf(H5DEBUG(T), "H5T: type conversion statistics:\n");
109 HDfprintf(H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s %10s\n",
110 "Conversion", "Elmts", "Calls", "User",
111 "System", "Elapsed", "Bandwidth");
112 HDfprintf(H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s %10s\n",
113 "----------", "-----", "-----", "----",
114 "------", "-------", "---------");
115 }
116 if (path->src && path->dst)
117 nbytes = MAX(H5T_get_size(path->src), H5T_get_size(path->dst));
118 else if (path->src)
119 nbytes = H5T_get_size(path->src);
120 else if (path->dst)
121 nbytes = H5T_get_size(path->dst);
122 else
123 nbytes = 0;
124 nbytes *= path->stats.nelmts;
125 H5_bandwidth(bandwidth, (double)nbytes, path->stats.timer.etime);
126 HDfprintf(H5DEBUG(T), " %-16s %10Hd %10d %8.2f %8.2f %8.2f %10s\n",
127 path->name,
128 path->stats.nelmts,
129 path->stats.ncalls,
130 path->stats.timer.utime,
131 path->stats.timer.stime,
132 path->stats.timer.etime,
133 bandwidth);
134 }
135 #endif
136 FUNC_LEAVE_NOAPI(SUCCEED)
137 } /* end H5T__print_stats() */
138
139
140 /*-------------------------------------------------------------------------
141 * Function: H5T_debug
142 *
143 * Purpose: Prints information about a data type.
144 *
145 * Return: SUCCEED/FAIL
146 *
147 *-------------------------------------------------------------------------
148 */
149 herr_t
H5T_debug(const H5T_t * dt,FILE * stream)150 H5T_debug(const H5T_t *dt, FILE *stream)
151 {
152 const char *s1 = "";
153 const char *s2 = "";
154 unsigned i;
155 herr_t ret_value = SUCCEED; /* Return value */
156
157 FUNC_ENTER_NOAPI_NOINIT
158
159 /* Check args */
160 HDassert(dt);
161 HDassert(stream);
162
163 switch (dt->shared->type) {
164 case H5T_NO_CLASS:
165 HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "no class");
166 break;
167
168 case H5T_INTEGER:
169 s1 = "int";
170 break;
171
172 case H5T_FLOAT:
173 s1 = "float";
174 break;
175
176 case H5T_TIME:
177 s1 = "time";
178 break;
179
180 case H5T_STRING:
181 s1 = "str";
182 break;
183
184 case H5T_BITFIELD:
185 s1 = "bits";
186 break;
187
188 case H5T_OPAQUE:
189 s1 = "opaque";
190 break;
191
192 case H5T_COMPOUND:
193 s1 = "struct";
194 break;
195
196 case H5T_ENUM:
197 s1 = "enum";
198 break;
199
200 case H5T_VLEN:
201 if(H5T_IS_VL_STRING(dt->shared))
202 s1 = "str";
203 else
204 s1 = "vlen";
205 break;
206
207 case H5T_REFERENCE:
208 case H5T_ARRAY:
209 case H5T_NCLASSES:
210 default:
211 s1 = "";
212 break;
213 } /* end switch */
214
215 switch (dt->shared->state) {
216 case H5T_STATE_TRANSIENT:
217 s2 = "[transient]";
218 break;
219
220 case H5T_STATE_RDONLY:
221 s2 = "[constant]";
222 break;
223
224 case H5T_STATE_IMMUTABLE:
225 s2 = "[predefined]";
226 break;
227
228 case H5T_STATE_NAMED:
229 s2 = "[named,closed]";
230 break;
231
232 case H5T_STATE_OPEN:
233 s2 = "[named,open]";
234 break;
235 default:
236 HDassert(0 && "This Should never be executed!");
237 } /* end switch */
238
239 HDfprintf(stream, "%s%s {nbytes=%lu", s1, s2, (unsigned long)(dt->shared->size));
240
241 if (H5T_IS_ATOMIC(dt->shared)) {
242 uint64_t tmp;
243
244 switch (dt->shared->u.atomic.order) {
245 case H5T_ORDER_ERROR:
246 HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "order error");
247 break;
248
249 case H5T_ORDER_BE:
250 s1 = "BE";
251 break;
252
253 case H5T_ORDER_LE:
254 s1 = "LE";
255 break;
256
257 case H5T_ORDER_VAX:
258 s1 = "VAX";
259 break;
260
261 case H5T_ORDER_NONE:
262 s1 = "NONE";
263 break;
264
265 case H5T_ORDER_MIXED:
266 default:
267 s1 = "order?";
268 break;
269 } /* end switch */
270
271 HDfprintf(stream, ", %s", s1);
272
273 if (dt->shared->u.atomic.offset)
274 HDfprintf(stream, ", offset=%lu", (unsigned long) (dt->shared->u.atomic.offset));
275 if (dt->shared->u.atomic.prec != 8 * dt->shared->size)
276 HDfprintf(stream, ", prec=%lu", (unsigned long) (dt->shared->u.atomic.prec));
277
278 switch (dt->shared->type) {
279 case H5T_NO_CLASS:
280 HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "no class");
281 break;
282
283 case H5T_INTEGER:
284 switch(dt->shared->u.atomic.u.i.sign) {
285 case H5T_SGN_ERROR:
286 HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "sign error");
287 break;
288
289 case H5T_SGN_NONE:
290 s1 = "unsigned";
291 break;
292
293 case H5T_SGN_2:
294 s1 = NULL;
295 break;
296
297 case H5T_NSGN:
298 default:
299 s1 = "sign?";
300 break;
301
302 } /* end switch */
303 if(s1)
304 HDfprintf(stream, ", %s", s1);
305 break;
306
307 case H5T_FLOAT:
308 switch(dt->shared->u.atomic.u.f.norm) {
309 case H5T_NORM_ERROR:
310 HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "norm error");
311 break;
312
313 case H5T_NORM_IMPLIED:
314 s1 = "implied";
315 break;
316
317 case H5T_NORM_MSBSET:
318 s1 = "msbset";
319 break;
320
321 case H5T_NORM_NONE:
322 s1 = "no-norm";
323 break;
324
325 default:
326 s1 = "norm?";
327 break;
328 } /* end switch */
329
330 HDfprintf(stream, ", sign=%lu+1",
331 (unsigned long)(dt->shared->u.atomic.u.f.sign));
332 HDfprintf(stream, ", mant=%lu+%lu (%s)",
333 (unsigned long)(dt->shared->u.atomic.u.f.mpos),
334 (unsigned long)(dt->shared->u.atomic.u.f.msize), s1);
335 HDfprintf(stream, ", exp=%lu+%lu",
336 (unsigned long)(dt->shared->u.atomic.u.f.epos),
337 (unsigned long)(dt->shared->u.atomic.u.f.esize));
338 tmp = dt->shared->u.atomic.u.f.ebias >> 32;
339 if (tmp) {
340 size_t hi = (size_t)tmp;
341 size_t lo = (size_t)(dt->shared->u.atomic.u.f.ebias & 0xffffffff);
342 HDfprintf(stream, " bias=0x%08lx%08lx",
343 (unsigned long)hi, (unsigned long)lo);
344 }
345 else {
346 size_t lo = (size_t)(dt->shared->u.atomic.u.f.ebias & 0xffffffff);
347 HDfprintf(stream, " bias=0x%08lx", (unsigned long)lo);
348 }
349 break;
350
351 case H5T_TIME:
352 case H5T_STRING:
353 case H5T_BITFIELD:
354 case H5T_OPAQUE:
355 case H5T_COMPOUND:
356 case H5T_REFERENCE:
357 case H5T_ENUM:
358 case H5T_VLEN:
359 case H5T_ARRAY:
360 case H5T_NCLASSES:
361 default:
362 /* No additional info */
363 break;
364 } /* end switch */
365 }
366 else if (H5T_COMPOUND == dt->shared->type) {
367 /* Compound data type */
368 for (i = 0; i < dt->shared->u.compnd.nmembs; i++) {
369 HDfprintf(stream, "\n\"%s\" @%lu",
370 dt->shared->u.compnd.memb[i].name,
371 (unsigned long)(dt->shared->u.compnd.memb[i].offset));
372 HDfprintf(stream, " ");
373 H5T_debug(dt->shared->u.compnd.memb[i].type, stream);
374 } /* end for */
375 HDfprintf(stream, "\n");
376 }
377 else if (H5T_VLEN == dt->shared->type) {
378 switch (dt->shared->u.vlen.loc) {
379 case H5T_LOC_BADLOC:
380 HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid datatype location");
381 break;
382
383 case H5T_LOC_MEMORY:
384 HDfprintf(stream, ", loc=memory");
385 break;
386
387 case H5T_LOC_DISK:
388 HDfprintf(stream, ", loc=disk");
389 break;
390
391 case H5T_LOC_MAXLOC:
392 default:
393 HDfprintf(stream, ", loc=UNKNOWN");
394 break;
395 } /* end switch */
396
397 if (H5T_IS_VL_STRING(dt->shared))
398 /* Variable length string datatype */
399 HDfprintf(stream, ", variable-length");
400 else {
401 /* Variable length sequence datatype */
402 HDfprintf(stream, " VLEN ");
403 H5T_debug(dt->shared->parent, stream);
404 HDfprintf(stream, "\n");
405 } /* end else */
406 }
407 else if (H5T_ENUM == dt->shared->type) {
408 size_t base_size;
409
410 /* Enumeration data type */
411 HDfprintf(stream, " ");
412 H5T_debug(dt->shared->parent, stream);
413 base_size = dt->shared->parent->shared->size;
414 for (i = 0; i < dt->shared->u.enumer.nmembs; i++) {
415 size_t k;
416
417 HDfprintf(stream, "\n\"%s\" = 0x", dt->shared->u.enumer.name[i]);
418 for (k = 0; k < base_size; k++)
419 HDfprintf(stream, "%02lx", (unsigned long)(dt->shared->u.enumer.value + (i * base_size) + k));
420 } /* end for */
421 HDfprintf(stream, "\n");
422 }
423 else if (H5T_OPAQUE == dt->shared->type) {
424 HDfprintf(stream, ", tag=\"%s\"", dt->shared->u.opaque.tag);
425 }
426 else {
427 /* Unknown */
428 HDfprintf(stream, "unknown class %d\n", (int)(dt->shared->type));
429 }
430 HDfprintf(stream, "}");
431
432 done:
433 FUNC_LEAVE_NOAPI(ret_value)
434 } /* end H5T_debug() */
435
436