mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
Fix variable bounds check for parallel output
The following code is in nc4hdf.c, function `nc4_put_vara`. ``` /* Check dimension bounds. Remember that unlimited dimnsions can * put data beyond their current length. */ for (d2 = 0; d2 < var->ndims; d2++) { dim = var->dim[d2]; assert(dim && dim->dimid == var->dimids[d2]); if (!dim->unlimited) { if (start[d2] >= (hssize_t)fdims[d2]) BAIL_QUIET(NC_EINVALCOORDS); if (start[d2] + count[d2] > fdims[d2]) BAIL_QUIET(NC_EEDGE); } } ``` There is an issue when the process with the highest rank has zero items to output. As an example, if I have 4 mpi processes which are each writing the following amount of data: * rank 0: 0 items * rank 1: 2548 items * rank 2: 4352 items * rank 3: 0 items. I will define the variable to have a length of 6900 items (0 + 2548 + 4352 + 0). When I am outputting data to the variable, each rank will call nc_put_vara_longlong with the following start and count values: * rank 0: start = 0, count = 0 * rank 1: start = 0, count = 2548 * rank 2: start = 2548, count = 4352 * rank 3: start = 6900, count = 0. In each case, the `start` for rank N is equal to `start` for rank N-1 + `count` for rank N-1. This all works ok until the highest rank is writing 0 items. In that case, the `start` value for that rank is equal to the total size of the variable and the check in the code fragment shown above fails since `start[] == fdims[]`. This could be fixed in the application code by checking whether the `count` is zero and if so, then set `start` to 0 also, but I think that is a kluge that should not be required. Note that this test appears three times in this file. In one case, the check for non-zero count already exists, but not in the other two. This pull request adds the check to the other two tests.
This commit is contained in:
parent
fa6d64d018
commit
9290b31c9d
@ -617,7 +617,7 @@ nc4_put_vara(NC *nc, int ncid, int varid, const size_t *startp,
|
||||
log_dim_info(var, fdims, fmaxdims, start, count);
|
||||
#endif
|
||||
|
||||
/* Check dimension bounds. Remember that unlimited dimnsions can
|
||||
/* Check dimension bounds. Remember that unlimited dimensions can
|
||||
* put data beyond their current length. */
|
||||
for (d2 = 0; d2 < var->ndims; d2++)
|
||||
{
|
||||
@ -625,7 +625,7 @@ nc4_put_vara(NC *nc, int ncid, int varid, const size_t *startp,
|
||||
assert(dim && dim->dimid == var->dimids[d2]);
|
||||
if (!dim->unlimited)
|
||||
{
|
||||
if (start[d2] >= (hssize_t)fdims[d2])
|
||||
if (start[d2] >= (hssize_t)fdims[d2] && count[d2] > 0)
|
||||
BAIL_QUIET(NC_EINVALCOORDS);
|
||||
if (start[d2] + count[d2] > fdims[d2])
|
||||
BAIL_QUIET(NC_EEDGE);
|
||||
@ -979,7 +979,7 @@ nc4_get_vara(NC *nc, int ncid, int varid, const size_t *startp,
|
||||
else
|
||||
{
|
||||
/* Check for out of bound requests. */
|
||||
if (start[d2] >= (hssize_t)fdims[d2])
|
||||
if (start[d2] >= (hssize_t)fdims[d2] && count[d2] > 0)
|
||||
BAIL_QUIET(NC_EINVALCOORDS);
|
||||
if (start[d2] + count[d2] > fdims[d2])
|
||||
BAIL_QUIET(NC_EEDGE);
|
||||
|
Loading…
Reference in New Issue
Block a user