diff options
Diffstat (limited to 'src/H5Dseq.c')
-rw-r--r-- | src/H5Dseq.c | 754 |
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() */ |