summaryrefslogtreecommitdiffstats
path: root/src/H5Dseq.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Dseq.c')
-rw-r--r--src/H5Dseq.c754
1 files changed, 149 insertions, 605 deletions
diff --git a/src/H5Dseq.c b/src/H5Dseq.c
index 113a8d5..5248b0a 100644
--- a/src/H5Dseq.c
+++ b/src/H5Dseq.c
@@ -70,22 +70,24 @@ static int interface_initialize_g = 0;
*/
herr_t
H5F_seq_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t seq_len, hsize_t dset_offset, void *buf/*out*/)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t mem_len=seq_len; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_read, FAIL);
/* Check args */
assert(f);
assert(layout);
- assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_readvv(f, dxpl_id, layout, dc_plist, store, 1, &dset_curr_seq, &seq_len, &dset_offset, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
done:
@@ -116,22 +118,24 @@ done:
*/
herr_t
H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t seq_len, hsize_t dset_offset, const void *buf)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t mem_len=seq_len; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_write, FAIL);
/* Check args */
assert(f);
assert(layout);
- assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_writevv(f, dxpl_id, layout, dc_plist, store, 1, &dset_curr_seq, &seq_len, &dset_offset, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
@@ -140,7 +144,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_seq_readv
+ * Function: H5F_seq_readvv
*
* 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
@@ -152,53 +156,61 @@ done:
* 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.
+ * Purpose: Reads a vector of byte sequences from a vector of byte
+ * sequences in a file dataset into a buffer in memory. The data is
+ * read from file F and the array's size and storage information is in
+ * LAYOUT. External files and chunks are described according to the
+ * storage information, STORE. The vector of byte sequences offsets for
+ * the file is in the DSET_OFFSET_ARR array into the dataset (offsets are
+ * in terms of bytes) and the size of each sequence is in the DSET_LEN_ARR
+ * array. The vector of byte sequences offsets for memory is in the
+ * MEM_OFFSET_ARR array into the dataset (offsets are in terms of bytes)
+ * and the size of each sequence is in the MEM_LEN_ARR array. The total
+ * size of the file array is implied in the LAYOUT argument. The maximum
+ * number of sequences in the file dataset and the memory buffer are
+ * DSET_MAX_NSEQ & MEM_MAX_NSEQ respectively. The current sequence being
+ * operated on in the file dataset and the memory buffer are DSET_CURR_SEQ
+ * & MEM_CURR_SEQ respectively. The current sequence being operated on
+ * will be updated as a result of the operation, as will the offsets and
+ * lengths of the file dataset and memory buffer sequences.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Wednesday, May 1, 2001
+ * Wednesday, May 7, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
- size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
- void *_buf/*out*/)
+ssize_t
+H5F_seq_readvv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
+ struct H5P_genplist_t *dc_plist, const H5D_storage_t *store,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_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 dset_offset; /* Offset in dataset */
- hsize_t seq_len; /* Number of bytes to read */
- hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */
- 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) */
- int ndims;
- hsize_t max_data; /*bytes in dataset */
- haddr_t addr=0; /*address in file */
- unsigned u; /*counters */
- size_t v; /*counters */
- int i,j; /*counters */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif /* H5_HAVE_PARALLEL */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5F_seq_readv, FAIL);
+ FUNC_ENTER_NOAPI(H5F_seq_readvv, FAIL);
/* Check args */
assert(f);
+ assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); /* Make certain we have the correct type of property list */
assert(layout);
- assert(efl);
- assert(real_buf);
- /* Make certain we have the correct type of property list */
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
+ assert(dc_plist);
+ assert(dset_curr_seq);
+ assert(*dset_curr_seq<dset_max_nseq);
+ assert(dset_len_arr);
+ assert(dset_offset_arr);
+ assert(mem_curr_seq);
+ assert(*mem_curr_seq<mem_max_nseq);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
+ assert(buf);
#ifdef H5_HAVE_PARALLEL
/* Get the transfer mode for MPIO transfers */
@@ -229,285 +241,52 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Read directly from file if the dataset is in an external file */
- if (efl->nused>0) {
- /* Iterate through the sequence vectors */
- for(v=0; v<nseq; v++) {
-#ifdef H5_HAVE_PARALLEL
- if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
- /*
- * Currently supports same number of collective access. Need to
- * be changed LATER to combine all reads into one collective MPIO
- * call.
- */
- unsigned long max, min, temp;
-
- 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,
- H5FD_mpio_communicator(f->shared->lf));
-#ifdef AKC
- printf("seq_len=%lu, min=%lu, max=%lu\n", temp, min, max);
-#endif
- if (max != min)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL,
- "collective access with unequal number of blocks not supported yet");
- }
-#endif /* H5_HAVE_PARALLEL */
- /* 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
- */
- H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_read(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
-
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
+ if (store && store->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((ret_value=H5O_efl_readvv(&(store->efl),
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
} else {
+ hsize_t max_data; /*bytes in dataset */
+ unsigned u; /*counters */
+
/* 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, dset_offset_arr, dxpl_id, real_buf)<0)
+ if((ret_value=H5F_contig_readvv(f, max_data, layout->addr,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
} /* end else */
break;
case H5D_CHUNKED:
- /*
- * This method is unable to access external raw data files
- */
- if (efl->nused>0)
- HGOTO_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)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
-
- /* Build the array of cumulative hyperslab sizes */
- /* (And set the memory offset to zero) */
- for(acc=1, i=(ndims-1); i>=0; i--) {
- mem_offset[i]=0;
- down_size[i]=acc;
- acc*=dset_dims[i];
- } /* end for */
- mem_offset[ndims]=0;
-
- /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */
- for(v=0; v<nseq; v++) {
- dset_offset=dset_offset_arr[v];
- seq_len=seq_len_arr[v];
- buf=real_buf;
-
- {
- /* Set location in dataset from the dset_offset */
- addr=dset_offset;
-
- /* Convert the bytes into elements */
- seq_len/=elmt_size;
- addr/=elmt_size;
-
- /* 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, dc_plist,
- hslab_size, mem_offset, coords, hslab_size,
- buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=0;
- coords[i-1]++;
-
- /* Carry the coord array correction up the array, if the dimension is finished */
- while(i>0 && coords[i-1]==(hssize_t)dset_dims[i-1]) {
- i--;
- coords[i]=0;
- if(i>0) {
- coords[i-1]++;
- assert(coords[i-1]<=(hssize_t)dset_dims[i-1]);
- } /* end if */
- } /* end while */
- } /* end if */
- } /* end for */
-
- /* 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;
-
- /* 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];
-
- /* 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, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(full_size*elmt_size);
-
- /* Decrement the sequence length left */
- seq_len-=full_size;
-
- /* Increment coordinate of slowest changing dimension */
- coords[0]+=hslab_size[0];
-
- } /* 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 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, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(partial_size*elmt_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 */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read 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 */
-
+ assert(store);
+ if((ret_value=H5F_istore_readvv(f, dxpl_id, layout, dc_plist, store->chunk_coords,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "istore read failed");
break;
case H5D_COMPACT:
-
/* Pass along the vector of sequences to read */
- if (H5F_compact_readv(f, layout, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
-
+ if((ret_value=H5F_compact_readvv(f, layout,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "compact read failed");
break;
+
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
@@ -515,69 +294,67 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* H5F_seq_readv() */
+} /* H5F_seq_readvv() */
/*-------------------------------------------------------------------------
- * Function: H5F_seq_writev
+ * Function: H5F_seq_writevv
*
* 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 DSET_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.
+ * a vector of byte sequences in a file dataset. The data is written to
+ * file F and the array's size and storage information is in LAYOUT.
+ * External files and chunks are described according to the storage
+ * information, STORE. The vector of byte sequences offsets for the file
+ * is in the DSET_OFFSET_ARR array into the dataset (offsets are in
+ * terms of bytes) and the size of each sequence is in the DSET_LEN_ARR
+ * array. The vector of byte sequences offsets for memory is in the
+ * MEM_OFFSET_ARR array into the dataset (offsets are in terms of bytes)
+ * and the size of each sequence is in the MEM_LEN_ARR array. The total
+ * size of the file array is implied in the LAYOUT argument. The maximum
+ * number of sequences in the file dataset and the memory buffer are
+ * DSET_MAX_NSEQ & MEM_MAX_NSEQ respectively. The current sequence being
+ * operated on in the file dataset and the memory buffer are DSET_CURR_SEQ
+ * & MEM_CURR_SEQ respectively. The current sequence being operated on
+ * will be updated as a result of the operation, as will the offsets and
+ * lengths of the file dataset and memory buffer sequences.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Friday, July 6, 2001
+ * Friday, May 2, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
- size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
- const void *_buf)
+ssize_t
+H5F_seq_writevv(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
+ struct H5P_genplist_t *dc_plist, const H5D_storage_t *store,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_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 dset_offset; /* Offset in dataset */
- hsize_t seq_len; /* Number of bytes to read */
- hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */
- 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) */
- int ndims;
- hsize_t max_data; /*bytes in dataset */
- haddr_t addr; /*address in file */
- unsigned u; /*counters */
- size_t v; /*counters */
- int i,j; /*counters */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif /* H5_HAVE_PARALLEL */
- herr_t ret_value = SUCCEED; /* Return value */
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_seq_writev, FAIL);
+ FUNC_ENTER_NOAPI(H5F_seq_writevv, FAIL);
/* Check args */
assert(f);
+ assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); /* Make certain we have the correct type of property list */
assert(layout);
- assert(efl);
- assert(real_buf);
- /* Make certain we have the correct type of property list */
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
+ assert(dc_plist);
+ assert(dset_curr_seq);
+ assert(*dset_curr_seq<dset_max_nseq);
+ assert(dset_len_arr);
+ assert(dset_offset_arr);
+ assert(mem_curr_seq);
+ assert(*mem_curr_seq<mem_max_nseq);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
+ assert(buf);
#ifdef H5_HAVE_PARALLEL
/* Get the transfer mode for MPIO transfers */
@@ -608,282 +385,50 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Write directly to file if the dataset is in an external file */
- if (efl->nused>0) {
- /* Iterate through the sequence vectors */
- for(v=0; v<nseq; v++) {
-#ifdef H5_HAVE_PARALLEL
- if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
- /*
- * Currently supports same number of collective access. Need to
- * be changed LATER to combine all reads into one collective MPIO
- * call.
- */
- unsigned long max, min, temp;
-
- 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,
- H5FD_mpio_communicator(f->shared->lf));
-#ifdef AKC
- printf("seq_len=%lu, min=%lu, max=%lu\n", temp, min, max);
-#endif
- if (max != min)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access with unequal number of blocks not supported yet");
- }
-#endif /* H5_HAVE_PARALLEL */
- /* 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
- */
- H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_write(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
-
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
+ if (store && store->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 ((ret_value=H5O_efl_writevv(&(store->efl),
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
} else {
+ hsize_t max_data; /* Bytes in dataset */
+ unsigned u; /* Local index variable */
+
/* 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, dset_offset_arr, dxpl_id, real_buf)<0)
+ if ((ret_value=H5F_contig_writevv(f, max_data, layout->addr,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
} /* end else */
break;
case H5D_CHUNKED:
- /*
- * This method is unable to access external raw data files
- */
- if (efl->nused>0)
- HGOTO_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)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
-
- /* Build the array of cumulative hyperslab sizes */
- /* (And set the memory offset to zero) */
- for(acc=1, i=(ndims-1); i>=0; i--) {
- mem_offset[i]=0;
- down_size[i]=acc;
- acc*=dset_dims[i];
- } /* end for */
- mem_offset[ndims]=0;
-
- /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */
- for(v=0; v<nseq; v++) {
- dset_offset=dset_offset_arr[v];
- seq_len=seq_len_arr[v];
- buf=real_buf;
-
- {
- /* Set location in dataset from the dset_offset */
- addr=dset_offset;
-
- /* Convert the bytes into elements */
- seq_len/=elmt_size;
- addr/=elmt_size;
-
- /* 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, dc_plist,
- hslab_size, mem_offset,coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=0;
- coords[i-1]++;
-
- /* Carry the coord array correction up the array, if the dimension is finished */
- while(i>0 && coords[i-1]==(hssize_t)dset_dims[i-1]) {
- i--;
- coords[i]=0;
- if(i>0) {
- coords[i-1]++;
- assert(coords[i-1]<=(hssize_t)dset_dims[i-1]);
- } /* end if */
- } /* end while */
- } /* end if */
- } /* end for */
-
- /* 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;
-
- /* 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];
-
- /* 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 */
-
- /* Write the full hyperslab in */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(full_size*elmt_size);
-
- /* Decrement the sequence length left */
- seq_len-=full_size;
-
- /* Increment coordinate of slowest changing dimension */
- coords[0]+=hslab_size[0];
-
- } /* 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 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, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(partial_size*elmt_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, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_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 */
-
+ assert(store);
+ if((ret_value=H5F_istore_writevv(f, dxpl_id, layout, dc_plist, store->chunk_coords,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "istore write failed");
break;
case H5D_COMPACT:
-
/* Pass along the vector of sequences to write */
- if (H5F_compact_writev(f, layout, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
+ if((ret_value=H5F_compact_writevv(f, layout,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "compact write failed");
break;
default:
@@ -893,5 +438,4 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* H5F_seq_writev() */
-
+} /* H5F_seq_writevv() */