From 17259643fec10d53a46311b60e4010a425acee45 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Fri, 10 Feb 2017 12:43:44 -0600 Subject: Implement attribute read/write. Added examples for this. Added optional snapshot parameter to h5dsm_file_open.c. Other minor fixes/cleanup. --- examples/h5dsm_attr_read.c | 106 +++++++++++++++++++++++ examples/h5dsm_attr_write.c | 100 +++++++++++++++++++++ examples/h5dsm_dset_read.c | 2 +- examples/h5dsm_file_open.c | 13 ++- src/H5VLdaosm.c | 206 ++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 415 insertions(+), 12 deletions(-) create mode 100644 examples/h5dsm_attr_read.c create mode 100644 examples/h5dsm_attr_write.c diff --git a/examples/h5dsm_attr_read.c b/examples/h5dsm_attr_read.c new file mode 100644 index 0000000..8909535 --- /dev/null +++ b/examples/h5dsm_attr_read.c @@ -0,0 +1,106 @@ +#include "h5dsm_example.h" +#include + +int main(int argc, char *argv[]) { + uuid_t pool_uuid; + char *pool_grp = NULL; + hid_t file = -1, obj = -1, attr = -1, fapl = -1; + int buf[4][6]; + int i, j; + H5VL_daosm_snap_id_t snap_id; + + (void)MPI_Init(&argc, &argv); + (void)daos_init(); + + /* Seed random number generator */ + srand(time(NULL)); + + if(argc < 6 || argc > 7) + PRINTF_ERROR("argc must be 6 or 7\n"); + + /* Parse UUID */ + if(0 != uuid_parse(argv[1], pool_uuid)) + ERROR; + + /* Set up FAPL */ + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + ERROR; + if(H5Pset_fapl_daosm(fapl, MPI_COMM_WORLD, MPI_INFO_NULL, pool_uuid, pool_grp) < 0) + ERROR; + + /* Open snapshot if specified */ + if(argc == 7) { + snap_id = (H5VL_daosm_snap_id_t)atoi(argv[6]); + printf("Opening snapshot %llu\n", (long long unsigned)snap_id); + if(H5Pset_daosm_snap_open(fapl, snap_id) < 0) + ERROR; + } /* end if */ + + /* Open file */ + if((file = H5Fopen(argv[2], H5F_ACC_RDONLY, fapl)) < 0) + ERROR; + + /* Open object */ + if(!strcmp(argv[3], "-d") || !strcmp(argv[3], "-D")) { + if((obj = H5Dopen2(file, argv[4], H5P_DEFAULT)) < 0) + ERROR; + } + else { + if(strcmp(argv[3], "-g") && strcmp(argv[3], "-G")) + PRINTF_ERROR("argv[3] must be -d, -D, -g, or -G\n"); + if((obj = H5Gopen2(file, argv[4], H5P_DEFAULT)) < 0) + ERROR; + } + + /* Open attribute */ + if((attr = H5Aopen(obj, argv[5], H5P_DEFAULT)) < 0) + ERROR; + + printf("Reading attribute\n"); + + /* Initialize buffer */ + for(i = 0; i < 4; i++) + for(j = 0; j < 6; j++) + buf[i][j] = -1; + + /* Read data */ + if(H5Aread(attr, H5T_NATIVE_INT, buf) < 0) + ERROR; + + /* Print buffer */ + printf("Successfully read data. Buffer is:\n"); + for(i = 0; i < 4; i++) { + for(j = 0; j < 6; j++) + printf("%d ", buf[i][j]); + printf("\n"); + } + + /* Close */ + if(H5Aclose(attr) < 0) + ERROR; + if(H5Oclose(obj) < 0) + ERROR; + if(H5Fclose(file) < 0) + ERROR; + if(H5Pclose(fapl) < 0) + ERROR; + + printf("Success\n"); + + (void)daos_fini(); + (void)MPI_Finalize(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Aclose(attr); + H5Oclose(obj); + H5Fclose(file); + H5Pclose(fapl); + } H5E_END_TRY; + + (void)daos_fini(); + (void)MPI_Finalize(); + return 1; +} + diff --git a/examples/h5dsm_attr_write.c b/examples/h5dsm_attr_write.c new file mode 100644 index 0000000..15f5ad1 --- /dev/null +++ b/examples/h5dsm_attr_write.c @@ -0,0 +1,100 @@ +#include "h5dsm_example.h" +#include + +int main(int argc, char *argv[]) { + uuid_t pool_uuid; + char *pool_grp = NULL; + hid_t file = -1, obj = -1, attr = -1, fapl = -1; + H5VL_daosm_snap_id_t snap_id; + int buf[4][6]; + int i, j; + + (void)MPI_Init(&argc, &argv); + (void)daos_init(); + + /* Seed random number generator */ + srand(time(NULL)); + + if(argc < 6 || argc > 7) + PRINTF_ERROR("argc must be 6 or 7\n"); + + /* Parse UUID */ + if(0 != uuid_parse(argv[1], pool_uuid)) + ERROR; + + /* Set up FAPL */ + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + ERROR; + if(H5Pset_fapl_daosm(fapl, MPI_COMM_WORLD, MPI_INFO_NULL, pool_uuid, pool_grp) < 0) + ERROR; + + /* Open file */ + if((file = H5Fopen(argv[2], H5F_ACC_RDWR, fapl)) < 0) + ERROR; + + /* Open object */ + if(!strcmp(argv[3], "-d") || !strcmp(argv[3], "-D")) { + if((obj = H5Dopen2(file, argv[4], H5P_DEFAULT)) < 0) + ERROR; + } + else { + if(strcmp(argv[3], "-g") && strcmp(argv[3], "-G")) + PRINTF_ERROR("argv[3] must be -d, -D, -g, or -G\n"); + if((obj = H5Gopen2(file, argv[4], H5P_DEFAULT)) < 0) + ERROR; + } + + /* Open attribute */ + if((attr = H5Aopen(obj, argv[5], H5P_DEFAULT)) < 0) + ERROR; + + /* Fill and print buffer */ + printf("Writing data. Buffer is:\n"); + for(i = 0; i < 4; i++) { + for(j = 0; j < 6; j++) { + buf[i][j] = rand() % 10; + printf("%d ", buf[i][j]); + } + printf("\n"); + } + + /* Write data */ + if(H5Awrite(attr, H5T_NATIVE_INT, buf) < 0) + ERROR; + + /* Save snapshot if requested */ + if(argc == 7) { + if(H5VLdaosm_snap_create(file, &snap_id) < 0) + ERROR; + printf("Saved snapshot: snap_id = %llu\n", (long long unsigned)snap_id); + } /* end if */ + + /* Close */ + if(H5Aclose(attr) < 0) + ERROR; + if(H5Oclose(obj) < 0) + ERROR; + if(H5Fclose(file) < 0) + ERROR; + if(H5Pclose(fapl) < 0) + ERROR; + + printf("Success\n"); + + (void)daos_fini(); + (void)MPI_Finalize(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Aclose(attr); + H5Oclose(obj); + H5Fclose(file); + H5Pclose(fapl); + } H5E_END_TRY; + + (void)daos_fini(); + (void)MPI_Finalize(); + return 1; +} + diff --git a/examples/h5dsm_dset_read.c b/examples/h5dsm_dset_read.c index 18d41d8..21a811a 100644 --- a/examples/h5dsm_dset_read.c +++ b/examples/h5dsm_dset_read.c @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) { if((dset = H5Dopen2(file, argv[3], H5P_DEFAULT)) < 0) ERROR; - printf("Reading dataset"); + printf("Reading dataset\n"); /* Initialize buffer */ for(i = 0; i < 4; i++) diff --git a/examples/h5dsm_file_open.c b/examples/h5dsm_file_open.c index b3846d0..3a1d399 100644 --- a/examples/h5dsm_file_open.c +++ b/examples/h5dsm_file_open.c @@ -4,12 +4,13 @@ int main(int argc, char *argv[]) { uuid_t pool_uuid; char *pool_grp = NULL; hid_t file = -1, fapl = -1; + H5VL_daosm_snap_id_t snap_id; (void)MPI_Init(&argc, &argv); (void)daos_init(); - if(argc != 3) - PRINTF_ERROR("argc != 3\n"); + if(argc < 3 || argc > 4) + PRINTF_ERROR("argc must be 3 or 4\n"); /* Parse UUID */ if(0 != uuid_parse(argv[1], pool_uuid)) @@ -21,6 +22,14 @@ int main(int argc, char *argv[]) { if(H5Pset_fapl_daosm(fapl, MPI_COMM_WORLD, MPI_INFO_NULL, pool_uuid, pool_grp) < 0) ERROR; + /* Open snapshot if specified */ + if(argc == 4) { + snap_id = (H5VL_daosm_snap_id_t)atoi(argv[3]); + printf("Opening snapshot %llu\n", (long long unsigned)snap_id); + if(H5Pset_daosm_snap_open(fapl, snap_id) < 0) + ERROR; + } /* end if */ + /* Open file */ if((file = H5Fopen_ff(argv[2], H5F_ACC_RDONLY, fapl, NULL)) < 0) ERROR; diff --git a/src/H5VLdaosm.c b/src/H5VLdaosm.c index 5338398..9ee7b3a 100644 --- a/src/H5VLdaosm.c +++ b/src/H5VLdaosm.c @@ -81,10 +81,10 @@ static void *H5VL_daosm_dataset_create(void *_item, static void *H5VL_daosm_dataset_open(void *_item, H5VL_loc_params_t loc_params, const char *name, hid_t dapl_id, hid_t dxpl_id, void **req); static herr_t H5VL_daosm_dataset_read(void *_dset, hid_t mem_type_id, - hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, void *buf, + hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, void *buf, void **req); static herr_t H5VL_daosm_dataset_write(void *_dset, hid_t mem_type_id, - hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, + hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req); /*static herr_t H5VL_daosm_dataset_specific(void *_dset, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);*/ @@ -102,10 +102,10 @@ static void *H5VL_daosm_attribute_create(void *_obj, hid_t aapl_id, hid_t dxpl_id, void **req); static void *H5VL_daosm_attribute_open(void *_obj, H5VL_loc_params_t loc_params, const char *name, hid_t aapl_id, hid_t dxpl_id, void **req); -/*static herr_t H5VL_daosm_attribute_read(void *_attr, hid_t mem_type_id, - hid_t plist_id, void *buf, void **req); +static herr_t H5VL_daosm_attribute_read(void *_attr, hid_t mem_type_id, + void *buf, hid_t dxpl_id, void **req); static herr_t H5VL_daosm_attribute_write(void *_attr, hid_t mem_type_id, - hid_t plist_id, const void *buf, void **req);*/ + const void *buf, hid_t dxpl_id, void **req); static herr_t H5VL_daosm_attribute_close(void *_attr, hid_t dxpl_id, void **req); @@ -155,8 +155,8 @@ static H5VL_class_t H5VL_daosm_g = { { /* attribute_cls */ H5VL_daosm_attribute_create, /* create */ H5VL_daosm_attribute_open, /* open */ - NULL,//H5VL_iod_attribute_read, /* read */ - NULL,//H5VL_iod_attribute_write, /* write */ + H5VL_daosm_attribute_read, /* read */ + H5VL_daosm_attribute_write, /* write */ NULL,//H5VL_iod_attribute_get, /* get */ NULL,//H5VL_iod_attribute_specific, /* specific */ NULL, /* optional */ @@ -2799,8 +2799,8 @@ done: */ static herr_t H5VL_daosm_dataset_write(void *_dset, hid_t H5_ATTR_UNUSED mem_type_id, - hid_t H5_ATTR_UNUSED mem_space_id, hid_t H5_ATTR_UNUSED file_space_id, - hid_t H5_ATTR_UNUSED dxpl_id, const void *buf, void H5_ATTR_UNUSED **req) + hid_t mem_space_id, hid_t file_space_id, hid_t H5_ATTR_UNUSED dxpl_id, + const void *buf, void H5_ATTR_UNUSED **req) { H5VL_daosm_dset_t *dset = (H5VL_daosm_dset_t *)_dset; int ndims; @@ -3419,6 +3419,194 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL_daosm_attribute_read + * + * Purpose: Reads raw data from an attribute into a buffer. + * + * Return: Success: 0 + * Failure: -1, attribute not read. + * + * Programmer: Neil Fortner + * February, 2017 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_daosm_attribute_read(void *_attr, hid_t H5_ATTR_UNUSED mem_type_id, + void *buf, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5VL_daosm_attr_t *attr = (H5VL_daosm_attr_t *)_attr; + int ndims; + hsize_t dim[H5S_MAX_RANK]; + size_t akey_len; + daos_key_t dkey; + char *akey = NULL; + daos_vec_iod_t iod; + daos_recx_t recx; + daos_sg_list_t sgl; + daos_iov_t sg_iov; + char attr_key[] = H5VL_DAOSM_ATTR_KEY; + size_t type_size; + uint64_t chunk_size; + int ret; + int i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* Get dataspace extent */ + if((ndims = H5Sget_simple_extent_ndims(attr->space_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get number of dimensions") + if(ndims != H5Sget_simple_extent_dims(attr->space_id, dim, NULL)) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get dimensions") + + /* Get datatype size */ + if((type_size = H5Tget_size(attr->type_id)) == 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype size") + + /* Calculate chunk size */ + chunk_size = (uint64_t)1; + for(i = 0; i < ndims; i++) + chunk_size *= (uint64_t)dim[i]; + + /* Set up operation to read data */ + /* Set up dkey */ + daos_iov_set(&dkey, attr_key, (daos_size_t)(sizeof(attr_key) - 1)); + + /* Create akey string (prefix "V-") */ + akey_len = HDstrlen(attr->name) + 2; + if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey") + akey[0] = 'V'; + akey[1] = '-'; + (void)HDstrcpy(akey + 2, attr->name); + + /* Set up recx */ + recx.rx_rsize = (uint64_t)type_size; + recx.rx_idx = (uint64_t)0; + recx.rx_nr = chunk_size; + + /* Set up iod */ + HDmemset(&iod, 0, sizeof(iod)); + daos_iov_set(&iod.vd_name, (void *)akey, (daos_size_t)akey_len); + daos_csum_set(&iod.vd_kcsum, NULL, 0); + iod.vd_nr = 1u; + iod.vd_recxs = &recx; + + /* Set up sgl */ + daos_iov_set(&sg_iov, (void *)buf, (daos_size_t)(chunk_size * (uint64_t)type_size)); + sgl.sg_nr.num = 1; + sgl.sg_iovs = &sg_iov; + + /* Read data from attribute */ + if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/))) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret) + +done: + /* Free memory */ + akey = (char *)H5MM_xfree(akey); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_daosm_attribute_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_daosm_attribute_write + * + * Purpose: Writes raw data from a buffer into an attribute. + * + * Return: Success: 0 + * Failure: -1, attribute not written. + * + * Programmer: Neil Fortner + * February, 2017 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_daosm_attribute_write(void *_attr, hid_t H5_ATTR_UNUSED mem_type_id, + const void *buf, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5VL_daosm_attr_t *attr = (H5VL_daosm_attr_t *)_attr; + int ndims; + hsize_t dim[H5S_MAX_RANK]; + size_t akey_len; + daos_key_t dkey; + char *akey = NULL; + daos_vec_iod_t iod; + daos_recx_t recx; + daos_sg_list_t sgl; + daos_iov_t sg_iov; + char attr_key[] = H5VL_DAOSM_ATTR_KEY; + size_t type_size; + uint64_t chunk_size; + int ret; + int i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* Check for write access */ + if(!(attr->item.file->flags & H5F_ACC_RDWR)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "no write intent on file") + + /* Get dataspace extent */ + if((ndims = H5Sget_simple_extent_ndims(attr->space_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get number of dimensions") + if(ndims != H5Sget_simple_extent_dims(attr->space_id, dim, NULL)) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get dimensions") + + /* Get datatype size */ + if((type_size = H5Tget_size(attr->type_id)) == 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype size") + + /* Calculate chunk size */ + chunk_size = (uint64_t)1; + for(i = 0; i < ndims; i++) + chunk_size *= (uint64_t)dim[i]; + + /* Set up operation to write data */ + /* Set up dkey */ + daos_iov_set(&dkey, attr_key, (daos_size_t)(sizeof(attr_key) - 1)); + + /* Create akey string (prefix "V-") */ + akey_len = HDstrlen(attr->name) + 2; + if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey") + akey[0] = 'V'; + akey[1] = '-'; + (void)HDstrcpy(akey + 2, attr->name); + + /* Set up recx */ + recx.rx_rsize = (uint64_t)type_size; + recx.rx_idx = (uint64_t)0; + recx.rx_nr = chunk_size; + + /* Set up iod */ + HDmemset(&iod, 0, sizeof(iod)); + daos_iov_set(&iod.vd_name, (void *)akey, (daos_size_t)akey_len); + daos_csum_set(&iod.vd_kcsum, NULL, 0); + iod.vd_nr = 1u; + iod.vd_recxs = &recx; + + /* Set up sgl */ + daos_iov_set(&sg_iov, (void *)buf, (daos_size_t)(chunk_size * (uint64_t)type_size)); + sgl.sg_nr.num = 1; + sgl.sg_iovs = &sg_iov; + + /* Write data to attribute */ + if(0 != (ret = daos_obj_update(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*event*/))) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't write data to attribute: %d", ret) + +done: + /* Free memory */ + akey = (char *)H5MM_xfree(akey); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_daosm_attribute_write() */ + + +/*------------------------------------------------------------------------- * Function: H5VL_daosm_attribute_close * * Purpose: Closes a daos-m HDF5 attribute. -- cgit v0.12