[svn-r14354] Bug fix for #956 where the element coordinates went wrong for dataspace selection. Added a test

for it, too.  This round of checkin isn't well tarnished yet.  I'll come back to work on Jan. 8. I'll revise it then. 

Tested it on kagiso, smirom, linew.
This commit is contained in:
Raymond Lu 2007-12-20 16:09:58 -05:00
parent 6878261a43
commit 8377804436
9 changed files with 471 additions and 4 deletions

View File

@ -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

View File

@ -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
/*-------------------------------------------------------------------------

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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@

402
test/tcoords.c Normal file
View File

@ -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");
}

View File

@ -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);

View File

@ -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);