From 67449f5c65efa0b1b2d17288a2387259ccd651d2 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Tue, 10 Jun 2003 16:04:58 -0500 Subject: [svn-r7021] Purpose: bug fix Description: H5Tget_native_type fails for multiple kinds of datatype on Cray; it fails fix-length string type, too. Platforms tested: Cray, h5committest --- src/H5Tconv.c | 21 ++-- src/H5Tnative.c | 41 ++++--- test/dtypes.c | 88 +++++++++++++++ test/ntypes.c | 311 +++++++++++++++++++++++++++++++++++++++++++++++------- tools/h5ls/h5ls.c | 6 +- 5 files changed, 400 insertions(+), 67 deletions(-) diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 13a6737..92f6fa3 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1885,12 +1885,12 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) H5MM_xfree(priv->src2dst); priv->src2dst = map; HGOTO_DONE(SUCCEED); - } else { - /* Sort source type by value and adjust src2dst[] appropriately */ - H5T_sort_value(src, priv->src2dst); } } + /* Sort source type by value and adjust src2dst[] appropriately */ + H5T_sort_value(src, priv->src2dst); + done: if (ret_value<0 && priv) { H5MM_xfree(priv->src2dst); @@ -1976,15 +1976,12 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, assert (H5T_ENUM==src->type); assert (H5T_ENUM==dst->type); - if (priv->length) { - /* Use O(1) lookup */ - H5T_sort_name(src, NULL); - H5T_sort_name(dst, NULL); - } else { - /* Use O(log N) lookup */ - H5T_sort_value(src, NULL); /*yes, by value*/ - H5T_sort_name(dst, NULL); /*yes, by name*/ - } + /* priv->src2dst map was computed for certain sort keys. Make sure those same + * sort keys are used here during conversion. See H5T_conv_enum_init(). But + * we actually don't care about the source type's order when doing the O(1) + * conversion algorithm, which is turned on by non-zero priv->length */ + H5T_sort_name(dst, NULL); + if (!priv->length) H5T_sort_value(src, NULL); /* * Direction of conversion. diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 3cd6789..4516ddd 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -22,6 +22,7 @@ #include "H5private.h" /*generic functions */ #include "H5Eprivate.h" /*error handling */ #include "H5Iprivate.h" /*ID functions */ +#include "H5Pprivate.h" /*property list */ #include "H5MMprivate.h" /*memory management */ #include "H5Tpkg.h" /*data-type functions */ @@ -212,9 +213,7 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); } else { - /*size_t char_size;*/ - - if(NULL==(dt=H5I_object(H5T_NATIVE_UCHAR))) + if(NULL==(dt=H5I_object(H5T_C_S1))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type"); @@ -346,8 +345,9 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig case H5T_ENUM: { char *memb_name; /* Enum's member name */ - void *memb_value; /* Enum's member value */ - + void *memb_value, *tmp_memb_value; /* Enum's member value */ + hid_t super_type_id, nat_super_type_id; + /* Don't need to do anything special for alignment, offset since the ENUM type usually is integer. */ /* Retrieve base type for enumarate type */ @@ -356,14 +356,17 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig if((nat_super_type = H5T_get_native_type(super_type, direction, struct_align, offset, comp_size))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "base native type retrieval failed"); + if((super_type_id=H5I_register(H5I_DATATYPE, super_type))<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot register datatype"); + if((nat_super_type_id=H5I_register(H5I_DATATYPE, nat_super_type))<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot register datatype"); + /* Allocate room for the enum values */ - if((memb_value = H5MM_malloc(H5T_get_size(super_type)))==NULL) + if((tmp_memb_value = H5MM_calloc(H5T_get_size(super_type)))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); + if((memb_value = H5MM_calloc(H5T_get_size(nat_super_type)))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory"); - /* Close super type */ - if(H5T_close(super_type)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype"); - /* Construct new enum type based on native type */ if((new_type=H5T_enum_create(nat_super_type))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create enum type"); @@ -374,18 +377,27 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig for(i=0; i=0; --i) { + char pattern[3]; + pattern[2] = i; + pattern[0] = pattern[1] = 0; + H5Tenum_insert(srctype, mname[i], pattern); + } + + /* Destination enum type */ + dsttype = H5Tenum_create(H5T_NATIVE_INT); + assert(H5Tget_size(dsttype)>H5Tget_size(srctype)); + for (i=0; i<8; i++) + H5Tenum_insert(dsttype, mname[i], &i); + + /* Source data */ + data = malloc(NTESTELEM*sizeof(int)); + for (i=0; ilen=j+1; - for(k=0; k<(j+1); k++) + for(k=0; k<(j+1); k++) { ((unsigned int *)t1->p)[k]=(unsigned int)(i*100+j*10+k); + } } /* end for */ } /* end for */ @@ -1222,15 +1336,18 @@ test_vl_dtype(hid_t file) /* Open a dataset */ if((dataset=H5Dopen(file, DSET_VL_NAME))<0) TEST_ERROR; - /* Get datatype for dataset */ + /* Get native datatype for dataset */ if((dtype = H5Dget_type(dataset))<0) TEST_ERROR; if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) TEST_ERROR; - - if(!H5Tequal(native_type, tid_m)) + + /* Also get native base type for this nested VL type. Should be an integer type. */ + if((nat_super_type=H5Tget_super(native_type))<0) TEST_ERROR; - + if((nat_super_type=H5Tget_super(nat_super_type))<0) + TEST_ERROR; + /* Read dataset from disk */ if(H5Dread(dataset,native_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,rdata)<0) TEST_ERROR; @@ -1247,13 +1364,25 @@ test_vl_dtype(hid_t file) printf(" VL data length don't match!, wdata[%d].len=%d, rdata[%d].len=%d\n",(int)i,(int)wdata[i].len,(int)i,(int)rdata[i].len); goto error; } /* end if */ + + /* use temporary buffer to convert datatype. This is for special + * platforms like Cray */ + tmp=malloc(t2->len*sizeof(unsigned int)); + memcpy(tmp, t2->p, t2->len*H5Tget_size(nat_super_type)); + + if (H5Tconvert(nat_super_type, H5T_NATIVE_UINT, t2->len, tmp, NULL, H5P_DEFAULT)) + TEST_ERROR; + for(k=0; klen; k++) { - if( ((unsigned int *)t1->p)[k] != ((unsigned int *)t2->p)[k] ) { + if( ((unsigned int *)t1->p)[k] != ((unsigned int *)tmp)[k] ) { H5_FAILED(); - printf(" VL data length don't match!, wdata[%d].len=%d, rdata[%d].len=%d\n",(int)i,(int)wdata[i].len,(int)i,(int)rdata[i].len); + printf(" VL data don't match!, wdata[%d].p=%d, rdata[%d].p=%d\n", + i,((unsigned int*)t1->p)[k],i,(unsigned int*)tmp[k]); goto error; } } /* end for */ + + free(tmp); } /* end for */ } /* end for */ @@ -1395,6 +1524,113 @@ error: /*------------------------------------------------------------------------- + * Function: test_str_dtype + * + * Purpose: Test H5Tget_native_type for fixed-length string datatype + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Raymond Lu + * October 15, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +test_str_dtype(hid_t file) +{ + const char wdata[SPACE1_DIM1][4]= { + "one", + "two", + "3rd", + "4th" + }; /* Information to write */ + char rdata[SPACE1_DIM1][4]; /* Information read in */ + hid_t dataset; /* Dataset ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1,dtype,native_type; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}; + unsigned i; /* counting variable */ + + /* Output message about test being performed */ + TESTING("fixed-length string datatype"); + + /* Create dataspace for datasets */ + if((sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL))<0) TEST_ERROR; + + /* Create a datatype to refer to */ + if((tid1 = H5Tcopy (H5T_C_S1))<0) TEST_ERROR; + + if(H5Tset_size (tid1,4)<0) TEST_ERROR; + if(H5T_STRING!=H5Tget_class(tid1)) + TEST_ERROR; + + /* Create a dataset */ + if((dataset=H5Dcreate(file,DSET_STR_NAME,tid1,sid1,H5P_DEFAULT))<0) TEST_ERROR; + + /* Write dataset to disk */ + if(H5Dwrite(dataset,tid1,H5S_ALL,H5S_ALL,H5P_DEFAULT,wdata)<0) TEST_ERROR; + + /* Close Dataset */ + if(H5Dclose(dataset)<0) TEST_ERROR; + + /* Open a dataset */ + if((dataset=H5Dopen(file, DSET_STR_NAME))<0) TEST_ERROR; + + /* Get datatype for dataset */ + if((dtype = H5Dget_type(dataset))<0) TEST_ERROR; + + /* Construct native type */ + if((native_type=H5Tget_native_type(dtype, H5T_DIR_DEFAULT))<0) + TEST_ERROR; + + /* Check if the data type is equal */ + if(!H5Tequal(native_type, tid1) || H5T_STRING!=H5Tget_class(native_type)) + TEST_ERROR; + + /* Read dataset from disk */ + if(H5Dread(dataset,native_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,rdata)<0) TEST_ERROR; + + /* Compare data read in */ + for(i=0; i