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