diff options
-rw-r--r-- | src/H5FD.c | 83 | ||||
-rw-r--r-- | src/H5FDmpio.c | 9 | ||||
-rw-r--r-- | src/H5FDpublic.h | 14 |
3 files changed, 67 insertions, 39 deletions
@@ -2300,51 +2300,62 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t siz } /* end if */ /* Current read doesn't overlap with metadata accumulator, read it into accumulator */ else { - /* Flush current contents, if dirty */ - if(file->accum_dirty) { - if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0) - HRETURN_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed"); - - /* Reset accumulator dirty flag */ - file->accum_dirty=FALSE; - } /* end if */ - - /* Cache the new piece of metadata */ - /* Check if we need to resize the buffer */ - if(size>file->accum_buf_size) { - /* Grow the metadata accumulator buffer */ - if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL) - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + /* Only update the metadata accumulator if it is not dirty or if + * we are allowed to write the accumulator out during reads (when + * it is dirty) + */ + if(file->feature_flags&H5FD_FEAT_ACCUMULATE_METADATA_READ || !file->accum_dirty) { + /* Flush current contents, if dirty */ + if(file->accum_dirty) { + if ((file->cls->write)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0) + HRETURN_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write request failed"); - /* Note the new buffer size */ - file->accum_buf_size=size; - } /* end if */ - else { - /* Check if we should shrink the accumulator buffer */ - if(size<(file->accum_buf_size/H5FD_ACCUM_THROTTLE) && - file->accum_buf_size>H5FD_ACCUM_THRESHOLD) { - size_t new_size=(file->accum_buf_size/H5FD_ACCUM_THROTTLE); /* New size of accumulator buffer */ + /* Reset accumulator dirty flag */ + file->accum_dirty=FALSE; + } /* end if */ - /* Shrink the accumulator buffer */ - if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,new_size))==NULL) + /* Cache the new piece of metadata */ + /* Check if we need to resize the buffer */ + if(size>file->accum_buf_size) { + /* Grow the metadata accumulator buffer */ + if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,size))==NULL) HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); /* Note the new buffer size */ - file->accum_buf_size=new_size; + file->accum_buf_size=size; } /* end if */ - } /* end else */ + else { + /* Check if we should shrink the accumulator buffer */ + if(size<(file->accum_buf_size/H5FD_ACCUM_THROTTLE) && + file->accum_buf_size>H5FD_ACCUM_THRESHOLD) { + size_t new_size=(file->accum_buf_size/H5FD_ACCUM_THROTTLE); /* New size of accumulator buffer */ - /* Update accumulator information */ - file->accum_loc=addr; - file->accum_size=size; - file->accum_dirty=FALSE; + /* Shrink the accumulator buffer */ + if ((file->meta_accum=H5FL_BLK_REALLOC(meta_accum,file->meta_accum,new_size))==NULL) + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer"); + + /* Note the new buffer size */ + file->accum_buf_size=new_size; + } /* end if */ + } /* end else */ + + /* Update accumulator information */ + file->accum_loc=addr; + file->accum_size=size; + file->accum_dirty=FALSE; - /* Read into accumulator */ - if ((file->cls->read)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0) - HRETURN_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed"); + /* Read into accumulator */ + if ((file->cls->read)(file, H5FD_MEM_DEFAULT, dxpl_id, file->accum_loc, file->accum_size, file->meta_accum)<0) + HRETURN_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed"); - /* Copy into buffer */ - HDmemcpy(buf,file->meta_accum,size); + /* Copy into buffer */ + HDmemcpy(buf,file->meta_accum,size); + } /* end if */ + else { + /* Dispatch to driver */ + if ((file->cls->read)(file, type, dxpl_id, addr, size, buf)<0) + HRETURN_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed"); + } /* end else */ } /* end else */ } /* end if */ else { diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 0ec8db3..2d81469 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -944,6 +944,15 @@ H5FD_mpio_query(const H5FD_t *_file, unsigned long *flags /* out */) if(flags) { *flags=0; *flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */ + + /* Distinguish between updating the metadata accumulator on writes and + * reads. This is particularly (perhaps only, even) important for MPI-I/O + * where we guarantee that writes are collective, but reads may not be. + * If we were to allow the metadata accumulator to be written during a + * read operation, the application would hang. + */ + *flags|=H5FD_FEAT_ACCUMULATE_METADATA_WRITE; /* OK to accumulate metadata for faster writes */ + *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ } /* end if */ diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index 49c89bc..52a8dec 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -90,8 +90,16 @@ typedef enum H5FD_mem_t { * the library will attempt to cache metadata as it is written to the file * and build up a larger block of metadata to eventually pass to the VFL * 'write' routine. + * + * Distinguish between updating the metadata accumulator on writes and + * reads. This is particularly (perhaps only, even) important for MPI-I/O + * where we guarantee that writes are collective, but reads may not be. + * If we were to allow the metadata accumulator to be written during a + * read operation, the application would hang. */ -#define H5FD_FEAT_ACCUMULATE_METADATA 0x00000002 +#define H5FD_FEAT_ACCUMULATE_METADATA_WRITE 0x00000002 +#define H5FD_FEAT_ACCUMULATE_METADATA_READ 0x00000004 +#define H5FD_FEAT_ACCUMULATE_METADATA (H5FD_FEAT_ACCUMULATE_METADATA_WRITE|H5FD_FEAT_ACCUMULATE_METADATA_READ) /* * Defining the H5FD_FEAT_DATA_SIEVE for a VFL driver means that * the library will attempt to cache raw data as it is read from/written to @@ -99,13 +107,13 @@ typedef enum H5FD_mem_t { * http://www.mcs.anl.gov/~thakur/papers/romio-coll.ps.gz * http://www.mcs.anl.gov/~thakur/papers/mpio-high-perf.ps.gz */ -#define H5FD_FEAT_DATA_SIEVE 0x00000004 +#define H5FD_FEAT_DATA_SIEVE 0x00000008 /* * Defining the H5FD_FEAT_AGGREGATE_SMALLDATA for a VFL driver means that * the library will attempt to allocate a larger block for "small" raw data * and then sub-allocate "small" raw data requests from that larger block. */ -#define H5FD_FEAT_AGGREGATE_SMALLDATA 0x00000008 +#define H5FD_FEAT_AGGREGATE_SMALLDATA 0x00000010 /* Forward declaration */ |