From 6ff8aac3a760ea8b69b5fad866b1d06cc41c6b14 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 23 Sep 2010 10:03:42 -0500 Subject: [svn-r19472] Description: Create a new, more streamlined method of generating I/O sequences when there is only a single block defined by a hyperslab. This improves the performance of Ger Van Diepen's (LOFAR team) benchmark by about 20%. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, w/threadsafe, in production mode Linux/PPC 2.6 (heiwa) w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode Mac OS X/32 10.6.4 (amazon) in debug mode Mac OS X/32 10.6.4 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode Mac OS X/32 10.6.4 (amazon) w/parallel, in debug mode --- src/H5Shyper.c | 899 ++++++++++++++++++++++++++++++++++++++------------------ src/H5Sselect.c | 4 +- test/th5s.c | 4 +- test/tselect.c | 218 +++++++------- 4 files changed, 725 insertions(+), 400 deletions(-) diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 628512f..1f56737 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -7973,10 +7973,10 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, hsize_t *mem_size; /* Size of the source buffer */ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ const hssize_t *sel_off; /* Selection offset in dataspace */ - hsize_t offset[H5O_LAYOUT_NDIMS]; /* Coordinate offset in dataspace */ + hsize_t offset[H5O_LAYOUT_NDIMS]; /* Coordinate offset in dataspace */ hsize_t tmp_count[H5O_LAYOUT_NDIMS];/* Temporary block count */ hsize_t tmp_block[H5O_LAYOUT_NDIMS];/* Temporary block offset */ - hsize_t wrap[H5O_LAYOUT_NDIMS]; /* Bytes to wrap around at the end of a row */ + hsize_t wrap[H5O_LAYOUT_NDIMS]; /* Bytes to wrap around at the end of a row */ hsize_t skip[H5O_LAYOUT_NDIMS]; /* Bytes to skip between blocks */ const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ hsize_t fast_dim_start, /* Local copies of fastest changing dimension info */ @@ -7994,15 +7994,14 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, int temp_dim; /* Temporary rank holder */ hsize_t acc; /* Accumulator */ hsize_t loc; /* Coordinate offset */ - unsigned u; /* Local index variable */ - int i; /* Local index variable */ - size_t curr_seq=0; /* Current sequence being operated on */ + size_t curr_seq = 0; /* Current sequence being operated on */ size_t actual_elem; /* The actual number of elements to count */ size_t actual_bytes;/* The actual number of bytes to copy */ - size_t nelmts; /* Starting number of elements */ size_t io_left; /* The number of elements left in I/O operation */ size_t start_io_left; /* The initial number of elements left in I/O operation */ size_t elem_size; /* Size of each element iterating over */ + unsigned u; /* Local index variable */ + int i; /* Local index variable */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_get_seq_list_opt) @@ -8051,251 +8050,118 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, } /* end for */ /* Calculate the number of elements to sequence through */ - H5_CHECK_OVERFLOW(iter->elmt_left,hsize_t,size_t); - start_io_left=io_left=MIN((size_t)iter->elmt_left,maxelem); - - /* Check if we stopped in the middle of a sequence of elements */ - if((iter->u.hyp.off[fast_dim]-tdiminfo[fast_dim].start)%tdiminfo[fast_dim].stride!=0 || - ((iter->u.hyp.off[fast_dim]!=tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count==1)) { - size_t leftover; /* The number of elements left over from the last sequence */ - - /* Calculate the number of elements left in the sequence */ - if(tdiminfo[fast_dim].count==1) { - H5_ASSIGN_OVERFLOW(leftover, tdiminfo[fast_dim].block-(iter->u.hyp.off[fast_dim]-tdiminfo[fast_dim].start) ,hsize_t,size_t); - } /* end if */ - else { - H5_ASSIGN_OVERFLOW(leftover, tdiminfo[fast_dim].block-((iter->u.hyp.off[fast_dim]-tdiminfo[fast_dim].start)%tdiminfo[fast_dim].stride) ,hsize_t,size_t); - } /* end else */ - - /* Make certain that we don't write too many */ - actual_elem=MIN(leftover,io_left); - - /* Compute the initial buffer offset */ - for(u = 0, loc = 0; u < ndims; u++) - loc += ((hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u])) * slab[u]; - - /* Add a new sequence */ - off[curr_seq] = loc; - H5_ASSIGN_OVERFLOW(len[curr_seq], actual_elem * elem_size, hsize_t, size_t); - - /* Increment sequence count */ - curr_seq++; - - /* Decrement the number of elements left */ - io_left -= actual_elem; - - /* Advance the hyperslab iterator */ - H5S_hyper_iter_next(iter, actual_elem); + H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); + io_left = MIN((size_t)iter->elmt_left, maxelem); - /* Decrement the number of elements left in selection */ - iter->elmt_left -= actual_elem; - } /* end if */ + /* Sanity check that there aren't any "remainder" sequences in process */ + HDassert(!((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride != 0 || + ((iter->u.hyp.off[fast_dim] != tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count == 1))); - /* Now that we've cleared the "remainder" of the previous fastest dimension - * sequence, we must be at the beginning of a sequence, so use the fancy - * algorithm to compute the offsets and run through as many as possible, - * until the buffer fills up. + /* We've cleared the "remainder" of the previous fastest dimension + * sequence before calling this routine, so we must be at the beginning of + * a sequence. Use the fancy algorithm to compute the offsets and run + * through as many as possible, until the buffer fills up. */ - if(io_left > 0 && curr_seq < maxseq) { /* Just in case the "remainder" above filled the buffer */ - /* Keep the number of elements we started with */ - nelmts = io_left; - /* Compute the arrays to perform I/O on */ + /* Keep the number of elements we started with */ + start_io_left = io_left; - /* Copy the location of the point to get */ - /* (Add in the selection offset) */ - for(u = 0; u < ndims; u++) - offset[u] = (hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u]); + /* Compute the arrays to perform I/O on */ - /* Compute the current "counts" for this location */ - for(u = 0; u < ndims; u++) { - if(tdiminfo[u].count == 1) { - tmp_count[u] = 0; - tmp_block[u] = iter->u.hyp.off[u] - tdiminfo[u].start; - } /* end if */ - else { - tmp_count[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) / tdiminfo[u].stride; - tmp_block[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) % tdiminfo[u].stride; - } /* end else */ - } /* end for */ + /* Copy the location of the point to get */ + /* (Add in the selection offset) */ + for(u = 0; u < ndims; u++) + offset[u] = (hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u]); - /* Compute the initial buffer offset */ - for(u = 0, loc = 0; u < ndims; u++) - loc += offset[u] * slab[u]; - - /* Set the number of elements to write each time */ - H5_ASSIGN_OVERFLOW(actual_elem,tdiminfo[fast_dim].block,hsize_t,size_t); - - /* Set the number of actual bytes */ - actual_bytes=actual_elem*elem_size; - - /* Set local copies of information for the fastest changing dimension */ - fast_dim_start = tdiminfo[fast_dim].start; - fast_dim_stride = tdiminfo[fast_dim].stride; - fast_dim_block = tdiminfo[fast_dim].block; - H5_ASSIGN_OVERFLOW(fast_dim_buf_off, slab[fast_dim] * fast_dim_stride, hsize_t, size_t); - fast_dim_offset = (hsize_t)((hssize_t)fast_dim_start + sel_off[fast_dim]); + /* Compute the current "counts" for this location */ + for(u = 0; u < ndims; u++) { + if(tdiminfo[u].count == 1) { + tmp_count[u] = 0; + tmp_block[u] = iter->u.hyp.off[u] - tdiminfo[u].start; + } /* end if */ + else { + tmp_count[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) / tdiminfo[u].stride; + tmp_block[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) % tdiminfo[u].stride; + } /* end else */ + } /* end for */ - /* Compute the number of blocks which would fit into the buffer */ - H5_CHECK_OVERFLOW(io_left / fast_dim_block, hsize_t, size_t); - tot_blk_count = (size_t)(io_left / fast_dim_block); + /* Compute the initial buffer offset */ + for(u = 0, loc = 0; u < ndims; u++) + loc += offset[u] * slab[u]; - /* Don't go over the maximum number of sequences allowed */ - tot_blk_count = MIN(tot_blk_count, (maxseq - curr_seq)); + /* Set the number of elements to write each time */ + H5_ASSIGN_OVERFLOW(actual_elem, tdiminfo[fast_dim].block, hsize_t, size_t); - /* Compute the amount to wrap at the end of each row */ - for(u = 0; u < ndims; u++) - wrap[u] = (mem_size[u] - (tdiminfo[u].stride * tdiminfo[u].count)) * slab[u]; + /* Set the number of actual bytes */ + actual_bytes = actual_elem * elem_size; - /* Compute the amount to skip between blocks */ - for(u = 0; u < ndims; u++) - skip[u] = (tdiminfo[u].stride - tdiminfo[u].block) * slab[u]; + /* Set local copies of information for the fastest changing dimension */ + fast_dim_start = tdiminfo[fast_dim].start; + fast_dim_stride = tdiminfo[fast_dim].stride; + fast_dim_block = tdiminfo[fast_dim].block; + H5_ASSIGN_OVERFLOW(fast_dim_buf_off, slab[fast_dim] * fast_dim_stride, hsize_t, size_t); + fast_dim_offset = (hsize_t)((hssize_t)fast_dim_start + sel_off[fast_dim]); - /* Check if there is a partial row left (with full blocks) */ - if(tmp_count[fast_dim] > 0) { - /* Get number of blocks in fastest dimension */ - H5_ASSIGN_OVERFLOW(fast_dim_count, tdiminfo[fast_dim].count - tmp_count[fast_dim], hsize_t, size_t); + /* Compute the number of blocks which would fit into the buffer */ + H5_CHECK_OVERFLOW(io_left / fast_dim_block, hsize_t, size_t); + tot_blk_count = (size_t)(io_left / fast_dim_block); - /* Make certain this entire row will fit into buffer */ - fast_dim_count=MIN(fast_dim_count,tot_blk_count); + /* Don't go over the maximum number of sequences allowed */ + tot_blk_count = MIN(tot_blk_count, (maxseq - curr_seq)); - /* Number of blocks to sequence over */ - act_blk_count=fast_dim_count; + /* Compute the amount to wrap at the end of each row */ + for(u = 0; u < ndims; u++) + wrap[u] = (mem_size[u] - (tdiminfo[u].stride * tdiminfo[u].count)) * slab[u]; - /* Loop over all the blocks in the fastest changing dimension */ - while(fast_dim_count>0) { - /* Store the sequence information */ - off[curr_seq]=loc; - len[curr_seq]=actual_bytes; + /* Compute the amount to skip between blocks */ + for(u = 0; u < ndims; u++) + skip[u] = (tdiminfo[u].stride - tdiminfo[u].block) * slab[u]; - /* Increment sequence count */ - curr_seq++; + /* Check if there is a partial row left (with full blocks) */ + if(tmp_count[fast_dim] > 0) { + /* Get number of blocks in fastest dimension */ + H5_ASSIGN_OVERFLOW(fast_dim_count, tdiminfo[fast_dim].count - tmp_count[fast_dim], hsize_t, size_t); - /* Increment information to reflect block just processed */ - loc+=fast_dim_buf_off; + /* Make certain this entire row will fit into buffer */ + fast_dim_count = MIN(fast_dim_count, tot_blk_count); - /* Decrement number of blocks */ - fast_dim_count--; - } /* end while */ + /* Number of blocks to sequence over */ + act_blk_count = fast_dim_count; - /* Decrement number of elements left */ - io_left -= actual_elem*act_blk_count; + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count > 0) { + /* Store the sequence information */ + off[curr_seq] = loc; + len[curr_seq] = actual_bytes; - /* Decrement number of blocks left */ - tot_blk_count -= act_blk_count; + /* Increment sequence count */ + curr_seq++; /* Increment information to reflect block just processed */ - tmp_count[fast_dim]+=act_blk_count; - - /* Check if we finished the entire row of blocks */ - if(tmp_count[fast_dim]>=tdiminfo[fast_dim].count) { - /* Increment offset in destination buffer */ - loc += wrap[fast_dim]; - - /* Increment information to reflect block just processed */ - offset[fast_dim]=fast_dim_offset; /* reset the offset in the fastest dimension */ - tmp_count[fast_dim]=0; + loc += fast_dim_buf_off; - /* Increment the offset and count for the other dimensions */ - temp_dim = (int)fast_dim - 1; - while(temp_dim >= 0) { - /* Move to the next row in the curent dimension */ - offset[temp_dim]++; - tmp_block[temp_dim]++; - - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) - break; - else { - /* Move to the next block in the current dimension */ - offset[temp_dim] += (tdiminfo[temp_dim].stride - tdiminfo[temp_dim].block); - loc += skip[temp_dim]; - tmp_block[temp_dim] = 0; - tmp_count[temp_dim]++; - - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_count[temp_dim]0) { + /* Decrement number of blocks */ + fast_dim_count--; + } /* end while */ -#define DUFF_GUTS \ - /* Store the sequence information */ \ - off[curr_seq] = loc; \ - len[curr_seq] = actual_bytes; \ - \ - /* Increment sequence count */ \ - curr_seq++; \ - \ - /* Increment information to reflect block just processed */ \ - loc += fast_dim_buf_off; + /* Decrement number of elements left */ + io_left -= actual_elem * act_blk_count; -#ifdef NO_DUFFS_DEVICE - /* Loop over all the blocks in the fastest changing dimension */ - while(fast_dim_count>0) { - DUFF_GUTS + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; - /* Decrement number of blocks */ - fast_dim_count--; - } /* end while */ -#else /* NO_DUFFS_DEVICE */ - { - size_t duffs_index; /* Counting index for Duff's device */ - - duffs_index = (fast_dim_count + 7) / 8; - switch (fast_dim_count % 8) { - case 0: - do - { - DUFF_GUTS - case 7: - DUFF_GUTS - case 6: - DUFF_GUTS - case 5: - DUFF_GUTS - case 4: - DUFF_GUTS - case 3: - DUFF_GUTS - case 2: - DUFF_GUTS - case 1: - DUFF_GUTS - } while (--duffs_index > 0); - } /* end switch */ - } -#endif /* NO_DUFFS_DEVICE */ -#undef DUFF_GUTS + /* Increment information to reflect block just processed */ + tmp_count[fast_dim] += act_blk_count; + /* Check if we finished the entire row of blocks */ + if(tmp_count[fast_dim] >= tdiminfo[fast_dim].count) { /* Increment offset in destination buffer */ loc += wrap[fast_dim]; + /* Increment information to reflect block just processed */ + offset[fast_dim] = fast_dim_offset; /* reset the offset in the fastest dimension */ + tmp_count[fast_dim] = 0; + /* Increment the offset and count for the other dimensions */ temp_dim = (int)fast_dim - 1; while(temp_dim >= 0) { @@ -8314,7 +8180,7 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, tmp_count[temp_dim]++; /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_count[temp_dim] 0) { + +#define DUFF_GUTS \ +/* Store the sequence information */ \ +off[curr_seq] = loc; \ +len[curr_seq] = actual_bytes; \ + \ +/* Increment sequence count */ \ +curr_seq++; \ + \ +/* Increment information to reflect block just processed */ \ +loc += fast_dim_buf_off; + +#ifdef NO_DUFFS_DEVICE + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count > 0) { + DUFF_GUTS - /* Decrement the number of rows left */ - curr_rows--; + /* Decrement number of blocks */ + fast_dim_count--; } /* end while */ +#else /* NO_DUFFS_DEVICE */ + { + size_t duffs_index; /* Counting index for Duff's device */ + + duffs_index = (fast_dim_count + 7) / 8; + switch (fast_dim_count % 8) { + case 0: + do + { + DUFF_GUTS + case 7: + DUFF_GUTS + case 6: + DUFF_GUTS + case 5: + DUFF_GUTS + case 4: + DUFF_GUTS + case 3: + DUFF_GUTS + case 2: + DUFF_GUTS + case 1: + DUFF_GUTS + } while (--duffs_index > 0); + } /* end switch */ + } +#endif /* NO_DUFFS_DEVICE */ +#undef DUFF_GUTS - /* Adjust the number of blocks & elements left to transfer */ + /* Increment offset in destination buffer */ + loc += wrap[fast_dim]; - /* Decrement number of elements left */ - H5_CHECK_OVERFLOW(actual_elem * (total_rows * tdiminfo[fast_dim].count), hsize_t, size_t); - io_left -= (size_t)(actual_elem * (total_rows * tdiminfo[fast_dim].count)); + /* Increment the offset and count for the other dimensions */ + temp_dim = (int)fast_dim - 1; + while(temp_dim >= 0) { + /* Move to the next row in the curent dimension */ + offset[temp_dim]++; + tmp_block[temp_dim]++; - /* Decrement number of blocks left */ - H5_CHECK_OVERFLOW( (total_rows*tdiminfo[fast_dim].count) ,hsize_t,size_t); - tot_blk_count -= (size_t)(total_rows*tdiminfo[fast_dim].count); + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) + break; + else { + /* Move to the next block in the current dimension */ + offset[temp_dim] += (tdiminfo[temp_dim].stride - tdiminfo[temp_dim].block); + loc += skip[temp_dim]; + tmp_block[temp_dim] = 0; + tmp_count[temp_dim]++; - /* Read in partial row of blocks */ - if(io_left>0 && curr_seq0) { - /* Store the sequence information */ - off[curr_seq]=loc; - len[curr_seq]=actual_bytes; + /* Decrement dimension count */ + temp_dim--; + } /* end while */ - /* Increment sequence count */ - curr_seq++; + /* Decrement the number of rows left */ + curr_rows--; + } /* end while */ - /* Increment information to reflect block just processed */ - loc+=fast_dim_buf_off; + /* Adjust the number of blocks & elements left to transfer */ - /* Decrement number of blocks */ - fast_dim_count--; - } /* end while */ + /* Decrement number of elements left */ + H5_CHECK_OVERFLOW(actual_elem * (total_rows * tdiminfo[fast_dim].count), hsize_t, size_t); + io_left -= (size_t)(actual_elem * (total_rows * tdiminfo[fast_dim].count)); + + /* Decrement number of blocks left */ + H5_CHECK_OVERFLOW((total_rows * tdiminfo[fast_dim].count), hsize_t, size_t); + tot_blk_count -= (size_t)(total_rows * tdiminfo[fast_dim].count); + + /* Read in partial row of blocks */ + if(io_left > 0 && curr_seq < maxseq) { + /* Get remaining number of blocks left to output */ + fast_dim_count = tot_blk_count; + + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count > 0) { + /* Store the sequence information */ + off[curr_seq] = loc; + len[curr_seq] = actual_bytes; - /* Decrement number of elements left */ - io_left -= actual_elem*tot_blk_count; + /* Increment sequence count */ + curr_seq++; /* Increment information to reflect block just processed */ - offset[fast_dim]+=(fast_dim_stride*tot_blk_count); /* move the offset in the fastest dimension */ + loc += fast_dim_buf_off; - /* Handle any leftover, partial blocks in this row */ - if(io_left>0 && curr_seq 0 && curr_seq < maxseq) { + actual_elem = io_left; + actual_bytes = actual_elem * elem_size; - /* Increment buffer correctly */ - offset[fast_dim]+=actual_elem; - } /* end if */ + /* Store the sequence information */ + off[curr_seq] = loc; + len[curr_seq] = actual_bytes; + + /* Increment sequence count */ + curr_seq++; + + /* Decrement the number of elements left */ + io_left -= actual_elem; + + /* Increment buffer correctly */ + offset[fast_dim] += actual_elem; + } /* end if */ + + /* don't bother checking slower dimensions */ + HDassert(io_left == 0 || curr_seq == maxseq); + } /* end if */ + + /* Update the iterator */ + + /* Update the iterator with the location we stopped */ + /* (Subtract out the selection offset) */ + for(u = 0; u < ndims; u++) + iter->u.hyp.off[u] = (hsize_t)((hssize_t)offset[u] - sel_off[u]); + + /* Decrement the number of elements left in selection */ + iter->elmt_left -= (start_io_left - io_left); + + /* Increment the number of sequences generated */ + *nseq += curr_seq; + + /* Increment the number of elements used */ + *nelem += start_io_left - io_left; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S_hyper_get_seq_list_opt() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_get_seq_list_single + PURPOSE + Create a list of offsets & lengths for a selection + USAGE + herr_t H5S_hyper_get_seq_list_single(space, flags, iter, maxseq, maxelem, nseq, nelem, off, len) + H5S_t *space; IN: Dataspace containing selection to use. + unsigned flags; IN: Flags for extra information about operation + H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last + position of interest in selection. + size_t maxseq; IN: Maximum number of sequences to generate + size_t maxelem; IN: Maximum number of elements to include in the + generated sequences + size_t *nseq; OUT: Actual number of sequences generated + size_t *nelem; OUT: Actual number of elements in sequences generated + hsize_t *off; OUT: Array of offsets + size_t *len; OUT: Array of lengths + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + Use the selection in the dataspace to generate a list of byte offsets and + lengths for the region(s) selected. Start/Restart from the position in the + ITER parameter. The number of sequences generated is limited by the MAXSEQ + parameter and the number of sequences actually generated is stored in the + NSEQ parameter. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S_hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, + size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, + hsize_t *off, size_t *len) +{ + const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ + const hssize_t *sel_off; /* Selection offset in dataspace */ + hsize_t *mem_size; /* Size of the source buffer */ + hsize_t base_offset[H5O_LAYOUT_NDIMS]; /* Base coordinate offset in dataspace */ + hsize_t offset[H5O_LAYOUT_NDIMS]; /* Coordinate offset in dataspace */ + hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hsize_t skip[H5O_LAYOUT_NDIMS]; /* Bytes to skip between blocks */ + hsize_t fast_dim_block; /* Local copies of fastest changing dimension info */ + hsize_t acc; /* Accumulator */ + hsize_t loc; /* Coordinate offset */ + size_t tot_blk_count; /* Total number of blocks left to output */ + size_t blk_count; /* Total number of blocks left to output */ + size_t elem_size; /* Size of each element iterating over */ + size_t io_left; /* The number of elements left in I/O operation */ + size_t actual_elem; /* The actual number of elements to count */ + unsigned ndims; /* Number of dimensions of dataset */ + unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + int temp_dim; /* Temporary rank holder */ + unsigned u; /* Local index variable */ + int i; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_get_seq_list_single) + + /* Check args */ + HDassert(space); + HDassert(iter); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); + + /* Set a local copy of the diminfo pointer */ + tdiminfo = iter->u.hyp.diminfo; + + /* Check if this is a "flattened" regular hyperslab selection */ + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { + /* Set the aliases for a few important dimension ranks */ + ndims = iter->u.hyp.iter_rank; + fast_dim = ndims - 1; + + /* Set the local copy of the selection offset */ + sel_off = iter->u.hyp.sel_off; + + /* Set up the pointer to the size of the memory space */ + mem_size = iter->u.hyp.size; + } /* end if */ + else { + /* Set the aliases for a few important dimension ranks */ + ndims = space->extent.rank; + fast_dim = ndims - 1; - /* don't bother checking slower dimensions */ - assert(io_left==0 || curr_seq==maxseq); + /* Set the local copy of the selection offset */ + sel_off = space->select.offset; + + /* Set up the pointer to the size of the memory space */ + mem_size = space->extent.size; + } /* end else */ + + /* initialize row sizes for each dimension */ + elem_size = iter->elmt_size; + for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { + slab[i] = acc; + acc *= mem_size[i]; + } /* end for */ + + /* Compute the amount to skip between sequences */ + for(u = 0; u < ndims; u++) + skip[u] = (mem_size[u] - tdiminfo[u].block) * slab[u]; + + /* Copy the base location of the block */ + /* (Add in the selection offset) */ + for(u = 0; u < ndims; u++) + base_offset[u] = (hsize_t)((hssize_t)tdiminfo[u].start + sel_off[u]); + + /* Copy the location of the point to get */ + /* (Add in the selection offset) */ + for(u = 0; u < ndims; u++) + offset[u] = (hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u]); + + /* Compute the initial buffer offset */ + for(u = 0, loc = 0; u < ndims; u++) + loc += offset[u] * slab[u]; + + /* Set local copies of information for the fastest changing dimension */ + fast_dim_block = tdiminfo[fast_dim].block; + + /* Calculate the number of elements to sequence through */ + H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); + io_left = MIN((size_t)iter->elmt_left, maxelem); + + /* Compute the number of blocks which would fit into the buffer */ + H5_CHECK_OVERFLOW(io_left / fast_dim_block, hsize_t, size_t); + tot_blk_count = (size_t)(io_left / fast_dim_block); + + /* Don't go over the maximum number of sequences allowed */ + tot_blk_count = MIN(tot_blk_count, maxseq); + + /* Set the number of elements to write each time */ + H5_ASSIGN_OVERFLOW(actual_elem, fast_dim_block, hsize_t, size_t); + + /* Check for blocks to operate on */ + if(tot_blk_count > 0) { + hsize_t tmp_block[H5O_LAYOUT_NDIMS];/* Temporary block offset */ + size_t actual_bytes; /* The actual number of bytes to copy */ + + /* Set the number of actual bytes */ + actual_bytes = actual_elem * elem_size; + + /* Set the starting block location */ + for(u = 0; u < ndims; u++) + tmp_block[u] = iter->u.hyp.off[u] - tdiminfo[u].start; + + /* Check for 1-dim selection */ + if(0 == fast_dim) { + /* Sanity checks */ + HDassert(1 == tot_blk_count); + HDassert(io_left == actual_elem); + + /* Store the sequence information */ + *off++ = loc; + *len++ = actual_bytes; } /* end if */ + else { + /* Create sequences until an entire row can't be used */ + blk_count = tot_blk_count; + while(blk_count > 0) { + /* Store the sequence information */ + *off++ = loc; + *len++ = actual_bytes; - /* Update the iterator */ + /* Set temporary dimension for advancing offsets */ + temp_dim = (int)fast_dim - 1; + + /* Increment offset in destination buffer */ + loc += slab[temp_dim]; + + /* Increment the offset and count for the other dimensions */ + while(temp_dim >= 0) { + /* Move to the next row in the curent dimension */ + offset[temp_dim]++; + tmp_block[temp_dim]++; + + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) + break; + else { + offset[temp_dim] = base_offset[temp_dim]; + loc += skip[temp_dim]; + tmp_block[temp_dim] = 0; + } /* end else */ + + /* Decrement dimension count */ + temp_dim--; + } /* end while */ + + /* Decrement block count */ + blk_count--; + } /* end while */ + } /* end else */ + + /* Update the iterator, if there were any blocks used */ /* Update the iterator with the location we stopped */ /* (Subtract out the selection offset) */ @@ -8400,17 +8584,43 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, iter->u.hyp.off[u] = (hsize_t)((hssize_t)offset[u] - sel_off[u]); /* Decrement the number of elements left in selection */ - iter->elmt_left -= (nelmts - io_left); + iter->elmt_left -= tot_blk_count * actual_elem; + + /* Increment the number of sequences generated */ + *nseq += tot_blk_count; + + /* Increment the number of elements used */ + *nelem += tot_blk_count * actual_elem; } /* end if */ - /* Set the number of sequences generated */ - *nseq = curr_seq; + /* Check for partial block, with room for another sequence */ + if(io_left > (tot_blk_count * actual_elem) && tot_blk_count < maxseq) { + size_t elmt_remainder; /* Elements remaining */ - /* Set the number of bytes used */ - *nelem = start_io_left - io_left; + /* Compute elements left */ + elmt_remainder = io_left - (tot_blk_count * actual_elem); + HDassert(elmt_remainder < fast_dim_block); + HDassert(elmt_remainder > 0); + + /* Store the sequence information */ + *off++ = loc; + *len++ = elmt_remainder * elem_size; + + /* Update the iterator with the location we stopped */ + iter->u.hyp.off[fast_dim] += (hsize_t)elmt_remainder; + + /* Decrement the number of elements left in selection */ + iter->elmt_left -= elmt_remainder; + + /* Increment the number of sequences generated */ + (*nseq)++; + + /* Increment the number of elements used */ + *nelem += elmt_remainder; + } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S_hyper_get_seq_list_opt() */ +} /* end H5S_hyper_get_seq_list_single() */ /*-------------------------------------------------------------------------- @@ -8451,26 +8661,141 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned UNUSED flags, H5S_sel_iter_t { herr_t ret_value; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_get_seq_list); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_get_seq_list) /* Check args */ - assert(space); - assert(iter); - assert(maxseq>0); - assert(maxelem>0); - assert(nseq); - assert(nelem); - assert(off); - assert(len); + HDassert(space); + HDassert(iter); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); /* Check for the special case of just one H5Sselect_hyperslab call made */ - if(space->select.sel_info.hslab->diminfo_valid) - /* Use optimized call to generate sequence list */ - ret_value=H5S_hyper_get_seq_list_opt(space,iter,maxseq,maxelem,nseq,nelem,off,len); + if(space->select.sel_info.hslab->diminfo_valid) { + const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ + const hssize_t *sel_off; /* Selection offset in dataspace */ + hsize_t *mem_size; /* Size of the source buffer */ + unsigned ndims; /* Number of dimensions of dataset */ + unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + hbool_t single_block; /* Whether the selection is a single block */ + unsigned u; /* Local index variable */ + + /* Set a local copy of the diminfo pointer */ + tdiminfo = iter->u.hyp.diminfo; + + /* Check if this is a "flattened" regular hyperslab selection */ + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { + /* Set the aliases for a few important dimension ranks */ + ndims = iter->u.hyp.iter_rank; + fast_dim = ndims - 1; + + /* Set the local copy of the selection offset */ + sel_off = iter->u.hyp.sel_off; + + /* Set up the pointer to the size of the memory space */ + mem_size = iter->u.hyp.size; + } /* end if */ + else { + /* Set the aliases for a few important dimension ranks */ + ndims = space->extent.rank; + fast_dim = ndims - 1; + + /* Set the local copy of the selection offset */ + sel_off = space->select.offset; + + /* Set up the pointer to the size of the memory space */ + mem_size = space->extent.size; + } /* end else */ + + /* Check if we stopped in the middle of a sequence of elements */ + if((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride != 0 || + ((iter->u.hyp.off[fast_dim] != tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count == 1)) { + hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hsize_t loc; /* Coordinate offset */ + hsize_t acc; /* Accumulator */ + size_t leftover; /* The number of elements left over from the last sequence */ + size_t actual_elem; /* The actual number of elements to count */ + size_t elem_size; /* Size of each element iterating over */ + int i; /* Local index variable */ + + + /* Calculate the number of elements left in the sequence */ + if(tdiminfo[fast_dim].count == 1) { + H5_ASSIGN_OVERFLOW(leftover, tdiminfo[fast_dim].block - (iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start), hsize_t, size_t); + } /* end if */ + else { + H5_ASSIGN_OVERFLOW(leftover, tdiminfo[fast_dim].block - ((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride), hsize_t, size_t); + } /* end else */ + + /* Make certain that we don't write too many */ + actual_elem = MIN3(leftover, (size_t)iter->elmt_left, maxelem); + + /* initialize row sizes for each dimension */ + elem_size = iter->elmt_size; + for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { + slab[i] = acc; + acc *= mem_size[i]; + } /* end for */ + + /* Compute the initial buffer offset */ + for(u = 0, loc = 0; u < ndims; u++) + loc += ((hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u])) * slab[u]; + + /* Add a new sequence */ + off[0] = loc; + H5_ASSIGN_OVERFLOW(len[0], actual_elem * elem_size, hsize_t, size_t); + + /* Increment sequence array locations */ + off++; + len++; + + /* Advance the hyperslab iterator */ + H5S_hyper_iter_next(iter, actual_elem); + + /* Decrement the number of elements left in selection */ + iter->elmt_left -= actual_elem; + + /* Decrement element/sequence limits */ + maxelem -= actual_elem; + maxseq--; + + /* Set the number of sequences generated and elements used */ + *nseq = 1; + *nelem = actual_elem; + + /* Check for using up all the sequences/elements */ + if(0 == iter->elmt_left || 0 == maxelem || 0 == maxseq) + return(SUCCEED); + } /* end if */ + else { + /* Reset the number of sequences generated and elements used */ + *nseq = 0; + *nelem = 0; + } /* end else */ + + /* Check for a single block selected */ + single_block = TRUE; + for(u = 0; u < ndims; u++) + if(1 != tdiminfo[u].count) { + single_block = FALSE; + break; + } /* end if */ + + /* Check for single block selection */ + if(single_block) + /* Use single-block optimized call to generate sequence list */ + ret_value = H5S_hyper_get_seq_list_single(space, iter, maxseq, maxelem, nseq, nelem, off, len); + else + /* Use optimized call to generate sequence list */ + ret_value = H5S_hyper_get_seq_list_opt(space, iter, maxseq, maxelem, nseq, nelem, off, len); + } /* end if */ else /* Call the general sequence generator routine */ - ret_value=H5S_hyper_get_seq_list_gen(space,iter,maxseq,maxelem,nseq,nelem,off,len); + ret_value = H5S_hyper_get_seq_list_gen(space, iter, maxseq, maxelem, nseq, nelem, off, len); - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_hyper_get_seq_list() */ diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 17b7fab..2a0e63f 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -189,10 +189,10 @@ H5S_select_get_seq_list(const H5S_t *space, unsigned flags, FUNC_ENTER_NOAPI_NOFUNC(H5S_select_get_seq_list) - assert(space); + HDassert(space); /* Call the selection type's get_seq_list function */ - ret_value=(*space->select.type->get_seq_list)(space,flags,iter,maxseq,maxbytes,nseq,nbytes,off,len); + ret_value = (*space->select.type->get_seq_list)(space, flags, iter, maxseq, maxbytes, nseq, nbytes, off, len); FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_select_get_seq_list() */ diff --git a/test/th5s.c b/test/th5s.c index ddd61e3..52fbe76 100644 --- a/test/th5s.c +++ b/test/th5s.c @@ -1043,9 +1043,9 @@ test_h5s_chunk(void) dsetID = H5Dopen2(fileID, "coords", H5P_DEFAULT); CHECK(dsetID, FAIL, "H5Dopen2"); - status= H5Dread (dsetID, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, chunk_data_dbl); + status= H5Dread(dsetID, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, chunk_data_dbl); CHECK(status, FAIL, "H5Dread"); - status= H5Dread (dsetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, chunk_data_flt); + status= H5Dread(dsetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, chunk_data_flt); CHECK(status, FAIL, "H5Dread"); status = H5Dclose(dsetID); diff --git a/test/tselect.c b/test/tselect.c index 1fa98bf..1041ab3 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -12870,7 +12870,7 @@ static void test_select_bounds(void) { hid_t sid; /* Dataspace ID */ - const hsize_t dims[SPACE11_RANK] = { SPACE11_DIM1, SPACE11_DIM2 }; /* Dataspace dimensions */ + const hsize_t dims[SPACE11_RANK] = {SPACE11_DIM1, SPACE11_DIM2}; /* Dataspace dimensions */ hsize_t coord[SPACE11_NPOINTS][SPACE11_RANK]; /* Coordinates for point selection */ hsize_t start[SPACE11_RANK]; /* The start of the hyperslab */ hsize_t stride[SPACE11_RANK]; /* The stride between block starts for the hyperslab */ @@ -12889,178 +12889,178 @@ test_select_bounds(void) CHECK(sid, FAIL, "H5Screate_simple"); /* Get bounds for 'all' selection */ - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0],0,"H5Sget_select_bounds"); - VERIFY(low_bounds[1],0,"H5Sget_select_bounds"); - VERIFY(high_bounds[0],SPACE11_DIM1-1,"H5Sget_select_bounds"); - VERIFY(high_bounds[1],SPACE11_DIM2-1,"H5Sget_select_bounds"); + VERIFY(low_bounds[0], 0, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], SPACE11_DIM1 - 1, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], SPACE11_DIM2 - 1, "H5Sget_select_bounds"); /* Set offset for selection */ - offset[0]=1; offset[1]=1; - ret=H5Soffset_simple(sid, offset); + offset[0] = 1; offset[1] = 1; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Get bounds for 'all' selection with offset (which should be ignored) */ - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0],0,"H5Sget_select_bounds"); - VERIFY(low_bounds[1],0,"H5Sget_select_bounds"); - VERIFY(high_bounds[0],SPACE11_DIM1-1,"H5Sget_select_bounds"); - VERIFY(high_bounds[1],SPACE11_DIM2-1,"H5Sget_select_bounds"); + VERIFY(low_bounds[0], 0, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], SPACE11_DIM1 - 1, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], SPACE11_DIM2 - 1, "H5Sget_select_bounds"); /* Reset offset for selection */ - offset[0]=0; offset[1]=0; - ret=H5Soffset_simple(sid, offset); + offset[0] = 0; offset[1] = 0; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Set 'none' selection */ - ret=H5Sselect_none(sid); + ret = H5Sselect_none(sid); CHECK(ret, FAIL, "H5Sselect_none"); /* Get bounds for 'none' selection */ H5E_BEGIN_TRY { - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_select_bounds"); - + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_select_bo unds"); + /* Set point selection */ - coord[0][0]= 3; coord[0][1]= 3; - coord[1][0]= 3; coord[1][1]= 96; - coord[2][0]= 96; coord[2][1]= 3; - coord[3][0]= 96; coord[3][1]= 96; + coord[0][0] = 3; coord[0][1] = 3; + coord[1][0] = 3; coord[1][1] = 96; + coord[2][0] = 96; coord[2][1] = 3; + coord[3][0] = 96; coord[3][1] = 96; ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)SPACE11_NPOINTS, (const hsize_t *)coord); CHECK(ret, FAIL, "H5Sselect_elements"); /* Get bounds for point selection */ - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0],3,"H5Sget_select_bounds"); - VERIFY(low_bounds[1],3,"H5Sget_select_bounds"); - VERIFY(high_bounds[0],SPACE11_DIM1-4,"H5Sget_select_bounds"); - VERIFY(high_bounds[1],SPACE11_DIM2-4,"H5Sget_select_bounds"); + VERIFY(low_bounds[0], 3, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 3, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], SPACE11_DIM1 - 4, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], SPACE11_DIM2 - 4, "H5Sget_select_bounds"); /* Set bad offset for selection */ - offset[0]=5; offset[1]=-5; - ret=H5Soffset_simple(sid, offset); + offset[0] = 5; offset[1] = -5; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Get bounds for hyperslab selection with negative offset */ H5E_BEGIN_TRY { - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Sget_select_bounds"); /* Set valid offset for selection */ - offset[0]=2; offset[1]=-2; - ret=H5Soffset_simple(sid, offset); + offset[0] = 2; offset[1] = -2; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Get bounds for point selection with offset */ - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0],5,"H5Sget_select_bounds"); - VERIFY(low_bounds[1],1,"H5Sget_select_bounds"); - VERIFY(high_bounds[0],SPACE11_DIM1-2,"H5Sget_select_bounds"); - VERIFY(high_bounds[1],SPACE11_DIM2-6,"H5Sget_select_bounds"); + VERIFY(low_bounds[0], 5, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 1, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], SPACE11_DIM1 - 2, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], SPACE11_DIM2 - 6, "H5Sget_select_bounds"); /* Reset offset for selection */ - offset[0]=0; offset[1]=0; - ret=H5Soffset_simple(sid, offset); + offset[0] = 0; offset[1] = 0; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Set "regular" hyperslab selection */ - start[0]= 2; start[1]= 2; - stride[0]= 10; stride[1]= 10; - count[0]= 4; count[1]= 4; - block[0]= 5; block[1]= 5; - ret = H5Sselect_hyperslab(sid,H5S_SELECT_SET,start,stride,count,block); + start[0] = 2; start[1] = 2; + stride[0] = 10; stride[1] = 10; + count[0] = 4; count[1] = 4; + block[0] = 5; block[1] = 5; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); /* Get bounds for hyperslab selection */ - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0],2,"H5Sget_select_bounds"); - VERIFY(low_bounds[1],2,"H5Sget_select_bounds"); - VERIFY(high_bounds[0],36,"H5Sget_select_bounds"); - VERIFY(high_bounds[1],36,"H5Sget_select_bounds"); + VERIFY(low_bounds[0], 2, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 2, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], 36, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], 36, "H5Sget_select_bounds"); /* Set bad offset for selection */ - offset[0]=5; offset[1]=-5; - ret=H5Soffset_simple(sid, offset); + offset[0] = 5; offset[1] = -5; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Get bounds for hyperslab selection with negative offset */ H5E_BEGIN_TRY { - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Sget_select_bounds"); /* Set valid offset for selection */ - offset[0]=5; offset[1]=-2; - ret=H5Soffset_simple(sid, offset); + offset[0] = 5; offset[1] = -2; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Get bounds for hyperslab selection with offset */ - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0],7,"H5Sget_select_bounds"); - VERIFY(low_bounds[1],0,"H5Sget_select_bounds"); - VERIFY(high_bounds[0],41,"H5Sget_select_bounds"); - VERIFY(high_bounds[1],34,"H5Sget_select_bounds"); + VERIFY(low_bounds[0], 7, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], 41, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], 34, "H5Sget_select_bounds"); /* Reset offset for selection */ - offset[0]=0; offset[1]=0; - ret=H5Soffset_simple(sid, offset); + offset[0] = 0; offset[1] = 0; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Make "irregular" hyperslab selection */ - start[0]= 20; start[1]= 20; - stride[0]= 20; stride[1]= 20; - count[0]= 2; count[1]= 2; - block[0]= 10; block[1]= 10; - ret = H5Sselect_hyperslab(sid,H5S_SELECT_OR,start,stride,count,block); + start[0] = 20; start[1] = 20; + stride[0] = 20; stride[1] = 20; + count[0] = 2; count[1] = 2; + block[0] = 10; block[1] = 10; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); /* Get bounds for hyperslab selection */ - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0],2,"H5Sget_select_bounds"); - VERIFY(low_bounds[1],2,"H5Sget_select_bounds"); - VERIFY(high_bounds[0],49,"H5Sget_select_bounds"); - VERIFY(high_bounds[1],49,"H5Sget_select_bounds"); + VERIFY(low_bounds[0], 2, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 2, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], 49, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], 49, "H5Sget_select_bounds"); /* Set bad offset for selection */ - offset[0]=5; offset[1]=-5; - ret=H5Soffset_simple(sid, offset); + offset[0] = 5; offset[1] = -5; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Get bounds for hyperslab selection with negative offset */ H5E_BEGIN_TRY { - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); } H5E_END_TRY; VERIFY(ret, FAIL, "H5Sget_select_bounds"); /* Set valid offset for selection */ - offset[0]=5; offset[1]=-2; - ret=H5Soffset_simple(sid, offset); + offset[0] = 5; offset[1] = -2; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Get bounds for hyperslab selection with offset */ - ret = H5Sget_select_bounds(sid,low_bounds,high_bounds); + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0],7,"H5Sget_select_bounds"); - VERIFY(low_bounds[1],0,"H5Sget_select_bounds"); - VERIFY(high_bounds[0],54,"H5Sget_select_bounds"); - VERIFY(high_bounds[1],47,"H5Sget_select_bounds"); + VERIFY(low_bounds[0], 7, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], 54, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], 47, "H5Sget_select_bounds"); /* Reset offset for selection */ - offset[0]=0; offset[1]=0; - ret=H5Soffset_simple(sid, offset); + offset[0] = 0; offset[1] = 0; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Close the dataspace */ - ret=H5Sclose (sid); + ret = H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); } /* test_select_bounds() */ @@ -13078,18 +13078,18 @@ test_select(void) size_t rdcc_nelmts; /* Raw data number of elements */ size_t rdcc_nbytes; /* Raw data number of bytes */ double rdcc_w0; /* Raw data write percentage */ - hssize_t offset[SPACE7_RANK]={1,1}; /* Offset for testing selection offsets */ + hssize_t offset[SPACE7_RANK] = {1, 1}; /* Offset for testing selection offsets */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Selections\n")); /* Create a dataset transfer property list */ - plist_id=H5Pcreate(H5P_DATASET_XFER); + plist_id = H5Pcreate(H5P_DATASET_XFER); CHECK(plist_id, FAIL, "H5Pcreate"); /* test I/O with a very small buffer for reads */ - ret=H5Pset_buffer(plist_id,(size_t)59,NULL,NULL); + ret = H5Pset_buffer(plist_id, (size_t)59, NULL, NULL); CHECK(ret, FAIL, "H5Pset_buffer"); /* These next tests use the same file */ @@ -13106,18 +13106,18 @@ test_select(void) test_select_combo(); /* Test combined hyperslab & element selection code */ test_select_hyper_stride(H5P_DEFAULT); /* Test strided hyperslab selection code */ test_select_hyper_stride(plist_id); /* Test strided hyperslab selection code */ - test_select_hyper_contig(H5T_STD_U16LE,H5P_DEFAULT); /* Test contiguous hyperslab selection code */ - test_select_hyper_contig(H5T_STD_U16LE,plist_id); /* Test contiguous hyperslab selection code */ - test_select_hyper_contig(H5T_STD_U16BE,H5P_DEFAULT); /* Test contiguous hyperslab selection code */ - test_select_hyper_contig(H5T_STD_U16BE,plist_id); /* Test contiguous hyperslab selection code */ - test_select_hyper_contig2(H5T_STD_U16LE,H5P_DEFAULT); /* Test more contiguous hyperslab selection cases */ - test_select_hyper_contig2(H5T_STD_U16LE,plist_id); /* Test more contiguous hyperslab selection cases */ - test_select_hyper_contig2(H5T_STD_U16BE,H5P_DEFAULT); /* Test more contiguous hyperslab selection cases */ - test_select_hyper_contig2(H5T_STD_U16BE,plist_id); /* Test more contiguous hyperslab selection cases */ - test_select_hyper_contig3(H5T_STD_U16LE,H5P_DEFAULT); /* Test yet more contiguous hyperslab selection cases */ - test_select_hyper_contig3(H5T_STD_U16LE,plist_id); /* Test yet more contiguous hyperslab selection cases */ - test_select_hyper_contig3(H5T_STD_U16BE,H5P_DEFAULT); /* Test yet more contiguous hyperslab selection cases */ - test_select_hyper_contig3(H5T_STD_U16BE,plist_id); /* Test yet more contiguous hyperslab selection cases */ + test_select_hyper_contig(H5T_STD_U16LE, H5P_DEFAULT); /* Test contiguous hyperslab selection code */ + test_select_hyper_contig(H5T_STD_U16LE, plist_id); /* Test contiguous hyperslab selection code */ + test_select_hyper_contig(H5T_STD_U16BE, H5P_DEFAULT); /* Test contiguous hyperslab selection code */ + test_select_hyper_contig(H5T_STD_U16BE, plist_id); /* Test contiguous hyperslab selection code */ + test_select_hyper_contig2(H5T_STD_U16LE, H5P_DEFAULT); /* Test more contiguous hyperslab selection cases */ + test_select_hyper_contig2(H5T_STD_U16LE, plist_id); /* Test more contiguous hyperslab selection cases */ + test_select_hyper_contig2(H5T_STD_U16BE, H5P_DEFAULT); /* Test more contiguous hyperslab selection cases */ + test_select_hyper_contig2(H5T_STD_U16BE, plist_id); /* Test more contiguous hyperslab selection cases */ + test_select_hyper_contig3(H5T_STD_U16LE, H5P_DEFAULT); /* Test yet more contiguous hyperslab selection cases */ + test_select_hyper_contig3(H5T_STD_U16LE, plist_id); /* Test yet more contiguous hyperslab selection cases */ + test_select_hyper_contig3(H5T_STD_U16BE, H5P_DEFAULT); /* Test yet more contiguous hyperslab selection cases */ + test_select_hyper_contig3(H5T_STD_U16BE, plist_id); /* Test yet more contiguous hyperslab selection cases */ test_select_hyper_contig_dr(H5T_STD_U16LE, H5P_DEFAULT); test_select_hyper_contig_dr(H5T_STD_U16LE, plist_id); test_select_hyper_contig_dr(H5T_STD_U16BE, H5P_DEFAULT); @@ -13148,32 +13148,32 @@ test_select(void) test_select_hyper_union_random_5d(plist_id); /* Test hyperslab union code for random 5-D hyperslabs */ /* Create a dataset transfer property list */ - fapl=H5Pcreate(H5P_FILE_ACCESS); + fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); /* Get the default file access properties for caching */ - ret=H5Pget_cache(fapl,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0); + ret = H5Pget_cache(fapl, &mdc_nelmts, &rdcc_nelmts, &rdcc_nbytes, &rdcc_w0); CHECK(ret, FAIL, "H5Pget_cache"); /* Increase the size of the raw data cache */ - rdcc_nbytes=10*1024*1024; + rdcc_nbytes = 10 * 1024 * 1024; /* Set the file access properties for caching */ - ret=H5Pset_cache(fapl,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0); + ret = H5Pset_cache(fapl, mdc_nelmts, rdcc_nelmts, rdcc_nbytes, rdcc_w0); CHECK(ret, FAIL, "H5Pset_cache"); /* Test reading in a large hyperslab with a chunked dataset */ - test_select_hyper_chunk(fapl,H5P_DEFAULT); + test_select_hyper_chunk(fapl, H5P_DEFAULT); /* Test reading in a large hyperslab with a chunked dataset a small amount at a time */ - test_select_hyper_chunk(fapl,plist_id); + test_select_hyper_chunk(fapl, plist_id); /* Close file access property list */ - ret=H5Pclose(fapl); + ret = H5Pclose(fapl); CHECK(ret, FAIL, "H5Pclose"); /* Close dataset transfer property list */ - ret=H5Pclose(plist_id); + ret = H5Pclose(plist_id); CHECK(ret, FAIL, "H5Pclose"); /* More tests for checking validity of selections */ -- cgit v0.12