diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2001-02-21 21:25:27 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2001-02-21 21:25:27 (GMT) |
commit | 4f098115dc9cb99067dda610db2df5ae8a942212 (patch) | |
tree | 769cb4596955989c2ffb26d4779025c15c69ccbf /src/H5Fseq.c | |
parent | 53ed6e6794bb72c3521d0f2804844b46e266514b (diff) | |
download | hdf5-4f098115dc9cb99067dda610db2df5ae8a942212.zip hdf5-4f098115dc9cb99067dda610db2df5ae8a942212.tar.gz hdf5-4f098115dc9cb99067dda610db2df5ae8a942212.tar.bz2 |
[svn-r3479] Purpose:
Bug Fixes
Description:
Fixed a bug in H5Shyper.c where 'contiguous' hyperslabs (i.e. ones which
took up an entire dataset) were not being detected correctly and would
instead be read a part at a time instead of all at once.
Also fixed a bug in the handling of hyperslabs for chunked datasets where
hyperslabs from chunks which weren't aligned on exact dimension bounaries
were not reading/writing data correctly.
Solution:
H5Shyper.c was a single line change from a 'block' size to a 'count' size.
H5Fseq.c changes we much more significant and involved detecting when
non-chunk aligned sequences of data were being written and constructing
hyperslab blocks to pass down to the chunking I/O routine (which only
understand hyperslab I/O requests, not element sequence requests).
This was complicated by the need to align the hyperslabs requested on
dimension boundaries...
Platforms tested:
FreeBSD 4.2. (hawkwind)
Diffstat (limited to 'src/H5Fseq.c')
-rw-r--r-- | src/H5Fseq.c | 515 |
1 files changed, 464 insertions, 51 deletions
diff --git a/src/H5Fseq.c b/src/H5Fseq.c index 01d484d..c369074 100644 --- a/src/H5Fseq.c +++ b/src/H5Fseq.c @@ -62,11 +62,13 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hsize_t seq_len, hsize_t file_offset, void *buf/*out*/) { hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ - hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ + 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; - haddr_t addr; /*address in file */ - intn i; /*counters */ + haddr_t addr=0; /*address in file */ + intn i,j; /*counters */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; #endif @@ -167,6 +169,9 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, break; case H5D_CHUNKED: + { + uintn leading_partials; /* Flag set if there are leading partial hyperslabs to take care of */ + /* * This method is unable to access external raw data files */ @@ -189,7 +194,7 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, { static int count=0; - if(count<10) { + 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++; @@ -203,41 +208,131 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, 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 */ + leading_partials=0; for(i=ndims-1; i>=0; i--) { coords[i]=addr%dset_dims[i]; addr/=dset_dims[i]; + if(i>0 && coords[i]>0) + leading_partials=1; +#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]); +printf("%s: leading_partials=%u\n",FUNC,leading_partials); +#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(seq_len>dset_dims[i]) { - if (0!=coords[i]) - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to copy into a proper hyperslab"); - hslab_size[i]=dset_dims[i]; - } /* end if */ - else - hslab_size[i]=seq_len; + /* + * 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 */ - /* Fold the length into the length in the next highest dimension */ - seq_len/=dset_dims[i]; + /* 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,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 */ + + /* 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; - /* Make certain the hyperslab sizes don't go less than 1 */ - if(seq_len<1) - seq_len=1; + /* 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: 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; + + /* 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<10) { - printf("%s: elmt_size=%d, addr=%d, seq_len=%d\n",FUNC,(int)elmt_size,(int)addr,(int)seq_len); - for(i=0; i<=ndims; i++) + 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]); @@ -246,9 +341,122 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, } #endif /* QAK */ - 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; + + /* Decrement the sequence length left */ + seq_len-=full_size; + + /* 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 */ + + /* + * 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]) { +#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]; + + 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 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 */ +#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"); + } + + /* Double-check the amount read in */ + assert(seq_len==partial_size); + } /* end if */ + } /* end if */ } break; @@ -288,11 +496,13 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hsize_t seq_len, hsize_t file_offset, const void *buf) { hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ - hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */ + 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) */ intn ndims; haddr_t addr; /*address in file */ - intn i; /*counters */ + intn i,j; /*counters */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; #endif @@ -393,6 +603,9 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, break; case H5D_CHUNKED: + { + uintn leading_partials; /* Flag set if there are leading partial hyperslabs to take care of */ + /* * This method is unable to access external raw data files */ @@ -409,7 +622,7 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, { static int count=0; - if(count<10) { + 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++; @@ -429,41 +642,131 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, 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 */ + leading_partials=0; for(i=ndims-1; i>=0; i--) { coords[i]=addr%dset_dims[i]; addr/=dset_dims[i]; + if(i>0 && coords[i]>0) + leading_partials=1; +#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]); +printf("%s: leading_partials=%u\n",FUNC,leading_partials); +#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(seq_len>dset_dims[i]) { - if (0!=coords[i]) - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to copy into a proper hyperslab"); - hslab_size[i]=dset_dims[i]; - } /* end if */ - else - hslab_size[i]=seq_len; + /* + * 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 */ - /* Fold the length into the length in the next highest dimension */ - seq_len/=dset_dims[i]; + /* 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,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"); + } + + /* Increment the buffer offset */ + buf=(const unsigned char *)buf+partial_size; - /* Make certain the hyperslab sizes don't go less than 1 */ - if(seq_len<1) - seq_len=1; + /* 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: 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; + + /* 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<10) { - printf("%s: elmt_size=%d, addr=%d, seq_len=%d\n",FUNC,(int)elmt_size,(int)addr,(int)seq_len); - for(i=0; i<=ndims; i++) + 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]); @@ -472,9 +775,119 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, } #endif /* QAK */ - 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"); + /* 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"); + } + + /* Increment the buffer offset */ + buf=(const unsigned char *)buf+full_size; + + /* Decrement the sequence length left */ + seq_len-=full_size; + + /* Increment coordinate of slowest changing dimension */ + coords[0]+=hslab_size[0]; + + } /* end if */ +#ifdef QAK +printf("%s: seq_len=%lu\n",FUNC,(unsigned long)seq_len); +#endif /* QAK */ + + /* + * 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]) { +#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]; + + 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 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"); + } + + /* 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) { +#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"); + } + + /* Double-check the amount read in */ + assert(seq_len==partial_size); + } /* end if */ + } /* end if */ } break; |