diff options
Diffstat (limited to 'src/H5Spoint.c')
-rw-r--r-- | src/H5Spoint.c | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/src/H5Spoint.c b/src/H5Spoint.c new file mode 100644 index 0000000..86b1bc9 --- /dev/null +++ b/src/H5Spoint.c @@ -0,0 +1,455 @@ +/* + * Copyright (C) 1998 NCSA + * All rights reserved. + * + * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> + * Tuesday, June 16, 1998 + * + * Purpose: Point selection data space I/O functions. + */ +#include <H5private.h> +#include <H5Eprivate.h> +#include <H5Sprivate.h> +#include <H5Vprivate.h> + +/* Interface initialization */ +#define PABLO_MASK H5S_point_mask +#define INTERFACE_INIT NULL +static intn interface_initialize_g = FALSE; + +/*------------------------------------------------------------------------- + * Function: H5S_point_init + * + * Purpose: Initializes iteration information for point selection. + * + * Return: non-negative on success, negative on failure. + * + * Programmer: Quincey Koziol + * Tuesday, June 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_point_init (const struct H5O_layout_t __unused__ *layout, + const H5S_t *space, H5S_sel_iter_t *sel_iter) +{ + FUNC_ENTER (H5S_point_init, FAIL); + + /* Check args */ + assert (layout); + assert (space && H5S_SEL_POINTS==space->select.type); + assert (sel_iter); + + /* Initialize the number of points to iterate over */ + sel_iter->pnt.elmt_left=space->select.num_elem; + + /* Start at the head of the list of points */ + sel_iter->pnt.curr=space->select.sel_info.pnt_lst->head; + + FUNC_LEAVE (SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5S_point_favail + * + * Purpose: Figure out the optimal number of elements to transfer to/from the file + * + * Return: non-negative number of elements on success, negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, June 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5S_point_favail (const H5S_t __unused__ *space, const H5S_sel_iter_t *sel_iter, size_t max) +{ + FUNC_ENTER (H5S_point_favail, FAIL); + + /* Check args */ + assert (space && H5S_SEL_POINTS==space->select.type); + assert (sel_iter); + + FUNC_LEAVE (MIN(sel_iter->pnt.elmt_left,max)); +} /* H5S_point_favail() */ + +/*------------------------------------------------------------------------- + * Function: H5S_point_fgath + * + * Purpose: Gathers data points from file F and accumulates them in the + * type conversion buffer BUF. The LAYOUT argument describes + * how the data is stored on disk and EFL describes how the data + * is organized in external files. ELMT_SIZE is the size in + * bytes of a datum which this function treats as opaque. + * FILE_SPACE describes the data space of the dataset on disk + * and the elements that have been selected for reading (via + * hyperslab, etc). This function will copy at most NELMTS elements. + * + * Notes: This could be optimized by gathering selected elements near (how + * near?) each other into one I/O request and then moving the correct + * elements into the return buffer + * + * Return: Success: Number of elements copied. + * + * Failure: 0 + * + * Programmer: Quincey Koziol + * Tuesday, June 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, + const struct H5O_compress_t *comp, const struct H5O_efl_t *efl, + size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, + size_t nelmts, + const H5D_transfer_t xfer_mode, void *_buf/*out*/) +{ + hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ + hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */ + uint8 *buf=(uint8 *)_buf; /* Alias for pointer arithmetic */ + intn i; /*counters */ + size_t num_read; /* number of elements read into buffer */ + + FUNC_ENTER (H5S_point_fgath, 0); + + /* Check args */ + assert (f); + assert (layout); + assert (elmt_size>0); + assert (file_space); + assert (file_iter); + assert (nelmts>0); + assert (buf); + + /* initialize hyperslab size and offset in memory buffer */ + for(i=0; i<layout->ndims; i++) { + hsize[i]=1; /* hyperslab size is 1, except for last element */ + zero[i]=0; /* memory offset is 0 */ + } /* end for */ + hsize[layout->ndims] = elmt_size; + + /* Walk though and request each element we need and put it into the buffer */ + num_read=0; + while(num_read<nelmts) { + if(file_iter->pnt.elmt_left>0) { + /* Copy the location of the point to get */ + HDmemcpy(file_offset,file_iter->pnt.curr->pnt,layout->ndims); + file_offset[layout->ndims] = 0; + + /* Go read the point */ + if (H5F_arr_read (f, layout, comp, efl, hsize, hsize, zero, file_offset, + xfer_mode, buf/*out*/)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); + } + + /* Increment the offset of the buffer */ + buf+=elmt_size; + + /* Increment the count read */ + num_read++; + + /* Advance the point iterator */ + file_iter->pnt.elmt_left--; + file_iter->pnt.curr=file_iter->pnt.curr->next; + } else { + break; /* out of elements in the selection */ + } /* end else */ + } /* end while */ + + FUNC_LEAVE (num_read); +} /* H5S_point_fgath() */ + +/*------------------------------------------------------------------------- + * Function: H5S_point_fscat + * + * Purpose: Scatters dataset elements from the type conversion buffer BUF + * to the file F where the data points are arranged according to + * the file data space FILE_SPACE and stored according to + * LAYOUT and EFL. Each element is ELMT_SIZE bytes. + * The caller is requesting that NELMTS elements are copied. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Tuesday, June 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout, + const struct H5O_compress_t *comp, const struct H5O_efl_t *efl, + size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, + size_t nelmts, + const H5D_transfer_t xfer_mode, const void *_buf) +{ + hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ + hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero vector */ + const uint8 *buf=(const uint8 *)_buf; /* Alias for pointer arithmetic */ + intn i; /*counters */ + size_t num_written; /* number of elements written from buffer */ + + FUNC_ENTER (H5S_point_fscat, FAIL); + + /* Check args */ + assert (f); + assert (layout); + assert (elmt_size>0); + assert (file_space); + assert (file_iter); + assert (nelmts>0); + assert (buf); + + /* initialize hyperslab size and offset in memory buffer */ + for(i=0; i<layout->ndims; i++) { + hsize[i]=1; /* hyperslab size is 1, except for last element */ + zero[i]=0; /* memory offset is 0 */ + } /* end for */ + hsize[layout->ndims] = elmt_size; + + /* Walk though and request each element we need and put it into the buffer */ + num_written=0; + while(num_written<nelmts) { + if(file_iter->pnt.elmt_left>0) { + /* Copy the location of the point to get */ + HDmemcpy(file_offset,file_iter->pnt.curr->pnt,layout->ndims); + file_offset[layout->ndims] = 0; + + /* Go read the point */ + if (H5F_arr_write (f, layout, comp, efl, hsize, hsize, zero, file_offset, + xfer_mode, buf)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); + } + + /* Increment the offset of the buffer */ + buf+=elmt_size; + + /* Increment the count read */ + num_written++; + + /* Advance the point iterator */ + file_iter->pnt.elmt_left--; + file_iter->pnt.curr=file_iter->pnt.curr->next; + } else { + break; /* out of elements in the selection */ + } /* end else */ + } /* end while */ + + FUNC_LEAVE (num_written); +} /* H5S_point_fscat() */ + +/*------------------------------------------------------------------------- + * Function: H5S_point_mgath + * + * Purpose: Gathers dataset elements from application memory BUF and + * copies them into the data type conversion buffer TCONV_BUF. + * Each element is ELMT_SIZE bytes and arranged in application + * memory according to MEM_SPACE. + * The caller is requesting that at most NELMTS be gathered. + * + * Return: Success: Number of elements copied. + * + * Failure: 0 + * + * Programmer: Quincey Koziol + * Tuesday, June 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5S_point_mgath (const void *_buf, size_t elmt_size, + const H5S_t *mem_space, H5S_sel_iter_t *mem_iter, + size_t nelmts, void *_tconv_buf/*out*/) +{ + hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */ + const uint8 *buf=(const uint8 *)_buf; /* Get local copies for address arithmetic */ + uint8 *tconv_buf=(uint8 *)_tconv_buf; + hsize_t acc; /*accumulator */ + intn space_ndims; /*dimensionality of space*/ + intn i; /*counters */ + size_t num_gath; /* number of elements gathered */ + + FUNC_ENTER (H5S_point_mgath, 0); + + /* Check args */ + assert (buf); + assert (elmt_size>0); + assert (mem_space && H5S_SEL_POINTS==mem_space->select.type); + assert (nelmts>0); + assert (tconv_buf); + + if ((space_ndims=H5S_get_dims (mem_space, mem_size, NULL))<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0, + "unable to retrieve data space dimensions"); + } + + for(num_gath=0; num_gath<nelmts; num_gath++) { + if(mem_iter->pnt.elmt_left>0) { + /* Compute the location of the point to get */ + for(i=0,acc=0; i<space_ndims; i++) + acc+=mem_size[i]*mem_iter->pnt.curr->pnt[i]; + + /* Copy the elements into the type conversion buffer */ + *tconv_buf=*(buf+acc); + + /* Increment the offset of the buffers */ + tconv_buf+=elmt_size; + + /* Advance the point iterator */ + mem_iter->pnt.elmt_left--; + mem_iter->pnt.curr=mem_iter->pnt.curr->next; + } else { + break; /* out of elements in the selection */ + } /* end else */ + } /* end for */ + + FUNC_LEAVE (num_gath); +} /* H5S_point_mgath() */ + +/*------------------------------------------------------------------------- + * Function: H5S_point_mscat + * + * Purpose: Scatters NELMTS data points from the type conversion buffer + * TCONV_BUF to the application buffer BUF. Each element is + * ELMT_SIZE bytes and they are organized in application memory + * according to MEM_SPACE. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, June 17, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_point_mscat (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]; /*total size of app buf */ + uint8 *buf=(uint8 *)_buf; /* Get local copies for address arithmetic */ + const uint8 *tconv_buf=(const uint8 *)_tconv_buf; + hsize_t acc; /*accumulator */ + intn space_ndims; /*dimensionality of space*/ + intn i; /*counters */ + size_t num_scat; /* Number of elements scattered */ + + FUNC_ENTER (H5S_point_mscat, FAIL); + + /* Check args */ + assert (tconv_buf); + assert (elmt_size>0); + assert (mem_space && H5S_SEL_POINTS==mem_space->select.type); + assert (nelmts>0); + assert (buf); + + /* + * Retrieve hyperslab information to determine what elements are being + * selected (there might be other selection methods in the future). We + * only handle hyperslabs with unit sample because there's currently no + * way to pass sample information to H5V_hyper_copy(). + */ + if ((space_ndims=H5S_get_dims (mem_space, mem_size, NULL))<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, + "unable to retrieve data space dimensions"); + } + + for(num_scat=0; num_scat<nelmts; num_scat++) { + if(mem_iter->pnt.elmt_left>0) { + /* Compute the location of the point to get */ + for(i=0,acc=0; i<space_ndims; i++) + acc+=mem_size[i]*mem_iter->pnt.curr->pnt[i]; + + /* Copy the elements into the type conversion buffer */ + *(buf+acc)=*tconv_buf; + + /* Increment the offset of the buffers */ + tconv_buf+=elmt_size; + + /* Advance the point iterator */ + mem_iter->pnt.elmt_left--; + mem_iter->pnt.curr=mem_iter->pnt.curr->next; + } else { + break; /* out of elements in the selection */ + } /* end else */ + } /* end for */ + + FUNC_LEAVE (SUCCEED); +} /* H5S_point_mscat() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_point_release + PURPOSE + Release point selection information for a dataspace + USAGE + herr_t H5S_point_release(space) + H5S_t *space; IN: Pointer to dataspace + RETURNS + SUCCEED/FAIL + DESCRIPTION + Releases all point selection information for a dataspace + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_point_release (H5S_t *space) +{ + intn i; /* Counters */ + + FUNC_ENTER (H5S_point_release, FAIL); + + /* Check args */ + assert (space); + +done: + FUNC_LEAVE (SUCCEED); +} /* H5S_point_release() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_point_npoints + PURPOSE + Compute number of elements in current selection + USAGE + hsize_t H5S_point_npoints(space) + H5S_t *space; IN: Pointer to dataspace + RETURNS + The number of elements in selection on success, 0 on failure + DESCRIPTION + Compute number of elements in current selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hsize_t +H5S_hyper_npoints (H5S_t *space) +{ + FUNC_ENTER (H5S_hyper_npoints, 0); + + /* Check args */ + assert (space); + + FUNC_LEAVE (space->select.num_elem); +} /* H5S_hyper_npoints() */ |