diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Sall.c | 158 |
1 files changed, 155 insertions, 3 deletions
diff --git a/src/H5Sall.c b/src/H5Sall.c index 5d79baf..a676f73 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -389,9 +389,10 @@ H5S_all_mscat (const void *tconv_buf, size_t elmt_size, herr_t H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/, + const H5S_t *mem_space, hid_t dxpl_id, void *_buf/*out*/, hbool_t *must_convert/*out*/) { + char *buf=(char*)_buf; /* Get pointer to buffer */ H5S_hyper_node_t *file_node=NULL,*mem_node=NULL; /* Hyperslab node */ hsize_t mem_size,file_size; hssize_t file_off,mem_off; @@ -400,6 +401,11 @@ H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline, hssize_t file_offset[H5O_LAYOUT_NDIMS]; hssize_t mem_offset[H5O_LAYOUT_NDIMS]; unsigned u; + unsigned small_contiguous=0, /* Flags for indicating contiguous hyperslabs */ + large_contiguous=0; + int i; + size_t down_size[H5O_LAYOUT_NDIMS]; + size_t acc; FUNC_ENTER(H5S_all_read, FAIL); *must_convert = TRUE; @@ -502,8 +508,81 @@ printf("%s: check 1.0\n",FUNC); file_offset[u] = 0; mem_offset[u] = 0; + /* Disallow reading a memory hyperslab in the "middle" of a dataset which */ + /* spans multiple rows in "interior" dimensions, but allow reading a */ + /* hyperslab which is in the "middle" of the fastest or slowest changing */ + /* dimension because a hyperslab which "fills" the interior dimensions is */ + /* contiguous in memory. i.e. these are allowed: */ + /* --------------------- --------------------- */ + /* | | | | */ + /* |*******************| | ********* | */ + /* |*******************| | | */ + /* | | | | */ + /* | | | | */ + /* --------------------- --------------------- */ + /* ("large" contiguous block) ("small" contiguous block) */ + /* But this is not: */ + /* --------------------- */ + /* | | */ + /* | ********* | */ + /* | ********* | */ + /* | | */ + /* | | */ + /* --------------------- */ + /* (not contiguous in memory) */ + if(mem_space->select.type==H5S_SEL_HYPERSLABS) { + /* Check for a "small" contiguous block */ + if(size[0]==1) { + small_contiguous=1; + /* size of block in all dimensions except the fastest must be '1' */ + for (u=0; u<(mem_space->extent.u.simple.rank-1); u++) { + if(size[u]>1) { + small_contiguous=0; + break; + } /* end if */ + } /* end for */ + } /* end if */ + /* Check for a "large" contiguous block */ + else { + large_contiguous=1; + /* size of block in all dimensions except the slowest must be the */ + /* full size of the dimension */ + for (u=1; u<mem_space->extent.u.simple.rank; u++) { + if(size[u]!=mem_space->extent.u.simple.size[u]) { + large_contiguous=0; + break; + } /* end if */ + } /* end for */ + } /* end else */ + + /* Check for contiguous block */ + if(small_contiguous || large_contiguous) { + /* Compute the "down sizes" for each dimension */ + for (acc=elmt_size, i=(mem_space->extent.u.simple.rank-1); i>=0; i--) { + down_size[i]=acc; + acc*=mem_space->extent.u.simple.size[i]; + } /* end for */ + + /* Adjust the buffer offset and memory offsets by the proper amount */ + for (u=0; u<mem_space->extent.u.simple.rank; u++) { + buf+=mem_offset[u]*down_size[u]; + mem_offset[u]=0; + } /* end for */ + } /* end if */ + else { + /* Non-contiguous hyperslab block */ + goto fall_through; + } /* end else */ + } /* end if */ + #ifdef QAK printf("%s: check 2.0\n",FUNC); +for (u=0; u<mem_space->extent.u.simple.rank; u++) + printf("size[%u]=%lu\n",u,(unsigned long)size[u]); +for (u=0; u<=mem_space->extent.u.simple.rank; u++) + printf("mem_offset[%u]=%lu\n",u,(unsigned long)mem_offset[u]); +for (u=0; u<=mem_space->extent.u.simple.rank; u++) + printf("file_offset[%u]=%lu\n",u,(unsigned long)file_offset[u]); #endif /* QAK */ /* Read data from the file */ if (H5F_arr_read(f, dxpl_id, layout, pline, NULL, efl, size, @@ -546,9 +625,10 @@ herr_t H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - const H5S_t *mem_space, hid_t dxpl_id, const void *buf, + const H5S_t *mem_space, hid_t dxpl_id, const void *_buf, hbool_t *must_convert/*out*/) { + const char *buf=(const char*)_buf; /* Get pointer to buffer */ H5S_hyper_node_t *file_node=NULL,*mem_node=NULL; /* Hyperslab node */ hsize_t mem_size,file_size; hssize_t file_off,mem_off; @@ -556,7 +636,12 @@ H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, hsize_t size[H5O_LAYOUT_NDIMS]; hssize_t file_offset[H5O_LAYOUT_NDIMS]; hssize_t mem_offset[H5O_LAYOUT_NDIMS]; - unsigned u; + unsigned u; + unsigned small_contiguous=0, /* Flags for indicating contiguous hyperslabs */ + large_contiguous=0; + int i; + size_t down_size[H5O_LAYOUT_NDIMS]; + size_t acc; FUNC_ENTER(H5S_all_write, FAIL); *must_convert = TRUE; @@ -656,6 +741,73 @@ H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, file_offset[u] = 0; mem_offset[u] = 0; + /* Disallow reading a memory hyperslab in the "middle" of a dataset which */ + /* spans multiple rows in "interior" dimensions, but allow reading a */ + /* hyperslab which is in the "middle" of the fastest or slowest changing */ + /* dimension because a hyperslab which "fills" the interior dimensions is */ + /* contiguous in memory. i.e. these are allowed: */ + /* --------------------- --------------------- */ + /* | | | | */ + /* |*******************| | ********* | */ + /* |*******************| | | */ + /* | | | | */ + /* | | | | */ + /* --------------------- --------------------- */ + /* ("large" contiguous block) ("small" contiguous block) */ + /* But this is not: */ + /* --------------------- */ + /* | | */ + /* | ********* | */ + /* | ********* | */ + /* | | */ + /* | | */ + /* --------------------- */ + /* (not contiguous in memory) */ + if(mem_space->select.type==H5S_SEL_HYPERSLABS) { + /* Check for a "small" contiguous block */ + if(size[0]==1) { + small_contiguous=1; + /* size of block in all dimensions except the fastest must be '1' */ + for (u=0; u<(mem_space->extent.u.simple.rank-1); u++) { + if(size[u]>1) { + small_contiguous=0; + break; + } /* end if */ + } /* end for */ + } /* end if */ + /* Check for a "large" contiguous block */ + else { + large_contiguous=1; + /* size of block in all dimensions except the slowest must be the */ + /* full size of the dimension */ + for (u=1; u<mem_space->extent.u.simple.rank; u++) { + if(size[u]!=mem_space->extent.u.simple.size[u]) { + large_contiguous=0; + break; + } /* end if */ + } /* end for */ + } /* end else */ + + /* Check for contiguous block */ + if(small_contiguous || large_contiguous) { + /* Compute the "down sizes" for each dimension */ + for (acc=elmt_size, i=(mem_space->extent.u.simple.rank-1); i>=0; i--) { + down_size[i]=acc; + acc*=mem_space->extent.u.simple.size[i]; + } /* end for */ + + /* Adjust the buffer offset and memory offsets by the proper amount */ + for (u=0; u<mem_space->extent.u.simple.rank; u++) { + buf+=mem_offset[u]*down_size[u]; + mem_offset[u]=0; + } /* end for */ + } /* end if */ + else { + /* Non-contiguous hyperslab block */ + goto fall_through; + } /* end else */ + } /* end if */ + /* Write data to the file */ if (H5F_arr_write(f, dxpl_id, layout, pline, NULL, efl, size, size, mem_offset, file_offset, buf)<0) { |