diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2001-07-10 21:19:18 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2001-07-10 21:19:18 (GMT) |
commit | 990fadfbe55353383639f0151990ec375fbe18cb (patch) | |
tree | a07f3b3215057bad7d46cbb9e26a4699b1fc8040 /src/H5Dseq.c | |
parent | 0c1c23245d103927c5d59c67b84526974e6217af (diff) | |
download | hdf5-990fadfbe55353383639f0151990ec375fbe18cb.zip hdf5-990fadfbe55353383639f0151990ec375fbe18cb.tar.gz hdf5-990fadfbe55353383639f0151990ec375fbe18cb.tar.bz2 |
[svn-r4181] Purpose:
Bug Fix, Code Cleanup, Code Optimization, etc.
Description:
Fold in the hyperslab speedups, clean up compile warnings and change a
few things from using 'unsigned' or 'hsize_t' to use 'size_t' instead.
Platforms tested:
FreeBSD 4.3 (hawkwind), Solaris 2.7 (arabica), Irix64 6.5 (modi4)
Diffstat (limited to 'src/H5Dseq.c')
-rw-r--r-- | src/H5Dseq.c | 1154 |
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() */ |