summaryrefslogtreecommitdiffstats
path: root/src/H5Shyper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Shyper.c')
-rw-r--r--src/H5Shyper.c353
1 files changed, 325 insertions, 28 deletions
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 2904b51..9733152 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -1906,18 +1906,20 @@ H5S_hyper_mread_opt (const void *_buf, size_t elmt_size,
size_t nelmts, void *_tconv_buf/*out*/)
{
hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Size of the source buffer */
- hsize_t hsize[H5O_LAYOUT_NDIMS]; /* Hyperslab size */
- hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset on disk */
+ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */
hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary block count */
hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block offset */
const uint8_t *src=(const uint8_t *)_buf; /* Alias for pointer arithmetic */
uint8_t *dst=(uint8_t *)_tconv_buf; /* Alias for pointer arithmetic */
intn fast_dim; /* Rank of the fastest changing dimension for the dataspace */
intn temp_dim; /* Temporary rank holder */
+ hsize_t acc; /* Accumulator */
+ size_t buf_off; /* Buffer offset for copying memory */
intn i; /* Counters */
intn ndims; /* Number of dimensions of dataset */
uintn actual_read; /* The actual number of elements to read in */
+ uintn actual_bytes; /* The actual number of bytes to copy */
size_t num_read=0; /* Number of elements read */
FUNC_ENTER (H5S_hyper_fread_opt, 0);
@@ -1936,22 +1938,24 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++)
printf("%s: mem_file->hyp.pos[%d]=%d\n",FUNC,(int)i,(int)mem_iter->hyp.pos[i]);
#endif /* QAK */
- /* Set the rank of the fastest changing dimension */
+ /* Set the aliases for dimension information */
fast_dim=mem_space->extent.u.simple.rank-1;
-
- /* Set up the hyperslab and 'zero' arrays */
ndims=mem_space->extent.u.simple.rank;
- /* initialize hyperslab size and offset in memory buffer */
- for(i=0; i<(ndims+1); i++) {
- hsize[i]=1; /* hyperslab size is 1, except for last element */
- zero[i]=0; /* memory offset is 0 */
- } /* end for */
- hsize[ndims] = elmt_size;
/* Set up the size of the memory space */
HDmemcpy(mem_size, mem_space->extent.u.simple.size,mem_space->extent.u.simple.rank*sizeof(hsize_t));
mem_size[mem_space->extent.u.simple.rank]=elmt_size;
+ /* initialize row sizes for each dimension */
+ for(i=(ndims-1),acc=1; i>=0; i--) {
+ slab[i]=acc*elmt_size;
+ acc*=mem_size[i];
+ } /* end for */
+#ifdef QAK
+for(i=0; i<ndims; i++)
+ printf("%s: mem_size[%d]=%d, slab[%d]=%d\n",FUNC,(int)i,(int)mem_size[i],(int)i,(int)slab[i]);
+#endif /* QAK */
+
/* Check if we stopped in the middle of a sequence of elements */
if((mem_iter->hyp.pos[fast_dim]-mem_space->select.sel_info.hslab.diminfo[fast_dim].start)%mem_space->select.sel_info.hslab.diminfo[fast_dim].stride!=0) {
uintn leftover; /* The number of elements left over from the last sequence */
@@ -1964,9 +1968,7 @@ printf("%s: Check 1.0\n",FUNC);
/* Make certain that we don't read too many */
actual_read=MIN(leftover,nelmts);
-
- /* Set the hyperslab size in the fastest changing dimension to read in */
- hsize[fast_dim]=actual_read;
+ actual_bytes=actual_read*elmt_size;
/* Copy the location of the point to get */
HDmemcpy(offset, mem_iter->hyp.pos,ndims*sizeof(hssize_t));
@@ -1976,12 +1978,11 @@ printf("%s: Check 1.0\n",FUNC);
for(i=0; i<ndims; i++)
offset[i] += mem_space->select.offset[i];
- /* Scatter out the rest of the sequence, if possible */
- if (H5V_hyper_copy (ndims+1, hsize,
- hsize, zero, dst,
- mem_size, offset, src)<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "unable to gather data from memory");
- }
+ /* Compute the initial buffer offset */
+ for(i=0,buf_off=0; i<ndims; i++)
+ buf_off+=offset[i]*slab[i];
+
+ HDmemcpy(dst,src+buf_off,actual_bytes);
/* Increment the offset of the buffer */
dst+=elmt_size*actual_read;
@@ -2031,9 +2032,19 @@ printf("%s: Check 2.0\n",FUNC);
tmp_block[i] = (mem_iter->hyp.pos[i]-mem_space->select.sel_info.hslab.diminfo[i].start)/mem_space->select.sel_info.hslab.diminfo[i].stride;
} /* end for */
+ /* Compute the initial buffer offset */
+ for(i=0,buf_off=0; i<ndims; i++)
+ buf_off+=offset[i]*slab[i];
+
/* Set the number of elements to read each time */
actual_read=mem_space->select.sel_info.hslab.diminfo[fast_dim].block;
- hsize[fast_dim]=actual_read;
+
+ /* Set the number of actual bytes */
+ actual_bytes=actual_read*elmt_size;
+#ifdef QAK
+printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_bytes);
+#endif /* QAK */
+
#ifdef QAK
printf("%s: actual_read=%d\n",FUNC,(int)actual_read);
for(i=0; i<file_space->extent.u.simple.rank; i++)
@@ -2049,7 +2060,7 @@ for(i=0; i<file_space->extent.u.simple.rank; i++)
/* Check if we are running out of room in the buffer */
if((actual_read+num_read)>nelmts) {
actual_read=nelmts-num_read;
- hsize[fast_dim]=actual_read;
+ actual_bytes=actual_read*elmt_size;
} /* end if */
#ifdef QAK
@@ -2058,12 +2069,8 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++)
printf("%s: tmp_count[%d]=%d, offset[%d]=%d\n",FUNC,(int)i,(int)tmp_count[i],(int)i,(int)offset[i]);
#endif /* QAK */
- /* Scatter out the rest of the sequence, if possible */
- if (H5V_hyper_copy (ndims+1, hsize,
- hsize, zero, dst,
- mem_size, offset, src)<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "unable to gather data from memory");
- }
+ /* Scatter out the rest of the sequence */
+ HDmemcpy(dst,src+buf_off,actual_bytes);
/* Increment the offset of the buffer */
dst+=elmt_size*actual_read;
@@ -2082,10 +2089,12 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++)
/* Check for partial block read! */
if(actual_read<mem_space->select.sel_info.hslab.diminfo[fast_dim].block) {
offset[temp_dim]+=actual_read;
+ buf_off+=actual_bytes;
break;
} /* end if */
else {
offset[temp_dim]+=mem_space->select.sel_info.hslab.diminfo[temp_dim].stride; /* reset the offset in the fastest dimension */
+ buf_off+=slab[temp_dim]*mem_space->select.sel_info.hslab.diminfo[temp_dim].stride;
tmp_count[temp_dim]++;
} /* end else */
@@ -2095,11 +2104,16 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++)
else {
tmp_count[temp_dim]=0; /* reset back to the beginning of the line */
offset[temp_dim]=mem_space->select.sel_info.hslab.diminfo[temp_dim].start+mem_space->select.offset[temp_dim];
+
+ /* Re-compute the initial buffer offset */
+ for(i=0,buf_off=0; i<ndims; i++)
+ buf_off+=offset[i]*slab[i];
} /* end else */
} /* end if */
else {
/* Move to the next row in the curent dimension */
offset[temp_dim]++;
+ buf_off+=slab[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 */
@@ -2108,6 +2122,7 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++)
else {
/* Move to the next block in the current dimension */
offset[temp_dim]+=(mem_space->select.sel_info.hslab.diminfo[temp_dim].stride-mem_space->select.sel_info.hslab.diminfo[temp_dim].block);
+ buf_off+=(mem_space->select.sel_info.hslab.diminfo[temp_dim].stride-mem_space->select.sel_info.hslab.diminfo[temp_dim].block)*slab[temp_dim];
tmp_block[temp_dim]=0;
tmp_count[temp_dim]++;
@@ -2118,6 +2133,10 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++)
tmp_count[temp_dim]=0; /* reset back to the beginning of the line */
tmp_block[temp_dim]=0;
offset[temp_dim]=mem_space->select.sel_info.hslab.diminfo[temp_dim].start+mem_space->select.offset[temp_dim];
+
+ /* Re-compute the initial buffer offset */
+ for(i=0,buf_off=0; i<ndims; i++)
+ buf_off+=offset[i]*slab[i];
}
} /* end else */
} /* end else */
@@ -2356,6 +2375,7 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info)
FUNC_LEAVE (num_read);
} /* H5S_hyper_mwrite() */
+#ifdef WORKS_QAK
/*-------------------------------------------------------------------------
* Function: H5S_hyper_mwrite_opt
@@ -2607,6 +2627,283 @@ for(i=0; i<mem_space->extent.u.simple.rank; i++)
FUNC_LEAVE (num_write);
} /* end H5S_hyper_mwrite_opt() */
+#else /* WORKS_QAK */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_mwrite_opt
+ *
+ * Purpose: Performs an optimized scatter to a memory buffer, based on a
+ * regular hyperslab (i.e. one which was generated from just one call to
+ * H5Sselect_hyperslab).
+ *
+ * Return: Success: Number of elements copied.
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 12, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_hyper_mwrite_opt (const void *_tconv_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_buf/*out*/)
+{
+ hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Size of the source buffer */
+ hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */
+ hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset on disk */
+ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary block count */
+ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block offset */
+ const uint8_t *src=(const uint8_t *)_tconv_buf; /* Alias for pointer arithmetic */
+ uint8_t *dst=(uint8_t *)_buf; /* Alias for pointer arithmetic */
+ intn fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ intn temp_dim; /* Temporary rank holder */
+ hsize_t acc; /* Accumulator */
+ size_t buf_off; /* Buffer offset for copying memory */
+ intn i; /* Counters */
+ intn ndims; /* Number of dimensions of dataset */
+ uintn actual_write; /* The actual number of elements to read in */
+ uintn actual_bytes; /* The actual number of bytes to copy */
+ size_t num_write=0; /* Number of elements read */
+
+ FUNC_ENTER (H5S_hyper_fwrite_opt, 0);
+
+#ifdef QAK
+printf("%s: Called!, elmt_size=%d\n",FUNC,(int)elmt_size);
+#endif /* QAK */
+ /* Check if this is the first element read in from the hyperslab */
+ if(mem_iter->hyp.pos[0]==(-1)) {
+ for(i=0; i<mem_space->extent.u.simple.rank; i++)
+ mem_iter->hyp.pos[i]=mem_space->select.sel_info.hslab.diminfo[i].start;
+ } /* end if */
+
+#ifdef QAK
+for(i=0; i<mem_space->extent.u.simple.rank; i++)
+ printf("%s: mem_file->hyp.pos[%d]=%d\n",FUNC,(int)i,(int)mem_iter->hyp.pos[i]);
+#endif /* QAK */
+
+ /* Set the aliases for a few important dimension ranks */
+ fast_dim=mem_space->extent.u.simple.rank-1;
+ ndims=mem_space->extent.u.simple.rank;
+
+ /* Set up the size of the memory space */
+ HDmemcpy(mem_size, mem_space->extent.u.simple.size,mem_space->extent.u.simple.rank*sizeof(hsize_t));
+ mem_size[mem_space->extent.u.simple.rank]=elmt_size;
+
+ /* initialize row sizes for each dimension */
+ for(i=(ndims-1),acc=1; i>=0; i--) {
+ slab[i]=acc*elmt_size;
+ acc*=mem_size[i];
+ } /* end for */
+#ifdef QAK
+for(i=0; i<ndims; i++)
+ printf("%s: mem_size[%d]=%d, slab[%d]=%d\n",FUNC,(int)i,(int)mem_size[i],(int)i,(int)slab[i]);
+#endif /* QAK */
+
+ /* Check if we stopped in the middle of a sequence of elements */
+ if((mem_iter->hyp.pos[fast_dim]-mem_space->select.sel_info.hslab.diminfo[fast_dim].start)%mem_space->select.sel_info.hslab.diminfo[fast_dim].stride!=0) {
+ uintn leftover; /* The number of elements left over from the last sequence */
+
+#ifdef QAK
+printf("%s: Check 1.0\n",FUNC);
+#endif /* QAK */
+ /* Calculate the number of elements left in the sequence */
+ leftover=mem_space->select.sel_info.hslab.diminfo[fast_dim].block-((mem_iter->hyp.pos[fast_dim]-mem_space->select.sel_info.hslab.diminfo[fast_dim].start)%mem_space->select.sel_info.hslab.diminfo[fast_dim].stride);
+
+ /* Make certain that we don't write too many */
+ actual_write=MIN(leftover,nelmts);
+ actual_bytes=actual_write*elmt_size;
+
+ /* Copy the location of the point to get */
+ HDmemcpy(offset, mem_iter->hyp.pos,ndims*sizeof(hssize_t));
+ offset[ndims] = 0;
+
+ /* Add in the selection offset */
+ for(i=0; i<ndims; i++)
+ offset[i] += mem_space->select.offset[i];
+
+ /* Compute the initial buffer offset */
+ for(i=0,buf_off=0; i<ndims; i++)
+ buf_off+=offset[i]*slab[i];
+
+ /* Scatter out the rest of the sequence */
+ HDmemcpy(dst+buf_off,src,actual_bytes);
+
+ /* Increment the offset of the buffer */
+ src+=elmt_size*actual_write;
+
+ /* Increment the count write */
+ num_write+=actual_write;
+
+ /* Decrement the number of elements left in selection */
+ mem_iter->hyp.elmt_left-=actual_write;
+
+ /* Advance the point iterator */
+ /* If we had enough buffer space to write out the rest of the sequence
+ * in the fastest changing dimension, move the iterator offset to
+ * the beginning of the next block to write. Otherwise, just advance
+ * the iterator in the fastest changing dimension.
+ */
+ if(actual_write==leftover) {
+ /* Move iterator offset to beginning of next sequence in the fastest changing dimension */
+ H5S_hyper_iter_next(mem_space,mem_iter);
+ } /* end if */
+ else {
+ mem_iter->hyp.pos[fast_dim]+=actual_write; /* whole sequence not written out, just advance fastest dimension offset */
+ } /* end if */
+ } /* end if */
+
+ /* 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.
+ */
+ if(num_write<nelmts) { /* Just in case the "remainder" above filled the buffer */
+#ifdef QAK
+printf("%s: Check 2.0\n",FUNC);
+#endif /* QAK */
+ /* Compute the arrays to perform I/O on */
+ /* Copy the location of the point to get */
+ HDmemcpy(offset, mem_iter->hyp.pos,ndims*sizeof(hssize_t));
+ offset[ndims] = 0;
+
+ /* Add in the selection offset */
+ for(i=0; i<ndims; i++)
+ offset[i] += mem_space->select.offset[i];
+
+ /* Compute the current "counts" for this location */
+ for(i=0; i<ndims; i++) {
+ tmp_count[i] = (mem_iter->hyp.pos[i]-mem_space->select.sel_info.hslab.diminfo[i].start)%mem_space->select.sel_info.hslab.diminfo[i].stride;
+ tmp_block[i] = (mem_iter->hyp.pos[i]-mem_space->select.sel_info.hslab.diminfo[i].start)/mem_space->select.sel_info.hslab.diminfo[i].stride;
+ } /* end for */
+
+ /* Compute the initial buffer offset */
+ for(i=0,buf_off=0; i<ndims; i++)
+ buf_off+=offset[i]*slab[i];
+
+ /* Set the number of elements to write each time */
+ actual_write=mem_space->select.sel_info.hslab.diminfo[fast_dim].block;
+
+ /* Set the number of actual bytes */
+ actual_bytes=actual_write*elmt_size;
+#ifdef QAK
+printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_bytes);
+#endif /* QAK */
+
+#ifdef QAK
+printf("%s: actual_write=%d\n",FUNC,(int)actual_write);
+for(i=0; i<file_space->extent.u.simple.rank; i++)
+ printf("%s: diminfo: start[%d]=%d, stride[%d]=%d, block[%d]=%d, count[%d]=%d\n",FUNC,
+ (int)i,(int)mem_space->select.sel_info.hslab.diminfo[i].start,
+ (int)i,(int)mem_space->select.sel_info.hslab.diminfo[i].stride,
+ (int)i,(int)mem_space->select.sel_info.hslab.diminfo[i].block,
+ (int)i,(int)mem_space->select.sel_info.hslab.diminfo[i].count);
+#endif /* QAK */
+
+ /* Read in data until an entire sequence can't be written out any longer */
+ while(num_write<nelmts) {
+ /* Check if we are running out of room in the buffer */
+ if((actual_write+num_write)>nelmts) {
+ actual_write=nelmts-num_write;
+ actual_bytes=actual_write*elmt_size;
+ } /* end if */
+
+#ifdef QAK
+printf("%s: num_write=%d\n",FUNC,(int)num_write);
+for(i=0; i<mem_space->extent.u.simple.rank; i++)
+ printf("%s: tmp_count[%d]=%d, offset[%d]=%d\n",FUNC,(int)i,(int)tmp_count[i],(int)i,(int)offset[i]);
+#endif /* QAK */
+
+ /* Scatter out the rest of the sequence */
+ HDmemcpy(dst+buf_off,src,actual_bytes);
+
+#ifdef QAK
+printf("%s: buf_off=%u, actual_bytes=%u\n",FUNC,(unsigned)buf_off,(int)actual_bytes);
+#endif /* QAK */
+
+ /* Increment the offset of the buffer */
+ src+=elmt_size*actual_write;
+
+ /* Increment the count write */
+ num_write+=actual_write;
+
+ /* Decrement the number of elements left in selection */
+ mem_iter->hyp.elmt_left-=actual_write;
+
+ /* Increment the offset and count */
+ temp_dim=fast_dim;
+ while(temp_dim>=0) {
+ if(temp_dim==fast_dim) {
+ /* Move to the next block in the current dimension */
+ /* Check for partial block write! */
+ if(actual_write<mem_space->select.sel_info.hslab.diminfo[fast_dim].block) {
+ offset[temp_dim]+=actual_write;
+ buf_off+=actual_bytes;
+ break;
+ } /* end if */
+ else {
+ offset[temp_dim]+=mem_space->select.sel_info.hslab.diminfo[temp_dim].stride; /* reset the offset in the fastest dimension */
+ buf_off+=slab[temp_dim]*mem_space->select.sel_info.hslab.diminfo[temp_dim].stride;
+ tmp_count[temp_dim]++;
+ } /* end else */
+
+ /* If this block is still in the range of blocks to output for the dimension, break out of loop */
+ if(tmp_count[temp_dim]<mem_space->select.sel_info.hslab.diminfo[temp_dim].count)
+ break;
+ else {
+ tmp_count[temp_dim]=0; /* reset back to the beginning of the line */
+ offset[temp_dim]=mem_space->select.sel_info.hslab.diminfo[temp_dim].start+mem_space->select.offset[temp_dim];
+
+ /* Re-compute the initial buffer offset */
+ for(i=0,buf_off=0; i<ndims; i++)
+ buf_off+=offset[i]*slab[i];
+ } /* end else */
+ } /* end if */
+ else {
+ /* Move to the next row in the curent dimension */
+ offset[temp_dim]++;
+ buf_off+=slab[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]<mem_space->select.sel_info.hslab.diminfo[temp_dim].block)
+ break;
+ else {
+ /* Move to the next block in the current dimension */
+ offset[temp_dim]+=(mem_space->select.sel_info.hslab.diminfo[temp_dim].stride-mem_space->select.sel_info.hslab.diminfo[temp_dim].block);
+ buf_off+=(mem_space->select.sel_info.hslab.diminfo[temp_dim].stride-mem_space->select.sel_info.hslab.diminfo[temp_dim].block)*slab[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]<mem_space->select.sel_info.hslab.diminfo[temp_dim].count)
+ break;
+ else {
+ tmp_count[temp_dim]=0; /* reset back to the beginning of the line */
+ tmp_block[temp_dim]=0;
+ offset[temp_dim]=mem_space->select.sel_info.hslab.diminfo[temp_dim].start+mem_space->select.offset[temp_dim];
+
+ /* Re-compute the initial buffer offset */
+ for(i=0,buf_off=0; i<ndims; i++)
+ buf_off+=offset[i]*slab[i];
+ }
+ } /* end else */
+ } /* end else */
+
+ /* Decrement dimension count */
+ temp_dim--;
+ } /* end while */
+ } /* end while */
+
+ /* Update the iterator with the location we stopped */
+ HDmemcpy(mem_iter->hyp.pos, offset, ndims*sizeof(hssize_t));
+ } /* end if */
+
+ FUNC_LEAVE (num_write);
+} /* end H5S_hyper_mwrite_opt() */
+#endif /* WORKS_QAK */
/*-------------------------------------------------------------------------