diff options
Diffstat (limited to 'src/H5Cmpio.c')
-rw-r--r-- | src/H5Cmpio.c | 205 |
1 files changed, 117 insertions, 88 deletions
diff --git a/src/H5Cmpio.c b/src/H5Cmpio.c index e17aacd..4e88e44 100644 --- a/src/H5Cmpio.c +++ b/src/H5Cmpio.c @@ -43,13 +43,13 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* Files */ #include "H5FDprivate.h" /* File drivers */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#include "H5SLprivate.h" /* Skip lists */ -#ifdef H5_HAVE_PARALLEL +#ifdef H5_HAVE_PARALLEL /****************/ /* Local Macros */ /****************/ @@ -64,6 +64,9 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5C__collective_write(H5F_t *f, hid_t dxpl_id, + H5SL_t *collective_write_list); +static herr_t H5C__collective_write_free(void *_item, void *key, void *op_data); /*********************/ @@ -80,6 +83,9 @@ /* Local Variables */ /*******************/ +/* Declare a free list to manage the H5C_collective_write_t struct */ +H5FL_DEFINE(H5C_collective_write_t); + /*------------------------------------------------------------------------- @@ -261,7 +267,7 @@ H5C_apply_candidate_list(H5F_t * f, /* Create skip list of entries for collective write */ if(NULL == (collective_write_list = H5SL_create(H5SL_TYPE_HADDR, NULL))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for entries") - } + } /* end if */ n = num_candidates / mpi_size; m = num_candidates % mpi_size; @@ -376,7 +382,7 @@ H5C_apply_candidate_list(H5F_t * f, if(TRUE == entry_ptr->coll_access) { entry_ptr->coll_access = FALSE; H5C__REMOVE_FROM_COLL_LIST(cache_ptr, entry_ptr, FAIL) - } + } /* end if */ } /* end else */ } /* end for */ @@ -453,10 +459,8 @@ H5C_apply_candidate_list(H5F_t * f, * will not call either the pre_serialize or serialize callbacks. */ - if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, - H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, - NULL, NULL) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") + if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL, NULL) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't clear entry.") } /* end if */ /* Else, if this process needs to flush this entry. */ @@ -500,9 +504,9 @@ H5C_apply_candidate_list(H5F_t * f, cache_ptr->entries_removed_counter = 0; cache_ptr->last_entry_removed_ptr = NULL; - if(H5C__flush_single_entry(f, dxpl_id, flush_ptr, H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, - NULL, collective_write_list) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't flush entry.") + /* Add this entry to the list of entries to collectively write */ + if(H5C__flush_single_entry(f, dxpl_id, flush_ptr, H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL, collective_write_list) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry.") if ( ( cache_ptr->entries_removed_counter > 1 ) || ( cache_ptr->last_entry_removed_ptr == entry_ptr ) ) @@ -655,14 +659,12 @@ H5C_apply_candidate_list(H5F_t * f, entries_cleared++; #if ( H5C_APPLY_CANDIDATE_LIST__DEBUG > 1 ) - HDfprintf(stdout, "%s:%d: clearing 0x%llx.\n", FUNC, mpi_rank, - (long long)clear_ptr->addr); + HDfprintf(stdout, "%s:%d: clearing 0x%llx.\n", FUNC, mpi_rank, + (long long)clear_ptr->addr); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ - if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, - H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, - NULL, NULL) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") + if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL, NULL) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't clear entry.") } /* end else-if */ /* Else, if this process needs to independently flush this entry. */ @@ -677,9 +679,9 @@ H5C_apply_candidate_list(H5F_t * f, (long long)flush_ptr->addr); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ - if(H5C__flush_single_entry(f, dxpl_id, flush_ptr, H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, - NULL, collective_write_list) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") + /* Add this entry to the list of entries to collectively write */ + if(H5C__flush_single_entry(f, dxpl_id, flush_ptr, H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL, collective_write_list) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't clear entry.") } /* end else-if */ } /* end if */ @@ -712,16 +714,15 @@ H5C_apply_candidate_list(H5F_t * f, if (delayed_ptr) { if (delayed_ptr->clear_on_unprotect) { - if(H5C__flush_single_entry(f, dxpl_id, delayed_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG, - NULL, NULL) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't flush entry collectively.") + if(H5C__flush_single_entry(f, dxpl_id, delayed_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG, NULL, NULL) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry.") entry_ptr->clear_on_unprotect = FALSE; entries_cleared++; } else if (delayed_ptr->flush_immediately) { - if(H5C__flush_single_entry(f, dxpl_id, delayed_ptr, H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, - NULL, collective_write_list) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't flush entry collectively.") + /* Add this entry to the list of entries to collectively write */ + if(H5C__flush_single_entry(f, dxpl_id, delayed_ptr, H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL, collective_write_list) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry collectively.") entry_ptr->flush_immediately = FALSE; entries_flushed++; @@ -731,15 +732,15 @@ H5C_apply_candidate_list(H5F_t * f, entries_flushed_or_cleared_last++; } /* end if */ + /* If we've deferred writing to do it collectively, take care of that now */ if(f->coll_md_write) { HDassert(collective_write_list); /* Write collective list */ - if(H5C_collective_write(f, - dxpl_id, - collective_write_list) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't write metadata collectively") - } + if(H5C__collective_write(f, dxpl_id, collective_write_list) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_WRITEERROR, FAIL, "Can't write metadata collectively") + } /* end if */ + /* ====================================================================== * * Finished flushing everything. * * ====================================================================== */ @@ -750,9 +751,9 @@ H5C_apply_candidate_list(H5F_t * f, HDassert((entries_flushed_collectively == entries_to_flush_collectively)); if((entries_flushed != entries_to_flush) || - (entries_cleared != entries_to_clear) || - (entries_flushed_or_cleared_last != entries_to_flush_or_clear_last) || - (entries_flushed_collectively != entries_to_flush_collectively)) + (entries_cleared != entries_to_clear) || + (entries_flushed_or_cleared_last != entries_to_flush_or_clear_last) || + (entries_flushed_collectively != entries_to_flush_collectively)) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry count mismatch.") done: @@ -760,7 +761,7 @@ done: candidate_assignment_table = (int *)H5MM_xfree((void *)candidate_assignment_table); if(collective_write_list) - if(H5SL_destroy(collective_write_list, H5C_collective_write_free, NULL) < 0) + if(H5SL_destroy(collective_write_list, H5C__collective_write_free, NULL) < 0) HDONE_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "failed to destroy skip list") FUNC_LEAVE_NOAPI(ret_value) @@ -1132,7 +1133,7 @@ H5C_mark_entries_as_clean(H5F_t * f, if(TRUE == entry_ptr->coll_access) { entry_ptr->coll_access = FALSE; H5C__REMOVE_FROM_COLL_LIST(cache_ptr, entry_ptr, FAIL) - } + } /* end if */ entry_ptr->clear_on_unprotect = TRUE; #if H5C_DO_SANITY_CHECKS @@ -1194,10 +1195,8 @@ H5C_mark_entries_as_clean(H5F_t * f, entry_ptr = entry_ptr->prev; entries_cleared++; - if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, - H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, - NULL, NULL) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") + if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL, NULL) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't clear entry.") } else { entry_ptr = entry_ptr->prev; @@ -1224,10 +1223,8 @@ H5C_mark_entries_as_clean(H5F_t * f, entry_ptr = entry_ptr->next; entries_cleared++; - if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, - H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, - NULL, NULL) < 0 ) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") + if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL, NULL) < 0 ) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't clear entry.") } else { entry_ptr = entry_ptr->next; @@ -1288,78 +1285,95 @@ done: *------------------------------------------------------------------------- */ herr_t -H5C_clear_coll_entries(H5C_t * cache_ptr, hbool_t partial) +H5C_clear_coll_entries(H5C_t *cache_ptr, hbool_t partial) { - int32_t list_len, coll_entries_cleared = 0; + int32_t clear_cnt; H5C_cache_entry_t * entry_ptr = NULL; - H5C_cache_entry_t * prev_ptr; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT entry_ptr = cache_ptr->coll_tail_ptr; - list_len = cache_ptr->coll_list_len; - - while(entry_ptr && (coll_entries_cleared < (partial ? list_len/2 : list_len))) { - prev_ptr = entry_ptr->coll_prev; + clear_cnt = (partial ? cache_ptr->coll_list_len / 2 : cache_ptr->coll_list_len); + while(entry_ptr && clear_cnt > 0) { + H5C_cache_entry_t *prev_ptr = entry_ptr->coll_prev; + /* Sanity check */ HDassert(entry_ptr->coll_access); + /* Mark entry as independent */ entry_ptr->coll_access = FALSE; H5C__REMOVE_FROM_COLL_LIST(cache_ptr, entry_ptr, FAIL) - coll_entries_cleared ++; + /* Decrement entry count */ + clear_cnt--; + + /* Advance to next entry */ entry_ptr = prev_ptr; - } + } /* end while */ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5C_clear_coll_entries */ -herr_t -H5C_collective_write(H5F_t *f, - hid_t dxpl_id, - H5SL_t *collective_write_list) + +/*------------------------------------------------------------------------- + * + * Function: H5C__collective_write + * + * Purpose: Perform a collective write of a list of metadata entries. + * + * Return: FAIL if error is detected, SUCCEED otherwise. + * + * Programmer: Mohamad Chaarawi + * February, 2016 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5C__collective_write(H5F_t *f, hid_t dxpl_id, H5SL_t *collective_write_list) { H5P_genplist_t *plist = NULL; - H5FD_mpio_xfer_t xfer_mode = H5FD_MPIO_COLLECTIVE; - H5FD_mpio_xfer_t orig_xfer_mode; - H5SL_node_t *node; - H5C_collective_write_t *item; + H5FD_mpio_xfer_t orig_xfer_mode = H5FD_MPIO_COLLECTIVE; int count; - void *base_buf; int *length_array = NULL; MPI_Aint *buf_array = NULL; MPI_Aint *offset_array = NULL; MPI_Datatype btype; - MPI_Datatype ftype; hbool_t btype_created = FALSE; + MPI_Datatype ftype; hbool_t ftype_created = FALSE; int mpi_code; - int i; herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT - - count = (int)H5SL_count(collective_write_list); + FUNC_ENTER_STATIC + /* Get original transfer mode */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list") - if(H5P_get(plist, H5D_XFER_IO_XFER_MODE_NAME, &orig_xfer_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O property") + /* Get number of entries in collective write list */ + count = (int)H5SL_count(collective_write_list); + if(count > 0) { + H5FD_mpio_xfer_t xfer_mode = H5FD_MPIO_COLLECTIVE; + H5SL_node_t *node; + H5C_collective_write_t *item; + void *base_buf; + int i; + if(H5P_set(plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O property") /* Allocate arrays */ if(NULL == (length_array = (int *)H5MM_malloc((size_t)count * sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for collective write table length array") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective write table length array") if(NULL == (buf_array = (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for collective buf table length array") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective buf table length array") if(NULL == (offset_array = (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for collective offset table length array") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective offset table length array") /* Fill arrays */ node = H5SL_first(collective_write_list); @@ -1367,6 +1381,7 @@ H5C_collective_write(H5F_t *f, if(NULL == (item = (H5C_collective_write_t *)H5SL_item(node))) HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't retrieve skip list item") + /* Set up initial array position & buffer base address */ length_array[0] = (int)item->length; base_buf = item->buf; buf_array[0] = (MPI_Aint)0; @@ -1378,28 +1393,31 @@ H5C_collective_write(H5F_t *f, if(NULL == (item = (H5C_collective_write_t *)H5SL_item(node))) HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't retrieve skip list item") + /* Set up array position */ length_array[i] = (int)item->length; buf_array[i] = (MPI_Aint)item->buf - (MPI_Aint)base_buf; offset_array[i] = (MPI_Aint)item->offset; + + /* Advance to next node & array location */ node = H5SL_next(node); i++; } /* end while */ - /* Create memory mpi type */ + /* Create memory MPI type */ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed(count, length_array, buf_array, MPI_BYTE, &btype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) btype_created = TRUE; if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&btype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) - /* Create file mpi type */ + /* Create file MPI type */ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed(count, length_array, offset_array, MPI_BYTE, &ftype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) ftype_created = TRUE; if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&ftype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) - /* Pass buf type, file type to the file driver. */ + /* Pass buf type, file type to the file driver */ if(H5FD_mpi_setup_collective(dxpl_id, &btype, &ftype) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O properties") @@ -1417,19 +1435,16 @@ H5C_collective_write(H5F_t *f, mpi_fh = *(MPI_File*)mpi_fh_p; /* just to match up with the 1st MPI_File_set_view from H5FD_mpio_write() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, - MPI_BYTE, "native", MPI_INFO_NULL))) + if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL))) HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) /* just to match up with MPI_File_write_at_all from H5FD_mpio_write() */ HDmemset(&mpi_stat, 0, sizeof(MPI_Status)); - if(MPI_SUCCESS != (mpi_code = MPI_File_write_at_all(mpi_fh, (MPI_Offset)0, NULL, 0, - MPI_BYTE, &mpi_stat))) + if(MPI_SUCCESS != (mpi_code = MPI_File_write_at_all(mpi_fh, (MPI_Offset)0, NULL, 0, MPI_BYTE, &mpi_stat))) HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at_all failed", mpi_code) /* just to match up with the 2nd MPI_File_set_view (reset) in H5FD_mpio_write() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, - MPI_BYTE, "native", MPI_INFO_NULL))) + if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL))) HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) } /* end else */ @@ -1453,23 +1468,37 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value); -} /* end H5C_collective_write() */ +} /* end H5C__collective_write() */ -herr_t -H5C_collective_write_free(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data) + +/*------------------------------------------------------------------------- + * + * Function: H5C__collective_write_free + * + * Purpose: Release node on collective write skiplist + * + * Return: FAIL if error is detected, SUCCEED otherwise. + * + * Programmer: Mohamad Chaarawi + * February, 2016 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5C__collective_write_free(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data) { H5C_collective_write_t *item = (H5C_collective_write_t *)_item; - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - HDassert(item); + /* Sanity check */ + HDassert(item); if(item->free_buf) item->buf = H5MM_xfree(item->buf); - /*!FIXME change to use free list for items */ - H5MM_free(item); + H5FL_FREE(H5C_collective_write_t, item); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5C_collective_write_free() */ +} /* end H5C__collective_write_free() */ #endif /* H5_HAVE_PARALLEL */ |