summaryrefslogtreecommitdiffstats
path: root/tools/lib/h5diff_array.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/h5diff_array.c')
-rw-r--r--tools/lib/h5diff_array.c400
1 files changed, 259 insertions, 141 deletions
diff --git a/tools/lib/h5diff_array.c b/tools/lib/h5diff_array.c
index dc3c9fb..105462f 100644
--- a/tools/lib/h5diff_array.c
+++ b/tools/lib/h5diff_array.c
@@ -182,6 +182,13 @@ typedef enum dtype_t
static int my_isnan(dtype_t type, void *val);
+/*-------------------------------------------------------------------------
+ * XCAO, 11/10/2010
+ * added to improve performance for compound datasets
+ */
+static void set_comp_members(hid_t tid, mcomp_t *members);
+static void free_comp_members(mcomp_t *members);
+
/*-------------------------------------------------------------------------
@@ -220,10 +227,23 @@ hsize_t diff_array( void *_mem1,
int ph=1; /* print header */
hsize_t i;
int j;
-
+ mcomp_t members;
+ H5T_class_t type_class;
/* get the size. */
size = H5Tget_size( m_type );
+ type_class = H5Tget_class(m_type);
+
+ /* Fast comparison first for atomic type by memcmp().
+ * It is OK not to list non-atomic type here because it will not be caught
+ * by the confition, but it gives more clarity for code planning
+ */
+ if (type_class != H5T_REFERENCE &&
+ type_class != H5T_COMPOUND &&
+ type_class != H5T_STRING &&
+ type_class != H5T_VLEN &&
+ HDmemcmp(mem1, mem2, size*nelmts)==0)
+ return 0;
if ( rank > 0 )
{
@@ -237,13 +257,74 @@ hsize_t diff_array( void *_mem1,
pos[j]=0;
}
- if(H5Tis_variable_str(m_type))
+ switch (type_class)
{
+ default:
+ assert(0);
+ break;
+
+ /*-------------------------------------------------------------------------
+ * float and integer atomic types
+ *-------------------------------------------------------------------------
+ */
+
+ case H5T_FLOAT:
+
+ if (H5Tequal(m_type, H5T_NATIVE_FLOAT))
+ nfound=diff_float(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_DOUBLE))
+ nfound=diff_double(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+#if H5_SIZEOF_LONG_DOUBLE !=0
+ else if (H5Tequal(m_type, H5T_NATIVE_LDOUBLE))
+ nfound=diff_ldouble(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+#endif
+ break;
+
+ case H5T_INTEGER:
+
+ if (H5Tequal(m_type, H5T_NATIVE_SCHAR))
+ nfound=diff_schar(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_UCHAR))
+ nfound=diff_uchar(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_SHORT))
+ nfound=diff_short(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_USHORT))
+ nfound=diff_ushort(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_INT))
+ nfound=diff_int(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_UINT))
+ nfound=diff_uint(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_LONG))
+ nfound=diff_long(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_ULONG))
+ nfound=diff_ulong(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_LLONG))
+ nfound=diff_llong(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+ else if (H5Tequal(m_type, H5T_NATIVE_ULLONG))
+ nfound=diff_ullong(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
+
+ break;
+
+ /*-------------------------------------------------------------------------
+ * Other types than float and integer
+ *-------------------------------------------------------------------------
+ */
+
+ case H5T_COMPOUND:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_ENUM:
+ case H5T_ARRAY:
+ case H5T_VLEN:
+ case H5T_REFERENCE:
+ HDmemset(&members, 0, sizeof (mcomp_t));
+ set_comp_members(m_type, &members);
for ( i = 0; i < nelmts; i++)
{
nfound+=diff_datum(
- ((unsigned char**)mem1)[(size_t)i],
- ((unsigned char**)mem2)[(size_t)i],
+ mem1 + i * size,
+ mem2 + i * size, /* offset */
m_type,
i,
rank,
@@ -255,98 +336,15 @@ hsize_t diff_array( void *_mem1,
name2,
container1_id,
container2_id,
- &ph);
+ &ph, &members);
if (options->n && nfound>=options->count)
+ {
+ free_comp_members(&members);
return nfound;
+ }
} /* i */
- }
-
- else
- {
- switch (H5Tget_class(m_type))
- {
- default:
- assert(0);
- break;
-
- /*-------------------------------------------------------------------------
- * float and integer atomic types
- *-------------------------------------------------------------------------
- */
-
- case H5T_FLOAT:
-
- if (H5Tequal(m_type, H5T_NATIVE_FLOAT))
- nfound=diff_float(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_DOUBLE))
- nfound=diff_double(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
-#if H5_SIZEOF_LONG_DOUBLE !=0
- else if (H5Tequal(m_type, H5T_NATIVE_LDOUBLE))
- nfound=diff_ldouble(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
-#endif
- break;
-
- case H5T_INTEGER:
-
- if (H5Tequal(m_type, H5T_NATIVE_SCHAR))
- nfound=diff_schar(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_UCHAR))
- nfound=diff_uchar(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_SHORT))
- nfound=diff_short(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_USHORT))
- nfound=diff_ushort(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_INT))
- nfound=diff_int(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_UINT))
- nfound=diff_uint(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_LONG))
- nfound=diff_long(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_ULONG))
- nfound=diff_ulong(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_LLONG))
- nfound=diff_llong(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
- else if (H5Tequal(m_type, H5T_NATIVE_ULLONG))
- nfound=diff_ullong(mem1,mem2,nelmts,hyper_start,rank,dims,acc,pos,options,name1,name2,&ph);
-
- break;
-
- /*-------------------------------------------------------------------------
- * Other types than float and integer
- *-------------------------------------------------------------------------
- */
-
- case H5T_COMPOUND:
- case H5T_STRING:
- case H5T_BITFIELD:
- case H5T_OPAQUE:
- case H5T_ENUM:
- case H5T_ARRAY:
- case H5T_VLEN:
- case H5T_REFERENCE:
-
- for ( i = 0; i < nelmts; i++)
- {
- nfound+=diff_datum(
- mem1 + i * size,
- mem2 + i * size, /* offset */
- m_type,
- i,
- rank,
- dims,
- acc,
- pos,
- options,
- name1,
- name2,
- container1_id,
- container2_id,
- &ph);
- if (options->n && nfound>=options->count)
- return nfound;
- } /* i */
- } /* switch */
- } /* else */
+ free_comp_members(&members);
+ } /* switch */
return nfound;
}
@@ -388,7 +386,6 @@ hsize_t diff_array( void *_mem1,
* Dereference the object and compare the type (basic object type).
*-------------------------------------------------------------------------
*/
-
hsize_t diff_datum(void *_mem1,
void *_mem2,
hid_t m_type,
@@ -402,13 +399,16 @@ hsize_t diff_datum(void *_mem1,
const char *obj2,
hid_t container1_id,
hid_t container2_id, /*where the reference came from*/
- int *ph) /*print header */
+ int *ph, /*print header */
+ mcomp_t *members) /*compound members */
{
unsigned char *mem1 = (unsigned char*)_mem1;
unsigned char *mem2 = (unsigned char*)_mem2;
unsigned u;
hid_t memb_type;
size_t type_size;
+ H5T_sign_t type_sign;
+ H5T_class_t type_class;
size_t offset;
int nmembs;
int j;
@@ -425,6 +425,18 @@ hsize_t diff_datum(void *_mem1,
int both_zero;
type_size = H5Tget_size( m_type );
+ type_class = H5Tget_class(m_type);
+
+ /* Fast comparison first for atomic type by memcmp().
+ * It is OK not to list non-atomic type here because it will not be caught
+ * by the confition, but it gives more clarity for code planning
+ */
+ if (type_class != H5T_REFERENCE &&
+ type_class != H5T_COMPOUND &&
+ type_class != H5T_STRING &&
+ type_class != H5T_VLEN &&
+ HDmemcmp(mem1, mem2, type_size)==0)
+ return 0;
switch (H5Tget_class(m_type))
{
@@ -441,12 +453,14 @@ hsize_t diff_datum(void *_mem1,
*/
case H5T_COMPOUND:
- nmembs = H5Tget_nmembers(m_type);
+ nmembs = members->n;
+
for (j = 0; j < nmembs; j++)
{
- offset = H5Tget_member_offset(m_type, (unsigned)j);
- memb_type = H5Tget_member_type(m_type, (unsigned)j);
+ offset = members->offsets[j];
+ memb_type = members->ids[j];
+
nfound+=diff_datum(
mem1+offset,
mem2+offset,
@@ -461,8 +475,7 @@ hsize_t diff_datum(void *_mem1,
obj2,
container1_id,
container2_id,
- ph);
- H5Tclose(memb_type);
+ ph, members->m[j]);
}
break;
@@ -475,24 +488,61 @@ hsize_t diff_datum(void *_mem1,
{
H5T_str_t pad;
char *s;
+ char *s1;
+ char *s2;
+ size_t size1;
+ size_t size2;
+
+ /* if variable length string */
+ if(H5Tis_variable_str(m_type))
+ {
+ /* Get pointer to first string */
+ s1 = *(char**) mem1;
+ size1 = HDstrlen(s1);
+ /* Get pointer to second string */
+ s2 = *(char**) mem2;
+ size2 = HDstrlen(s2);
+ }
+ else
+ {
+ /* Get pointer to first string */
+ s1 = mem1;
+ size1 = H5Tget_size(m_type);
+ /* Get pointer to second string */
+ s2 = mem2;
+ size2 = H5Tget_size(m_type);
+ }
- /* Get pointer to first string to compare */
- s = (char *)mem1;
+ /*
+ * compare for shorter string
+ * TODO: this code need to be improved to handle the difference
+ * of length of strings.
+ * For now mimic the previous way.
+ */
+ if(size1 < size2)
+ {
+ size = size1;
+ s = s1;
+ }
+ else
+ {
+ size = size2;
+ s = s2;
+ }
/* check for NULL pointer for string */
if(s!=NULL)
{
- if(H5Tis_variable_str(m_type))
- size = HDstrlen(s);
- else
- size = H5Tget_size(m_type);
+ /* try fast compare first */
+ if (HDmemcmp(s1, s2, size)==0)
+ break;
pad = H5Tget_strpad(m_type);
for (u=0; u<size && (s[u] || pad!=H5T_STR_NULLTERM); u++)
nfound+=character_compare(
- mem1 + u,
- mem2 + u, /* offset */
+ s1 + u,
+ s2 + u, /* offset */
i, /* index position */
u, /* string character position */
rank,
@@ -631,21 +681,23 @@ hsize_t diff_datum(void *_mem1,
for (u = 0, nelmts = 1; u <ndims; u++)
nelmts *= adims[u];
for (u = 0; u < nelmts; u++)
- nfound+=diff_datum(
- mem1 + u * size,
- mem2 + u * size, /* offset */
- memb_type,
- i, /* index position */
- rank,
- dims,
- acc,
- pos,
- options,
- obj1,
- obj2,
- container1_id,
- container2_id,
- ph);
+ {
+ nfound+=diff_datum(
+ mem1 + u * size,
+ mem2 + u * size, /* offset */
+ memb_type,
+ i, /* index position */
+ rank,
+ dims,
+ acc,
+ pos,
+ options,
+ obj1,
+ obj2,
+ container1_id,
+ container2_id,
+ ph, NULL);
+ }
H5Tclose(memb_type);
}
break;
@@ -673,8 +725,7 @@ hsize_t diff_datum(void *_mem1,
* Dataset region reference
*-------------------------------------------------------------------------
*/
-
- if (H5Tequal(m_type, H5T_STD_REF_DSETREG))
+ if (type_size==H5R_DSET_REG_REF_BUF_SIZE)
{
hid_t region1_id;
hid_t region2_id;
@@ -708,7 +759,7 @@ hsize_t diff_datum(void *_mem1,
* Object references. get the type and OID of the referenced object
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_STD_REF_OBJ))
+ else if (type_size == H5R_OBJ_REF_BUF_SIZE)
{
H5O_type_t obj1_type;
H5O_type_t obj2_type;
@@ -792,7 +843,7 @@ hsize_t diff_datum(void *_mem1,
obj2,
container1_id,
container2_id,
- ph);
+ ph, NULL);
H5Tclose(memb_type);
@@ -806,13 +857,13 @@ hsize_t diff_datum(void *_mem1,
*/
case H5T_INTEGER:
-
+ type_sign = H5Tget_sign(m_type);
/*-------------------------------------------------------------------------
* H5T_NATIVE_SCHAR
*-------------------------------------------------------------------------
*/
- if (H5Tequal(m_type, H5T_NATIVE_SCHAR))
+ if (type_size==1 && type_sign!=H5T_SGN_NONE)
{
char temp1_char;
char temp2_char;
@@ -908,7 +959,7 @@ hsize_t diff_datum(void *_mem1,
* H5T_NATIVE_UCHAR
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_UCHAR))
+ else if (type_size==1 && type_sign==H5T_SGN_NONE)
{
unsigned char temp1_uchar;
unsigned char temp2_uchar;
@@ -1007,7 +1058,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_SHORT))
+ else if (type_size==2 && type_sign!=H5T_SGN_NONE)
{
short temp1_short;
short temp2_short;
@@ -1106,7 +1157,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_USHORT))
+ else if (type_size==2 && type_sign==H5T_SGN_NONE)
{
unsigned short temp1_ushort;
unsigned short temp2_ushort;
@@ -1206,7 +1257,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_INT))
+ else if (type_size==4 && type_sign!=H5T_SGN_NONE)
{
int temp1_int;
int temp2_int;
@@ -1304,7 +1355,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_UINT))
+ else if (type_size==4 && type_sign==H5T_SGN_NONE)
{
unsigned int temp1_uint;
unsigned int temp2_uint;
@@ -1402,7 +1453,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_LONG))
+ else if (type_size==8 && type_sign!=H5T_SGN_NONE)
{
long temp1_long;
long temp2_long;
@@ -1502,7 +1553,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_ULONG))
+ else if (type_size==8 && type_sign==H5T_SGN_NONE)
{
unsigned long temp1_ulong;
unsigned long temp2_ulong;
@@ -1601,7 +1652,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_LLONG))
+ else if (type_size==8 && type_sign!=H5T_SGN_NONE)
{
long long temp1_llong;
long long temp2_llong;
@@ -1699,7 +1750,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_ULLONG))
+ else if (type_size==8 && type_sign==H5T_SGN_NONE)
{
unsigned long long temp1_ullong;
unsigned long long temp2_ullong;
@@ -1816,7 +1867,7 @@ hsize_t diff_datum(void *_mem1,
* H5T_NATIVE_FLOAT
*-------------------------------------------------------------------------
*/
- if (H5Tequal(m_type, H5T_NATIVE_FLOAT))
+ if (type_size==4)
{
float temp1_float;
float temp2_float;
@@ -2029,7 +2080,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_DOUBLE))
+ else if (type_size==8)
{
double temp1_double;
double temp2_double;
@@ -2245,7 +2296,7 @@ hsize_t diff_datum(void *_mem1,
*-------------------------------------------------------------------------
*/
- else if (H5Tequal(m_type, H5T_NATIVE_LDOUBLE))
+ else if (type_size==8)
{
long double temp1_double;
long double temp2_double;
@@ -6000,3 +6051,70 @@ static void h5diff_print_char(char ch)
break;
}
}
+
+
+/*-------------------------------------------------------------------------
+ * XCAO, 11/10/2010
+ * added to improve performance for compound datasets
+ * set up compound datatype structures.
+ */
+static void set_comp_members(hid_t tid, mcomp_t *members)
+{
+ int i;
+
+ if (tid <=0 || !members)
+ return;
+
+ if (H5Tget_class(tid) != H5T_COMPOUND)
+ return;
+
+ members->n = H5Tget_nmembers( tid );
+ if (members->n <=0)
+ return;
+
+ members->ids = HDcalloc(members->n, sizeof(hid_t));
+ members->flags = HDcalloc(members->n, sizeof(unsigned char));
+ members->offsets = HDcalloc(members->n, sizeof(size_t));
+ members->m = HDcalloc(members->n, sizeof(mcomp_t *));
+
+ for (i=0; i< members->n; i++)
+ {
+ members->ids[i] = H5Tget_member_type( tid, i );
+ members->flags[i] = H5Tis_variable_str( members->ids[i] );
+ members->offsets[i] = H5Tget_member_offset( tid, i );
+ if (H5Tget_class( members->ids[i])==H5T_COMPOUND)
+ {
+ members->m[i] = (mcomp_t *)HDmalloc(sizeof(mcomp_t));
+ set_comp_members(members->ids[i], members->m[i]);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * XCAO, 11/10/2010
+ * added to improve performance for compound datasets
+ * clean and close compound members.
+ */
+static void free_comp_members(mcomp_t *members)
+{
+ int i;
+
+ if (!members || members->n<=0 || !members->ids)
+ return;
+
+ for (i=0; i<members->n; i++)
+ {
+ if (members->m[i])
+ {
+ free_comp_members(members->m[i]);
+ HDfree(members->m[i]);
+ }
+ H5Tclose(members->ids[i]);
+ }
+
+ HDfree (members->m);
+ HDfree (members->ids);
+ HDfree (members->flags);
+ HDfree (members->offsets);
+}
+