Skip to content

Commit

Permalink
Handle case when D*.fill_starts variables are not available in map files
Browse files Browse the repository at this point in the history
PR #174 added a feature to write missing values from the map files.
It add a new variable D*.fill_starts into the map file.
This commit checks if it is available. If not, it ignores that variable
and use D*.nreqs, as if there is no missing values.
  • Loading branch information
wkliao committed Sep 11, 2024
1 parent 3b814f7 commit 1e60cc1
Showing 1 changed file with 23 additions and 20 deletions.
43 changes: 23 additions & 20 deletions src/read_decomp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ int read_decomp (e3sm_io_config *cfg, e3sm_io_decom *decom) {
char name[128];
int err, rank, nprocs, ncid, varid, proc_start, proc_count;
int i, j, k, nreqs, *all_nreqs, *all_raw_nreqs, dimids[3], id;
int *fill_nreqs = NULL, has_raw_decom, decomp_nprocs;
int *fill_nreqs = NULL, has_fill_starts, has_raw_decom, decomp_nprocs;
MPI_Offset mpi_num, mpi_decomp_nprocs, start, count;
MPI_Info info = MPI_INFO_NULL;
e3sm_io_config decom_cfg;
Expand Down Expand Up @@ -230,20 +230,34 @@ int read_decomp (e3sm_io_config *cfg, e3sm_io_decom *decom) {
for (i=0; i<decom->ndims[id]; i++)
decom->dims[id][i] = (MPI_Offset)dims_int[i];

/* Obtain varid of request variable Dx.fill_starts, the starting index
* in offsets[] and lengths[] for elements to be filled with fill
* value. Note use Dx.fill_starts as the number of write requests, so
* writes stop at this index, without filling the missing elements.
*
* First, check if variable D*.fill_starts is available. The older
* versions, prior to PR #174, do not include this variable.
*/
sprintf (name, "D%d.fill_starts", id + 1);
err = driver->inq_varid (ncid, name, &varid);
has_fill_starts = 1;
if (err == NC_ENOTVAR)
has_fill_starts = 0;
else
CHECK_ERR

if (cfg->fill_mode && cfg->strategy == canonical) {
/* Read variable Dx.fill_starts, which stores the index of Dx.nreqs
* pointing to the first request that needs to be filled with fill
* values. In other words, Dx.nreqs[i] is always bigger than
* Dx.fill_starts[i] and (Dx.nreqs[i] - Dx.fill_starts[i]) is the
* number of requests that need to be filled.
*/
sprintf (name, "D%d.fill_starts", id + 1);
err = driver->inq_varid (ncid, name, &varid);
CHECK_ERR

fill_nreqs = (int *)malloc (decomp_nprocs * sizeof (int));
err = driver->get_vara (ncid, varid, MPI_INT, NULL, NULL, fill_nreqs, coll);
CHECK_ERR
if (has_fill_starts) {
fill_nreqs = (int *)malloc (decomp_nprocs * sizeof (int));
err = driver->get_vara (ncid, varid, MPI_INT, NULL, NULL, fill_nreqs, coll);
CHECK_ERR
}

/* Obtain varid of request variable Dx.nreqs. Note Dx.nreqs
* includes the missing elements to be filled if there is any
Expand All @@ -253,24 +267,13 @@ int read_decomp (e3sm_io_config *cfg, e3sm_io_decom *decom) {
err = driver->inq_varid (ncid, name, &varid);
CHECK_ERR
}
else {
/* Obtain varid of request variable Dx.fill_starts, the starting
* index in offsets[] and lengths[] for elements to be filled with
* fill value. Note use Dx.fill_starts as the number of write
* requests, so writes stop at this index, without filling the
* missing elements.
*/
sprintf (name, "D%d.fill_starts", id + 1);
err = driver->inq_varid (ncid, name, &varid);
CHECK_ERR
}

/* read all process's numbers of requests */
all_nreqs = (int *)malloc (decomp_nprocs * sizeof (int));
err = driver->get_vara (ncid, varid, MPI_INT, NULL, NULL, all_nreqs, coll);
CHECK_ERR

if (cfg->fill_mode && cfg->strategy == canonical) {
if (cfg->fill_mode && cfg->strategy == canonical && has_fill_starts) {
for (i=0; i<decomp_nprocs; i++) {
if (all_nreqs[i] != fill_nreqs[i])
break;
Expand Down

0 comments on commit 1e60cc1

Please sign in to comment.