示例#1
0
/*-----------------------------------------------------------------
 * 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;
}
示例#2
0
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*/
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
0
/*-------------------------------------------------------------------------
* 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;
}