diff options
-rw-r--r-- | src/H5F.c | 8 | ||||
-rw-r--r-- | src/H5FDdpss.c | 627 | ||||
-rw-r--r-- | src/H5FDdpss.h | 32 | ||||
-rw-r--r-- | src/H5FDgass.c | 1 | ||||
-rw-r--r-- | src/H5Farray.c | 17 | ||||
-rw-r--r-- | src/H5Fprivate.h | 4 | ||||
-rw-r--r-- | src/H5config.h.in | 3 | ||||
-rw-r--r-- | src/Makefile.in | 4 | ||||
-rw-r--r-- | test/Makefile.in | 10 | ||||
-rw-r--r-- | test/dpss_read.c | 187 | ||||
-rw-r--r-- | test/dpss_write.c | 149 |
11 files changed, 1037 insertions, 5 deletions
@@ -25,6 +25,7 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5FDfamily.h> /*family of files */ #include <H5FDmpio.h> /*MPI-2 I/O */ #include <H5FDgass.h> /*GASS I/O */ +#include <H5FDdpss.h> /*DPSS I/O */ #include <H5FDmulti.h> /*multiple files partitioned by mem usage */ #include <H5FDsec2.h> /*Posix unbuffered I/O */ #include <H5FDstdio.h> /* Standard C buffered I/O */ @@ -95,6 +96,10 @@ H5F_xfer_t H5F_xfer_dflt = { NULL, /*No information needed for free() calls */ -2, /*See H5Pget_driver() */ NULL, /*No file driver-specific information yet */ +#ifdef COALESCE_READS + 0, /*coalesce single reads into a read */ + /*transaction */ +#endif }; /* @@ -209,6 +214,9 @@ H5F_init_interface(void) #ifdef H5_HAVE_GASS if ((status=H5FD_GASS)<0) goto end_registration; #endif +#ifdef HAVE_DPSS + if ((status=H5FD_DPSS)<0) goto end_registration; +#endif if ((status=H5FD_CORE)<0) goto end_registration; if ((status=H5FD_MULTI)<0) goto end_registration; #ifdef H5_HAVE_PARALLEL diff --git a/src/H5FDdpss.c b/src/H5FDdpss.c new file mode 100644 index 0000000..576d5d4 --- /dev/null +++ b/src/H5FDdpss.c @@ -0,0 +1,627 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Thomas Radke <tradke@aei-potsdam.mpg.de> + * Monday, October 11, 1999 + * + * Purpose: This is the Distributed Parallel Storage System I/O driver. + * + */ + +#include <hdf5.h> +#include <H5Eprivate.h> /* error handling */ +#include <H5MMprivate.h> /* memory management */ + +/*** FIXME: should this be included here or in <hdf5.h> ??? ***/ +#include "H5FDdpss.h" + +#ifdef COALESCE_READS +/* Packages needed by this file.*/ +#include <H5Fprivate.h> +#include <H5Iprivate.h> +#endif + + +/* uncomment this to get some debugging output from this driver */ +#if 1 +#define DEBUG 1 +#endif + +/* The driver identification number, initialized at runtime */ +static hid_t H5FD_DPSS_g = 0; + + +/* compile this only if HDF5 was configured to use the DPSS I/O driver */ +#ifdef H5_HAVE_DPSS + +/* include the DPSS Storage Client header */ +#include <grid_storage_file.h> + +/* + * The description of a file belonging to this driver. The `eoa' and `eof' + * determine the amount of hdf5 address space in use and the high-water mark + * of the file (the current size of the underlying Unix file). + * When opening a file the `eof' will be set to the current file size, + * `eoa' will be set * to zero. + */ +typedef struct H5FD_dpss_t { + H5FD_t pub; /* public stuff, must be first */ + grid_storage_handle_t handle; /* the DPSS file handle */ + haddr_t eoa; /* end of allocated region */ + haddr_t eof; /* end of file; current file size */ +} H5FD_dpss_t; + + +/*** FIXME: is this really needed here ? ***/ +/* + * This driver supports systems that have the lseek64() function by defining + * some macros here so we don't have to have conditional compilations later + * throughout the code. + * + * file_offset_t: The datatype for file offsets, the second argument of + * the lseek() or lseek64() call. + * + * file_seek: The function which adjusts the current file position, + * either lseek() or lseek64(). + */ +#ifdef HAVE_LSEEK64 +# define file_offset_t off64_t +# define file_seek lseek64 +#else +# define file_offset_t off_t +# define file_seek lseek +#endif + +/* + * These macros check for overflow of various quantities. These macros + * assume that file_offset_t is signed and haddr_t and size_t are unsigned. + * + * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' + * is too large to be represented by the second argument + * of the file seek function. + * + * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too + * large to be represented by the `size_t' type. + * + * REGION_OVERFLOW: Checks whether an address and size pair describe data + * which can be addressed entirely by the second + * argument of the file seek function. + */ +#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1) +#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ + ((A) & ~(haddr_t)MAXADDR)) +#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) +#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ + sizeof(file_offset_t)<sizeof(size_t) || \ + HADDR_UNDEF==(A)+(Z) || \ + (file_offset_t)((A)+(Z))<(file_offset_t)(A)) + +#define PRINT_GLOBUS_ERROR_MSG(globus_result) \ + { \ + char *globus_error_msg; \ + \ + globus_error_msg = globus_object_printable_to_string ( \ + globus_error_get (globus_result)); \ + if (globus_error_msg) { \ + /*** FIXME: put appropriate minor error code in here ***/ \ + HERROR (H5E_IO, -1, globus_error_msg); \ + globus_free (globus_error_msg); \ + } \ + } + +/* DPSS driver function prototypes */ +static H5FD_t *H5FD_dpss_open (const char *name, unsigned flags, + hid_t UNUSED fapl_id, haddr_t maxaddr); +static herr_t H5FD_dpss_close (H5FD_t *_file); +static haddr_t H5FD_dpss_get_eoa (H5FD_t *_file); +static herr_t H5FD_dpss_set_eoa (H5FD_t *_file, haddr_t addr); +static haddr_t H5FD_dpss_get_eof (H5FD_t *_file); +static herr_t H5FD_dpss_read (H5FD_t *_file, hid_t fapl_id, haddr_t addr, + hsize_t size, void *buf); +static herr_t H5FD_dpss_write (H5FD_t *_file, hid_t UNUSED fapl_id,haddr_t addr, + hsize_t size, const void *buf); + +/* The DPSS I/O driver information */ +static const H5FD_class_t H5FD_dpss_g = { + "dpss", /* name */ + MAXADDR, /* maxaddr */ + NULL, /* sb_size */ + NULL, /* sb_encode */ + NULL, /* sb_decode */ + 0, /* fapl_size */ + NULL, /* fapl_get */ + NULL, /* fapl_copy */ + NULL, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD_dpss_open, /* open */ + H5FD_dpss_close, /* close */ + NULL, /* cmp */ + NULL, /* alloc */ + NULL, /* free */ + H5FD_dpss_get_eoa, /* get_eoa */ + H5FD_dpss_set_eoa, /* set_eoa */ + H5FD_dpss_get_eof, /* get_eof */ + H5FD_dpss_read, /* read */ + H5FD_dpss_write, /* write */ + NULL, /* flush */ + H5FD_FLMAP_SINGLE, /* fl_map */ +}; + +/* Interface initialization */ +#define PABLO_MASK H5FD_dpss_mask +#define INTERFACE_INIT H5FD_dpss_init +static intn interface_initialize_g = 0; + + +/*------------------------------------------------------------------------- + * Function: H5FD_dpss_init + * + * Purpose: Initialize this driver by registering the driver with the + * library. + * + * Return: Success: The driver ID for the DPSS driver. + * + * Failure: Negative. + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5FD_dpss_init (void) +{ + int globus_result; /* NOTE: globus_module_activate() doesn't + return a globus_result_t type */ + + FUNC_ENTER (H5FD_dpss_init, FAIL); + + /* register the DPSS driver if it wasn't already */ + if (! H5FD_DPSS_g) + H5FD_DPSS_g = H5FDregister (&H5FD_dpss_g); + + /* active the DPSS storage client module which in turn activates + all other Globus modules that are needed */ + if (H5FD_DPSS_g >= 0) { + globus_result = globus_module_activate (GRID_STORAGE_FILE_MODULE); + if (GLOBUS_SUCCESS != globus_result) { + H5FDunregister (H5FD_DPSS_g); + H5FD_DPSS_g = -1; + HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL, + "Cannot activate Globus Grid Storage File module"); + } + } + + FUNC_LEAVE (H5FD_DPSS_g); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_dpss + * + * Purpose: Modify the file application list to use the DPSS I/O + * driver defined in this source file. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_dpss (hid_t fapl_id) +{ + herr_t ret_value=FAIL; + + FUNC_ENTER (H5FD_set_fapl_dpss, FAIL); + + /* Check arguments */ + if (H5P_FILE_ACCESS != H5Pget_class (fapl_id)) + HRETURN_ERROR (H5E_PLIST, H5E_BADTYPE, FAIL, "not a fapl"); + + ret_value = H5Pset_driver (fapl_id, H5FD_DPSS, NULL); + + FUNC_LEAVE (ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_dpss_open + * + * Purpose: Creates/opens a DPSS file instance identified by its URL + * as an HDF5 file. + * + * Return: Success: A pointer to a new file data structure. The + * public fields will be initialized by the + * caller, which is always H5FD_open(). + * + * Failure: NULL + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5FD_t * +H5FD_dpss_open (const char *name, unsigned flags, hid_t UNUSED fapl_id, + haddr_t maxaddr) +{ + int i; + globus_result_t globus_result; + grid_storage_url_t *url = (grid_storage_url_t *) name; + grid_storage_handle_t handle; + H5FD_dpss_t *file; + unsigned int o_flags; + char int_attribute_value [10]; + int64_t file_size; + char **property_names, + **property_values; + grid_storage_attribute_t attributes = GRID_STORAGE_ATTRIBUTE_INITIALIZER; + + + FUNC_ENTER (H5FD_dpss_open, NULL); + +#ifdef DEBUG + fprintf (stdout, "H5FD_dpss_open: name='%s', flags=0x%x\n", name, flags); +#endif + + /* Check arguments */ + if (!name || !*name) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); + if (0==maxaddr || HADDR_UNDEF==maxaddr) + HRETURN_ERROR (H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); + if (ADDR_OVERFLOW (maxaddr)) + HRETURN_ERROR (H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); + + /* Build the open flags */ + o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; + if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC; + if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT; + if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL; + sprintf (int_attribute_value, "%d", o_flags); + + /* set the 'open flags' attribute */ + globus_result = + grid_storage_add_attribute (GRID_STORAGE_ATTRIBUTE_OPEN_FLAGS, + int_attribute_value, &attributes); + if (GLOBUS_SUCCESS != globus_result) { + PRINT_GLOBUS_ERROR_MSG (globus_result); + HRETURN_ERROR (H5E_IO, H5E_CANTOPENFILE, NULL, + "Can't set attributes for file instance"); + } + + /* open the file instance */ + globus_result = grid_storage_open ((grid_storage_url_t *) url, &handle, + &attributes); + if (GLOBUS_SUCCESS != globus_result) { + PRINT_GLOBUS_ERROR_MSG (globus_result); + HRETURN_ERROR (H5E_IO, H5E_CANTOPENFILE, NULL, + "Can't open file instance"); + } + + /* Get the size of the file instance. + Read all the instance properties ... */ + globus_result = grid_storage_list_properties (url, NULL, &property_names, + &property_values); + if (GLOBUS_SUCCESS != globus_result) { + PRINT_GLOBUS_ERROR_MSG (globus_result); + grid_storage_close (&handle, NULL); + HRETURN_ERROR (H5E_IO, H5E_CANTOPENFILE, NULL, + "Can't get properties of file instance"); + } + /* ... now sort out the 'size' property */ + file_size = -1; + for (i = 0; property_names [i]; i++) { + if (strcmp (property_names [i], GRID_STORAGE_PROPERTY_SIZE) == 0) { + if (property_values [i]) + sscanf (property_values [i], "%"PRINTF_LL_WIDTH"u", &file_size); + } + /* don't forget to free the allocated property strings */ + globus_libc_free (property_names [i]); + globus_libc_free (property_values [i]); + } + globus_libc_free (property_names); + globus_libc_free (property_values); + + /* Did we find a size ? */ + if (file_size < 0) { + grid_storage_close (&handle, NULL); + HRETURN_ERROR (H5E_IO, H5E_CANTOPENFILE, NULL, + "Can't get size of file instance"); + } + + /* Create the new file struct */ + if (NULL == (file = (H5FD_dpss_t *) H5MM_calloc (sizeof (H5FD_dpss_t)))) + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + "Can't allocate file struct"); + file->handle = handle; + file->eof = (haddr_t) file_size; + + FUNC_LEAVE ((H5FD_t *) file); +} + +/*------------------------------------------------------------------------- + * Function: H5FD_dpss_close +* + * Purpose: Closes a previously opened DPSS file instance. + * + * Return: Success: 0 + * + * Failure: -1, file not closed. + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_dpss_close (H5FD_t *_file) +{ + globus_result_t globus_result; + H5FD_dpss_t *file = (H5FD_dpss_t *) _file; + + FUNC_ENTER (H5FD_dpss_close, FAIL); + + if (NULL == file) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file handle"); + + globus_result = grid_storage_close (&file->handle, NULL); + if (GLOBUS_SUCCESS != globus_result) { + PRINT_GLOBUS_ERROR_MSG (globus_result); + HRETURN_ERROR (H5E_IO, H5E_CANTCLOSEFILE, FAIL, "Failed to close file instance"); + } + + H5MM_xfree (file); + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_dpss_get_eoa + * + * Purpose: Gets the end-of-address marker for the file. The EOA marker + * is the first address past the last byte allocated in the + * format address space. + * + * Return: Success: The end-of-address marker. + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_dpss_get_eoa (H5FD_t *_file) +{ + H5FD_dpss_t *file = (H5FD_dpss_t *) _file; + + FUNC_ENTER (H5FD_dpss_get_eoa, HADDR_UNDEF); + + FUNC_LEAVE (file->eoa); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_dpss_set_eoa + * + * Purpose: Set the end-of-address marker for the file. This function is + * called shortly after an existing HDF5 file is opened in order + * to tell the driver where the end of the HDF5 data is located. + * + * Return: Success: 0 + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_dpss_set_eoa (H5FD_t *_file, haddr_t addr) +{ + H5FD_dpss_t *file = (H5FD_dpss_t *) _file; + + FUNC_ENTER (H5FD_dpss_set_eoa, FAIL); + + file->eoa = addr; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_dpss_get_eof + * + * Purpose: Returns the end-of-file marker, which is the greater of + * either the Unix end-of-file or the HDF5 end-of-address + * markers. + * + * Return: Success: End of file address, the first address past + * the end of the "file", either the DPSS + * file or the HDF5 file. + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_dpss_get_eof (H5FD_t *_file) +{ + H5FD_dpss_t *file = (H5FD_dpss_t*) _file; + + FUNC_ENTER (H5FD_dpss_get_eof, HADDR_UNDEF); + + FUNC_LEAVE (file->eof > file->eoa ? file->eof : file->eoa); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_dpss_read + * + * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF. + * + * Return: Success: Zero. Result is stored in caller-supplied + * buffer BUF. + * + * Failure: -1, Contents of buffer BUF are undefined. + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_dpss_read (H5FD_t *_file, hid_t dxpl_id, haddr_t addr, + hsize_t size, void *buf/*out*/) +{ + H5FD_dpss_t *file = (H5FD_dpss_t *) _file; + globus_result_t globus_result; +#ifdef COALESCE_READS + static int count = 0; /* counter for single reads */ + H5F_xfer_t *xfer_parms; /*transfer property list*/ +#endif + + FUNC_ENTER (H5FD_dpss_read, FAIL); + +#ifdef DEBUG + fprintf (stdout, "H5FD_dpss_read: addr 0x%lx, size %ld\n", + (unsigned long int) addr, (unsigned long int) size); +#endif + + /* Check parameters */ + if (! file) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file handle"); + if (! buf) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer pointer"); + + /* Check for overflow conditions */ + if (HADDR_UNDEF == addr) + HRETURN_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL, "addr undefined"); + if (REGION_OVERFLOW (addr, size)) + HRETURN_ERROR (H5E_ARGS, H5E_OVERFLOW, FAIL, "addr too large"); + if (addr + size > file->eoa) + HRETURN_ERROR (H5E_ARGS, H5E_OVERFLOW, FAIL, "addr too large"); + +#ifdef COALESCE_READS + /* Get the dataset transfer property list */ + if (H5P_DEFAULT == dxpl_id) { + xfer_parms = &H5F_xfer_dflt; + } else if (H5P_DATA_XFER != H5P_get_class (dxpl_id) || + NULL == (xfer_parms = H5I_object (dxpl_id))) { + HRETURN_ERROR (H5E_PLIST, H5E_BADTYPE, FAIL, "not a xfer"); + } + + if (xfer_parms->gather_reads) { + if (! count) + count = xfer_parms->gather_reads; +#ifdef DEBUG + fprintf (stdout, "H5FD_dpss_read: request would be queued\n"); +#endif + } else { +#ifdef DEBUG + fprintf (stdout, "H5FD_dpss_read: transaction would be performed " + "with %d individual reads\n", count + 1); +#endif + count = 0; + } +#endif + + /* do the (synchronuous) write operation */ + globus_result = grid_storage_read (&file->handle, (unsigned char *) buf, + (size_t) addr, (size_t) size, NULL); + if (GLOBUS_SUCCESS != globus_result) { + PRINT_GLOBUS_ERROR_MSG (globus_result); + HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, + "Failed to read file instance"); + } + + FUNC_LEAVE (SUCCEED); +} + +/*------------------------------------------------------------------------- + * Function: H5FD_dpss_write + * + * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR + * from buffer BUF. + * + * Return: Success: Zero + * + * Failure: -1 + * + * Programmer: Thomas Radke + * Monday, October 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_dpss_write (H5FD_t *_file, hid_t UNUSED dxpl_id, haddr_t addr, + hsize_t size, const void *buf) +{ + H5FD_dpss_t *file = (H5FD_dpss_t *) _file; + globus_result_t globus_result; + + FUNC_ENTER (H5FD_dpss_write, FAIL); + +#ifdef DEBUG + fprintf (stdout, "H5FD_dpss_write: addr 0x%lx, size %ld\n", + (unsigned long int) addr, (unsigned long int) size); +#endif + + /* Check parameters */ + if (! file) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file handle"); + if (! buf) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer pointer"); + + /* Check for overflow conditions */ + if (HADDR_UNDEF == addr) + HRETURN_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL, "addr undefined"); + if (REGION_OVERFLOW (addr, size)) + HRETURN_ERROR (H5E_ARGS, H5E_OVERFLOW, FAIL, "addr too large"); + if (addr + size > file->eoa) + HRETURN_ERROR (H5E_ARGS, H5E_OVERFLOW, FAIL, "addr too large"); + + /* do the (synchronuous) write operation */ + globus_result = grid_storage_write (&file->handle, (unsigned char *) buf, + (size_t) addr, (size_t) size, NULL); + if (GLOBUS_SUCCESS != globus_result) { + PRINT_GLOBUS_ERROR_MSG (globus_result); + HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, + "Failed to write file instance"); + } + + /* expand end-of-file marker if necessary */ + if (addr > file->eof) + file->eof = addr; + + FUNC_LEAVE (SUCCEED); +} + +#endif /* DPSS */ + diff --git a/src/H5FDdpss.h b/src/H5FDdpss.h new file mode 100644 index 0000000..7ba8ca2 --- /dev/null +++ b/src/H5FDdpss.h @@ -0,0 +1,32 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Thomas Radke <tradke@aei-potsdam.mpg.de> + * Monday, October 11, 1999 + * + * Purpose: The public header file for the DPSS driver. + */ +#ifndef H5FDdpss_H +#define H5FDdpss_H + +#include <H5public.h> /* typedef for herr_t */ +#include <H5Ipublic.h> /* typedef for hid_t */ + +#ifdef H5_HAVE_DPSS +#define H5FD_DPSS (H5FD_dpss_init()) +#else +#define H5FD_DPSS (-1) +#endif + +/* Function prototypes */ +#ifdef H5_HAVE_DPSS + +hid_t H5FD_dpss_init(void); +herr_t H5Pset_fapl_dpss (hid_t fapl_id); +herr_t H5Pget_fapl_dpss (hid_t fapl_id); + +#endif + +#endif /* H5FDdpss_H */ + diff --git a/src/H5FDgass.c b/src/H5FDgass.c index 911053d..bafbd2e 100644 --- a/src/H5FDgass.c +++ b/src/H5FDgass.c @@ -355,7 +355,6 @@ H5FD_gass_open(const char *name, unsigned flags, hid_t fapl_id, if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR) && (flags & H5F_ACC_EXCL)) { if ((fd = globus_gass_open (filename, O_RDWR|O_TRUNC)) < 0) HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "open failed"); - } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR) && (flags & H5F_ACC_TRUNC)) { if ((fd = globus_gass_open (filename, O_RDWR|O_TRUNC)) < 0) diff --git a/src/H5Farray.c b/src/H5Farray.c index 02a39d3..f2b79f1 100644 --- a/src/H5Farray.c +++ b/src/H5Farray.c @@ -143,6 +143,9 @@ H5F_arr_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; #endif +#ifdef COALESCE_READS + H5F_xfer_t *xfer_parms; /*transfer property list*/ +#endif FUNC_ENTER(H5F_arr_read, FAIL); @@ -270,7 +273,21 @@ H5F_arr_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, } #endif +#ifdef COALESCE_READS + /* Get the dataset transfer property list */ + if (H5P_DEFAULT == dxpl_id) { + xfer_parms = &H5F_xfer_dflt; + } else if (H5P_DATA_XFER != H5P_get_class (dxpl_id) || + NULL == (xfer_parms = H5I_object (dxpl_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); + } + + for (z=0, xfer_parms->gather_reads = nelmts - 1; + z<nelmts; + z++, xfer_parms->gather_reads--) { +#else for (z=0; z<nelmts; z++) { +#endif /* Read from file */ if (efl && efl->nused>0) { diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index ad4e1cf..fff050b 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -274,6 +274,10 @@ typedef struct H5F_xfer_t { void *free_info; /*VL datatype free information */ hid_t driver_id; /*File driver ID */ void *driver_info; /*File driver specific information */ +#ifdef COALESCE_READS + uintn gather_reads; /*coalesce single reads into a read */ + /*transaction */ +#endif } H5F_xfer_t; /* The raw data chunk cache */ diff --git a/src/H5config.h.in b/src/H5config.h.in index bf00559..8078e26 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -77,6 +77,9 @@ /* Define if we have Globus GASS support */ #undef HAVE_GASS +/* Define if we have Globus DPSS support */ +#undef HAVE_DPSS + /* The number of bytes in a __int64. */ #undef SIZEOF___INT64 diff --git a/src/Makefile.in b/src/Makefile.in index 20bd313..cdef845 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -26,7 +26,7 @@ LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fistore.c \ H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c \ H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5R.c H5RA.c H5S.c H5Sall.c \ H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c H5T.c H5Tbit.c \ - H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5V.c H5Z.c H5Zdeflate.c + H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5V.c H5Z.c H5Zdeflate.c H5FDdpss.c LIB_OBJ=$(LIB_SRC:.c=.lo) @@ -39,7 +39,7 @@ PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \ H5FDsec2.h H5FDcore.h H5FDmulti.h H5FDstdio.h H5Gpublic.h H5HGpublic.h \ H5HLpublic.h H5Ipublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h \ H5RApublic.h H5Spublic.h H5Tpublic.h H5Zpublic.h H5pubconf.h hdf5.h \ - H5api_adpt.h + H5api_adpt.h H5FDdpss.h ## Other header files (not to be installed)... PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ diff --git a/test/Makefile.in b/test/Makefile.in index 5d711bc..05c3ec4 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -18,7 +18,7 @@ CPPFLAGS=-I. -I$(srcdir) -I../src -I$(top_srcdir)/src @CPPFLAGS@ RUNTEST=$(LT_RUN) TEST_PROGS=testhdf5 lheap ohdr stab gheap hyperslab istore bittests dtypes \ dsets cmpd_dset extend external links unlink big mtime fillval mount \ - flush1 flush2 enum gass_write gass_read gass_append + flush1 flush2 enum gass_write gass_read gass_append dpss_read dpss_write TIMINGS=iopipe chunk ragged overhead ## The libh5test.a library provides common support code for the tests. We link @@ -57,7 +57,7 @@ TEST_SRC=big.c bittests.c chunk.c cmpd_dset.c dsets.c dtypes.c extend.c \ iopipe.c istore.c lheap.c links.c mount.c mtime.c ohdr.c overhead.c \ ragged.c stab.c tattr.c testhdf5.c tfile.c th5s.c tmeta.c trefer.c \ tselect.c tvltypes.c tvlstr.c unlink.c enum.c gass_write.c gass_read.c \ - gass_append.c + gass_append.c dpss_read.c dpss_write.c TEST_OBJ=$(TEST_SRC:.c=.lo) @@ -164,4 +164,10 @@ gass_read: gass_read.lo gass_append: gass_append.lo @$(LT_LINK_EXE) $(CFLAGS) -o $@ gass_append.lo $(LIB) $(LIBHDF5) $(LDFLAGS) $(LIBS) +dpss_read: dpss_read.lo + @$(LT_LINK_EXE) $(CFLAGS) -o $@ dpss_read.lo $(LIB) $(LIBHDF5) $(LDFLAGS) $(LIBS) + +dpss_write: dpss_write.lo + @$(LT_LINK_EXE) $(CFLAGS) -o $@ dpss_write.lo $(LIB) $(LIBHDF5) $(LDFLAGS) $(LIBS) + @CONCLUDE@ diff --git a/test/dpss_read.c b/test/dpss_read.c new file mode 100644 index 0000000..953d06a --- /dev/null +++ b/test/dpss_read.c @@ -0,0 +1,187 @@ +/* + * Copyright © 1998 NCSA + * All rights reserved. + * + * Programmer: Saurabh Bagchi (bagchi@uiuc.edu) + * Wednesday, August 11, 1999. + * + * Modifications: Saurabh Bagchi (Aug 17, 1999) + * Modified to work with VFL (HDF51.3). + */ + +/* Test the following functionality of the DPSS driver. + 1. Open a remote file for read (the dataset was written using dpss_write.c). + 2. Create a memory buffer to hold the dataset. + 3. Read the dataset into the memory buffer. + 4. Get some information about the dataset from the file. +*/ +#include <h5test.h> +#include <strings.h> + +#ifndef HAVE_DPSS +int main(void) +{ + printf("Test skipped because DPSS driver not available\n"); + return 0; +} +#else + +#define DATASETNAME "IntArray" +#define NX_SUB 98 /* hyperslab dimensions */ +#define NY_SUB 98 +#define NX 100 /* output buffer dimensions */ +#define NY 100 +#define NZ 3 +#define RANK 2 +#define RANK_OUT 3 + +int +main (int argc, char **argv) +{ + hid_t fapl = -1, file, dataset; /* handles */ + hid_t datatype, dataspace; + hid_t memspace; + H5T_class_t class; /* data type class */ + H5T_order_t order; /* data order */ + size_t size; /* + * size of the data element + * stored in file + */ + hsize_t dimsm[3]; /* memory space dimensions */ + hsize_t dims_out[2]; /* dataset dimensions */ + herr_t status; + + int data_out[NX][NY][NZ ]; /* output buffer */ + + hsize_t count[2]; /* size of the hyperslab in the file */ + hssize_t offset[2]; /* hyperslab offset in the file */ + hsize_t count_out[3]; /* size of the hyperslab in memory */ + hssize_t offset_out[3]; /* hyperslab offset in memory */ + int i, j, k, status_n, rank; + char *url; + + if (argc != 2) { + printf ("Incorrect command line. \n"); + printf ("Correct command line: %s <url>\n\n", argv[0]); + exit(1); + } + + url = argv [1]; + + printf ("\n Reading dataset %s \n\n", DATASETNAME); + + for (j = 0; j < NX; j++) { + for (i = 0; i < NY; i++) { + for (k = 0; k < NZ ; k++) + data_out[j][i][k] = 0; + } + } + + /* Create access property list and set the driver to DPSS */ + fapl = H5Pcreate (H5P_FILE_ACCESS); + if (fapl < 0) { + printf (" H5Pcreate failed. \n"); + return -1; + } + + status = H5Pset_fapl_dpss (fapl); + if (status < 0) { + printf ("H5Pset_fapl_dpss failed. \n"); + return -1; + } + + /* + * Open the file and the dataset. + */ + file = H5Fopen(url, H5F_ACC_RDONLY, fapl); + if (file < 0) { + printf ("Could not open file '%s'\n", url); + return -1; + } + dataset = H5Dopen(file, DATASETNAME); + + /* + * Get datatype and dataspace handles and then query + * dataset class, order, size, rank and dimensions. + */ + datatype = H5Dget_type(dataset); /* datatype handle */ + class = H5Tget_class(datatype); + if (class == H5T_INTEGER) printf("Data set has INTEGER type \n"); + order = H5Tget_order(datatype); + if (order == H5T_ORDER_LE) printf("Little endian order \n"); + + size = H5Tget_size(datatype); + printf(" Data size is %d \n", size); + + dataspace = H5Dget_space(dataset); /* dataspace handle */ + rank = H5Sget_simple_extent_ndims(dataspace); + status_n = H5Sget_simple_extent_dims(dataspace, dims_out, NULL); + printf("rank %d, dimensions %lu x %lu \n", rank, + (unsigned long)(dims_out[0]), (unsigned long)(dims_out[1])); + + /* + * Define hyperslab in the dataset. + */ + offset[0] = 0; + offset[1] = 0; + count[0] = NX_SUB; + count[1] = NY_SUB; + status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, NULL, + count, NULL); + + /* + * Define the memory dataspace. + */ + dimsm[0] = NX; + dimsm[1] = NY; + dimsm[2] = NZ ; + memspace = H5Screate_simple(RANK_OUT,dimsm,NULL); + + /* + * Define memory hyperslab. + */ + offset_out[0] = 3; + offset_out[1] = 0; + offset_out[2] = 0; + count_out[0] = NX_SUB; + count_out[1] = NY_SUB; + count_out[2] = 1; + status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, NULL, + count_out, NULL); + + /* + * Read data from hyperslab in the file into the hyperslab in + * memory and display. + */ + status = H5Dread(dataset, H5T_NATIVE_INT, memspace, dataspace, + H5P_DEFAULT, data_out); +#if 0 + for (j = 0; j < NX; j++) { + for (i = 0; i < NY; i++) printf("%d ", data_out[j][i][0]); + printf("\n"); + } +#endif + /* + * 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 + * 0 0 0 0 0 0 0 + * 3 4 5 6 0 0 0 + * 4 5 6 7 0 0 0 + * 5 6 7 8 0 0 0 + * 0 0 0 0 0 0 0 + */ + + /* + * Close/release resources. + */ + H5Tclose(datatype); + H5Dclose(dataset); + H5Sclose(dataspace); + H5Sclose(memspace); + H5Fclose(file); + H5Pclose(fapl); + + return 0; +} +#endif + diff --git a/test/dpss_write.c b/test/dpss_write.c new file mode 100644 index 0000000..bd0a318 --- /dev/null +++ b/test/dpss_write.c @@ -0,0 +1,149 @@ +/* + * Copyright © 1998 NCSA + * All rights reserved. + * + * Programmer: Saurabh Bagchi (bagchi@uiuc.edu) + * Friday, August 6, 1999. + * + * Modifications: Thomas Radke (tradke@aei-potsdam.mpg.de) + * Modified to work with DPSS Virtual File Driver. + */ + +/* Test the following functionality of the DPSS driver. + 1. Open a remote file for write. + 2. Create a new dataset within the file. + 3. Create a local memory buffer to hold the data. + 4. Write the local data to the remote dataset. +*/ +#include <h5test.h> + +#ifndef HAVE_DPSS +int main(void) +{ + printf("Test skipped because DPSS driver not available\n"); + return 0; +} +#else + +#define DATASETNAME "IntArray" +#define NX 100 /* dataset dimensions */ +#define NY 100 +#define RANK 2 + +int main (int argc, char **argv) +{ + + hid_t fapl =-1, file; + hid_t dataspace, datatype, dataset; + hsize_t dimsf[2]; + + herr_t status = 0; + int data[NX][NY]; /* data to write */ + int i, j; + + if (argc != 2) { + fprintf (stderr, "Usage: %s <URL>\n", argv [0]); + exit (0); + } + + /* + * Data and output buffer initialization. + */ + for (j = 0; j < NX; j++) { + for (i = 0; i < NY; i++) + data[j][i] = i + j; + } + /* + * 0 1 2 3 4 5 + * 1 2 3 4 5 6 + * 2 3 4 5 6 7 + * 3 4 5 6 7 8 + * 4 5 6 7 8 9 + */ + + /* Create access property list and set the driver to DPSS */ + fapl = H5Pcreate (H5P_FILE_ACCESS); + if (fapl < 0) { + printf (" H5Pcreate failed. \n"); + return -1; + } + + status = H5Pset_fapl_dpss (fapl); + if (status < 0) { + printf ("H5Pset_fapl_dpss failed. \n"); + return -1; + } + + /* + * Create a new file using H5F_ACC_TRUNC access, + * default file creation properties, and DPSS file + * access properties. + */ + file = H5Fcreate(argv [1], H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + if (file < 0) { + printf ("Failed to create file instance '%s'\n", argv [1]); + return -1; + } + + /* + * Describe the size of the array and create the data space for fixed + * size dataset. + */ + dimsf[0] = NX; + dimsf[1] = NY; + dataspace = H5Screate_simple(RANK, dimsf, NULL); + if (dataspace < 0) { + printf ("H5Screate failed. \n"); + return -1; + } + + /* + * Define datatype for the data in the file. + * We will store little endian INT numbers. + */ + datatype = H5Tcopy(H5T_NATIVE_INT); + if (datatype < 0) { + printf ("H5Tcopy failed. \n"); + return -1; + } + + status = H5Tset_order(datatype, H5T_ORDER_LE); + if (status < 0) { + printf ("H5Tset_order failed. \n"); + return -1; + } + + /* + * Create a new dataset within the file using defined dataspace and + * datatype and default dataset creation properties. + */ + dataset = H5Dcreate(file, DATASETNAME, datatype, dataspace, + H5P_DEFAULT); + if (dataset < 0) { + printf ("H5Dcreate failed. \n"); + return -1; + } + + /* + * Write the data to the dataset using default transfer properties. + */ + status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, data); + if (status < 0) { + printf ("H5Dwrite failed. \n"); + return -1; + } + + /* + * Close/release resources. + */ + H5Sclose(dataspace); + H5Tclose(datatype); + H5Dclose(dataset); + H5Fclose(file); + H5Pclose(fapl); + + return 0; +} +#endif + |