summaryrefslogtreecommitdiffstats
path: root/src/H5Dseq.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Dseq.c')
-rw-r--r--src/H5Dseq.c1154
1 files changed, 544 insertions, 610 deletions
diff --git a/src/H5Dseq.c b/src/H5Dseq.c
index 3868202..1c05dcf 100644
--- a/src/H5Dseq.c
+++ b/src/H5Dseq.c
@@ -52,6 +52,7 @@ static intn interface_initialize_g = 0;
* Thursday, September 28, 2000
*
* Modifications:
+ * Re-written to use new vector I/O call - QAK, 7/7/01
*
*-------------------------------------------------------------------------
*/
@@ -59,28 +60,118 @@ herr_t
H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline, const H5O_fill_t *fill,
const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size,
- hsize_t seq_len, hsize_t file_offset, void *buf/*out*/)
+ size_t seq_len, hsize_t file_offset, void *buf/*out*/)
{
+ FUNC_ENTER(H5F_seq_read, FAIL);
+
+ /* Check args */
+ assert(f);
+ assert(layout);
+ assert(buf);
+
+ if (H5F_seq_readv(f, dxpl_id, layout, pline, fill, efl, file_space, elmt_size, 1, &seq_len, &file_offset, buf)<0)
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
+
+ FUNC_LEAVE(SUCCEED);
+} /* H5F_seq_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_seq_write
+ *
+ * Purpose: Writes a sequence of bytes to a file dataset from a buffer in
+ * in memory. The data is written to file F and the array's size and
+ * storage information is in LAYOUT. External files are described
+ * according to the external file list, EFL. The sequence offset is
+ * FILE_OFFSET in the file (offsets are
+ * in terms of bytes) and the size of the hyperslab is SEQ_LEN. The
+ * total size of the file array is implied in the LAYOUT argument.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 9, 2000
+ *
+ * Modifications:
+ * Re-written to use new vector I/O routine - QAK, 7/7/01
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
+ const struct H5O_pline_t *pline, const H5O_fill_t *fill,
+ const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size,
+ size_t seq_len, hsize_t file_offset, const void *buf)
+{
+ FUNC_ENTER(H5F_seq_write, FAIL);
+
+ /* Check args */
+ assert(f);
+ assert(layout);
+ assert(buf);
+
+ if (H5F_seq_writev(f, dxpl_id, layout, pline, fill, efl, file_space, elmt_size, 1, &seq_len, &file_offset, buf)<0)
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
+
+ FUNC_LEAVE(SUCCEED);
+} /* H5F_seq_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_seq_readv
+ *
+ * Purpose: Reads in a vector of byte sequences from a file dataset into a
+ * buffer in in memory. The data is read from file F and the array's size
+ * and storage information is in LAYOUT. External files are described
+ * according to the external file list, EFL. The vector of byte sequences
+ * offsets is in the FILE_OFFSET array into the dataset (offsets are in
+ * terms of bytes) and the size of each sequence is in the SEQ_LEN array.
+ * The total size of the file array is implied in the LAYOUT argument.
+ * Bytes read into BUF are sequentially stored in the buffer, each sequence
+ * from the vector stored directly after the previous. The number of
+ * sequences is NSEQ.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 1, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
+ const struct H5O_pline_t *pline, const H5O_fill_t *fill,
+ const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size,
+ size_t nseq, size_t seq_len_arr[], hsize_t file_offset_arr[],
+ void *_buf/*out*/)
+{
+ unsigned char *real_buf=(unsigned char *)_buf; /* Local pointer to buffer to fill */
+ unsigned char *buf; /* Local pointer to buffer to fill */
+ hsize_t file_offset; /* Offset in dataset */
+ hsize_t seq_len; /* Number of bytes to read */
hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */
hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */
hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/
hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative yperslab sizes (in elements) */
hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */
intn ndims;
- hsize_t max_data = 0; /*bytes in dataset */
+ hsize_t max_data; /*bytes in dataset */
haddr_t addr=0; /*address in file */
uintn u; /*counters */
+ size_t v; /*counters */
intn i,j; /*counters */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif
- FUNC_ENTER(H5F_seq_read, FAIL);
+ FUNC_ENTER(H5F_seq_readv, FAIL);
/* Check args */
assert(f);
assert(layout);
- assert(buf);
+ assert(real_buf);
#ifdef H5_HAVE_PARALLEL
{
@@ -110,30 +201,11 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
"filters are not allowed for contiguous data");
}
- /*
- * Initialize loop variables. The loop is a multi-dimensional loop
- * that counts from SIZE down to zero and IDX is the counter. Each
- * element of IDX is treated as a digit with IDX[0] being the least
- * significant digit.
- */
- if (efl && efl->nused>0) {
- addr = 0;
- } else {
- addr = layout->addr;
- /* Compute the size of the dataset in bytes */
- for(u=0, max_data=1; u<layout->ndims; u++)
- max_data *= layout->dim[u];
-
- /* Adjust the maximum size of the data by the offset into it */
- max_data -= file_offset;
- }
- addr += file_offset;
-
- /*
- * Now begin to walk through the array, copying data from disk to
- * memory.
- */
+ /* Read directly from file if the dataset is in an external file */
+ if (efl && efl->nused>0) {
+ /* Iterate through the sequence vectors */
+ for(v=0; v<nseq; v++) {
#ifdef H5_HAVE_PARALLEL
if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
/*
@@ -143,8 +215,8 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
*/
unsigned long max, min, temp;
- temp = seq_len;
- assert(temp==seq_len); /* verify no overflow */
+ temp = seq_len_arr[v];
+ assert(temp==seq_len_arr[v]); /* verify no overflow */
MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX,
H5FD_mpio_communicator(f->shared->lf));
MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN,
@@ -157,20 +229,26 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
"collective access with unequal number of blocks not supported yet");
}
#endif
+ /* Note: We can't use data sieve buffers for datasets in external files
+ * because the 'addr' of all external files is set to 0 (above) and
+ * all datasets in external files would alias to the same set of
+ * file offsets, totally mixing up the data sieve buffer information. -QAK
+ */
+ if (H5O_efl_read(f, efl, file_offset_arr[v], seq_len_arr[v], real_buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,
+ "external data read failed");
+ }
- /* Read directly from file if the dataset is in an external file */
- if (efl && efl->nused>0) {
- /* Note: We can't use data sieve buffers for datasets in external files
- * because the 'addr' of all external files is set to 0 (above) and
- * all datasets in external files would alias to the same set of
- * file offsets, totally mixing up the data sieve buffer information. -QAK
- */
- if (H5O_efl_read(f, efl, addr, seq_len, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,
- "external data read failed");
- }
+ /* Increment offset in buffer */
+ real_buf += seq_len_arr[v];
+ } /* end for */
} else {
- if (H5F_contig_read(f, max_data, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) {
+ /* Compute the size of the dataset in bytes */
+ for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++)
+ max_data *= layout->dim[u];
+
+ /* Pass along the vector of sequences to read */
+ if (H5F_contig_readv(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0) {
HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,
"block read failed");
}
@@ -178,289 +256,218 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
break;
case H5D_CHUNKED:
- {
- /*
- * This method is unable to access external raw data files
- */
- if (efl && efl->nused>0) {
- HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL,
- "chunking and external files are mutually exclusive");
- }
- /* Compute the file offset coordinates and hyperslab size */
- if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0)
- HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
-
-#ifdef QAK
- /* The library shouldn't be reading partial elements currently */
- assert(seq_len%elmt_size!=0);
- assert(addr%elmt_size!=0);
-#endif /* QAK */
-
-#ifdef QAK
-/* Print out the file offsets & hyperslab sizes */
-{
- static int count=0;
-
- if(count<1000000) {
- printf("%s: elmt_size=%d, addr=%d, seq_len=%d\n",FUNC,(int)elmt_size,(int)addr,(int)seq_len);
- printf("%s: file_offset=%d\n",FUNC,(int)file_offset);
- count++;
- }
-}
-#endif /* QAK */
- /* Set location in dataset from the file_offset */
- addr=file_offset;
-
- /* Convert the bytes into elements */
- seq_len/=elmt_size;
- addr/=elmt_size;
-
- /* Build the array of cumulative hyperslab sizes */
- for(acc=1, i=(ndims-1); i>=0; i--) {
- down_size[i]=acc;
- acc*=dset_dims[i];
-#ifdef QAK
-printf("%s: acc=%ld, down_size[%d]=%ld\n",FUNC,(long)acc,i,(long)down_size[i]);
-#endif /* QAK */
- } /* end for */
+ /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */
+ for(v=0; v<nseq; v++) {
+ file_offset=file_offset_arr[v];
+ seq_len=seq_len_arr[v];
+ buf=real_buf;
+
+ {
+ /*
+ * This method is unable to access external raw data files
+ */
+ if (efl && efl->nused>0) {
+ HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL,
+ "chunking and external files are mutually exclusive");
+ }
+ /* Compute the file offset coordinates and hyperslab size */
+ if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0)
+ HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
+
+
+ /* Set location in dataset from the file_offset */
+ addr=file_offset;
+
+ /* Convert the bytes into elements */
+ seq_len/=elmt_size;
+ addr/=elmt_size;
+
+ /* Build the array of cumulative hyperslab sizes */
+ for(acc=1, i=(ndims-1); i>=0; i--) {
+ down_size[i]=acc;
+ acc*=dset_dims[i];
+ } /* end for */
- /* Compute the hyperslab offset from the address given */
- for(i=ndims-1; i>=0; i--) {
- coords[i]=addr%dset_dims[i];
- addr/=dset_dims[i];
-#ifdef QAK
-printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,i,(long)coords[i]);
-#endif /* QAK */
- } /* end for */
- coords[ndims]=0; /* No offset for element info */
-#ifdef QAK
-printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,ndims,(long)coords[ndims]);
-#endif /* QAK */
-
- /*
- * Peel off initial partial hyperslabs until we've got a hyperslab which starts
- * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate
- * zero for all dimensions except the slowest changing one
- */
- for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /* Check if we have a partial hyperslab in this lower dimension */
- if(coords[i]>0) {
-#ifdef QAK
-printf("%s: Need to get hyperslab, seq_len=%ld, coords[%d]=%ld\n",FUNC,(long)seq_len,i,(long)coords[i]);
-#endif /* QAK */
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(i==j)
- hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]);
- else
- if(j>i)
- hslab_size[j]=dset_dims[j];
- else
- hslab_size[j]=1;
- partial_size*=hslab_size[j];
-#ifdef QAK
-printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)hslab_size[j]);
-#endif /* QAK */
+ /* Compute the hyperslab offset from the address given */
+ for(i=ndims-1; i>=0; i--) {
+ coords[i]=addr%dset_dims[i];
+ addr/=dset_dims[i];
+ } /* end for */
+ coords[ndims]=0; /* No offset for element info */
+
+ /*
+ * Peel off initial partial hyperslabs until we've got a hyperslab which starts
+ * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate
+ * zero for all dimensions except the slowest changing one
+ */
+ for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) {
+ hsize_t partial_size; /* Size of the partial hyperslab in bytes */
+
+ /* Check if we have a partial hyperslab in this lower dimension */
+ if(coords[i]>0) {
+ /* Reset the partial hyperslab size */
+ partial_size=1;
+
+ /* Build the partial hyperslab information */
+ for(j=0; j<ndims; j++) {
+ if(i==j)
+ hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]);
+ else
+ if(j>i)
+ hslab_size[j]=dset_dims[j];
+ else
+ hslab_size[j]=1;
+ partial_size*=hslab_size[j];
+ } /* end for */
+ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
+
+ /* Read in the partial hyperslab */
+ if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords,
+ hslab_size, buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
+ }
+
+ /* Increment the buffer offset */
+ buf=(unsigned char *)buf+partial_size;
+
+ /* Decrement the length of the sequence to read */
+ seq_len-=partial_size;
+
+ /* Correct the coords array */
+ coords[i]=0;
+ coords[i-1]++;
+ } /* end if */
} /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-#ifdef QAK
-printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)hslab_size[ndims]);
-#endif /* QAK */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords,
- hslab_size, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
- }
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+partial_size;
+ /* Check if there is more than just a partial hyperslab to read */
+ if(seq_len>=down_size[0]) {
+ hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */
+ hsize_t full_size; /* Size of the full hyperslab in bytes */
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
+ /* Get the sequence length for computing the hyperslab sizes */
+ tmp_seq_len=seq_len;
- /* Correct the coords array */
- coords[i]=0;
- coords[i-1]++;
- } /* end if */
- } /* end for */
-#ifdef QAK
-printf("%s: after reading initial partial hyperslabs, seq_len=%lu\n",FUNC,(unsigned long)seq_len);
-#endif /* QAK */
-
- /* Check if there is more than just a partial hyperslab to read */
- if(seq_len>=down_size[0]) {
- hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */
- hsize_t full_size; /* Size of the full hyperslab in bytes */
-
- /* Get the sequence length for computing the hyperslab sizes */
- tmp_seq_len=seq_len;
-
- /* Reset the size of the hyperslab read in */
- full_size=1;
-
- /* Compute the hyperslab size from the length given */
- for(i=ndims-1; i>=0; i--) {
- /* Check if the hyperslab is wider than the width of the dimension */
- if(tmp_seq_len>dset_dims[i]) {
- assert(0==coords[i]);
- hslab_size[i]=dset_dims[i];
- } /* end if */
- else
- hslab_size[i]=tmp_seq_len;
+ /* Reset the size of the hyperslab read in */
+ full_size=1;
- /* compute the number of elements read in */
- full_size*=hslab_size[i];
+ /* Compute the hyperslab size from the length given */
+ for(i=ndims-1; i>=0; i--) {
+ /* Check if the hyperslab is wider than the width of the dimension */
+ if(tmp_seq_len>dset_dims[i]) {
+ assert(0==coords[i]);
+ hslab_size[i]=dset_dims[i];
+ } /* end if */
+ else
+ hslab_size[i]=tmp_seq_len;
- /* Fold the length into the length in the next highest dimension */
- tmp_seq_len/=dset_dims[i];
-#ifdef QAK
-printf("%s: tmp_seq_len=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)tmp_seq_len,i,(long)hslab_size[i]);
-#endif /* QAK */
+ /* compute the number of elements read in */
+ full_size*=hslab_size[i];
- /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/
- assert(tmp_seq_len>=1 || i==0);
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
+ /* Fold the length into the length in the next highest dimension */
+ tmp_seq_len/=dset_dims[i];
-#ifdef QAK
-/* Print out the file offsets & hyperslab sizes */
-{
- static int count=0;
-
- if(count<1000000) {
- printf("%s: elmt_size=%d, addr=%d, full_size=%ld, tmp_seq_len=%ld seq_len=%ld\n",FUNC,(int)elmt_size,(int)addr,(long)full_size,(long)tmp_seq_len,(long)seq_len);
- for(i=0; i<ndims; i++)
- printf("%s: dset_dims[%d]=%d\n",FUNC,i,(int)dset_dims[i]);
- for(i=0; i<=ndims; i++)
- printf("%s: coords[%d]=%d, hslab_size[%d]=%d\n",FUNC,i,(int)coords[i],(int)i,(int)hslab_size[i]);
- count++;
- }
-}
-#endif /* QAK */
+ /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/
+ assert(tmp_seq_len>=1 || i==0);
+ } /* end for */
+ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
- /* Read the full hyperslab in */
- if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords,
- hslab_size, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
- }
+ /* Read the full hyperslab in */
+ if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords,
+ hslab_size, buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
+ }
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+full_size;
+ /* Increment the buffer offset */
+ buf=(unsigned char *)buf+full_size;
- /* Decrement the sequence length left */
- seq_len-=full_size;
+ /* Decrement the sequence length left */
+ seq_len-=full_size;
- /* Increment coordinate of slowest changing dimension */
- coords[0]+=hslab_size[0];
+ /* Increment coordinate of slowest changing dimension */
+ coords[0]+=hslab_size[0];
- } /* end if */
-#ifdef QAK
-printf("%s: after reading 'middle' full hyperslabs, seq_len=%lu\n",FUNC,(unsigned long)seq_len);
-#endif /* QAK */
+ } /* end if */
- /*
- * Peel off final partial hyperslabs until we've finished reading all the data
- */
- if(seq_len>0) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
+ /*
+ * Peel off final partial hyperslabs until we've finished reading all the data
+ */
+ if(seq_len>0) {
+ hsize_t partial_size; /* Size of the partial hyperslab in bytes */
+
+ /*
+ * Peel off remaining partial hyperslabs, from the next-slowest dimension
+ * on down to the next-to-fastest changing dimension
+ */
+ for(i=1; i<(ndims-1); i++) {
+ /* Check if there are enough elements to read in a row in this dimension */
+ if(seq_len>=down_size[i]) {
+ /* Reset the partial hyperslab size */
+ partial_size=1;
+
+ /* Build the partial hyperslab information */
+ for(j=0; j<ndims; j++) {
+ if(j<i)
+ hslab_size[j]=1;
+ else
+ if(j==i)
+ hslab_size[j]=seq_len/down_size[j];
+ else
+ hslab_size[j]=dset_dims[j];
+
+ partial_size*=hslab_size[j];
+ } /* end for */
+ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
+
+ /* Read in the partial hyperslab */
+ if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords,
+ hslab_size, buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
+ }
+
+ /* Increment the buffer offset */
+ buf=(unsigned char *)buf+partial_size;
+
+ /* Decrement the length of the sequence to read */
+ seq_len-=partial_size;
+
+ /* Correct the coords array */
+ coords[i]=hslab_size[i];
+ } /* end if */
+ } /* end for */
- /*
- * Peel off remaining partial hyperslabs, from the next-slowest dimension
- * on down to the next-to-fastest changing dimension
- */
- for(i=1; i<(ndims-1); i++) {
- /* Check if there are enough elements to read in a row in this dimension */
- if(seq_len>=down_size[i]) {
-#ifdef QAK
-printf("%s: seq_len=%ld, down_size[%d]=%ld\n",FUNC,(long)seq_len,i+1,(long)down_size[i+1]);
-#endif /* QAK */
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j<i)
- hslab_size[j]=1;
- else
- if(j==i)
- hslab_size[j]=seq_len/down_size[j];
- else
- hslab_size[j]=dset_dims[j];
+ /* Handle fastest changing dimension if there are any elements left */
+ if(seq_len>0) {
+ assert(seq_len<dset_dims[ndims-1]);
- partial_size*=hslab_size[j];
-#ifdef QAK
-printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]);
-#endif /* QAK */
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-#ifdef QAK
-printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]);
-#endif /* QAK */
+ /* Reset the partial hyperslab size */
+ partial_size=1;
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords,
- hslab_size, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
- }
+ /* Build the partial hyperslab information */
+ for(j=0; j<ndims; j++) {
+ if(j==(ndims-1))
+ hslab_size[j]=seq_len;
+ else
+ hslab_size[j]=1;
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+partial_size;
+ partial_size*=hslab_size[j];
+ } /* end for */
+ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
+ /* Read in the partial hyperslab */
+ if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords,
+ hslab_size, buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
+ }
- /* Correct the coords array */
- coords[i]=hslab_size[i];
+ /* Double-check the amount read in */
+ assert(seq_len==partial_size);
+ } /* end if */
} /* end if */
- } /* end for */
-#ifdef QAK
-printf("%s: after reading trailing hyperslabs for all but the last dimension, seq_len=%ld\n",FUNC,(long)seq_len);
-#endif /* QAK */
-
- /* Handle fastest changing dimension if there are any elements left */
- if(seq_len>0) {
-#ifdef QAK
-printf("%s: i=%d, seq_len=%ld\n",FUNC,ndims-1,(long)seq_len);
-#endif /* QAK */
- assert(seq_len<dset_dims[ndims-1]);
-
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j==(ndims-1))
- hslab_size[j]=seq_len;
- else
- hslab_size[j]=1;
-
- partial_size*=hslab_size[j];
-#ifdef QAK
-printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]);
-#endif /* QAK */
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-#ifdef QAK
-printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]);
-#endif /* QAK */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, pline, fill, coords,
- hslab_size, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
- }
+ }
+ /* Increment offset in buffer */
+ real_buf += seq_len_arr[v];
+ } /* end for */
- /* Double-check the amount read in */
- assert(seq_len==partial_size);
- } /* end if */
- } /* end if */
- }
break;
default:
@@ -469,55 +476,64 @@ printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsign
} /* end switch() */
FUNC_LEAVE(SUCCEED);
-} /* H5F_seq_read() */
+} /* H5F_seq_readv() */
/*-------------------------------------------------------------------------
- * Function: H5F_seq_write
+ * Function: H5F_seq_writev
*
- * Purpose: Writes a sequence of bytes to a file dataset from a buffer in
- * in memory. The data is written to file F and the array's size and
- * storage information is in LAYOUT. External files are described
- * according to the external file list, EFL. The sequence offset is
- * FILE_OFFSET in the file (offsets are
- * in terms of bytes) and the size of the hyperslab is SEQ_LEN. The
- * total size of the file array is implied in the LAYOUT argument.
+ * Purpose: Writes a vector of byte sequences from a buffer in memory into
+ * a file dataset. The data is written to file F and the array's size
+ * and storage information is in LAYOUT. External files are described
+ * according to the external file list, EFL. The vector of byte sequences
+ * offsets is in the FILE_OFFSET array into the dataset (offsets are in
+ * terms of bytes) and the size of each sequence is in the SEQ_LEN array.
+ * The total size of the file array is implied in the LAYOUT argument.
+ * Bytes written from BUF are sequentially stored in the buffer, each sequence
+ * from the vector stored directly after the previous. The number of
+ * sequences is NSEQ.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Monday, October 9, 2000
+ * Friday, July 6, 2001
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
+H5F_seq_writev(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline, const H5O_fill_t *fill,
const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size,
- hsize_t seq_len, hsize_t file_offset, const void *buf)
+ size_t nseq, size_t seq_len_arr[], hsize_t file_offset_arr[],
+ const void *_buf)
{
+ const unsigned char *real_buf=(const unsigned char *)_buf; /* Local pointer to buffer to fill */
+ const unsigned char *buf; /* Local pointer to buffer to fill */
+ hsize_t file_offset; /* Offset in dataset */
+ hsize_t seq_len; /* Number of bytes to read */
hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */
hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */
hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/
hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative hyperslab sizes (in elements) */
- hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */
+ hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */
intn ndims;
- hsize_t max_data = 0; /*bytes in dataset */
+ hsize_t max_data; /*bytes in dataset */
haddr_t addr; /*address in file */
uintn u; /*counters */
+ size_t v; /*counters */
intn i,j; /*counters */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif
- FUNC_ENTER(H5F_seq_write, FAIL);
+ FUNC_ENTER(H5F_seq_writev, FAIL);
/* Check args */
assert(f);
assert(layout);
- assert(buf);
+ assert(real_buf);
#ifdef H5_HAVE_PARALLEL
{
@@ -547,30 +563,11 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
"filters are not allowed for contiguous data");
}
- /*
- * Initialize loop variables. The loop is a multi-dimensional loop
- * that counts from SIZE down to zero and IDX is the counter. Each
- * element of IDX is treated as a digit with IDX[0] being the least
- * significant digit.
- */
- if (efl && efl->nused>0) {
- addr = 0;
- } else {
- addr = layout->addr;
- /* Compute the size of the dataset in bytes */
- for(u=0, max_data=1; u<layout->ndims; u++)
- max_data *= layout->dim[u];
-
- /* Adjust the maximum size of the data by the offset into it */
- max_data -= file_offset;
- }
- addr += file_offset;
-
- /*
- * Now begin to walk through the array, copying data from disk to
- * memory.
- */
+ /* Write directly to file if the dataset is in an external file */
+ if (efl && efl->nused>0) {
+ /* Iterate through the sequence vectors */
+ for(v=0; v<nseq; v++) {
#ifdef H5_HAVE_PARALLEL
if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
/*
@@ -580,8 +577,8 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
*/
unsigned long max, min, temp;
- temp = seq_len;
- assert(temp==seq_len); /* verify no overflow */
+ temp = seq_len_arr[v];
+ assert(temp==seq_len_arr[v]); /* verify no overflow */
MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX,
H5FD_mpio_communicator(f->shared->lf));
MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN,
@@ -594,20 +591,26 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
"collective access with unequal number of blocks not supported yet");
}
#endif
+ /* Note: We can't use data sieve buffers for datasets in external files
+ * because the 'addr' of all external files is set to 0 (above) and
+ * all datasets in external files would alias to the same set of
+ * file offsets, totally mixing up the data sieve buffer information. -QAK
+ */
+ if (H5O_efl_write(f, efl, file_offset_arr[v], seq_len_arr[v], real_buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
+ "external data write failed");
+ }
- /* Write directly to file if the dataset is in an external file */
- if (efl && efl->nused>0) {
- /* Note: We can't use data sieve buffers for datasets in external files
- * because the 'addr' of all external files is set to 0 (above) and
- * all datasets in external files would alias to the same set of
- * file offsets, totally mixing up the data sieve buffer information. -QAK
- */
- if (H5O_efl_write(f, efl, addr, seq_len, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
- "external data write failed");
- }
+ /* Increment offset in buffer */
+ real_buf += seq_len_arr[v];
+ } /* end for */
} else {
- if (H5F_contig_write(f, max_data, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) {
+ /* Compute the size of the dataset in bytes */
+ for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++)
+ max_data *= layout->dim[u];
+
+ /* Pass along the vector of sequences to write */
+ if (H5F_contig_writev(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, file_offset_arr, dxpl_id, real_buf)<0) {
HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
"block write failed");
}
@@ -615,286 +618,217 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
break;
case H5D_CHUNKED:
- {
- /*
- * This method is unable to access external raw data files
- */
- if (efl && efl->nused>0) {
- HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL,
- "chunking and external files are mutually exclusive");
- }
- /* Compute the file offset coordinates and hyperslab size */
- if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0)
- HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
-
-#ifdef QAK
-/* Print out the file offsets & hyperslab sizes */
-{
- static int count=0;
-
- if(count<1000000) {
- printf("%s: elmt_size=%d, addr=%d, seq_len=%lu\n",FUNC,(int)elmt_size,(int)addr,(unsigned long)seq_len);
- printf("%s: file_offset=%d\n",FUNC,(int)file_offset);
- count++;
- }
-}
-#endif /* QAK */
-#ifdef QAK
- /* The library shouldn't be reading partial elements currently */
- assert((seq_len%elmt_size)!=0);
- assert((addr%elmt_size)!=0);
-#endif /* QAK */
-
- /* Set location in dataset from the file_offset */
- addr=file_offset;
-
- /* Convert the bytes into elements */
- seq_len/=elmt_size;
- addr/=elmt_size;
-
- /* Build the array of cumulative hyperslab sizes */
- for(acc=1, i=(ndims-1); i>=0; i--) {
- down_size[i]=acc;
- acc*=dset_dims[i];
-#ifdef QAK
-printf("%s: acc=%ld, down_size[%d]=%ld\n",FUNC,(long)acc,i,(long)down_size[i]);
-#endif /* QAK */
- } /* end for */
-
- /* Compute the hyperslab offset from the address given */
- for(i=ndims-1; i>=0; i--) {
- coords[i]=addr%dset_dims[i];
- addr/=dset_dims[i];
-#ifdef QAK
-printf("%s: addr=%lu, dset_dims[%d]=%ld, coords[%d]=%ld\n",FUNC,(unsigned long)addr,i,(long)dset_dims[i],i,(long)coords[i]);
-#endif /* QAK */
- } /* end for */
- coords[ndims]=0; /* No offset for element info */
-#ifdef QAK
-printf("%s: addr=%lu, coords[%d]=%ld\n",FUNC,(unsigned long)addr,ndims,(long)coords[ndims]);
-#endif /* QAK */
-
- /*
- * Peel off initial partial hyperslabs until we've got a hyperslab which starts
- * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate
- * zero for all dimensions except the slowest changing one
- */
- for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /* Check if we have a partial hyperslab in this lower dimension */
- if(coords[i]>0) {
-#ifdef QAK
-printf("%s: Need to get hyperslab, seq_len=%ld, coords[%d]=%ld\n",FUNC,(long)seq_len,i,(long)coords[i]);
-#endif /* QAK */
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(i==j)
- hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]);
- else
- if(j>i)
- hslab_size[j]=dset_dims[j];
- else
- hslab_size[j]=1;
- partial_size*=hslab_size[j];
-#ifdef QAK
-printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)hslab_size[j]);
-#endif /* QAK */
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-#ifdef QAK
-printf("%s: partial_size=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)hslab_size[ndims]);
-#endif /* QAK */
-
- /* Write out the partial hyperslab */
- if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords,
- hslab_size, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed");
+ /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */
+ for(v=0; v<nseq; v++) {
+ file_offset=file_offset_arr[v];
+ seq_len=seq_len_arr[v];
+ buf=real_buf;
+
+ {
+ /*
+ * This method is unable to access external raw data files
+ */
+ if (efl && efl->nused>0) {
+ HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL,
+ "chunking and external files are mutually exclusive");
}
+ /* Compute the file offset coordinates and hyperslab size */
+ if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0)
+ HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+partial_size;
+ /* Set location in dataset from the file_offset */
+ addr=file_offset;
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=0;
- coords[i-1]++;
- } /* end if */
- } /* end for */
-#ifdef QAK
-printf("%s: seq_len=%lu\n",FUNC,(unsigned long)seq_len);
-#endif /* QAK */
-
- /* Check if there is more than just a partial hyperslab to read */
- if(seq_len>=down_size[0]) {
- hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */
- hsize_t full_size; /* Size of the full hyperslab in bytes */
-
- /* Get the sequence length for computing the hyperslab sizes */
- tmp_seq_len=seq_len;
-
- /* Reset the size of the hyperslab read in */
- full_size=1;
-
- /* Compute the hyperslab size from the length given */
- for(i=ndims-1; i>=0; i--) {
- /* Check if the hyperslab is wider than the width of the dimension */
- if(tmp_seq_len>dset_dims[i]) {
- assert(0==coords[i]);
- hslab_size[i]=dset_dims[i];
- } /* end if */
- else
- hslab_size[i]=tmp_seq_len;
+ /* Convert the bytes into elements */
+ seq_len/=elmt_size;
+ addr/=elmt_size;
- /* compute the number of elements read in */
- full_size*=hslab_size[i];
-
- /* Fold the length into the length in the next highest dimension */
- tmp_seq_len/=dset_dims[i];
-#ifdef QAK
-printf("%s: tmp_seq_len=%lu, hslab_size[%d]=%ld\n",FUNC,(unsigned long)tmp_seq_len,i,(long)hslab_size[i]);
-#endif /* QAK */
-
- /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/
- assert(tmp_seq_len>=1 || i==0);
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
-#ifdef QAK
-/* Print out the file offsets & hyperslab sizes */
-{
- static int count=0;
-
- if(count<1000000) {
- printf("%s: elmt_size=%d, addr=%d, full_size=%ld, tmp_seq_len=%ld seq_len=%ld\n",FUNC,(int)elmt_size,(int)addr,(long)full_size,(long)tmp_seq_len,(long)seq_len);
- for(i=0; i<ndims; i++)
- printf("%s: dset_dims[%d]=%d\n",FUNC,i,(int)dset_dims[i]);
- for(i=0; i<=ndims; i++)
- printf("%s: coords[%d]=%d, hslab_size[%d]=%d\n",FUNC,i,(int)coords[i],(int)i,(int)hslab_size[i]);
- count++;
- }
-}
-#endif /* QAK */
+ /* Build the array of cumulative hyperslab sizes */
+ for(acc=1, i=(ndims-1); i>=0; i--) {
+ down_size[i]=acc;
+ acc*=dset_dims[i];
+ } /* end for */
- /* Write the full hyperslab in */
- if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords,
- hslab_size, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed");
- }
+ /* Compute the hyperslab offset from the address given */
+ for(i=ndims-1; i>=0; i--) {
+ coords[i]=addr%dset_dims[i];
+ addr/=dset_dims[i];
+ } /* end for */
+ coords[ndims]=0; /* No offset for element info */
+
+ /*
+ * Peel off initial partial hyperslabs until we've got a hyperslab which starts
+ * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate
+ * zero for all dimensions except the slowest changing one
+ */
+ for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) {
+ hsize_t partial_size; /* Size of the partial hyperslab in bytes */
+
+ /* Check if we have a partial hyperslab in this lower dimension */
+ if(coords[i]>0) {
+ /* Reset the partial hyperslab size */
+ partial_size=1;
+
+ /* Build the partial hyperslab information */
+ for(j=0; j<ndims; j++) {
+ if(i==j)
+ hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]);
+ else
+ if(j>i)
+ hslab_size[j]=dset_dims[j];
+ else
+ hslab_size[j]=1;
+ partial_size*=hslab_size[j];
+ } /* end for */
+ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
+
+ /* Write out the partial hyperslab */
+ if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords,
+ hslab_size, buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
+ }
+
+ /* Increment the buffer offset */
+ buf=(const unsigned char *)buf+partial_size;
+
+ /* Decrement the length of the sequence to read */
+ seq_len-=partial_size;
+
+ /* Correct the coords array */
+ coords[i]=0;
+ coords[i-1]++;
+ } /* end if */
+ } /* end for */
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+full_size;
+ /* Check if there is more than just a partial hyperslab to read */
+ if(seq_len>=down_size[0]) {
+ hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */
+ hsize_t full_size; /* Size of the full hyperslab in bytes */
- /* Decrement the sequence length left */
- seq_len-=full_size;
+ /* Get the sequence length for computing the hyperslab sizes */
+ tmp_seq_len=seq_len;
- /* Increment coordinate of slowest changing dimension */
- coords[0]+=hslab_size[0];
+ /* Reset the size of the hyperslab read in */
+ full_size=1;
- } /* end if */
-#ifdef QAK
-printf("%s: seq_len=%lu\n",FUNC,(unsigned long)seq_len);
-#endif /* QAK */
+ /* Compute the hyperslab size from the length given */
+ for(i=ndims-1; i>=0; i--) {
+ /* Check if the hyperslab is wider than the width of the dimension */
+ if(tmp_seq_len>dset_dims[i]) {
+ assert(0==coords[i]);
+ hslab_size[i]=dset_dims[i];
+ } /* end if */
+ else
+ hslab_size[i]=tmp_seq_len;
- /*
- * Peel off final partial hyperslabs until we've finished reading all the data
- */
- if(seq_len>0) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
+ /* compute the number of elements read in */
+ full_size*=hslab_size[i];
- /*
- * Peel off remaining partial hyperslabs, from the next-slowest dimension
- * on down to the next-to-fastest changing dimension
- */
- for(i=1; i<(ndims-1); i++) {
- /* Check if there are enough elements to read in a row in this dimension */
- if(seq_len>=down_size[i]) {
-#ifdef QAK
-printf("%s: seq_len=%ld, down_size[%d]=%ld\n",FUNC,(long)seq_len,i+1,(long)down_size[i+1]);
-#endif /* QAK */
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j<i)
- hslab_size[j]=1;
- else
- if(j==i)
- hslab_size[j]=seq_len/down_size[j];
- else
- hslab_size[j]=dset_dims[j];
+ /* Fold the length into the length in the next highest dimension */
+ tmp_seq_len/=dset_dims[i];
- partial_size*=hslab_size[j];
-#ifdef QAK
-printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]);
-#endif /* QAK */
+ /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/
+ assert(tmp_seq_len>=1 || i==0);
} /* end for */
hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-#ifdef QAK
-printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]);
-#endif /* QAK */
- /* Write out the partial hyperslab */
+ /* Write the full hyperslab in */
if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords,
hslab_size, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed");
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
}
/* Increment the buffer offset */
- buf=(const unsigned char *)buf+partial_size;
+ buf=(const unsigned char *)buf+full_size;
+
+ /* Decrement the sequence length left */
+ seq_len-=full_size;
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
+ /* Increment coordinate of slowest changing dimension */
+ coords[0]+=hslab_size[0];
- /* Correct the coords array */
- coords[i]=hslab_size[i];
} /* end if */
- } /* end for */
- /* Handle fastest changing dimension if there are any elements left */
- if(seq_len>0) {
-#ifdef QAK
-printf("%s: i=%d, seq_len=%ld\n",FUNC,ndims-1,(long)seq_len);
-#endif /* QAK */
- assert(seq_len<dset_dims[ndims-1]);
-
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j==(ndims-1))
- hslab_size[j]=seq_len;
- else
- hslab_size[j]=1;
-
- partial_size*=hslab_size[j];
-#ifdef QAK
-printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,j,(long)coords[j],j,(long)hslab_size[j]);
-#endif /* QAK */
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-#ifdef QAK
-printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsigned long)partial_size,ndims,(long)coords[ndims],ndims,(long)hslab_size[ndims]);
-#endif /* QAK */
-
- /* Write in the final partial hyperslab */
- if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords,
- hslab_size, buf)<0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked write failed");
- }
+ /*
+ * Peel off final partial hyperslabs until we've finished reading all the data
+ */
+ if(seq_len>0) {
+ hsize_t partial_size; /* Size of the partial hyperslab in bytes */
+
+ /*
+ * Peel off remaining partial hyperslabs, from the next-slowest dimension
+ * on down to the next-to-fastest changing dimension
+ */
+ for(i=1; i<(ndims-1); i++) {
+ /* Check if there are enough elements to read in a row in this dimension */
+ if(seq_len>=down_size[i]) {
+ /* Reset the partial hyperslab size */
+ partial_size=1;
+
+ /* Build the partial hyperslab information */
+ for(j=0; j<ndims; j++) {
+ if(j<i)
+ hslab_size[j]=1;
+ else
+ if(j==i)
+ hslab_size[j]=seq_len/down_size[j];
+ else
+ hslab_size[j]=dset_dims[j];
+
+ partial_size*=hslab_size[j];
+ } /* end for */
+ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
+
+ /* Write out the partial hyperslab */
+ if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords,
+ hslab_size, buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
+ }
+
+ /* Increment the buffer offset */
+ buf=(const unsigned char *)buf+partial_size;
+
+ /* Decrement the length of the sequence to read */
+ seq_len-=partial_size;
+
+ /* Correct the coords array */
+ coords[i]=hslab_size[i];
+ } /* end if */
+ } /* end for */
+
+ /* Handle fastest changing dimension if there are any elements left */
+ if(seq_len>0) {
+ assert(seq_len<dset_dims[ndims-1]);
+
+ /* Reset the partial hyperslab size */
+ partial_size=1;
+
+ /* Build the partial hyperslab information */
+ for(j=0; j<ndims; j++) {
+ if(j==(ndims-1))
+ hslab_size[j]=seq_len;
+ else
+ hslab_size[j]=1;
+
+ partial_size*=hslab_size[j];
+ } /* end for */
+ hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
+
+ /* Write out the final partial hyperslab */
+ if (H5F_istore_write(f, dxpl_id, layout, pline, fill, coords,
+ hslab_size, buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
+ }
+
+ /* Double-check the amount read in */
+ assert(seq_len==partial_size);
+ } /* end if */
+ } /* end if */
+ }
+ /* Increment offset in buffer */
+ real_buf += seq_len_arr[v];
+ } /* end for */
- /* Double-check the amount read in */
- assert(seq_len==partial_size);
- } /* end if */
- } /* end if */
- }
break;
default:
@@ -903,5 +837,5 @@ printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsign
} /* end switch() */
FUNC_LEAVE(SUCCEED);
-} /* H5F_seq_write() */
+} /* H5F_seq_writev() */