From c3caa3f2690eca4430022af129c0a1530b613fa6 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 20 Jul 1998 15:14:08 -0500 Subject: [svn-r519] Strided hyperslab selections now work. --- src/H5D.c | 15 ++--- src/H5Farray.c | 10 +++ src/H5Shyper.c | 192 ++++++++++++++++++++++++++++++++++++++++--------------- src/H5Sprivate.h | 1 + src/H5Sselect.c | 38 +++++++++-- 5 files changed, 192 insertions(+), 64 deletions(-) diff --git a/src/H5D.c b/src/H5D.c index ac91502..65cb0b8 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -1447,7 +1447,7 @@ printf("%s: check 6.0\n",FUNC); printf("%s: check 6.5\n",FUNC); { int i; - uint8 *b; + uint16 *b; if(qak_debug) { b=tconv_buf; @@ -1612,6 +1612,9 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * enough value in xfer_parms since turning off data type conversion also * turns off background preservation. */ +#ifdef QAK +printf("%s: check 0.5, nelmts=%d\n",FUNC,(int)nelmts); +#endif /* QAK */ if (nelmts!=H5S_select_npoints (file_space)) { HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes"); @@ -1766,19 +1769,13 @@ printf("%s: check 5.0, nelmts=%d, smine_start=%d, smine_nelmts=%d\n",FUNC,(int)n #ifdef QAK { int i; - int *b; + uint16 *b; if(qak_debug) { - b=buf; - b+=1430; - printf("buf:"); - for (i=0; indims=%d\n",FUNC,(int)layout->ndims); for(i=0; indims; i++) printf("%s: %d: hslab_size=%d, mem_size=%d, mem_offset=%d, file_offset=%d\n",FUNC,i,(int)_hslab_size[i],(int)mem_size[i],(int)mem_offset[i],(int)file_offset[i]); + if(qak_debug) { + printf("%s: *buf=%d, *(buf+1)=%d\n", FUNC,(int)*(const uint16 *)buf,(int)*((const uint16 *)buf+1)); + } } #endif /* QAK */ @@ -369,9 +374,14 @@ H5F_arr_write (H5F_t *f, const struct H5O_layout_t *layout, #endif #ifdef QAK { + extern int qak_debug; + printf("%s: layout->ndims=%d\n",FUNC,(int)layout->ndims); for(i=0; indims; i++) printf("%s: %d: hslab_size=%d, mem_size=%d, mem_offset=%d, file_offset=%d\n",FUNC,i,(int)_hslab_size[i],(int)mem_size[i],(int)mem_offset[i],(int)file_offset[i]); + if(qak_debug) { + printf("%s: *buf=%d, *(buf+1)=%d\n", FUNC,(int)*(const uint16 *)buf,(int)*((const uint16 *)buf+1)); + } } #endif /* QAK */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index cf8b66d..9ff2cce 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -111,6 +111,34 @@ printf("%s: max=%d\n",FUNC,(int)max); } /* H5S_hyper_favail() */ /*------------------------------------------------------------------------- + * Function: H5S_hyper_compare_regions + * + * Purpose: Compares two regions for equality (regions must not overlap!) + * + * Return: an integer less than, equal to, or greater than zero if the first + * region is considered to be respectively less than, equal to, or + * greater than the second + * + * Programmer: Quincey Koziol + * Friday, July 17, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5S_hyper_compare_regions (const void *r1, const void *r2) +{ + if(((const H5S_hyper_region_t *)r1)->start<((const H5S_hyper_region_t *)r2)->start) + return(-1); + else + if(((const H5S_hyper_region_t *)r1)->start>((const H5S_hyper_region_t *)r2)->start) + return(1); + else + return(0); +} /* end H5S_hyper_compare_regions */ + +/*------------------------------------------------------------------------- * Function: H5S_hyper_get_regions * * Purpose: Builds a sorted array of the overlaps in a dimension @@ -132,8 +160,10 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, H5S_hyper_bound_t **lo_bounds, H5S_hyper_bound_t **hi_bounds, hssize_t *pos) { H5S_hyper_region_t *ret_value=NULL; /* Pointer to array to return */ + H5S_hyper_node_t *node; /* Region node for a given boundary */ size_t num_reg=0, /* Number of regions in array */ - curr_reg=0; /* The current region we are working with */ + curr_reg=0, /* The current region we are working with */ + uniq_reg; /* The number of unique regions */ intn next_dim, /* Next fastest dimension */ temp_dim; /* Temporary dim. holder */ size_t i; /* Counters */ @@ -175,16 +205,21 @@ printf("%s: check 1.1, bound_count=%d\n",FUNC,bound_count); if(lo_bounds[0][i].boundhi_bounds[dim][i].bound && i=lo_bounds[dim][i].bound && i=0; j--) - printf("%s: lo_bound[%d][%d]=%d, hi_bound[%d][%d]=%d\n", - FUNC,j,i,(int)lo_bounds[j][i].bound,j,i,(int)hi_bounds[j][i].bound); + printf("%s: lo_bound[%d]=%d, hi_bound[%d]=%d\n", + FUNC,j,(int)node->start[j],j,(int)node->end[j]); } #endif /* QAK */ /* Check if each boundary overlaps in the higher dimensions */ + node=lo_bounds[dim][i].node; temp_dim=dim; - while(temp_dim>=0 && pos[temp_dim]>=lo_bounds[temp_dim][i].bound && - pos[temp_dim]<=hi_bounds[temp_dim][i].bound) + while(temp_dim>=0 && pos[temp_dim]>=node->start[temp_dim] && + pos[temp_dim]<=node->end[temp_dim]) temp_dim--; /* Yes, all previous positions match, this is a valid region */ @@ -219,43 +260,54 @@ printf("%s: check 3.0\n",FUNC); /* Check if we've allocated the array yet */ if(num_reg==0) { #ifdef QAK -printf("%s: check 3.1\n",FUNC); +printf("%s: check 3.1\n", FUNC); #endif /* QAK */ /* Allocate array */ ret_value=H5MM_malloc(sizeof(H5S_hyper_region_t)); /* Initialize with first region */ - ret_value[0].start=MAX(lo_bounds[next_dim][i].bound,pos[next_dim]); - ret_value[0].end=hi_bounds[next_dim][i].bound; + ret_value[0].start=MAX(node->start[next_dim],pos[next_dim]); + ret_value[0].end=node->end[next_dim]; +#ifdef QAK +printf("%s: check 3.2, lo_bounds=%d, start=%d, hi_bounds=%d, end=%d\n",FUNC, + (int)node->start[next_dim],(int)ret_value[curr_reg].start,(int)node->end[next_dim],(int)ret_value[curr_reg].end); +#endif /* QAK */ /* Increment the number of regions */ num_reg++; } else { - /* Check if we should merge this region into the current region */ - if(lo_bounds[next_dim][i].boundstart[next_dim],(int)ret_value[curr_reg].start,(int)node->end[next_dim],(int)ret_value[curr_reg].end); #endif /* QAK */ - ret_value[curr_reg].end=MAX(hi_bounds[next_dim][i].bound,ret_value[curr_reg].end); - } - else { /* no overlap with previous region, add new region */ -#ifdef QAK -printf("%s: check 4.2\n",FUNC); -#endif /* QAK */ - /* Enlarge array */ - ret_value=H5MM_realloc(ret_value,sizeof(H5S_hyper_region_t)*(num_reg+1)); + /* Enlarge array */ + ret_value=H5MM_realloc(ret_value,sizeof(H5S_hyper_region_t)*(num_reg+1)); - /* Initialize with new region */ - ret_value[num_reg].start=lo_bounds[next_dim][i].bound; - ret_value[num_reg].end=hi_bounds[next_dim][i].bound; + /* Initialize with new region */ + ret_value[num_reg].start=node->start[next_dim]; + ret_value[num_reg].end=node->end[next_dim]; - /* Increment the number of regions & the current region */ - num_reg++; - curr_reg++; - } /* end else */ + /* Increment the number of regions & the current region */ + num_reg++; + curr_reg++; } /* end else */ } /* end if */ } /* end for */ + + /* Sort region list and eliminate duplicates if necessary */ + if(num_reg>1) { + qsort(ret_value,num_reg,sizeof(H5S_hyper_region_t),H5S_hyper_compare_regions); + for(i=1,curr_reg=0,uniq_reg=1; ispace->extent.u.simple.rank); +printf("%s: check 2.0, rank=%d, num_regions=%d\n",FUNC,(int)fhyper_info->space->extent.u.simple.rank,(int)num_regions); for(i=0; inelmts>0; i++) { -#ifdef QAK -printf("%s: check 2.1, i=%d\n",FUNC,(int)i); -#endif /* QAK */ region_size=MIN(fhyper_info->nelmts,(regions[i].end-regions[i].start)+1); hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size; mem_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start; +#ifdef QAK +printf("%s: check 2.1, i=%d, region_size=%d\n",FUNC,(int)i,(int)region_size); +#endif /* QAK */ /* * Gather from memory. @@ -937,7 +991,7 @@ printf("%s: check 3.0\n",FUNC); hi_bounds[i]=mem_space->select.sel_info.hyper_lst->hi_bounds[i]; #ifdef QAK printf("%s: check 3.1, lo[%d]=%p, hi[%d]=%p\n",FUNC,i,lo_bounds[i],i,hi_bounds[i]); - for(j=0; jselect.sel_info.hyper_lst->count; j++) + for(j=0; j<(int)mem_space->select.sel_info.hyper_lst->count; j++) printf("%s: check 3.2, lo[%d][%d]=%d, hi[%d][%d]=%d\n",FUNC,i,j,(int)lo_bounds[i][j].bound,i,j,(int)hi_bounds[i][j].bound); #endif /* QAK */ } /* end for */ @@ -959,7 +1013,7 @@ printf("%s: check 4.0\n",FUNC); #endif /* QAK */ num_read=H5S_hyper_mread(-1,&fhyper_info); #ifdef QAK -printf("%s: check 5.0\n",FUNC); +printf("%s: check 5.0, num_read=%d\n",FUNC,(int)num_read); #endif /* QAK */ /* Release the memory we allocated */ @@ -1351,17 +1405,38 @@ printf("%s: check 3.2, i=%d\n",FUNC,(int)i); #ifdef QAK printf("%s: check 4.0\n",FUNC); + { + intn j; + + for(i=0; iextent.u.simple.rank; i++) { + for(j=0; j<(int)space->select.sel_info.hyper_lst->count; j++) { +printf("%s: lo_bound[%d][%d]=%d(%p), hi_bound[%d][%d]=%d(%p)\n",FUNC, + i,j,(int)space->select.sel_info.hyper_lst->lo_bounds[i][j].bound, + space->select.sel_info.hyper_lst->lo_bounds[i][j].node, + i,j,(int)space->select.sel_info.hyper_lst->hi_bounds[i][j].bound, + space->select.sel_info.hyper_lst->hi_bounds[i][j].node); + } + } + } #endif /* QAK */ /* Insert each boundary of the hyperslab into the sorted lists of bounds */ for(i=0; iextent.u.simple.rank; i++) { /* Check if this is the first hyperslab inserted */ if(space->select.sel_info.hyper_lst->count==0) { +#ifdef QAK +printf("%s: check 4.1, start[%d]=%d, end[%d]=%d\n",FUNC,i,(int)slab->start[i],i,(int)slab->end[i]); +printf("%s: check 4.1, hyper_lst->count=%d\n",FUNC,(int)space->select.sel_info.hyper_lst->count); +#endif /* QAK */ space->select.sel_info.hyper_lst->lo_bounds[i][0].bound=slab->start[i]; space->select.sel_info.hyper_lst->lo_bounds[i][0].node=slab; space->select.sel_info.hyper_lst->hi_bounds[i][0].bound=slab->end[i]; space->select.sel_info.hyper_lst->hi_bounds[i][0].node=slab; } /* end if */ else { +#ifdef QAK +printf("%s: check 4.3, start[%d]=%d, end[%d]=%d\n",FUNC,i,(int)slab->start[i],i,(int)slab->end[i]); +printf("%s: check 4.3, hyper_lst->count=%d\n",FUNC,(int)space->select.sel_info.hyper_lst->count); +#endif /* QAK */ /* Take care of the low boundary first */ /* Find the location to insert in front of */ if((bound_loc=H5S_hyper_bsearch(slab->start[i],space->select.sel_info.hyper_lst->lo_bounds[i], @@ -1369,14 +1444,17 @@ printf("%s: check 4.0\n",FUNC); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't find location to insert hyperslab boundary"); +#ifdef QAK +printf("%s: check 4.5, bound_loc=%d\n",FUNC,(int)bound_loc); +#endif /* QAK */ /* Check if we need to move boundary elements */ if(bound_loc!=(intn)space->select.sel_info.hyper_lst->count) { - HDmemmove(space->select.sel_info.hyper_lst->lo_bounds[bound_loc+1], - space->select.sel_info.hyper_lst->lo_bounds[bound_loc], + HDmemmove(&space->select.sel_info.hyper_lst->lo_bounds[i][bound_loc+1], + &space->select.sel_info.hyper_lst->lo_bounds[i][bound_loc], sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hyper_lst->count-bound_loc)); } /* end if */ - space->select.sel_info.hyper_lst->lo_bounds[bound_loc][i].bound=slab->start[i]; - space->select.sel_info.hyper_lst->lo_bounds[bound_loc][i].node=slab; + space->select.sel_info.hyper_lst->lo_bounds[i][bound_loc].bound=slab->start[i]; + space->select.sel_info.hyper_lst->lo_bounds[i][bound_loc].node=slab; /* Take care of the high boundary next */ /* Find the location to insert in front of */ @@ -1387,12 +1465,12 @@ printf("%s: check 4.0\n",FUNC); /* Check if we need to move boundary elements */ if(bound_loc!=(intn)space->select.sel_info.hyper_lst->count) { - HDmemmove(space->select.sel_info.hyper_lst->hi_bounds[bound_loc+1], - space->select.sel_info.hyper_lst->hi_bounds[bound_loc], + HDmemmove(&space->select.sel_info.hyper_lst->hi_bounds[i][bound_loc+1], + &space->select.sel_info.hyper_lst->hi_bounds[i][bound_loc], sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hyper_lst->count-bound_loc)); } /* end if */ - space->select.sel_info.hyper_lst->hi_bounds[bound_loc][i].bound=slab->end[i]; - space->select.sel_info.hyper_lst->hi_bounds[bound_loc][i].node=slab; + space->select.sel_info.hyper_lst->hi_bounds[i][bound_loc].bound=slab->end[i]; + space->select.sel_info.hyper_lst->hi_bounds[i][bound_loc].node=slab; } /* end else */ } /* end for */ #ifdef QAK @@ -1410,6 +1488,17 @@ printf("%s: check 5.0\n",FUNC); space->select.num_elem+=elem_count; #ifdef QAK printf("%s: check 6.0\n",FUNC); + { + intn j; + + for(i=0; iextent.u.simple.rank; i++) { + for(j=0; j<(int)space->select.sel_info.hyper_lst->count; j++) { +printf("%s: lo_bound[%d][%d]=%d, hi_bound[%d][%d]=%d\n",FUNC,i,j, + (int)space->select.sel_info.hyper_lst->lo_bounds[i][j].bound,i,j, + (int)space->select.sel_info.hyper_lst->hi_bounds[i][j].bound); + } + } + } #endif /* QAK */ done: @@ -1504,6 +1593,9 @@ H5S_point_npoints (const H5S_t *space) /* Check args */ assert (space); +#ifdef QAK +printf("%s: check 1.0, nelmts=%d\n",FUNC,(int)space->select.num_elem); +#endif /* QAK */ FUNC_LEAVE (space->select.num_elem); } /* H5S_point_npoints() */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 2c0dfa2..35371ba 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -334,5 +334,6 @@ herr_t H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *size); herr_t H5S_hyper_release (H5S_t *space); herr_t H5S_hyper_sel_iter_release (H5S_sel_iter_t *sel_iter); hsize_t H5S_hyper_npoints (const H5S_t *space); +int H5S_hyper_compare_regions (const void *r1, const void *r2); #endif diff --git a/src/H5Sselect.c b/src/H5Sselect.c index c8ddd4b..658529e 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -187,8 +187,11 @@ H5Sselect_hyperslab (hid_t spaceid, H5S_seloper_t op, H5S_t *space = NULL; /* Dataspace to modify selection of */ hsize_t *stride, /* Stride array */ *block=NULL; /* Block size array */ + hssize_t slab[H5O_LAYOUT_NDIMS]; /* Location of the block to add for strided selections */ + size_t slice[H5O_LAYOUT_NDIMS]; /* Size of preceding dimension's slice */ + uintn acc; /* Accumulator for building slices */ uintn contig; /* whether selection is contiguous or not */ - int i; /* Counters */ + int i,j; /* Counters */ herr_t ret_value=FAIL; /* return value */ FUNC_ENTER (H5Sselect_hyperslab, FAIL); @@ -278,19 +281,44 @@ printf("%s: check 2.0\n",FUNC); "can't allocate hyperslab lo bound information"); } /* end if */ +/* Generate list of blocks to add/remove based on selection operation */ + #ifdef QAK printf("%s: check 3.0\n",FUNC); #endif /* QAK */ /* Add hyperslab to selection */ if(contig) { /* Check for trivial case */ - if(H5S_hyper_add(space,start,count)<0) { + + /* Account for strides & blocks being equal, but larger than one */ + /* (Why someone would torture us this way, I don't know... -QAK :-) */ + for(i=0; iextent.u.simple.rank; i++) + slab[i]=count[i]*stride[i]; + + /* Add the contiguous hyperslab to the selection */ + if(H5S_hyper_add(space,start,(const hsize_t *)slab)<0) { HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab"); } } else { -/* Generate list of blocks to add/remove based on selection operation */ -/* Add/Remove blocks to/from selection */ - assert("complex hyperslabs not supported yet" && 0); + /* Build the slice sizes for each dimension */ + for(i=0, acc=1; iextent.u.simple.rank; i++) { + slice[i]=acc; + acc*=count[i]; + } /* end for */ + + /* Step through all the blocks to add */ + /* (reuse the count in ACC above) */ + for(i=0; i<(int)acc; i++) { + /* Build the location of the block */ + for(j=0; jextent.u.simple.rank; j++) + slab[j]=start[j]+((i/slice[j])%count[j])*stride[j]; + + /* Add the block to the list of hyperslab selections */ + if(H5S_hyper_add(space,(const hssize_t *)slab,(const hsize_t *)block)<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, + "can't insert hyperslab"); + } /* end if */ + } /* end for */ } /* end if */ /* Set selection type */ -- cgit v0.12