#include #include "h5core/h5_core.h" #include "h5_core_private.h" /*! Write data to dataset. - Open/Create dataset - set hyperslabs for disk and memory via callback functions - Write data - Close dataset */ h5_err_t h5priv_write_dataset_by_name ( h5_file_t* const f, const hid_t loc_id, h5_dsinfo_t* dsinfo, hid_t (*set_memspace)(h5_file_t*,hid_t), hid_t (*set_diskspace)(h5_file_t*,hid_t), const void* const data ) { H5_PRIV_API_ENTER (h5_err_t, "f=%p, loc_id=%d (%s), dsinfo=%p, set_memspace=%p, " "set_diskspace=%p, data=%p", f, loc_id, hdf5_get_objname(loc_id), dsinfo, set_memspace, set_diskspace, data); h5_info ("Writing dataset %s/%s.", hdf5_get_objname (loc_id), dsinfo->name); h5_err_t exists; TRY (exists = hdf5_link_exists (loc_id, dsinfo->name)); if ((exists > 0) && ((f->mode==H5_O_WRONLY) || (f->mode==H5_O_APPEND))) { h5_warn ("Dataset %s/%s already exist.", hdf5_get_objname (loc_id), dsinfo->name); H5_PRIV_API_LEAVE (h5priv_handle_file_mode_error(f->mode)); } /* open/create dataset */ hid_t dset_id; hid_t dataspace_id; hid_t diskspace_id; hid_t memspace_id; if (exists) { /* overwrite dataset */ TRY (dset_id = hdf5_open_dataset (loc_id, dsinfo->name)); TRY (dataspace_id = hdf5_get_dataset_space (dset_id)); TRY (hdf5_set_dataset_extent (dset_id, dsinfo->dims)); /* exten dataset? */ } else { /* create dataset */ TRY (dataspace_id = hdf5_create_dataspace ( dsinfo->rank, dsinfo->dims, dsinfo->max_dims)); TRY (dset_id = hdf5_create_dataset ( loc_id, dsinfo->name, dsinfo->type_id, dataspace_id, dsinfo->create_prop)); } TRY (memspace_id = (*set_memspace)(f, 0)); TRY (diskspace_id = (*set_diskspace)(f, dataspace_id)); #ifdef PARALLEL_IO TRY (h5_start_throttle (f)); #endif TRY (hdf5_write_dataset ( dset_id, dsinfo->type_id, memspace_id, diskspace_id, f->xfer_prop, data)); #ifdef PARALLEL_IO TRY (h5_end_throttle (f)); #endif TRY (hdf5_close_dataspace (diskspace_id)); TRY (hdf5_close_dataspace (memspace_id)); TRY (hdf5_close_dataset (dset_id)); f->empty = 0; H5_PRIV_API_RETURN (H5_SUCCESS); } h5_err_t h5priv_read_dataset ( h5_file_t* const f, hid_t dset_id, h5_dsinfo_t* dsinfo, hid_t (*set_mspace)(h5_file_t*,hid_t), hid_t (*set_dspace)(h5_file_t*,hid_t), void* const data ) { H5_PRIV_API_ENTER (h5_err_t, "f=%p, dset_id=%d (%s), dsinfo=%p, set_mspace=%p, " "set_dspace=%p, data=%p", f, dset_id, hdf5_get_objname(dset_id), dsinfo, set_mspace, set_dspace, data); hid_t mspace_id; hid_t dspace_id; TRY (mspace_id = (*set_mspace)(f, dset_id)); TRY (dspace_id = (*set_dspace)(f, dset_id)); #ifdef PARALLEL_IO TRY (h5_start_throttle (f)); #endif TRY (hdf5_read_dataset ( dset_id, dsinfo->type_id, mspace_id, dspace_id, f->xfer_prop, data)); #ifdef PARALLEL_IO TRY (h5_end_throttle (f)); #endif TRY (hdf5_close_dataspace (dspace_id)); TRY (hdf5_close_dataspace (mspace_id)); H5_PRIV_API_RETURN (H5_SUCCESS); } h5_err_t h5priv_read_dataset_by_name ( h5_file_t* const f, hid_t loc_id, h5_dsinfo_t* dsinfo, hid_t (*set_mspace)(h5_file_t*,hid_t), hid_t (*set_dspace)(h5_file_t*,hid_t), void* const data ) { H5_PRIV_API_ENTER (h5_err_t, "f=%p, loc_id=%d (%s), dsinfo=%p, " "set_mpace=%p, set_dspace=%p, data=%p", f, loc_id, hdf5_get_objname(loc_id), dsinfo, set_mspace, set_dspace, data); hid_t dset_id; TRY (dset_id = hdf5_open_dataset (loc_id, dsinfo->name)); TRY (h5priv_read_dataset (f, dset_id, dsinfo, set_mspace, set_dspace, data)); TRY (hdf5_close_dataset (dset_id)); H5_PRIV_API_RETURN (H5_SUCCESS); } h5_err_t h5priv_close_step ( h5_file_t* const f ) { H5_PRIV_API_ENTER (h5_err_t, "f=%p", f); if (f->step_gid <= 0) H5_PRIV_API_LEAVE (H5_SUCCESS); TRY (hdf5_close_group (f->step_gid)); f->step_gid = -1; H5_PRIV_API_RETURN (H5_SUCCESS); } h5_err_t h5_set_step ( h5_file_t* const f, /*!< [in] Handle to open file */ const h5_id_t step_idx /*!< [in] Step to set. */ ) { H5_CORE_API_ENTER (h5_err_t, "f=%p, step_idx=%lld", f, (long long)step_idx); TRY (h5priv_close_step (f)); f->step_idx = step_idx; sprintf ( f->step_name, "%s#%0*lld", f->prefix_step_name, f->width_step_idx, (long long) f->step_idx); h5_info ( "Proc[%d]: Open step #%lld for file %lld", f->myproc, (long long)f->step_idx, (long long)(size_t) f); TRY (f->step_gid = h5priv_open_group (is_writable(f), f->file, f->step_name)); H5_CORE_API_RETURN (H5_SUCCESS); } /*! Normalize HDF5 type */ h5_int64_t h5_normalize_h5_type ( hid_t type ) { H5_CORE_API_ENTER (h5_int64_t, "type=%d", type); H5T_class_t tclass; int size; TRY (tclass = H5Tget_class (type)); TRY (size = H5Tget_size (type)); switch (tclass){ case H5T_INTEGER: if (size==8) { H5_CORE_API_LEAVE (H5_INT64_T); } else if (size==4) { H5_CORE_API_LEAVE (H5_INT32_T); } else if (size==2) { H5_CORE_API_LEAVE (H5_INT16_T); } break; case H5T_FLOAT: if ( size==8 ) { H5_CORE_API_LEAVE (H5_FLOAT64_T); } else if ( size==4 ) { H5_CORE_API_LEAVE (H5_FLOAT32_T); } break; case H5T_STRING: H5_CORE_API_LEAVE (H5_STRING_T); default: ; /* NOP */ } H5_CORE_API_RETURN (h5_warn ("Unknown type %d", (int)type)); } h5_int64_t h5_get_dataset_type( const hid_t group_id, const char* dset_name ) { H5_CORE_API_ENTER (h5_int64_t, "group_id=%d, dset_name='%s'", group_id, dset_name); hid_t dset_id; hid_t hdf5_type; h5_int64_t type; TRY (dset_id = hdf5_open_dataset (group_id, dset_name)); TRY (hdf5_type = hdf5_get_dataset_type (dset_id)); TRY (type = h5_normalize_h5_type (hdf5_type)); TRY (hdf5_close_type (hdf5_type)); TRY (hdf5_close_dataset (dset_id)); H5_CORE_API_RETURN (type); } h5_err_t h5_has_step ( h5_file_t* const f, /*!< [in] Handle to open file */ const h5_id_t step_idx /*!< [in] Step number to query */ ) { H5_CORE_API_ENTER (h5_err_t, "f=%p, step_idx=%lld", f, (long long)step_idx); char name[2*H5_STEPNAME_LEN]; sprintf (name, "%s#%0*lld", f->prefix_step_name, f->width_step_idx, (long long)step_idx); H5_CORE_API_RETURN (hdf5_link_exists(f->file, name)); } h5_err_t h5_normalize_dataset_name ( const char *name, char *name2 ) { H5_CORE_API_ENTER (h5_err_t, "name='%s', name2='%s'", name, name2); if ( strlen(name) > H5_DATANAME_LEN-1 ) { strncpy ( name2, name, H5_DATANAME_LEN-1 ); name2[H5_DATANAME_LEN-1] = '\0'; h5_warn ("Truncated name '%s' to '%s'.", name, name2); } else { strcpy ( name2, name ); } if ( strcmp( name2, H5_BLOCKNAME ) == 0 ) { H5_CORE_API_LEAVE ( h5_error ( H5_ERR_INVAL, "Can't create dataset or field with name '%s'" " because it is reserved by H5Block.", H5_BLOCKNAME)); } H5_CORE_API_RETURN (H5_SUCCESS); } #ifdef PARALLEL_IO h5_err_t h5_set_throttle ( h5_file_t* const f, const int factor ) { H5_CORE_API_ENTER (h5_err_t, "f=%p, factor=%d", f, factor); if ( (f->mode & H5_VFD_INDEPENDENT) || (f->mode & H5_VFD_MPIPOSIX) ) { f->throttle = factor; h5_info ("Throttling enabled with factor = %d", f->throttle ); } else { h5_warn ("Throttling is only permitted with the MPI-POSIX " "or MPI-IO Independent VFD." ); } H5_CORE_API_RETURN (H5_SUCCESS); } h5_err_t h5_start_throttle ( h5_file_t* const f ) { H5_CORE_API_ENTER (h5_err_t, "f=%p", f); if (f->throttle > 0) { int token = 1; h5_info ("Throttling with factor = %d", f->throttle); if (f->myproc / f->throttle > 0) { h5_debug ("[%d] throttle: waiting on token from %d", f->myproc, f->myproc - f->throttle); // wait to receive token before continuing with read TRY( h5priv_mpi_recv( &token, 1, MPI_INT, f->myproc - f->throttle, // receive from previous proc f->myproc, // use this proc id as message tag f->comm ) ); } h5_debug ("[%d] throttle: received token", f->myproc); } H5_CORE_API_RETURN (H5_SUCCESS); } h5_err_t h5_end_throttle ( h5_file_t* const f ) { H5_CORE_API_ENTER (h5_err_t, "f=%p", f); if (f->throttle > 0) { int token; if (f->myproc + f->throttle < f->nprocs) { // pass token to next proc h5_debug ("[%d] throttle: passing token to %d", f->myproc, f->myproc + f->throttle); TRY (h5priv_mpi_send( &token, 1, MPI_INT, f->myproc + f->throttle, // send to next proc f->myproc + f->throttle, // use the id of the target as tag f->comm )); } } H5_CORE_API_RETURN (H5_SUCCESS); } #endif // PARALLEL_IO