summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rw-r--r--src/H5Shyper.c58
-rw-r--r--src/H5Sprivate.h1
-rw-r--r--src/H5Sselect.c3
-rw-r--r--test/Makefile.am2
-rw-r--r--test/Makefile.in5
-rw-r--r--test/tcoords.c402
-rw-r--r--test/testhdf5.c1
-rw-r--r--test/testhdf5.h2
9 files changed, 471 insertions, 4 deletions
diff --git a/MANIFEST b/MANIFEST
index e995e3e..7473603 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -804,6 +804,7 @@
./test/tbogus.h5
./test/tchecksum.c
./test/tconfig.c
+./test/tcoords.c
./test/testerror.sh.in
./test/testframe.c
./test/testhdf5.c
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 8c56056..7e3b30c 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -280,8 +280,10 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
if(iter->elmt_size>0) {
/* Check for any "contiguous" blocks that can be flattened */
for(u=rank-1; u>0; u--) {
- if(tdiminfo[u].count==1 && tdiminfo[u].block==mem_size[u])
+ if(tdiminfo[u].count==1 && tdiminfo[u].block==mem_size[u]) {
cont_dim++;
+ iter->dims_flatten[u] = TRUE;
+ }
} /* end for */
} /* end if */
@@ -418,6 +420,7 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
*
*-------------------------------------------------------------------------
*/
+#ifdef TMP
static herr_t
H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords)
{
@@ -434,15 +437,25 @@ H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords)
/* Check if this is a "flattened" regular hyperslab selection */
if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rank<iter->rank) {
unsigned flat_dim; /* The rank of the flattened dimension */
+ unsigned dim = iter->rank - iter->u.hyp.iter_rank;
/* Get the rank of the flattened dimension */
flat_dim=iter->u.hyp.iter_rank-1;
/* Copy the coordinates up to where things got flattened */
+#ifdef TMP
HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*flat_dim);
/* Compute the coordinates for the flattened dimensions */
H5V_array_calc(iter->u.hyp.off[flat_dim],iter->rank-flat_dim,&(iter->dims[flat_dim]),&(coords[flat_dim]));
+#else
+ /* Compute the coords for the flattened dimensions */
+ H5V_array_calc(iter->u.hyp.off[0],dim+1,iter->dims,coords);
+
+ /* Copy the coords for the unflattened dimensions */
+ if(dim+1 < iter->rank)
+ HDmemcpy(&(coords[dim+1]),&(iter->u.hyp.off[1]),sizeof(hsize_t)*(iter->u.hyp.iter_rank -1));
+#endif
} /* end if */
else
HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*iter->rank);
@@ -452,6 +465,49 @@ H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords)
FUNC_LEAVE_NOAPI(SUCCEED);
} /* H5S_hyper_iter_coords() */
+#else
+static herr_t
+H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_iter_coords);
+
+ /* Check args */
+ assert (iter);
+ assert (coords);
+
+ /* Copy the offset of the current point */
+
+ /* Check for a single "regular" hyperslab */
+ if(iter->u.hyp.diminfo_valid) {
+ /* Check if this is a "flattened" regular hyperslab selection */
+ if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rank<iter->rank) {
+ unsigned dim = iter->rank - iter->u.hyp.iter_rank;
+ int u, v;
+ int begin = -1;
+
+ for(u=iter->rank-1, v=iter->u.hyp.iter_rank-1; u>=0, v>=0; u--) {
+ if(!iter->dims_flatten[u]) {
+ if(begin > 0) {
+ /* Compute the coords for the flattened dimensions */
+ H5V_array_calc(iter->u.hyp.off[v],begin-u+1,&(iter->dims[u]),&(coords[u]));
+ begin = -1;
+ } else
+ HDmemcpy(&(coords[u]), &(iter->u.hyp.off[v]), sizeof(hsize_t));
+ v--;
+ }
+ else if(iter->dims_flatten[u] && (begin == -1))
+ begin = u;
+ }
+ } /* end if */
+ else
+ HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*iter->rank);
+ } /* end if */
+ else
+ HDmemcpy(coords,iter->u.hyp.off,sizeof(hsize_t)*iter->rank);
+
+ FUNC_LEAVE_NOAPI(SUCCEED);
+} /* H5S_hyper_iter_coords() */
+#endif
/*-------------------------------------------------------------------------
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index ace2559..64bf3a5 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -103,6 +103,7 @@ typedef struct H5S_sel_iter_t {
/* Information common to all iterators */
unsigned rank; /* Rank of dataspace the selection iterator is operating on */
hsize_t *dims; /* Dimensions of dataspace the selection is operating on */
+ hbool_t *dims_flatten;
hsize_t elmt_left; /* Number of elements left to iterate over */
size_t elmt_size; /* Size of elements to iterate over */
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 41b565f..09083fa 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -804,6 +804,9 @@ H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_s
if(sel_iter->rank>0) {
/* Point to the dataspace dimensions */
sel_iter->dims=space->extent.size;
+
+ /* Allocate space for the flags whether the dimension is flattened */
+ sel_iter->dims_flatten = (hbool_t*)H5MM_calloc(sel_iter->rank*sizeof(hbool_t));
} /* end if */
else
sel_iter->dims = NULL;
diff --git a/test/Makefile.am b/test/Makefile.am
index e5a1394..62b1f92 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -121,7 +121,7 @@ CHECK_CLEANFILES+=cmpd_dset.h5 compact_dataset.h5 dataset.h5 extend.h5 istore.h5
# Sources for testhdf5 executable
testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \
- tgenprop.c th5o.c th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c \
+ tgenprop.c th5o.c th5s.c tcoords.c theap.c tid.c titerate.c tmeta.c tmisc.c \
trefer.c trefstr.c tselect.c tskiplist.c tsohm.c ttime.c ttst.c tunicode.c \
tvlstr.c tvltypes.c
diff --git a/test/Makefile.in b/test/Makefile.in
index add9df2..a7617b3 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -288,7 +288,7 @@ stab_DEPENDENCIES = libh5test.la $(LIBHDF5)
am_testhdf5_OBJECTS = testhdf5.$(OBJEXT) tarray.$(OBJEXT) \
tattr.$(OBJEXT) tchecksum.$(OBJEXT) tconfig.$(OBJEXT) \
tfile.$(OBJEXT) tgenprop.$(OBJEXT) th5o.$(OBJEXT) \
- th5s.$(OBJEXT) theap.$(OBJEXT) tid.$(OBJEXT) \
+ th5s.$(OBJEXT) tcoords.$(OBJEXT) theap.$(OBJEXT) tid.$(OBJEXT) \
titerate.$(OBJEXT) tmeta.$(OBJEXT) tmisc.$(OBJEXT) \
trefer.$(OBJEXT) trefstr.$(OBJEXT) tselect.$(OBJEXT) \
tskiplist.$(OBJEXT) tsohm.$(OBJEXT) ttime.$(OBJEXT) \
@@ -652,7 +652,7 @@ ttsafe_SOURCES = ttsafe.c ttsafe_dcreate.c ttsafe_error.c ttsafe_cancel.c
# Sources for testhdf5 executable
testhdf5_SOURCES = testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \
- tgenprop.c th5o.c th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c \
+ tgenprop.c th5o.c th5s.c tcoords.c theap.c tid.c titerate.c tmeta.c tmisc.c \
trefer.c trefstr.c tselect.c tskiplist.c tsohm.c ttime.c ttst.c tunicode.c \
tvlstr.c tvltypes.c
@@ -959,6 +959,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tattr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tchecksum.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconfig.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcoords.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testframe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testhdf5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testmeta.Po@am__quote@
diff --git a/test/tcoords.c b/test/tcoords.c
new file mode 100644
index 0000000..67e7aa1
--- /dev/null
+++ b/test/tcoords.c
@@ -0,0 +1,402 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/***********************************************************
+*
+* Test program: th5s
+*
+* Test the element coordinates for dataspace selection.
+*
+*************************************************************/
+
+#include "testhdf5.h"
+
+/*
+** Data used to write the dataset.
+*/
+
+static int da_buffer[12][1][6][2];
+
+static hsize_t da_dims[4] = { 12, 1, 6, 2 };
+static hsize_t da_maxdims[4] = { H5S_UNLIMITED, H5S_UNLIMITED, H5S_UNLIMITED, H5S_UNLIMITED };
+/*static hsize_t da_chunksize[4] = { 3, 1, 2, 1 };*/
+static hsize_t da_chunksize[4] = { 12, 1, 6, 2 };
+
+/*
+** The dataset end of the selection is done using element selection.
+** These are the element locations.
+*/
+#ifdef TMP
+static hsize_t da_elements[12][4] = { { 11, 0, 0, 0 },
+ { 11, 0, 0, 1 },
+ { 11, 0, 5, 0 },
+ { 11, 0, 5, 1 },
+ { 11, 0, 1, 0 },
+ { 11, 0, 1, 1 },
+ { 11, 0, 2, 0 },
+ { 11, 0, 2, 1 },
+ { 11, 0, 3, 0 },
+ { 11, 0, 3, 1 },
+ { 11, 0, 4, 0 },
+ { 11, 0, 4, 1 } };
+#else
+static hsize_t da_elements[12][4] = { { 11, 0, 0, 0 },
+ { 11, 0, 0, 1 },
+ { 11, 0, 1, 0 },
+ { 11, 0, 1, 1 },
+ { 11, 0, 2, 0 },
+ { 11, 0, 2, 1 },
+ { 11, 0, 3, 0 },
+ { 11, 0, 3, 1 },
+ { 11, 0, 4, 0 },
+ { 11, 0, 4, 1 },
+ { 11, 0, 5, 0 },
+ { 11, 0, 5, 1 } };
+#endif
+
+/*
+** This is where it gets interesting.
+**
+** First experiment: the data being read is rank=2, so use two
+** dimensions. However, the array is 6x3, while the transfer is 6x2.
+** We use a hyperslab to select the subset. This case shows no
+** problem.
+*/
+static int mem1_buffer[6][3];
+
+static hsize_t mem1_dims[2] = { 6, 3};
+
+static hsize_t mem1_start[2] = { 0, 0 };
+static hsize_t mem1_count[2] = { 1, 1 };
+static hsize_t mem1_stride[2] = { 1, 1 };
+static hsize_t mem1_block[2] = { 6, 2 };
+
+
+/*
+** Second experiment: the transfer is the same rank as above, but we
+** add two dimensions of 1. I.e., the array is 1x1x6x2. In this
+** case, the 6x2 selection is over the entire array, not a subset of
+** the array. However, we still use hyperslab selection. This case
+** shows no problem.
+*/
+static int mem2_buffer[1][1][6][2];
+
+static hsize_t mem2_dims[4] = { 1, 1, 6, 2 };
+
+static hsize_t mem2_start[4] = { 0, 0, 0, 0 };
+static hsize_t mem2_count[4] = { 1, 1, 1, 1 };
+static hsize_t mem2_stride[4] = { 1, 1, 1, 1 };
+static hsize_t mem2_block[4] = { 1, 1, 6, 2 };
+
+
+/*
+** Third experiment: the transfer is the same rank as above, and we
+** add two dimensions of 1, but now the array is larger: 1x1x6x3.
+** The selection is now over a subset of the array (1x1x6x2). This
+** case demonstrates the problem.
+*/
+/*static int mem3_buffer[1][1][6][3];*/
+static int mem3_buffer[1][1][6][3];
+
+/*static hsize_t mem3_dims[4] = { 1, 1, 6, 3 };*/
+static hsize_t mem3_dims[4] = { 1, 1, 6, 3 };
+
+static hsize_t mem3_start[4] = { 0, 0, 0, 0 };
+static hsize_t mem3_count[4] = { 1, 1, 1, 1 };
+static hsize_t mem3_stride[4] = { 1, 1, 1, 1 };
+static hsize_t mem3_block[4] = { 1, 1, 6, 2 };
+
+/*
+** Fourth experiment: the transfer is the same rank as above, but we
+** add two dimensions of 1. I.e., the array is 1x6x3. In this
+** case, the 6x2 selection is over the entire array, not a subset of
+** the array. However, we still use hyperslab selection. This case
+** shows the problem.
+*/
+static int mem4_buffer[1][6][3];
+
+static hsize_t mem4_dims[3] = { 1, 6, 3 };
+
+static hsize_t mem4_start[3] = { 0, 0, 0 };
+static hsize_t mem4_count[3] = { 1, 1, 1 };
+static hsize_t mem4_stride[3] = { 1, 1, 1 };
+static hsize_t mem4_block[3] = { 1, 6, 2 };
+
+
+/*
+** Subroutine to write the dataset. It's probably not important to
+** this example, other than to know it's shape.
+*/
+void write_dataset()
+{
+ int i;
+ hid_t fid, dsid, daid, msid, plid;
+ herr_t rv;
+
+ fid = H5Fcreate("coord.hdf", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ if(fid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ /*dsid = H5Screate_simple(4, da_dims, da_maxdims);*/
+ dsid = H5Screate_simple(4, da_dims, da_dims);
+ if(dsid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ plid = H5Pcreate(H5P_DATASET_CREATE);
+ if(plid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ rv = H5Pset_layout(plid, H5D_CHUNKED);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ rv = H5Pset_chunk(plid, 4, da_chunksize);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ daid = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dsid, H5P_DEFAULT, plid, H5P_DEFAULT);
+ if(daid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ /*
+ ** We'll only be interested in the front plane ([0][0][0-5[0-1]) so
+ ** we only initialize that.
+ */
+ for(i = 0; i < 12; i++)
+ {
+ int j;
+ for(j = 0; j < 6; j++)
+ {
+ da_buffer[i][0][j][0] = j * 10;
+ da_buffer[i][0][j][1] = j * 10 + 1;
+ }
+ }
+
+ msid = H5Screate_simple(4, da_dims, da_dims);
+ if(msid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ rv = H5Dwrite(daid, H5T_NATIVE_INT, msid, dsid, H5P_DEFAULT, da_buffer);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ rv = H5Dclose(daid);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ rv = H5Fclose(fid);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+}
+
+/*
+** Read a dataset using the provided parameters.
+*/
+void read_dataset(int rank,
+ int* buffer,
+ hsize_t* mdims,
+ hsize_t* start,
+ hsize_t* count,
+ hsize_t* stride,
+ hsize_t* block)
+{
+ hid_t fid, dsid, daid, msid, plid;
+ herr_t rv;
+
+ fid = H5Fopen("coord.hdf", H5F_ACC_RDONLY, H5P_DEFAULT);
+ if(fid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ daid = H5Dopen2(fid, "dataset", H5P_DEFAULT);
+ if(daid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+
+ dsid = H5Dget_space(daid);
+ if(dsid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ /*
+ ** Element selection is used to select 18 elements from the dataset.
+ */
+#ifdef TMP
+ rv = H5Sselect_elements(dsid, H5S_SELECT_SET, 12, (const hsize_t**)da_elements);
+#else
+ rv = H5Sselect_hyperslab(dsid, H5S_SELECT_SET, mem2_start, mem2_stride, mem2_count, mem2_block);
+#endif
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ msid = H5Screate_simple(rank, mdims, mdims);
+ if(dsid < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ /*
+ ** The element selection above is combined with hyperslab
+ ** selection. The selection is always be a contiguous block. (See
+ ** above.)
+ */
+ rv = H5Sselect_hyperslab(msid, H5S_SELECT_SET, start, stride, count, block);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ rv = H5Dread(daid, H5T_NATIVE_INT, msid, dsid, H5P_DEFAULT, buffer);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ rv = H5Dclose(daid);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+
+ rv = H5Fclose(fid);
+ if(rv < 0)
+ {
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit(1);
+ }
+}
+
+void test_coords(void)
+{
+ int i, j;
+
+ write_dataset();
+
+ /* 1.
+ ** Use a rank=2 in memory array. (See above)
+ */
+ memset(mem1_buffer, 0, sizeof(mem1_buffer));
+ read_dataset(2, (int*)mem1_buffer, mem1_dims, mem1_start, mem1_count, mem1_stride, mem1_block);
+ for(i = 0; i < 6; i++)
+ {
+ for(j=0; j<2; j++)
+ if(da_buffer[11][0][i][j] != mem1_buffer[i][j])
+ TestErrPrintf(" %3d %3d\n", mem1_buffer[i][j], mem1_buffer[i][j]);
+ }
+
+ /* 2.
+ ** Use a rank=4 in memory array. Make the array smaller and select
+ ** the whole array. (See above)
+ */
+ memset(mem2_buffer, 0, sizeof(mem2_buffer));
+ read_dataset(4, (int*)mem2_buffer, mem2_dims, mem2_start, mem2_count, mem2_stride, mem2_block);
+ for(i = 0; i < 6; i++)
+ {
+ for(j=0; j<2; j++)
+ if(da_buffer[11][0][i][j] != mem2_buffer[0][0][i][j])
+ TestErrPrintf(" %3d %3d\n", mem2_buffer[0][0][i][j], mem2_buffer[0][0][i][j]);
+ }
+
+ /* 3.
+ ** Use a rank=4 in memory array, but don't select the whole array. (See above)
+ */
+ memset(mem3_buffer, 0, sizeof(mem3_buffer));
+ read_dataset(4, (int*)mem3_buffer, mem3_dims, mem3_start, mem3_count, mem3_stride, mem3_block);
+ for(i = 0; i < 6; i++)
+ {
+ for(j=0; j<2; j++)
+ if(da_buffer[11][0][i][j] != mem3_buffer[0][0][i][j])
+ TestErrPrintf(" %3d %3d\n", mem3_buffer[0][0][i][j], mem3_buffer[0][0][i][j]);
+
+ }
+
+ /* 4.
+ ** Use a rank=3 in memory array. (See above)
+ */
+ memset(mem4_buffer, 0, sizeof(mem4_buffer));
+ read_dataset(3, (int*)mem4_buffer, mem4_dims, mem4_start, mem4_count, mem4_stride, mem4_block);
+ for(i = 0; i < 6; i++)
+ {
+ for(j=0; j<2; j++)
+ if(da_buffer[11][0][i][j] != mem4_buffer[0][i][j])
+ TestErrPrintf(" %3d %3d\n", mem4_buffer[0][i][j], mem4_buffer[0][i][j]);
+ }
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: cleanup_coords
+ *
+ * Purpose: Cleanup temporary test files
+ *
+ * Return: none
+ *
+ * Programmer: Raymond Lu
+ * 20 Dec. 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+cleanup_coords(void)
+{
+ remove("coord.hdf");
+}
diff --git a/test/testhdf5.c b/test/testhdf5.c
index 5b174be..4afbfe8 100644
--- a/test/testhdf5.c
+++ b/test/testhdf5.c
@@ -54,6 +54,7 @@ main(int argc, char *argv[])
AddTest("file", test_file, cleanup_file, "Low-Level File I/O", NULL);
AddTest("objects", test_h5o, cleanup_h5o, "Generic Object Functions", NULL);
AddTest("h5s", test_h5s, cleanup_h5s, "Dataspaces", NULL);
+ AddTest("coords", test_coords, cleanup_coords, "Dataspace coordinates", NULL);
AddTest("sohm", test_sohm, cleanup_sohm, "Shared Object Header Messages", NULL);
AddTest("attr", test_attr, cleanup_attr, "Attributes", NULL);
AddTest("select", test_select, cleanup_select, "Selections", NULL);
diff --git a/test/testhdf5.h b/test/testhdf5.h
index 45ad476..ed8b049 100644
--- a/test/testhdf5.h
+++ b/test/testhdf5.h
@@ -133,6 +133,7 @@ void test_file(void);
void test_h5o(void);
void test_h5t(void);
void test_h5s(void);
+void test_coords(void);
void test_h5d(void);
void test_attr(void);
void test_select(void);
@@ -156,6 +157,7 @@ void cleanup_checksum(void);
void cleanup_file(void);
void cleanup_h5o(void);
void cleanup_h5s(void);
+void cleanup_coords(void);
void cleanup_attr(void);
void cleanup_select(void);
void cleanup_time(void);