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 #include "H5private.h"
15 #include "h5tools.h"
16 #include "h5tools_utils.h"
17 #include "h5diff.h"
18 #include "ph5diff.h"
19 
20 /*-------------------------------------------------------------------------
21  * printf formatting
22  *-------------------------------------------------------------------------
23  */
24 
25 #define F_FORMAT      "%-15g %-15g %-15g\n"
26 
27 #if H5_SIZEOF_LONG_DOUBLE !=0
28 #define LD_FORMAT     "%-15Lf %-15Lf %-15Lf\n"
29 #endif
30 
31 #define I_FORMAT      "%-15d %-15d %-15d\n"
32 #define S_FORMAT      "%-16s %-17s\n"
33 #define UI_FORMAT     "%-15u %-15u %-15u\n"
34 #define LI_FORMAT     "%-15ld %-15ld %-15ld\n"
35 #define ULI_FORMAT    "%-15lu %-15lu %-15lu\n"
36 #define LLI_FORMAT    "%-15" H5_PRINTF_LL_WIDTH "d %-15" H5_PRINTF_LL_WIDTH "d %-15" H5_PRINTF_LL_WIDTH "d\n"
37 #define ULLI_FORMAT   "%-15" H5_PRINTF_LL_WIDTH "u %-15" H5_PRINTF_LL_WIDTH "u %-15" H5_PRINTF_LL_WIDTH "u\n"
38 
39 /* with -p option */
40 #define F_FORMAT_P    "%-15.10g %-15.10g %-15.10g %-14.10g\n"
41 
42 #if H5_SIZEOF_LONG_DOUBLE !=0
43 #define LD_FORMAT_P    "%-15.10Lf %-15.10Lf %-15.10Lf %-14.10Lf\n"
44 #endif
45 
46 #define I_FORMAT_P    "%-15d %-15d %-15d %-14f\n"
47 #define UI_FORMAT_P   "%-15u %-15u %-15u %-14f\n"
48 #define LI_FORMAT_P   "%-15ld %-15ld %-15ld %-14f\n"
49 #define ULI_FORMAT_P  "%-15lu %-15lu %-15lu %-14f\n"
50 #define LLI_FORMAT_P  "%-15" H5_PRINTF_LL_WIDTH "d %-15" H5_PRINTF_LL_WIDTH "d %-15" H5_PRINTF_LL_WIDTH "d %-14f\n"
51 #define ULLI_FORMAT_P "%-15" H5_PRINTF_LL_WIDTH "u %-15" H5_PRINTF_LL_WIDTH "u %-15" H5_PRINTF_LL_WIDTH "d %-14f\n"
52 #define SPACES        "          "
53 
54 /* not comparable */
55 #define F_FORMAT_P_NOTCOMP  "%-15.10g %-15.10g %-15.10g not comparable\n"
56 
57 #if H5_SIZEOF_LONG_DOUBLE !=0
58 #define LD_FORMAT_P_NOTCOMP  "%-15.10Lf %-15.10Lf %-15.10Lf not comparable\n"
59 #endif
60 
61 #define I_FORMAT_P_NOTCOMP  "%-15d %-15d %-15d not comparable\n"
62 #define UI_FORMAT_P_NOTCOMP   "%-15u %-15u %-15u not comparable\n"
63 #define LI_FORMAT_P_NOTCOMP   "%-15ld %-15ld %-15ld not comparable\n"
64 #define ULI_FORMAT_P_NOTCOMP  "%-15lu %-15lu %-15lu not comparable\n"
65 #define LLI_FORMAT_P_NOTCOMP  "%-15" H5_PRINTF_LL_WIDTH "d %-15" H5_PRINTF_LL_WIDTH "d %-15" H5_PRINTF_LL_WIDTH "d not comparable\n"
66 #define ULLI_FORMAT_P_NOTCOMP "%-15" H5_PRINTF_LL_WIDTH "u %-15" H5_PRINTF_LL_WIDTH "u %-15" H5_PRINTF_LL_WIDTH "d not comparable\n"
67 
68 /* if system EPSILON is defined, use the system EPSILON; otherwise, use
69  constants that are close to most EPSILON values */
70 
71 #ifndef FLT_EPSILON
72 #define FLT_EPSILON 1.19209E-07
73 #endif
74 
75 #ifndef DBL_EPSILON
76 #define DBL_EPSILON 2.22045E-16
77 #endif
78 
79 /*-------------------------------------------------------------------------
80  * -p relative error formula
81  *
82  * We assume the true value of a quantity to be A (value in first dataset)
83  *  and the measured or inferred value to be B (value in second dataset).
84  *  The relative error is defined by
85  *
86  *  B - A
87  * --------
88  *    A
89  *
90 
91  *-------------------------------------------------------------------------
92  */
93 
94 static hbool_t not_comparable;
95 
96 #define PER(A,B) {                                                      \
97     per = -1;                                                           \
98     not_comparable = FALSE;                                             \
99     both_zero = FALSE;                                                  \
100     if(H5_DBL_ABS_EQUAL(0, (double)A) && H5_DBL_ABS_EQUAL(0, (double)B)) \
101         both_zero = TRUE;                                               \
102     if(!H5_DBL_ABS_EQUAL(0, (double)A))                                 \
103         per = (double)ABS((double)((B) - (A)) / (double)(A));           \
104     else                                                                \
105         not_comparable = TRUE;                                          \
106 }
107 
108 #define PER_UNSIGN(TYPE,A,B) {                                          \
109     per = -1;                                                           \
110     not_comparable = FALSE;                                             \
111     both_zero = FALSE;                                                  \
112     if(H5_DBL_ABS_EQUAL(0, (double)A) && H5_DBL_ABS_EQUAL(0, (double)B)) \
113         both_zero = TRUE;                                               \
114     if(!H5_DBL_ABS_EQUAL(0, (double)A))                                 \
115         per = ABS((double)((TYPE)((B) - (A))) / (double)(A)) ;          \
116     else                                                                \
117         not_comparable = TRUE;                                          \
118 }
119 
120 #define PDIFF(a,b)    (((b) > (a)) ? ((b) - (a)) : ((a) -(b)))
121 
122 typedef struct mcomp_t {
123     unsigned n; /* number of members */
124     hid_t *ids; /* member type id */
125     size_t *offsets;
126     struct mcomp_t **m; /* members */
127 } mcomp_t;
128 
129 /*-------------------------------------------------------------------------
130  * local prototypes
131  *-------------------------------------------------------------------------
132  */
133 static hsize_t diff_region(hid_t obj1_id, hid_t obj2_id, hid_t region1_id,
134         hid_t region2_id, diff_opt_t *opts);
135 static hbool_t all_zero(const void *_mem, size_t size);
136 static int ull2float(unsigned long long ull_value, float *f_value);
137 static hsize_t character_compare(char *mem1, char *mem2, hsize_t i, size_t u,
138         int rank, hsize_t *dims, hsize_t *acc, hsize_t *pos,
139         diff_opt_t *opts, const char *obj1, const char *obj2, int *ph);
140 static hsize_t character_compare_opt(unsigned char *mem1, unsigned char *mem2,
141         hsize_t i, int rank, hsize_t *dims, hsize_t *acc, hsize_t *pos,
142         diff_opt_t *opts, const char *obj1, const char *obj2, int *ph);
143 static hbool_t equal_float(float value, float expected, diff_opt_t *opts);
144 static hbool_t equal_double(double value, double expected, diff_opt_t *opts);
145 #if H5_SIZEOF_LONG_DOUBLE !=0
146 static hbool_t equal_ldouble(long double value, long double expected, diff_opt_t *opts);
147 #endif
148 static int print_data(diff_opt_t *opts);
149 static void print_pos(int *ph, int pp, hsize_t curr_pos, hsize_t *acc,
150         hsize_t *pos, int rank, hsize_t *dims, const char *obj1,
151         const char *obj2);
152 static void print_char_pos(int *ph, int pp, hsize_t curr_pos, size_t u,
153         hsize_t *acc, hsize_t *pos, int rank, hsize_t *dims, const char *obj1,
154         const char *obj2);
155 static void h5diff_print_char(char ch);
156 static hsize_t diff_datum(void *_mem1, void *_mem2, hid_t m_type, hsize_t index,
157         int rank, hsize_t *dims, hsize_t *acc, hsize_t *pos,
158         diff_opt_t *opts, const char *obj1, const char *obj2,
159         hid_t container1_id, hid_t container2_id, /*where the reference came from*/
160         int *ph, /*print header */
161         mcomp_t *members); /*compound members */
162 static hsize_t diff_float(unsigned char *mem1, unsigned char *mem2,
163         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
164         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
165         const char *obj2, int *ph);
166 static hsize_t diff_double(unsigned char *mem1, unsigned char *mem2,
167         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
168         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
169         const char *obj2, int *ph);
170 #if H5_SIZEOF_LONG_DOUBLE !=0
171 static hsize_t diff_ldouble(unsigned char *mem1,
172         unsigned char *mem2,
173         hsize_t nelmts,
174         hsize_t hyper_start,
175         int rank,
176         hsize_t *dims,
177         hsize_t *acc,
178         hsize_t *pos,
179         diff_opt_t *opts,
180         const char *obj1,
181         const char *obj2,
182         int *ph);
183 #endif
184 static hsize_t diff_schar(unsigned char *mem1, unsigned char *mem2,
185         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
186         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
187         const char *obj2, int *ph);
188 static hsize_t diff_uchar(unsigned char *mem1, unsigned char *mem2,
189         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
190         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
191         const char *obj2, int *ph);
192 static hsize_t diff_short(unsigned char *mem1, unsigned char *mem2,
193         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
194         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
195         const char *obj2, int *ph);
196 static hsize_t diff_ushort(unsigned char *mem1, unsigned char *mem2,
197         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
198         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
199         const char *obj2, int *ph);
200 static hsize_t diff_int(unsigned char *mem1, unsigned char *mem2,
201         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
202         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
203         const char *obj2, int *ph);
204 static hsize_t diff_uint(unsigned char *mem1, unsigned char *mem2,
205         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
206         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
207         const char *obj2, int *ph);
208 static hsize_t diff_long(unsigned char *mem1, unsigned char *mem2,
209         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
210         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
211         const char *obj2, int *ph);
212 static hsize_t diff_ulong(unsigned char *mem1, unsigned char *mem2,
213         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
214         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
215         const char *obj2, int *ph);
216 static hsize_t diff_llong(unsigned char *mem1, unsigned char *mem2,
217         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
218         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
219         const char *obj2, int *ph);
220 static hsize_t diff_ullong(unsigned char *mem1, unsigned char *mem2,
221         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
222         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
223         const char *obj2, int *ph);
224 
225 /*-------------------------------------------------------------------------
226  * NaN detection
227  *-------------------------------------------------------------------------
228  */
229 
230 #if H5_SIZEOF_LONG_DOUBLE !=0
231 typedef enum dtype_t
232 {
233     FLT_FLOAT,
234     FLT_DOUBLE,
235     FLT_LDOUBLE
236 }dtype_t;
237 #else
238 
239 typedef enum dtype_t {
240     FLT_FLOAT, FLT_DOUBLE
241 } dtype_t;
242 #endif
243 
244 static hbool_t my_isnan(dtype_t type, void *val);
245 
246 /*-------------------------------------------------------------------------
247  * XCAO, 11/10/2010
248  * added to improve performance for compound datasets
249  */
250 static void get_member_types(hid_t tid, mcomp_t *members);
251 static void close_member_types(mcomp_t *members);
252 
253 /*-------------------------------------------------------------------------
254  * Function: diff_array
255  *
256  * Purpose: compare two memory buffers;
257  *
258  * Return: number of differences found
259  *-------------------------------------------------------------------------
260  */
261 
diff_array(void * _mem1,void * _mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,diff_opt_t * opts,const char * name1,const char * name2,hid_t m_type,hid_t container1_id,hid_t container2_id)262 hsize_t diff_array(
263         void *_mem1,
264         void *_mem2,
265         hsize_t nelmts,
266         hsize_t hyper_start,
267         int rank,
268         hsize_t *dims,
269         diff_opt_t *opts,
270         const char *name1,
271         const char *name2,
272         hid_t m_type,
273         hid_t container1_id,
274         hid_t container2_id) /* dataset where the reference came from*/
275 {
276     hsize_t         nfound = 0; /* number of differences found */
277     size_t          size; /* size of datum */
278     unsigned char  *mem1 = (unsigned char*) _mem1;
279     unsigned char  *mem2 = (unsigned char*) _mem2;
280     hsize_t         acc[32]; /* accumulator position */
281     hsize_t         pos[32]; /* matrix position */
282     int             ph = 1; /* print header  */
283     hsize_t         i;
284     int             j;
285     mcomp_t         members;
286     H5T_class_t     type_class;
287 
288     h5diffdebug2("diff_array start - errstat:%d\n", opts->err_stat);
289     /* get the size. */
290     size = H5Tget_size(m_type);
291     type_class = H5Tget_class(m_type);
292 
293     /* Fast comparison first for atomic type by memcmp().
294      * It is OK not to list non-atomic type here because it will not be caught
295      * by the condition, but it gives more clarity for code planning
296      */
297     if (type_class != H5T_REFERENCE &&
298             type_class != H5T_COMPOUND &&
299             type_class != H5T_STRING &&
300             type_class != H5T_VLEN &&
301             HDmemcmp(mem1, mem2, size*nelmts) == 0)
302         return 0;
303 
304     if (rank > 0) {
305         acc[rank - 1] = 1;
306         for (j = (rank - 2); j >= 0; j--) {
307             acc[j] = acc[j + 1] * dims[j + 1];
308         }
309         for (j = 0; j < rank; j++)
310             pos[j] = 0;
311     }
312 
313     switch (type_class) {
314     case H5T_NO_CLASS:
315     case H5T_TIME:
316     case H5T_NCLASSES:
317     default:
318         HDassert(0);
319         break;
320 
321     /*-------------------------------------------------------------------------
322      * float and integer atomic types
323      *-------------------------------------------------------------------------
324      */
325     case H5T_FLOAT:
326         if (H5Tequal(m_type, H5T_NATIVE_FLOAT))
327             nfound = diff_float(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
328         else if (H5Tequal(m_type, H5T_NATIVE_DOUBLE))
329             nfound = diff_double(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
330 #if H5_SIZEOF_LONG_DOUBLE != 0
331         else if (H5Tequal(m_type, H5T_NATIVE_LDOUBLE))
332         nfound = diff_ldouble(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
333 #endif
334         break;
335 
336     case H5T_INTEGER:
337         if (H5Tequal(m_type, H5T_NATIVE_SCHAR))
338             nfound = diff_schar(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
339         else if (H5Tequal(m_type, H5T_NATIVE_UCHAR))
340             nfound = diff_uchar(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
341         else if (H5Tequal(m_type, H5T_NATIVE_SHORT))
342             nfound = diff_short(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
343         else if (H5Tequal(m_type, H5T_NATIVE_USHORT))
344             nfound = diff_ushort(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
345         else if (H5Tequal(m_type, H5T_NATIVE_INT))
346             nfound = diff_int(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
347         else if (H5Tequal(m_type, H5T_NATIVE_UINT))
348             nfound = diff_uint(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
349         else if (H5Tequal(m_type, H5T_NATIVE_LONG))
350             nfound = diff_long(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
351         else if (H5Tequal(m_type, H5T_NATIVE_ULONG))
352             nfound = diff_ulong(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
353         else if (H5Tequal(m_type, H5T_NATIVE_LLONG))
354             nfound = diff_llong(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
355         else if (H5Tequal(m_type, H5T_NATIVE_ULLONG))
356             nfound = diff_ullong(mem1, mem2, nelmts, hyper_start, rank, dims, acc, pos, opts, name1, name2, &ph);
357         break;
358 
359     /*-------------------------------------------------------------------------
360      * Other types than float and integer
361      *-------------------------------------------------------------------------
362      */
363     case H5T_COMPOUND:
364     case H5T_STRING:
365     case H5T_BITFIELD:
366     case H5T_OPAQUE:
367     case H5T_ENUM:
368     case H5T_ARRAY:
369     case H5T_VLEN:
370     case H5T_REFERENCE:
371         HDmemset(&members, 0, sizeof(mcomp_t));
372         get_member_types(m_type, &members);
373         for (i = 0; i < nelmts; i++) {
374             nfound += diff_datum(mem1 + i * size, mem2 + i * size, m_type, i, rank, dims, acc, pos, opts,
375                     name1, name2, container1_id, container2_id, &ph, &members);
376             if (opts->n && nfound >= opts->count)
377                 break;
378         } /* i */
379         close_member_types(&members);
380     } /* switch */
381     h5diffdebug3("diff_array finish:%d - errstat:%d\n", nfound, opts->err_stat);
382 
383     return nfound;
384 }
385 
386 /*-------------------------------------------------------------------------
387  * Function: diff_datum
388  *
389  * Purpose: compare the values pointed to in _MEM1 and _MEM2 of type M_TYPE
390  *
391  * Return: number of differences found
392  *
393  * The comparison of the 2 buffers read from the files is made datum by datum.
394  *
395  * H5T_INTEGER and H5T_FLOAT
396  *  Copy the buffer into a compatible local datum and do a numerical
397  *  compare of this datum
398  * H5T_COMPOUND
399  *  Recursively call this function for each member
400  * H5T_ARRAY
401  *  Recursively call this function for each element
402  * H5T_VLEN
403  *  Recursively call this function for each element
404  * H5T_STRING
405  *  compare byte by byte in a cycle from 0 to type_size. this type_size is the
406  *  value obtained by the get_size function but it is the string length for
407  *  variable sized strings
408  * H5T_OPAQUE
409  *  compare byte by byte in a cycle from 0 to type_size
410  * H5T_BITFIELD
411  *  compare byte by byte in a cycle from 0 to type_size
412  * H5T_ENUM
413  *  for each pair of elements being compared, both bit patterns are converted to
414  *  their corresponding enumeration constant and a string comparison is made
415  * H5T_REFERENCE
416  *  Dereference the object and compare the type (basic object type).
417  *-------------------------------------------------------------------------
418  */
diff_datum(void * _mem1,void * _mem2,hid_t m_type,hsize_t index,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,hid_t container1_id,hid_t container2_id,int * ph,mcomp_t * members)419 static hsize_t diff_datum(
420         void *_mem1,
421         void *_mem2,
422         hid_t m_type,
423         hsize_t index,
424         int rank,
425         hsize_t *dims,
426         hsize_t *acc,
427         hsize_t *pos,
428         diff_opt_t *opts,
429         const char *obj1,
430         const char *obj2,
431         hid_t container1_id,
432         hid_t container2_id, /*where the reference came from*/
433         int *ph,             /*print header */
434         mcomp_t *members)    /*compound members */
435 {
436     unsigned char  *mem1 = (unsigned char*) _mem1;
437     unsigned char  *mem2 = (unsigned char*) _mem2;
438     size_t          u;
439     size_t          type_size;
440     H5T_sign_t      type_sign;
441     H5T_class_t     type_class;
442     size_t          offset;
443     unsigned        nmembs;
444     unsigned        j;
445     hsize_t         nelmts;
446     size_t          size = 0;
447     hbool_t         iszero1;
448     hbool_t         iszero2;
449     hsize_t         nfound = 0;    /* differences found */
450     hsize_t         ret_value = opts->err_stat;
451     double          per;
452     hbool_t         both_zero;
453 
454     h5difftrace("diff_datum start\n");
455 
456     type_size = H5Tget_size(m_type);
457     type_class = H5Tget_class(m_type);
458 
459     /* Fast comparison first for atomic type by memcmp().
460      * It is OK not to list non-atomic type here because it will not be caught
461      * by the condition, but it gives more clarity for code planning
462      */
463     if (type_class != H5T_REFERENCE &&
464             type_class != H5T_COMPOUND &&
465             type_class != H5T_STRING &&
466             type_class != H5T_VLEN &&
467             HDmemcmp(mem1, mem2, type_size) == 0)
468         HGOTO_DONE(opts->err_stat);
469 
470     switch (H5Tget_class(m_type)) {
471     case H5T_NO_CLASS:
472     case H5T_TIME:
473     case H5T_NCLASSES:
474     default:
475         HGOTO_ERROR(1, H5E_tools_min_id_g, "Invalid type class");
476         break;
477 
478     /*-------------------------------------------------------------------------
479      * H5T_COMPOUND
480      *-------------------------------------------------------------------------
481      */
482     case H5T_COMPOUND:
483         h5difftrace("diff_datum H5T_COMPOUND\n");
484         {
485             hid_t memb_type = -1;
486             nmembs = members->n;
487 
488             for (j = 0; j < nmembs; j++) {
489                 offset = members->offsets[j];
490                 memb_type = members->ids[j];
491 
492                 nfound += diff_datum(mem1 + offset, mem2 + offset, memb_type, index,
493                         rank, dims, acc, pos, opts, obj1, obj2, container1_id, container2_id, ph, members->m[j]);
494             }
495         }
496         break;
497 
498     /*-------------------------------------------------------------------------
499      * H5T_STRING
500      *-------------------------------------------------------------------------
501      */
502     case H5T_STRING:
503         h5difftrace("diff_datum H5T_STRING\n");
504         {
505             char *s = NULL;
506             char *sx = NULL;
507             char *s1 = NULL;
508             char *s2 = NULL;
509             size_t size1;
510             size_t size2;
511             size_t sizex;
512             size_t size_mtype = H5Tget_size(m_type);
513             H5T_str_t pad = H5Tget_strpad(m_type);
514 
515             /* if variable length string */
516             if (H5Tis_variable_str(m_type)) {
517                 h5difftrace("diff_datum H5T_STRING variable\n");
518                 /* Get pointer to first string */
519                 s1 = *(char **)((void *)mem1);
520                 if (s1)
521                     size1 = HDstrlen(s1);
522                 else
523                     size1 = 0;
524 
525                 /* Get pointer to second string */
526                 s2 = *(char **)((void *)mem2);
527                 if (s2)
528                     size2 = HDstrlen(s2);
529                 else
530                     size2 = 0;
531             }
532             else if (H5T_STR_NULLTERM == pad) {
533                 h5difftrace("diff_datum H5T_STRING null term\n");
534                 /* Get pointer to first string */
535                 s1 = (char*) mem1;
536                 if (s1)
537                     size1 = HDstrlen(s1);
538                 else
539                     size1 = 0;
540 
541                 if (size1 > size_mtype)
542                     size1 = size_mtype;
543 
544                 /* Get pointer to second string */
545                 s2 = (char*) mem2;
546                 if (s2)
547                     size2 = HDstrlen(s2);
548                 else
549                     size2 = 0;
550 
551                 if (size2 > size_mtype)
552                     size2 = size_mtype;
553             }
554             else {
555                 /* Get pointer to first string */
556                 s1 = (char *) mem1;
557                 size1 = size_mtype;
558 
559                 /* Get pointer to second string */
560                 s2 = (char *) mem2;
561                 size2 = size_mtype;
562             }
563 
564             /*
565              * compare for shorter string
566              * TODO: this code need to be improved to handle the difference
567              *       of length of strings.
568              *       For now mimic the previous way.
569              */
570             h5diffdebug2("diff_datum string size:%d\n", size1);
571             h5diffdebug2("diff_datum string size:%d\n", size2);
572             if (size1 != size2) {
573                 h5difftrace("diff_datum string sizes\n");
574                 nfound++;
575             }
576             if (size1 < size2) {
577                 size = size1;
578                 s = s1;
579                 sizex = size2;
580                 sx = s2;
581             }
582             else {
583                 size = size2;
584                 s = s2;
585                 sizex = size1;
586                 sx = s1;
587             }
588 
589             /* check for NULL pointer for string */
590             if (s != NULL) {
591                 /* try fast compare first */
592                 if (HDmemcmp(s, sx, size) == 0) {
593                     if (size1 != size2)
594                         if (print_data(opts))
595                             for (u = size; u < sizex; u++)
596                                 character_compare(s + u, sx + u, index, u, rank, dims, acc, pos, opts, obj1, obj2, ph);
597                 }
598                 else
599                     for (u = 0; u < size; u++)
600                         nfound += character_compare(s + u, sx + u, index, u, rank, dims, acc, pos, opts, obj1, obj2, ph);
601             } /* end check for NULL pointer for string */
602         }
603         break;
604 
605     /*-------------------------------------------------------------------------
606      * H5T_BITFIELD
607      *-------------------------------------------------------------------------
608      */
609     case H5T_BITFIELD:
610         h5difftrace("diff_datum H5T_BITFIELD\n");
611         /* byte-by-byte comparison */
612         for (u = 0; u < type_size; u++)
613             nfound += character_compare_opt(mem1 + u, mem2 + u, index, rank, dims, acc, pos, opts, obj1, obj2, ph);
614         break;
615 
616     /*-------------------------------------------------------------------------
617      * H5T_OPAQUE
618      *-------------------------------------------------------------------------
619      */
620     case H5T_OPAQUE:
621         h5difftrace("diff_datum H5T_OPAQUE\n");
622         /* byte-by-byte comparison */
623         for (u = 0; u < type_size; u++)
624             nfound += character_compare_opt(mem1 + u, mem2 + u, index, rank, dims, acc, pos, opts, obj1, obj2, ph);
625         break;
626 
627     /*-------------------------------------------------------------------------
628      * H5T_ENUM
629      *-------------------------------------------------------------------------
630      */
631     case H5T_ENUM:
632         /* For enumeration types we compare the names instead of the
633          * integer values.  For each pair of elements being
634          * compared, we convert both bit patterns to their corresponding
635          * enumeration constant and do a string comparison
636          */
637         h5difftrace("diff_datum H5T_ENUM\n");
638         {
639             char enum_name1[1024];
640             char enum_name2[1024];
641             herr_t err1;
642             herr_t err2;
643 
644             /* disable error reporting */
645             H5E_BEGIN_TRY {
646                 /* If the enum value cannot be converted to a string
647                  * it is set to an error string for later output.
648                  */
649                 err1 = H5Tenum_nameof(m_type, mem1, enum_name1, sizeof enum_name1);
650                 if (err1 < 0)
651                     HDsnprintf(enum_name1, sizeof(enum_name1), "**INVALID VALUE**");
652 
653                 err2 = H5Tenum_nameof(m_type, mem2, enum_name2, sizeof enum_name2);
654                 if (err2 < 0)
655                     HDsnprintf(enum_name2, sizeof(enum_name2), "**INVALID VALUE**");
656 
657                 /* One or more bad enum values */
658                 if (err1 < 0 || err2 < 0) {
659                     /* If the two values cannot be converted to a string
660                      * (probably due to them being invalid enum values),
661                      * don't attempt to convert them - just report errors.
662                      */
663                     nfound += 1;
664                     if (print_data(opts)) {
665                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
666                         parallel_print(SPACES);
667                         parallel_print(S_FORMAT, enum_name1, enum_name2);
668                     }
669                 }
670                 else {
671                     /* Both enum values were valid */
672                     if (HDstrcmp(enum_name1, enum_name2) != 0) {
673                         nfound = 1;
674                         if (print_data(opts)) {
675                             print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
676                             parallel_print(SPACES);
677                             parallel_print(S_FORMAT, enum_name1, enum_name2);
678                         }
679                     }
680                     else {
681                         for (u = 0; u < type_size; u++)
682                             nfound += character_compare_opt(mem1 + u, mem2 + u, index, rank, dims, acc, pos, opts, obj1, obj2, ph);
683                     }
684                 }
685                 /* enable error reporting */
686             } H5E_END_TRY;
687         }
688         break;
689 
690     /*-------------------------------------------------------------------------
691      * H5T_ARRAY
692      *-------------------------------------------------------------------------
693      */
694     case H5T_ARRAY:
695         {
696             hid_t   memb_type = -1;
697             hsize_t adims[H5S_MAX_RANK];
698             int     ndims;
699 
700             /* get the array's base datatype for each element */
701             memb_type = H5Tget_super(m_type);
702             size = H5Tget_size(memb_type);
703             ndims = H5Tget_array_ndims(m_type);
704             H5Tget_array_dims2(m_type, adims);
705             HDassert(ndims >= 1 && ndims <= H5S_MAX_RANK);
706 
707             /* calculate the number of array elements */
708             for (u = 0, nelmts = 1; u < (unsigned) ndims; u++)
709                 nelmts *= adims[u];
710             for (u = 0; u < nelmts; u++) {
711                 nfound += diff_datum(mem1 + u * size, mem2 + u * size, memb_type, index,
712                         rank, dims, acc, pos, opts, obj1, obj2, container1_id, container2_id, ph, members);
713             }
714             H5Tclose(memb_type);
715         }
716         break;
717 
718     /*-------------------------------------------------------------------------
719      * H5T_REFERENCE
720      *-------------------------------------------------------------------------
721      */
722     case H5T_REFERENCE:
723         iszero1 = all_zero(_mem1, H5Tget_size(m_type));
724         iszero2 = all_zero(_mem2, H5Tget_size(m_type));
725         if (iszero1 != iszero2) {
726             nfound++;
727             HGOTO_DONE (opts->err_stat);
728         }
729         else if (!iszero1 && !iszero2) {
730             /*-------------------------------------------------------------------------
731              * H5T_STD_REF_DSETREG
732              * Dataset region reference
733              *-------------------------------------------------------------------------
734              */
735             hid_t obj1_id = -1;
736             hid_t obj2_id = -1;
737 
738             if (type_size == H5R_DSET_REG_REF_BUF_SIZE) {
739                 hid_t region1_id = -1;
740                 hid_t region2_id = -1;
741 
742                 if ((obj1_id = H5Rdereference2(container1_id, H5P_DEFAULT, H5R_DATASET_REGION, _mem1)) < 0) {
743                     opts->err_stat = 1;
744                     H5TOOLS_INFO(H5E_tools_min_id_g, "H5Rdereference2 object 1 failed");
745                 }
746                 if ((obj2_id = H5Rdereference2(container2_id, H5P_DEFAULT, H5R_DATASET_REGION, _mem2)) < 0) {
747                     opts->err_stat = 1;
748                     H5TOOLS_INFO(H5E_tools_min_id_g, "H5Rdereference2 object 2 failed");
749                 }
750                 if ((region1_id = H5Rget_region(container1_id, H5R_DATASET_REGION, _mem1)) < 0) {
751                     opts->err_stat = 1;
752                     H5TOOLS_INFO(H5E_tools_min_id_g, "H5Rget_region object 1 failed");
753                 }
754                 if ((region2_id = H5Rget_region(container2_id, H5R_DATASET_REGION, _mem2)) < 0) {
755                     opts->err_stat = 1;
756                     H5TOOLS_INFO(H5E_tools_min_id_g, "H5Rget_region object 2 failed");
757                 }
758 
759                 nfound = diff_region(obj1_id, obj2_id, region1_id, region2_id, opts);
760 
761                 H5Oclose(obj1_id);
762                 H5Oclose(obj2_id);
763                 H5Sclose(region1_id);
764                 H5Sclose(region2_id);
765             }/*dataset reference*/
766 
767             /*-------------------------------------------------------------------------
768              * H5T_STD_REF_OBJ
769              * Object references. get the type and OID of the referenced object
770              *-------------------------------------------------------------------------
771              */
772             else if (type_size == H5R_OBJ_REF_BUF_SIZE) {
773                 H5O_type_t obj1_type;
774                 H5O_type_t obj2_type;
775 
776                 if (H5Rget_obj_type2(container1_id, H5R_OBJECT, _mem1, &obj1_type) < 0) {
777                     opts->err_stat = 1;
778                     H5TOOLS_INFO(H5E_tools_min_id_g, "H5Rget_obj_type2 object 1 failed");
779                 }
780                 if (H5Rget_obj_type2(container2_id, H5R_OBJECT, _mem2, &obj2_type) < 0) {
781                     opts->err_stat = 1;
782                     H5TOOLS_INFO(H5E_tools_min_id_g, "H5Rget_obj_type2 object 2 failed");
783                 }
784 
785                 /* check object type */
786                 if (obj1_type != obj2_type) {
787                     parallel_print("Different object types referenced: <%s> and <%s>", obj1, obj2);
788                     opts->not_cmp = 1;
789                     HGOTO_DONE (opts->err_stat);
790                 }
791 
792                 if ((obj1_id = H5Rdereference2(container1_id, H5P_DEFAULT, H5R_OBJECT, _mem1)) < 0) {
793                     opts->err_stat = 1;
794                     H5TOOLS_INFO(H5E_tools_min_id_g, "H5Rdereference2 object 1 failed");
795                 }
796                 if ((obj2_id = H5Rdereference2(container2_id, H5P_DEFAULT, H5R_OBJECT, _mem2)) < 0) {
797                     opts->err_stat = 1;
798                     H5TOOLS_INFO(H5E_tools_min_id_g, "H5Rdereference2 object 2 failed");
799                 }
800 
801                 /* compare */
802                 if (obj1_type == H5O_TYPE_DATASET)
803                     nfound = diff_datasetid(obj1_id, obj2_id, NULL, NULL, opts);
804                 else {
805                     if (opts->m_verbose)
806                         parallel_print(
807                                 "Warning: Comparison not possible of object types referenced: <%s> and <%s>\n",
808                                 obj1, obj2);
809                     opts->not_cmp = 1;
810                 }
811 
812                 H5Oclose(obj1_id);
813                 H5Oclose(obj2_id);
814             }/*object reference*/
815         }/*is zero*/
816         break;
817 
818     /*-------------------------------------------------------------------------
819      * H5T_VLEN
820      *-------------------------------------------------------------------------
821      */
822     case H5T_VLEN:
823         {
824             hid_t memb_type = -1;
825 
826             /* get the VL sequences's base datatype for each element */
827             memb_type = H5Tget_super(m_type);
828             size = H5Tget_size(memb_type);
829 
830             /* get the number of sequence elements */
831             nelmts = ((hvl_t *)((void *)mem1))->len;
832 
833             for (j = 0; j < nelmts; j++)
834                 nfound += diff_datum(((char *) (((hvl_t *)((void *)mem1))->p)) + j * size, ((char *) (((hvl_t *)((void *)mem2))->p)) + j * size, memb_type, index,      /* Extra (void *) cast to quiet "cast to create alignment" warning - 2019/07/05, QAK */
835                         rank, dims, acc, pos, opts, obj1, obj2, container1_id, container2_id, ph, members);
836 
837             H5Tclose(memb_type);
838         }
839         break;
840 
841     /*-------------------------------------------------------------------------
842      * H5T_INTEGER
843      *-------------------------------------------------------------------------
844      */
845     case H5T_INTEGER:
846         type_sign = H5Tget_sign(m_type);
847         /*-------------------------------------------------------------------------
848          * H5T_NATIVE_SCHAR
849          *-------------------------------------------------------------------------
850          */
851         if (type_size == 1 && type_sign != H5T_SGN_NONE) {
852             char temp1_char;
853             char temp2_char;
854 
855             if(type_size != sizeof(char))
856                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not char size");
857             HDmemcpy(&temp1_char, mem1, sizeof(char));
858             HDmemcpy(&temp2_char, mem2, sizeof(char));
859             /* -d and !-p */
860             if (opts->d && !opts->p) {
861                 if (ABS(temp1_char-temp2_char) > opts->delta) {
862                     if (print_data(opts)) {
863                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
864                         parallel_print(SPACES);
865                         parallel_print(I_FORMAT, temp1_char, temp2_char, ABS(temp1_char - temp2_char));
866                     }
867                     nfound++;
868                 }
869             }
870             /* !-d and -p */
871             else if (!opts->d && opts->p) {
872                 PER(temp1_char, temp2_char);
873 
874                 if (not_comparable && !both_zero) {
875                     if (print_data(opts)) {
876                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
877                         parallel_print(SPACES);
878                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_char, temp2_char, ABS(temp1_char - temp2_char));
879                     }
880                     nfound++;
881                 }
882                 else if (per > opts->percent) {
883                     if (print_data(opts)) {
884                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
885                         parallel_print(SPACES);
886                         parallel_print(I_FORMAT_P, temp1_char, temp2_char, ABS(temp1_char - temp2_char), per);
887                     }
888                     nfound++;
889                 }
890             }
891             /* -d and -p */
892             else if (opts->d && opts->p) {
893                 PER(temp1_char, temp2_char);
894 
895                 if (not_comparable && !both_zero) {
896                     if (print_data(opts)) {
897                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
898                         parallel_print(SPACES);
899                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_char, temp2_char, ABS(temp1_char - temp2_char));
900                     }
901                     nfound++;
902                 }
903                 else if (per > opts->percent && ABS(temp1_char - temp2_char) > opts->delta) {
904                     if (print_data(opts)) {
905                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
906                         parallel_print(SPACES);
907                         parallel_print(I_FORMAT_P, temp1_char, temp2_char, ABS(temp1_char - temp2_char), per);
908                     }
909                     nfound++;
910                 }
911             }
912             else if (temp1_char != temp2_char) {
913                 if (print_data(opts)) {
914                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
915                     parallel_print(SPACES);
916                     parallel_print(I_FORMAT, temp1_char, temp2_char, ABS(temp1_char - temp2_char));
917                 }
918                 nfound++;
919             }
920         } /*H5T_NATIVE_SCHAR*/
921 
922         /*-------------------------------------------------------------------------
923          * H5T_NATIVE_UCHAR
924          *-------------------------------------------------------------------------
925          */
926         else if (type_size == 1 && type_sign == H5T_SGN_NONE) {
927             unsigned char temp1_uchar;
928             unsigned char temp2_uchar;
929 
930             if(type_size != sizeof(unsigned char))
931                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not unsigned char size");
932 
933             HDmemcpy(&temp1_uchar, mem1, sizeof(unsigned char));
934             HDmemcpy(&temp2_uchar, mem2, sizeof(unsigned char));
935             /* -d and !-p */
936             if (opts->d && !opts->p) {
937                 if (PDIFF(temp1_uchar, temp2_uchar) > opts->delta) {
938                     if (print_data(opts)) {
939                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
940                         parallel_print(SPACES);
941                         parallel_print(I_FORMAT, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
942                     }
943                     nfound++;
944                 }
945             }
946             /* !-d and -p */
947             else if (!opts->d && opts->p) {
948                 PER_UNSIGN(signed char, temp1_uchar, temp2_uchar);
949 
950                 if (not_comparable && !both_zero) {
951                     if (print_data(opts)) {
952                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
953                         parallel_print(SPACES);
954                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
955                     }
956                     nfound++;
957                 }
958                 else if (per > opts->percent) {
959                     if (print_data(opts)) {
960                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
961                         parallel_print(SPACES);
962                         parallel_print(I_FORMAT_P, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar), per);
963                     }
964                     nfound++;
965                 }
966             }
967             /* -d and -p */
968             else if (opts->d && opts->p) {
969                 PER_UNSIGN(signed char, temp1_uchar, temp2_uchar);
970 
971                 if (not_comparable && !both_zero) {
972                     if (print_data(opts)) {
973                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
974                         parallel_print(SPACES);
975                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
976                     }
977                     nfound++;
978                 }
979                 else if (per > opts->percent && PDIFF(temp1_uchar, temp2_uchar) > opts->delta) {
980                     if (print_data(opts)) {
981                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
982                         parallel_print(SPACES);
983                         parallel_print(I_FORMAT_P, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar), per);
984                     }
985                     nfound++;
986                 }
987             }
988             else if (temp1_uchar != temp2_uchar) {
989                 if (print_data(opts)) {
990                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
991                     parallel_print(SPACES);
992                     parallel_print(I_FORMAT, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
993                 }
994                 nfound++;
995             }
996         } /*H5T_NATIVE_UCHAR*/
997 
998         /*-------------------------------------------------------------------------
999          * H5T_NATIVE_SHORT
1000          *-------------------------------------------------------------------------
1001          */
1002         else if (type_size == 2 && type_sign != H5T_SGN_NONE) {
1003             short temp1_short;
1004             short temp2_short;
1005 
1006             if(type_size != sizeof(short))
1007                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not short size");
1008 
1009             HDmemcpy(&temp1_short, mem1, sizeof(short));
1010             HDmemcpy(&temp2_short, mem2, sizeof(short));
1011             /* -d and !-p */
1012             if (opts->d && !opts->p) {
1013                 if (ABS(temp1_short - temp2_short) > opts->delta) {
1014                     if (print_data(opts)) {
1015                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1016                         parallel_print(SPACES);
1017                         parallel_print(I_FORMAT, temp1_short, temp2_short, ABS(temp1_short - temp2_short));
1018                     }
1019                     nfound++;
1020                 }
1021             }
1022             /* !-d and -p */
1023             else if (!opts->d && opts->p) {
1024                 PER(temp1_short, temp2_short);
1025 
1026                 if (not_comparable && !both_zero) {
1027                     if (print_data(opts)) {
1028                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1029                         parallel_print(SPACES);
1030                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_short, temp2_short, ABS(temp1_short - temp2_short));
1031                     }
1032                     nfound++;
1033                 }
1034                 else if (per > opts->percent) {
1035                     if (print_data(opts)) {
1036                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1037                         parallel_print(SPACES);
1038                         parallel_print(I_FORMAT_P, temp1_short, temp2_short, ABS(temp1_short - temp2_short), per);
1039                     }
1040                     nfound++;
1041                 }
1042             }
1043             /* -d and -p */
1044             else if (opts->d && opts->p) {
1045                 PER(temp1_short, temp2_short);
1046 
1047                 if (not_comparable && !both_zero) {
1048                     if (print_data(opts)) {
1049                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1050                         parallel_print(SPACES);
1051                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_short, temp2_short, ABS(temp1_short - temp2_short));
1052                     }
1053                     nfound++;
1054                 }
1055                 else if (per > opts->percent && ABS(temp1_short - temp2_short) > opts->delta) {
1056                     if (print_data(opts)) {
1057                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1058                         parallel_print(SPACES);
1059                         parallel_print(I_FORMAT_P, temp1_short, temp2_short, ABS(temp1_short - temp2_short), per);
1060                     }
1061                     nfound++;
1062                 }
1063             }
1064             else if (temp1_short != temp2_short) {
1065                 if (print_data(opts)) {
1066                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1067                     parallel_print(SPACES);
1068                     parallel_print(I_FORMAT, temp1_short, temp2_short, ABS(temp1_short - temp2_short));
1069                 }
1070                 nfound++;
1071             }
1072         } /*H5T_NATIVE_SHORT*/
1073 
1074         /*-------------------------------------------------------------------------
1075          * H5T_NATIVE_USHORT
1076          *-------------------------------------------------------------------------
1077          */
1078         else if (type_size == 2 && type_sign == H5T_SGN_NONE) {
1079             unsigned short temp1_ushort;
1080             unsigned short temp2_ushort;
1081 
1082             if(type_size != sizeof(unsigned short))
1083                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not unsigned short size");
1084 
1085             HDmemcpy(&temp1_ushort, mem1, sizeof(unsigned short));
1086             HDmemcpy(&temp2_ushort, mem2, sizeof(unsigned short));
1087             /* -d and !-p */
1088             if (opts->d && !opts->p) {
1089                 if (PDIFF(temp1_ushort, temp2_ushort) > opts->delta) {
1090                     if (print_data(opts)) {
1091                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1092                         parallel_print(SPACES);
1093                         parallel_print(I_FORMAT, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort));
1094                     }
1095                     nfound++;
1096                 }
1097             }
1098             /* !-d and -p */
1099             else if (!opts->d && opts->p) {
1100                 PER_UNSIGN(signed short, temp1_ushort, temp2_ushort);
1101 
1102                 if (not_comparable && !both_zero) {
1103                     if (print_data(opts)) {
1104                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1105                         parallel_print(SPACES);
1106                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort));
1107                     }
1108                     nfound++;
1109                 }
1110                 else if (per > opts->percent) {
1111                     if (print_data(opts)) {
1112                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1113                         parallel_print(SPACES);
1114                         parallel_print(I_FORMAT_P, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort), per);
1115                     }
1116                     nfound++;
1117                 }
1118             }
1119             /* -d and -p */
1120             else if (opts->d && opts->p) {
1121                 PER_UNSIGN(signed short, temp1_ushort, temp2_ushort);
1122 
1123                 if (not_comparable && !both_zero) {
1124                     if (print_data(opts)) {
1125                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1126                         parallel_print(SPACES);
1127                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort));
1128                     }
1129                     nfound++;
1130                 }
1131                 else if (per > opts->percent && PDIFF(temp1_ushort, temp2_ushort) > opts->delta) {
1132                     if (print_data(opts)) {
1133                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1134                         parallel_print(SPACES);
1135                         parallel_print(I_FORMAT_P, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort), per);
1136                     }
1137                     nfound++;
1138                 }
1139             }
1140             else if (temp1_ushort != temp2_ushort) {
1141                 if (print_data(opts)) {
1142                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1143                     parallel_print(SPACES);
1144                     parallel_print(I_FORMAT, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort));
1145                 }
1146                 nfound++;
1147             }
1148         } /*H5T_NATIVE_USHORT*/
1149 
1150         /*-------------------------------------------------------------------------
1151          * H5T_NATIVE_INT
1152          *-------------------------------------------------------------------------
1153          */
1154         else if (type_size == 4 && type_sign != H5T_SGN_NONE) {
1155             int temp1_int;
1156             int temp2_int;
1157 
1158             if(type_size != sizeof(int))
1159                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not int size");
1160 
1161             HDmemcpy(&temp1_int, mem1, sizeof(int));
1162             HDmemcpy(&temp2_int, mem2, sizeof(int));
1163             /* -d and !-p */
1164             if (opts->d && !opts->p) {
1165                 if (ABS(temp1_int-temp2_int) > opts->delta) {
1166                     if (print_data(opts)) {
1167                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1168                         parallel_print(SPACES);
1169                         parallel_print(I_FORMAT, temp1_int, temp2_int, ABS(temp1_int - temp2_int));
1170                     }
1171                     nfound++;
1172                 }
1173             }
1174             /* !-d and -p */
1175             else if (!opts->d && opts->p) {
1176                 PER(temp1_int, temp2_int);
1177 
1178                 if (not_comparable && !both_zero) {
1179                     if (print_data(opts)) {
1180                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1181                         parallel_print(SPACES);
1182                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_int, temp2_int, ABS(temp1_int - temp2_int));
1183                     }
1184                     nfound++;
1185                 }
1186                 else if (per > opts->percent) {
1187                     if (print_data(opts)) {
1188                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1189                         parallel_print(SPACES);
1190                         parallel_print(I_FORMAT_P, temp1_int, temp2_int, ABS(temp1_int - temp2_int), per);
1191                     }
1192                     nfound++;
1193                 }
1194             }
1195             /* -d and -p */
1196             else if (opts->d && opts->p) {
1197                 PER(temp1_int, temp2_int);
1198 
1199                 if (not_comparable && !both_zero) {
1200                     if (print_data(opts)) {
1201                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1202                         parallel_print(SPACES);
1203                         parallel_print(I_FORMAT_P_NOTCOMP, temp1_int, temp2_int, ABS(temp1_int - temp2_int));
1204                     }
1205                     nfound++;
1206                 }
1207                 else if (per > opts->percent && ABS(temp1_int - temp2_int) > opts->delta) {
1208                     if (print_data(opts)) {
1209                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1210                         parallel_print(SPACES);
1211                         parallel_print(I_FORMAT_P, temp1_int, temp2_int, ABS(temp1_int - temp2_int), per);
1212                     }
1213                     nfound++;
1214                 }
1215             }
1216             else if (temp1_int != temp2_int) {
1217                 if (print_data(opts)) {
1218                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1219                     parallel_print(SPACES);
1220                     parallel_print(I_FORMAT, temp1_int, temp2_int, ABS(temp1_int - temp2_int));
1221                 }
1222                 nfound++;
1223             }
1224         } /*H5T_NATIVE_INT*/
1225 
1226         /*-------------------------------------------------------------------------
1227          * H5T_NATIVE_UINT
1228          *-------------------------------------------------------------------------
1229          */
1230         else if (type_size == 4 && type_sign == H5T_SGN_NONE) {
1231             unsigned int temp1_uint;
1232             unsigned int temp2_uint;
1233 
1234             if(type_size != sizeof(unsigned int))
1235                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not unsigned int size");
1236 
1237             HDmemcpy(&temp1_uint, mem1, sizeof(unsigned int));
1238             HDmemcpy(&temp2_uint, mem2, sizeof(unsigned int));
1239             /* -d and !-p */
1240             if (opts->d && !opts->p) {
1241                 if (PDIFF(temp1_uint, temp2_uint) > opts->delta) {
1242                     if (print_data(opts)) {
1243                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1244                         parallel_print(SPACES);
1245                         parallel_print(UI_FORMAT, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint));
1246                     }
1247                     nfound++;
1248                 }
1249             }
1250             /* !-d and -p */
1251             else if (!opts->d && opts->p) {
1252                 PER_UNSIGN(signed int, temp1_uint, temp2_uint);
1253 
1254                 if (not_comparable && !both_zero) {
1255                     if (print_data(opts)) {
1256                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1257                         parallel_print(SPACES);
1258                         parallel_print(UI_FORMAT_P_NOTCOMP, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint));
1259                     }
1260                     nfound++;
1261                 }
1262                 else if (per > opts->percent) {
1263                     if (print_data(opts)) {
1264                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1265                         parallel_print(SPACES);
1266                         parallel_print(UI_FORMAT_P, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint), per);
1267                     }
1268                     nfound++;
1269                 }
1270             }
1271             /* -d and -p */
1272             else if (opts->d && opts->p) {
1273                 PER_UNSIGN(signed int, temp1_uint, temp2_uint);
1274 
1275                 if (not_comparable && !both_zero) {
1276                     if (print_data(opts)) {
1277                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1278                         parallel_print(SPACES);
1279                         parallel_print(UI_FORMAT_P_NOTCOMP, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint));
1280                     }
1281                     nfound++;
1282                 }
1283                 else if (per > opts->percent && PDIFF(temp1_uint,temp2_uint) > opts->delta) {
1284                     if (print_data(opts)) {
1285                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1286                         parallel_print(SPACES);
1287                         parallel_print(UI_FORMAT_P, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint), per);
1288                     }
1289                     nfound++;
1290                 }
1291             }
1292             else if (temp1_uint != temp2_uint) {
1293                 if (print_data(opts)) {
1294                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1295                     parallel_print(SPACES);
1296                     parallel_print(UI_FORMAT, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint));
1297                 }
1298                 nfound++;
1299             }
1300         } /*H5T_NATIVE_UINT*/
1301 
1302         /*-------------------------------------------------------------------------
1303          * H5T_NATIVE_LONG
1304          *-------------------------------------------------------------------------
1305          */
1306         else if (type_size == 8 && type_sign != H5T_SGN_NONE) {
1307             long temp1_long;
1308             long temp2_long;
1309 
1310             if(type_size != sizeof(long))
1311                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not long size");
1312 
1313             HDmemcpy(&temp1_long, mem1, sizeof(long));
1314             HDmemcpy(&temp2_long, mem2, sizeof(long));
1315             /* -d and !-p */
1316             if (opts->d && !opts->p) {
1317                 if (ABS(temp1_long-temp2_long) > opts->delta) {
1318                     if (print_data(opts)) {
1319                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1320                         parallel_print(SPACES);
1321                         parallel_print(LI_FORMAT, temp1_long, temp2_long, ABS(temp1_long - temp2_long));
1322                     }
1323                     nfound++;
1324                 }
1325             }
1326             /* !-d and -p */
1327             else if (!opts->d && opts->p) {
1328                 PER(temp1_long, temp2_long);
1329 
1330                 if (not_comparable && !both_zero) {
1331                     if (print_data(opts)) {
1332                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1333                         parallel_print(SPACES);
1334                         parallel_print(LI_FORMAT_P_NOTCOMP, temp1_long, temp2_long, ABS(temp1_long - temp2_long));
1335                     }
1336                     nfound++;
1337                 }
1338                 else if (per > opts->percent) {
1339                     if (print_data(opts)) {
1340                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1341                         parallel_print(SPACES);
1342                         parallel_print(LI_FORMAT_P, temp1_long, temp2_long, ABS(temp1_long - temp2_long), per);
1343                     }
1344                     nfound++;
1345                 }
1346             }
1347             /* -d and -p */
1348             else if (opts->d && opts->p) {
1349                 PER(temp1_long, temp2_long);
1350 
1351                 if (not_comparable && !both_zero) {
1352                     if (print_data(opts)) {
1353                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1354                         parallel_print(SPACES);
1355                         parallel_print(LI_FORMAT_P_NOTCOMP, temp1_long, temp2_long, ABS(temp1_long - temp2_long));
1356                     }
1357                     nfound++;
1358                 }
1359                 else if (per > opts->percent && ABS(temp1_long-temp2_long) > opts->delta) {
1360                     if (print_data(opts)) {
1361                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1362                         parallel_print(SPACES);
1363                         parallel_print(LI_FORMAT_P, temp1_long, temp2_long, ABS(temp1_long - temp2_long), per);
1364                     }
1365                     nfound++;
1366                 }
1367             }
1368             else if (temp1_long != temp2_long) {
1369                 if (print_data(opts)) {
1370                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1371                     parallel_print(SPACES);
1372                     parallel_print(LI_FORMAT, temp1_long, temp2_long, ABS(temp1_long - temp2_long));
1373                 }
1374                 nfound++;
1375             }
1376         } /*H5T_NATIVE_LONG*/
1377 
1378         /*-------------------------------------------------------------------------
1379          * H5T_NATIVE_ULONG
1380          *-------------------------------------------------------------------------
1381          */
1382         else if (type_size == 8 && type_sign == H5T_SGN_NONE) {
1383             unsigned long temp1_ulong;
1384             unsigned long temp2_ulong;
1385 
1386             if(type_size != sizeof(unsigned long))
1387                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not unsigned long size");
1388 
1389             HDmemcpy(&temp1_ulong, mem1, sizeof(unsigned long));
1390             HDmemcpy(&temp2_ulong, mem2, sizeof(unsigned long));
1391             /* -d and !-p */
1392             if (opts->d && !opts->p) {
1393                 if (PDIFF(temp1_ulong, temp2_ulong) > opts->delta) {
1394                     if (print_data(opts)) {
1395                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1396                         parallel_print(SPACES);
1397                         parallel_print(ULI_FORMAT, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong));
1398                     }
1399                     nfound++;
1400                 }
1401             }
1402             /* !-d and -p */
1403             else if (!opts->d && opts->p) {
1404                 PER_UNSIGN(signed long, temp1_ulong, temp2_ulong);
1405 
1406                 if (not_comparable && !both_zero) {
1407                     if (print_data(opts)) {
1408                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1409                         parallel_print(SPACES);
1410                         parallel_print(ULI_FORMAT_P_NOTCOMP, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong));
1411                     }
1412                     nfound++;
1413                 }
1414                 else if (per > opts->percent) {
1415                     if (print_data(opts)) {
1416                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1417                         parallel_print(SPACES);
1418                         parallel_print(ULI_FORMAT_P, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong), per);
1419                     }
1420                     nfound++;
1421                 }
1422             }
1423             /* -d and -p */
1424             else if (opts->d && opts->p) {
1425                 PER_UNSIGN(signed long, temp1_ulong, temp2_ulong);
1426 
1427                 if (not_comparable && !both_zero) {
1428                     if (print_data(opts)) {
1429                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1430                         parallel_print(SPACES);
1431                         parallel_print(ULI_FORMAT_P_NOTCOMP, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong));
1432                     }
1433                     nfound++;
1434                 }
1435                 else if (per > opts->percent && PDIFF(temp1_ulong,temp2_ulong) > opts->delta) {
1436                     if (print_data(opts)) {
1437                         print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1438                         parallel_print(SPACES);
1439                         parallel_print(ULI_FORMAT_P, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong), per);
1440                     }
1441                     nfound++;
1442                 }
1443             }
1444             else if (temp1_ulong != temp2_ulong) {
1445                 if (print_data(opts)) {
1446                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1447                     parallel_print(SPACES);
1448                     parallel_print(ULI_FORMAT, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong));
1449                 }
1450                 nfound++;
1451             }
1452         } /*H5T_NATIVE_ULONG*/
1453         break; /* H5T_INTEGER class */
1454 
1455     /*-------------------------------------------------------------------------
1456      * H5T_FLOAT
1457      *-------------------------------------------------------------------------
1458      */
1459     case H5T_FLOAT:
1460         /*-------------------------------------------------------------------------
1461          * H5T_NATIVE_FLOAT
1462          *-------------------------------------------------------------------------
1463          */
1464         if (type_size == 4) {
1465             float temp1_float;
1466             float temp2_float;
1467             hbool_t isnan1 = FALSE;
1468             hbool_t isnan2 = FALSE;
1469 
1470             if(type_size != sizeof(float))
1471                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not float size");
1472 
1473             HDmemcpy(&temp1_float, mem1, sizeof(float));
1474             HDmemcpy(&temp2_float, mem2, sizeof(float));
1475 
1476             /* logic for detecting NaNs is different with opts -d, -p and no opts */
1477 
1478             /*-------------------------------------------------------------------------
1479              * -d and !-p
1480              *-------------------------------------------------------------------------
1481              */
1482             if (opts->d && !opts->p) {
1483                 /*-------------------------------------------------------------------------
1484                  * detect NaNs
1485                  *-------------------------------------------------------------------------
1486                  */
1487                 if (opts->do_nans) {
1488                     isnan1 = my_isnan(FLT_FLOAT, &temp1_float);
1489                     isnan2 = my_isnan(FLT_FLOAT, &temp2_float);
1490                 }
1491 
1492                 /* both not NaN, do the comparison */
1493                 if (!isnan1 && !isnan2) {
1494                     if (ABS(temp1_float-temp2_float) > (float) opts->delta) {
1495                         if (print_data(opts)) {
1496                             print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1497                             parallel_print(SPACES);
1498                             parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
1499                         }
1500                         nfound++;
1501                     }
1502                 }
1503                 /* only one is NaN, assume difference */
1504                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1505                     if (print_data(opts)) {
1506                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1507                         parallel_print(SPACES);
1508                         parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
1509                     }
1510                     nfound++;
1511                 }
1512             }
1513             /*-------------------------------------------------------------------------
1514              * !-d and -p
1515              *-------------------------------------------------------------------------
1516              */
1517             else if (!opts->d && opts->p) {
1518                 /*-------------------------------------------------------------------------
1519                  * detect NaNs
1520                  *-------------------------------------------------------------------------
1521                  */
1522                 if (opts->do_nans) {
1523                     isnan1 = my_isnan(FLT_FLOAT, &temp1_float);
1524                     isnan2 = my_isnan(FLT_FLOAT, &temp2_float);
1525                 }
1526 
1527                 /* both not NaN, do the comparison */
1528                 if (!isnan1 && !isnan2) {
1529                     PER(temp1_float, temp2_float);
1530 
1531                     if (not_comparable && !both_zero) {
1532                         if (print_data(opts)) {
1533                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1534                             parallel_print(SPACES);
1535                             parallel_print(F_FORMAT_P_NOTCOMP, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
1536                         }
1537                         nfound++;
1538                     }
1539                     else if (per > opts->percent && (double) ABS(temp1_float - temp2_float) > opts->delta) {
1540                         if (print_data(opts)) {
1541                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1542                             parallel_print(SPACES);
1543                             parallel_print(F_FORMAT_P, (double) temp1_float, (double) temp2_float,
1544                                     (double) ABS(temp1_float - temp2_float), (double) ABS(1 - temp2_float / temp1_float));
1545                         }
1546                         nfound++;
1547                     }
1548                 }
1549                 /* only one is NaN, assume difference */
1550                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1551                     if (print_data(opts)) {
1552                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1553                         parallel_print(SPACES);
1554                         parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
1555                     }
1556                     nfound++;
1557                 }
1558             }
1559             /*-------------------------------------------------------------------------
1560              * -d and -p
1561              *-------------------------------------------------------------------------
1562              */
1563             else if (opts->d && opts->p) {
1564                 /*-------------------------------------------------------------------------
1565                  * detect NaNs
1566                  *-------------------------------------------------------------------------
1567                  */
1568                 if (opts->do_nans) {
1569                     isnan1 = my_isnan(FLT_FLOAT, &temp1_float);
1570                     isnan2 = my_isnan(FLT_FLOAT, &temp2_float);
1571                 }
1572 
1573                 /* both not NaN, do the comparison */
1574                 if (!isnan1 && !isnan2) {
1575                     PER(temp1_float, temp2_float);
1576 
1577                     if (not_comparable && !both_zero) {
1578                         if (print_data(opts)) {
1579                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1580                             parallel_print(SPACES);
1581                             parallel_print(F_FORMAT_P_NOTCOMP, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
1582                         }
1583                         nfound++;
1584                     }
1585                     else if (per > opts->percent) {
1586                         if (print_data(opts)) {
1587                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1588                             parallel_print(SPACES);
1589                             parallel_print(F_FORMAT_P, (double) temp1_float, (double) temp2_float,
1590                                     (double) ABS(temp1_float - temp2_float), (double) ABS(1 - temp2_float / temp1_float));
1591                         }
1592                         nfound++;
1593                     }
1594                 }
1595                 /* only one is NaN, assume difference */
1596                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1597                     if (print_data(opts)) {
1598                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1599                         parallel_print(SPACES);
1600                         parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
1601                     }
1602                     nfound++;
1603                 }
1604             }
1605             /*-------------------------------------------------------------------------
1606              * no -d and -p
1607              *-------------------------------------------------------------------------
1608              */
1609             else if (equal_float(temp1_float, temp2_float, opts) == FALSE) {
1610                 if (print_data(opts)) {
1611                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1612                     parallel_print(SPACES);
1613                     parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
1614                 }
1615                 nfound++;
1616             }
1617         } /*H5T_NATIVE_FLOAT*/
1618 
1619         /*-------------------------------------------------------------------------
1620          * H5T_NATIVE_DOUBLE
1621          *-------------------------------------------------------------------------
1622          */
1623         else if (type_size == 8) {
1624             double temp1_double;
1625             double temp2_double;
1626             hbool_t isnan1 = FALSE;
1627             hbool_t isnan2 = FALSE;
1628 
1629             if(type_size != sizeof(double))
1630                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not double size");
1631 
1632             HDmemcpy(&temp1_double, mem1, sizeof(double));
1633             HDmemcpy(&temp2_double, mem2, sizeof(double));
1634 
1635             /* logic for detecting NaNs is different with opts -d, -p and no opts */
1636             /*-------------------------------------------------------------------------
1637              * -d and !-p
1638              *-------------------------------------------------------------------------
1639              */
1640             if (opts->d && !opts->p) {
1641                 /*-------------------------------------------------------------------------
1642                  * detect NaNs
1643                  *-------------------------------------------------------------------------
1644                  */
1645                 if (opts->do_nans) {
1646                     isnan1 = my_isnan(FLT_DOUBLE, &temp1_double);
1647                     isnan2 = my_isnan(FLT_DOUBLE, &temp2_double);
1648                 }
1649 
1650                 /* both not NaN, do the comparison */
1651                 if (!isnan1 && !isnan2) {
1652                     if (ABS(temp1_double-temp2_double) > opts->delta) {
1653                         if (print_data(opts)) {
1654                             print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1655                             parallel_print(SPACES);
1656                             parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1657                         }
1658                         nfound++;
1659                     }
1660                 }
1661                 /* only one is NaN, assume difference */
1662                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1663                     if (print_data(opts)) {
1664                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1665                         parallel_print(SPACES);
1666                         parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1667                     }
1668                     nfound++;
1669                 }
1670             } /* opts->d && !opts->p */
1671             /*-------------------------------------------------------------------------
1672              * !-d and -p
1673              *-------------------------------------------------------------------------
1674              */
1675             else if (!opts->d && opts->p) {
1676                 /*-------------------------------------------------------------------------
1677                  * detect NaNs
1678                  *-------------------------------------------------------------------------
1679                  */
1680                 if (opts->do_nans) {
1681                     isnan1 = my_isnan(FLT_DOUBLE, &temp1_double);
1682                     isnan2 = my_isnan(FLT_DOUBLE, &temp2_double);
1683                 }
1684 
1685                 /* both not NaN, do the comparison */
1686                 if (!isnan1 && !isnan2) {
1687                     PER(temp1_double, temp2_double);
1688 
1689                     if (not_comparable && !both_zero) {
1690                         if (print_data(opts)) {
1691                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1692                             parallel_print(SPACES);
1693                             parallel_print(F_FORMAT_P_NOTCOMP, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1694                         }
1695                         nfound++;
1696                     }
1697                     else if (per > opts->percent) {
1698                         if (print_data(opts)) {
1699                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1700                             parallel_print(SPACES);
1701                             parallel_print(F_FORMAT_P, temp1_double, temp2_double, ABS(temp1_double - temp2_double), ABS(1 - temp2_double / temp1_double));
1702                         }
1703                         nfound++;
1704                     }
1705                 }
1706                 /* only one is NaN, assume difference */
1707                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1708                     if (print_data(opts)) {
1709                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1710                         parallel_print(SPACES);
1711                         parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1712                     }
1713                     nfound++;
1714                 }
1715             }
1716             /*-------------------------------------------------------------------------
1717              * -d and -p
1718              *-------------------------------------------------------------------------
1719              */
1720             else if (opts->d && opts->p) {
1721                 /*-------------------------------------------------------------------------
1722                 * detect NaNs
1723                 *-------------------------------------------------------------------------
1724                 */
1725                 if (opts->do_nans) {
1726                     isnan1 = my_isnan(FLT_DOUBLE, &temp1_double);
1727                     isnan2 = my_isnan(FLT_DOUBLE, &temp2_double);
1728                 }
1729 
1730                 /* both not NaN, do the comparison */
1731                 if (!isnan1 && !isnan2) {
1732                     PER(temp1_double, temp2_double);
1733 
1734                     if (not_comparable && !both_zero) {
1735                         if (print_data(opts)) {
1736                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1737                             parallel_print(SPACES);
1738                             parallel_print(F_FORMAT_P_NOTCOMP, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1739                         }
1740                         nfound++;
1741                     }
1742                     else if (per > opts->percent &&
1743                     ABS(temp1_double-temp2_double) > opts->delta) {
1744                         if (print_data(opts)) {
1745                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1746                             parallel_print(SPACES);
1747                             parallel_print(F_FORMAT_P, temp1_double, temp2_double, ABS(temp1_double - temp2_double), ABS(1 - temp2_double / temp1_double));
1748                         }
1749                         nfound++;
1750                     }
1751                 }
1752                 /* only one is NaN, assume difference */
1753                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1754                     if (print_data(opts)) {
1755                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1756                         parallel_print(SPACES);
1757                         parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1758                     }
1759                     nfound++;
1760                 }
1761             }
1762             /*-------------------------------------------------------------------------
1763              * no -d and -p
1764              *-------------------------------------------------------------------------
1765              */
1766             else if (equal_double(temp1_double, temp2_double, opts) == FALSE) {
1767                 if (print_data(opts)) {
1768                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1769                     parallel_print(SPACES);
1770                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1771                 }
1772                 nfound++;
1773             }
1774         } /*H5T_NATIVE_DOUBLE*/
1775 
1776 #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
1777 
1778         /*-------------------------------------------------------------------------
1779          * H5T_NATIVE_LDOUBLE
1780          *-------------------------------------------------------------------------
1781          */
1782         else if (type_size == H5_SIZEOF_LONG_DOUBLE) {
1783             long double temp1_double;
1784             long double temp2_double;
1785             hbool_t     isnan1 = FALSE;
1786             hbool_t     isnan2 = FALSE;
1787 
1788             if(type_size != sizeof(long double)) {
1789                 HGOTO_ERROR(1, H5E_tools_min_id_g, "Type size is not long double size");
1790             }
1791 
1792             HDmemcpy(&temp1_double, mem1, sizeof(long double));
1793             HDmemcpy(&temp2_double, mem2, sizeof(long double));
1794 
1795             /* logic for detecting NaNs is different with options -d, -p and no options */
1796 
1797             /*-------------------------------------------------------------------------
1798              * -d and !-p
1799              *-------------------------------------------------------------------------
1800              */
1801             if (opts->d && !opts->p) {
1802                 /*-------------------------------------------------------------------------
1803                  * detect NaNs
1804                  *-------------------------------------------------------------------------
1805                  */
1806                 if (opts->do_nans) {
1807                     isnan1 = my_isnan(FLT_LDOUBLE,&temp1_double);
1808                     isnan2 = my_isnan(FLT_LDOUBLE,&temp2_double);
1809                 }
1810 
1811                 /* both not NaN, do the comparison */
1812                 if (!isnan1 && !isnan2) {
1813                     if (ABS(temp1_double-temp2_double) > opts->delta) {
1814                         if (print_data(opts)) {
1815                             print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1816                             parallel_print(SPACES);
1817                             parallel_print(LD_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1818                         }
1819                         nfound++;
1820                     }
1821                 } /* NaN */
1822                 /* only one is NaN, assume difference */
1823                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1824                     if (print_data(opts)) {
1825                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1826                         parallel_print(SPACES);
1827                         parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1828                     }
1829                     nfound++;
1830                 }
1831             }
1832             /*-------------------------------------------------------------------------
1833              * !-d and -p
1834              *-------------------------------------------------------------------------
1835              */
1836             else if (!opts->d && opts->p) {
1837                 /*-------------------------------------------------------------------------
1838                  * detect NaNs
1839                  *-------------------------------------------------------------------------
1840                  */
1841                 if (opts->do_nans) {
1842                     isnan1 = my_isnan(FLT_LDOUBLE, &temp1_double);
1843                     isnan2 = my_isnan(FLT_LDOUBLE, &temp2_double);
1844                 }
1845 
1846                 /* both not NaN, do the comparison */
1847                 if (!isnan1 && !isnan2) {
1848                     PER(temp1_double,temp2_double);
1849 
1850                     if (not_comparable && !both_zero) {
1851                         if (print_data(opts)) {
1852                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1853                             parallel_print(SPACES);
1854                             parallel_print(LD_FORMAT_P_NOTCOMP, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1855                         }
1856                         nfound++;
1857                     }
1858                     else if (per > opts->percent) {
1859                         if (print_data(opts)) {
1860                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1861                             parallel_print(SPACES);
1862                             parallel_print(LD_FORMAT_P, temp1_double, temp2_double, ABS(temp1_double - temp2_double), ABS(1 - temp2_double / temp1_double));
1863                         }
1864                         nfound++;
1865                     }
1866                 } /* NaN */
1867                 /* only one is NaN, assume difference */
1868                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1869                     if (print_data(opts)) {
1870                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1871                         parallel_print(SPACES);
1872                         parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1873                     }
1874                     nfound++;
1875                 }
1876             }
1877             /*-------------------------------------------------------------------------
1878              * -d and -p
1879              *-------------------------------------------------------------------------
1880              */
1881             else if (opts->d && opts->p) {
1882                 /*-------------------------------------------------------------------------
1883                  * detect NaNs
1884                  *-------------------------------------------------------------------------
1885                  */
1886                 if (opts->do_nans) {
1887                     isnan1 = my_isnan(FLT_LDOUBLE, &temp1_double);
1888                     isnan2 = my_isnan(FLT_LDOUBLE, &temp2_double);
1889                 }
1890 
1891                 /* both not NaN, do the comparison */
1892                 if (!isnan1 && !isnan2) {
1893                     PER(temp1_double,temp2_double);
1894 
1895                     if (not_comparable && !both_zero) {
1896                         if (print_data(opts)) {
1897                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1898                             parallel_print(SPACES);
1899                             parallel_print(LD_FORMAT_P_NOTCOMP, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1900                         }
1901                         nfound++;
1902                     }
1903                     else if (per > opts->percent && ABS(temp1_double-temp2_double) > opts->delta) {
1904                         if (print_data(opts)) {
1905                             print_pos(ph, 1, index, acc, pos, rank, dims, obj1, obj2);
1906                             parallel_print(SPACES);
1907                             parallel_print(LD_FORMAT_P, temp1_double, temp2_double, ABS(temp1_double - temp2_double), ABS(1 - temp2_double / temp1_double));
1908                         }
1909                         nfound++;
1910                     }
1911                 } /* NaN */
1912                 /* only one is NaN, assume difference */
1913                 else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
1914                     if (print_data(opts)) {
1915                         print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1916                         parallel_print(SPACES);
1917                         parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1918                     }
1919                     nfound++;
1920                 }
1921             }
1922             /*-------------------------------------------------------------------------
1923              * no -d and -p
1924              *-------------------------------------------------------------------------
1925              */
1926             else if (equal_ldouble(temp1_double, temp2_double, opts) == FALSE) {
1927                 if (print_data(opts)) {
1928                     print_pos(ph, 0, index, acc, pos, rank, dims, obj1, obj2);
1929                     parallel_print(SPACES);
1930                     parallel_print(LD_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
1931                 }
1932                 nfound++;
1933             }
1934         } /*H5T_NATIVE_LDOUBLE*/
1935 #endif  /* H5_SIZEOF_LONG_DOUBLE */
1936 
1937         break; /* H5T_FLOAT class */
1938 
1939     } /* switch */
1940 
1941 done:
1942     opts->err_stat = opts->err_stat | ret_value;
1943 
1944     h5diffdebug3("diff_datum finish:%d - errstat:%d\n", nfound, opts->err_stat);
1945 
1946     return nfound;
1947 }
1948 
1949 /*-------------------------------------------------------------------------
1950  * Function: all_zero
1951  *
1952  * Purpose: Determines if memory is initialized to all zero bytes.
1953  *
1954  * Return: TRUE if all bytes are zero; FALSE otherwise
1955  *-------------------------------------------------------------------------
1956  */
1957 
all_zero(const void * _mem,size_t size)1958 static hbool_t all_zero(const void *_mem, size_t size) {
1959     const unsigned char *mem = (const unsigned char *) _mem;
1960 
1961     while (size-- > 0)
1962         if (mem[size])
1963             return FALSE;
1964 
1965     return TRUE;
1966 }
1967 
1968 /*-------------------------------------------------------------------------
1969  * Function: print_region_block
1970  *
1971  * Purpose: print start coordinates and opposite corner of a region block
1972  *
1973  * Return: void
1974  *-------------------------------------------------------------------------
1975  */
1976 
1977 static
print_region_block(int i,hsize_t * ptdata,int ndims)1978 void print_region_block(int i, hsize_t *ptdata, int ndims) {
1979     int j;
1980 
1981     parallel_print("        ");
1982     for (j = 0; j < ndims; j++)
1983         parallel_print("%s%lu", j ? "," : "   (", (unsigned long) ptdata[i * 2 * ndims + j]);
1984     for (j = 0; j < ndims; j++)
1985         parallel_print("%s%lu", j ? "," : ")-(", (unsigned long) ptdata[i * 2 * ndims + j + ndims]);
1986     parallel_print(")");
1987 
1988 }
1989 
1990 /*-------------------------------------------------------------------------
1991  * Function: print_points
1992  *
1993  * Purpose: print points of a region reference
1994  *
1995  * Return: void
1996  *-------------------------------------------------------------------------
1997  */
1998 
1999 static
print_points(int i,hsize_t * ptdata,int ndims)2000 void print_points(int i, hsize_t *ptdata, int ndims) {
2001     int j;
2002 
2003     parallel_print("              ");
2004     for (j = 0; j < ndims; j++)
2005         parallel_print("%s%lu", j ? "," : "(", (unsigned long) (ptdata[i * ndims + j]));
2006     parallel_print(")");
2007 
2008 }
2009 
2010 /*-------------------------------------------------------------------------
2011  * Function: diff_region
2012  *
2013  * Purpose: diff a dataspace region
2014  *
2015  * Return: number of differences
2016  *-------------------------------------------------------------------------
2017  */
2018 
diff_region(hid_t obj1_id,hid_t obj2_id,hid_t region1_id,hid_t region2_id,diff_opt_t * opts)2019 static hsize_t diff_region(hid_t obj1_id, hid_t obj2_id, hid_t region1_id, hid_t region2_id, diff_opt_t *opts)
2020 
2021 {
2022     hsize_t  ret_value = 0;
2023     hssize_t nblocks1, npoints1;
2024     hssize_t nblocks2, npoints2;
2025     hsize_t  alloc_size;
2026     hsize_t *ptdata1 = NULL;
2027     hsize_t *ptdata2 = NULL;
2028     int      ndims1;
2029     int      ndims2;
2030     int      i, j;
2031     hsize_t  nfound_b = 0; /* block differences found */
2032     hsize_t  nfound_p = 0; /* point differences found */
2033 
2034     ndims1 = H5Sget_simple_extent_ndims(region1_id);
2035     ndims2 = H5Sget_simple_extent_ndims(region2_id);
2036 
2037     /*
2038      * These two functions fail if the region does not have blocks or points,
2039      * respectively. They do not currently know how to translate from one to
2040      * the other.
2041      */
2042     H5E_BEGIN_TRY {
2043         nblocks1 = H5Sget_select_hyper_nblocks(region1_id);
2044         nblocks2 = H5Sget_select_hyper_nblocks(region2_id);
2045 
2046         npoints1 = H5Sget_select_elem_npoints(region1_id);
2047         npoints2 = H5Sget_select_elem_npoints(region2_id);
2048     } H5E_END_TRY;
2049 
2050     if (nblocks1 != nblocks2 || npoints1 != npoints2 || ndims1 != ndims2) {
2051         opts->not_cmp = 1;
2052         HGOTO_DONE (0);
2053     }
2054 
2055     /*-------------------------------------------------------------------------
2056      * compare block information
2057      *-------------------------------------------------------------------------
2058      */
2059     if (nblocks1 > 0) {
2060         HDassert(ndims1 > 0);
2061         alloc_size = (hsize_t) nblocks1 * (unsigned) ndims1 * 2 * sizeof(ptdata1[0]);
2062         HDassert(alloc_size == (hsize_t)((size_t )alloc_size)); /*check for overflow*/
2063 
2064         if((ptdata1 = (hsize_t *) HDmalloc((size_t )alloc_size)) == NULL) {
2065             opts->err_stat = 1;
2066             H5TOOLS_INFO(H5E_tools_min_id_g, "Buffer allocation failed");
2067         }
2068         else {
2069             H5_CHECK_OVERFLOW(nblocks1, hssize_t, hsize_t);
2070             H5Sget_select_hyper_blocklist(region1_id, (hsize_t) 0, (hsize_t) nblocks1, ptdata1);
2071 
2072             if((ptdata2 = (hsize_t *) HDmalloc((size_t )alloc_size)) == NULL) {
2073                 opts->err_stat = 1;
2074                 H5TOOLS_INFO(H5E_tools_min_id_g, "Buffer allocation failed");
2075             }
2076             else {
2077                 H5_CHECK_OVERFLOW(nblocks2, hssize_t, hsize_t);
2078                 H5Sget_select_hyper_blocklist(region2_id, (hsize_t) 0, (hsize_t) nblocks2, ptdata2);
2079 
2080                 for (i = 0; i < nblocks1; i++) {
2081                     /* start coordinates and opposite corner */
2082                     for (j = 0; j < ndims1; j++) {
2083                         hsize_t start1, start2, end1, end2;
2084 
2085                         start1 = ptdata1[i * 2 * ndims1 + j];
2086                         start2 = ptdata2[i * 2 * ndims1 + j];
2087                         end1 = ptdata1[i * 2 * ndims1 + j + ndims1];
2088                         end2 = ptdata2[i * 2 * ndims1 + j + ndims1];
2089                         if (start1 != start2 || end1 != end2)
2090                             nfound_b++;
2091                     }
2092                 }
2093 
2094                 /* print differences if found */
2095                 if (nfound_b && opts->m_verbose) {
2096                     H5O_info_t oi1, oi2;
2097 
2098                     H5Oget_info2(obj1_id, &oi1, H5O_INFO_BASIC);
2099                     H5Oget_info2(obj2_id, &oi2, H5O_INFO_BASIC);
2100 
2101                     parallel_print("Referenced dataset      %lu            %lu\n", (unsigned long) oi1.addr, (unsigned long) oi2.addr);
2102                     parallel_print( "------------------------------------------------------------\n");
2103 
2104                     parallel_print("Region blocks\n");
2105                     for (i = 0; i < nblocks1; i++) {
2106                         parallel_print("block #%d", i);
2107                         print_region_block(i, ptdata1, ndims1);
2108                         print_region_block(i, ptdata2, ndims1);
2109                         parallel_print("\n");
2110                     }
2111                 }
2112                 HDfree(ptdata2);
2113             } /* else ptdata2 */
2114 
2115             HDfree(ptdata1);
2116         } /* else ptdata1 */
2117     }
2118 
2119     /*-------------------------------------------------------------------------
2120      * compare point information
2121      *-------------------------------------------------------------------------
2122      */
2123     if (npoints1 > 0) {
2124         alloc_size = (hsize_t) npoints1 * (unsigned) ndims1 * sizeof(ptdata1[0]);
2125         HDassert(alloc_size == (hsize_t)((size_t )alloc_size)); /*check for overflow*/
2126 
2127         if((ptdata1 = (hsize_t *) HDmalloc((size_t )alloc_size)) == NULL) {
2128             opts->err_stat = 1;
2129             H5TOOLS_INFO(H5E_tools_min_id_g, "Buffer allocation failed");
2130         }
2131         else {
2132             H5_CHECK_OVERFLOW(npoints1, hssize_t, hsize_t);
2133             H5Sget_select_elem_pointlist(region1_id, (hsize_t) 0, (hsize_t) npoints1, ptdata1);
2134 
2135             if((ptdata2 = (hsize_t *) HDmalloc((size_t )alloc_size)) == NULL) {
2136                 opts->err_stat = 1;
2137                 H5TOOLS_INFO(H5E_tools_min_id_g, "Buffer allocation failed");
2138             }
2139             else {
2140                 H5_CHECK_OVERFLOW(npoints1, hssize_t, hsize_t);
2141                 H5Sget_select_elem_pointlist(region2_id, (hsize_t) 0, (hsize_t) npoints2, ptdata2);
2142 
2143                 for (i = 0; i < npoints1; i++) {
2144                     hsize_t pt1, pt2;
2145 
2146                     for (j = 0; j < ndims1; j++) {
2147                         pt1 = ptdata1[i * ndims1 + j];
2148                         pt2 = ptdata2[i * ndims1 + j];
2149                         if (pt1 != pt2)
2150                             nfound_p++;
2151                     }
2152                 }
2153 
2154                 if (nfound_p && opts->m_verbose) {
2155                     parallel_print("Region points\n");
2156                     for (i = 0; i < npoints1; i++) {
2157                         hsize_t pt1, pt2;
2158                         int diff_data = 0;
2159 
2160                         for (j = 0; j < ndims1; j++) {
2161                             pt1 = ptdata1[i * ndims1 + j];
2162                             pt2 = ptdata2[i * ndims1 + j];
2163                             if (pt1 != pt2) {
2164                                 diff_data = 1;
2165                                 break;
2166                             }
2167                         }
2168                         if (diff_data) {
2169                             parallel_print("point #%d", i);
2170                             print_points(i, ptdata1, ndims1);
2171                             print_points(i, ptdata2, ndims1);
2172                             parallel_print("\n");
2173                         }
2174                     }
2175                 }
2176                 HDfree(ptdata2);
2177             } /* else ptdata2 */
2178 
2179 #if defined (H5DIFF_DEBUG)
2180             for (i = 0; i < npoints1; i++) {
2181                 parallel_print("%sPt%lu: " , i ? "," : "", (unsigned long)i);
2182 
2183                 for (j = 0; j < ndims1; j++)
2184                     parallel_print("%s%lu", j ? "," : "(", (unsigned long)(ptdata1[i * ndims1 + j]));
2185 
2186                 parallel_print(")");
2187             }
2188 #endif
2189 
2190             HDfree(ptdata1);
2191         } /* else ptdata1 */
2192     }
2193 
2194     nfound_b = nfound_b / (unsigned) ndims1;
2195     nfound_p = nfound_p / (unsigned) ndims1;
2196 
2197     ret_value = nfound_p + nfound_b;
2198 
2199 done:
2200     return ret_value;
2201 }
2202 
2203 /*-------------------------------------------------------------------------
2204  * Function: character_compare
2205  *
2206  * Purpose:  do a byte-by-byte comparison and print in char format
2207  *
2208  * Return:   number of differences found
2209  *-------------------------------------------------------------------------
2210  */
2211 
character_compare(char * mem1,char * mem2,hsize_t i,size_t u,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)2212 static hsize_t character_compare(char *mem1, char *mem2, hsize_t i, size_t u,
2213         int rank, hsize_t *dims, hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1, const char *obj2, int *ph)
2214 {
2215     hsize_t nfound = 0; /* differences found */
2216     char    temp1_uchar;
2217     char    temp2_uchar;
2218 
2219     HDmemcpy(&temp1_uchar, mem1, sizeof(unsigned char));
2220     HDmemcpy(&temp2_uchar, mem2, sizeof(unsigned char));
2221     h5diffdebug3("character_compare start %d=%d\n",temp1_uchar,temp2_uchar);
2222 
2223     if (temp1_uchar != temp2_uchar) {
2224         if (print_data(opts)) {
2225             print_char_pos(ph, 0, i, u, acc, pos, rank, dims, obj1, obj2);
2226             parallel_print("            ");
2227             h5diff_print_char(temp1_uchar);
2228             parallel_print("            ");
2229             h5diff_print_char(temp2_uchar);
2230             parallel_print("\n");
2231         }
2232         nfound++;
2233     }
2234     h5difftrace("character_compare finish\n");
2235 
2236     return nfound;
2237 }
2238 
2239 /*-------------------------------------------------------------------------
2240  * Function: character_compare_opt
2241  *
2242  * Purpose:  do a byte-by-byte comparison and print in numerical format
2243  *
2244  * Return:   number of differences found
2245  *-------------------------------------------------------------------------
2246  */
2247 
character_compare_opt(unsigned char * mem1,unsigned char * mem2,hsize_t i,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)2248 static hsize_t character_compare_opt(unsigned char *mem1, unsigned char *mem2,
2249         hsize_t i, int rank, hsize_t *dims, hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1, const char *obj2, int *ph)
2250 {
2251     hsize_t       nfound = 0; /* differences found */
2252     unsigned char temp1_uchar;
2253     unsigned char temp2_uchar;
2254     double        per;
2255     hbool_t       both_zero;
2256 
2257     HDmemcpy(&temp1_uchar, mem1, sizeof(unsigned char));
2258     HDmemcpy(&temp2_uchar, mem2, sizeof(unsigned char));
2259 
2260     h5difftrace("character_compare_opt start\n");
2261     /* -d and !-p */
2262 
2263     if (opts->d && !opts->p) {
2264         if (PDIFF(temp1_uchar,temp2_uchar) > opts->delta) {
2265             if (print_data(opts)) {
2266                 print_pos(ph, 0, i, acc, pos, rank, dims, obj1, obj2);
2267                 parallel_print(SPACES);
2268                 parallel_print(I_FORMAT, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
2269             }
2270             nfound++;
2271         }
2272     }
2273     /* !-d and -p */
2274     else if (!opts->d && opts->p) {
2275         PER_UNSIGN(signed char, temp1_uchar, temp2_uchar);
2276         if (per > opts->percent) {
2277             if (print_data(opts)) {
2278                 print_pos(ph, 1, i, acc, pos, rank, dims, obj1, obj2);
2279                 parallel_print(SPACES);
2280                 parallel_print(I_FORMAT_P, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar), per);
2281             }
2282             nfound++;
2283         }
2284     }
2285     /* -d and -p */
2286     else if (opts->d && opts->p) {
2287         PER_UNSIGN(signed char, temp1_uchar, temp2_uchar);
2288         if (per > opts->percent && PDIFF(temp1_uchar,temp2_uchar) > opts->delta) {
2289             if (print_data(opts)) {
2290                 print_pos(ph, 1, i, acc, pos, rank, dims, obj1, obj2);
2291                 parallel_print(SPACES);
2292                 parallel_print(I_FORMAT_P, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar), per);
2293             }
2294             nfound++;
2295         }
2296     }
2297     else if (temp1_uchar != temp2_uchar) {
2298         if (print_data(opts)) {
2299             print_pos(ph, 0, i, acc, pos, rank, dims, obj1, obj2);
2300             parallel_print(SPACES);
2301             parallel_print(I_FORMAT, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
2302         }
2303         nfound++;
2304     } h5difftrace("character_compare_opt finish\n");
2305 
2306     return nfound;
2307 }
2308 
2309 /*-------------------------------------------------------------------------
2310  * Function: diff_float
2311  *
2312  * Purpose:  diff a H5T_NATIVE_FLOAT type
2313  *
2314  * Return:   number of differences found
2315 *
2316  *-------------------------------------------------------------------------
2317  */
diff_float(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)2318 static hsize_t diff_float(unsigned char *mem1, unsigned char *mem2,
2319         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims, hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
2320         const char *obj2, int *ph)
2321 
2322 {
2323     hsize_t nfound = 0; /* number of differences found */
2324     float   temp1_float;
2325     float   temp2_float;
2326     hsize_t i;
2327     double  per;
2328     hbool_t both_zero;
2329     hbool_t isnan1 = FALSE;
2330     hbool_t isnan2 = FALSE;
2331 
2332     h5difftrace("diff_float start\n");
2333 
2334     /*-------------------------------------------------------------------------
2335      * -d and !-p
2336      *-------------------------------------------------------------------------
2337      */
2338 
2339     if (opts->d && !opts->p) {
2340         for (i = 0; i < nelmts; i++) {
2341             HDmemcpy(&temp1_float, mem1, sizeof(float));
2342             HDmemcpy(&temp2_float, mem2, sizeof(float));
2343 
2344             /*-------------------------------------------------------------------------
2345              * detect NaNs
2346              *-------------------------------------------------------------------------
2347              */
2348             if (opts->do_nans) {
2349                 isnan1 = my_isnan(FLT_FLOAT, &temp1_float);
2350                 isnan2 = my_isnan(FLT_FLOAT, &temp2_float);
2351             }
2352 
2353             /* both not NaN, do the comparison */
2354             if (!isnan1 && !isnan2) {
2355                 if ((double) ABS(temp1_float - temp2_float) > opts->delta) {
2356                     if (print_data(opts)) {
2357                         print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2358                         parallel_print(SPACES);
2359                         parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
2360                     }
2361                     nfound++;
2362                 }
2363             }
2364             /* only one is NaN, assume difference */
2365             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2366                 if (print_data(opts)) {
2367                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2368                     parallel_print(SPACES);
2369                     parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
2370                 }
2371                 nfound++;
2372 
2373             }
2374             mem1 += sizeof(float);
2375             mem2 += sizeof(float);
2376             if (opts->n && nfound >= opts->count)
2377                 return nfound;
2378         } /* i */
2379     }
2380     /*-------------------------------------------------------------------------
2381      * !-d and -p
2382      *-------------------------------------------------------------------------
2383      */
2384     else if (!opts->d && opts->p) {
2385         for (i = 0; i < nelmts; i++) {
2386             HDmemcpy(&temp1_float, mem1, sizeof(float));
2387             HDmemcpy(&temp2_float, mem2, sizeof(float));
2388 
2389             /*-------------------------------------------------------------------------
2390              * detect NaNs
2391              *-------------------------------------------------------------------------
2392              */
2393             if (opts->do_nans) {
2394                 isnan1 = my_isnan(FLT_FLOAT, &temp1_float);
2395                 isnan2 = my_isnan(FLT_FLOAT, &temp2_float);
2396             }
2397             /* both not NaN, do the comparison */
2398             if ((!isnan1 && !isnan2)) {
2399                 PER(temp1_float, temp2_float);
2400 
2401                 if (not_comparable && !both_zero) {
2402                     if (print_data(opts)) {
2403                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2404                         parallel_print(SPACES);
2405                         parallel_print(F_FORMAT_P_NOTCOMP, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
2406                     }
2407                     nfound++;
2408                 }
2409                 else if (per > opts->percent) {
2410                     if (print_data(opts)) {
2411                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2412                         parallel_print(SPACES);
2413                         parallel_print(F_FORMAT_P, (double) temp1_float, (double) temp2_float,
2414                                 (double) ABS(temp1_float - temp2_float), (double) ABS(1 - temp2_float / temp1_float));
2415                     }
2416                     nfound++;
2417                 }
2418             }
2419             /* only one is NaN, assume difference */
2420             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2421                 if (print_data(opts)) {
2422                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2423                     parallel_print(SPACES);
2424                     parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
2425                 }
2426                 nfound++;
2427 
2428             }
2429             mem1 += sizeof(float);
2430             mem2 += sizeof(float);
2431             if (opts->n && nfound >= opts->count)
2432                 return nfound;
2433         } /* i */
2434     }
2435     /*-------------------------------------------------------------------------
2436      * -d and -p
2437      *-------------------------------------------------------------------------
2438      */
2439     else if (opts->d && opts->p) {
2440         for (i = 0; i < nelmts; i++) {
2441             HDmemcpy(&temp1_float, mem1, sizeof(float));
2442             HDmemcpy(&temp2_float, mem2, sizeof(float));
2443 
2444             /*-------------------------------------------------------------------------
2445              * detect NaNs
2446              *-------------------------------------------------------------------------
2447              */
2448             if (opts->do_nans) {
2449                 isnan1 = my_isnan(FLT_FLOAT, &temp1_float);
2450                 isnan2 = my_isnan(FLT_FLOAT, &temp2_float);
2451             }
2452 
2453             /* both not NaN, do the comparison */
2454             if (!isnan1 && !isnan2) {
2455                 PER(temp1_float, temp2_float);
2456 
2457                 if (not_comparable && !both_zero) {
2458                     if (print_data(opts)) {
2459                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2460                         parallel_print(SPACES);
2461                         parallel_print(F_FORMAT_P_NOTCOMP, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
2462                     }
2463                     nfound++;
2464                 }
2465                 else if (per > opts->percent && (double) ABS(temp1_float - temp2_float) > opts->delta) {
2466                     if (print_data(opts)) {
2467                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2468                         parallel_print(SPACES);
2469                         parallel_print(F_FORMAT_P, (double) temp1_float, (double) temp2_float,
2470                                 (double) ABS(temp1_float - temp2_float), (double) ABS(1 - temp2_float / temp1_float));
2471                     }
2472                     nfound++;
2473                 }
2474 
2475             }
2476             /* only one is NaN, assume difference */
2477             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2478                 if (print_data(opts)) {
2479                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2480                     parallel_print(SPACES);
2481                     parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
2482                 }
2483                 nfound++;
2484 
2485             }
2486             mem1 += sizeof(float);
2487             mem2 += sizeof(float);
2488             if (opts->n && nfound >= opts->count)
2489                 return nfound;
2490         } /* i */
2491     }
2492 
2493     /*-------------------------------------------------------------------------
2494      * no -d and -p
2495      *-------------------------------------------------------------------------
2496      */
2497     else {
2498         for (i = 0; i < nelmts; i++) {
2499             HDmemcpy(&temp1_float, mem1, sizeof(float));
2500             HDmemcpy(&temp2_float, mem2, sizeof(float));
2501 
2502             if (equal_float(temp1_float, temp2_float, opts) == FALSE) {
2503                 if (print_data(opts)) {
2504                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2505                     parallel_print(SPACES);
2506                     parallel_print(F_FORMAT, (double) temp1_float, (double) temp2_float, (double) ABS(temp1_float - temp2_float));
2507                 }
2508                 nfound++;
2509             }
2510 
2511             mem1 += sizeof(float);
2512             mem2 += sizeof(float);
2513             if (opts->n && nfound >= opts->count)
2514                 return nfound;
2515         } /* nelmts */
2516     }
2517     h5difftrace("diff_float finish\n");
2518 
2519     return nfound;
2520 }
2521 
2522 /*-------------------------------------------------------------------------
2523  * Function: diff_double
2524  *
2525  * Purpose:  diff a H5T_NATIVE_DOUBLE type
2526  *
2527  * Return:   number of differences found
2528  *-------------------------------------------------------------------------
2529  */
diff_double(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)2530 static hsize_t diff_double(unsigned char *mem1, unsigned char *mem2,
2531         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
2532         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
2533         const char *obj2, int *ph)
2534 
2535 {
2536     hsize_t nfound = 0; /* number of differences found */
2537     double  temp1_double;
2538     double  temp2_double;
2539     hsize_t i;
2540     double  per;
2541     hbool_t both_zero;
2542     hbool_t isnan1 = FALSE;
2543     hbool_t isnan2 = FALSE;
2544 
2545     h5difftrace("diff_double start\n");
2546     /*-------------------------------------------------------------------------
2547      * -d and !-p
2548      *-------------------------------------------------------------------------
2549      */
2550 
2551     if (opts->d && !opts->p) {
2552         for (i = 0; i < nelmts; i++) {
2553             HDmemcpy(&temp1_double, mem1, sizeof(double));
2554             HDmemcpy(&temp2_double, mem2, sizeof(double));
2555 
2556             /*-------------------------------------------------------------------------
2557              * detect NaNs
2558              *-------------------------------------------------------------------------
2559              */
2560             if (opts->do_nans) {
2561                 isnan1 = my_isnan(FLT_DOUBLE, &temp1_double);
2562                 isnan2 = my_isnan(FLT_DOUBLE, &temp2_double);
2563             }
2564 
2565             /* both not NaN, do the comparison */
2566             if (!isnan1 && !isnan2) {
2567                 if (ABS(temp1_double-temp2_double) > opts->delta) {
2568                     if (print_data(opts)) {
2569                         print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2570                         parallel_print(SPACES);
2571                         parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2572                     }
2573                     nfound++;
2574                 }
2575             }
2576             /* only one is NaN, assume difference */
2577             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2578                 if (print_data(opts)) {
2579                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2580                     parallel_print(SPACES);
2581                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2582                 }
2583                 nfound++;
2584 
2585             }
2586             mem1 += sizeof(double);
2587             mem2 += sizeof(double);
2588             if (opts->n && nfound >= opts->count)
2589                 return nfound;
2590         } /* i */
2591     }
2592 
2593     /*-------------------------------------------------------------------------
2594      * !-d and -p
2595      *-------------------------------------------------------------------------
2596      */
2597     else if (!opts->d && opts->p) {
2598         for (i = 0; i < nelmts; i++) {
2599             HDmemcpy(&temp1_double, mem1, sizeof(double));
2600             HDmemcpy(&temp2_double, mem2, sizeof(double));
2601 
2602             /*-------------------------------------------------------------------------
2603              * detect NaNs
2604              *-------------------------------------------------------------------------
2605              */
2606             if (opts->do_nans) {
2607                 isnan1 = my_isnan(FLT_DOUBLE, &temp1_double);
2608                 isnan2 = my_isnan(FLT_DOUBLE, &temp2_double);
2609             }
2610             /* both not NaN, do the comparison */
2611             if (!isnan1 && !isnan2) {
2612                 PER(temp1_double, temp2_double);
2613 
2614                 if (not_comparable && !both_zero) {
2615                     if (print_data(opts)) {
2616                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2617                         parallel_print(SPACES);
2618                         parallel_print(F_FORMAT_P_NOTCOMP, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2619                     }
2620                     nfound++;
2621                 }
2622                 else if (per > opts->percent) {
2623                     if (print_data(opts)) {
2624                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2625                         parallel_print(SPACES);
2626                         parallel_print(F_FORMAT_P, temp1_double, temp2_double,
2627                                 ABS(temp1_double - temp2_double), ABS(1 - temp2_double / temp1_double));
2628                     }
2629                     nfound++;
2630                 }
2631             }
2632             /* only one is NaN, assume difference */
2633             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2634                 if (print_data(opts)) {
2635                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2636                     parallel_print(SPACES);
2637                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2638                 }
2639                 nfound++;
2640 
2641             }
2642             mem1 += sizeof(double);
2643             mem2 += sizeof(double);
2644             if (opts->n && nfound >= opts->count)
2645                 return nfound;
2646         } /* i */
2647     }
2648     /*-------------------------------------------------------------------------
2649      * -d and -p
2650      *-------------------------------------------------------------------------
2651      */
2652     else if (opts->d && opts->p) {
2653 
2654         for (i = 0; i < nelmts; i++) {
2655             HDmemcpy(&temp1_double, mem1, sizeof(double));
2656             HDmemcpy(&temp2_double, mem2, sizeof(double));
2657 
2658             /*-------------------------------------------------------------------------
2659              * detect NaNs
2660              *-------------------------------------------------------------------------
2661              */
2662             if (opts->do_nans) {
2663                 isnan1 = my_isnan(FLT_DOUBLE, &temp1_double);
2664                 isnan2 = my_isnan(FLT_DOUBLE, &temp2_double);
2665             }
2666 
2667             /* both not NaN, do the comparison */
2668             if (!isnan1 && !isnan2) {
2669                 PER(temp1_double, temp2_double);
2670 
2671                 if (not_comparable && !both_zero)  {
2672                     if (print_data(opts)) {
2673                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2674                         parallel_print(SPACES);
2675                         parallel_print(F_FORMAT_P_NOTCOMP, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2676                     }
2677                     nfound++;
2678                 }
2679                 else if (per > opts->percent && ABS(temp1_double-temp2_double) > opts->delta) {
2680                     if (print_data(opts)) {
2681                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2682                         parallel_print(SPACES);
2683                         parallel_print(F_FORMAT_P, temp1_double, temp2_double,
2684                                 ABS(temp1_double - temp2_double), ABS(1 - temp2_double / temp1_double));
2685                     }
2686                     nfound++;
2687                 }
2688             }
2689             /* only one is NaN, assume difference */
2690             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2691                 if (print_data(opts)) {
2692                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2693                     parallel_print(SPACES);
2694                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2695                 }
2696                 nfound++;
2697             }
2698             mem1 += sizeof(double);
2699             mem2 += sizeof(double);
2700             if (opts->n && nfound >= opts->count)
2701                 return nfound;
2702         } /* i */
2703     }
2704     /*-------------------------------------------------------------------------
2705      * no -d and -p
2706      *-------------------------------------------------------------------------
2707      */
2708     else {
2709         for (i = 0; i < nelmts; i++) {
2710             HDmemcpy(&temp1_double, mem1, sizeof(double));
2711             HDmemcpy(&temp2_double, mem2, sizeof(double));
2712 
2713             if (equal_double(temp1_double, temp2_double, opts) == FALSE) {
2714                 if (print_data(opts)) {
2715                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2716                     parallel_print(SPACES);
2717                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2718                 }
2719                 nfound++;
2720             }
2721 
2722             mem1 += sizeof(double);
2723             mem2 += sizeof(double);
2724             if (opts->n && nfound >= opts->count)
2725                 return nfound;
2726         } /* nelmts */
2727     }
2728     h5difftrace("diff_double finish\n");
2729 
2730     return nfound;
2731 }
2732 
2733 /*-------------------------------------------------------------------------
2734  * Function: diff_ldouble
2735  *
2736  * Purpose:  diff a H5T_NATIVE_LDOUBLE type
2737  *
2738  * Return:   number of differences found
2739  *-------------------------------------------------------------------------
2740  */
2741 #if H5_SIZEOF_LONG_DOUBLE !=0
2742 
diff_ldouble(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)2743 static hsize_t diff_ldouble(unsigned char *mem1,
2744         unsigned char *mem2,
2745         hsize_t nelmts,
2746         hsize_t hyper_start,
2747         int rank,
2748         hsize_t *dims,
2749         hsize_t *acc,
2750         hsize_t *pos,
2751         diff_opt_t *opts,
2752         const char *obj1,
2753         const char *obj2,
2754         int *ph)
2755 
2756 {
2757     hsize_t     nfound = 0; /* number of differences found */
2758     long double temp1_double;
2759     long double temp2_double;
2760     hsize_t     i;
2761     double      per;
2762     hbool_t     both_zero;
2763     hbool_t     isnan1 = FALSE;
2764     hbool_t     isnan2 = FALSE;
2765 
2766     h5difftrace("diff_ldouble start\n");
2767 
2768     /*-------------------------------------------------------------------------
2769      * -d and !-p
2770      *-------------------------------------------------------------------------
2771      */
2772 
2773     if (opts->d && !opts->p) {
2774         for ( i = 0; i < nelmts; i++) {
2775             HDmemcpy(&temp1_double, mem1, sizeof(long double));
2776             HDmemcpy(&temp2_double, mem2, sizeof(long double));
2777 
2778             /*-------------------------------------------------------------------------
2779              * detect NaNs
2780              *-------------------------------------------------------------------------
2781              */
2782             if (opts->do_nans) {
2783                 isnan1 = my_isnan(FLT_LDOUBLE,&temp1_double);
2784                 isnan2 = my_isnan(FLT_LDOUBLE,&temp2_double);
2785             }
2786 
2787             /* both not NaN, do the comparison */
2788             if (!isnan1 && !isnan2) {
2789                 if (ABS(temp1_double-temp2_double) > opts->delta) {
2790                     if (print_data(opts)) {
2791                         print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2792                         parallel_print(SPACES);
2793                         parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2794                     }
2795                     nfound++;
2796                 }
2797             }
2798             /* only one is NaN, assume difference */
2799             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2800                 if (print_data(opts)) {
2801                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2802                     parallel_print(SPACES);
2803                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2804                 }
2805                 nfound++;
2806 
2807             }
2808             mem1 += sizeof(long double);
2809             mem2 += sizeof(long double);
2810             if (opts->n && nfound >= opts->count)
2811                 return nfound;
2812         } /* i */
2813     }
2814 
2815     /*-------------------------------------------------------------------------
2816      * !-d and -p
2817      *-------------------------------------------------------------------------
2818      */
2819     else if (!opts->d && opts->p) {
2820         for (i = 0; i < nelmts; i++) {
2821             HDmemcpy(&temp1_double, mem1, sizeof(long double));
2822             HDmemcpy(&temp2_double, mem2, sizeof(long double));
2823 
2824             /*-------------------------------------------------------------------------
2825              * detect NaNs
2826              *-------------------------------------------------------------------------
2827              */
2828             if (opts->do_nans) {
2829                 isnan1 = my_isnan(FLT_LDOUBLE, &temp1_double);
2830                 isnan2 = my_isnan(FLT_LDOUBLE, &temp2_double);
2831             }
2832             /* both not NaN, do the comparison */
2833             if (!isnan1 && !isnan2) {
2834                 PER(temp1_double, temp2_double);
2835 
2836                 if (not_comparable && !both_zero) {
2837                     if (print_data(opts)) {
2838                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2839                         parallel_print(SPACES);
2840                         parallel_print(F_FORMAT_P_NOTCOMP, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2841                     }
2842                     nfound++;
2843                 }
2844                 else if (per > opts->percent) {
2845                     if (print_data(opts)) {
2846                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2847                         parallel_print(SPACES);
2848                         parallel_print(F_FORMAT_P, temp1_double, temp2_double,
2849                                 ABS(temp1_double - temp2_double), ABS(1-temp2_double / temp1_double));
2850                     }
2851                     nfound++;
2852                 }
2853             }
2854             /* only one is NaN, assume difference */
2855             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2856                 if (print_data(opts)) {
2857                     print_pos(ph, 0, hyper_start+i, acc, pos, rank, dims, obj1, obj2);
2858                     parallel_print(SPACES);
2859                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2860                 }
2861                 nfound++;
2862             }
2863             mem1 += sizeof(long double);
2864             mem2 += sizeof(long double);
2865             if (opts->n && nfound >= opts->count)
2866                 return nfound;
2867         } /* i */
2868     }
2869     /*-------------------------------------------------------------------------
2870      * -d and -p
2871      *-------------------------------------------------------------------------
2872      */
2873     else if (opts->d && opts->p) {
2874         for (i = 0; i < nelmts; i++) {
2875             HDmemcpy(&temp1_double, mem1, sizeof(long double));
2876             HDmemcpy(&temp2_double, mem2, sizeof(long double));
2877 
2878             /*-------------------------------------------------------------------------
2879              * detect NaNs
2880              *-------------------------------------------------------------------------
2881              */
2882             if (opts->do_nans) {
2883                 isnan1 = my_isnan(FLT_LDOUBLE, &temp1_double);
2884                 isnan2 = my_isnan(FLT_LDOUBLE, &temp2_double);
2885             }
2886 
2887             /* both not NaN, do the comparison */
2888             if (!isnan1 && !isnan2) {
2889                 PER(temp1_double, temp2_double);
2890 
2891                 if (not_comparable && !both_zero) {
2892                     if (print_data(opts)) {
2893                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2894                         parallel_print(SPACES);
2895                         parallel_print(F_FORMAT_P_NOTCOMP, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2896                     }
2897                     nfound++;
2898                 }
2899                 else if (per > opts->percent && ABS(temp1_double - temp2_double) > opts->delta) {
2900                     if (print_data(opts)) {
2901                         print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2902                         parallel_print(SPACES);
2903                         parallel_print(F_FORMAT_P, temp1_double, temp2_double, ABS(temp1_double - temp2_double), ABS(1-temp2_double / temp1_double));
2904                     }
2905                     nfound++;
2906                 }
2907             }
2908             /* only one is NaN, assume difference */
2909             else if ((isnan1 && !isnan2) || (!isnan1 && isnan2)) {
2910                 if (print_data(opts))  {
2911                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2912                     parallel_print(SPACES);
2913                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2914                 }
2915                 nfound++;
2916             }
2917             mem1 += sizeof(long double);
2918             mem2 += sizeof(long double);
2919             if (opts->n && nfound >= opts->count)
2920                 return nfound;
2921         } /* i */
2922     }
2923     /*-------------------------------------------------------------------------
2924      * no -d and -p
2925      *-------------------------------------------------------------------------
2926      */
2927     else {
2928         for (i = 0; i < nelmts; i++)  {
2929             HDmemcpy(&temp1_double, mem1, sizeof(long double));
2930             HDmemcpy(&temp2_double, mem2, sizeof(long double));
2931 
2932             if (equal_ldouble(temp1_double, temp2_double, opts) == FALSE) {
2933                 if (print_data(opts)) {
2934                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2935                     parallel_print(SPACES);
2936                     parallel_print(F_FORMAT, temp1_double, temp2_double, ABS(temp1_double - temp2_double));
2937                 }
2938                 nfound++;
2939             }
2940             mem1 += sizeof(long double);
2941             mem2 += sizeof(long double);
2942             if (opts->n && nfound >= opts->count)
2943                 return nfound;
2944         } /* nelmts */
2945     }
2946     h5difftrace("diff_ldouble finish\n");
2947 
2948     return nfound;
2949 }
2950 #endif /* H5_SIZEOF_LONG_DOUBLE */
2951 
2952 /*-------------------------------------------------------------------------
2953  * Function: diff_schar
2954  *
2955  * Purpose:  diff a H5T_NATIVE_SCHAR type
2956  *
2957  * Return:   number of differences found
2958  *-------------------------------------------------------------------------
2959  */
diff_schar(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)2960 static hsize_t diff_schar(unsigned char *mem1, unsigned char *mem2,
2961         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
2962         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
2963         const char *obj2, int *ph)
2964 
2965 {
2966     hsize_t nfound = 0; /* number of differences found */
2967     char    temp1_char;
2968     char    temp2_char;
2969     hsize_t i;
2970     double  per;
2971     hbool_t both_zero;
2972 
2973     h5difftrace("diff_schar start\n");
2974     /* -d and !-p */
2975     if (opts->d && !opts->p) {
2976         for (i = 0; i < nelmts; i++) {
2977             HDmemcpy(&temp1_char, mem1, sizeof(char));
2978             HDmemcpy(&temp2_char, mem2, sizeof(char));
2979 
2980             if (ABS(temp1_char-temp2_char) > opts->delta) {
2981                 if (print_data(opts)) {
2982                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
2983                     parallel_print(SPACES);
2984                     parallel_print(I_FORMAT, temp1_char, temp2_char, ABS(temp1_char - temp2_char));
2985                 }
2986                 nfound++;
2987             }
2988             mem1 += sizeof(char);
2989             mem2 += sizeof(char);
2990             if (opts->n && nfound >= opts->count)
2991                 return nfound;
2992         }
2993     }
2994     /* !-d and -p */
2995     else if (!opts->d && opts->p) {
2996         for (i = 0; i < nelmts; i++) {
2997             HDmemcpy(&temp1_char, mem1, sizeof(char));
2998             HDmemcpy(&temp2_char, mem2, sizeof(char));
2999 
3000             PER(temp1_char, temp2_char);
3001 
3002             if (not_comparable && !both_zero) {
3003                 if (print_data(opts)) {
3004                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3005                     parallel_print(SPACES);
3006                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_char, temp2_char, ABS(temp1_char - temp2_char));
3007                 }
3008                 nfound++;
3009             }
3010             else if (per > opts->percent) {
3011                 if (print_data(opts)) {
3012                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3013                     parallel_print(SPACES);
3014                     parallel_print(I_FORMAT_P, temp1_char, temp2_char, ABS(temp1_char - temp2_char), per);
3015                 }
3016                 nfound++;
3017             }
3018             mem1 += sizeof(char);
3019             mem2 += sizeof(char);
3020             if (opts->n && nfound >= opts->count)
3021                 return nfound;
3022         }
3023     }
3024     /* -d and -p */
3025     else if (opts->d && opts->p) {
3026         for (i = 0; i < nelmts; i++) {
3027             HDmemcpy(&temp1_char, mem1, sizeof(char));
3028             HDmemcpy(&temp2_char, mem2, sizeof(char));
3029 
3030             PER(temp1_char, temp2_char);
3031 
3032             if (not_comparable && !both_zero) {
3033                 if (print_data(opts)) {
3034                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3035                     parallel_print(SPACES);
3036                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_char, temp2_char, ABS(temp1_char - temp2_char));
3037                 }
3038                 nfound++;
3039             }
3040             else if (per > opts->percent && ABS(temp1_char-temp2_char) > opts->delta) {
3041                 if (print_data(opts)) {
3042                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3043                     parallel_print(SPACES);
3044                     parallel_print(I_FORMAT_P, temp1_char, temp2_char, ABS(temp1_char - temp2_char), per);
3045                 }
3046                 nfound++;
3047             }
3048             mem1 += sizeof(char);
3049             mem2 += sizeof(char);
3050             if (opts->n && nfound >= opts->count)
3051                 return nfound;
3052         }
3053     }
3054     else {
3055         for (i = 0; i < nelmts; i++) {
3056             HDmemcpy(&temp1_char, mem1, sizeof(char));
3057             HDmemcpy(&temp2_char, mem2, sizeof(char));
3058 
3059             if (temp1_char != temp2_char) {
3060                 if (print_data(opts)) {
3061                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3062                     parallel_print(SPACES);
3063                     parallel_print(I_FORMAT, temp1_char, temp2_char, ABS(temp1_char - temp2_char));
3064                 }
3065                 nfound++;
3066             }
3067 
3068             mem1 += sizeof(char);
3069             mem2 += sizeof(char);
3070             if (opts->n && nfound >= opts->count)
3071                 return nfound;
3072         } /* nelmts */
3073     }
3074     h5difftrace("diff_schar finish\n");
3075 
3076     return nfound;
3077 }
3078 
3079 /*-------------------------------------------------------------------------
3080  * Function: diff_uchar
3081  *
3082  * Purpose:  diff a H5T_NATIVE_UCHAR type
3083  *
3084  * Return:   number of differences found
3085  *-------------------------------------------------------------------------
3086  */
diff_uchar(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)3087 static hsize_t diff_uchar(unsigned char *mem1, unsigned char *mem2,
3088         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
3089         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
3090         const char *obj2, int *ph)
3091 {
3092     hsize_t       nfound = 0; /* number of differences found */
3093     unsigned char temp1_uchar;
3094     unsigned char temp2_uchar;
3095     hsize_t       i;
3096     double        per;
3097     hbool_t       both_zero;
3098 
3099     h5difftrace("diff_uchar start\n");
3100     /* -d and !-p */
3101     if (opts->d && !opts->p) {
3102         for (i = 0; i < nelmts; i++) {
3103             HDmemcpy(&temp1_uchar, mem1, sizeof(unsigned char));
3104             HDmemcpy(&temp2_uchar, mem2, sizeof(unsigned char));
3105 
3106             if (PDIFF(temp1_uchar,temp2_uchar) > opts->delta) {
3107                 if (print_data(opts)) {
3108                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3109                     parallel_print(SPACES);
3110                     parallel_print(I_FORMAT, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
3111                 }
3112                 nfound++;
3113             }
3114             mem1 += sizeof(unsigned char);
3115             mem2 += sizeof(unsigned char);
3116             if (opts->n && nfound >= opts->count)
3117                 return nfound;
3118         }
3119     }
3120     /* !-d and -p */
3121     else if (!opts->d && opts->p) {
3122         for (i = 0; i < nelmts; i++) {
3123             HDmemcpy(&temp1_uchar, mem1, sizeof(unsigned char));
3124             HDmemcpy(&temp2_uchar, mem2, sizeof(unsigned char));
3125 
3126             PER_UNSIGN(signed char, temp1_uchar, temp2_uchar);
3127 
3128             if (not_comparable && !both_zero) {
3129                 if (print_data(opts)) {
3130                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3131                     parallel_print(SPACES);
3132                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
3133                 }
3134                 nfound++;
3135             }
3136             else if (per > opts->percent) {
3137                 if (print_data(opts)) {
3138                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3139                     parallel_print(SPACES);
3140                     parallel_print(I_FORMAT_P, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar), per);
3141                 }
3142                 nfound++;
3143             }
3144             mem1 += sizeof(unsigned char);
3145             mem2 += sizeof(unsigned char);
3146             if (opts->n && nfound >= opts->count)
3147                 return nfound;
3148         }
3149     }
3150     /* -d and -p */
3151     else if (opts->d && opts->p) {
3152         for (i = 0; i < nelmts; i++) {
3153             HDmemcpy(&temp1_uchar, mem1, sizeof(unsigned char));
3154             HDmemcpy(&temp2_uchar, mem2, sizeof(unsigned char));
3155 
3156             PER_UNSIGN(signed char, temp1_uchar, temp2_uchar);
3157 
3158             if (not_comparable && !both_zero) {
3159                 if (print_data(opts)) {
3160                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3161                     parallel_print(SPACES);
3162                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
3163                 }
3164                 nfound++;
3165             }
3166             else if (per > opts->percent && PDIFF(temp1_uchar,temp2_uchar) > opts->delta) {
3167                 if (print_data(opts)) {
3168                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3169                     parallel_print(SPACES);
3170                     parallel_print(I_FORMAT_P, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar), per);
3171                 }
3172                 nfound++;
3173             }
3174             mem1 += sizeof(unsigned char);
3175             mem2 += sizeof(unsigned char);
3176             if (opts->n && nfound >= opts->count)
3177                 return nfound;
3178         }
3179     }
3180     else {
3181         for (i = 0; i < nelmts; i++) {
3182             HDmemcpy(&temp1_uchar, mem1, sizeof(unsigned char));
3183             HDmemcpy(&temp2_uchar, mem2, sizeof(unsigned char));
3184 
3185             if (temp1_uchar != temp2_uchar) {
3186                 if (print_data(opts)) {
3187                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3188                     parallel_print(SPACES);
3189                     parallel_print(I_FORMAT, temp1_uchar, temp2_uchar, PDIFF(temp1_uchar, temp2_uchar));
3190                 }
3191                 nfound++;
3192             }
3193 
3194             mem1 += sizeof(unsigned char);
3195             mem2 += sizeof(unsigned char);
3196             if (opts->n && nfound >= opts->count)
3197                 return nfound;
3198         } /* nelmts */
3199     }
3200     h5difftrace("diff_uchar finish\n");
3201 
3202     return nfound;
3203 }
3204 
3205 /*-------------------------------------------------------------------------
3206  * Function: diff_short
3207  *
3208  * Purpose:  diff a H5T_NATIVE_SHORT type
3209  *
3210  * Return:   number of differences found
3211  *-------------------------------------------------------------------------
3212  */
diff_short(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)3213 static hsize_t diff_short(unsigned char *mem1, unsigned char *mem2,
3214         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
3215         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
3216         const char *obj2, int *ph)
3217 {
3218     hsize_t nfound = 0; /* number of differences found */
3219     short   temp1_short;
3220     short   temp2_short;
3221     hsize_t i;
3222     double  per;
3223     hbool_t both_zero;
3224 
3225     h5difftrace("diff_short start\n");
3226     /* -d and !-p */
3227     if (opts->d && !opts->p) {
3228         for (i = 0; i < nelmts; i++) {
3229             HDmemcpy(&temp1_short, mem1, sizeof(short));
3230             HDmemcpy(&temp2_short, mem2, sizeof(short));
3231 
3232             if (ABS(temp1_short-temp2_short) > opts->delta) {
3233                 if (print_data(opts)) {
3234                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3235                     parallel_print(SPACES);
3236                     parallel_print(I_FORMAT, temp1_short, temp2_short, ABS(temp1_short - temp2_short));
3237                 }
3238                 nfound++;
3239             }
3240             mem1 += sizeof(short);
3241             mem2 += sizeof(short);
3242             if (opts->n && nfound >= opts->count)
3243                 return nfound;
3244         }
3245     }
3246     /* !-d and -p */
3247     else if (!opts->d && opts->p) {
3248         for (i = 0; i < nelmts; i++) {
3249             HDmemcpy(&temp1_short, mem1, sizeof(short));
3250             HDmemcpy(&temp2_short, mem2, sizeof(short));
3251 
3252             PER(temp1_short, temp2_short);
3253 
3254             if (not_comparable && !both_zero) {
3255                 if (print_data(opts)) {
3256                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3257                     parallel_print(SPACES);
3258                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_short, temp2_short, ABS(temp1_short - temp2_short));
3259                 }
3260                 nfound++;
3261             }
3262             else if (per > opts->percent) {
3263                 if (print_data(opts)) {
3264                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3265                     parallel_print(SPACES);
3266                     parallel_print(I_FORMAT_P, temp1_short, temp2_short, ABS(temp1_short - temp2_short), per);
3267                 }
3268                 nfound++;
3269             }
3270             mem1 += sizeof(short);
3271             mem2 += sizeof(short);
3272             if (opts->n && nfound >= opts->count)
3273                 return nfound;
3274         }
3275     }
3276     /* -d and -p */
3277     else if (opts->d && opts->p) {
3278         for (i = 0; i < nelmts; i++) {
3279             HDmemcpy(&temp1_short, mem1, sizeof(short));
3280             HDmemcpy(&temp2_short, mem2, sizeof(short));
3281 
3282             PER(temp1_short, temp2_short);
3283 
3284             if (not_comparable && !both_zero) {
3285                 if (print_data(opts)) {
3286                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3287                     parallel_print(SPACES);
3288                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_short, temp2_short, ABS(temp1_short - temp2_short));
3289                 }
3290                 nfound++;
3291             }
3292             else if (per > opts->percent && ABS(temp1_short-temp2_short) > opts->delta) {
3293                 if (print_data(opts)) {
3294                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3295                     parallel_print(SPACES);
3296                     parallel_print(I_FORMAT_P, temp1_short, temp2_short, ABS(temp1_short - temp2_short), per);
3297                 }
3298                 nfound++;
3299             }
3300             mem1 += sizeof(short);
3301             mem2 += sizeof(short);
3302             if (opts->n && nfound >= opts->count)
3303                 return nfound;
3304         }
3305     }
3306     else {
3307         for (i = 0; i < nelmts; i++) {
3308             HDmemcpy(&temp1_short, mem1, sizeof(short));
3309             HDmemcpy(&temp2_short, mem2, sizeof(short));
3310 
3311             if (temp1_short != temp2_short) {
3312                 if (print_data(opts)) {
3313                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3314                     parallel_print(SPACES);
3315                     parallel_print(I_FORMAT, temp1_short, temp2_short, ABS(temp1_short - temp2_short));
3316                 }
3317                 nfound++;
3318             }
3319 
3320             mem1 += sizeof(short);
3321             mem2 += sizeof(short);
3322             if (opts->n && nfound >= opts->count)
3323                 return nfound;
3324         } /* nelmts */
3325     }
3326     h5difftrace("diff_short finish\n");
3327 
3328     return nfound;
3329 }
3330 
3331 /*-------------------------------------------------------------------------
3332  * Function: diff_ushort
3333  *
3334  * Purpose:  diff a H5T_NATIVE_USHORT type
3335  *
3336  * Return:   number of differences found
3337  *-------------------------------------------------------------------------
3338  */
diff_ushort(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)3339 static hsize_t diff_ushort(unsigned char *mem1, unsigned char *mem2,
3340         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
3341         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
3342         const char *obj2, int *ph)
3343 
3344 {
3345     hsize_t        nfound = 0; /* number of differences found */
3346     unsigned short temp1_ushort;
3347     unsigned short temp2_ushort;
3348     hsize_t        i;
3349     double         per;
3350     hbool_t        both_zero;
3351 
3352     h5difftrace("diff_ushort start\n");
3353     /* -d and !-p */
3354     if (opts->d && !opts->p) {
3355         for (i = 0; i < nelmts; i++) {
3356             HDmemcpy(&temp1_ushort, mem1, sizeof(unsigned short));
3357             HDmemcpy(&temp2_ushort, mem2, sizeof(unsigned short));
3358 
3359             if (PDIFF(temp1_ushort,temp2_ushort) > opts->delta) {
3360                 if (print_data(opts)) {
3361                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3362                     parallel_print(SPACES);
3363                     parallel_print(I_FORMAT, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort));
3364                 }
3365                 nfound++;
3366             }
3367             mem1 += sizeof(unsigned short);
3368             mem2 += sizeof(unsigned short);
3369             if (opts->n && nfound >= opts->count)
3370                 return nfound;
3371         }
3372     }
3373     /* !-d and -p */
3374     else if (!opts->d && opts->p) {
3375         for (i = 0; i < nelmts; i++) {
3376             HDmemcpy(&temp1_ushort, mem1, sizeof(unsigned short));
3377             HDmemcpy(&temp2_ushort, mem2, sizeof(unsigned short));
3378 
3379             PER_UNSIGN(signed short, temp1_ushort, temp2_ushort);
3380 
3381             if (not_comparable && !both_zero)  {
3382                 if (print_data(opts)) {
3383                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3384                     parallel_print(SPACES);
3385                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort));
3386                 }
3387                 nfound++;
3388             }
3389             else if (per > opts->percent) {
3390                 if (print_data(opts)) {
3391                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3392                     parallel_print(SPACES);
3393                     parallel_print(I_FORMAT_P, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort), per);
3394                 }
3395                 nfound++;
3396             }
3397             mem1 += sizeof(unsigned short);
3398             mem2 += sizeof(unsigned short);
3399             if (opts->n && nfound >= opts->count)
3400                 return nfound;
3401         }
3402     }
3403     /* -d and -p */
3404     else if (opts->d && opts->p) {
3405         for (i = 0; i < nelmts; i++) {
3406             HDmemcpy(&temp1_ushort, mem1, sizeof(unsigned short));
3407             HDmemcpy(&temp2_ushort, mem2, sizeof(unsigned short));
3408 
3409             PER_UNSIGN(signed short, temp1_ushort, temp2_ushort);
3410 
3411             if (not_comparable && !both_zero) {
3412                 if (print_data(opts)) {
3413                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3414                     parallel_print(SPACES);
3415                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort));
3416                 }
3417                 nfound++;
3418             }
3419             else if (per > opts->percent && PDIFF(temp1_ushort,temp2_ushort) > opts->delta) {
3420                 if (print_data(opts)) {
3421                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3422                     parallel_print(SPACES);
3423                     parallel_print(I_FORMAT_P, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort), per);
3424                 }
3425                 nfound++;
3426             }
3427             mem1 += sizeof(unsigned short);
3428             mem2 += sizeof(unsigned short);
3429             if (opts->n && nfound >= opts->count)
3430                 return nfound;
3431         }
3432     }
3433     else {
3434         for (i = 0; i < nelmts; i++) {
3435             HDmemcpy(&temp1_ushort, mem1, sizeof(unsigned short));
3436             HDmemcpy(&temp2_ushort, mem2, sizeof(unsigned short));
3437 
3438             if (temp1_ushort != temp2_ushort) {
3439                 if (print_data(opts)) {
3440                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3441                     parallel_print(SPACES);
3442                     parallel_print(I_FORMAT, temp1_ushort, temp2_ushort, PDIFF(temp1_ushort, temp2_ushort));
3443                 }
3444                 nfound++;
3445             }
3446 
3447             mem1 += sizeof(unsigned short);
3448             mem2 += sizeof(unsigned short);
3449             if (opts->n && nfound >= opts->count)
3450                 return nfound;
3451         } /* nelmts */
3452     }
3453     h5difftrace("diff_ushort finish\n");
3454 
3455     return nfound;
3456 }
3457 
3458 /*-------------------------------------------------------------------------
3459  * Function:  diff_int
3460  *
3461  * Purpose:   diff a H5T_NATIVE_INT type
3462  *
3463  * Return:    number of differences found
3464   *-------------------------------------------------------------------------
3465  */
diff_int(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)3466 static hsize_t diff_int(unsigned char *mem1, unsigned char *mem2,
3467         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
3468         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
3469         const char *obj2, int *ph)
3470 {
3471     hsize_t nfound = 0; /* number of differences found */
3472     int     temp1_int;
3473     int     temp2_int;
3474     hsize_t i;
3475     double  per;
3476     hbool_t both_zero;
3477 
3478     h5difftrace("diff_int start\n");
3479     /* -d and !-p */
3480     if (opts->d && !opts->p) {
3481         for (i = 0; i < nelmts; i++) {
3482             HDmemcpy(&temp1_int, mem1, sizeof(int));
3483             HDmemcpy(&temp2_int, mem2, sizeof(int));
3484 
3485             if (ABS(temp1_int-temp2_int) > opts->delta) {
3486                 if (print_data(opts)) {
3487                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3488                     parallel_print(SPACES);
3489                     parallel_print(I_FORMAT, temp1_int, temp2_int, ABS(temp1_int - temp2_int));
3490                 }
3491                 nfound++;
3492             }
3493             mem1 += sizeof(int);
3494             mem2 += sizeof(int);
3495             if (opts->n && nfound >= opts->count)
3496                 return nfound;
3497         }
3498     }
3499     /* !-d and -p */
3500     else if (!opts->d && opts->p) {
3501         for (i = 0; i < nelmts; i++) {
3502             HDmemcpy(&temp1_int, mem1, sizeof(int));
3503             HDmemcpy(&temp2_int, mem2, sizeof(int));
3504 
3505             PER(temp1_int, temp2_int);
3506 
3507             if (not_comparable && !both_zero) {
3508                 if (print_data(opts)) {
3509                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3510                     parallel_print(SPACES);
3511                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_int, temp2_int, ABS(temp1_int - temp2_int));
3512                 }
3513                 nfound++;
3514             }
3515             else if (per > opts->percent) {
3516                 if (print_data(opts)) {
3517                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3518                     parallel_print(SPACES);
3519                     parallel_print(I_FORMAT_P, temp1_int, temp2_int, ABS(temp1_int - temp2_int), per);
3520                 }
3521                 nfound++;
3522             }
3523             mem1 += sizeof(int);
3524             mem2 += sizeof(int);
3525             if (opts->n && nfound >= opts->count)
3526                 return nfound;
3527         }
3528     }
3529     /* -d and -p */
3530     else if (opts->d && opts->p) {
3531         for (i = 0; i < nelmts; i++) {
3532             HDmemcpy(&temp1_int, mem1, sizeof(int));
3533             HDmemcpy(&temp2_int, mem2, sizeof(int));
3534 
3535             PER(temp1_int, temp2_int);
3536 
3537             if (not_comparable && !both_zero) {
3538                 if (print_data(opts)) {
3539                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3540                     parallel_print(SPACES);
3541                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_int, temp2_int, ABS(temp1_int - temp2_int));
3542                 }
3543                 nfound++;
3544             }
3545             else if (per > opts->percent && ABS(temp1_int-temp2_int) > opts->delta) {
3546                 if (print_data(opts)) {
3547                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3548                     parallel_print(SPACES);
3549                     parallel_print(I_FORMAT_P, temp1_int, temp2_int, ABS(temp1_int - temp2_int), per);
3550                 }
3551                 nfound++;
3552             }
3553             mem1 += sizeof(int);
3554             mem2 += sizeof(int);
3555             if (opts->n && nfound >= opts->count)
3556                 return nfound;
3557         }
3558     }
3559     else {
3560         for (i = 0; i < nelmts; i++) {
3561             HDmemcpy(&temp1_int, mem1, sizeof(int));
3562             HDmemcpy(&temp2_int, mem2, sizeof(int));
3563 
3564             if (temp1_int != temp2_int) {
3565                 if (print_data(opts)) {
3566                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3567                     parallel_print(SPACES);
3568                     parallel_print(I_FORMAT, temp1_int, temp2_int, ABS(temp1_int - temp2_int));
3569                 }
3570                 nfound++;
3571             }
3572 
3573             mem1 += sizeof(int);
3574             mem2 += sizeof(int);
3575             if (opts->n && nfound >= opts->count)
3576                 return nfound;
3577         } /* nelmts */
3578 
3579     }
3580     h5difftrace("diff_int finish\n");
3581     return nfound;
3582 }
3583 
3584 /*-------------------------------------------------------------------------
3585  * Function: diff_uint
3586  *
3587  * Purpose:  diff a H5T_NATIVE_UINT type
3588  *
3589  * Return:  number of differences found
3590  *-------------------------------------------------------------------------
3591  */
diff_uint(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)3592 static hsize_t diff_uint(unsigned char *mem1, unsigned char *mem2,
3593         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
3594         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
3595         const char *obj2, int *ph)
3596 {
3597     hsize_t nfound = 0; /* number of differences found */
3598     unsigned int temp1_uint;
3599     unsigned int temp2_uint;
3600     hsize_t i;
3601     double per;
3602     hbool_t both_zero;
3603 
3604     h5difftrace("diff_uint start\n");
3605     /* -d and !-p */
3606     if (opts->d && !opts->p) {
3607         for (i = 0; i < nelmts; i++) {
3608             HDmemcpy(&temp1_uint, mem1, sizeof(unsigned int));
3609             HDmemcpy(&temp2_uint, mem2, sizeof(unsigned int));
3610 
3611             if (PDIFF(temp1_uint,temp2_uint) > opts->delta) {
3612                 if (print_data(opts)) {
3613                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3614                     parallel_print(SPACES);
3615                     parallel_print(I_FORMAT, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint));
3616                 }
3617                 nfound++;
3618             }
3619             mem1 += sizeof(unsigned int);
3620             mem2 += sizeof(unsigned int);
3621             if (opts->n && nfound >= opts->count)
3622                 return nfound;
3623         }
3624     }
3625     /* !-d and -p */
3626     else if (!opts->d && opts->p) {
3627         for (i = 0; i < nelmts; i++) {
3628             HDmemcpy(&temp1_uint, mem1, sizeof(unsigned int));
3629             HDmemcpy(&temp2_uint, mem2, sizeof(unsigned int));
3630 
3631             PER_UNSIGN(signed int, temp1_uint, temp2_uint);
3632 
3633             if (not_comparable && !both_zero) {
3634                 if (print_data(opts)) {
3635                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3636                     parallel_print(SPACES);
3637                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint));
3638                 }
3639                 nfound++;
3640             }
3641             else if (per > opts->percent) {
3642                 if (print_data(opts)) {
3643                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3644                     parallel_print(SPACES);
3645                     parallel_print(I_FORMAT_P, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint), per);
3646                 }
3647                 nfound++;
3648             }
3649             mem1 += sizeof(unsigned int);
3650             mem2 += sizeof(unsigned int);
3651             if (opts->n && nfound >= opts->count)
3652                 return nfound;
3653         }
3654     }
3655     /* -d and -p */
3656     else if (opts->d && opts->p) {
3657         for (i = 0; i < nelmts; i++) {
3658             HDmemcpy(&temp1_uint, mem1, sizeof(unsigned int));
3659             HDmemcpy(&temp2_uint, mem2, sizeof(unsigned int));
3660 
3661             PER_UNSIGN(signed int, temp1_uint, temp2_uint);
3662 
3663             if (not_comparable && !both_zero) {
3664                 if (print_data(opts)) {
3665                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3666                     parallel_print(SPACES);
3667                     parallel_print(I_FORMAT_P_NOTCOMP, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint));
3668                 }
3669                 nfound++;
3670             }
3671             else if (per > opts->percent
3672                     && PDIFF(temp1_uint,temp2_uint) > opts->delta) {
3673                 if (print_data(opts)) {
3674                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3675                     parallel_print(SPACES);
3676                     parallel_print(I_FORMAT_P, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint), per);
3677                 }
3678                 nfound++;
3679             }
3680             mem1 += sizeof(unsigned int);
3681             mem2 += sizeof(unsigned int);
3682             if (opts->n && nfound >= opts->count)
3683                 return nfound;
3684         }
3685     }
3686     else {
3687         for (i = 0; i < nelmts; i++) {
3688             HDmemcpy(&temp1_uint, mem1, sizeof(unsigned int));
3689             HDmemcpy(&temp2_uint, mem2, sizeof(unsigned int));
3690 
3691             if (temp1_uint != temp2_uint) {
3692                 if (print_data(opts)) {
3693                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3694                     parallel_print(SPACES);
3695                     parallel_print(I_FORMAT, temp1_uint, temp2_uint, PDIFF(temp1_uint, temp2_uint));
3696                 }
3697                 nfound++;
3698             }
3699 
3700             mem1 += sizeof(unsigned int);
3701             mem2 += sizeof(unsigned int);
3702             if (opts->n && nfound >= opts->count)
3703                 return nfound;
3704         } /* nelmts */
3705     }
3706     h5difftrace("diff_uint finish\n");
3707 
3708     return nfound;
3709 }
3710 
3711 /*-------------------------------------------------------------------------
3712  * Function: diff_long
3713  *
3714  * Purpose:  diff a H5T_NATIVE_LONG type
3715  *
3716  * Return:   number of differences found
3717  *-------------------------------------------------------------------------
3718  */
diff_long(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)3719 static hsize_t diff_long(unsigned char *mem1, unsigned char *mem2,
3720         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
3721         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
3722         const char *obj2, int *ph)
3723 {
3724     hsize_t nfound = 0; /* number of differences found */
3725     long temp1_long;
3726     long temp2_long;
3727     hsize_t i;
3728     double per;
3729     hbool_t both_zero;
3730 
3731     h5difftrace("diff_long start\n");
3732     /* -d and !-p */
3733     if (opts->d && !opts->p) {
3734         for (i = 0; i < nelmts; i++) {
3735             for (i = 0; i < nelmts; i++) {
3736                 HDmemcpy(&temp1_long, mem1, sizeof(long));
3737                 HDmemcpy(&temp2_long, mem2, sizeof(long));
3738 
3739                 if (ABS(temp1_long-temp2_long) > opts->delta) {
3740                     if (print_data(opts)) {
3741                         print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3742                         parallel_print(SPACES);
3743                         parallel_print(LI_FORMAT, temp1_long, temp2_long, ABS(temp1_long - temp2_long));
3744                     }
3745                     nfound++;
3746                 }
3747                 mem1 += sizeof(long);
3748                 mem2 += sizeof(long);
3749                 if (opts->n && nfound >= opts->count)
3750                     return nfound;
3751             }
3752         }
3753     }
3754     /* !-d and -p */
3755     else if (!opts->d && opts->p) {
3756         for (i = 0; i < nelmts; i++) {
3757             HDmemcpy(&temp1_long, mem1, sizeof(long));
3758             HDmemcpy(&temp2_long, mem2, sizeof(long));
3759 
3760             PER(temp1_long, temp2_long);
3761 
3762             if (not_comparable && !both_zero) {
3763                 if (print_data(opts)) {
3764                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3765                     parallel_print(SPACES);
3766                     parallel_print(LI_FORMAT_P_NOTCOMP, temp1_long, temp2_long, ABS(temp1_long - temp2_long));
3767                 }
3768                 nfound++;
3769             }
3770             else if (per > opts->percent) {
3771                 if (print_data(opts)) {
3772                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3773                     parallel_print(SPACES);
3774                     parallel_print(LI_FORMAT_P, temp1_long, temp2_long, ABS(temp1_long - temp2_long), per);
3775                 }
3776                 nfound++;
3777             }
3778             mem1 += sizeof(long);
3779             mem2 += sizeof(long);
3780             if (opts->n && nfound >= opts->count)
3781                 return nfound;
3782         }
3783     }
3784     /* -d and -p */
3785     else if (opts->d && opts->p) {
3786         for (i = 0; i < nelmts; i++) {
3787             HDmemcpy(&temp1_long, mem1, sizeof(long));
3788             HDmemcpy(&temp2_long, mem2, sizeof(long));
3789 
3790             PER(temp1_long, temp2_long);
3791 
3792             if (not_comparable && !both_zero) {
3793                 if (print_data(opts)) {
3794                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3795                     parallel_print(SPACES);
3796                     parallel_print(LI_FORMAT_P_NOTCOMP, temp1_long, temp2_long, ABS(temp1_long - temp2_long));
3797                 }
3798                 nfound++;
3799             }
3800             else if (per > opts->percent && ABS(temp1_long-temp2_long) > opts->delta) {
3801                 if (print_data(opts)) {
3802                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3803                     parallel_print(SPACES);
3804                     parallel_print(LI_FORMAT_P, temp1_long, temp2_long, ABS(temp1_long - temp2_long), per);
3805                 }
3806                 nfound++;
3807             }
3808             mem1 += sizeof(long);
3809             mem2 += sizeof(long);
3810             if (opts->n && nfound >= opts->count)
3811                 return nfound;
3812         }
3813     }
3814     else {
3815         for (i = 0; i < nelmts; i++) {
3816             HDmemcpy(&temp1_long, mem1, sizeof(long));
3817             HDmemcpy(&temp2_long, mem2, sizeof(long));
3818 
3819             if (temp1_long != temp2_long) {
3820                 if (print_data(opts)) {
3821                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3822                     parallel_print(SPACES);
3823                     parallel_print(LI_FORMAT, temp1_long, temp2_long, ABS(temp1_long - temp2_long));
3824                 }
3825                 nfound++;
3826             }
3827 
3828             mem1 += sizeof(long);
3829             mem2 += sizeof(long);
3830             if (opts->n && nfound >= opts->count)
3831                 return nfound;
3832         } /* nelmts */
3833     }
3834     h5difftrace("diff_long finish\n");
3835 
3836     return nfound;
3837 }
3838 
3839 /*-------------------------------------------------------------------------
3840  * Function: diff_ulong
3841  *
3842  * Purpose:  diff a H5T_NATIVE_ULONG type
3843  *
3844  * Return:   number of differences found
3845  *-------------------------------------------------------------------------
3846  */
diff_ulong(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)3847 static hsize_t diff_ulong(unsigned char *mem1, unsigned char *mem2,
3848         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
3849         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
3850         const char *obj2, int *ph)
3851 {
3852     hsize_t       nfound = 0; /* number of differences found */
3853     unsigned long temp1_ulong;
3854     unsigned long temp2_ulong;
3855     hsize_t       i;
3856     double        per;
3857     hbool_t       both_zero;
3858 
3859     h5difftrace("diff_ulong start\n");
3860 
3861     /* -d and !-p */
3862     if (opts->d && !opts->p) {
3863         for (i = 0; i < nelmts; i++) {
3864             for (i = 0; i < nelmts; i++) {
3865                 HDmemcpy(&temp1_ulong, mem1, sizeof(unsigned long));
3866                 HDmemcpy(&temp2_ulong, mem2, sizeof(unsigned long));
3867 
3868                 if (PDIFF(temp1_ulong,temp2_ulong) > opts->delta) {
3869                     if (print_data(opts)) {
3870                         print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3871                         parallel_print(SPACES);
3872                         parallel_print(LI_FORMAT, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong));
3873                     }
3874                     nfound++;
3875                 }
3876                 mem1 += sizeof(unsigned long);
3877                 mem2 += sizeof(unsigned long);
3878                 if (opts->n && nfound >= opts->count)
3879                     return nfound;
3880             }
3881         }
3882     }
3883     /* !-d and -p */
3884     else if (!opts->d && opts->p) {
3885         for (i = 0; i < nelmts; i++) {
3886             HDmemcpy(&temp1_ulong, mem1, sizeof(unsigned long));
3887             HDmemcpy(&temp2_ulong, mem2, sizeof(unsigned long));
3888 
3889             PER_UNSIGN(signed long, temp1_ulong, temp2_ulong);
3890 
3891             if (not_comparable && !both_zero) {
3892                 if (print_data(opts)) {
3893                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3894                     parallel_print(SPACES);
3895                     parallel_print(ULI_FORMAT_P_NOTCOMP, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong));
3896                 }
3897                 nfound++;
3898             }
3899             else if (per > opts->percent) {
3900                 if (print_data(opts)) {
3901                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3902                     parallel_print(SPACES);
3903                     parallel_print(LI_FORMAT_P, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong), per);
3904                 }
3905                 nfound++;
3906             }
3907             mem1 += sizeof(unsigned long);
3908             mem2 += sizeof(unsigned long);
3909             if (opts->n && nfound >= opts->count)
3910                 return nfound;
3911         }
3912     }
3913     /* -d and -p */
3914     else if (opts->d && opts->p) {
3915         for (i = 0; i < nelmts; i++) {
3916             HDmemcpy(&temp1_ulong, mem1, sizeof(unsigned long));
3917             HDmemcpy(&temp2_ulong, mem2, sizeof(unsigned long));
3918 
3919             PER_UNSIGN(signed long, temp1_ulong, temp2_ulong);
3920 
3921             if (not_comparable && !both_zero) {
3922                 if (print_data(opts)) {
3923                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3924                     parallel_print(SPACES);
3925                     parallel_print(ULI_FORMAT_P_NOTCOMP, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong));
3926                 }
3927                 nfound++;
3928             }
3929             else if (per > opts->percent
3930                     && PDIFF(temp1_ulong,temp2_ulong) > opts->delta) {
3931                 if (print_data(opts)) {
3932                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3933                     parallel_print(SPACES);
3934                     parallel_print(LI_FORMAT_P, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong), per);
3935                 }
3936                 nfound++;
3937             }
3938             mem1 += sizeof(unsigned long);
3939             mem2 += sizeof(unsigned long);
3940             if (opts->n && nfound >= opts->count)
3941                 return nfound;
3942         }
3943     }
3944     else {
3945         for (i = 0; i < nelmts; i++) {
3946             HDmemcpy(&temp1_ulong, mem1, sizeof(unsigned long));
3947             HDmemcpy(&temp2_ulong, mem2, sizeof(unsigned long));
3948 
3949             if (temp1_ulong != temp2_ulong) {
3950                 if (print_data(opts)) {
3951                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3952                     parallel_print(SPACES);
3953                     parallel_print(LI_FORMAT, temp1_ulong, temp2_ulong, PDIFF(temp1_ulong, temp2_ulong));
3954                 }
3955                 nfound++;
3956             }
3957 
3958             mem1 += sizeof(unsigned long);
3959             mem2 += sizeof(unsigned long);
3960             if (opts->n && nfound >= opts->count)
3961                 return nfound;
3962         } /* nelmts */
3963     }
3964     h5difftrace("diff_ulong finish\n");
3965 
3966     return nfound;
3967 }
3968 
3969 /*-------------------------------------------------------------------------
3970  * Function: diff_llong
3971  *
3972  * Purpose:  diff a H5T_NATIVE_LLONG type
3973  *
3974  * Return:   number of differences found
3975  *-------------------------------------------------------------------------
3976  */
diff_llong(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)3977 static hsize_t diff_llong(unsigned char *mem1, unsigned char *mem2,
3978         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims,
3979         hsize_t *acc, hsize_t *pos, diff_opt_t *opts, const char *obj1,
3980         const char *obj2, int *ph)
3981 {
3982     hsize_t   nfound = 0; /* number of differences found */
3983     long long temp1_llong;
3984     long long temp2_llong;
3985     hsize_t   i;
3986     double    per;
3987     hbool_t   both_zero;
3988 
3989     h5difftrace("diff_llong start\n");
3990     /* -d and !-p */
3991     if (opts->d && !opts->p) {
3992         for (i = 0; i < nelmts; i++) {
3993             HDmemcpy(&temp1_llong, mem1, sizeof(long long));
3994             HDmemcpy(&temp2_llong, mem2, sizeof(long long));
3995 
3996             if (ABS( temp1_llong-temp2_llong) > opts->delta) {
3997                 if (print_data(opts)) {
3998                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
3999                     parallel_print(SPACES);
4000                     parallel_print(LLI_FORMAT, temp1_llong, temp2_llong, ABS(temp1_llong - temp2_llong));
4001                 }
4002                 nfound++;
4003             }
4004             mem1 += sizeof(long long);
4005             mem2 += sizeof(long long);
4006             if (opts->n && nfound >= opts->count)
4007                 return nfound;
4008         }
4009     }
4010     /* !-d and -p */
4011     else if (!opts->d && opts->p) {
4012         for (i = 0; i < nelmts; i++) {
4013             HDmemcpy(&temp1_llong, mem1, sizeof(long long));
4014             HDmemcpy(&temp2_llong, mem2, sizeof(long long));
4015 
4016             PER(temp1_llong, temp2_llong);
4017 
4018             if (not_comparable && !both_zero) {
4019                 if (print_data(opts)) {
4020                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4021                     parallel_print(SPACES);
4022                 parallel_print(LLI_FORMAT_P_NOTCOMP, temp1_llong, temp2_llong, ABS(temp1_llong - temp2_llong));
4023             }
4024             nfound++;
4025         }
4026         else if (per > opts->percent) {
4027             if (print_data(opts)) {
4028                 print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4029                 parallel_print(SPACES);
4030                 parallel_print(LLI_FORMAT_P, temp1_llong, temp2_llong, ABS(temp1_llong - temp2_llong),per);
4031             }
4032             nfound++;
4033         }
4034         mem1 += sizeof(long long);
4035         mem2 += sizeof(long long);
4036         if (opts->n && nfound >= opts->count)
4037             return nfound;
4038         }
4039     }
4040     /* -d and -p */
4041     else if (opts->d && opts->p) {
4042         for (i = 0; i < nelmts; i++) {
4043             HDmemcpy(&temp1_llong, mem1, sizeof(long long));
4044             HDmemcpy(&temp2_llong, mem2, sizeof(long long));
4045 
4046             PER(temp1_llong, temp2_llong);
4047 
4048             if (not_comparable && !both_zero) {
4049                 if (print_data(opts)) {
4050                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4051                     parallel_print(SPACES);
4052                     parallel_print(LLI_FORMAT_P_NOTCOMP, temp1_llong, temp2_llong, ABS(temp1_llong - temp2_llong));
4053                 }
4054                 nfound++;
4055             }
4056             else if (per > opts->percent
4057                     && ABS(temp1_llong-temp2_llong) > opts->delta) {
4058                 if (print_data(opts)) {
4059                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4060                     parallel_print(SPACES);
4061                     parallel_print(LLI_FORMAT_P, temp1_llong, temp2_llong, ABS(temp1_llong - temp2_llong),per);
4062                 }
4063                 nfound++;
4064             }
4065             mem1 += sizeof(long long);
4066             mem2 += sizeof(long long);
4067             if (opts->n && nfound >= opts->count)
4068                 return nfound;
4069         }
4070     }
4071     else {
4072         for (i = 0; i < nelmts; i++) {
4073             HDmemcpy(&temp1_llong, mem1, sizeof(long long));
4074             HDmemcpy(&temp2_llong, mem2, sizeof(long long));
4075 
4076             if (temp1_llong != temp2_llong) {
4077                 if (print_data(opts)) {
4078                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4079                     parallel_print(SPACES);
4080                     parallel_print(LLI_FORMAT, temp1_llong, temp2_llong, ABS(temp1_llong - temp2_llong));
4081                 }
4082                 nfound++;
4083             }
4084 
4085             mem1 += sizeof(long long);
4086             mem2 += sizeof(long long);
4087             if (opts->n && nfound >= opts->count)
4088                 return nfound;
4089         } /* nelmts */
4090     }
4091     h5difftrace("diff_llong finish\n");
4092 
4093     return nfound;
4094 }
4095 
4096 /*-------------------------------------------------------------------------
4097  * Function: diff_ullong
4098  *
4099  * Purpose:  diff a H5T_NATIVE_ULLONG type
4100  *
4101  * Return:   number of differences found
4102  *-------------------------------------------------------------------------
4103  */
diff_ullong(unsigned char * mem1,unsigned char * mem2,hsize_t nelmts,hsize_t hyper_start,int rank,hsize_t * dims,hsize_t * acc,hsize_t * pos,diff_opt_t * opts,const char * obj1,const char * obj2,int * ph)4104 static hsize_t diff_ullong(unsigned char *mem1, unsigned char *mem2,
4105         hsize_t nelmts, hsize_t hyper_start, int rank, hsize_t *dims, hsize_t *acc,
4106         hsize_t *pos, diff_opt_t *opts, const char *obj1, const char *obj2, int *ph)
4107 
4108 {
4109     hsize_t            nfound = 0; /* number of differences found */
4110     unsigned long long temp1_ullong;
4111     unsigned long long temp2_ullong;
4112     hsize_t            i;
4113     float              f1, f2;
4114     double             per;
4115     hbool_t            both_zero;
4116 
4117     h5difftrace("diff_ullong start\n");
4118     /* -d and !-p */
4119     if (opts->d && !opts->p) {
4120         for (i = 0; i < nelmts; i++) {
4121             HDmemcpy(&temp1_ullong, mem1, sizeof(unsigned long long));
4122             HDmemcpy(&temp2_ullong, mem2, sizeof(unsigned long long));
4123 
4124             if (PDIFF(temp1_ullong,temp2_ullong) > (unsigned long long) opts->delta) {
4125                 if (print_data(opts)) {
4126                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4127                     parallel_print(SPACES);
4128                     parallel_print(ULLI_FORMAT,temp1_ullong,temp2_ullong,PDIFF(temp1_ullong,temp2_ullong));
4129                 }
4130                 nfound++;
4131             }
4132             mem1 += sizeof(unsigned long long);
4133             mem2 += sizeof(unsigned long long);
4134             if (opts->n && nfound >= opts->count)
4135                 return nfound;
4136         }
4137     }
4138     /* !-d and -p */
4139     else if (!opts->d && opts->p) {
4140         for (i = 0; i < nelmts; i++) {
4141             HDmemcpy(&temp1_ullong, mem1, sizeof(unsigned long long));
4142             HDmemcpy(&temp2_ullong, mem2, sizeof(unsigned long long));
4143 
4144             ull2float(temp1_ullong, &f1);
4145             ull2float(temp2_ullong, &f2);
4146             PER(f1, f2);
4147 
4148             if (not_comparable && !both_zero) {
4149                 if (print_data(opts)) {
4150                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4151                     parallel_print(SPACES);
4152                     parallel_print(ULLI_FORMAT_P_NOTCOMP,temp1_ullong,temp2_ullong,PDIFF(temp1_ullong,temp2_ullong));
4153                 }
4154                 nfound++;
4155             }
4156             else if (per > opts->percent) {
4157                 if (print_data(opts)) {
4158                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4159                     parallel_print(SPACES);
4160                     parallel_print(ULLI_FORMAT_P,temp1_ullong,temp2_ullong,PDIFF(temp1_ullong,temp2_ullong),per);
4161                 }
4162                 nfound++;
4163             }
4164             mem1 += sizeof(unsigned long long);
4165             mem2 += sizeof(unsigned long long);
4166             if (opts->n && nfound >= opts->count)
4167                 return nfound;
4168         }
4169     }
4170     /* -d and -p */
4171     else if (opts->d && opts->p) {
4172         for (i = 0; i < nelmts; i++) {
4173             HDmemcpy(&temp1_ullong, mem1, sizeof(unsigned long long));
4174             HDmemcpy(&temp2_ullong, mem2, sizeof(unsigned long long));
4175 
4176             ull2float(temp1_ullong, &f1);
4177             ull2float(temp2_ullong, &f2);
4178             PER(f1, f2);
4179 
4180             if (not_comparable && !both_zero) {
4181                 if (print_data(opts)) {
4182                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4183                     parallel_print(SPACES);
4184                     parallel_print(ULLI_FORMAT_P_NOTCOMP,temp1_ullong,temp2_ullong,PDIFF(temp1_ullong,temp2_ullong));
4185                 }
4186                 nfound++;
4187             }
4188             else if (per > opts->percent
4189                     && PDIFF(temp1_ullong,temp2_ullong) > (unsigned long long) opts->delta) {
4190                 if (print_data(opts)) {
4191                     print_pos(ph, 1, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4192                     parallel_print(SPACES);
4193                     parallel_print(ULLI_FORMAT_P,temp1_ullong,temp2_ullong,PDIFF(temp1_ullong,temp2_ullong),per);
4194                 }
4195                 nfound++;
4196             }
4197             mem1 += sizeof(unsigned long long);
4198             mem2 += sizeof(unsigned long long);
4199             if (opts->n && nfound >= opts->count)
4200                 return nfound;
4201         }
4202     }
4203     else {
4204         for (i = 0; i < nelmts; i++) {
4205             HDmemcpy(&temp1_ullong, mem1, sizeof(unsigned long long));
4206             HDmemcpy(&temp2_ullong, mem2, sizeof(unsigned long long));
4207 
4208             if (temp1_ullong != temp2_ullong) {
4209                 if (print_data(opts)) {
4210                     print_pos(ph, 0, hyper_start + i, acc, pos, rank, dims, obj1, obj2);
4211                     parallel_print(SPACES);
4212                     parallel_print(ULLI_FORMAT,temp1_ullong,temp2_ullong,PDIFF(temp1_ullong,temp2_ullong));
4213                 }
4214                 nfound++;
4215             }
4216 
4217             mem1 += sizeof(unsigned long long);
4218             mem2 += sizeof(unsigned long long);
4219             if (opts->n && nfound >= opts->count)
4220                 return nfound;
4221         } /* nelmts */
4222     }
4223     h5difftrace("diff_ullong finish\n");
4224 
4225     return nfound;
4226 }
4227 
4228 /*-------------------------------------------------------------------------
4229  * Function:    ull2float
4230  *
4231  * Purpose:     convert unsigned long long to float
4232  *-------------------------------------------------------------------------
4233  */
4234 static
ull2float(unsigned long long ull_value,float * f_value)4235 int ull2float(unsigned long long ull_value, float *f_value)
4236 {
4237     int            ret_value = SUCCEED;
4238     hid_t          dxpl_id = -1;
4239     unsigned char *buf = NULL;
4240     size_t         src_size;
4241     size_t         dst_size;
4242 
4243     h5difftrace("ull2float start\n");
4244     if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
4245         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pcreate failed");
4246 
4247     src_size = H5Tget_size(H5T_NATIVE_ULLONG);
4248     dst_size = H5Tget_size(H5T_NATIVE_FLOAT);
4249     if((buf = (unsigned char*) HDcalloc((size_t )1, MAX(src_size, dst_size))) == NULL)
4250         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "Could not allocate buffer for dims");
4251 
4252     HDmemcpy(buf, &ull_value, src_size);
4253 
4254     /* do conversion */
4255     if (H5Tconvert(H5T_NATIVE_ULLONG, H5T_NATIVE_FLOAT, (size_t) 1, buf, NULL, dxpl_id) < 0)
4256         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tconvert failed");
4257 
4258     HDmemcpy(f_value, buf, dst_size);
4259 
4260 done:
4261     H5E_BEGIN_TRY {
4262         H5Pclose(dxpl_id);
4263     } H5E_END_TRY;
4264 
4265     if (buf)
4266         HDfree(buf);
4267 
4268     h5difftrace("ull2float finish\n");
4269 
4270     return ret_value;
4271 }
4272 
4273 /*-------------------------------------------------------------------------
4274  * Function:    equal_double
4275  *
4276  * Purpose:     use a absolute error formula to deal with floating point uncertainty
4277  *-------------------------------------------------------------------------
4278  */
equal_double(double value,double expected,diff_opt_t * opts)4279 static hbool_t equal_double(double value, double expected, diff_opt_t *opts) {
4280     h5difftrace("equal_double start\n");
4281     if (opts->do_nans) {
4282         /*-------------------------------------------------------------------------
4283         * detect NaNs
4284         *-------------------------------------------------------------------------
4285         */
4286         hbool_t isnan1 = my_isnan(FLT_DOUBLE, &value);
4287         hbool_t isnan2 = my_isnan(FLT_DOUBLE, &expected);
4288 
4289         /*-------------------------------------------------------------------------
4290         * we consider NaN == NaN to be true
4291         *-------------------------------------------------------------------------
4292         */
4293         if (isnan1 && isnan2)
4294             return TRUE;
4295 
4296         /*-------------------------------------------------------------------------
4297         * one is a NaN, do not compare but assume difference
4298         *-------------------------------------------------------------------------
4299         */
4300         if ((isnan1 && !isnan2) || (!isnan1 && isnan2))
4301             return FALSE;
4302     }
4303 
4304     if (value == expected)
4305         return TRUE;
4306 
4307     if (opts->use_system_epsilon)
4308         if (ABS((value-expected)) < DBL_EPSILON)
4309             return TRUE;
4310 
4311     h5difftrace("equal_double finish\n");
4312 
4313     return FALSE;
4314 }
4315 
4316 /*-------------------------------------------------------------------------
4317  * Function:    equal_ldouble
4318  *
4319  * Purpose:     use a absolute error formula to deal with floating point uncertainty
4320  *-------------------------------------------------------------------------
4321  */
4322 
4323 #if H5_SIZEOF_LONG_DOUBLE !=0
4324 static
equal_ldouble(long double value,long double expected,diff_opt_t * opts)4325 hbool_t equal_ldouble(long double value, long double expected, diff_opt_t *opts)
4326 {
4327     h5difftrace("equal_ldouble start\n");
4328     if (opts->do_nans) {
4329         /*-------------------------------------------------------------------------
4330          * detect NaNs
4331          *-------------------------------------------------------------------------
4332          */
4333         hbool_t isnan1 = my_isnan(FLT_LDOUBLE, &value);
4334         hbool_t isnan2 = my_isnan(FLT_LDOUBLE, &expected);
4335 
4336         /*-------------------------------------------------------------------------
4337          * we consider NaN == NaN to be true
4338          *-------------------------------------------------------------------------
4339          */
4340         if (isnan1 && isnan2)
4341             return TRUE;
4342 
4343         /*-------------------------------------------------------------------------
4344          * one is a NaN, do not compare but assume difference
4345          *-------------------------------------------------------------------------
4346          */
4347         if ((isnan1 && !isnan2) || (!isnan1 && isnan2))
4348             return FALSE;
4349     }
4350 
4351     if (value == expected)
4352         return TRUE;
4353 
4354     if (opts->use_system_epsilon)
4355         if (ABS((value-expected)) < DBL_EPSILON)
4356             return TRUE;
4357 
4358     h5difftrace("equal_ldouble finish\n");
4359 
4360     return FALSE;
4361 }
4362 
4363 #endif /* #if H5_SIZEOF_LONG_DOUBLE !=0 */
4364 
4365 /*-------------------------------------------------------------------------
4366  * Function:    equal_float
4367  *
4368  * Purpose:     use a absolute error formula to deal with floating point uncertainty
4369  *-------------------------------------------------------------------------
4370  */
equal_float(float value,float expected,diff_opt_t * opts)4371 static hbool_t equal_float(float value, float expected, diff_opt_t *opts) {
4372     h5difftrace("equal_float start\n");
4373     if (opts->do_nans) {
4374         /*-------------------------------------------------------------------------
4375         * detect NaNs
4376         *-------------------------------------------------------------------------
4377         */
4378         hbool_t isnan1 = my_isnan(FLT_FLOAT, &value);
4379         hbool_t isnan2 = my_isnan(FLT_FLOAT, &expected);
4380 
4381         /*-------------------------------------------------------------------------
4382          * we consider NaN == NaN to be true
4383          *-------------------------------------------------------------------------
4384          */
4385         if (isnan1 && isnan2)
4386             return TRUE;
4387 
4388         /*-------------------------------------------------------------------------
4389          * one is a NaN, do not compare but assume difference
4390          *-------------------------------------------------------------------------
4391          */
4392         if ((isnan1 && !isnan2) || (!isnan1 && isnan2))
4393             return FALSE;
4394     }
4395 
4396     if (value == expected)
4397         return TRUE;
4398 
4399     if (opts->use_system_epsilon)
4400         if (ABS( (value-expected) ) < FLT_EPSILON)
4401             return TRUE;
4402 
4403     h5difftrace("equal_float finish\n");
4404 
4405     return FALSE;
4406 }
4407 
4408 /*-------------------------------------------------------------------------
4409  * Function:  my_isnan
4410  *
4411  * Purpose:   Determines whether VAL points to NaN.
4412  *
4413  * Return:    TRUE or FALSE
4414  *-------------------------------------------------------------------------
4415  */
my_isnan(dtype_t type,void * val)4416 static hbool_t my_isnan(dtype_t type, void *val) {
4417     hbool_t retval = FALSE;
4418     char s[256];
4419 
4420     h5difftrace("my_isnan start\n");
4421     if (FLT_FLOAT == type) {
4422         float x;
4423 
4424         HDmemcpy(&x, val, sizeof(float));
4425         retval = (x != x);
4426     }
4427     else if (FLT_DOUBLE == type) {
4428         double x;
4429 
4430         HDmemcpy(&x, val, sizeof(double));
4431         retval = (x != x);
4432     }
4433 #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0
4434     else if (FLT_LDOUBLE == type) {
4435         long double x;
4436 
4437         HDmemcpy(&x, val, sizeof(long double));
4438         retval = (x!=x);
4439     }
4440 #endif
4441     else
4442         return FALSE;
4443 
4444     /*
4445     * Sometimes NaN==NaN (e.g., DEC Alpha) so we try to print it and see if
4446     * the result contains a NaN string.
4447     */
4448     if (!retval) {
4449         if (FLT_FLOAT == type) {
4450             float x;
4451 
4452             HDmemcpy(&x, val, sizeof(float));
4453             HDsnprintf(s, sizeof(s), "%g", (double) x);
4454         }
4455         else if (FLT_DOUBLE == type) {
4456             double x;
4457 
4458             HDmemcpy(&x, val, sizeof(double));
4459             HDsnprintf(s, sizeof(s), "%g", x);
4460         }
4461 #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0
4462         else if (FLT_LDOUBLE == type) {
4463             long double x;
4464 
4465             HDmemcpy(&x, val, sizeof(long double));
4466             HDsnprintf(s, sizeof(s), "%Lg", x);
4467         }
4468 #endif
4469         else
4470             return FALSE;
4471 
4472         if (HDstrstr(s, "NaN") ||
4473                 HDstrstr(s, "NAN") ||
4474                 HDstrstr(s, "nan") ||
4475                 HDstrstr(s, "-1.#IND")) {
4476             retval = TRUE;
4477         }
4478     }
4479 
4480     h5difftrace("my_isnan finish\n");
4481 
4482     return retval;
4483 }
4484 
4485 /*-------------------------------------------------------------------------
4486  *
4487  * Local functions
4488  *
4489  *-------------------------------------------------------------------------
4490  */
4491 
4492 /*-------------------------------------------------------------------------
4493  * Function: print_data
4494  *
4495  * Purpose:  print data only in report or verbose modes, and do not print in quiet mode
4496  *-------------------------------------------------------------------------
4497  */
4498 static
print_data(diff_opt_t * opts)4499 int print_data(diff_opt_t *opts)
4500 {
4501     return ((opts->m_report || opts->m_verbose) && !opts->m_quiet) ? 1 : 0;
4502 }
4503 
4504 /*-------------------------------------------------------------------------
4505  * Function: print_header
4506  *
4507  * Purpose:  print header for difference
4508  *-------------------------------------------------------------------------
4509  */
4510 static
print_header(int pp,int rank,hsize_t * dims,const char * obj1,const char * obj2)4511 void print_header(int pp, /* print percentage */
4512         int rank, hsize_t *dims, const char *obj1, const char *obj2)
4513 {
4514     /* print header */
4515     parallel_print("%-16s", "size:");
4516     print_dimensions(rank, dims);
4517     parallel_print("%-11s", "");
4518     print_dimensions(rank, dims);
4519     parallel_print("\n");
4520 
4521     if (pp) {
4522         parallel_print("%-15s %-15s %-15s %-15s %-15s\n", "position",
4523                 (obj1 != NULL) ? obj1 : " ", (obj2 != NULL) ? obj2 : " ", "difference", "relative");
4524         parallel_print(
4525                 "------------------------------------------------------------------------\n");
4526     }
4527     else {
4528         parallel_print("%-15s %-15s %-15s %-20s\n", "position",
4529                 (obj1 != NULL) ? obj1 : " ", (obj2 != NULL) ? obj2 : " ", "difference");
4530         parallel_print(
4531                 "------------------------------------------------------------\n");
4532     }
4533 }
4534 
4535 /*-------------------------------------------------------------------------
4536  * Function: print_pos
4537  *
4538  * Purpose:  print in matrix notation, converting from an array index position
4539  *-------------------------------------------------------------------------
4540  */
4541 static
print_pos(int * ph,int pp,hsize_t curr_pos,hsize_t * acc,hsize_t * pos,int rank,hsize_t * dims,const char * obj1,const char * obj2)4542 void print_pos(int *ph, /* print header */
4543         int pp, /* print percentage */
4544         hsize_t curr_pos, hsize_t *acc, hsize_t *pos, int rank, hsize_t *dims,
4545         const char *obj1, const char *obj2)
4546 {
4547     int i;
4548 
4549     /* print header */
4550     if (*ph == 1) {
4551         *ph = 0;
4552 
4553         print_header(pp, rank, dims, obj1, obj2);
4554     } /* end print header */
4555 
4556     for (i = 0; i < rank; i++) {
4557         pos[i] = curr_pos / acc[i];
4558         curr_pos -= acc[i] * pos[i];
4559     }
4560     HDassert(curr_pos == 0);
4561 
4562     if (rank > 0) {
4563         parallel_print("[ ");
4564         for (i = 0; i < rank; i++) {
4565             parallel_print(HSIZE_T_FORMAT, (unsigned long long)pos[i]);
4566             parallel_print(" ");
4567         }
4568         parallel_print("]");
4569     }
4570     else
4571         parallel_print("      ");
4572 }
4573 
4574 /*-------------------------------------------------------------------------
4575  * Function: print_char_pos
4576  *
4577  * Purpose:  print character position in string
4578  *-------------------------------------------------------------------------
4579  */
4580 static
print_char_pos(int * ph,int pp,hsize_t curr_pos,size_t u,hsize_t * acc,hsize_t * pos,int rank,hsize_t * dims,const char * obj1,const char * obj2)4581 void print_char_pos(int *ph, /* print header */
4582         int pp, /* print percentage */
4583         hsize_t curr_pos, size_t u, hsize_t *acc, hsize_t *pos, int rank, hsize_t *dims,
4584         const char *obj1, const char *obj2)
4585 {
4586     int i;
4587 
4588     /* print header */
4589     if (*ph == 1) {
4590         *ph = 0;
4591 
4592         print_header(pp, rank, dims, obj1, obj2);
4593     } /* end print header */
4594 
4595     for (i = 0; i < rank; i++) {
4596         pos[i] = curr_pos / acc[i];
4597         curr_pos -= acc[i] * pos[i];
4598     }
4599     HDassert(curr_pos == 0);
4600 
4601     parallel_print("[ ");
4602     if (rank > 0) {
4603         for (i = 0; i < rank; i++) {
4604             parallel_print(HSIZE_T_FORMAT, (unsigned long long)pos[i]);
4605             parallel_print(" ");
4606         }
4607 
4608     }
4609     else
4610         parallel_print("%zu", u);
4611 
4612     parallel_print("]");
4613 }
4614 
4615 /*-------------------------------------------------------------------------
4616  * Function: h5diff_print_char. Adapted from h5tools_print_char
4617  *
4618  * Purpose:  Print a char
4619  *-------------------------------------------------------------------------
4620  */
h5diff_print_char(char ch)4621 static void h5diff_print_char(char ch)
4622 {
4623     switch (ch) {
4624     case '"':
4625         parallel_print("\\\"");
4626         break;
4627     case '\\':
4628         parallel_print("\\\\");
4629         break;
4630     case '\b':
4631         parallel_print("\\b");
4632         break;
4633     case '\f':
4634         parallel_print("\\f");
4635         break;
4636     case '\n':
4637         parallel_print("\\n");
4638         break;
4639     case '\r':
4640         parallel_print("\\r");
4641         break;
4642     case '\t':
4643         parallel_print("\\t");
4644         break;
4645     default:
4646         if (isprint(ch))
4647             parallel_print("%c", ch);
4648         else
4649             parallel_print("\\%03o", ch);
4650         break;
4651     }
4652 }
4653 
4654 /*-------------------------------------------------------------------------
4655  * added to improve performance for compound datasets
4656  * set up compound datatype structures.
4657  *-------------------------------------------------------------------------
4658  */
get_member_types(hid_t tid,mcomp_t * members)4659 static void get_member_types(hid_t tid, mcomp_t *members)
4660 {
4661     int      tclass;
4662     unsigned u;
4663 
4664     if (tid <= 0 || !members)
4665         return;
4666 
4667     tclass = H5Tget_class(tid);
4668     if (tclass == H5T_ARRAY || tclass == H5T_VLEN) {
4669         hid_t base_tid = H5Tget_super(tid);
4670         get_member_types(base_tid, members);
4671         H5Tclose(base_tid);
4672     }
4673     else if (tclass == H5T_COMPOUND) {
4674         int nmembs;
4675 
4676         if ((nmembs = H5Tget_nmembers(tid)) <= 0)
4677             return;
4678         members->n = (unsigned) nmembs;
4679 
4680         members->ids = (hid_t *) HDcalloc((size_t )members->n, sizeof(hid_t));
4681         members->offsets = (size_t *) HDcalloc((size_t )members->n, sizeof(size_t));
4682         members->m = (mcomp_t **) HDcalloc((size_t )members->n, sizeof(mcomp_t *));
4683 
4684         for (u = 0; u < members->n; u++) {
4685             members->ids[u] = H5Tget_member_type(tid, u);
4686             members->offsets[u] = H5Tget_member_offset(tid, u);
4687             members->m[u] = (mcomp_t *) HDmalloc(sizeof(mcomp_t));
4688             HDmemset(members->m[u], 0, sizeof(mcomp_t));
4689             get_member_types(members->ids[u], members->m[u]);
4690         }
4691     }
4692 
4693     return;
4694 }
4695 
4696 /*-------------------------------------------------------------------------
4697  * added to improve performance for compound datasets
4698  * clean and close compound members.
4699  *-------------------------------------------------------------------------
4700  */
close_member_types(mcomp_t * members)4701 static void close_member_types(mcomp_t *members)
4702 {
4703     unsigned u;
4704 
4705     if (!members || members->n <= 0 || !members->ids)
4706         return;
4707 
4708     for (u = 0; u < members->n; u++) {
4709         if (members->m[u]) {
4710             close_member_types(members->m[u]);
4711             HDfree(members->m[u]);
4712         }
4713         H5Tclose(members->ids[u]);
4714     }
4715 
4716     HDfree(members->m);
4717     HDfree(members->ids);
4718     HDfree(members->offsets);
4719 }
4720 
4721