diff options
Diffstat (limited to 'tools/lib/h5diff_array.c')
-rw-r--r-- | tools/lib/h5diff_array.c | 400 |
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); +} + |