/*----------------------------------------------------------------- * Function: match_up_memsize * * Purpose: match smaller memory size up to bigger memory size *------------------------------------------------------------------ */ herr_t match_up_memsize (hid_t f_tid1_id, hid_t f_tid2_id, hid_t *m_tid1, hid_t *m_tid2, size_t *m_size1, size_t *m_size2) { herr_t ret = SUCCEED; if( (*m_size1) != (*m_size2) ) { if( (*m_size1) < (*m_size2) ) { H5Tclose( *m_tid1 ); if(( (*m_tid1) = h5tools_get_native_type(f_tid2_id)) < 0) { ret = FAIL; goto out; } *m_size1 = H5Tget_size( *m_tid1 ); } /* end if */ else { H5Tclose(*m_tid2); if(( (*m_tid2) = h5tools_get_native_type(f_tid1_id)) < 0) { ret = FAIL; goto out; } *m_size2 = H5Tget_size(*m_tid2); } /* end else */ } /* end if */ HDassert( (*m_size1) == (*m_size2) ); out: return ret; }
int do_copy_refobjs(hid_t fidin, hid_t fidout, trav_table_t *travt, pack_opt_t *options) /* repack options */ { hid_t grp_in=(-1); /* read group ID */ hid_t grp_out=(-1); /* write group ID */ hid_t dset_in=(-1); /* read dataset ID */ hid_t dset_out=(-1); /* write dataset ID */ hid_t type_in=(-1); /* named type ID */ hid_t dcpl_id=(-1); /* dataset creation property list ID */ hid_t space_id=(-1); /* space ID */ hid_t ftype_id=(-1); /* file data type ID */ hid_t mtype_id=(-1); /* memory data type ID */ size_t msize; /* memory size of memory type */ hsize_t nelmts; /* number of elements in dataset */ int rank; /* rank of dataset */ hsize_t dims[H5S_MAX_RANK]; /* dimensions of dataset */ unsigned int i, j; int k; /*------------------------------------------------------------------------- * browse *------------------------------------------------------------------------- */ for ( i = 0; i < travt->nobjs; i++) { switch ( travt->objs[i].type ) { /*------------------------------------------------------------------------- * H5G_GROUP *------------------------------------------------------------------------- */ case H5G_GROUP: /*------------------------------------------------------------------------- * copy referenced objects in attributes *------------------------------------------------------------------------- */ if ((grp_out=H5Gopen(fidout,travt->objs[i].name))<0) goto error; if((grp_in = H5Gopen (fidin,travt->objs[i].name))<0) goto error; if (copy_refs_attr(grp_in,grp_out,options,travt,fidout)<0) goto error; if (H5Gclose(grp_out)<0) goto error; if (H5Gclose(grp_in)<0) goto error; /*------------------------------------------------------------------------- * check for hard links *------------------------------------------------------------------------- */ if (travt->objs[i].nlinks) { for ( j=0; j<travt->objs[i].nlinks; j++) { H5Glink(fidout, H5G_LINK_HARD, travt->objs[i].name, travt->objs[i].links[j].new_name); } } break; /*------------------------------------------------------------------------- * H5G_DATASET *------------------------------------------------------------------------- */ case H5G_DATASET: if ((dset_in=H5Dopen(fidin,travt->objs[i].name))<0) goto error; if ((space_id=H5Dget_space(dset_in))<0) goto error; if ((ftype_id=H5Dget_type (dset_in))<0) goto error; if ((dcpl_id=H5Dget_create_plist(dset_in))<0) goto error; if ( (rank=H5Sget_simple_extent_ndims(space_id))<0) goto error; if ( H5Sget_simple_extent_dims(space_id,dims,NULL)<0) goto error; nelmts=1; for (k=0; k<rank; k++) nelmts*=dims[k]; if ((mtype_id=h5tools_get_native_type(ftype_id))<0) goto error; if ((msize=H5Tget_size(mtype_id))==0) goto error; /*------------------------------------------------------------------------- * check if the dataset creation property list has filters that * are not registered in the current configuration * 1) the external filters GZIP and SZIP might not be available * 2) the internal filters might be turned off *------------------------------------------------------------------------- */ if (h5tools_canreadf((NULL),dcpl_id)==1) { /*------------------------------------------------------------------------- * test for a valid output dataset *------------------------------------------------------------------------- */ dset_out = FAIL; /*------------------------------------------------------------------------- * object references are a special case * we cannot just copy the buffers, but instead we recreate the reference *------------------------------------------------------------------------- */ if (H5Tequal(mtype_id, H5T_STD_REF_OBJ)) { H5G_obj_t1 obj_type; hid_t refobj_id; hobj_ref_t *refbuf=NULL; /* buffer for object references */ hobj_ref_t *buf=NULL; const char* refname; unsigned u; /*------------------------------------------------------------------------- * read to memory *------------------------------------------------------------------------- */ if (nelmts) { buf=(void *) HDmalloc((unsigned)(nelmts*msize)); if ( buf==NULL){ printf( "cannot read into memory\n" ); goto error; } if (H5Dread(dset_in,mtype_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf)<0) goto error; if ((obj_type = H5Rget_obj_type(dset_in,H5R_OBJECT,buf))<0) goto error; refbuf=HDcalloc((unsigned)nelmts,msize); if ( refbuf==NULL){ printf( "cannot allocate memory\n" ); goto error; } for ( u=0; u<nelmts; u++) { H5E_BEGIN_TRY { if ((refobj_id = H5Rdereference(dset_in,H5R_OBJECT,&buf[u]))<0) continue; } H5E_END_TRY; /* get the name. a valid name could only occur in the second traversal of the file */ if ((refname=MapIdToName(refobj_id,travt))!=NULL) { /* create the reference, -1 parameter for objects */ if (H5Rcreate(&refbuf[u],fidout,refname,H5R_OBJECT,-1)<0) goto error; if(options->verbose) { printf(FORMAT_OBJ,"dset",travt->objs[i].name ); printf("object <%s> object reference created to <%s>\n", travt->objs[i].name, refname); } }/*refname*/ close_obj(obj_type,refobj_id); }/* u */ }/*nelmts*/ /*------------------------------------------------------------------------- * create/write dataset/close *------------------------------------------------------------------------- */ if ((dset_out=H5Dcreate(fidout,travt->objs[i].name,mtype_id,space_id,dcpl_id))<0) goto error; if (nelmts) { if (H5Dwrite(dset_out,mtype_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,refbuf)<0) goto error; } if (buf) free(buf); if (refbuf) free(refbuf); }/*H5T_STD_REF_OBJ*/ /*------------------------------------------------------------------------- * dataset region references *------------------------------------------------------------------------- */ else if (H5Tequal(mtype_id, H5T_STD_REF_DSETREG)) { H5G_obj_t1 obj_type; hid_t refobj_id; hdset_reg_ref_t *refbuf=NULL; /* input buffer for region references */ hdset_reg_ref_t *buf=NULL; /* output buffer */ const char* refname; unsigned u; /*------------------------------------------------------------------------- * read input to memory *------------------------------------------------------------------------- */ if (nelmts) { buf=(void *) HDmalloc((unsigned)(nelmts*msize)); if ( buf==NULL){ printf( "cannot read into memory\n" ); goto error; } if (H5Dread(dset_in,mtype_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf)<0) goto error; if ((obj_type = H5Rget_obj_type(dset_in,H5R_DATASET_REGION,buf))<0) goto error; /*------------------------------------------------------------------------- * create output *------------------------------------------------------------------------- */ refbuf=HDcalloc(sizeof(hdset_reg_ref_t),(size_t)nelmts); /*init to zero */ if ( refbuf==NULL){ printf( "cannot allocate memory\n" ); goto error; } for ( u=0; u<nelmts; u++) { H5E_BEGIN_TRY { if ((refobj_id = H5Rdereference(dset_in,H5R_DATASET_REGION,&buf[u]))<0) continue; } H5E_END_TRY; /* get the name. a valid name could only occur in the second traversal of the file */ if ((refname=MapIdToName(refobj_id,travt))!=NULL) { hid_t region_id; /* region id of the referenced dataset */ if ((region_id = H5Rget_region(dset_in,H5R_DATASET_REGION,&buf[u]))<0) goto error; /* create the reference, we need the space_id */ if (H5Rcreate(&refbuf[u],fidout,refname,H5R_DATASET_REGION,region_id)<0) goto error; if (H5Sclose(region_id)<0) goto error; if(options->verbose) { printf(FORMAT_OBJ,"dset",travt->objs[i].name ); printf("object <%s> region reference created to <%s>\n", travt->objs[i].name, refname); } }/*refname*/ close_obj(obj_type,refobj_id); }/* u */ }/*nelmts*/ /*------------------------------------------------------------------------- * create/write dataset/close *------------------------------------------------------------------------- */ if ((dset_out=H5Dcreate(fidout,travt->objs[i].name,mtype_id,space_id,dcpl_id))<0) goto error; if (nelmts) { if (H5Dwrite(dset_out,mtype_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,refbuf)<0) goto error; } if (buf) free(buf); if (refbuf) free(refbuf); } /* H5T_STD_REF_DSETREG */ /*------------------------------------------------------------------------- * not references, open previously created object in 1st traversal *------------------------------------------------------------------------- */ else { if ((dset_out=H5Dopen(fidout,travt->objs[i].name))<0) goto error; } assert(dset_out!=FAIL); /*------------------------------------------------------------------------- * copy referenced objects in attributes *------------------------------------------------------------------------- */ if (copy_refs_attr(dset_in,dset_out,options,travt,fidout)<0) goto error; /*------------------------------------------------------------------------- * check for hard links *------------------------------------------------------------------------- */ if (travt->objs[i].nlinks) { for ( j=0; j<travt->objs[i].nlinks; j++){ H5Glink(fidout, H5G_LINK_HARD, travt->objs[i].name, travt->objs[i].links[j].new_name); } } if (H5Dclose(dset_out)<0) goto error; }/*can_read*/
hsize_t diff_attr(hid_t loc1_id, hid_t loc2_id, const char *path1, const char *path2, diff_opt_t *options) { hid_t attr1_id=-1; /* attr ID */ hid_t attr2_id=-1; /* attr ID */ hid_t space1_id=-1; /* space ID */ hid_t space2_id=-1; /* space ID */ hid_t ftype1_id=-1; /* file data type ID */ hid_t ftype2_id=-1; /* file data type ID */ hid_t mtype1_id=-1; /* memory data type ID */ hid_t mtype2_id=-1; /* memory data type ID */ size_t msize1; /* memory size of memory type */ size_t msize2; /* memory size of memory type */ void *buf1=NULL; /* data buffer */ void *buf2=NULL; /* data buffer */ hsize_t nelmts1; /* number of elements in dataset */ int rank1; /* rank of dataset */ int rank2; /* rank of dataset */ hsize_t dims1[H5S_MAX_RANK];/* dimensions of dataset */ hsize_t dims2[H5S_MAX_RANK];/* dimensions of dataset */ char name1[512]; char name2[512]; char np1[512]; char np2[512]; H5O_info_t oinfo1, oinfo2; /* Object info */ unsigned u; /* Local index variable */ hsize_t nfound = 0; hsize_t nfound_total = 0; int j; if(H5Oget_info(loc1_id, &oinfo1) < 0) goto error; if(H5Oget_info(loc2_id, &oinfo2) < 0) goto error; if(oinfo1.num_attrs != oinfo2.num_attrs) return 1; for( u = 0; u < (unsigned)oinfo1.num_attrs; u++) { /* reset buffers for every attribute, we might goto out and call free */ buf1 = NULL; buf2 = NULL; /* open attribute */ if((attr1_id = H5Aopen_by_idx(loc1_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; /* get name */ if(H5Aget_name(attr1_id, 255, name1) < 0) goto error; /* use the name on the first file to open the second file */ H5E_BEGIN_TRY { if((attr2_id = H5Aopen(loc2_id, name1, H5P_DEFAULT)) < 0) goto error; } H5E_END_TRY; /* get name */ if(H5Aget_name(attr2_id, 255, name2) < 0) goto error; /* get the datatypes */ if ((ftype1_id = H5Aget_type(attr1_id)) < 0) goto error; if ((ftype2_id = H5Aget_type(attr2_id)) < 0) goto error; if ((mtype1_id = h5tools_get_native_type(ftype1_id))<0) goto error; if ((mtype2_id = h5tools_get_native_type(ftype2_id))<0) goto error; if ((msize1 = H5Tget_size(mtype1_id))==0) goto error; if ((msize2 = H5Tget_size(mtype2_id))==0) goto error; /* get the dataspace */ if ((space1_id = H5Aget_space(attr1_id)) < 0) goto error; if ((space2_id = H5Aget_space(attr2_id)) < 0) goto error; /* get dimensions */ if ( (rank1 = H5Sget_simple_extent_dims(space1_id, dims1, NULL)) < 0 ) goto error; if ( (rank2 = H5Sget_simple_extent_dims(space2_id, dims2, NULL)) < 0 ) goto error; /*------------------------------------------------------------------------- * check for comparable TYPE and SPACE *------------------------------------------------------------------------- */ if ( msize1 != msize2 || diff_can_type(ftype1_id, ftype2_id, rank1, rank2, dims1, dims2, NULL, NULL, name1, name2, options, 0)!=1) { if (H5Tclose(ftype1_id)<0) goto error; if (H5Tclose(ftype2_id)<0) goto error; if (H5Sclose(space1_id)<0) goto error; if (H5Sclose(space2_id)<0) goto error; if (H5Aclose(attr1_id)<0) goto error; if (H5Aclose(attr2_id)<0) goto error; if (H5Tclose(mtype1_id)<0) goto error; if (H5Tclose(mtype2_id)<0) goto error; continue; } /*------------------------------------------------------------------------- * read *------------------------------------------------------------------------- */ nelmts1=1; for (j=0; j<rank1; j++) nelmts1*=dims1[j]; buf1=(void *) HDmalloc((unsigned)(nelmts1*msize1)); buf2=(void *) HDmalloc((unsigned)(nelmts1*msize2)); if ( buf1==NULL || buf2==NULL){ parallel_print( "cannot read into memory\n" ); goto error; } if (H5Aread(attr1_id,mtype1_id,buf1)<0) goto error; if (H5Aread(attr2_id,mtype2_id,buf2)<0) goto error; /* format output string */ sprintf(np1,"%s of <%s>",name1,path1); sprintf(np2,"%s of <%s>",name2,path2); /*------------------------------------------------------------------------- * array compare *------------------------------------------------------------------------- */ /* always print name */ if (options->m_verbose) { do_print_objname ("attribute", np1, np2); nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, np1, np2, mtype1_id, attr1_id, attr2_id); print_found(nfound); } /* check first if we have differences */ else { if (options->m_quiet==0) { /* shut up temporarily */ options->m_quiet=1; nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, np1, np2, mtype1_id, attr1_id, attr2_id); /* print again */ options->m_quiet=0; if (nfound) { do_print_objname ("attribute", np1, np2); nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, np1, np2, mtype1_id, attr1_id, attr2_id); print_found(nfound); } /*if*/ } /*if*/ /* in quiet mode, just count differences */ else { nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, np1, np2, mtype1_id, attr1_id, attr2_id); } /*else quiet */ } /*else verbose */ /*------------------------------------------------------------------------- * close *------------------------------------------------------------------------- */ if (H5Tclose(ftype1_id)<0) goto error; if (H5Tclose(ftype2_id)<0) goto error; if (H5Sclose(space1_id)<0) goto error; if (H5Sclose(space2_id)<0) goto error; if (H5Aclose(attr1_id)<0) goto error; if (H5Aclose(attr2_id)<0) goto error; if (H5Tclose(mtype1_id)<0) goto error; if (H5Tclose(mtype2_id)<0) goto error; if (buf1) HDfree(buf1); if (buf2) HDfree(buf2); nfound_total += nfound; } /* u */ return nfound_total; error: H5E_BEGIN_TRY { H5Tclose(ftype1_id); H5Tclose(ftype2_id); H5Tclose(mtype1_id); H5Tclose(mtype2_id); H5Sclose(space1_id); H5Sclose(space2_id); H5Aclose(attr1_id); H5Aclose(attr2_id); if (buf1) HDfree(buf1); if (buf2) HDfree(buf2); } H5E_END_TRY; options->err_stat=1; return nfound_total; }
int main(void) { hid_t fil,spc,set; hid_t cs6, cmp, fix; hid_t cmp1, cmp2, cmp3; hid_t plist; hid_t array_dt; hsize_t dim[2]; hsize_t cdim[4]; char string5[5]; float fok[2] = {1234., 2341.}; float fnok[2] = {5678., 6785.}; float *fptr; char *data; char *mname; int result = 0; printf("%-70s", "Testing alignment in compound datatypes"); strcpy(string5, "Hi!"); HDunlink(fname); fil = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if (fil < 0) { puts("*FAILED*"); return 1; } H5E_BEGIN_TRY { H5Ldelete(fil, setname, H5P_DEFAULT); } H5E_END_TRY; cs6 = H5Tcopy(H5T_C_S1); H5Tset_size(cs6, sizeof(string5)); H5Tset_strpad(cs6, H5T_STR_NULLPAD); cmp = H5Tcreate(H5T_COMPOUND, sizeof(fok) + sizeof(string5) + sizeof(fnok)); H5Tinsert(cmp, "Awkward length", 0, cs6); cdim[0] = sizeof(fok) / sizeof(float); array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); H5Tinsert(cmp, "Ok", sizeof(string5), array_dt); H5Tclose(array_dt); cdim[0] = sizeof(fnok) / sizeof(float); array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); H5Tinsert(cmp, "Not Ok", sizeof(fok) + sizeof(string5), array_dt); H5Tclose(array_dt); fix=h5tools_get_native_type(cmp); cmp1 = H5Tcreate(H5T_COMPOUND, sizeof(fok)); cdim[0] = sizeof(fok) / sizeof(float); array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); H5Tinsert(cmp1, "Ok", 0, array_dt); H5Tclose(array_dt); cmp2 = H5Tcreate(H5T_COMPOUND, sizeof(string5)); H5Tinsert(cmp2, "Awkward length", 0, cs6); cmp3 = H5Tcreate(H5T_COMPOUND, sizeof(fnok)); cdim[0] = sizeof(fnok) / sizeof(float); array_dt = H5Tarray_create2(H5T_NATIVE_FLOAT, 1, cdim); H5Tinsert(cmp3, "Not Ok", 0, array_dt); H5Tclose(array_dt); plist = H5Pcreate(H5P_DATASET_XFER); H5Pset_preserve(plist, 1); /* * Create a small dataset, and write data into it we write each field * in turn so that we are avoid alignment issues at this point */ dim[0] = 1; spc = H5Screate_simple(1, dim, NULL); set = H5Dcreate2(fil, setname, cmp, spc, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); H5Dwrite(set, cmp1, spc, H5S_ALL, plist, fok); H5Dwrite(set, cmp2, spc, H5S_ALL, plist, string5); H5Dwrite(set, cmp3, spc, H5S_ALL, plist, fnok); H5Dclose(set); /* Now open the set, and read it back in */ data = malloc(H5Tget_size(fix)); if(!data) { perror("malloc() failed"); abort(); } set = H5Dopen2(fil, setname, H5P_DEFAULT); H5Dread(set, fix, spc, H5S_ALL, H5P_DEFAULT, data); fptr = (float *)(data + H5Tget_member_offset(fix, 1)); if(fok[0] != fptr[0] || fok[1] != fptr[1] || fnok[0] != fptr[2] || fnok[1] != fptr[3]) { result = 1; printf("%14s (%2d) %6s = %s\n", mname = H5Tget_member_name(fix, 0), (int)H5Tget_member_offset(fix,0), string5, (char *)(data + H5Tget_member_offset(fix, 0))); free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 1)); printf("Data comparison:\n" "%14s (%2d) %6f = %f\n" " %6f = %f\n", mname = H5Tget_member_name(fix, 1), (int)H5Tget_member_offset(fix,1), fok[0], fptr[0], fok[1], fptr[1]); free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 2)); printf("%14s (%2d) %6f = %f\n" " %6f = %6f\n", mname = H5Tget_member_name(fix, 2), (int)H5Tget_member_offset(fix,2), fnok[0], fptr[0], fnok[1], fptr[1]); free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 1)); printf("\n" "Short circuit\n" " %6f = %f\n" " %6f = %f\n" " %6f = %f\n" " %6f = %f\n", fok[0], fptr[0], fok[1], fptr[1], fnok[0], fptr[2], fnok[1], fptr[3]); puts("*FAILED*"); } else { puts(" PASSED"); } free(data); H5Sclose(spc); H5Tclose(cmp); H5Tclose(cmp1); H5Tclose(cmp2); H5Tclose(cmp3); H5Pclose(plist); H5Fclose(fil); HDunlink(fname); fflush(stdout); return result; }
hsize_t diff_attr(hid_t loc1_id, hid_t loc2_id, const char *path1, const char *path2, diff_opt_t *options) { hid_t attr1_id=-1; /* attr ID */ hid_t attr2_id=-1; /* attr ID */ hid_t space1_id=-1; /* space ID */ hid_t space2_id=-1; /* space ID */ hid_t ftype1_id=-1; /* file data type ID */ hid_t ftype2_id=-1; /* file data type ID */ int vstrtype1=0; /* ftype1 is a variable string */ int vstrtype2=0; /* ftype2 is a variable string */ hid_t mtype1_id=-1; /* memory data type ID */ hid_t mtype2_id=-1; /* memory data type ID */ size_t msize1; /* memory size of memory type */ size_t msize2; /* memory size of memory type */ void *buf1=NULL; /* data buffer */ void *buf2=NULL; /* data buffer */ int buf1hasdata=0; /* buffer has data */ int buf2hasdata=0; /* buffer has data */ hsize_t nelmts1; /* number of elements in dataset */ int rank1; /* rank of dataset */ int rank2; /* rank of dataset */ hsize_t dims1[H5S_MAX_RANK];/* dimensions of dataset */ hsize_t dims2[H5S_MAX_RANK];/* dimensions of dataset */ char *name1; char *name2; char np1[512]; char np2[512]; unsigned u; /* Local index variable */ hsize_t nfound = 0; hsize_t nfound_total = 0; int j; table_attrs_t * match_list_attrs = NULL; if( build_match_list_attrs(loc1_id, loc2_id, &match_list_attrs, options) < 0) goto error; /* if detect any unique extra attr */ if(match_list_attrs->nattrs_only1 || match_list_attrs->nattrs_only2) { /* exit will be 1 */ options->contents = 0; } for(u = 0; u < (unsigned)match_list_attrs->nattrs; u++) { if( (match_list_attrs->attrs[u].exist[0]) && (match_list_attrs->attrs[u].exist[1]) ) { name1 = name2 = match_list_attrs->attrs[u].name; /*-------------- * attribute 1 */ if((attr1_id = H5Aopen(loc1_id, name1, H5P_DEFAULT)) < 0) goto error; /*-------------- * attribute 2 */ if((attr2_id = H5Aopen(loc2_id, name2, H5P_DEFAULT)) < 0) goto error; /* get the datatypes */ if((ftype1_id = H5Aget_type(attr1_id)) < 0) goto error; vstrtype1 = H5Tis_variable_str(ftype1_id); if((ftype2_id = H5Aget_type(attr2_id)) < 0) goto error; vstrtype2 = H5Tis_variable_str(ftype2_id); /* no compare if either one but not both are variable string type */ if (vstrtype1 != vstrtype2){ if ((options->m_verbose||options->m_list_not_cmp)) parallel_print("Not comparable: one of attribute <%s/%s> or <%s/%s> is of variable length type\n", path1, name1, path2, name2); options->not_cmp = 1; return 0; } if((mtype1_id = h5tools_get_native_type(ftype1_id))<0) goto error; if((mtype2_id = h5tools_get_native_type(ftype2_id))<0) goto error; if((msize1 = H5Tget_size(mtype1_id))==0) goto error; if((msize2 = H5Tget_size(mtype2_id))==0) goto error; /* get the dataspace */ if((space1_id = H5Aget_space(attr1_id)) < 0) goto error; if((space2_id = H5Aget_space(attr2_id)) < 0) goto error; /* get dimensions */ if((rank1 = H5Sget_simple_extent_dims(space1_id, dims1, NULL)) < 0) goto error; if((rank2 = H5Sget_simple_extent_dims(space2_id, dims2, NULL)) < 0) goto error; /*---------------------------------------------------------------------- * check for comparable TYPE and SPACE *---------------------------------------------------------------------- */ /* pass dims1 and dims2 for maxdims as well since attribute's maxdims * are always same */ if( diff_can_type(ftype1_id, ftype2_id, rank1, rank2, dims1, dims2, dims1, dims2, name1, name2, options, 0) != 1 ) { if(H5Tclose(ftype1_id) < 0) goto error; if(H5Tclose(ftype2_id) < 0) goto error; if(H5Sclose(space1_id) < 0) goto error; if(H5Sclose(space2_id) < 0) goto error; if(H5Aclose(attr1_id) < 0) goto error; if(H5Aclose(attr2_id) < 0) goto error; if(H5Tclose(mtype1_id) < 0) goto error; if(H5Tclose(mtype2_id) < 0) goto error; continue; } /*----------------------------------------------------------------- * "upgrade" the smaller memory size *------------------------------------------------------------------ */ if (FAIL == match_up_memsize (ftype1_id, ftype2_id, &mtype1_id, &mtype2_id, &msize1, &msize2)) goto error; /*--------------------------------------------------------------------- * read *---------------------------------------------------------------------- */ nelmts1 = 1; for(j = 0; j < rank1; j++) nelmts1 *= dims1[j]; buf1 = (void *)HDmalloc((size_t)(nelmts1 * msize1)); buf2 = (void *)HDmalloc((size_t)(nelmts1 * msize2)); if(buf1 == NULL || buf2 == NULL){ parallel_print( "cannot read into memory\n" ); goto error; } if(H5Aread(attr1_id,mtype1_id,buf1) < 0){ parallel_print("Failed reading attribute1 %s/%s\n", path1, name1); goto error; }else buf1hasdata = 1; if(H5Aread(attr2_id,mtype2_id,buf2) < 0){ parallel_print("Failed reading attribute2 %s/%s\n", path2, name2); goto error; }else buf2hasdata = 1; /* format output string */ HDsnprintf(np1, sizeof(np1), "%s of <%s>", name1, path1); HDsnprintf(np2, sizeof(np1), "%s of <%s>", name2, path2); /*--------------------------------------------------------------------- * array compare *---------------------------------------------------------------------- */ /* always print name */ /* verbose (-v) and report (-r) mode */ if(options->m_verbose || options->m_report) { do_print_attrname("attribute", np1, np2); nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, np1, np2, mtype1_id, attr1_id, attr2_id); print_found(nfound); } /* quiet mode (-q), just count differences */ else if(options->m_quiet) { nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, np1, np2, mtype1_id, attr1_id, attr2_id); } /* the rest (-c, none, ...) */ else { nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, np1, np2, mtype1_id, attr1_id, attr2_id); /* print info if compatible and difference found */ if(nfound) { do_print_attrname("attribute", np1, np2); print_found(nfound); } /* end if */ } /* end else */ /*---------------------------------------------------------------------- * close *---------------------------------------------------------------------- */ /* Free buf1 and buf2, check both VLEN-data VLEN-string to reclaim any * VLEN memory first */ if(TRUE == h5tools_detect_vlen(mtype1_id)) H5Dvlen_reclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); HDfree(buf1); buf1 = NULL; if(TRUE == h5tools_detect_vlen(mtype2_id)) H5Dvlen_reclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); HDfree(buf2); buf2 = NULL; if(H5Tclose(ftype1_id) < 0) goto error; if(H5Tclose(ftype2_id) < 0) goto error; if(H5Sclose(space1_id) < 0) goto error; if(H5Sclose(space2_id) < 0) goto error; if(H5Aclose(attr1_id) < 0) goto error; if(H5Aclose(attr2_id) < 0) goto error; if(H5Tclose(mtype1_id) < 0) goto error; if(H5Tclose(mtype2_id) < 0) goto error; nfound_total += nfound; } } /* u */ table_attrs_free(match_list_attrs); return nfound_total; error: H5E_BEGIN_TRY { if(buf1) { if(buf1hasdata && TRUE == h5tools_detect_vlen(mtype1_id)) H5Dvlen_reclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); HDfree(buf1); } /* end if */ if(buf2) { if(buf2hasdata && TRUE == h5tools_detect_vlen(mtype2_id)) H5Dvlen_reclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); HDfree(buf2); } /* end if */ table_attrs_free(match_list_attrs); H5Tclose(ftype1_id); H5Tclose(ftype2_id); H5Tclose(mtype1_id); H5Tclose(mtype2_id); H5Sclose(space1_id); H5Sclose(space2_id); H5Aclose(attr1_id); H5Aclose(attr2_id); } H5E_END_TRY; options->err_stat = 1; return nfound_total; }
/*------------------------------------------------------------------------- * Function: diff_datasetid * * Purpose: check for comparable datasets and read into a compatible * memory type * * Return: Number of differences found * * Programmer: Pedro Vicente, [email protected] * * Date: May 9, 2003 * * Modifications: * * * October 2006: Read by hyperslabs for big datasets. * * A threshold of H5TOOLS_MALLOCSIZE (128 MB) is the limit upon which I/O hyperslab is done * i.e., if the memory needed to read a dataset is greater than this limit, * then hyperslab I/O is done instead of one operation I/O * For each dataset, the memory needed is calculated according to * * memory needed = number of elements * size of each element * * if the memory needed is lower than H5TOOLS_MALLOCSIZE, then the following operations * are done * * H5Dread( input_dataset1 ) * H5Dread( input_dataset2 ) * * with all elements in the datasets selected. If the memory needed is greater than * H5TOOLS_MALLOCSIZE, then the following operations are done instead: * * a strip mine is defined for each dimension k (a strip mine is defined as a * hyperslab whose size is memory manageable) according to the formula * * (1) strip_mine_size[k ] = MIN(dimension[k ], H5TOOLS_BUFSIZE / size of memory type) * * where H5TOOLS_BUFSIZE is a constant currently defined as 1MB. This formula assures * that for small datasets (small relative to the H5TOOLS_BUFSIZE constant), the strip * mine size k is simply defined as its dimension k, but for larger datasets the * hyperslab size is still memory manageable. * a cycle is done until the number of elements in the dataset is reached. In each * iteration, two parameters are defined for the function H5Sselect_hyperslab, * the start and size of each hyperslab, according to * * (2) hyperslab_size [k] = MIN(dimension[k] - hyperslab_offset[k], strip_mine_size [k]) * * where hyperslab_offset [k] is initially set to zero, and later incremented in * hyperslab_size[k] offsets. The reason for the operation * * dimension[k] - hyperslab_offset[k] * * in (2) is that, when using the strip mine size, it assures that the "remaining" part * of the dataset that does not fill an entire strip mine is processed. * *------------------------------------------------------------------------- */ hsize_t diff_datasetid( hid_t did1, hid_t did2, const char *obj1_name, const char *obj2_name, diff_opt_t *options) { hid_t sid1=-1; hid_t sid2=-1; hid_t f_tid1=-1; hid_t f_tid2=-1; hid_t m_tid1=-1; hid_t m_tid2=-1; size_t m_size1; size_t m_size2; H5T_sign_t sign1; H5T_sign_t sign2; int rank1; int rank2; hsize_t nelmts1; hsize_t nelmts2; hsize_t dims1[H5S_MAX_RANK]; hsize_t dims2[H5S_MAX_RANK]; hsize_t maxdim1[H5S_MAX_RANK]; hsize_t maxdim2[H5S_MAX_RANK]; const char *name1=NULL; /* relative names */ const char *name2=NULL; hsize_t storage_size1; hsize_t storage_size2; hsize_t nfound=0; /* number of differences found */ int can_compare=1; /* do diff or not */ void *buf1=NULL; void *buf2=NULL; void *sm_buf1=NULL; void *sm_buf2=NULL; hid_t sm_space; /*stripmine data space */ size_t need; /* bytes needed for malloc */ int i; unsigned int vl_data = 0; /*contains VL datatypes */ /* Get the dataspace handle */ if ( (sid1 = H5Dget_space(did1)) < 0 ) goto error; /* Get rank */ if ( (rank1 = H5Sget_simple_extent_ndims(sid1)) < 0 ) goto error; /* Get the dataspace handle */ if ( (sid2 = H5Dget_space(did2)) < 0 ) goto error; /* Get rank */ if ( (rank2 = H5Sget_simple_extent_ndims(sid2)) < 0 ) goto error; /* Get dimensions */ if ( H5Sget_simple_extent_dims(sid1,dims1,maxdim1) < 0 ) goto error; /* Get dimensions */ if ( H5Sget_simple_extent_dims(sid2,dims2,maxdim2) < 0 ) { goto error; } /*------------------------------------------------------------------------- * get the file data type *------------------------------------------------------------------------- */ /* Get the data type */ if ( (f_tid1 = H5Dget_type(did1)) < 0 ) goto error; /* Get the data type */ if ( (f_tid2 = H5Dget_type(did2)) < 0 ) { goto error; } /*------------------------------------------------------------------------- * check for empty datasets *------------------------------------------------------------------------- */ storage_size1=H5Dget_storage_size(did1); storage_size2=H5Dget_storage_size(did2); if (storage_size1==0 || storage_size2==0) { if ( (options->m_verbose||options->m_list_not_cmp) && obj1_name && obj2_name) parallel_print("Not comparable: <%s> or <%s> is an empty dataset\n", obj1_name, obj2_name); can_compare=0; options->not_cmp=1; } /*------------------------------------------------------------------------- * check for comparable TYPE and SPACE *------------------------------------------------------------------------- */ if (diff_can_type(f_tid1, f_tid2, rank1, rank2, dims1, dims2, maxdim1, maxdim2, obj1_name, obj2_name, options, 0)!=1) { can_compare=0; } /*------------------------------------------------------------------------- * memory type and sizes *------------------------------------------------------------------------- */ if ((m_tid1=h5tools_get_native_type(f_tid1)) < 0) goto error; if ((m_tid2=h5tools_get_native_type(f_tid2)) < 0) goto error; m_size1 = H5Tget_size( m_tid1 ); m_size2 = H5Tget_size( m_tid2 ); /*------------------------------------------------------------------------- * check for different signed/unsigned types *------------------------------------------------------------------------- */ if (can_compare) { sign1=H5Tget_sign(m_tid1); sign2=H5Tget_sign(m_tid2); if ( sign1 != sign2 ) { if ((options->m_verbose||options->m_list_not_cmp) && obj1_name && obj2_name) { parallel_print("Not comparable: <%s> has sign %s ", obj1_name, get_sign(sign1)); parallel_print("and <%s> has sign %s\n", obj2_name, get_sign(sign2)); } can_compare=0; options->not_cmp=1; } } /* Check if type is either VLEN-data or VLEN-string to reclaim any * VLEN memory buffer later */ if( TRUE == h5tools_detect_vlen(m_tid1) ) vl_data = TRUE; /*------------------------------------------------------------------------ * only attempt to compare if possible *------------------------------------------------------------------------- */ if(can_compare) /* it is possible to compare */ { /*----------------------------------------------------------------- * get number of elements *------------------------------------------------------------------ */ nelmts1 = 1; for(i = 0; i < rank1; i++) nelmts1 *= dims1[i]; nelmts2 = 1; for(i = 0; i < rank2; i++) nelmts2 *= dims2[i]; HDassert(nelmts1 == nelmts2); /*----------------------------------------------------------------- * "upgrade" the smaller memory size *------------------------------------------------------------------ */ if (FAIL == match_up_memsize (f_tid1, f_tid2, &m_tid1, &m_tid2, &m_size1, &m_size2)) goto error; /* print names */ if(obj1_name) name1 = diff_basename(obj1_name); if(obj2_name) name2 = diff_basename(obj2_name); /*---------------------------------------------------------------- * read/compare *----------------------------------------------------------------- */ need = (size_t)(nelmts1 * m_size1); /* bytes needed */ if(need < H5TOOLS_MALLOCSIZE) { buf1 = HDmalloc(need); buf2 = HDmalloc(need); } /* end if */ if(buf1 != NULL && buf2 != NULL) { if(H5Dread(did1, m_tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf1) < 0) goto error; if(H5Dread(did2, m_tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf2) < 0) goto error; /* array diff */ nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, name1, name2, m_tid1, did1, did2); /* reclaim any VL memory, if necessary */ if(vl_data) { H5Dvlen_reclaim(m_tid1, sid1, H5P_DEFAULT, buf1); H5Dvlen_reclaim(m_tid2, sid2, H5P_DEFAULT, buf2); } /* end if */ } /* end if */ else /* possibly not enough memory, read/compare by hyperslabs */ { size_t p_type_nbytes = m_size1; /*size of memory type */ hsize_t p_nelmts = nelmts1; /*total selected elmts */ hsize_t elmtno; /*counter */ int carry; /*counter carry value */ /* stripmine info */ hsize_t sm_size[H5S_MAX_RANK]; /*stripmine size */ hsize_t sm_nbytes; /*bytes per stripmine */ hsize_t sm_nelmts; /*elements per stripmine*/ /* hyperslab info */ hsize_t hs_offset[H5S_MAX_RANK]; /*starting offset */ hsize_t hs_size[H5S_MAX_RANK]; /*size this pass */ hsize_t hs_nelmts; /*elements in request */ hsize_t zero[8]; /*vector of zeros */ /* * determine the strip mine size and allocate a buffer. The strip mine is * a hyperslab whose size is manageable. */ sm_nbytes = p_type_nbytes; for(i = rank1; i > 0; --i) { hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; if(size == 0) /* datum size > H5TOOLS_BUFSIZE */ size = 1; sm_size[i - 1] = MIN(dims1[i - 1], size); sm_nbytes *= sm_size[i - 1]; HDassert(sm_nbytes > 0); } /* end for */ /* malloc return code should be verified. * If fail, need to handle the error. * This else branch should be recoded as a separate function. * Note that there are many "goto error" within this branch * that fails to address freeing other objects created here. * E.g., sm_space. */ sm_buf1 = HDmalloc((size_t)sm_nbytes); HDassert(sm_buf1); sm_buf2 = HDmalloc((size_t)sm_nbytes); HDassert(sm_buf2); sm_nelmts = sm_nbytes / p_type_nbytes; sm_space = H5Screate_simple(1, &sm_nelmts, NULL); /* the stripmine loop */ HDmemset(hs_offset, 0, sizeof hs_offset); HDmemset(zero, 0, sizeof zero); for(elmtno = 0; elmtno < p_nelmts; elmtno += hs_nelmts) { /* calculate the hyperslab size */ if(rank1 > 0) { for(i = 0, hs_nelmts = 1; i < rank1; i++) { hs_size[i] = MIN(dims1[i] - hs_offset[i], sm_size[i]); hs_nelmts *= hs_size[i]; } /* end for */ if(H5Sselect_hyperslab(sid1, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL) < 0) goto error; if(H5Sselect_hyperslab(sid2, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL) < 0) goto error; if(H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL) < 0) goto error; } /* end if */ else hs_nelmts = 1; if(H5Dread(did1,m_tid1,sm_space,sid1,H5P_DEFAULT,sm_buf1) < 0) goto error; if(H5Dread(did2,m_tid2,sm_space,sid2,H5P_DEFAULT,sm_buf2) < 0) goto error; /* get array differences. in the case of hyperslab read, increment the number of differences found in each hyperslab and pass the position at the beggining for printing */ nfound += diff_array(sm_buf1, sm_buf2, hs_nelmts, elmtno, rank1, dims1, options, name1, name2, m_tid1, did1, did2); /* reclaim any VL memory, if necessary */ if(vl_data) { H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf2); } /* end if */ /* calculate the next hyperslab offset */ for(i = rank1, carry = 1; i > 0 && carry; --i) { hs_offset[i - 1] += hs_size[i - 1]; if(hs_offset[i - 1] == dims1[i - 1]) hs_offset[i - 1] = 0; else carry = 0; } /* i */ } /* elmtno */ H5Sclose(sm_space); } /* hyperslab read */ } /*can_compare*/ /*------------------------------------------------------------------------- * close *------------------------------------------------------------------------- */ /* free */ if(buf1 != NULL) { HDfree(buf1); buf1 = NULL; } /* end if */ if(buf2 != NULL) { HDfree(buf2); buf2 = NULL; } /* end if */ if(sm_buf1 != NULL) { HDfree(sm_buf1); sm_buf1 = NULL; } /* end if */ if(sm_buf2 != NULL) { HDfree(sm_buf2); sm_buf2 = NULL; } /* end if */ H5E_BEGIN_TRY { H5Sclose(sid1); H5Sclose(sid2); H5Tclose(f_tid1); H5Tclose(f_tid2); H5Tclose(m_tid1); H5Tclose(m_tid2); } H5E_END_TRY; return nfound; error: options->err_stat=1; /* free */ if (buf1!=NULL) { /* reclaim any VL memory, if necessary */ if(vl_data) H5Dvlen_reclaim(m_tid1, sid1, H5P_DEFAULT, buf1); HDfree(buf1); buf1=NULL; } if (buf2!=NULL) { /* reclaim any VL memory, if necessary */ if(vl_data) H5Dvlen_reclaim(m_tid2, sid2, H5P_DEFAULT, buf2); HDfree(buf2); buf2=NULL; } if (sm_buf1!=NULL) { /* reclaim any VL memory, if necessary */ if(vl_data) H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); HDfree(sm_buf1); sm_buf1=NULL; } if (sm_buf2!=NULL) { /* reclaim any VL memory, if necessary */ if(vl_data) H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf2); HDfree(sm_buf2); sm_buf2=NULL; } /* disable error reporting */ H5E_BEGIN_TRY { H5Sclose(sid1); H5Sclose(sid2); H5Tclose(f_tid1); H5Tclose(f_tid2); H5Tclose(m_tid1); H5Tclose(m_tid2); /* enable error reporting */ } H5E_END_TRY; return nfound; }
/*------------------------------------------------------------------------- * Function: diff_datasetid * * Purpose: check for comparable datasets and read into a compatible * memory type * * Return: Number of differences found * * Programmer: Pedro Vicente, [email protected] * * Date: May 9, 2003 * * Modifications: * * October 2006: Read by hyperslabs for big datasets. * * A threshold of H5TOOLS_MALLOCSIZE (128 MB) is the limit upon which I/O hyperslab is done * i.e., if the memory needed to read a dataset is greater than this limit, * then hyperslab I/O is done instead of one operation I/O * For each dataset, the memory needed is calculated according to * * memory needed = number of elements * size of each element * * if the memory needed is lower than H5TOOLS_MALLOCSIZE, then the following operations * are done * * H5Dread( input_dataset1 ) * H5Dread( input_dataset2 ) * * with all elements in the datasets selected. If the memory needed is greater than * H5TOOLS_MALLOCSIZE, then the following operations are done instead: * * a strip mine is defined for each dimension k (a strip mine is defined as a * hyperslab whose size is memory manageable) according to the formula * * (1) strip_mine_size[k ] = MIN(dimension[k ], H5TOOLS_BUFSIZE / size of memory type) * * where H5TOOLS_BUFSIZE is a constant currently defined as 1MB. This formula assures * that for small datasets (small relative to the H5TOOLS_BUFSIZE constant), the strip * mine size k is simply defined as its dimension k, but for larger datasets the * hyperslab size is still memory manageable. * a cycle is done until the number of elements in the dataset is reached. In each * iteration, two parameters are defined for the function H5Sselect_hyperslab, * the start and size of each hyperslab, according to * * (2) hyperslab_size [k] = MIN(dimension[k] - hyperslab_offset[k], strip_mine_size [k]) * * where hyperslab_offset [k] is initially set to zero, and later incremented in * hyperslab_size[k] offsets. The reason for the operation * * dimension[k] - hyperslab_offset[k] * * in (2) is that, when using the strip mine size, it assures that the "remaining" part * of the dataset that does not fill an entire strip mine is processed. * *------------------------------------------------------------------------- */ hsize_t diff_datasetid( hid_t did1, hid_t did2, const char *obj1_name, const char *obj2_name, diff_opt_t *options) { hid_t sid1=-1; hid_t sid2=-1; hid_t f_tid1=-1; hid_t f_tid2=-1; hid_t m_tid1=-1; hid_t m_tid2=-1; size_t m_size1; size_t m_size2; H5T_sign_t sign1; H5T_sign_t sign2; int rank1; int rank2; hsize_t nelmts1; hsize_t nelmts2; hsize_t dims1[H5S_MAX_RANK]; hsize_t dims2[H5S_MAX_RANK]; hsize_t maxdim1[H5S_MAX_RANK]; hsize_t maxdim2[H5S_MAX_RANK]; const char *name1=NULL; /* relative names */ const char *name2=NULL; hsize_t storage_size1; hsize_t storage_size2; hsize_t nfound=0; /* number of differences found */ int cmp=1; /* do diff or not */ void *buf1=NULL; void *buf2=NULL; void *sm_buf1=NULL; void *sm_buf2=NULL; size_t need; /* bytes needed for malloc */ int i; /* Get the dataspace handle */ if ( (sid1 = H5Dget_space(did1)) < 0 ) goto error; /* Get rank */ if ( (rank1 = H5Sget_simple_extent_ndims(sid1)) < 0 ) goto error; /* Get the dataspace handle */ if ( (sid2 = H5Dget_space(did2)) < 0 ) goto error; /* Get rank */ if ( (rank2 = H5Sget_simple_extent_ndims(sid2)) < 0 ) goto error; /* Get dimensions */ if ( H5Sget_simple_extent_dims(sid1,dims1,maxdim1) < 0 ) goto error; /* Get dimensions */ if ( H5Sget_simple_extent_dims(sid2,dims2,maxdim2) < 0 ) goto error; /*------------------------------------------------------------------------- * Get the file data type *------------------------------------------------------------------------- */ /* Get the data type */ if ( (f_tid1 = H5Dget_type(did1)) < 0 ) goto error; /* Get the data type */ if ( (f_tid2 = H5Dget_type(did2)) < 0 ) goto error; /*------------------------------------------------------------------------- * check for empty datasets *------------------------------------------------------------------------- */ storage_size1=H5Dget_storage_size(did1); storage_size2=H5Dget_storage_size(did2); if (storage_size1<0 || storage_size2<0) goto error; if (storage_size1==0 || storage_size2==0) { if (options->m_verbose && obj1_name && obj2_name) printf("<%s> or <%s> are empty datasets\n", obj1_name, obj2_name); cmp=0; options->not_cmp=1; } /*------------------------------------------------------------------------- * check for comparable TYPE and SPACE *------------------------------------------------------------------------- */ if (diff_can_type(f_tid1, f_tid2, rank1, rank2, dims1, dims2, maxdim1, maxdim2, obj1_name, obj2_name, options)!=1) { cmp=0; options->not_cmp=1; } /*------------------------------------------------------------------------- * memory type and sizes *------------------------------------------------------------------------- */ if ((m_tid1=h5tools_get_native_type(f_tid1))<0) goto error; if ((m_tid2=h5tools_get_native_type(f_tid2))<0) goto error; m_size1 = H5Tget_size( m_tid1 ); m_size2 = H5Tget_size( m_tid2 ); /*------------------------------------------------------------------------- * check for different signed/unsigned types *------------------------------------------------------------------------- */ sign1=H5Tget_sign(m_tid1); sign2=H5Tget_sign(m_tid2); if ( sign1 != sign2 ) { if (options->m_verbose && obj1_name) { printf("Comparison not supported: <%s> has sign %s ", obj1_name, get_sign(sign1)); printf("and <%s> has sign %s\n", obj2_name, get_sign(sign2)); } cmp=0; options->not_cmp=1; } /*------------------------------------------------------------------------- * only attempt to compare if possible *------------------------------------------------------------------------- */ if (cmp) { /*------------------------------------------------------------------------- * get number of elements *------------------------------------------------------------------------- */ nelmts1 = 1; for (i = 0; i < rank1; i++) { nelmts1 *= dims1[i]; } nelmts2 = 1; for (i = 0; i < rank2; i++) { nelmts2 *= dims2[i]; } assert(nelmts1==nelmts2); /*------------------------------------------------------------------------- * "upgrade" the smaller memory size *------------------------------------------------------------------------- */ if ( m_size1 != m_size2 ) { if ( m_size1 < m_size2 ) { H5Tclose(m_tid1); if ((m_tid1=h5tools_get_native_type(f_tid2))<0) goto error; m_size1 = H5Tget_size( m_tid1 ); } else { H5Tclose(m_tid2); if ((m_tid2=h5tools_get_native_type(f_tid1))<0) goto error; m_size2 = H5Tget_size( m_tid2 ); } } assert(m_size1==m_size2); /* print names */ if (obj1_name) { name1=diff_basename(obj1_name); } if (obj2_name) { name2=diff_basename(obj2_name); } /*------------------------------------------------------------------------- * read/compare *------------------------------------------------------------------------- */ need = (size_t)(nelmts1*m_size1); /* bytes needed */ if ( need < H5TOOLS_MALLOCSIZE) { buf1 = HDmalloc(need); buf2 = HDmalloc(need); } if ( buf1!=NULL && buf2!=NULL) { if ( H5Dread(did1,m_tid1,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf1) < 0 ) goto error; if ( H5Dread(did2,m_tid2,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf2) < 0 ) goto error; /* array diff */ nfound = diff_array(buf1, buf2, nelmts1, (hsize_t)0, rank1, dims1, options, name1, name2, m_tid1, did1, did2); } else /* possibly not enough memory, read/compare by hyperslabs */ { size_t p_type_nbytes = m_size1; /*size of memory type */ hsize_t p_nelmts = nelmts1; /*total selected elmts */ hsize_t elmtno; /*counter */ int carry; /*counter carry value */ unsigned int vl_data = 0; /*contains VL datatypes */ /* stripmine info */ hsize_t sm_size[H5S_MAX_RANK]; /*stripmine size */ hsize_t sm_nbytes; /*bytes per stripmine */ hsize_t sm_nelmts; /*elements per stripmine*/ hid_t sm_space; /*stripmine data space */ /* hyperslab info */ hsize_t hs_offset[H5S_MAX_RANK]; /*starting offset */ hsize_t hs_size[H5S_MAX_RANK]; /*size this pass */ hsize_t hs_nelmts; /*elements in request */ hsize_t zero[8]; /*vector of zeros */ /* check if we have VL data in the dataset's datatype */ if (H5Tdetect_class(m_tid1, H5T_VLEN) == TRUE) vl_data = TRUE; /* * determine the strip mine size and allocate a buffer. The strip mine is * a hyperslab whose size is manageable. */ sm_nbytes = p_type_nbytes; for (i = rank1; i > 0; --i) { sm_size[i - 1] = MIN(dims1[i - 1], H5TOOLS_BUFSIZE / sm_nbytes); sm_nbytes *= sm_size[i - 1]; assert(sm_nbytes > 0); } sm_buf1 = malloc((size_t)sm_nbytes); sm_buf2 = malloc((size_t)sm_nbytes); sm_nelmts = sm_nbytes / p_type_nbytes; sm_space = H5Screate_simple(1, &sm_nelmts, NULL); /* the stripmine loop */ memset(hs_offset, 0, sizeof hs_offset); memset(zero, 0, sizeof zero); for (elmtno = 0; elmtno < p_nelmts; elmtno += hs_nelmts) { /* calculate the hyperslab size */ if (rank1 > 0) { for (i = 0, hs_nelmts = 1; i < rank1; i++) { hs_size[i] = MIN(dims1[i] - hs_offset[i], sm_size[i]); hs_nelmts *= hs_size[i]; } if (H5Sselect_hyperslab(sid1, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL)<0) goto error; if (H5Sselect_hyperslab(sid2, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL)<0) goto error; if (H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL)<0) goto error; } else { H5Sselect_all(sid1); H5Sselect_all(sid2); H5Sselect_all(sm_space); hs_nelmts = 1; } /* rank */ if ( H5Dread(did1,m_tid1,sm_space,sid1,H5P_DEFAULT,sm_buf1) < 0 ) goto error; if ( H5Dread(did2,m_tid2,sm_space,sid2,H5P_DEFAULT,sm_buf2) < 0 ) goto error; /* get array differences. in the case of hyperslab read, increment the number of differences found in each hyperslab and pass the position at the beggining for printing */ nfound += diff_array(sm_buf1, sm_buf2, hs_nelmts, elmtno, rank1, dims1, options, name1, name2, m_tid1, did1, did2); /* reclaim any VL memory, if necessary */ if(vl_data) { H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf2); } /* calculate the next hyperslab offset */ for (i = rank1, carry = 1; i > 0 && carry; --i) { hs_offset[i - 1] += hs_size[i - 1]; if (hs_offset[i - 1] == dims1[i - 1]) hs_offset[i - 1] = 0; else carry = 0; } /* i */ } /* elmtno */ H5Sclose(sm_space); /* free */ if (sm_buf1!=NULL) { free(sm_buf1); sm_buf1=NULL; } if (sm_buf2!=NULL) { free(sm_buf2); sm_buf2=NULL; } } /* hyperslab read */ }/*cmp*/ /*------------------------------------------------------------------------- * compare attributes * the if condition refers to cases when the dataset is a referenced object *------------------------------------------------------------------------- */ if (obj1_name) nfound += diff_attr(did1,did2,obj1_name,obj2_name,options); /*------------------------------------------------------------------------- * close *------------------------------------------------------------------------- */ /* free */ if (buf1!=NULL) { free(buf1); buf1=NULL; } if (buf2!=NULL) { free(buf2); buf2=NULL; } if (sm_buf1!=NULL) { free(sm_buf1); sm_buf1=NULL; } if (sm_buf2!=NULL) { free(sm_buf2); sm_buf2=NULL; } H5E_BEGIN_TRY { H5Sclose(sid1); H5Sclose(sid2); H5Tclose(f_tid1); H5Tclose(f_tid2); H5Tclose(m_tid1); H5Tclose(m_tid2); } H5E_END_TRY; return nfound; error: options->err_stat=1; /* free */ if (buf1!=NULL) { free(buf1); buf1=NULL; } if (buf2!=NULL) { free(buf2); buf2=NULL; } if (sm_buf1!=NULL) { free(sm_buf1); sm_buf1=NULL; } if (sm_buf2!=NULL) { free(sm_buf2); sm_buf2=NULL; } /* disable error reporting */ H5E_BEGIN_TRY { H5Sclose(sid1); H5Sclose(sid2); H5Tclose(f_tid1); H5Tclose(f_tid2); H5Tclose(m_tid1); H5Tclose(m_tid2); /* enable error reporting */ } H5E_END_TRY; return nfound; }