From a6c64046431266a313aedb2486d838d449661508 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Mon, 14 Nov 2016 15:21:52 -0600 Subject: Initial implementation of dataset create/open/close, transactions. Not working on boro, though it is unclear if that is due to a pug in this code or in daos. --- src/H5F.c | 26 +++ src/H5FF.c | 323 +++++++++++++++++++++++++++++++++++ src/H5FFmodule.h | 34 ++++ src/H5FFprivate.h | 54 ++++++ src/H5FFpublic.h | 71 ++++++++ src/H5Fprivate.h | 1 + src/H5Ipublic.h | 1 + src/H5Pdxpl.c | 7 + src/H5TR.c | 382 +++++++++++++++++++++++++++++++++++++++++ src/H5TRmodule.h | 34 ++++ src/H5TRprivate.h | 57 +++++++ src/H5TRpublic.h | 65 +++++++ src/H5VLdaosm.c | 501 +++++++++++++++++++++++++++++++++++++++++++++++++----- src/H5VLdaosm.h | 33 +++- src/H5private.h | 4 + src/Makefile.am | 6 +- src/hdf5.h | 3 +- 17 files changed, 1550 insertions(+), 52 deletions(-) create mode 100644 src/H5FF.c create mode 100755 src/H5FFmodule.h create mode 100755 src/H5FFprivate.h create mode 100644 src/H5FFpublic.h create mode 100644 src/H5TR.c create mode 100755 src/H5TRmodule.h create mode 100755 src/H5TRprivate.h create mode 100755 src/H5TRpublic.h diff --git a/src/H5F.c b/src/H5F.c index ec2e388..b19cf9b 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -82,6 +82,32 @@ static const H5I_class_t H5I_FILE_CLS[1] = {{ }}; +/*------------------------------------------------------------------------- + * Function: H5F_init + * + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * July 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_init() */ + + /*-------------------------------------------------------------------------- NAME H5F__init_package -- Initialize interface-specific information diff --git a/src/H5FF.c b/src/H5FF.c new file mode 100644 index 0000000..b65b200 --- /dev/null +++ b/src/H5FF.c @@ -0,0 +1,323 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Wrappers around existing HDF5 to support Exascale FastForward + * functionality. + */ + + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5FFmodule.h" /* This source code file is part of the H5FF module */ + +#define H5A_FRIEND /*suppress error about including H5Apkg */ +#define H5D_FRIEND /*suppress error about including H5Dpkg */ +#define H5F_FRIEND /*suppress error about including H5Fpkg */ +#define H5G_FRIEND /*suppress error about including H5Gpkg */ +#define H5T_FRIEND /*suppress error about including H5Tpkg */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +//#include "H5Apkg.h" /* Attribute access */ +#include "H5Dpkg.h" /* Dataset access */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5FFprivate.h" /* FastForward wrappers */ +//#include "H5Gpkg.h" /* Group access */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ +//#include "H5Tpkg.h" /* Datatype access */ + +#include "H5VLdaosm.h" /* IOD plugin - tmp */ + +#ifdef H5_HAVE_EFF +/****************/ +/* Local Macros */ +/****************/ +H5FL_EXTERN(H5RC_t); + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Package initialization variable */ +hbool_t H5_PKG_INIT_VAR = FALSE; + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +herr_t +H5FF__init_package(void) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + if(H5F_init() < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init file interface") + + /*if(H5G_init() < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init group interface") + + if(H5D_init() < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init dataset interface") + + if(H5A_init() < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init attribute interface") + + if(H5M_init() < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init map interface") + + if(H5RC_init() < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init map interface") DSMINC*/ + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5FF__init_package() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dcreate_ff + * + * Purpose: Asynchronous wrapper around H5Dcreate(). + * + * Return: Success: The placeholder ID for a new dataset. When + * the asynchronous operation completes, this + * ID will transparently be modified to be a + * "normal" ID. + * Failure: FAIL + * + * Programmer: Neil Fortner + * Monday, November 7, 2016 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dcreate_ff(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, + hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, hid_t trans_id, + hid_t H5_ATTR_UNUSED estack_id) +{ + void *dset = NULL; /* dset token from VOL plugin */ + H5VL_object_t *obj = NULL; /* object token of loc_id */ + hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */ + H5VL_loc_params_t loc_params; + H5P_genplist_t *plist; /* Property list pointer */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE9("i", "i*siiiiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id, + dapl_id, trans_id, estack_id); + + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + + /* Get correct property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + else + if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list") + + /* Get correct property list */ + if(H5P_DEFAULT == dcpl_id) + dcpl_id = H5P_DATASET_CREATE_DEFAULT; + else + if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID") + + /* Get correct property list */ + if(H5P_DEFAULT == dapl_id) + dapl_id = H5P_DATASET_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* set creation properties */ + if(H5P_set(plist, H5VL_PROP_DSET_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5VL_PROP_DSET_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + if(H5P_set(plist, H5VL_PROP_DSET_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* store the transaction ID in the dxpl */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set property value for trans_id") + + /* get the location object */ + if(NULL == (obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Create the dataset through the VOL */ + if(NULL == (dset = H5VL_dataset_create(obj->vol_obj, loc_params, obj->vol_info->vol_cls, + name, dcpl_id, dapl_id, dxpl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") + + /* Get an atom for the dataset */ + if((ret_value = H5VL_register_id(H5I_DATASET, dset, obj->vol_info, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + +done: + if (ret_value < 0 && dset) + if(H5VL_dataset_close (dset, obj->vol_info->vol_cls, dxpl_id, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") + FUNC_LEAVE_API(ret_value) +} /* end H5Dcreate_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dopen_ff + * + * Purpose: Asynchronous wrapper around H5Dopen(). + * + * Return: Success: The placeholder ID for a dataset. When + * the asynchronous operation completes, this + * ID will transparently be modified to be a + * "normal" ID. + * Failure: FAIL + * + * Programmer: Neil Fortner + * Monday, November 7, 2016 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dopen_ff(hid_t loc_id, const char *name, hid_t dapl_id, hid_t trans_id, hid_t H5_ATTR_UNUSED estack_id) +{ + void *dset = NULL; /* dset token from VOL plugin */ + H5VL_object_t *obj = NULL; /* object token of loc_id */ + hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */ + H5P_genplist_t *plist; /* Property list pointer */ + H5VL_loc_params_t loc_params; + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("i", "i*siii", loc_id, name, dapl_id, trans_id, estack_id); + + /* Check args */ + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + + /* Get correct property list */ + if(H5P_DEFAULT == dapl_id) + dapl_id = H5P_DATASET_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the location object */ + if(NULL == (obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* store the transaction ID in the dxpl */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set property value for trans_id") + + /* Create the dataset through the VOL */ + if(NULL == (dset = H5VL_dataset_open(obj->vol_obj, loc_params, obj->vol_info->vol_cls, name, + dapl_id, dxpl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + + /* Get an atom for the dataset */ + if((ret_value = H5VL_register_id(H5I_DATASET, dset, obj->vol_info, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + +done: + if (ret_value < 0 && dset) + if(H5VL_dataset_close (dset, obj->vol_info->vol_cls, dxpl_id, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") + FUNC_LEAVE_API(ret_value) +} /* end H5Dopen_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dclose_ff + * + * Purpose: Closes access to a dataset (DATASET_ID) and releases + * resources used by it. It is illegal to subsequently use that + * same dataset ID in calls to other dataset functions. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Monday, November 7, 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dclose_ff(hid_t dset_id, hid_t H5_ATTR_UNUSED estack_id) +{ + H5VL_object_t *dset; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ii", dset_id, estack_id); + + /* Check args */ + if(NULL == (dset = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + + /* + * Decrement the counter on the dataset. It will be freed if the count + * reaches zero. + * + * Pass in TRUE for the 3rd parameter to tell the function to remove + * dataset's ID even though the freeing function might fail. Please + * see the comments in H5I_dec_ref for details. (SLU - 2010/9/7) + */ + if(H5I_dec_app_ref_always_close(dset_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dclose_ff() */ + +#endif /* H5_HAVE_EFF */ + diff --git a/src/H5FFmodule.h b/src/H5FFmodule.h new file mode 100755 index 0000000..93a1d05 --- /dev/null +++ b/src/H5FFmodule.h @@ -0,0 +1,34 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi + * Ocotber 2015 + * + * Purpose: This file contains declarations which define macros for the + * H5FF package. Including this header means that the source file + * is part of the H5FF package. + */ +#ifndef _H5FFmodule_H +#define _H5FFmodule_H + +/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error + * reporting macros. + */ +#define H5FF_MODULE +#define H5_MY_PKG H5FF +#define H5_MY_PKG_ERR H5E_F +#define H5_MY_PKG_INIT YES + +#endif /* _H5FFmodule_H */ diff --git a/src/H5FFprivate.h b/src/H5FFprivate.h new file mode 100755 index 0000000..cfbb49e --- /dev/null +++ b/src/H5FFprivate.h @@ -0,0 +1,54 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains private information about the H5FF module + */ +#ifndef _H5FFprivate_H +#define _H5FFprivate_H + +/* Include package's public header */ +#include "H5FFpublic.h" + +/* Private headers needed by this file */ +#include "H5private.h" /* Generic Functions */ +#include "H5VLdaosm.h" /* DAOS-M VOL plugin */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/* DXPL property to store the transaction ID from the FF wrappers */ +#define H5VL_TRANS_ID "transaction_id" + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/******************************/ +/* Library Private Prototypes */ +/******************************/ + +#ifdef H5_HAVE_EFF + +#endif /* H5_HAVE_EFF */ + +#endif /* _H5FFprivate_H */ + diff --git a/src/H5FFpublic.h b/src/H5FFpublic.h new file mode 100644 index 0000000..b6585ae --- /dev/null +++ b/src/H5FFpublic.h @@ -0,0 +1,71 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains function prototypes for each exported function in the + * H5FF module. + */ +#ifndef _H5FFpublic_H +#define _H5FFpublic_H + +/* System headers needed by this file */ + +/* Public headers needed by this file */ +#include "H5VLpublic.h" /* Public VOL header file */ + +/*****************/ +/* Public Macros */ +/*****************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define H5_HAVE_EFF 1 /* DSMINC */ + +#ifdef H5_HAVE_EFF + +/*******************/ +/* Public Typedefs */ +/*******************/ + +/********************/ +/* Public Variables */ +/********************/ + +/*********************/ +/* Public Prototypes */ +/*********************/ + +/* API wrappers */ +/*H5_DLL hid_t H5Fcreate_ff(const char *filename, unsigned flags, hid_t fcpl, + hid_t fapl, hid_t estack_id); +H5_DLL hid_t H5Fopen_ff(const char *filename, unsigned flags, hid_t fapl_id, + hid_t *rcxt_id, hid_t estack_id); +H5_DLL herr_t H5Fclose_ff(hid_t file_id, hbool_t persist_flag, hid_t estack_id);*/ +H5_DLL hid_t H5Dcreate_ff(hid_t loc_id, const char *name, hid_t type_id, + hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, hid_t trans_id, + hid_t estack_id); +H5_DLL hid_t H5Dopen_ff(hid_t loc_id, const char *name, hid_t dapl_id, + hid_t trans_id, hid_t estack_id); +H5_DLL herr_t H5Dclose_ff(hid_t dset_id, hid_t estack_id); + +#endif /* H5_HAVE_EFF */ + +#ifdef __cplusplus +} +#endif + +#endif /* _H5FFpublic_H */ + diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 049035a..6936cc6 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -618,6 +618,7 @@ typedef struct H5F_block_t { /* Private functions */ +H5_DLL herr_t H5F_init(void); H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id); H5_DLL herr_t H5F_try_close(H5F_t *f); diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index e4f5abc..6c823b7 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -45,6 +45,7 @@ typedef enum H5I_type_t { H5I_REFERENCE, /*type ID for Reference objects */ H5I_VFL, /*type ID for virtual file layer */ H5I_VOL, /*type ID for virtual object layer */ + H5I_TR, /*type ID for Transaction objects */ H5I_GENPROP_CLS, /*type ID for generic property list classes */ H5I_GENPROP_LST, /*type ID for generic property lists */ H5I_ERROR_CLASS, /*type ID for error classes */ diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index 9353094..df80725 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -39,6 +39,7 @@ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5FDprivate.h" /* File drivers */ +#include "H5FFprivate.h" /* Fast Forward routines */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Ppkg.h" /* Property lists */ @@ -315,6 +316,7 @@ static const H5FD_dxpl_type_t H5D_dxpl_type_g = H5FD_NOIO_DXPL; /* Default value static herr_t H5P__dxfr_reg_prop(H5P_genclass_t *pclass) { + hid_t trans_id = FAIL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -506,6 +508,11 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the transaction ID property*/ + if(H5P_register_real(pclass, H5VL_TRANS_ID, sizeof(hid_t), &trans_id, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + #ifdef H5_DEBUG_BUILD /* Register the dxpl IO type property */ if(H5P_register_real(pclass, H5FD_DXPL_TYPE_NAME, H5FD_DXPL_TYPE_SIZE, &H5D_dxpl_type_g, diff --git a/src/H5TR.c b/src/H5TR.c new file mode 100644 index 0000000..cfee25f --- /dev/null +++ b/src/H5TR.c @@ -0,0 +1,382 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi + * August, 2013 + * + * Purpose: Transaction APIs to support Exascale FastForward + * functionality. + * + */ + + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5TRmodule.h" /* This source code file is part of the H5TR module */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5TRprivate.h" /* Transactions */ +#include "H5VLprivate.h" /* VOL plugins */ + +#ifdef H5_HAVE_EFF + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Package initialization variable */ +hbool_t H5_PKG_INIT_VAR = FALSE; + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5TR_t struct */ +H5FL_DEFINE(H5TR_t); + +/* Dataspace ID class */ +static const H5I_class_t H5I_TR_CLS[1] = {{ + H5I_TR, /* ID class value */ + 0, /* Class flags */ + 2, /* # of reserved IDs for class */ + (H5I_free_t)H5TR_close /* Callback routine for closing objects of this class */ +}}; + + + +/*------------------------------------------------------------------------- + * Function: H5TR_init + * + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * August 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5TR_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5TR_init() */ + + +/*-------------------------------------------------------------------------- +NAME + H5TR__init_package -- Initialize interface-specific information +USAGE + herr_t H5TR__init_package() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. + +--------------------------------------------------------------------------*/ +herr_t +H5TR__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Initialize the atom group for the TR IDs */ + if(H5I_register_type(H5I_TR_CLS) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize interface") + + H5_PKG_INIT_VAR = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5TR__init_package() */ + + +/*-------------------------------------------------------------------------- + NAME + H5TR_term_package + PURPOSE + Terminate various H5TR objects + USAGE + void H5TR_term_package() + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Release the atom group and any other resources allocated. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Can't report errors... + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5TR_term_package(void) +{ + int n = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if(H5_PKG_INIT_VAR) { + if(H5I_nmembers(H5I_TR) > 0) { + (void)H5I_clear_type(H5I_TR, FALSE, FALSE); + n++; /*H5I*/ + } /* end if */ + else { + n += (H5I_dec_type_ref(H5I_TR) > 0); + + /* Mark closed */ + if(0 == n) + H5_PKG_INIT_VAR = FALSE; + } /* end else */ + } /* end if */ + + FUNC_LEAVE_NOAPI(n) +} /* end H5TR_term_package() */ + + +/*------------------------------------------------------------------------- + * Function: H5TRcreate + * + * Purpose: Wraps an hid_t around a transaction number, a file ID, + * and a read context ID on that file that operations using + * the created transaction will read from. + * + * Return: Success: The ID for a new transaction. + * Failure: FAIL + * + * Programmer: Neil Fortner + * November 2016 + * + *------------------------------------------------------------------------- + */ +hid_t +H5TRcreate(hid_t obj_id, uint64_t trans_num) +{ + H5VL_object_t *obj = NULL; + H5TR_t *tr = NULL; + hid_t ret_value; + + FUNC_ENTER_API(FAIL) + + /* get the location object */ + if(NULL == (obj = H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* create a new transaction object */ + if(NULL == (tr = H5TR_create(obj->vol_obj, obj->vol_info->vol_cls, trans_num))) + HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create transaction object") + + /* Get an atom for the TR */ + if((ret_value = H5I_register(H5I_TR, tr, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize transaction handle") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5TRcreate() */ + + +/*------------------------------------------------------------------------- + * Function: H5TR_create + * + * Purpose: Private version for H5TRcreate. + * + * Return: Success: Transaction struct. + * Failure: NULL + * + * Programmer: Neil Fortner + * November 2016 + * + *------------------------------------------------------------------------- + */ +H5TR_t * +H5TR_create(void *_obj, const H5VL_class_t *vol_cls, daos_epoch_t epoch) +{ + H5VL_daosm_obj_t *obj = (H5VL_daosm_obj_t *)_obj; + H5TR_t *tr = NULL; + H5TR_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* allocate transaction struct */ + if(NULL == (tr = H5FL_CALLOC(H5TR_t))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate top transaction structure") + + tr->file = obj->file; + tr->epoch = epoch; + tr->vol_cls = vol_cls; + + /* set return value */ + ret_value = tr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5TR_create() */ + +herr_t +H5TRget_trans_num(hid_t trans_id, uint64_t *trans_num) +{ + H5TR_t *tr = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*Il", trans_id, trans_num); + + /* get the TR object */ + if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a transaction ID") + + *trans_num = (uint64_t)tr->epoch; + +done: + FUNC_LEAVE_API(ret_value) +} /* H5TRget_trans_num */ + + +/*------------------------------------------------------------------------- + * Function: H5TRcommit + * + * Purpose: Finishes/Commits a transaction. If rcxt_id is not NULL, + * create a read context from the finished transaction number. + * If the finish fails, the user is still reponsible to call + * H5RCclose() on the rcxt_id and H5TRclose() on the tr_id + * to free resources. + * + * Return: Success: Non-Negative. + * Failure: Negative + * + * Programmer: Neil Fortner + * November 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5TRcommit(hid_t tr_id) +{ + H5TR_t *tr = NULL; + int ret; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", tr_id); + + /* get the TR object */ + if(NULL == (tr = (H5TR_t *)H5I_object_verify(tr_id, H5I_TR))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID") + + /* Commit the transaction */ + if(0 != (ret = daos_epoch_commit(tr->file->coh, tr->epoch, NULL /*state*/, NULL /*event*/))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to commit epoch: %d", ret) + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5TRcommit()*/ + + +/*------------------------------------------------------------------------- + * Function: H5TRclose + * + * Purpose: Closes the specified transaction ID. The ID will no longer be + * valid for accessing the transaction. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * August 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5TRclose(hid_t tr_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", tr_id); + + /* Check args */ + if(NULL == H5I_object_verify(tr_id, H5I_TR)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an transaction ID") + + if(H5I_dec_app_ref(tr_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close transaction") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5TRclose() */ + + +/*------------------------------------------------------------------------- + * Function: H5TR_close + * + * Purpose: Frees the transaction struct. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * November 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5TR_close(H5TR_t *tr) +{ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + tr = H5FL_FREE(H5TR_t, tr); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5TR_close() */ + +#endif /* H5_HAVE_EFF */ + diff --git a/src/H5TRmodule.h b/src/H5TRmodule.h new file mode 100755 index 0000000..db5936f --- /dev/null +++ b/src/H5TRmodule.h @@ -0,0 +1,34 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi + * Ocotber 2015 + * + * Purpose: This file contains declarations which define macros for the + * H5TR package. Including this header means that the source file + * is part of the H5TR package. + */ +#ifndef _H5TRmodule_H +#define _H5TRmodule_H + +/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error + * reporting macros. + */ +#define H5TR_MODULE +#define H5_MY_PKG H5TR +#define H5_MY_PKG_ERR H5E_TRANS +#define H5_MY_PKG_INIT YES + +#endif /* _H5TRmodule_H */ diff --git a/src/H5TRprivate.h b/src/H5TRprivate.h new file mode 100755 index 0000000..0289ebe --- /dev/null +++ b/src/H5TRprivate.h @@ -0,0 +1,57 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains private information about the H5TR module + */ +#ifndef _H5TRprivate_H +#define _H5TRprivate_H + +/* Include package's public header */ +#include "H5TRpublic.h" + +/* Private headers needed by this file */ +#include "H5VLdaosm.h" /* DAOS-M plugin */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + +#ifdef H5_HAVE_EFF + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/* the transaction struct */ +typedef struct H5TR_t { + struct H5VL_daosm_file_t *file; + daos_epoch_t epoch; + const H5VL_class_t *vol_cls; /* the vol plugin class that gnerated this request */ +} H5TR_t; + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/******************************/ +/* Library Private Prototypes */ +/******************************/ +herr_t H5TR_init(void); + +H5_DLL H5TR_t *H5TR_create(void *file, const H5VL_class_t *vol_cls, uint64_t trans_num); +H5_DLL herr_t H5TR_close(H5TR_t *tr); + +#endif /* H5_HAVE_EFF */ +#endif /* _H5TRprivate_H */ diff --git a/src/H5TRpublic.h b/src/H5TRpublic.h new file mode 100755 index 0000000..2c830a7 --- /dev/null +++ b/src/H5TRpublic.h @@ -0,0 +1,65 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains function prototypes for each exported function in the + * H5TR module. + */ +#ifndef _H5TRpublic_H +#define _H5TRpublic_H + +/* System headers needed by this file */ + +/* Public headers needed by this file */ +#include "H5public.h" +#include "H5Ipublic.h" + +/*****************/ +/* Public Macros */ +/*****************/ +#define H5TR_START_NUM_PEERS_NAME "number_of_peers_name" + +/*******************/ +/* Public Typedefs */ +/*******************/ + +/********************/ +/* Public Variables */ +/********************/ + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef H5_HAVE_EFF + +/*********************/ +/* Public Prototypes */ +/*********************/ + +/* API wrappers */ +H5_DLL hid_t H5TRcreate(hid_t obj_id, uint64_t trans_num); +H5_DLL herr_t H5TRget_trans_num(hid_t trans_id, uint64_t *trans_num); +H5_DLL herr_t H5TRcommit(hid_t trans_id); +//H5_DLL herr_t H5TRskip(hid_t file_id, uint64_t start_trans_num, uint64_t count, hid_t estack_id); +//H5_DLL herr_t H5TRabort(hid_t trans_id, hid_t estack_id); +H5_DLL herr_t H5TRclose(hid_t trans_id); + +#endif /* H5_HAVE_EFF */ + +#ifdef __cplusplus +} +#endif +#endif /* _H5TRpublic_H */ diff --git a/src/H5VLdaosm.c b/src/H5VLdaosm.c index de5bdf6..bedba85 100644 --- a/src/H5VLdaosm.c +++ b/src/H5VLdaosm.c @@ -25,9 +25,12 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ #include "H5FDprivate.h" /* File drivers */ +#include "H5FFprivate.h" /* Fast Forward */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ +#include "H5Sprivate.h" /* Dataspaces */ +#include "H5TRprivate.h" /* Transactions */ #include "H5VLprivate.h" /* VOL plugins */ #include "H5VLdaosm.h" /* DAOS-M plugin */ @@ -43,6 +46,21 @@ static void *H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_i //static herr_t H5VL_iod_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); static herr_t H5VL_daosm_file_close(void *file, hid_t dxpl_id, void **req); +/* Group callbacks */ +static herr_t H5VL_daosm_group_close(void *grp, hid_t dxpl_id, void **req); + +/* Dataset callbacks */ +static void *H5VL_daosm_dataset_create(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req); +static void *H5VL_daosm_dataset_open(void *obj, 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, 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, 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); +static herr_t H5VL_daosm_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);*/ +static herr_t H5VL_daosm_dataset_close(void *dt, hid_t dxpl_id, void **req); + /* DAOSM-specific file access properties */ typedef struct H5VL_daosm_fapl_t { MPI_Comm comm; /*communicator */ @@ -53,6 +71,8 @@ typedef struct H5VL_daosm_fapl_t { /* Free list definitions */ H5FL_DEFINE(H5VL_daosm_file_t); +H5FL_DEFINE(H5VL_daosm_group_t); +H5FL_DEFINE(H5VL_daosm_dset_t); /* The DAOS-M VOL plugin struct */ static H5VL_class_t H5VL_daosm_g = { @@ -75,14 +95,14 @@ static H5VL_class_t H5VL_daosm_g = { NULL,//H5VL_iod_attribute_close /* close */ }, { /* dataset_cls */ - NULL,//H5VL_iod_dataset_create, /* create */ - NULL,//H5VL_iod_dataset_open, /* open */ + H5VL_daosm_dataset_create, /* create */ + H5VL_daosm_dataset_open, /* open */ NULL,//H5VL_iod_dataset_read, /* read */ NULL,//H5VL_iod_dataset_write, /* write */ NULL,//H5VL_iod_dataset_get, /* get */ NULL,//H5VL_iod_dataset_specific, /* specific */ NULL, /* optional */ - NULL,//H5VL_iod_dataset_close /* close */ + H5VL_daosm_dataset_close /* close */ }, { /* datatype_cls */ NULL,//H5VL_iod_datatype_commit, /* commit */ @@ -480,8 +500,8 @@ H5VL_daosm_hash128(const char *name, void *hash) *------------------------------------------------------------------------- */ static void * -H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, - hid_t H5_ATTR_UNUSED dxpl_id, void **req) +H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t dxpl_id, void **req) { H5VL_daosm_fapl_t *fa = NULL; H5P_genplist_t *plist = NULL; /* Property list pointer */ @@ -490,6 +510,7 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa daos_iov_t glob; uint64_t gh_sizes[2]; char *gh_buf = NULL; + daos_obj_id_t oid = {0, 0, 0}; hbool_t must_bcast = FALSE; int ret; void *ret_value = NULL; @@ -515,10 +536,16 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa if(NULL == (file = H5FL_CALLOC(H5VL_daosm_file_t))) HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate DAOS-M file struct"); file->glob_md_oh = DAOS_HDL_INVAL; - file->root_oh = DAOS_HDL_INVAL; + file->root_grp = NULL; file->fcpl_id = FAIL; file->fapl_id = FAIL; + /* allocate the root group */ + if(NULL == (file->root_grp = H5FL_CALLOC(H5VL_daosm_group_t))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate root group"); + file->root_grp->obj_oh = DAOS_HDL_INVAL; + file->root_grp->gapl_id = FAIL; + MPI_Comm_rank(fa->comm, &file->my_rank); MPI_Comm_size(fa->comm, &file->num_procs); @@ -527,7 +554,6 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa if(file->my_rank == 0) { daos_epoch_state_t epoch_state; - daos_obj_id_t oid = {0, 0, 0}; /* If there are other processes and we fail we must bcast anyways so they * don't hang */ @@ -535,6 +561,7 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa must_bcast = TRUE; /* Connect to the pool */ + /* TODO: move pool handling to startup/shutdown routines DSMINC */ if(0 != (ret = daos_pool_connect(fa->pool_uuid, NULL/*fa->pool_grp DSMINC*/, NULL /*pool_svc*/, DAOS_PC_RW, &file->poh, NULL /*&file->pool_info*/, NULL /*event*/))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't connect to pool: %d", ret) @@ -571,27 +598,18 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa if(0 != (ret = daos_obj_declare(file->coh, oid, 0, NULL /*oa*/, NULL /*event*/))) HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, "can't create global metadata object: %d", ret) - /* Open global metadata object */ - if(0 != (ret = daos_obj_open(file->glob_md_oh, oid, 0, DAOS_OO_EXCL, &file->glob_md_oh, NULL /*event*/))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open global metadata object: %d", ret) - /* Create root group */ - HDmemset(&oid, 0, sizeof(oid)); - oid.lo = 1; - daos_obj_id_generate(&oid, DAOS_OC_TINY_RW); - if(0 != (ret = daos_obj_declare(file->coh, oid, epoch, NULL /*oa*/, NULL /*event*/))) + file->root_grp->oid.lo = 1; + daos_obj_id_generate(&file->root_grp->oid, DAOS_OC_TINY_RW); + if(0 != (ret = daos_obj_declare(file->coh, file->root_grp->oid, epoch, NULL /*oa*/, NULL /*event*/))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create root group: %d", ret) /* Open root group */ - if(0 != (ret = daos_obj_open(file->root_oh, oid, epoch, DAOS_OO_RW, &file->root_oh, NULL /*event*/))) + if(0 != (ret = daos_obj_open(file->coh, file->root_grp->oid, epoch, DAOS_OO_RW, &file->root_grp->obj_oh, NULL /*event*/))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't open root group: %d", ret) /* Write root group OID to global metadata object DSMINC */ - /* Flush the epoch */ - if(0 != (ret = daos_epoch_flush(file->coh, epoch, NULL /*state*/, NULL /*event*/))) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, NULL, "can't flush epoch: %d", ret) - /* Bcast global handles if there are other processes */ if(file->num_procs > 1) { /* Calculate sizes of global pool and container handles */ @@ -672,16 +690,25 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa if(0 != (ret = daos_cont_global2local(file->poh, glob, &file->coh))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't get local container handle: %d", ret) - /* Leave global md object and root group handles empty for now */ + /* Leave root group handle empty for now */ /* Handle pool_info and container_info DSMINC */ } /* end else */ + /* Open global metadata object */ + if(0 != (ret = daos_obj_open(file->glob_md_oh, oid, 0, DAOS_OO_RW, &file->glob_md_oh, NULL /*event*/))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open global metadata object: %d", ret) + /* Finish setting up file struct */ + file->common.type = H5I_FILE; + file->common.file = file; file->file_name = HDstrdup(name); file->flags = flags; - HDmemset(&file->max_oid, 0, sizeof(file->max_oid)); - file->max_oid.lo = 1; + file->root_grp->common.type = H5I_GROUP; + file->root_grp->common.file = file; + if((file->root_grp->gapl_id = H5Pcopy(H5P_GROUP_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy default gapl"); + file->max_oid = 1; if((file->fcpl_id = H5Pcopy(fcpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fcpl"); if((file->fapl_id = H5Pcopy(fapl_id)) < 0) @@ -697,8 +724,8 @@ done: /* Clean up */ H5MM_xfree(gh_buf); - /* If the operation is synchronous and it failed at the server, or - it failed locally, then cleanup and return fail */ + /* If the operation is synchronous and it failed at the server, or it failed + * locally, then cleanup and return fail */ if(NULL == ret_value) { /* Bcast gh_sizes as '0' if necessary - this will trigger failures in * the other processes so we do not need to do the second bcast. */ @@ -732,8 +759,8 @@ done: *------------------------------------------------------------------------- */ static void * -H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id, - hid_t dxpl_id, void **req) +H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id, + hid_t dxpl_id, void **req) { H5VL_daosm_fapl_t *fa = NULL; H5P_genplist_t *plist = NULL; /* Property list pointer */ @@ -742,6 +769,7 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id, daos_iov_t glob; uint64_t gh_sizes[2]; char *gh_buf = NULL; + daos_obj_id_t oid = {0, 0, 0}; hbool_t must_bcast = FALSE; int ret; void *ret_value = NULL; @@ -758,10 +786,16 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id, if(NULL == (file = H5FL_CALLOC(H5VL_daosm_file_t))) HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate IOD file struct"); file->glob_md_oh = DAOS_HDL_INVAL; - file->root_oh = DAOS_HDL_INVAL; + file->root_grp = NULL; file->fcpl_id = FAIL; file->fapl_id = FAIL; + /* allocate the root group */ + if(NULL == (file->root_grp = H5FL_CALLOC(H5VL_daosm_group_t))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate root group"); + file->root_grp->obj_oh = DAOS_HDL_INVAL; + file->root_grp->gapl_id = FAIL; + MPI_Comm_rank(fa->comm, &file->my_rank); MPI_Comm_size(fa->comm, &file->num_procs); @@ -770,7 +804,6 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id, if(file->my_rank == 0) { daos_epoch_state_t epoch_state; - daos_obj_id_t oid = {0, 0, 0}; /* If there are other processes and we fail we must bcast anyways so they * don't hang */ @@ -794,17 +827,11 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id, if(0 != (ret = daos_epoch_hold(file->coh, &epoch, NULL /*state*/, NULL /*event*/))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't hold epoch: %d", ret) - /* Open global metadata object */ - daos_obj_id_generate(&oid, DAOS_OC_REPLICA_RW); - if(0 != (ret = daos_obj_open(file->glob_md_oh, oid, 0, DAOS_OO_EXCL, &file->glob_md_oh, NULL /*event*/))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open global metadata object: %d", ret) - /* Open root group */ /* Read root group OID from global metadata object DSMINC */ - HDmemset(&oid, 0, sizeof(oid)); - oid.lo = 1; - daos_obj_id_generate(&oid, DAOS_OC_TINY_RW); - if(0 != (ret = daos_obj_open(file->root_oh, oid, epoch, DAOS_OO_RW, &file->root_oh, NULL /*event*/))) + file->root_grp->oid.lo = 1; + daos_obj_id_generate(&file->root_grp->oid, DAOS_OC_TINY_RW); + if(0 != (ret = daos_obj_open(file->coh, file->root_grp->oid, epoch, DAOS_OO_RW, &file->root_grp->obj_oh, NULL /*event*/))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't open root group: %d", ret) /* Bcast global handles if there are other processes */ @@ -882,16 +909,27 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id, if(0 != (ret = daos_cont_global2local(file->poh, glob, &file->coh))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't get local container handle: %d", ret) - /* Leave global md object and root group handles empty for now */ + /* Leave root group handle empty for now */ /* Handle pool_info and container_info DSMINC */ } /* end else */ + /* Open global metadata object */ + daos_obj_id_generate(&oid, DAOS_OC_REPLICA_RW); + if(0 != (ret = daos_obj_open(file->glob_md_oh, oid, 0, DAOS_OO_RW, &file->glob_md_oh, NULL /*event*/))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open global metadata object: %d", ret) + /* Finish setting up file struct */ + file->common.type = H5I_FILE; + file->common.file = file; file->file_name = HDstrdup(name); file->flags = flags; + file->root_grp->common.type = H5I_GROUP; + file->root_grp->common.file = file; + if((file->root_grp->gapl_id = H5Pcopy(H5P_GROUP_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy default gapl"); HDmemset(&file->max_oid, 0, sizeof(file->max_oid)); - file->max_oid.lo = 1; + file->max_oid = 1; if((file->fapl_id = H5Pcopy(fapl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fapl"); @@ -905,8 +943,8 @@ done: /* Clean up buffer */ H5MM_xfree(gh_buf); - /* If the operation is synchronous and it failed at the server, or - it failed locally, then cleanup and return fail */ + /* If the operation is synchronous and it failed at the server, or it failed + * locally, then cleanup and return fail */ if(NULL == ret_value) { /* Bcast gh_sizes as '0' if necessary - this will trigger failures in * the other processes so we do not need to do the second bcast. */ @@ -940,7 +978,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL_daosm_file_close(void *_file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +H5VL_daosm_file_close(void *_file, hid_t dxpl_id, void **req) { H5VL_daosm_file_t *file = (H5VL_daosm_file_t *)_file; daos_handle_t hdl_inval = DAOS_HDL_INVAL; @@ -951,6 +989,12 @@ H5VL_daosm_file_close(void *_file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UN HDassert(file); +#if 0 /* DSMINC */ + /* Flush the epoch */ + if(0 != (ret = daos_epoch_flush(file->coh, epoch, NULL /*state*/, NULL /*event*/))) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, NULL, "can't flush epoch: %d", ret) +#endif + /* Free file data structures */ if(file->file_name) HDfree(file->file_name); @@ -964,9 +1008,9 @@ H5VL_daosm_file_close(void *_file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UN if(HDmemcmp(&file->glob_md_oh, &hdl_inval, sizeof(hdl_inval))) if(0 != (ret = daos_obj_close(file->glob_md_oh, NULL /*event*/))) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close global metadata object: %d", ret) - if(HDmemcmp(&file->root_oh, &hdl_inval, sizeof(hdl_inval))) - if(0 != (ret = daos_obj_close(file->root_oh, NULL /*event*/))) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close root group: %d", ret) + if(file->root_grp) + if(H5VL_daosm_group_close(file->root_grp, dxpl_id, req) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close root group") if(HDmemcmp(&file->coh, &hdl_inval, sizeof(hdl_inval))) if(0 != (ret = daos_cont_close(file->coh, NULL /*event*/))) HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close container: %d", ret) @@ -978,3 +1022,368 @@ H5VL_daosm_file_close(void *_file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UN FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_daosm_file_close() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_daosm_group_close + * + * Purpose: Closes a daos-m HDF5 group. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * November, 2016 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_daosm_group_close(void *_grp, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + H5VL_daosm_group_t *grp = (H5VL_daosm_group_t *)_grp; + daos_handle_t hdl_inval = DAOS_HDL_INVAL; + int ret; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(grp); + + /* Free group data structures */ + if(grp->gapl_id != FAIL && H5I_dec_ref(grp->gapl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + if(HDmemcmp(&grp->obj_oh, &hdl_inval, sizeof(hdl_inval))) + if(0 != (ret = daos_obj_close(grp->obj_oh, NULL /*event*/))) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close group object: %d", ret) + grp = H5FL_FREE(H5VL_daosm_group_t, grp); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_daosm_group_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_daosm_dataset_create + * + * Purpose: Sends a request to DAOS-M to create a dataset + * + * Return: Success: dataset object. + * Failure: NULL + * + * Programmer: Neil Fortner + * November, 2016 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_daosm_dataset_create(void *_obj, + H5VL_loc_params_t H5_ATTR_UNUSED loc_params, const char *name, + hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req) +{ + H5VL_daosm_obj_t *obj = (H5VL_daosm_obj_t *)_obj; + H5VL_daosm_dset_t *dset = NULL; + H5P_genplist_t *plist = NULL; /* Property list pointer */ + hid_t type_id, space_id; + hid_t trans_id; + H5TR_t *tr = NULL; + H5VL_daosm_group_t *target_grp = NULL; + const char *target_name = NULL; + size_t target_name_len; + char const_key[4] = {'L', 'i', 'n', 'k'}; + daos_dkey_t dkey; + daos_vec_iod_t iod; + daos_recx_t recx; + daos_sg_list_t sgl; + daos_iov_t sg_iov; + uint8_t oid_buf[24]; + uint8_t *p; + int ret; + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Get the dcpl plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); + + /* get creation properties */ + if(H5P_get(plist, H5VL_PROP_DSET_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id") + if(H5P_get(plist, H5VL_PROP_DSET_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id") + + /* get the transaction ID */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); + if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id"); + + /* get the TR object */ + if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID") + + /* Traverse the path */ + /* Just use obj for now DSMINC */ + if(obj->type == H5I_FILE) + target_grp = ((H5VL_daosm_file_t *)obj)->root_grp; + else + target_grp = (H5VL_daosm_group_t *)obj; + target_name = name; + target_name_len = HDstrlen(target_name); + + /* Allocate the dataset object that is returned to the user */ + if(NULL == (dset = H5FL_CALLOC(H5VL_daosm_dset_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate IOD dataset struct"); + dset->obj_oh = DAOS_HDL_INVAL; + dset->type_id = FAIL; + dset->space_id = FAIL; + dset->dcpl_id = FAIL; + dset->dapl_id = FAIL; + + /* Create dataset */ + dset->oid.lo = obj->file->max_oid; + daos_obj_id_generate(&dset->oid, DAOS_OC_LARGE_RW); + if(0 != (ret = daos_obj_declare(obj->file->coh, dset->oid, tr->epoch, NULL /*oa*/, NULL /*event*/))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create dataset: %d", ret) + obj->file->max_oid = dset->oid.lo + (uint64_t)1; + obj->file->max_oid_dirty = TRUE; + + /* Set up dkey */ + /* For now always use dkey = const, akey = name. Add option to switch these + * DSMINC */ + dkey.iov_buf_len = dkey.iov_len = sizeof(const_key); + dkey.iov_buf = const_key; + + /* Set up recx */ + recx.rx_rsize = (uint64_t)sizeof(daos_obj_id_t); + recx.rx_idx = (uint64_t)0; + recx.rx_nr = (uint64_t)0; + recx.rx_cookie = (uint64_t)0; + + /* Set up iod */ + HDmemset(&iod, 0, sizeof(iod)); + daos_iov_set(&iod.vd_name, (void *)target_name, (daos_size_t)target_name_len); + iod.vd_nr = 1u; + iod.vd_recxs = &recx; + + /* Encode dset oid */ + HDassert(sizeof(oid_buf) == sizeof(dset->oid)); + p = oid_buf; + UINT64ENCODE(p, dset->oid.lo) + UINT64ENCODE(p, dset->oid.mid) + UINT64ENCODE(p, dset->oid.hi) + + /* Set up sgl */ + daos_iov_set(&sg_iov, oid_buf, (daos_size_t)sizeof(oid_buf)); + sgl.sg_nr.num = 1; + sgl.sg_nr.num_out = 0; + sgl.sg_iovs = &sg_iov; + + /* Create link to dataset */ + if(0 != (ret = daos_obj_update(target_grp->obj_oh, tr->epoch, &dkey, 1, &iod, &sgl, NULL /*event*/))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create link to dataset: %d", ret) + + /* Open dataset */ + if(0 != (ret = daos_obj_open(obj->file->coh, dset->oid, tr->epoch, DAOS_OO_RW, &dset->obj_oh, NULL /*event*/))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't open root group: %d", ret) + + /* Write datatype, dataspace, dcpl DSMINC */ + + /* Finish setting up dataset struct */ + dset->common.type = H5I_DATASET; + dset->common.file = obj->file; + if((dset->type_id = H5Tcopy(type_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy datatype"); + if((dset->space_id = H5Scopy(space_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dataspace"); + if((dset->dcpl_id = H5Pcopy(dcpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dcpl"); + if((dset->dapl_id = H5Pcopy(dapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl"); + + ret_value = (void *)dset; + +done: + /* If the operation is synchronous and it failed at the server, or it failed + * locally, then cleanup and return fail */ + /* Destroy DAOS object if created before failure DSMINC */ + if(NULL == ret_value) + /* Close dataset */ + if(dset != NULL && H5VL_daosm_dataset_close(dset, dxpl_id, req) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "can't close dataset") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_daosm_dataset_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_daosm_dataset_open + * + * Purpose: Sends a request to DAOS-M to open a dataset + * + * Return: Success: dataset object. + * Failure: NULL + * + * Programmer: Neil Fortner + * November, 2016 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_daosm_dataset_open(void *_obj, + H5VL_loc_params_t H5_ATTR_UNUSED loc_params, const char *name, + hid_t dapl_id, hid_t dxpl_id, void **req) +{ + H5VL_daosm_obj_t *obj = (H5VL_daosm_obj_t *)_obj; + H5VL_daosm_dset_t *dset = NULL; + H5P_genplist_t *plist = NULL; /* Property list pointer */ + hid_t type_id, space_id; + hid_t trans_id; + H5TR_t *tr = NULL; + H5VL_daosm_group_t *target_grp = NULL; + const char *target_name = NULL; + size_t target_name_len; + char const_key[4] = {'L', 'i', 'n', 'k'}; + daos_dkey_t dkey; + daos_vec_iod_t iod; + daos_recx_t recx; + daos_sg_list_t sgl; + daos_iov_t sg_iov; + uint8_t oid_buf[24]; + uint8_t *p; + int ret; + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + /* get the transaction ID */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); + if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id"); + + /* get the TR object */ + if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID") + + /* Traverse the path */ + /* Just use obj for now DSMINC */ + if(obj->type == H5I_FILE) + target_grp = ((H5VL_daosm_file_t *)obj)->root_grp; + else + target_grp = (H5VL_daosm_group_t *)obj; + target_name = name; + target_name_len = HDstrlen(target_name); + + /* Allocate the dataset object that is returned to the user */ + if(NULL == (dset = H5FL_CALLOC(H5VL_daosm_dset_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate IOD dataset struct"); + dset->obj_oh = DAOS_HDL_INVAL; + dset->type_id = FAIL; + dset->space_id = FAIL; + dset->dcpl_id = FAIL; + dset->dapl_id = FAIL; + + /* Set up dkey */ + /* For now always use dkey = const, akey = name. Add option to switch these + * DSMINC */ + dkey.iov_buf_len = dkey.iov_len = sizeof(const_key); + dkey.iov_buf = const_key; + + /* Set up recx */ + recx.rx_rsize = (uint64_t)sizeof(daos_obj_id_t); + recx.rx_idx = (uint64_t)0; + recx.rx_nr = (uint64_t)0; + recx.rx_cookie = (uint64_t)0; + + /* Set up iod */ + HDmemset(&iod, 0, sizeof(iod)); + daos_iov_set(&iod.vd_name, (void *)target_name, (daos_size_t)target_name_len); + iod.vd_nr = 1u; + iod.vd_recxs = &recx; + + /* Set up sgl */ + daos_iov_set(&sg_iov, oid_buf, (daos_size_t)sizeof(oid_buf)); + sgl.sg_nr.num = 1; + sgl.sg_nr.num_out = 0; + sgl.sg_iovs = &sg_iov; + + /* Read link to dataset */ + if(0 != (ret = daos_obj_fetch(target_grp->obj_oh, tr->epoch, &dkey, 1, &iod, &sgl, NULL /*maps */, NULL /*event*/))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't read link to dataset: %d", ret) + + /* Decode dset oid */ + HDassert(sizeof(oid_buf) == sizeof(dset->oid)); + p = oid_buf; + UINT64DECODE(p, dset->oid.lo) + UINT64DECODE(p, dset->oid.mid) + UINT64DECODE(p, dset->oid.hi) + + /* Open dataset */ + if(0 != (ret = daos_obj_open(obj->file->coh, dset->oid, tr->epoch, DAOS_OO_RW, &dset->obj_oh, NULL /*event*/))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't open root group: %d", ret) + + /* Read datatype, dataspace, dcpl DSMINC */ + + /* Finish setting up dataset struct */ + dset->common.type = H5I_DATASET; + dset->common.file = obj->file; + if((dset->dapl_id = H5Pcopy(dapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl"); + + ret_value = (void *)dset; + +done: + /* If the operation is synchronous and it failed at the server, or it failed + * locally, then cleanup and return fail */ + if(NULL == ret_value) + /* Close dataset */ + if(dset != NULL && H5VL_daosm_dataset_close(dset, dxpl_id, req) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "can't close dataset") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_daosm_dataset_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_daosm_dataset_close + * + * Purpose: Closes a daos-m HDF5 dataset. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * November, 2016 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_daosm_dataset_close(void *_dset, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + H5VL_daosm_dset_t *dset = (H5VL_daosm_dset_t *)_dset; + daos_handle_t hdl_inval = DAOS_HDL_INVAL; + int ret; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(dset); + + /* Free dataset data structures */ + if(HDmemcmp(&dset->obj_oh, &hdl_inval, sizeof(hdl_inval))) + if(0 != (ret = daos_obj_close(dset->obj_oh, NULL /*event*/))) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close dataset DAOS object: %d", ret) + if(dset->type_id != FAIL && H5I_dec_ref(dset->type_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close datatype"); + if(dset->space_id != FAIL && H5I_dec_ref(dset->space_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dataspace"); + if(dset->dcpl_id != FAIL && H5I_dec_ref(dset->dcpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + if(dset->dapl_id != FAIL && H5I_dec_ref(dset->dapl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + dset = H5FL_FREE(H5VL_daosm_dset_t, dset); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_daosm_file_close() */ + diff --git a/src/H5VLdaosm.h b/src/H5VLdaosm.h index 084c488..76fb327 100644 --- a/src/H5VLdaosm.h +++ b/src/H5VLdaosm.h @@ -40,8 +40,15 @@ extern "C" { #ifdef H5_HAVE_EFF -/* the file struct */ +/* Common object information */ +typedef struct H5VL_daosm_obj_t { + H5I_type_t type; + struct H5VL_daosm_file_t *file; +} H5VL_daosm_obj_t; + +/* The file struct */ typedef struct H5VL_daosm_file_t { + H5VL_daosm_obj_t common; /* Must be first */ daos_handle_t poh; daos_handle_t coh; //daos_pool_info_t pool_info; @@ -50,8 +57,9 @@ typedef struct H5VL_daosm_file_t { uuid_t uuid; unsigned flags; daos_handle_t glob_md_oh; - daos_handle_t root_oh; - daos_obj_id_t max_oid; + struct H5VL_daosm_group_t *root_grp; + uint64_t max_oid; + hbool_t max_oid_dirty; hid_t fcpl_id; hid_t fapl_id; MPI_Comm comm; @@ -60,6 +68,25 @@ typedef struct H5VL_daosm_file_t { int num_procs; } H5VL_daosm_file_t; +/* The group struct */ +typedef struct H5VL_daosm_group_t { + H5VL_daosm_obj_t common; /* Must be first */ + daos_obj_id_t oid; + daos_handle_t obj_oh; + hid_t gapl_id; +} H5VL_daosm_group_t; + +/* The dataset struct */ +typedef struct H5VL_daosm_dset_t { + H5VL_daosm_obj_t common; /* Must be first */ + daos_obj_id_t oid; + daos_handle_t obj_oh; + hid_t type_id; + hid_t space_id; + hid_t dcpl_id; + hid_t dapl_id; +} H5VL_daosm_dset_t; + extern hid_t H5VL_DAOSM_g; H5_DLL hid_t H5VL_daosm_init(void); diff --git a/src/H5private.h b/src/H5private.h index a86cdcd..848228e 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -278,6 +278,8 @@ #endif /* H5_HAVE_MPE */ +#define H5_HAVE_EFF 1 //DSMINC + /* * dmalloc (debugging malloc) support */ @@ -2563,6 +2565,8 @@ H5_DLL int H5T_top_term_package(void); H5_DLL int H5VL_term_package(void); H5_DLL int H5Z_term_package(void); +H5_DLL int H5TR_term_package(void); + /* Checksum functions */ H5_DLL uint32_t H5_checksum_fletcher32(const void *data, size_t len); H5_DLL uint32_t H5_checksum_crc(const void *data, size_t len); diff --git a/src/Makefile.am b/src/Makefile.am index adb0a5e..deff08f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,6 +65,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5FD.c H5FDcore.c \ H5FDfamily.c H5FDint.c H5FDlog.c \ H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \ + H5FF.c \ H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c H5FSstat.c H5FStest.c \ H5G.c H5Gbtree2.c H5Gcache.c \ H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \ @@ -110,7 +111,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c \ H5Topaque.c \ H5Torder.c \ - H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c H5Tvlen.c H5TS.c H5VM.c H5WB.c H5Z.c \ + H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c H5Tvlen.c H5TR.c H5TS.c H5VM.c H5WB.c H5Z.c \ H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c \ H5Zscaleoffset.c H5Zszip.c H5Ztrans.c @@ -132,13 +133,14 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers H5FDpublic.h H5FDcore.h H5FDdirect.h \ H5FDfamily.h H5FDlog.h H5FDmpi.h H5FDmpio.h \ H5FDmulti.h H5FDsec2.h H5FDstdio.h \ + H5FFpublic.h \ H5VLpublic.h H5VLnative.h \ H5VLdaosm.h \ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h \ H5PLextern.h H5PLpublic.h \ H5Rpublic.h H5Spublic.h \ - H5Tpublic.h H5Zpublic.h + H5Tpublic.h H5TRpublic.h H5Zpublic.h # install libhdf5.settings in lib directory settingsdir=$(libdir) diff --git a/src/hdf5.h b/src/hdf5.h index 5c764ba..b7580bc 100644 --- a/src/hdf5.h +++ b/src/hdf5.h @@ -42,7 +42,8 @@ #include "H5VLpublic.h" /* VOL plugins */ /* FastForward headers */ -//#include "H5FFpublic.h" /* FastForward wrappers */ DSMINC +#include "H5FFpublic.h" /* FastForward wrappers */ +#include "H5TRpublic.h" /* Transactions */ #include "H5VLdaosm.h" /* DAOS-M VOL plugin */ /* Predefined VOL plugins */ -- cgit v0.12