void *
ss_blob_read(ss_blob_t *blob, /* The blob from which data should be read. This is the blob's top scope for
* tasks that are participating for collectivity and are members of the blob's
* file communicator but not the blob's scope communicator. */
hid_t iospace, /* This is an optional hyperslab describing the part of the blob that is to
* be read. The extent and selection are relative to the portion of the
* dataset owned by the blob and described in some previous call to
* ss_blob_bind_f() (perhaps in an earlier execution). If not specified then
* all of the blob's data is read. Such a selection is generally constructed
* by calling ss_blob_space() and applying the selection. */
unsigned flags, /* Various bit flags commonly passed to this function. */
ss_prop_t UNUSED *props /* See [Blob Properties]. (Unused at this time.) */
)
{
SS_ENTER(ss_blob_read, voidP);
ss_scope_t topscope=SS_SCOPE_NULL; /* The top scope for BLOB */
ss_gblob_t *gblob=NULL; /* Global blob record for the file */
size_t d_idx=SS_NOSIZE; /* Index into gblob->d table */
void *buffer=NULL; /* Result buffer */
hid_t iom=-1, iof=-1; /* Data spaces for memory and file -- extent and selections */
hid_t dxpl=-1; /* Dataset transfer property list -- not copied here so do not close */
hid_t mtype=-1; /* Memory datatype saved after unbind */
herr_t status; /* Return status of called functions */
size_t tsize=SS_NOSIZE; /* Datatype size in bytes */
hssize_t nelmts; /* Number of elements in the I/O operation */
if (!ss_mpi_extras((ss_pers_t**)&blob, &topscope)) SS_ERROR(FAILED);
gblob = SS_GFILE_LINK(&topscope)->gblob;
if (blob) {
/* Verify data space consistency to the extent possible without actually calling H5Dread(). This also generates the
* dataset-dimension data spaces for memory and file. We have to do this before unbinding the memory but we still want
* to unbind it if necessary. So the error return is delayed until after the unbinding. */
if ((status = ss_blob_ckspaces(blob, iospace, &iom, &iof))<0) SS_SAVE;
/* Get a buffer for the result and unbind memory if so requested. If not bound to memory we'll allocate a buffer after
* we've checked that we're bound to a dataset. */
if ((buffer = SS_BLOB(blob)->m.mem)) {
if (flags & SS_BLOB_UNBIND) {
SS_BLOB(blob)->m.mem = NULL;
mtype = SS_BLOB(blob)->m.mtype; /*will be closed at end*/
SS_BLOB(blob)->m.mtype = 0;
if (H5Sclose(SS_BLOB(blob)->m.mspace)<0) SS_ERROR(HDF5);
SS_BLOB(blob)->m.mspace = 0;
} else {
if ((mtype = H5Tcopy(SS_BLOB(blob)->m.mtype))<0) SS_ERROR(HDF5);
}
}
/* Now that we've had an opportunity to unbind, raise the ss_blob_ckspaces() error if there was one. */
if (status<0) {
SS_REFAIL;
SS_ERROR(FAILED);
}
/* Make sure the blob is bound to a dataset */
if (!SS_BLOB(blob)->dsetaddr) SS_ERROR_FMT(USAGE, ("blob is not bound to a dataset"));
if (SS_NOSIZE==(d_idx=ss_blob_didx(blob))) SS_ERROR(FAILED);
SS_ASSERT(SS_BLOB(blob)->dsetaddr==*((haddr_t*)(&gblob->d[d_idx].stat.objno)[0]));
SS_ASSERT(gblob->d[d_idx].dset>0);
/* Allocate a buffer if we don't have one by now. */
if (!buffer) {
SS_ASSERT(mtype<0);
if ((mtype = H5Tget_native_type(gblob->d[d_idx].dtype, H5T_DIR_DEFAULT))<0) SS_ERROR(HDF5);
if (0==(tsize=H5Tget_size(mtype))) SS_ERROR(HDF5);
if ((nelmts = H5Sget_select_npoints(iom))<0) SS_ERROR(HDF5);
if (NULL==(buffer=malloc(MAX((size_t)1, (size_t)(nelmts*tsize))))) SS_ERROR(RESOURCE);
}
/* Get the dataset transfer property list. We do not allow this to be specified by the caller because SSlib does too
* many things under the covers to make that reliable. */
dxpl = flags & SS_BLOB_COLLECTIVE ? SS_GFILE_LINK(&topscope)->dxpl_collective : SS_GFILE_LINK(&topscope)->dxpl_independent;
/* Read the data */
/* ISSUE: The two-phase I/O optimization for reads is not implemented. */
if (H5Dread(gblob->d[d_idx].dset, mtype, iom, iof, dxpl, buffer)<0) SS_ERROR(HDF5);
/* Cleanup */
if (H5Sclose(iom)<0) SS_ERROR(HDF5);
iom = -1;
if (H5Sclose(iof)<0) SS_ERROR(HDF5);
iof = -1;
if (H5Tclose(mtype)<0) SS_ERROR(HDF5);
mtype = -1;
}
SS_CLEANUP:
if (iom>0) H5Sclose(iom);
if (iof>0) H5Sclose(iof);
if (mtype>0) H5Tclose(mtype);
SS_LEAVE(buffer);
}