2003-04-01 01:59:04 +08:00
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
|
* Copyright by the Board of Trustees of the University of Illinois. *
|
|
|
|
|
* All rights reserved. *
|
|
|
|
|
* *
|
|
|
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
|
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
|
|
|
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
|
|
|
|
* of the source code distribution tree; Copyright.html can be found at the *
|
|
|
|
|
* root level of an installed copy of the electronic HDF5 document set and *
|
|
|
|
|
* is linked from the top-level documents page. It can also be found at *
|
|
|
|
|
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
|
|
|
|
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/***********************************************************
|
|
|
|
|
*
|
|
|
|
|
* Test program: tattr
|
|
|
|
|
*
|
|
|
|
|
* Test the attribute functionality
|
|
|
|
|
*
|
|
|
|
|
*************************************************************/
|
|
|
|
|
|
2001-04-04 02:09:16 +08:00
|
|
|
|
#include "testhdf5.h"
|
2003-10-06 05:14:40 +08:00
|
|
|
|
#include "h5test.h"
|
2001-04-04 02:09:16 +08:00
|
|
|
|
#include "hdf5.h"
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
1999-01-13 04:55:21 +08:00
|
|
|
|
#define FILENAME "tattr.h5"
|
1998-04-24 06:24:52 +08:00
|
|
|
|
#define ATTR_NAME_LEN 16
|
|
|
|
|
#define ATTR_MAX_DIMS 7
|
2002-10-30 00:37:49 +08:00
|
|
|
|
#define ATTR_TMP_NAME "temp_name"
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* 3-D dataset with fixed dimensions */
|
|
|
|
|
#define SPACE1_NAME "Space1"
|
|
|
|
|
#define SPACE1_RANK 3
|
|
|
|
|
#define SPACE1_DIM1 3
|
|
|
|
|
#define SPACE1_DIM2 15
|
|
|
|
|
#define SPACE1_DIM3 13
|
|
|
|
|
|
2003-05-14 02:54:25 +08:00
|
|
|
|
/* Dataset Information */
|
|
|
|
|
#define DSET1_NAME "Dataset1"
|
|
|
|
|
#define DSET2_NAME "Dataset2"
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
/* Group Information */
|
|
|
|
|
#define GROUP1_NAME "/Group1"
|
|
|
|
|
|
2003-10-06 05:14:40 +08:00
|
|
|
|
/* Named Datatype Information */
|
|
|
|
|
#define TYPE1_NAME "/Type"
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
/* Attribute Rank & Dimensions */
|
|
|
|
|
#define ATTR1_NAME "Attr1"
|
|
|
|
|
#define ATTR1_RANK 1
|
|
|
|
|
#define ATTR1_DIM1 3
|
1998-06-19 05:03:30 +08:00
|
|
|
|
int attr_data1[ATTR1_DIM1]={512,-234,98123}; /* Test data for 1st attribute */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
2002-10-30 00:37:49 +08:00
|
|
|
|
/* rank & dimensions for another attribute */
|
|
|
|
|
#define ATTR1A_NAME "Attr1_a"
|
|
|
|
|
int attr_data1a[ATTR1_DIM1]={256,11945,-22107};
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
#define ATTR2_NAME "Attr2"
|
|
|
|
|
#define ATTR2_RANK 2
|
|
|
|
|
#define ATTR2_DIM1 2
|
|
|
|
|
#define ATTR2_DIM2 2
|
1998-06-19 05:03:30 +08:00
|
|
|
|
int attr_data2[ATTR2_DIM1][ATTR2_DIM2]={{7614,-416},{197814,-3}}; /* Test data for 2nd attribute */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
#define ATTR3_NAME "Attr3"
|
|
|
|
|
#define ATTR3_RANK 3
|
|
|
|
|
#define ATTR3_DIM1 2
|
|
|
|
|
#define ATTR3_DIM2 2
|
|
|
|
|
#define ATTR3_DIM3 2
|
|
|
|
|
double attr_data3[ATTR3_DIM1][ATTR3_DIM2][ATTR3_DIM3]={{{2.3,-26.1},{0.123,-10.0}},{{981724.2,-0.91827},{2.0,23.0}}}; /* Test data for 3rd attribute */
|
|
|
|
|
|
|
|
|
|
#define ATTR4_NAME "Attr4"
|
|
|
|
|
#define ATTR4_RANK 2
|
|
|
|
|
#define ATTR4_DIM1 2
|
|
|
|
|
#define ATTR4_DIM2 2
|
|
|
|
|
#define ATTR4_FIELDNAME1 "i"
|
|
|
|
|
#define ATTR4_FIELDNAME2 "d"
|
|
|
|
|
#define ATTR4_FIELDNAME3 "c"
|
1998-04-24 23:50:48 +08:00
|
|
|
|
size_t attr4_field1_off=0;
|
|
|
|
|
size_t attr4_field2_off=0;
|
|
|
|
|
size_t attr4_field3_off=0;
|
1998-04-24 06:24:52 +08:00
|
|
|
|
struct attr4_struct {
|
1998-06-19 05:03:30 +08:00
|
|
|
|
int i;
|
1998-04-24 06:24:52 +08:00
|
|
|
|
double d;
|
|
|
|
|
char c;
|
|
|
|
|
} attr_data4[ATTR4_DIM1][ATTR4_DIM2]={{{3,-26.1,'d'},{-100000, 0.123,'3'}},
|
|
|
|
|
{{-23,981724.2,'Q'},{0,2.0,'\n'}}}; /* Test data for 4th attribute */
|
|
|
|
|
|
1998-04-29 06:33:07 +08:00
|
|
|
|
#define ATTR5_NAME "Attr5"
|
|
|
|
|
#define ATTR5_RANK 0
|
2001-11-28 00:29:13 +08:00
|
|
|
|
float attr_data5=(float)-5.123; /* Test data for 5th attribute */
|
1998-04-29 06:33:07 +08:00
|
|
|
|
|
2000-04-13 05:10:05 +08:00
|
|
|
|
herr_t attr_op1(hid_t loc_id, const char *name, void *op_data);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_basic_write(): Test basic H5A (attribute) code.
|
|
|
|
|
** Tests integer attributes on both datasets and groups
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_basic_write(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File IDs */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
|
|
|
|
hid_t group; /* Group ID */
|
|
|
|
|
hid_t sid1,sid2; /* Dataspace ID */
|
2002-10-30 00:37:49 +08:00
|
|
|
|
hid_t attr, attr2; /* Attribute ID */
|
|
|
|
|
hsize_t attr_size; /* storage size for attribute */
|
|
|
|
|
ssize_t attr_name_size; /* size of attribute name */
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
char *attr_name=NULL; /* name of attribute */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
|
|
|
|
|
hsize_t dims2[] = {ATTR1_DIM1};
|
|
|
|
|
hsize_t dims3[] = {ATTR2_DIM1,ATTR2_DIM2};
|
1999-08-28 06:07:00 +08:00
|
|
|
|
int read_data1[ATTR1_DIM1]={0}; /* Buffer for reading 1st attribute */
|
|
|
|
|
int i;
|
1998-04-24 06:24:52 +08:00
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
1998-04-29 06:33:07 +08:00
|
|
|
|
MESSAGE(5, ("Testing Basic Scalar Attribute Writing Functions\n"));
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Create file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fcreate");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for dataset */
|
|
|
|
|
sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
|
|
|
|
|
CHECK(sid1, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create a dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dcreate(fid1,DSET1_NAME,H5T_NATIVE_UCHAR,sid1,H5P_DEFAULT);
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
CHECK(dataset, FAIL, "H5Dcreate");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Create dataspace for attribute */
|
|
|
|
|
sid2 = H5Screate_simple(ATTR1_RANK, dims2, NULL);
|
|
|
|
|
CHECK(sid2, FAIL, "H5Screate_simple");
|
|
|
|
|
|
1998-04-29 00:37:17 +08:00
|
|
|
|
/* Try to create an attribute on the file (should fail) */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Acreate(fid1,ATTR1_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-29 00:37:17 +08:00
|
|
|
|
VERIFY(ret, FAIL, "H5Acreate");
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
/* Create an attribute for the dataset */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
attr=H5Acreate(dataset,ATTR1_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(attr, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Try to create the same attribute again (should fail) */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Acreate(dataset,ATTR1_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(ret, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write attribute information */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Awrite(attr,H5T_NATIVE_INT,attr_data1);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
2002-10-30 00:37:49 +08:00
|
|
|
|
/* Create an another attribute for the dataset */
|
|
|
|
|
attr2=H5Acreate(dataset,ATTR1A_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
|
|
|
|
CHECK(attr, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write attribute information */
|
|
|
|
|
ret=H5Awrite(attr2,H5T_NATIVE_INT,attr_data1a);
|
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
|
|
|
|
/* Check storage size for attribute */
|
|
|
|
|
attr_size=H5Aget_storage_size(attr);
|
|
|
|
|
VERIFY(attr_size, (ATTR1_DIM1*sizeof(int)), "H5A_get_storage_size");
|
|
|
|
|
|
1999-08-28 06:07:00 +08:00
|
|
|
|
/* Read attribute information immediately, without closing attribute */
|
|
|
|
|
ret=H5Aread(attr,H5T_NATIVE_INT,read_data1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR1_DIM1; i++)
|
|
|
|
|
if(attr_data1[i]!=read_data1[i]) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
|
1999-08-28 06:07:00 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
2002-10-30 00:37:49 +08:00
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* change attribute name */
|
|
|
|
|
ret=H5Arename(dataset, ATTR1_NAME, ATTR_TMP_NAME);
|
|
|
|
|
CHECK(ret, FAIL, "H5Arename");
|
|
|
|
|
|
|
|
|
|
/* Open attribute again */
|
|
|
|
|
attr=H5Aopen_name(dataset, ATTR_TMP_NAME);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_name");
|
|
|
|
|
|
|
|
|
|
/* Verify new attribute name */
|
|
|
|
|
attr_name_size = H5Aget_name(attr, 0, NULL);
|
|
|
|
|
CHECK(attr_name_size, FAIL, "H5Aget_name");
|
|
|
|
|
|
|
|
|
|
if(attr_name_size>0)
|
2002-11-20 20:52:49 +08:00
|
|
|
|
attr_name = (char*)HDcalloc((size_t)(attr_name_size+1), sizeof(char));
|
2002-10-30 00:37:49 +08:00
|
|
|
|
|
2002-11-22 00:23:38 +08:00
|
|
|
|
ret=(herr_t)H5Aget_name(attr, (size_t)(attr_name_size+1), attr_name);
|
2002-10-30 00:37:49 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Aget_name");
|
|
|
|
|
ret=HDstrcmp(attr_name, ATTR_TMP_NAME);
|
|
|
|
|
VERIFY(ret, 0, "HDstrcmp");
|
|
|
|
|
|
|
|
|
|
if(attr_name)
|
|
|
|
|
HDfree(attr_name);
|
|
|
|
|
|
|
|
|
|
/* Read attribute information immediately, without closing attribute */
|
|
|
|
|
ret=H5Aread(attr,H5T_NATIVE_INT,read_data1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR1_DIM1; i++)
|
|
|
|
|
if(attr_data1[i]!=read_data1[i]) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
|
2002-10-30 00:37:49 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Open the second attribute again */
|
|
|
|
|
attr2=H5Aopen_name(dataset, ATTR1A_NAME);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_name");
|
|
|
|
|
|
|
|
|
|
/* Verify new attribute name */
|
|
|
|
|
attr_name_size = H5Aget_name(attr2, 0, NULL);
|
|
|
|
|
CHECK(attr_name_size, FAIL, "H5Aget_name");
|
|
|
|
|
|
|
|
|
|
if(attr_name_size>0)
|
2002-11-20 20:52:49 +08:00
|
|
|
|
attr_name = (char*)HDcalloc((size_t)(attr_name_size+1), sizeof(char));
|
2002-10-30 00:37:49 +08:00
|
|
|
|
|
2002-11-22 00:23:38 +08:00
|
|
|
|
ret=(herr_t)H5Aget_name(attr2, (size_t)(attr_name_size+1), attr_name);
|
2002-10-30 00:37:49 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Aget_name");
|
|
|
|
|
ret=HDstrcmp(attr_name, ATTR1A_NAME);
|
|
|
|
|
VERIFY(ret, 0, "HDstrcmp");
|
|
|
|
|
|
|
|
|
|
if(attr_name)
|
|
|
|
|
HDfree(attr_name);
|
|
|
|
|
|
|
|
|
|
/* Read attribute information immediately, without closing attribute */
|
|
|
|
|
ret=H5Aread(attr2,H5T_NATIVE_INT,read_data1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR1_DIM1; i++)
|
|
|
|
|
if(attr_data1a[i]!=read_data1[i]) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
|
2002-10-30 00:37:49 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* change first attribute back to the original name */
|
|
|
|
|
ret=H5Arename(dataset, ATTR_TMP_NAME, ATTR1_NAME);
|
|
|
|
|
CHECK(ret, FAIL, "H5Arename");
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
ret = H5Sclose(sid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
ret = H5Sclose(sid2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Close Dataset */
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Create group */
|
|
|
|
|
group = H5Gcreate(fid1, GROUP1_NAME, 0);
|
|
|
|
|
CHECK(group, FAIL, "H5Gcreate");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for attribute */
|
|
|
|
|
sid2 = H5Screate_simple(ATTR2_RANK, dims3, NULL);
|
|
|
|
|
CHECK(sid2, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create an attribute for the group */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
attr=H5Acreate(group,ATTR2_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(attr, FAIL, "H5Acreate");
|
|
|
|
|
|
2002-10-30 00:37:49 +08:00
|
|
|
|
/* Check storage size for attribute */
|
|
|
|
|
attr_size=H5Aget_storage_size(attr);
|
|
|
|
|
VERIFY(attr_size, (ATTR2_DIM1*ATTR2_DIM2*sizeof(int)), "H5Aget_storage_size");
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
/* Try to create the same attribute again (should fail) */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Acreate(group,ATTR2_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(ret, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write attribute information */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Awrite(attr,H5T_NATIVE_INT,attr_data2);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
2002-10-30 00:37:49 +08:00
|
|
|
|
/* Check storage size for attribute */
|
|
|
|
|
attr_size=H5Aget_storage_size(attr);
|
|
|
|
|
VERIFY(attr_size, (ATTR2_DIM1*ATTR2_DIM2*sizeof(int)), "H5A_get_storage_size");
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close Attribute dataspace */
|
|
|
|
|
ret = H5Sclose(sid2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Close Group */
|
|
|
|
|
ret = H5Gclose(group);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
} /* test_attr_basic_write() */
|
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_basic_read(): Test basic H5A (attribute) code.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_basic_read(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File IDs */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
|
|
|
|
hid_t group; /* Group ID */
|
|
|
|
|
hid_t attr; /* Attribute ID */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
int read_data1[ATTR1_DIM1]={0}; /* Buffer for reading 1st attribute */
|
|
|
|
|
int read_data2[ATTR2_DIM1][ATTR2_DIM2]={{0}}; /* Buffer for reading 2nd attribute */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
int i,j;
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Basic Attribute Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Create file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fopen");
|
|
|
|
|
|
|
|
|
|
/* Open the dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dopen(fid1,DSET1_NAME);
|
1998-04-29 06:33:07 +08:00
|
|
|
|
CHECK(dataset, FAIL, "H5Dopen");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
2002-10-30 00:37:49 +08:00
|
|
|
|
VERIFY(ret, 2, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Open an attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_name(dataset,ATTR1_NAME);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_name");
|
|
|
|
|
|
|
|
|
|
/* Read attribute information */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Aread(attr,H5T_NATIVE_INT,read_data1);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR1_DIM1; i++)
|
|
|
|
|
if(attr_data1[i]!=read_data1[i]) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Open the group */
|
|
|
|
|
group=H5Gopen(fid1,GROUP1_NAME);
|
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(group);
|
|
|
|
|
VERIFY(ret, 1, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Open an attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_name(group,ATTR2_NAME);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_name");
|
|
|
|
|
|
|
|
|
|
/* Read attribute information */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Aread(attr,H5T_NATIVE_INT,read_data2);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR2_DIM1; i++)
|
|
|
|
|
for(j=0; j<ATTR2_DIM2; j++)
|
|
|
|
|
if(attr_data2[i][j]!=read_data2[i][j]) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data2[%d][%d]=%d, read_data2[%d][%d]=%d\n",__LINE__, i,j,attr_data2[i][j],i,j,read_data1[i]);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close group */
|
|
|
|
|
ret = H5Gclose(group);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
} /* test_attr_basic_read() */
|
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
1998-04-29 06:33:07 +08:00
|
|
|
|
** test_attr_compound_write(): Test H5A (attribute) code.
|
|
|
|
|
** Tests compound datatype attributes
|
1998-04-24 06:24:52 +08:00
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
1998-04-29 06:33:07 +08:00
|
|
|
|
test_attr_compound_write(void)
|
1998-04-24 06:24:52 +08:00
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File IDs */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
|
|
|
|
hid_t tid1; /* Attribute datatype ID */
|
|
|
|
|
hid_t sid1,sid2; /* Dataspace ID */
|
|
|
|
|
hid_t attr; /* Attribute ID */
|
|
|
|
|
hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
|
|
|
|
|
hsize_t dims2[] = {ATTR4_DIM1,ATTR4_DIM2};
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Multiple Attribute Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Create file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fcreate");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for dataset */
|
|
|
|
|
sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
|
|
|
|
|
CHECK(sid1, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create a dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dcreate(fid1,DSET1_NAME,H5T_NATIVE_UCHAR,sid1,H5P_DEFAULT);
|
|
|
|
|
CHECK(dataset, FAIL, "H5Dcreate");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Close dataset's dataspace */
|
|
|
|
|
ret = H5Sclose(sid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Create the attribute datatype. */
|
|
|
|
|
tid1 = H5Tcreate (H5T_COMPOUND, sizeof(struct attr4_struct));
|
|
|
|
|
CHECK(tid1, FAIL, "H5Tcreate");
|
1998-04-24 23:50:48 +08:00
|
|
|
|
attr4_field1_off=HOFFSET(struct attr4_struct, i);
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret = H5Tinsert(tid1, ATTR4_FIELDNAME1, attr4_field1_off, H5T_NATIVE_INT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Tinsert");
|
1998-04-24 23:50:48 +08:00
|
|
|
|
attr4_field2_off=HOFFSET(struct attr4_struct, d);
|
|
|
|
|
ret = H5Tinsert(tid1, ATTR4_FIELDNAME2, attr4_field2_off, H5T_NATIVE_DOUBLE);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Tinsert");
|
1998-04-24 23:50:48 +08:00
|
|
|
|
attr4_field3_off=HOFFSET(struct attr4_struct, c);
|
1998-11-26 01:21:21 +08:00
|
|
|
|
ret = H5Tinsert(tid1, ATTR4_FIELDNAME3, attr4_field3_off,
|
|
|
|
|
H5T_NATIVE_SCHAR);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Tinsert");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for 1st attribute */
|
|
|
|
|
sid2 = H5Screate_simple(ATTR4_RANK, dims2, NULL);
|
|
|
|
|
CHECK(sid2, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create complex attribute for the dataset */
|
|
|
|
|
attr=H5Acreate(dataset,ATTR4_NAME,tid1,sid2,H5P_DEFAULT);
|
|
|
|
|
CHECK(attr, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Try to create the same attribute again (should fail) */
|
1998-04-29 00:37:17 +08:00
|
|
|
|
ret=H5Acreate(dataset,ATTR4_NAME,tid1,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(ret, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write complex attribute data */
|
1998-06-17 03:38:26 +08:00
|
|
|
|
ret=H5Awrite(attr,tid1,attr_data4);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close attribute's dataspace */
|
|
|
|
|
ret = H5Sclose(sid2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Close attribute's datatype */
|
|
|
|
|
ret = H5Tclose(tid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Tclose");
|
|
|
|
|
|
|
|
|
|
/* Close Dataset */
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
1998-04-29 06:33:07 +08:00
|
|
|
|
} /* test_attr_compound_write() */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
1998-04-29 06:33:07 +08:00
|
|
|
|
** test_attr_compound_read(): Test basic H5A (attribute) code.
|
1998-04-24 06:24:52 +08:00
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
1998-04-29 06:33:07 +08:00
|
|
|
|
test_attr_compound_read(void)
|
1998-04-24 06:24:52 +08:00
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File IDs */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
|
|
|
|
hid_t space; /* Attribute dataspace */
|
|
|
|
|
hid_t type; /* Attribute datatype */
|
|
|
|
|
hid_t attr; /* Attribute ID */
|
|
|
|
|
char attr_name[ATTR_NAME_LEN]; /* Buffer for attribute names */
|
|
|
|
|
int rank; /* Attribute rank */
|
|
|
|
|
hsize_t dims[ATTR_MAX_DIMS]; /* Attribute dimensions */
|
2001-09-26 01:46:32 +08:00
|
|
|
|
H5T_class_t t_class; /* Attribute datatype class */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
H5T_order_t order; /* Attribute datatype order */
|
|
|
|
|
size_t size; /* Attribute datatype size as stored in file */
|
|
|
|
|
int fields; /* # of Attribute datatype fields */
|
|
|
|
|
char *fieldname; /* Name of a field */
|
|
|
|
|
size_t offset; /* Attribute datatype field offset */
|
|
|
|
|
hid_t field; /* Attribute field datatype */
|
1998-04-28 21:59:08 +08:00
|
|
|
|
struct attr4_struct read_data4[ATTR4_DIM1][ATTR4_DIM2]; /* Buffer for reading 4th attribute */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
int i,j;
|
|
|
|
|
size_t name_len; /* Length of attribute name */
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Basic Attribute Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Open file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fopen");
|
|
|
|
|
|
|
|
|
|
/* Open the dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dopen(fid1,DSET1_NAME);
|
|
|
|
|
CHECK(dataset, FAIL, "H5Dopen");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 1, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Open 1st attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_idx(dataset,0);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_idx");
|
|
|
|
|
|
|
|
|
|
/* Verify Dataspace */
|
|
|
|
|
space=H5Aget_space(attr);
|
|
|
|
|
CHECK(space, FAIL, "H5Aget_space");
|
1998-09-01 11:35:23 +08:00
|
|
|
|
rank=H5Sget_simple_extent_ndims(space);
|
|
|
|
|
VERIFY(rank, ATTR4_RANK, "H5Sget_simple_extent_ndims");
|
|
|
|
|
ret=H5Sget_simple_extent_dims(space,dims, NULL);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sget_simple_extent_dims");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
if(dims[0]!=ATTR4_DIM1) {
|
|
|
|
|
printf("attribute dimensions different: dims[0]=%d, should be %d\n",(int)dims[0],ATTR4_DIM1);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
if(dims[1]!=ATTR4_DIM2) {
|
|
|
|
|
printf("attribute dimensions different: dims[1]=%d, should be %d\n",(int)dims[1],ATTR4_DIM2);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
H5Sclose(space);
|
|
|
|
|
|
|
|
|
|
/* Verify Datatype */
|
|
|
|
|
type=H5Aget_type(attr);
|
|
|
|
|
CHECK(type, FAIL, "H5Aget_type");
|
2001-09-26 01:46:32 +08:00
|
|
|
|
t_class=H5Tget_class(type);
|
|
|
|
|
VERIFY(t_class, H5T_COMPOUND, "H5Tget_class");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
fields=H5Tget_nmembers(type);
|
|
|
|
|
VERIFY(fields, 3, "H5Tget_nmembers");
|
|
|
|
|
for(i=0; i<fields; i++) {
|
2003-10-14 03:31:33 +08:00
|
|
|
|
fieldname=H5Tget_member_name(type,(unsigned)i);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
if(!(HDstrcmp(fieldname,ATTR4_FIELDNAME1) ||
|
|
|
|
|
HDstrcmp(fieldname,ATTR4_FIELDNAME2) ||
|
|
|
|
|
HDstrcmp(fieldname,ATTR4_FIELDNAME3))) {
|
|
|
|
|
printf("invalid field name for field #%d: %s\n",i,fieldname);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
free(fieldname);
|
|
|
|
|
} /* end for */
|
|
|
|
|
offset=H5Tget_member_offset(type,0);
|
1998-04-24 23:50:48 +08:00
|
|
|
|
VERIFY(offset, attr4_field1_off, "H5Tget_member_offset");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
offset=H5Tget_member_offset(type,1);
|
1998-04-24 23:50:48 +08:00
|
|
|
|
VERIFY(offset, attr4_field2_off, "H5Tget_member_offset");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
offset=H5Tget_member_offset(type,2);
|
1998-04-24 23:50:48 +08:00
|
|
|
|
VERIFY(offset, attr4_field3_off, "H5Tget_member_offset");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Verify each field's type, class & size */
|
|
|
|
|
field=H5Tget_member_type(type,0);
|
|
|
|
|
CHECK(field, FAIL, "H5Tget_member_type");
|
2001-09-26 01:46:32 +08:00
|
|
|
|
t_class=H5Tget_class(field);
|
|
|
|
|
VERIFY(t_class, H5T_INTEGER, "H5Tget_class");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
order=H5Tget_order(field);
|
1998-06-19 05:03:30 +08:00
|
|
|
|
VERIFY(order, H5Tget_order(H5T_NATIVE_INT), "H5Tget_order");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
size=H5Tget_size(field);
|
1998-06-19 05:03:30 +08:00
|
|
|
|
VERIFY(size, H5Tget_size(H5T_NATIVE_INT), "H5Tget_size");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
H5Tclose(field);
|
|
|
|
|
field=H5Tget_member_type(type,1);
|
|
|
|
|
CHECK(field, FAIL, "H5Tget_member_type");
|
2001-09-26 01:46:32 +08:00
|
|
|
|
t_class=H5Tget_class(field);
|
|
|
|
|
VERIFY(t_class, H5T_FLOAT, "H5Tget_class");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
order=H5Tget_order(field);
|
|
|
|
|
VERIFY(order, H5Tget_order(H5T_NATIVE_DOUBLE), "H5Tget_order");
|
|
|
|
|
size=H5Tget_size(field);
|
|
|
|
|
VERIFY(size, H5Tget_size(H5T_NATIVE_DOUBLE), "H5Tget_size");
|
|
|
|
|
H5Tclose(field);
|
|
|
|
|
field=H5Tget_member_type(type,2);
|
|
|
|
|
CHECK(field, FAIL, "H5Tget_member_type");
|
2001-09-26 01:46:32 +08:00
|
|
|
|
t_class=H5Tget_class(field);
|
|
|
|
|
VERIFY(t_class, H5T_INTEGER, "H5Tget_class");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
order=H5Tget_order(field);
|
1998-11-26 01:21:21 +08:00
|
|
|
|
VERIFY(order, H5Tget_order(H5T_NATIVE_SCHAR), "H5Tget_order");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
size=H5Tget_size(field);
|
1998-11-26 01:21:21 +08:00
|
|
|
|
VERIFY(size, H5Tget_size(H5T_NATIVE_SCHAR), "H5Tget_size");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
H5Tclose(field);
|
|
|
|
|
|
|
|
|
|
/* Read attribute information */
|
1998-06-17 03:38:26 +08:00
|
|
|
|
ret=H5Aread(attr,type,read_data4);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR4_DIM1; i++)
|
|
|
|
|
for(j=0; j<ATTR4_DIM2; j++)
|
|
|
|
|
if(HDmemcmp(&attr_data4[i][j],&read_data4[i][j],sizeof(struct attr4_struct))) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data4[%d][%d].i=%d, read_data4[%d][%d].i=%d\n",__LINE__,i,j,attr_data4[i][j].i,i,j,read_data4[i][j].i);
|
|
|
|
|
printf("%d: attribute data different: attr_data4[%d][%d].d=%f, read_data4[%d][%d].d=%f\n",__LINE__,i,j,attr_data4[i][j].d,i,j,read_data4[i][j].d);
|
|
|
|
|
printf("%d: attribute data different: attr_data4[%d][%d].c=%c, read_data4[%d][%d].c=%c\n",__LINE__,i,j,attr_data4[i][j].c,i,j,read_data4[i][j].c);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Verify Name */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,ATTR_NAME_LEN, attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR4_NAME), "H5Aget_name");
|
|
|
|
|
if(HDstrcmp(attr_name,ATTR4_NAME)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,ATTR4_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute datatype */
|
|
|
|
|
ret=H5Tclose(type);
|
|
|
|
|
CHECK(ret, FAIL, "H5Tclose");
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close dataset */
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
1998-04-29 06:33:07 +08:00
|
|
|
|
} /* test_attr_compound_read() */
|
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_scalar_write(): Test scalar H5A (attribute) writing code.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_scalar_write(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File IDs */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
|
|
|
|
hid_t sid1,sid2; /* Dataspace ID */
|
|
|
|
|
hid_t attr; /* Attribute ID */
|
|
|
|
|
hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Basic Attribute Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Create file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
1998-04-29 06:33:07 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fcreate");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for dataset */
|
|
|
|
|
sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
|
|
|
|
|
CHECK(sid1, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create a dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dcreate(fid1,DSET1_NAME,H5T_NATIVE_UCHAR,sid1,H5P_DEFAULT);
|
|
|
|
|
CHECK(dataset, FAIL, "H5Dcreate");
|
1998-04-29 06:33:07 +08:00
|
|
|
|
|
|
|
|
|
/* Create dataspace for attribute */
|
|
|
|
|
sid2 = H5Screate_simple(ATTR5_RANK, NULL, NULL);
|
|
|
|
|
CHECK(sid2, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create an attribute for the dataset */
|
|
|
|
|
attr=H5Acreate(dataset,ATTR5_NAME,H5T_NATIVE_FLOAT,sid2,H5P_DEFAULT);
|
|
|
|
|
CHECK(attr, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Try to create the same attribute again (should fail) */
|
|
|
|
|
ret=H5Acreate(dataset,ATTR5_NAME,H5T_NATIVE_FLOAT,sid2,H5P_DEFAULT);
|
|
|
|
|
VERIFY(ret, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write attribute information */
|
|
|
|
|
ret=H5Awrite(attr,H5T_NATIVE_FLOAT,&attr_data5);
|
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
ret = H5Sclose(sid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
ret = H5Sclose(sid2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Close Dataset */
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
} /* test_attr_scalar_write() */
|
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_scalar_read(): Test scalar H5A (attribute) reading code.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_scalar_read(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File IDs */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
2003-12-14 04:08:09 +08:00
|
|
|
|
hid_t sid; /* Dataspace ID */
|
|
|
|
|
hid_t attr; /* Attribute ID */
|
|
|
|
|
H5S_class_t stype; /* Dataspace class */
|
1998-04-29 06:33:07 +08:00
|
|
|
|
float rdata=0.0; /* Buffer for reading 1st attribute */
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Basic Scalar Attribute Reading Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Create file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
|
1998-04-29 06:33:07 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fopen");
|
|
|
|
|
|
|
|
|
|
/* Open the dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dopen(fid1,DSET1_NAME);
|
1998-04-29 06:33:07 +08:00
|
|
|
|
CHECK(dataset, FAIL, "H5Dopen");
|
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 1, "H5Aget_num_attrs");
|
1998-04-29 06:33:07 +08:00
|
|
|
|
|
|
|
|
|
/* Open an attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_name(dataset,ATTR5_NAME);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_name");
|
|
|
|
|
|
|
|
|
|
/* Read attribute information */
|
|
|
|
|
ret=H5Aread(attr,H5T_NATIVE_FLOAT,&rdata);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
VERIFY(rdata, attr_data5, "H5Aread");
|
|
|
|
|
|
2003-12-14 04:08:09 +08:00
|
|
|
|
/* Get the attribute's dataspace */
|
|
|
|
|
sid = H5Aget_space(attr);
|
|
|
|
|
CHECK(sid, FAIL, "H5Aget_space");
|
|
|
|
|
|
|
|
|
|
/* Make certain the dataspace is scalar */
|
|
|
|
|
stype = H5Sget_simple_extent_type (sid);
|
|
|
|
|
VERIFY(stype, H5S_SCALAR, "H5Sget_simple_extent_type");
|
|
|
|
|
|
|
|
|
|
/* Close dataspace */
|
|
|
|
|
ret = H5Sclose(sid);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
1998-04-29 06:33:07 +08:00
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
} /* test_attr_scalar_read() */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_mult_write(): Test basic H5A (attribute) code.
|
|
|
|
|
** Tests integer attributes on both datasets and groups
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_mult_write(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File IDs */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
|
|
|
|
hid_t sid1,sid2; /* Dataspace ID */
|
|
|
|
|
hid_t attr; /* Attribute ID */
|
|
|
|
|
hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
|
|
|
|
|
hsize_t dims2[] = {ATTR1_DIM1};
|
|
|
|
|
hsize_t dims3[] = {ATTR2_DIM1,ATTR2_DIM2};
|
|
|
|
|
hsize_t dims4[] = {ATTR3_DIM1,ATTR3_DIM2,ATTR3_DIM3};
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Multiple Attribute Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Create file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fcreate");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for dataset */
|
|
|
|
|
sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
|
|
|
|
|
CHECK(sid1, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create a dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dcreate(fid1,DSET1_NAME,H5T_NATIVE_UCHAR,sid1,H5P_DEFAULT);
|
|
|
|
|
CHECK(dataset, FAIL, "H5Dcreate");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Close dataset's dataspace */
|
|
|
|
|
ret = H5Sclose(sid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for 1st attribute */
|
|
|
|
|
sid2 = H5Screate_simple(ATTR1_RANK, dims2, NULL);
|
|
|
|
|
CHECK(sid2, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create 1st attribute for the dataset */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
attr=H5Acreate(dataset,ATTR1_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(attr, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Try to create the same attribute again (should fail) */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Acreate(dataset,ATTR1_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(ret, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write 1st attribute data */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Awrite(attr,H5T_NATIVE_INT,attr_data1);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
|
|
|
|
/* Close 1st attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close attribute's dataspace */
|
|
|
|
|
ret = H5Sclose(sid2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for 2nd attribute */
|
|
|
|
|
sid2 = H5Screate_simple(ATTR2_RANK, dims3, NULL);
|
|
|
|
|
CHECK(sid2, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create 2nd attribute for the dataset */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
attr=H5Acreate(dataset,ATTR2_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(attr, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Try to create the same attribute again (should fail) */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Acreate(dataset,ATTR2_NAME,H5T_NATIVE_INT,sid2,H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(ret, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write 2nd attribute information */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Awrite(attr,H5T_NATIVE_INT,attr_data2);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
|
|
|
|
/* Close 2nd attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close 2nd attribute's dataspace */
|
|
|
|
|
ret = H5Sclose(sid2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for 3rd attribute */
|
|
|
|
|
sid2 = H5Screate_simple(ATTR3_RANK, dims4, NULL);
|
|
|
|
|
CHECK(sid2, FAIL, "H5Screate_simple");
|
|
|
|
|
|
|
|
|
|
/* Create 3rd attribute for the dataset */
|
|
|
|
|
attr=H5Acreate(dataset,ATTR3_NAME,H5T_NATIVE_DOUBLE,sid2,H5P_DEFAULT);
|
|
|
|
|
CHECK(attr, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Try to create the same attribute again (should fail) */
|
|
|
|
|
ret=H5Acreate(dataset,ATTR3_NAME,H5T_NATIVE_DOUBLE,sid2,H5P_DEFAULT);
|
|
|
|
|
VERIFY(ret, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write 3rd attribute information */
|
1998-06-17 03:38:26 +08:00
|
|
|
|
ret=H5Awrite(attr,H5T_NATIVE_DOUBLE,attr_data3);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
|
|
|
|
/* Close 3rd attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close 3rd attribute's dataspace */
|
|
|
|
|
ret = H5Sclose(sid2);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Close Dataset */
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
} /* test_attr_mult_write() */
|
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_mult_read(): Test basic H5A (attribute) code.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_mult_read(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File IDs */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
|
|
|
|
hid_t space; /* Attribute dataspace */
|
|
|
|
|
hid_t type; /* Attribute datatype */
|
|
|
|
|
hid_t attr; /* Attribute ID */
|
|
|
|
|
char attr_name[ATTR_NAME_LEN]; /* Buffer for attribute names */
|
|
|
|
|
char temp_name[ATTR_NAME_LEN]; /* Buffer for mangling attribute names */
|
|
|
|
|
int rank; /* Attribute rank */
|
|
|
|
|
hsize_t dims[ATTR_MAX_DIMS]; /* Attribute dimensions */
|
2001-09-26 01:46:32 +08:00
|
|
|
|
H5T_class_t t_class; /* Attribute datatype class */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
H5T_order_t order; /* Attribute datatype order */
|
|
|
|
|
size_t size; /* Attribute datatype size as stored in file */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
int read_data1[ATTR1_DIM1]={0}; /* Buffer for reading 1st attribute */
|
|
|
|
|
int read_data2[ATTR2_DIM1][ATTR2_DIM2]={{0}}; /* Buffer for reading 2nd attribute */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
double read_data3[ATTR3_DIM1][ATTR3_DIM2][ATTR3_DIM3]={{{0}}}; /* Buffer for reading 3rd attribute */
|
|
|
|
|
int i,j,k;
|
|
|
|
|
size_t name_len; /* Length of attribute name */
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Basic Attribute Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Open file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fopen");
|
|
|
|
|
|
|
|
|
|
/* Open the dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dopen(fid1,DSET1_NAME);
|
|
|
|
|
CHECK(dataset, FAIL, "H5Dopen");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 3, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Open 1st attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_idx(dataset,0);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_idx");
|
|
|
|
|
|
|
|
|
|
/* Verify Dataspace */
|
|
|
|
|
space=H5Aget_space(attr);
|
|
|
|
|
CHECK(space, FAIL, "H5Aget_space");
|
1998-09-01 11:35:23 +08:00
|
|
|
|
rank=H5Sget_simple_extent_ndims(space);
|
|
|
|
|
VERIFY(rank, ATTR1_RANK, "H5Sget_simple_extent_ndims");
|
|
|
|
|
ret=H5Sget_simple_extent_dims(space,dims, NULL);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sget_simple_extent_dims");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
if(dims[0]!=ATTR1_DIM1) {
|
|
|
|
|
printf("attribute dimensions different: dims[0]=%d, should be %d\n",(int)dims[0],ATTR1_DIM1);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
H5Sclose(space);
|
|
|
|
|
|
|
|
|
|
/* Verify Datatype */
|
|
|
|
|
type=H5Aget_type(attr);
|
|
|
|
|
CHECK(type, FAIL, "H5Aget_type");
|
2001-09-26 01:46:32 +08:00
|
|
|
|
t_class=H5Tget_class(type);
|
|
|
|
|
VERIFY(t_class, H5T_INTEGER, "H5Tget_class");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
order=H5Tget_order(type);
|
1998-06-19 05:03:30 +08:00
|
|
|
|
VERIFY(order, H5Tget_order(H5T_NATIVE_INT), "H5Tget_order");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
size=H5Tget_size(type);
|
1998-06-19 05:03:30 +08:00
|
|
|
|
VERIFY(size, H5Tget_size(H5T_NATIVE_INT), "H5Tget_size");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
H5Tclose(type);
|
|
|
|
|
|
|
|
|
|
/* Read attribute information */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Aread(attr,H5T_NATIVE_INT,read_data1);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR1_DIM1; i++)
|
|
|
|
|
if(attr_data1[i]!=read_data1[i]) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data1[%d]=%d, read_data1[%d]=%d\n",__LINE__,i,attr_data1[i],i,read_data1[i]);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Verify Name */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr, ATTR_NAME_LEN, attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR1_NAME), "H5Aget_name");
|
|
|
|
|
if(HDstrcmp(attr_name,ATTR1_NAME)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,ATTR1_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Verify Name with too small of a buffer */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,HDstrlen(ATTR1_NAME), attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR1_NAME), "H5Aget_name");
|
|
|
|
|
HDstrcpy(temp_name,ATTR1_NAME); /* make a copy of the name */
|
|
|
|
|
temp_name[HDstrlen(ATTR1_NAME)-1]='\0'; /* truncate it to match the one retrieved */
|
|
|
|
|
if(HDstrcmp(attr_name,temp_name)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,temp_name);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Open 2nd attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_idx(dataset,1);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_idx");
|
|
|
|
|
|
|
|
|
|
/* Verify Dataspace */
|
|
|
|
|
space=H5Aget_space(attr);
|
|
|
|
|
CHECK(space, FAIL, "H5Aget_space");
|
1998-09-01 11:35:23 +08:00
|
|
|
|
rank=H5Sget_simple_extent_ndims(space);
|
|
|
|
|
VERIFY(rank, ATTR2_RANK, "H5Sget_simple_extent_ndims");
|
|
|
|
|
ret=H5Sget_simple_extent_dims(space,dims, NULL);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sget_simple_extent_dims");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
if(dims[0]!=ATTR2_DIM1) {
|
|
|
|
|
printf("attribute dimensions different: dims[0]=%d, should be %d\n",(int)dims[0],ATTR2_DIM1);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
if(dims[1]!=ATTR2_DIM2) {
|
|
|
|
|
printf("attribute dimensions different: dims[1]=%d, should be %d\n",(int)dims[1],ATTR2_DIM2);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
H5Sclose(space);
|
|
|
|
|
|
|
|
|
|
/* Verify Datatype */
|
|
|
|
|
type=H5Aget_type(attr);
|
|
|
|
|
CHECK(type, FAIL, "H5Aget_type");
|
2001-09-26 01:46:32 +08:00
|
|
|
|
t_class=H5Tget_class(type);
|
|
|
|
|
VERIFY(t_class, H5T_INTEGER, "H5Tget_class");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
order=H5Tget_order(type);
|
1998-06-19 05:03:30 +08:00
|
|
|
|
VERIFY(order, H5Tget_order(H5T_NATIVE_INT), "H5Tget_order");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
size=H5Tget_size(type);
|
1998-06-19 05:03:30 +08:00
|
|
|
|
VERIFY(size, H5Tget_size(H5T_NATIVE_INT), "H5Tget_size");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
H5Tclose(type);
|
|
|
|
|
|
|
|
|
|
/* Read attribute information */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
ret=H5Aread(attr,H5T_NATIVE_INT,read_data2);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR2_DIM1; i++)
|
|
|
|
|
for(j=0; j<ATTR2_DIM2; j++)
|
|
|
|
|
if(attr_data2[i][j]!=read_data2[i][j]) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data2[%d][%d]=%d, read_data2[%d][%d]=%d\n",__LINE__,i,j,attr_data2[i][j],i,j,read_data2[i][j]);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Verify Name */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,ATTR_NAME_LEN, attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR2_NAME), "H5Aget_name");
|
|
|
|
|
if(HDstrcmp(attr_name,ATTR2_NAME)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,ATTR2_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Verify Name with too small of a buffer */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,HDstrlen(ATTR2_NAME), attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR2_NAME), "H5Aget_name");
|
|
|
|
|
HDstrcpy(temp_name,ATTR2_NAME); /* make a copy of the name */
|
|
|
|
|
temp_name[HDstrlen(ATTR2_NAME)-1]='\0'; /* truncate it to match the one retrieved */
|
|
|
|
|
if(HDstrcmp(attr_name,temp_name)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,temp_name);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Open 2nd attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_idx(dataset,2);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_idx");
|
|
|
|
|
|
|
|
|
|
/* Verify Dataspace */
|
|
|
|
|
space=H5Aget_space(attr);
|
|
|
|
|
CHECK(space, FAIL, "H5Aget_space");
|
1998-09-01 11:35:23 +08:00
|
|
|
|
rank=H5Sget_simple_extent_ndims(space);
|
|
|
|
|
VERIFY(rank, ATTR3_RANK, "H5Sget_simple_extent_ndims");
|
|
|
|
|
ret=H5Sget_simple_extent_dims(space,dims, NULL);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sget_simple_extent_dims");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
if(dims[0]!=ATTR3_DIM1) {
|
|
|
|
|
printf("attribute dimensions different: dims[0]=%d, should be %d\n",(int)dims[0],ATTR3_DIM1);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
if(dims[1]!=ATTR3_DIM2) {
|
|
|
|
|
printf("attribute dimensions different: dims[1]=%d, should be %d\n",(int)dims[1],ATTR3_DIM2);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
if(dims[2]!=ATTR3_DIM3) {
|
|
|
|
|
printf("attribute dimensions different: dims[2]=%d, should be %d\n",(int)dims[2],ATTR3_DIM3);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
H5Sclose(space);
|
|
|
|
|
|
|
|
|
|
/* Verify Datatype */
|
|
|
|
|
type=H5Aget_type(attr);
|
|
|
|
|
CHECK(type, FAIL, "H5Aget_type");
|
2001-09-26 01:46:32 +08:00
|
|
|
|
t_class=H5Tget_class(type);
|
|
|
|
|
VERIFY(t_class, H5T_FLOAT, "H5Tget_class");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
order=H5Tget_order(type);
|
|
|
|
|
VERIFY(order, H5Tget_order(H5T_NATIVE_DOUBLE), "H5Tget_order");
|
|
|
|
|
size=H5Tget_size(type);
|
|
|
|
|
VERIFY(size, H5Tget_size(H5T_NATIVE_DOUBLE), "H5Tget_size");
|
|
|
|
|
H5Tclose(type);
|
|
|
|
|
|
|
|
|
|
/* Read attribute information */
|
1998-06-17 03:38:26 +08:00
|
|
|
|
ret=H5Aread(attr,H5T_NATIVE_DOUBLE,read_data3);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Verify values read in */
|
|
|
|
|
for(i=0; i<ATTR3_DIM1; i++)
|
|
|
|
|
for(j=0; j<ATTR3_DIM2; j++)
|
|
|
|
|
for(k=0; k<ATTR3_DIM3; k++)
|
|
|
|
|
if(attr_data3[i][j][k]!=read_data3[i][j][k]) {
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
printf("%d: attribute data different: attr_data3[%d][%d][%d]=%f, read_data3[%d][%d][%d]=%f\n",__LINE__,i,j,k,attr_data3[i][j][k],i,j,k,read_data3[i][j][k]);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Verify Name */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,ATTR_NAME_LEN, attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR3_NAME), "H5Aget_name");
|
|
|
|
|
if(HDstrcmp(attr_name,ATTR3_NAME)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,ATTR3_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Verify Name with too small of a buffer */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,HDstrlen(ATTR3_NAME), attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR3_NAME), "H5Aget_name");
|
|
|
|
|
HDstrcpy(temp_name,ATTR3_NAME); /* make a copy of the name */
|
|
|
|
|
temp_name[HDstrlen(ATTR3_NAME)-1]='\0'; /* truncate it to match the one retrieved */
|
|
|
|
|
if(HDstrcmp(attr_name,temp_name)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,temp_name);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close dataset */
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
} /* test_attr_mult_read() */
|
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** attr_op1(): Attribute operator
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
2000-04-13 05:10:05 +08:00
|
|
|
|
herr_t attr_op1(hid_t UNUSED loc_id, const char *name, void *op_data)
|
1998-04-24 06:24:52 +08:00
|
|
|
|
{
|
|
|
|
|
int *count=(int *)op_data;
|
2000-04-13 05:10:05 +08:00
|
|
|
|
herr_t ret=0;
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
switch(*count) {
|
|
|
|
|
case 0:
|
|
|
|
|
if(HDstrcmp(name,ATTR1_NAME)) {
|
|
|
|
|
printf("attribute name different: name=%s, should be %s\n",name,ATTR1_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
(*count)++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
if(HDstrcmp(name,ATTR2_NAME)) {
|
|
|
|
|
printf("attribute name different: name=%s, should be %s\n",name,ATTR2_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
(*count)++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
if(HDstrcmp(name,ATTR3_NAME)) {
|
|
|
|
|
printf("attribute name different: name=%s, should be %s\n",name,ATTR3_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
(*count)++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
ret=-1;
|
|
|
|
|
break;
|
|
|
|
|
} /* end switch() */
|
|
|
|
|
|
|
|
|
|
return(ret);
|
|
|
|
|
} /* end attr_op1() */
|
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_iterate(): Test H5A (attribute) iterator code.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_iterate(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t file; /* HDF5 File ID */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
hid_t sid; /* Dataspace ID */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
unsigned start; /* Starting attribute to look up */
|
|
|
|
|
int count; /* operator data for the iterator */
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Basic Attribute Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Open file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
file = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(file, FAIL, "H5Fopen");
|
|
|
|
|
|
2003-05-14 02:54:25 +08:00
|
|
|
|
/* Create a dataspace */
|
|
|
|
|
sid=H5Screate(H5S_SCALAR);
|
|
|
|
|
CHECK(sid, FAIL, "H5Screate");
|
|
|
|
|
|
|
|
|
|
/* Create a new dataset */
|
|
|
|
|
dataset=H5Dcreate(file,DSET2_NAME,H5T_NATIVE_INT,sid,H5P_DEFAULT);
|
|
|
|
|
CHECK(dataset, FAIL, "H5Dcreate");
|
|
|
|
|
|
|
|
|
|
/* Close dataspace */
|
|
|
|
|
ret = H5Sclose(sid);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
2003-05-14 02:54:25 +08:00
|
|
|
|
VERIFY(ret, 0, "H5Aget_num_attrs");
|
|
|
|
|
|
|
|
|
|
/* Iterate over attributes on dataset */
|
|
|
|
|
start=0;
|
|
|
|
|
count=0;
|
|
|
|
|
ret = H5Aiterate(dataset,&start,attr_op1,&count);
|
|
|
|
|
VERIFY(ret, 0, "H5Aiterate");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Close dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Open existing dataset w/attributes */
|
|
|
|
|
dataset=H5Dopen(file,DSET1_NAME);
|
|
|
|
|
CHECK(dataset, FAIL, "H5Dopen");
|
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 3, "H5Aget_num_attrs");
|
|
|
|
|
|
|
|
|
|
/* Iterate over attributes on dataset */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
start=0;
|
|
|
|
|
count=0;
|
|
|
|
|
ret = H5Aiterate(dataset,&start,attr_op1,&count);
|
|
|
|
|
VERIFY(ret, 0, "H5Aiterate");
|
|
|
|
|
|
|
|
|
|
/* Close dataset */
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(file);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
} /* test_attr_iterate() */
|
|
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_delete(): Test H5A (attribute) code for deleting objects.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_delete(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t fid1; /* HDF5 File ID */
|
|
|
|
|
hid_t dataset; /* Dataset ID */
|
|
|
|
|
hid_t attr; /* Attribute ID */
|
|
|
|
|
char attr_name[ATTR_NAME_LEN]; /* Buffer for attribute names */
|
|
|
|
|
size_t name_len; /* Length of attribute name */
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Basic Attribute Functions\n"));
|
|
|
|
|
|
|
|
|
|
/* Open file */
|
1999-01-13 04:55:21 +08:00
|
|
|
|
fid1 = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
CHECK(fid1, FAIL, "H5Fopen");
|
|
|
|
|
|
|
|
|
|
/* Open the dataset */
|
2003-05-14 02:54:25 +08:00
|
|
|
|
dataset=H5Dopen(fid1,DSET1_NAME);
|
|
|
|
|
CHECK(dataset, FAIL, "H5Dopen");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 3, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Try to delete bogus attribute */
|
|
|
|
|
ret=H5Adelete(dataset,"Bogus");
|
1998-04-29 00:37:17 +08:00
|
|
|
|
VERIFY(ret, FAIL, "H5Adelete");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 3, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Delete middle (2nd) attribute */
|
|
|
|
|
ret=H5Adelete(dataset,ATTR2_NAME);
|
|
|
|
|
CHECK(ret, FAIL, "H5Adelete");
|
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 2, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Open 1st attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_idx(dataset,0);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_idx");
|
|
|
|
|
|
|
|
|
|
/* Verify Name */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,ATTR_NAME_LEN,attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR1_NAME), "H5Aget_name");
|
|
|
|
|
if(HDstrcmp(attr_name,ATTR1_NAME)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,ATTR1_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Open last (formally 3rd) attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_idx(dataset,1);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_idx");
|
|
|
|
|
|
|
|
|
|
/* Verify Name */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,ATTR_NAME_LEN, attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR3_NAME), "H5Aget_name");
|
|
|
|
|
if(HDstrcmp(attr_name,ATTR3_NAME)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,ATTR3_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Delete first attribute */
|
|
|
|
|
ret=H5Adelete(dataset,ATTR1_NAME);
|
|
|
|
|
CHECK(ret, FAIL, "H5Adelete");
|
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 1, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Open last (formally 3rd) attribute for the dataset */
|
|
|
|
|
attr=H5Aopen_idx(dataset,0);
|
|
|
|
|
CHECK(attr, FAIL, "H5Aopen_idx");
|
|
|
|
|
|
|
|
|
|
/* Verify Name */
|
[svn-r537] Changes since 19980722
----------------------
./src/H5A.c
./src/H5Apublic.h
./test/tattr.c
Switched the order of the second and third argument of
H5Aget_name() to make it consistent with other functions that
take buffers and buffer sizes.
./src/H5G.c
./src/H5Gpublic.h
./src/H5Gprivate.h
The H5Gget_comment() function returns the size of the comment
including the null terminator. If the object has no comment
then zero is returned. If an error occurs then a negative
value is returned.
./MANIFEST
./tools/Makefile.in
./tools/h5tools.h [NEW]
./tools/h5dump.c [NEW]
Created a library for printing values of datasets in a way
that looks nice. It's not done yet, but I needed it for
debugging the contents of files from Jim Reus.
./tools/h5ls.c
Added the `-d' and `--dump' options which cause the contents
of a dataset to be printed. Added `-w N' and `--width=N'
options to control how wide the raw data output should be. If
you want single-column output then say `-w1'.
Printing dataset values can now handle datasets of any integer
or floating point atomic type. As a special case, integers
which are one byte wide are treated a character strings for
now.
Sample output:
$ h5ls --dump --width=60 banana.hdf
ARCHIVE 0:0:0:744 Dataset {52/Inf}
Data:
(0) "U struct complex { double R; double I; };\012V"
(43) " double;\012"
U 0:0:0:2500 Dataset {256/512}
Data: printing of compound data types is not implemented yet
V 0:0:0:3928 Dataset {256/512}
Data:
(0) 0, 0.015625, 0.03125, 0.046875, 0.0625,
(5) 0.078125, 0.09375, 0.109375, 0.125, 0.140625,
(10) 0.15625, 0.171875, 0.1875, 0.203125, 0.21875,
(15) 0.234375, 0.25, 0.265625, 0.28125, 0.296875,
...
1998-07-24 05:19:17 +08:00
|
|
|
|
name_len=H5Aget_name(attr,ATTR_NAME_LEN, attr_name);
|
1998-04-24 06:24:52 +08:00
|
|
|
|
VERIFY(name_len, HDstrlen(ATTR3_NAME), "H5Aget_name");
|
|
|
|
|
if(HDstrcmp(attr_name,ATTR3_NAME)) {
|
|
|
|
|
printf("attribute name different: attr_name=%s, should be %s\n",attr_name,ATTR3_NAME);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Delete first attribute */
|
|
|
|
|
ret=H5Adelete(dataset,ATTR3_NAME);
|
|
|
|
|
CHECK(ret, FAIL, "H5Adelete");
|
|
|
|
|
|
|
|
|
|
/* Verify the correct number of attributes */
|
1998-09-01 11:35:23 +08:00
|
|
|
|
ret=H5Aget_num_attrs(dataset);
|
|
|
|
|
VERIFY(ret, 0, "H5Aget_num_attrs");
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* Close dataset */
|
|
|
|
|
ret = H5Dclose(dataset);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret = H5Fclose(fid1);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
} /* test_attr_delete() */
|
|
|
|
|
|
2003-10-06 05:14:40 +08:00
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr_dtype_shared(): Test H5A (attribute) code for using
|
|
|
|
|
** shared datatypes in attributes.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
static void
|
|
|
|
|
test_attr_dtype_shared(void)
|
|
|
|
|
{
|
|
|
|
|
hid_t file_id; /* File ID */
|
|
|
|
|
hid_t dset_id; /* Dataset ID */
|
|
|
|
|
hid_t space_id; /* Dataspace ID for dataset & attribute */
|
|
|
|
|
hid_t type_id; /* Datatype ID for named datatype */
|
|
|
|
|
hid_t attr_id; /* Attribute ID */
|
|
|
|
|
int data=8; /* Data to write */
|
|
|
|
|
int rdata=0; /* Read read in */
|
|
|
|
|
H5G_stat_t statbuf; /* Object's information */
|
|
|
|
|
off_t empty_filesize; /* Size of empty file */
|
|
|
|
|
off_t filesize; /* Size of file after modifications */
|
|
|
|
|
herr_t ret; /* Generic return value */
|
|
|
|
|
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Shared Datatypes with Attributes\n"));
|
|
|
|
|
|
|
|
|
|
/* Create a file */
|
|
|
|
|
file_id=H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
|
|
|
|
CHECK(file_id, FAIL, "H5Fopen");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret=H5Fclose(file_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
|
|
|
|
|
/* Get size of file */
|
|
|
|
|
empty_filesize=h5_get_file_size(FILENAME);
|
|
|
|
|
if(empty_filesize==0) {
|
|
|
|
|
printf("Line %d: file size wrong!\n",__LINE__);
|
|
|
|
|
num_errs++;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Re-open file */
|
|
|
|
|
file_id=H5Fopen(FILENAME,H5F_ACC_RDWR,H5P_DEFAULT);
|
|
|
|
|
CHECK(file_id, FAIL, "H5Fopen");
|
|
|
|
|
|
|
|
|
|
/* Create a datatype to commit and use */
|
|
|
|
|
type_id=H5Tcopy(H5T_NATIVE_INT);
|
|
|
|
|
CHECK(type_id, FAIL, "H5Tcopy");
|
|
|
|
|
|
|
|
|
|
/* Commit datatype to file */
|
|
|
|
|
ret=H5Tcommit(file_id,TYPE1_NAME,type_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Tcommit");
|
|
|
|
|
|
|
|
|
|
/* Check reference count on named datatype */
|
|
|
|
|
ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gget_objinfo");
|
|
|
|
|
VERIFY(statbuf.nlink, 1, "H5Tcommit");
|
|
|
|
|
|
|
|
|
|
/* Create dataspace for dataset */
|
|
|
|
|
space_id=H5Screate(H5S_SCALAR);
|
|
|
|
|
CHECK(space_id, FAIL, "H5Screate");
|
|
|
|
|
|
|
|
|
|
/* Create dataset */
|
|
|
|
|
dset_id=H5Dcreate(file_id,DSET1_NAME,type_id,space_id,H5P_DEFAULT);
|
|
|
|
|
CHECK(dset_id, FAIL, "H5Dcreate");
|
|
|
|
|
|
|
|
|
|
/* Check reference count on named datatype */
|
|
|
|
|
ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gget_objinfo");
|
|
|
|
|
VERIFY(statbuf.nlink, 2, "H5Dcreate");
|
|
|
|
|
|
|
|
|
|
/* Create attribute on dataset */
|
|
|
|
|
attr_id=H5Acreate(dset_id,ATTR1_NAME,type_id,space_id,H5P_DEFAULT);
|
|
|
|
|
CHECK(attr_id, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Check reference count on named datatype */
|
|
|
|
|
ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gget_objinfo");
|
|
|
|
|
VERIFY(statbuf.nlink, 3, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Delete attribute */
|
|
|
|
|
ret=H5Adelete(dset_id,ATTR1_NAME);
|
|
|
|
|
CHECK(ret, FAIL, "H5Adelete");
|
|
|
|
|
|
|
|
|
|
/* Check reference count on named datatype */
|
|
|
|
|
ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gget_objinfo");
|
|
|
|
|
VERIFY(statbuf.nlink, 2, "H5Adelete");
|
|
|
|
|
|
|
|
|
|
/* Create attribute on dataset */
|
|
|
|
|
attr_id=H5Acreate(dset_id,ATTR1_NAME,type_id,space_id,H5P_DEFAULT);
|
|
|
|
|
CHECK(attr_id, FAIL, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Check reference count on named datatype */
|
|
|
|
|
ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gget_objinfo");
|
|
|
|
|
VERIFY(statbuf.nlink, 3, "H5Acreate");
|
|
|
|
|
|
|
|
|
|
/* Write data into the attribute */
|
|
|
|
|
ret=H5Awrite(attr_id,H5T_NATIVE_INT,&data);
|
|
|
|
|
CHECK(ret, FAIL, "H5Awrite");
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close dataset */
|
|
|
|
|
ret=H5Dclose(dset_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Close dataspace */
|
|
|
|
|
ret=H5Sclose(space_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Sclose");
|
|
|
|
|
|
|
|
|
|
/* Close datatype */
|
|
|
|
|
ret=H5Tclose(type_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Tclose");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret=H5Fclose(file_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
|
|
|
|
|
/* Re-open file */
|
|
|
|
|
file_id=H5Fopen(FILENAME,H5F_ACC_RDWR,H5P_DEFAULT);
|
|
|
|
|
CHECK(file_id, FAIL, "H5Fopen");
|
|
|
|
|
|
|
|
|
|
/* Open dataset */
|
|
|
|
|
dset_id=H5Dopen(file_id,DSET1_NAME);
|
|
|
|
|
CHECK(dset_id, FAIL, "H5Dopen");
|
|
|
|
|
|
|
|
|
|
/* Open attribute */
|
|
|
|
|
attr_id=H5Aopen_name(dset_id,ATTR1_NAME);
|
|
|
|
|
CHECK(attr_id, FAIL, "H5Aopen_name");
|
|
|
|
|
|
|
|
|
|
/* Read data from the attribute */
|
|
|
|
|
ret=H5Aread(attr_id,H5T_NATIVE_INT,&rdata);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aread");
|
|
|
|
|
VERIFY(data, rdata, "H5Aread");
|
|
|
|
|
|
|
|
|
|
/* Close attribute */
|
|
|
|
|
ret=H5Aclose(attr_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Aclose");
|
|
|
|
|
|
|
|
|
|
/* Close dataset */
|
|
|
|
|
ret=H5Dclose(dset_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Dclose");
|
|
|
|
|
|
|
|
|
|
/* Check reference count on named datatype */
|
|
|
|
|
ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gget_objinfo");
|
|
|
|
|
VERIFY(statbuf.nlink, 3, "H5Aopen_name");
|
|
|
|
|
|
|
|
|
|
/* Unlink the dataset */
|
|
|
|
|
ret=H5Gunlink(file_id,DSET1_NAME);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gunlink");
|
|
|
|
|
|
|
|
|
|
/* Check reference count on named datatype */
|
|
|
|
|
ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gget_objinfo");
|
|
|
|
|
VERIFY(statbuf.nlink, 1, "H5Gunlink");
|
|
|
|
|
|
|
|
|
|
/* Unlink the named datatype */
|
|
|
|
|
ret=H5Gunlink(file_id,TYPE1_NAME);
|
|
|
|
|
CHECK(ret, FAIL, "H5Gunlink");
|
|
|
|
|
|
|
|
|
|
/* Close file */
|
|
|
|
|
ret=H5Fclose(file_id);
|
|
|
|
|
CHECK(ret, FAIL, "H5Fclose");
|
|
|
|
|
|
|
|
|
|
/* Check size of file */
|
|
|
|
|
filesize=h5_get_file_size(FILENAME);
|
|
|
|
|
VERIFY(filesize, empty_filesize, "H5Fclose");
|
|
|
|
|
} /* test_attr_dtype_shared() */
|
|
|
|
|
|
1998-04-24 06:24:52 +08:00
|
|
|
|
/****************************************************************
|
|
|
|
|
**
|
|
|
|
|
** test_attr(): Main H5A (attribute) testing routine.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************/
|
|
|
|
|
void
|
|
|
|
|
test_attr(void)
|
|
|
|
|
{
|
|
|
|
|
/* Output message about test being performed */
|
|
|
|
|
MESSAGE(5, ("Testing Attributes\n"));
|
|
|
|
|
|
|
|
|
|
/* These next two tests use the same file information */
|
|
|
|
|
test_attr_basic_write(); /* Test basic H5A writing code */
|
|
|
|
|
test_attr_basic_read(); /* Test basic H5A reading code */
|
|
|
|
|
|
|
|
|
|
/* These next two tests use the same file information */
|
1998-04-29 06:33:07 +08:00
|
|
|
|
test_attr_compound_write(); /* Test complex datatype H5A writing code */
|
|
|
|
|
test_attr_compound_read(); /* Test complex datatype H5A reading code */
|
|
|
|
|
|
|
|
|
|
/* These next two tests use the same file information */
|
|
|
|
|
test_attr_scalar_write(); /* Test scalar dataspace H5A writing code */
|
|
|
|
|
test_attr_scalar_read(); /* Test scalar dataspace H5A reading code */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
|
|
|
|
|
/* These next four tests use the same file information */
|
|
|
|
|
test_attr_mult_write(); /* Test H5A writing code for multiple attributes */
|
|
|
|
|
test_attr_mult_read(); /* Test H5A reading code for multiple attributes */
|
|
|
|
|
test_attr_iterate(); /* Test H5A iterator code */
|
|
|
|
|
test_attr_delete(); /* Test H5A code for deleting attributes */
|
2003-10-06 05:14:40 +08:00
|
|
|
|
|
|
|
|
|
/* This next test use the same file information */
|
|
|
|
|
test_attr_dtype_shared(); /* Test using shared dataypes in attributes */
|
1998-04-24 06:24:52 +08:00
|
|
|
|
} /* test_attr() */
|
|
|
|
|
|
1998-07-03 08:57:00 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: cleanup_attr
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Cleanup temporary test files
|
|
|
|
|
*
|
|
|
|
|
* Return: none
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Albert Cheng
|
|
|
|
|
* July 2, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
cleanup_attr(void)
|
|
|
|
|
{
|
1999-01-13 04:55:21 +08:00
|
|
|
|
remove(FILENAME);
|
1998-07-03 08:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
|