Skip to content

Commit

Permalink
Merge pull request #388 from DrylandEcology/feature_nc_progress
Browse files Browse the repository at this point in the history
Create a "Progress" netCDF

* Simulation progress (success/failure) is now tracked by `"progress.nc"` for `"netCDF"`-based SOILWAT2 (close #387; @N1ckP3rsl3y, @dschlaep).
  
* A user provided `"progress.nc"` (e.g., from a previous partial run) that describes the simulation `"progress"`. Specifications must be consistent with `"domain.nc"`. If absent, it is automatically generated based on `"domain.nc"`.

* Progress tracking makes re-starts after partial completion of the simulation set by an earlier execution possible.

* Simple progress messages printed to the console (if not quiet mode).
  • Loading branch information
dschlaep authored Jan 10, 2024
2 parents 8e3adf3 + 84dbffc commit 07ba534
Show file tree
Hide file tree
Showing 18 changed files with 774 additions and 99 deletions.
10 changes: 9 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
* For `"netCDF"`-based SOILWAT2, information about the `"domain"`
(i.e., simulation units and their geographic locations) is obtained from
`"domain.nc"` (#361; @N1ckP3rsl3y, @dschlaep).
* For `"netCDF"`-based SOILWAT2, simulation progress (success/failure) is
tracked by `"progress.nc"` (#387; @N1ckP3rsl3y, @dschlaep);
progress tracking makes re-starts after partial completion of the
simulation set by an earlier execution possible.


* Tests now utilize the same template/deep-copy approach (@dschlaep),
i.e., input files from `test/example/` populate a `"template"` and
Expand Down Expand Up @@ -79,14 +84,17 @@
* New input directory `"Input_nc/"` that describes `"netCDF"`-based inputs
(paths provided by new entries in `"files.in"`).
* New text input file `"files_nc.in"` that lists for each input purpose
(currently, only `"domain"` is implemented)
(currently, `"domain"` and `"progress"` are implemented)
the path to the `"netCDF"` input file and associated variable name.
* New text input file `"attribues_nc.in"` to provide global attributes and a
geographic (and optionally a projected) `"CRS"` (coordinate reference system)
that describe the `"domain.nc"`.
* A user provided `"domain.nc"` that describes the simulation `"domain"`.
Specifications must be consistent with `"domain.in"`.
If absent, a template is automatically generated based on `"domain.in"`.
* A user provided `"progress.nc"` that describes the simulation `"progress"`.
Specifications must be consistent with `"domain.nc"`.
If absent, it is automatically generated based on `"domain.nc"`.


# SOILWAT2 v7.2.0
Expand Down
5 changes: 5 additions & 0 deletions doc/additional_pages/A_SOILWAT2_user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ on your side.
CPPFLAGS=-DSWNETCDF NC_CFLAGS="-I/path/to/include" NC_LIBS="-L/path/to/lib" make
```

* User-specified username and hostname, e.g.,
```{.sh}
USERNAME=nobody HOSTNAME=nowhere make
```

<br>


Expand Down
9 changes: 6 additions & 3 deletions include/SW_Domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ extern "C" {
void SW_DOM_calc_ncSuid(SW_DOMAIN* SW_Domain, unsigned long suid,
unsigned long ncSuid[]);
void SW_DOM_calc_nSUIDs(SW_DOMAIN* SW_Domain);
Bool SW_DOM_CheckProgress(char* domainType, unsigned long ncSuid[]);
void SW_DOM_CreateProgress(SW_DOMAIN* SW_Domain);
Bool SW_DOM_CheckProgress(int progFileID, int progVarID,
unsigned long ncSuid[], LOG_INFO* LogInfo);
void SW_DOM_CreateProgress(SW_DOMAIN* SW_Domain, LOG_INFO* LogInfo);
void SW_DOM_read(SW_DOMAIN* SW_Domain, LOG_INFO* LogInfo);
void SW_DOM_SetProgress(char* domainType, unsigned long ncSuid[]);
void SW_DOM_SetProgress(Bool isFailure, const char* domType, int progFileID,
int progVarID, unsigned long ncSuid[],
LOG_INFO* LogInfo);
void SW_DOM_SimSet(SW_DOMAIN* SW_Domain, unsigned long userSUID,
LOG_INFO* LogInfo);
void SW_DOM_deepCopy(SW_DOMAIN* source, SW_DOMAIN* dest, LOG_INFO* LogInfo);
Expand Down
6 changes: 4 additions & 2 deletions include/SW_datastructs.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#endif

#define SW_NFILES 26 // For `InFiles`
#define SW_NVARNC 1 // For `InFilesNC`
#define SW_NVARNC 2 // For `InFilesNC`


/* =================================================== */
Expand Down Expand Up @@ -769,7 +769,8 @@ typedef struct {
Bool stopRun; // Specifies if an error has occurred and
// the program needs to stop early (backtrack)

Bool QuietMode; /**< Don't print version, error message, or notify user about logfile (only used by SOILWAT2) */
Bool QuietMode, /**< Don't print version, error message, or notify user about logfile (only used by SOILWAT2) */
printProgressMsg; /**< Do/don't print progress messages to the console */
} LOG_INFO;

typedef struct {
Expand Down Expand Up @@ -1066,6 +1067,7 @@ typedef struct {
char *InFilesNC[SW_NVARNC];

int ncFileIDs[SW_NVARNC];
int ncVarIDs[SW_NVARNC];
} SW_NETCDF;

/* =================================================== */
Expand Down
18 changes: 14 additions & 4 deletions include/SW_netCDF.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ extern "C" {
/* --------------------------------------------------- */

#define vNCdom 0 // Domain netCDF index within `InFilesNC` and `varNC` (SW_NETCDF)
#define vNCprog 1 // Progress netCDF index within `InFilesNC` and `varNC` (SW_NETCDF)

#define DOMAIN_TEMP "Input_nc/domain_template.nc"

Expand All @@ -21,17 +22,26 @@ extern "C" {
void SW_NC_check(SW_DOMAIN* SW_Domain, int ncFileID, const char* fileName,
LOG_INFO* LogInfo);
void SW_NC_create_domain_template(SW_DOMAIN* SW_Domain, LOG_INFO* LogInfo);
void SW_NC_create_template(const char* fileName, unsigned long timeSize,
unsigned long vertSize, const char* varName,
char* varAttributes[], LOG_INFO* LogInfo);
void SW_NC_create_template(const char* domFile, int domFileID,
const char* fileName, int* newFileID, int newVarType,
unsigned long timeSize, unsigned long vertSize, const char* varName,
const char* attNames[], const char* attVals[], int numAtts, Bool isInput,
const char* freq, LOG_INFO* LogInfo);
void SW_NC_create_progress(SW_DOMAIN* SW_Domain, LOG_INFO* LogInfo);
void SW_NC_set_progress(Bool isFailure, const char* domType, int progFileID,
int progVarID, unsigned long ncSUID[],
LOG_INFO* LogInfo);
Bool SW_NC_check_progress(int progFileID, int progVarID,
unsigned long ncSUID[], LOG_INFO* LogInfo);
void SW_NC_read_inputs(SW_ALL* sw, SW_DOMAIN* SW_Domain, unsigned long ncSUID[],
LOG_INFO* LogInfo);
void SW_NC_check_input_files(SW_DOMAIN* SW_Domain, LOG_INFO* LogInfo);
void SW_NC_read(SW_NETCDF* SW_netCDF, PATH_INFO* PathInfo, LOG_INFO* LogInfo);
void SW_NC_init_ptrs(SW_NETCDF* SW_netCDF);
void SW_NC_deconstruct(SW_NETCDF* SW_netCDF);
void SW_NC_open_files(SW_NETCDF* SW_netCDF, LOG_INFO* LogInfo);
void SW_NC_open_dom_prog_files(SW_NETCDF* SW_netCDF, LOG_INFO* LogInfo);
void SW_NC_close_files(SW_NETCDF* SW_netCDF);
void SW_NC_deepCopy(SW_NETCDF* source, SW_NETCDF* dest, LOG_INFO* LogInfo);

#ifdef __cplusplus
}
Expand Down
1 change: 1 addition & 0 deletions include/Times.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ double diff_walltime(WallTimeSpec start, Bool ok_start);
void SW_WT_StartTime(SW_WALLTIME *wt);
void SW_WT_TimeRun(WallTimeSpec ts, Bool ok_ts, SW_WALLTIME *wt);
void SW_WT_ReportTime(SW_WALLTIME wt, LOG_INFO* LogInfo);
void timeStringISO8601(char *timeString, int stringLength);

#ifdef __cplusplus
}
Expand Down
1 change: 1 addition & 0 deletions include/filefuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Bool MkDir(const char *dname, LOG_INFO* LogInfo);
Bool RemoveFiles(const char *fspec, LOG_INFO* LogInfo);
Bool CopyFile(const char *from, const char *to, LOG_INFO* LogInfo);
void LogError(LOG_INFO* LogInfo, const int mode, const char *fmt, ...);
void sw_message(const char *msg);

int key_to_id(const char* key, const char **possibleKeys,
int numPossKeys);
Expand Down
5 changes: 3 additions & 2 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ SHELL = /bin/sh

#------ Identification
SW2_VERSION := "$(shell git describe --abbrev=7 --dirty --always --tags)"
HOSTNAME := "$(shell uname -sn)"
HOSTNAME ?= "$(shell uname -sn)"
USERNAME ?= "$(USER)"

sw_info := -DSW2_VERSION=\"$(SW2_VERSION)\" \
-DUSERNAME=\"$(USER)\" \
-DUSERNAME=\"$(USERNAME)\" \
-DHOSTNAME=\"$(HOSTNAME)\"


Expand Down
70 changes: 51 additions & 19 deletions src/SW_Control.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,25 @@ void SW_CTL_RunSimSet(SW_ALL *sw_template, SW_OUTPUT_POINTERS SW_OutputPtrs[],
char tag_suid[32]; /* 32 = 11 character for "(suid = ) " + 20 character for ULONG_MAX + '\0' */
tag_suid[0] = '\0';

Check warning on line 211 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L211

Added line #L211 was not covered by tests
WallTimeSpec tss, tsr;
Bool ok_tss = swFALSE, ok_tsr = swFALSE;
Bool ok_tss = swFALSE, ok_tsr = swFALSE, ok_suid;

Check warning on line 213 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L213

Added line #L213 was not covered by tests

int progFileID = 0; // Value does not matter if SWNETCDF is not defined
int progVarID = 0; // Value does not matter if SWNETCDF is not defined

Check warning on line 216 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L215-L216

Added lines #L215 - L216 were not covered by tests

#if defined(SWNETCDF)
progFileID = SW_Domain->netCDFInfo.ncFileIDs[vNCprog];
progVarID = SW_Domain->netCDFInfo.ncVarIDs[vNCprog];
#endif

set_walltime(&tss, &ok_tss);

Check warning on line 223 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L223

Added line #L223 was not covered by tests

#if defined(SOILWAT)
if(main_LogInfo->printProgressMsg) {
sw_message("is running simulations across the domain ...");

Check warning on line 227 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L226-L227

Added lines #L226 - L227 were not covered by tests
}
#endif

/* Loop over suids in simulation set of domain */
for(suid = SW_Domain->startSimSet; suid < SW_Domain->endSimSet; suid++)

Check warning on line 232 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L232

Added line #L232 was not covered by tests
{
/* Check wall time against limit */
Expand All @@ -229,41 +244,53 @@ void SW_CTL_RunSimSet(SW_ALL *sw_template, SW_OUTPUT_POINTERS SW_OutputPtrs[],

LOG_INFO local_LogInfo;
sw_init_logs(main_LogInfo->logfp, &local_LogInfo);
local_LogInfo.printProgressMsg = main_LogInfo->printProgressMsg;

Check warning on line 247 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L246-L247

Added lines #L246 - L247 were not covered by tests


/* Check if suid needs to be simulated */
SW_DOM_calc_ncSuid(SW_Domain, suid, ncSuid);

Check warning on line 251 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L251

Added line #L251 was not covered by tests
if(SW_DOM_CheckProgress(SW_Domain->DomainType, ncSuid)) {

nSims++; // Counter of simulation runs
ok_suid = SW_DOM_CheckProgress(progFileID, progVarID, ncSuid,

Check warning on line 253 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L253

Added line #L253 was not covered by tests
&local_LogInfo);

if(ok_suid && !local_LogInfo.stopRun) {

Check warning on line 256 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L256

Added line #L256 was not covered by tests
/* Count simulation run */
nSims++;

Check warning on line 258 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L258

Added line #L258 was not covered by tests

/* Simulate suid */
set_walltime(&tsr, &ok_tsr);
SW_CTL_run_sw(sw_template, SW_Domain, ncSuid,

Check warning on line 262 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L261-L262

Added lines #L261 - L262 were not covered by tests
SW_OutputPtrs, NULL, &local_LogInfo);
SW_WT_TimeRun(tsr, ok_tsr, SW_WallTime);

Check warning on line 264 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L264

Added line #L264 was not covered by tests

if(local_LogInfo.stopRun) {
main_LogInfo->numDomainErrors++; // Counter of simulation units with error
/* Report progress for suid */
SW_DOM_SetProgress(local_LogInfo.stopRun,
SW_Domain->DomainType, progFileID,

Check warning on line 268 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L267-L268

Added lines #L267 - L268 were not covered by tests
progVarID, ncSuid, &local_LogInfo);
}

} else {
// Set simulation run progress
SW_DOM_SetProgress(SW_Domain->DomainType, ncSuid);
}
/* Report errors and warnings for suid */
if(local_LogInfo.stopRun) {
main_LogInfo->numDomainErrors++; // Counter of simulation units with error

Check warning on line 274 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L273-L274

Added lines #L273 - L274 were not covered by tests
}

if (local_LogInfo.numWarnings > 0) {
main_LogInfo->numDomainWarnings++; // Counter of simulation units with warnings
}
if (local_LogInfo.numWarnings > 0) {
main_LogInfo->numDomainWarnings++; // Counter of simulation units with warnings

Check warning on line 278 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L277-L278

Added lines #L277 - L278 were not covered by tests
}

if (local_LogInfo.stopRun || local_LogInfo.numWarnings > 0) {
snprintf(tag_suid, 32, "(suid = %lu) ", suid + 1);
sw_write_warnings(tag_suid, &local_LogInfo);
}
if (local_LogInfo.stopRun || local_LogInfo.numWarnings > 0) {
snprintf(tag_suid, 32, "(suid = %lu) ", suid + 1);
sw_write_warnings(tag_suid, &local_LogInfo);

Check warning on line 283 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L281-L283

Added lines #L281 - L283 were not covered by tests
}
}

if (nSims == main_LogInfo->numDomainErrors) {
/* Produce global error if all suids failed */
if (nSims > 0 && nSims == main_LogInfo->numDomainErrors) {
LogError(

Check warning on line 289 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L288-L289

Added lines #L288 - L289 were not covered by tests
main_LogInfo,
LOGERROR,
"All simulated units produced errors."
"All simulated units (n = %zu) produced errors.",
nSims
);
}

Expand Down Expand Up @@ -364,7 +391,7 @@ void SW_CTL_setup_domain(unsigned long userSUID,
}

// Open necessary netCDF input files and check for consistency with domain
SW_NC_open_files(&SW_Domain->netCDFInfo, LogInfo);
SW_NC_open_dom_prog_files(&SW_Domain->netCDFInfo, LogInfo);
if(LogInfo->stopRun) {
return; // Exit function prematurely due to error
}
Expand All @@ -376,6 +403,11 @@ void SW_CTL_setup_domain(unsigned long userSUID,
}
#endif

SW_DOM_CreateProgress(SW_Domain, LogInfo);
if(LogInfo->stopRun) {
return; // Exit function prematurely due to error

Check warning on line 408 in src/SW_Control.c

View check run for this annotation

Codecov / codecov/patch

src/SW_Control.c#L408

Added line #L408 was not covered by tests
}

SW_DOM_SimSet(SW_Domain, userSUID, LogInfo);
}

Expand Down
Loading

0 comments on commit 07ba534

Please sign in to comment.