Exemple #1
0
/*-------------------------------------------------------------------------
 * Function:	H5D_select_io
 *
 * Purpose:	Perform I/O directly from application memory and a file
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Quincey Koziol
 *              Tuesday, November 27, 2007
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5D_select_io(H5D_io_info_t *io_info,
    size_t nelmts, size_t elmt_size,
    const H5S_t *file_space, const H5S_t *mem_space,
    haddr_t addr, void *chunk/*in*/,
    const H5D_select_buf_t *io_buf)
{
    H5S_sel_iter_t mem_iter;    /* Memory selection iteration info */
    hbool_t mem_iter_init = 0;  /* Memory selection iteration info has been initialized */
    H5S_sel_iter_t file_iter;   /* File selection iteration info */
    hbool_t file_iter_init = 0;	/* File selection iteration info has been initialized */
    hsize_t _mem_off[H5D_IO_VECTOR_SIZE];      /* Array to store sequence offsets in memory */
    hsize_t *mem_off = NULL;    /* Pointer to sequence offsets in memory */
    hsize_t _file_off[H5D_IO_VECTOR_SIZE];     /* Array to store sequence offsets in the file */
    hsize_t *file_off = NULL;   /* Pointer to sequence offsets in the file */
    size_t _mem_len[H5D_IO_VECTOR_SIZE];       /* Array to store sequence lengths in memory */
    size_t *mem_len = NULL;     /* Pointer to sequence lengths in memory */
    size_t _file_len[H5D_IO_VECTOR_SIZE];      /* Array to store sequence lengths in the file */
    size_t *file_len = NULL;    /* Pointer to sequence lengths in the file */
    size_t curr_mem_seq;        /* Current memory sequence to operate on */
    size_t curr_file_seq;       /* Current file sequence to operate on */
    size_t mem_nseq;            /* Number of sequences generated in the file */
    size_t file_nseq;           /* Number of sequences generated in memory */
    ssize_t tmp_file_len;       /* Temporary number of bytes in file sequence */
    herr_t ret_value = SUCCEED; /* Return value */

    FUNC_ENTER_NOAPI(H5D_select_io, FAIL)

    /* Check args */
    HDassert(io_info);
    HDassert(io_info->dset);
    HDassert(io_info->store);
    HDassert(TRUE == H5P_isa_class(io_info->dxpl_id, H5P_DATASET_XFER));
    HDassert(io_buf->u.rbuf);

    /* Allocate the vector I/O arrays */
    if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
        if(NULL == (mem_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array")
        if(NULL == (mem_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array")
        if(NULL == (file_len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array")
        if(NULL == (file_off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array")
    } /* end if */
    else {
Exemple #2
0
/*-------------------------------------------------------------------------
 * Function:	H5D_compact_fill
 *
 * Purpose:	Write fill values to a compactly stored dataset.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Quincey Koziol
 *		May 6, 2007
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5D_compact_fill(H5D_t *dset, hid_t dxpl_id)
{
    herr_t	ret_value = SUCCEED;	/* Return value */

    FUNC_ENTER_NOAPI(H5D_compact_fill, FAIL)

    /* Check args */
    HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER));
    HDassert(dset && H5D_COMPACT == dset->shared->layout.type);
    HDassert(dset->shared->layout.u.compact.buf);
    HDassert(dset->shared->type);
    HDassert(dset->shared->space);

    /* If the fill value is defined, initialize the data buffer with it */
    if(dset->shared->fill.buf) {
        hssize_t snpoints;      /* Number of points in space (for error checking) */
        size_t npoints;         /* Number of points in space */

        /* Get the number of elements in the dataset's dataspace */
        snpoints = H5S_GET_EXTENT_NPOINTS(dset->shared->space);
        HDassert(snpoints >= 0);
        H5_ASSIGN_OVERFLOW(npoints, snpoints, hssize_t, size_t);

        /* If necessary, convert fill value datatypes (which copies VL components, etc.) */
        if(H5T_detect_class(dset->shared->type, H5T_VLEN) > 0) {
            H5T_path_t *tpath;      /* Datatype conversion path */
            uint8_t *bkg_buf = NULL;    /* Background conversion buffer */
            H5T_t *mem_type;            /* Pointer to memory datatype */
            size_t mem_type_size, file_type_size;       /* Size of datatype in memory and on disk */
            hid_t mem_tid;              /* Memory version of disk datatype */

            /* Create temporary datatype for conversion operation */
            if(NULL == (mem_type = H5T_copy(dset->shared->type, H5T_COPY_REOPEN)))
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy file datatype")
            if((mem_tid = H5I_register(H5I_DATATYPE, mem_type)) < 0) {
                H5T_close(mem_type);
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
            } /* end if */
Exemple #3
0
/*-------------------------------------------------------------------------
 * Function:  H5D_mpio_spaces_xfer
 *
 * Purpose:  Use MPI-IO to transfer data efficiently
 *    directly between app buffer and file.
 *
 * Return:  non-negative on success, negative on failure.
 *
 * Programmer:  rky 980813
 *
 * Notes:
 *      For collective data transfer only since this would eventually call
 *      H5FD_mpio_setup to do setup to eveually call MPI_File_set_view in
 *      H5FD_mpio_read or H5FD_mpio_write.  MPI_File_set_view is a collective
 *      call.  Letting independent data transfer use this route would result in
 *      hanging.
 *
 *      The preconditions for calling this routine are located in the
 *      H5S_mpio_opt_possible() routine, which determines whether this routine
 *      can be called for a given dataset transfer.
 *
 * Modifications:
 *  rky 980918
 *  Added must_convert parameter to let caller know we can't optimize
 *  the xfer.
 *
 *  Albert Cheng, 001123
 *  Include the MPI_type freeing as part of cleanup code.
 *
 *      QAK - 2002/04/02
 *      Removed the must_convert parameter and move preconditions to
 *      H5S_mpio_opt_possible() routine
 *
 *      QAK - 2002/06/17
 *      Removed 'disp' parameter from H5FD_mpio_setup routine and use the
 *      address of the dataset in MPI_File_set_view() calls, as necessary.
 *
 *      QAK - 2002/06/18
 *      Removed 'dc_plist' parameter, since it was not used.  Also, switch to
 *      getting the 'extra_offset' setting for each selection.
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5D_mpio_spaces_xfer(H5D_io_info_t *io_info, size_t elmt_size,
    const H5S_t *file_space, const H5S_t *mem_space,
    void *_buf /*out*/, hbool_t do_write )
{
    haddr_t   addr;                  /* Address of dataset (or selection) within file */
    size_t   mpi_buf_count, mpi_file_count;       /* Number of "objects" to transfer */
    hsize_t   mpi_buf_offset, mpi_file_offset;       /* Offset within dataset where selection (ie. MPI type) begins */
    MPI_Datatype mpi_buf_type, mpi_file_type;   /* MPI types for buffer (memory) and file */
    hbool_t   mbt_is_derived=0,      /* Whether the buffer (memory) type is derived and needs to be free'd */
     mft_is_derived=0;      /* Whether the file type is derived and needs to be free'd */
    hbool_t   plist_is_setup=0;      /* Whether the dxpl has been customized */
    uint8_t  *buf=(uint8_t *)_buf;   /* Alias for pointer arithmetic */
    int          mpi_code;              /* MPI return code */
    herr_t   ret_value = SUCCEED;   /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5D_mpio_spaces_xfer);

    /* Check args */
    assert (io_info);
    assert (io_info->dset);
    assert (file_space);
    assert (mem_space);
    assert (buf);
    assert (IS_H5FD_MPIO(io_info->dset->ent.file));
    /* Make certain we have the correct type of property list */
    assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER));

    /* create the MPI buffer type */
    if (H5S_mpio_space_type( mem_space, elmt_size,
             /* out: */
             &mpi_buf_type,
             &mpi_buf_count,
             &mpi_buf_offset,
             &mbt_is_derived )<0)
      HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI buf type");

    /* create the MPI file type */
    if ( H5S_mpio_space_type( file_space, elmt_size,
             /* out: */
             &mpi_file_type,
             &mpi_file_count,
             &mpi_file_offset,
             &mft_is_derived )<0)
      HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI file type");

    /* Get the base address of the contiguous dataset or the chunk */
    if(io_info->dset->shared->layout.type == H5D_CONTIGUOUS)
       addr = H5D_contig_get_addr(io_info->dset) + mpi_file_offset;
    else {
        haddr_t   chunk_addr; /* for collective chunk IO */

        assert(io_info->dset->shared->layout.type == H5D_CHUNKED);
        chunk_addr=H5D_istore_get_addr(io_info,NULL);
        addr = H5F_BASE_ADDR(io_info->dset->ent.file) + chunk_addr + mpi_file_offset;
    }

    /*
     * Pass buf type, file type to the file driver. Request an MPI type
     * transfer (instead of an elementary byteblock transfer).
     */
    if(H5FD_mpi_setup_collective(io_info->dxpl_id, mpi_buf_type, mpi_file_type)<0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O properties");
    plist_is_setup=1;

    /* Adjust the buffer pointer to the beginning of the selection */
    buf+=mpi_buf_offset;

    /* transfer the data */
    if (do_write) {
      if (H5F_block_write(io_info->dset->ent.file, H5FD_MEM_DRAW, addr, mpi_buf_count, io_info->dxpl_id, buf) <0)
      HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,"MPI write failed");
    } else {
      if (H5F_block_read (io_info->dset->ent.file, H5FD_MEM_DRAW, addr, mpi_buf_count, io_info->dxpl_id, buf) <0)
      HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL,"MPI read failed");
    }

done:
    /* Reset the dxpl settings */
    if(plist_is_setup) {
        if(H5FD_mpi_teardown_collective(io_info->dxpl_id)<0)
          HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "unable to reset dxpl values");
    } /* end if */

    /* free the MPI buf and file types */
    if (mbt_is_derived) {
  if (MPI_SUCCESS != (mpi_code= MPI_Type_free( &mpi_buf_type )))
            HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
    }
    if (mft_is_derived) {
  if (MPI_SUCCESS != (mpi_code= MPI_Type_free( &mpi_file_type )))
            HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
    }

    FUNC_LEAVE_NOAPI(ret_value);
} /* end H5D_mpio_spaces_xfer() */
Exemple #4
0
/*-------------------------------------------------------------------------
 * Function:	H5D_select_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 dataspace 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:	Non-negative on success/Negative on failure
 *
 * Programmer:	Quincey Koziol
 *              Thursday, June 20, 2002
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5D_select_fscat (H5D_io_info_t *io_info,
    const H5S_t *space, H5S_sel_iter_t *iter, size_t nelmts,
    haddr_t chunk_addr, void *chunk/*in*/, const void *_buf)
{
    const uint8_t *buf=_buf;       /* Alias for pointer arithmetic */
    hsize_t _off[H5D_IO_VECTOR_SIZE];             /* Array to store sequence offsets */
    hsize_t *off=NULL;             /* Pointer to sequence offsets */
    hsize_t mem_off;               /* Offset in memory */
    size_t mem_curr_seq;           /* "Current sequence" in memory */
    size_t dset_curr_seq;          /* "Current sequence" in dataset */
    size_t _len[H5D_IO_VECTOR_SIZE];              /* Array to store sequence lengths */
    size_t *len=NULL;              /* Array to store sequence lengths */
    size_t orig_mem_len, mem_len;  /* Length of sequence in memory */
    size_t  nseq;                  /* Number of sequences generated */
    size_t  nelem;                 /* Number of elements used in sequences */
    herr_t  ret_value=SUCCEED;     /* Return value */

    FUNC_ENTER_NOAPI(H5D_select_fscat, FAIL);

    /* Check args */
    assert (io_info);
    assert (space);
    assert (iter);
    assert (nelmts>0);
    assert (_buf);
    assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER));

    /* Allocate the vector I/O arrays */
    if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
        if((len = H5FL_SEQ_MALLOC(size_t,io_info->dxpl_cache->vec_size))==NULL)
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
        if((off = H5FL_SEQ_MALLOC(hsize_t,io_info->dxpl_cache->vec_size))==NULL)
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
    } /* end if */
    else {
        len=_len;
        off=_off;
    } /* end else */

    /* Loop until all elements are written */
    while(nelmts>0) {
        /* Get list of sequences for selection to write */
        if(H5S_SELECT_GET_SEQ_LIST(space,H5S_GET_SEQ_LIST_SORTED,iter,io_info->dxpl_cache->vec_size,nelmts,&nseq,&nelem,off,len)<0)
            HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");

        /* Reset the current sequence information */
        mem_curr_seq=dset_curr_seq=0;
        orig_mem_len=mem_len=nelem*iter->elmt_size;
        mem_off=0;

        /* Write sequence list out */
        if((*io_info->ops.writevv)(io_info, nseq, &dset_curr_seq, len, off, (size_t)1, &mem_curr_seq, &mem_len, &mem_off, chunk_addr, chunk, buf) < 0)
            HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");

        /* Update buffer */
        buf += orig_mem_len;

        /* Decrement number of elements left to process */
        nelmts -= nelem;
    } /* end while */

done:
    if(io_info->dxpl_cache->vec_size != H5D_IO_VECTOR_SIZE) {
        if(len!=NULL)
            H5FL_SEQ_FREE(size_t,len);
        if(off!=NULL)
            H5FL_SEQ_FREE(hsize_t,off);
    } /* end if */
    FUNC_LEAVE_NOAPI(ret_value);
} /* H5D_select_fscat() */