diff options
Diffstat (limited to 'src/H5Dmpio.c')
-rw-r--r-- | src/H5Dmpio.c | 77 |
1 files changed, 54 insertions, 23 deletions
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index d2c5267..a5899d4 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -113,9 +113,9 @@ typedef struct H5D_filtered_collective_io_info_t { } owners; struct { - MPI_Request *receive_requests_array; - unsigned char **receive_buffer_array; - int num_receive_requests; + MPI_Request *receive_requests_array; /* Array of receive requests posted to receive chunk modification data from other processes */ + unsigned char **receive_buffer_array; /* Array of receive buffers to store chunk modification data from other processes */ + int num_receive_requests; /* Number of entries in the receive_requests_array and receive_buffer_array arrays */ } async_info; } H5D_filtered_collective_io_info_t; @@ -348,7 +348,10 @@ done: * Purpose: Given arrays by MPI ranks, gathers them into a single array * which is either gathered to the rank specified by root when * allgather is false, or is distributed back to all ranks - * when allgather is true. If the sort_func argument is + * when allgather is true. The number of processes + * participating in the gather operation should be specified + * for nprocs and the MPI communicator to use should be + * specified for comm. If the sort_func argument is * specified, the list is sorted before being returned. * * If allgather is specified as true, root is ignored. @@ -1266,10 +1269,10 @@ if(H5DEBUG(D)) * 1. Construct a list of selected chunks in the collective IO * operation * A. If any chunk is being written to by more than 1 - * process, the process writing the most data to the - * chunk will take ownership of the chunk (the first - * process seen that is writing the most data becomes - * the new owner in the case of ties) + * process, the process writing to the chunk which + * currently has the least amount of chunks assigned + * to it becomes the new owner (in the case of ties, + * the lowest MPI rank becomes the new owner) * 2. If the operation is a write operation * A. Loop through each chunk in the operation * I. If this is not a full overwrite of the chunk @@ -1461,7 +1464,7 @@ done: H5MM_free(chunk_list[i].buf); H5MM_free(chunk_list); - } + } /* end if */ if (num_chunks_selected_array) H5MM_free(num_chunks_selected_array); @@ -1700,10 +1703,10 @@ done: * 1. Construct a list of selected chunks in the collective IO * operation * A. If any chunk is being written to by more than 1 - * process, the process writing the most data to the - * chunk will take ownership of the chunk (the first - * process seen that is writing the most data becomes - * the new owner in the case of ties) + * process, the process writing to the chunk which + * currently has the least amount of chunks assigned + * to it becomes the new owner (in the case of ties, + * the lowest MPI rank becomes the new owner) * 2. If the operation is a read operation * A. Loop through each chunk in the operation * I. Read the chunk from the file @@ -1947,11 +1950,11 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i if (collective_chunk_list){ H5MM_free(collective_chunk_list); collective_chunk_list = NULL; - } + } /* end if */ if (has_chunk_selected_array){ H5MM_free(has_chunk_selected_array); has_chunk_selected_array = NULL; - } + } /* end if */ } /* end for */ /* Free the MPI file and memory types, if they were derived */ @@ -1973,7 +1976,7 @@ done: H5MM_free(chunk_list[i].buf); H5MM_free(chunk_list); - } + } /* end if */ if (collective_chunk_list) H5MM_free(collective_chunk_list); @@ -2197,6 +2200,23 @@ H5D__cmp_filtered_collective_io_info_entry(const void *filtered_collective_io_in FUNC_LEAVE_NOAPI(H5F_addr_cmp(addr1, addr2)) } /* end H5D__cmp_filtered_collective_io_info_entry() */ + +/*------------------------------------------------------------------------- + * Function: H5D__cmp_filtered_collective_io_info_entry_owner + * + * Purpose: Routine to compare filtered collective chunk io info + * entries's original owner fields + * + * Description: Callback for qsort() to compare filtered collective chunk + * io info entries's original owner fields + * + * Return: -1, 0, 1 + * + * Programmer: Jordan Henderson + * Monday, Apr. 10th, 2017 + * + *------------------------------------------------------------------------- + */ static int H5D__cmp_filtered_collective_io_info_entry_owner(const void *filtered_collective_io_info_entry1, const void *filtered_collective_io_info_entry2) { @@ -2575,7 +2595,8 @@ done: * Purpose: Constructs a list of entries which contain the necessary * information for inter-process communication when performing * collective io on filtered chunks. This list is used by - * every process in operations that must be collectively done + * each process when performing I/O on locally selected chunks + * and also in operations that must be collectively done * on every chunk, such as chunk re-allocation, insertion of * chunks into the chunk index, etc. * @@ -2668,7 +2689,17 @@ done: /*------------------------------------------------------------------------- * Function: H5D__chunk_redistribute_shared_chunks * - * Purpose: + * Purpose: When performing a collective write on a Dataset with + * filters applied, this function is used to redistribute any + * chunks which are selected by more than one process, so as + * to preserve file integrity after the write by ensuring + * that any shared chunks are only modified by one process. + * + * The current implementation simply hands the list off to + * rank 0, which then scans the list and for each shared + * chunk, it redistributes the chunk to the process writing + * to the chunk which currently has the least amount of chunks + * assigned to it. * * Return: Non-negative on success/Negative on failure * @@ -2782,7 +2813,7 @@ H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_ty if (shared_chunks_info_array) { H5MM_free(shared_chunks_info_array); shared_chunks_info_array = NULL; - } + } /* end if */ /* Now that the chunks have been redistributed, each process must send its modification data * to the new owners of any of the chunks it previously possessed. Accordingly, each process @@ -2907,7 +2938,7 @@ done: for (i = 0; i < num_send_requests; i++) { if (mod_data[i]) H5MM_free(mod_data[i]); - } + } /* end for */ if (send_requests) H5MM_free(send_requests); @@ -3070,7 +3101,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk */ if (!chunk_entry->full_overwrite || io_info->op_type == H5D_IO_OP_READ) { buf_size = chunk_entry->chunk_states.chunk_current.length; - } + } /* end if */ else { hssize_t extent_npoints; @@ -3078,7 +3109,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") buf_size = (hsize_t) extent_npoints * type_info->src_type_size; - } + } /* end else */ chunk_entry->chunk_states.new_chunk.length = buf_size; @@ -3189,7 +3220,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk dataspace = NULL; } H5MM_free(chunk_entry->async_info.receive_buffer_array[i]); - } + } /* end for */ /* Filter the chunk */ if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, 0, &filter_mask, |