Files
hdf5/src/H5Fseq.c
Quincey Koziol 55869bd2ff [svn-r7116] Purpose:
Update code

Description:
    Move "PABLO_MASK" definition above header file inclusion to avoid problems
with inline functions in header files.

Platforms tested:
    FreeBSD 4.8 (sleipnir)
    h5committest
2003-06-27 10:59:48 -05:00

445 lines
20 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
* Thursday, September 28, 2000
*
* Purpose: Provides I/O facilities for sequences of bytes stored with various
* layout policies. These routines are similar to the H5Farray.c routines,
* these deal in terms of byte offsets and lengths, not coordinates and
* hyperslab sizes.
*
*/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
/* Pablo information */
/* (Put before include files to avoid problems with inline functions) */
#define PABLO_MASK H5Fseq_mask
#include "H5private.h"
#include "H5Dprivate.h"
#include "H5Eprivate.h"
#include "H5Fpkg.h"
#include "H5FDprivate.h" /*file driver */
#include "H5Iprivate.h"
#include "H5MFprivate.h"
#include "H5MMprivate.h" /*memory management */
#include "H5Oprivate.h"
#include "H5Pprivate.h"
#include "H5Vprivate.h"
/* MPIO & MPIPOSIX driver functions are needed for some special checks */
#include "H5FDmpio.h"
#include "H5FDmpiposix.h"
/* Interface initialization */
#define INTERFACE_INIT NULL
static int interface_initialize_g = 0;
/*-------------------------------------------------------------------------
* Function: H5F_seq_read
*
* Purpose: Reads a sequence of bytes from a file dataset into a buffer in
* in memory. The data is read from file F and the array's size and
* storage information is in LAYOUT. External files are described
* according to the external file list, EFL. The sequence offset is
* DSET_OFFSET in the dataset (offsets are in terms of bytes) and the
* size of the hyperslab is SEQ_LEN. The total size of the file array
* is implied in the LAYOUT argument.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, September 28, 2000
*
* Modifications:
* Re-written to use new vector I/O call - QAK, 7/7/01
*
*-------------------------------------------------------------------------
*/
herr_t
H5F_seq_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t seq_len, hsize_t dset_offset, void *buf/*out*/)
{
hsize_t mem_off=0; /* Offset in memory */
size_t mem_len=seq_len; /* Length in memory */
size_t mem_curr_seq=0; /* "Current sequence" in memory */
size_t dset_curr_seq=0; /* "Current sequence" in dataset */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_read, FAIL);
/* Check args */
assert(f);
assert(layout);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
if (H5F_seq_readvv(f, dxpl_id, layout, dc_plist, store, 1, &dset_curr_seq, &seq_len, &dset_offset, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5F_seq_read() */
/*-------------------------------------------------------------------------
* Function: H5F_seq_write
*
* Purpose: Writes a sequence of bytes to a file dataset from a buffer in
* in memory. The data is written to file F and the array's size and
* storage information is in LAYOUT. External files are described
* according to the external file list, EFL. The sequence offset is
* DSET_OFFSET in the dataset (offsets are in terms of bytes) and the
* size of the hyperslab is SEQ_LEN. The total size of the file array
* is implied in the LAYOUT argument.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Monday, October 9, 2000
*
* Modifications:
* Re-written to use new vector I/O routine - QAK, 7/7/01
*
*-------------------------------------------------------------------------
*/
herr_t
H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t seq_len, hsize_t dset_offset, const void *buf)
{
hsize_t mem_off=0; /* Offset in memory */
size_t mem_len=seq_len; /* Length in memory */
size_t mem_curr_seq=0; /* "Current sequence" in memory */
size_t dset_curr_seq=0; /* "Current sequence" in dataset */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_write, FAIL);
/* Check args */
assert(f);
assert(layout);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
if (H5F_seq_writevv(f, dxpl_id, layout, dc_plist, store, 1, &dset_curr_seq, &seq_len, &dset_offset, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5F_seq_write() */
/*-------------------------------------------------------------------------
* Function: H5F_seq_readvv
*
* Purpose: Reads in a vector of byte sequences from a file dataset into a
* buffer in in memory. The data is read from file F and the array's size
* and storage information is in LAYOUT. External files are described
* according to the external file list, EFL. The vector of byte sequences
* offsets is in the DSET_OFFSET array into the dataset (offsets are in
* terms of bytes) and the size of each sequence is in the SEQ_LEN array.
* The total size of the file array is implied in the LAYOUT argument.
* Bytes read into BUF are sequentially stored in the buffer, each sequence
* from the vector stored directly after the previous. The number of
* sequences is NSEQ.
* Purpose: Reads a vector of byte sequences from a vector of byte
* sequences in a file dataset into a buffer in memory. The data is
* read from file F and the array's size and storage information is in
* LAYOUT. External files and chunks are described according to the
* storage information, STORE. The vector of byte sequences offsets for
* the file is in the DSET_OFFSET_ARR array into the dataset (offsets are
* in terms of bytes) and the size of each sequence is in the DSET_LEN_ARR
* array. The vector of byte sequences offsets for memory is in the
* MEM_OFFSET_ARR array into the dataset (offsets are in terms of bytes)
* and the size of each sequence is in the MEM_LEN_ARR array. The total
* size of the file array is implied in the LAYOUT argument. The maximum
* number of sequences in the file dataset and the memory buffer are
* DSET_MAX_NSEQ & MEM_MAX_NSEQ respectively. The current sequence being
* operated on in the file dataset and the memory buffer are DSET_CURR_SEQ
* & MEM_CURR_SEQ respectively. The current sequence being operated on
* will be updated as a result of the operation, as will the offsets and
* lengths of the file dataset and memory buffer sequences.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Wednesday, May 7, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
ssize_t
H5F_seq_readvv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
struct H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
void *buf/*out*/)
{
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif /* H5_HAVE_PARALLEL */
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_readvv, FAIL);
/* Check args */
assert(f);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); /* Make certain we have the correct type of property list */
assert(layout);
assert(dc_plist);
assert(dset_curr_seq);
assert(*dset_curr_seq<dset_max_nseq);
assert(dset_len_arr);
assert(dset_offset_arr);
assert(mem_curr_seq);
assert(*mem_curr_seq<mem_max_nseq);
assert(mem_len_arr);
assert(mem_offset_arr);
assert(buf);
#ifdef H5_HAVE_PARALLEL
/* Get the transfer mode for MPIO transfers */
if(IS_H5FD_MPIO(f)) {
hid_t driver_id; /* VFL driver ID */
H5P_genplist_t *plist; /* Property list */
/* Get the plist structure */
if(NULL == (plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Get the driver ID */
if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id)<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve VFL driver ID");
/* Check if we are using the MPIO driver (for the DXPL) */
if(H5FD_MPIO==driver_id) {
/* Get the transfer mode */
xfer_mode=(H5FD_mpio_xfer_t)H5P_peek_unsigned(plist, H5D_XFER_IO_XFER_MODE_NAME);
} /* end if */
} /* end if */
/* Collective MPIO access is unsupported for non-contiguous datasets */
if (H5D_CHUNKED==layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Read directly from file if the dataset is in an external file */
if (store && store->efl.nused>0) {
/* Note: We can't use data sieve buffers for datasets in external files
* because the 'addr' of all external files is set to 0 (above) and
* all datasets in external files would alias to the same set of
* file offsets, totally mixing up the data sieve buffer information. -QAK
*/
if((ret_value=H5O_efl_readvv(&(store->efl),
dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
buf))<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
} else {
hsize_t max_data; /*bytes in dataset */
unsigned u; /*counters */
/* Compute the size of the dataset in bytes */
for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++)
max_data *= layout->dim[u];
/* Pass along the vector of sequences to read */
if((ret_value=H5F_contig_readvv(f, max_data, layout->addr,
dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
} /* end else */
break;
case H5D_CHUNKED:
assert(store);
if((ret_value=H5F_istore_readvv(f, dxpl_id, layout, dc_plist, store->chunk_coords,
dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
buf))<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "istore read failed");
break;
case H5D_COMPACT:
/* Pass along the vector of sequences to read */
if((ret_value=H5F_compact_readvv(f, layout,
dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "compact read failed");
break;
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
} /* end switch() */
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5F_seq_readvv() */
/*-------------------------------------------------------------------------
* Function: H5F_seq_writevv
*
* Purpose: Writes a vector of byte sequences from a buffer in memory into
* a vector of byte sequences in a file dataset. The data is written to
* file F and the array's size and storage information is in LAYOUT.
* External files and chunks are described according to the storage
* information, STORE. The vector of byte sequences offsets for the file
* is in the DSET_OFFSET_ARR array into the dataset (offsets are in
* terms of bytes) and the size of each sequence is in the DSET_LEN_ARR
* array. The vector of byte sequences offsets for memory is in the
* MEM_OFFSET_ARR array into the dataset (offsets are in terms of bytes)
* and the size of each sequence is in the MEM_LEN_ARR array. The total
* size of the file array is implied in the LAYOUT argument. The maximum
* number of sequences in the file dataset and the memory buffer are
* DSET_MAX_NSEQ & MEM_MAX_NSEQ respectively. The current sequence being
* operated on in the file dataset and the memory buffer are DSET_CURR_SEQ
* & MEM_CURR_SEQ respectively. The current sequence being operated on
* will be updated as a result of the operation, as will the offsets and
* lengths of the file dataset and memory buffer sequences.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Friday, May 2, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
ssize_t
H5F_seq_writevv(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
struct H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
const void *buf)
{
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif /* H5_HAVE_PARALLEL */
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_writevv, FAIL);
/* Check args */
assert(f);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); /* Make certain we have the correct type of property list */
assert(layout);
assert(dc_plist);
assert(dset_curr_seq);
assert(*dset_curr_seq<dset_max_nseq);
assert(dset_len_arr);
assert(dset_offset_arr);
assert(mem_curr_seq);
assert(*mem_curr_seq<mem_max_nseq);
assert(mem_len_arr);
assert(mem_offset_arr);
assert(buf);
#ifdef H5_HAVE_PARALLEL
/* Get the transfer mode for MPIO transfers */
if(IS_H5FD_MPIO(f)) {
hid_t driver_id; /* VFL driver ID */
H5P_genplist_t *plist=NULL; /* Property list */
/* Get the plist structure */
if(NULL == (plist = H5I_object(dxpl_id)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Get the driver ID */
if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id)<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve VFL driver ID");
/* Check if we are using the MPIO driver (for the DXPL) */
if(H5FD_MPIO==driver_id) {
/* Get the transfer mode */
xfer_mode=(H5FD_mpio_xfer_t)H5P_peek_unsigned(plist, H5D_XFER_IO_XFER_MODE_NAME);
} /* end if */
} /* end if */
/* Collective MPIO access is unsupported for non-contiguous datasets */
if (H5D_CHUNKED==layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access on chunked datasets not supported yet");
#endif /* H5_HAVE_PARALLEL */
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Write directly to file if the dataset is in an external file */
if (store && store->efl.nused>0) {
/* Note: We can't use data sieve buffers for datasets in external files
* because the 'addr' of all external files is set to 0 (above) and
* all datasets in external files would alias to the same set of
* file offsets, totally mixing up the data sieve buffer information. -QAK
*/
if ((ret_value=H5O_efl_writevv(&(store->efl),
dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
buf))<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
} else {
hsize_t max_data; /* Bytes in dataset */
unsigned u; /* Local index variable */
/* Compute the size of the dataset in bytes */
for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++)
max_data *= layout->dim[u];
/* Pass along the vector of sequences to write */
if ((ret_value=H5F_contig_writevv(f, max_data, layout->addr,
dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
} /* end else */
break;
case H5D_CHUNKED:
assert(store);
if((ret_value=H5F_istore_writevv(f, dxpl_id, layout, dc_plist, store->chunk_coords,
dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
buf))<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "istore write failed");
break;
case H5D_COMPACT:
/* Pass along the vector of sequences to write */
if((ret_value=H5F_compact_writevv(f, layout,
dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "compact write failed");
break;
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
} /* end switch() */
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5F_seq_writevv() */