-
Notifications
You must be signed in to change notification settings - Fork 542
Developer Guide
This page details instructions for developers of WAVEWATCH III® (henceforth WW3) to add features to the existing framework, including new science and technological advancements, improve performance, fix bugs etc. WW3 is a community model and we follow the GitFlow model to facilitate collaboration and contributions to WW3.
This guide will take you through the main steps and practical actions for contributing to WW3. If you are interested in further details, the WW3 Gitflow page provides more information on GitFlow. For information to clone, build and run WW3, see the Quick Start guide.
GitFlow is a branching style where there are two main branches, main
and develop
. The main
branch contains stable, tested code that is ready for production type use, while develop is a faster moving branch where recent developments are reintegrated too. There are two other types of branches, feature
and bugfix
. These two types of branches are created from the develop
branch for adding features or bug fixes respectively before being reintegrated to the develop
branch.
WW3 has one authoritative repository part of the NOAA-EMC organization. This repository is maintained by NCEP/EMC code managers and will be used to produce public releases and is the central reference to all copies of the code. In addition to the authoritative repository, there are trusted institutional repositories/forks. A developer may choose to create a fork from the authoritative repo or from one of the trusted institutional repos.
- Authoritative repository: NOAA-EMC/WW3
- Trusted institutional repositories:
All development will be made by forks out of one of these trusted institutional repositories. The develop
branch is the primary source of code that is currently being updated. All new feature branches are created from there, and completed development threads target updates to that branch via pull request.
Updates to the main
branch will be done by the authoritative fork. Updates to the develop
branch should be done via a pull request to the authoritative or trusted institutional forks.
To contribute to WW3, developers will fork the authoritative repo or one of the trusted institutional repos using their own GitHub accounts. In the developer's fork,
new developments should be made in a feature or bug fix branch created from the develop branch. Developers should make an effort to communicate via GitHub issues with
the code manager from the repository associated with the developer's fork to indicate what developments are being made.
Once a feature branch has been tested and is mature to become a candidate for reintegration to the main repo, the developer sends a pull request to the authoritative or institutional forks to start the process of reintegration.
The "fork and branch" workflow we are adopting is explained in more detail in this Scott's Weblog post. The main steps are:
- Create an issue associated to the new development.
- Fork the WW3 GitHub repository.
- Clone the forked repository to your local system.
- Add a Git remote for the original repository.
- Create a feature branch, make changes, commit and push changes to your GitHub fork.
- Communicate via GitHub issues with the source repository code manager to indicate what is being developed.
- Open a pull request from the new branch to the original repo.
- Clean up your fork after your pull request is merged.
Create a new issue on the GitHub page, choosing between the options for features or bugs. In the issue, complete the template as much as possible detailing the work that is to be done. If you are going to be doing the work, either assign yourself to the issue or indicate in the issue that you will follow up with a Pull Request.
- Create and account on github.com,
- On
github.com
choose one of the WW3 trusted repositories- Authoritative repository: NOAA-EMC/WW3
- Trusted institutional repositories:
- Locate and click the
fork
icon on the upper right-hand corner of the WW3 GitHub page.
This creates a full copy of the WW3 repository under your user account. More information can be found on GitHub documentation here.
You can now navigate to your GitHub dashboard and choose the newly-created fork. To start your development work, you need a copy of your WW3 fork on your local machine.
To do that, you must git clone
your fork locally. First, find the right address for the fork on your GitHub fork page clicking the "Clone or Download" dropdown menu. Then, on your local box:
git clone https://github.com/<username>/WW3.git
If you are using ssh:
git clone ssh://[email protected]/<username>/WW3.git
Remotes are GitHub repositories that are linked to your local copy. A first remote origin
is automatically created when you clone a repo. In this case, that links your local copy to the fork you created in your GitHub account. You can keep your local copy synced with your fork and vice-versa by simply using commands such as git pull
to sync the local copy with the fork, or git push
the way around. We will also want to keep the local copy and your fork synced with changes made in the repository your forked from.
That is possible by creating a remote link within your local copy that points to the upstream
repo:
git remote add upstream https://github.com/NOAA-EMC/WW3
or
git remote add upstream https://github.com/<TrustedInstitution>/WW3
Syncing your local copy to the upstream remote is done within your local copy by using the commands:
-
Change to the active development branch
git checkout develop
-
Copy over changes to upstream repo
git fetch upstream
-
Merge changes to your local repo
git merge upstream/develop
-
Push changes to your GitHub fork
git push
Likewise, when the main
changes, you will want to sync your fork accordingly.
Using git push
to upstream repos will fail, and should not be attempted.
Adding new or modifying existing features of WW3 should be done in a feature
branch. Fixing a bug can be done in a bugfix
branch.
This involves the development cycle steps below.
Before you get started, please note some rules of engagement here:
- Create an issue with the planned feature update or reporting the bug fix being worked on.
- Create one
feature
orbugfix
branch for every single feature or single bugfix you will be working on. Do not bundle all features or bugfixes in a single branch,- This creates a situation where undeveloped features will get in the way of reintegrating mature work,
- Pull requests with more than one feature per branch will be asked to split their development into multiple pull requests.
The development cycle steps:
- Create a new feature branch from the
develop
branchgit checkout -b <branch name> develop
- Make changes to the files,
- Make sure to check out the Coding Best Practices for WW3 developer etiquette,
- Test your changes using the
regtests
- To ensure regression tests work, you need to download large files that are not part of the WW3 GitHub repo,
- In your local copy from the top level directory, run the script:
sh model/bin/ww3_from_ftp.sh
- Make note of the added files and ensure they remain untracked (eg, do not use
git add
for these files),
- Frequently commit your changes to the branch.
- Check changes made
git status
- Add files indicated by
status
git add <some files>
- Commit changes locally,
- Use a commit message in the form "
branchname
>: [description of changes]":
git commit -m "<branch name>: [description of changes and files affected]"
- Use a commit message in the form "
- Check changes made
- Push changes to your GitHub fork
git push origin <branch name>
Pull requests are proposed changes to a repository submitted by a user and accepted or rejected by the main repo code managers. This should happen when you made changes in one of your feature
branches that are mature and could become part of the WW3 package. Before you submit a pull request, make sure to verify if your changes satisfy our checklist for a developer submitting pull requests. When you get to that point, follow the guidelines well-established in GitHub:
-
Using your browser, navigate to the original repository you created your fork from.
- To the right of the Branch menu, click New pull request.
-
On the Compare page, click the highlighted link
compare across forks
. -
Confirm that the base fork is the repository you'd like to merge changes into.
- Use the base branch drop-down menu to select the branch of the upstream repository you'd like to merge changes into.
-
Use the head fork drop-down menu to select your fork,
- then use the compare branch drop-down menu to select the branch you made your changes in.
-
Type a title and description for your pull request. Follow the PR template instructions to provide the necessary details.
-
If you do not want to allow anyone with push access to the upstream repository to make changes to your PR, unselect Allow edits from maintainers.
-
To create a pull request that is ready for review, click Create Pull Request.
- To create a draft pull request, use the drop-down and select Create Draft Pull Request, then click Draft Pull Request.
For more information about draft pull requests, see About pull requests.
After your changes have been merged into the develop branch, it can be helpful to delete the branch with the feature and do any other clean-up in your fork. Now, you can restart the development cycle with new branches created from an up-to-date develop branch of the authoritative repository.
A series of regression tests are prepared to check the WW3 with different options and physics. Developers are encouraged to check their implementations with the regression tests to ensure the code compilation, consistency of model output and data reproducibility. Regression tests are enforced when new main or develop branches are created, and this typically involves running a complete set including all available regression tests with different configurations (see “The Matrix” section below). If you add new features, it is strongly encouraged that you add a regtest for the new feature, as outlined in the checklist for adding or modifying a regtest.
The following regression tests are available under retests directory:
Test Label | Description |
---|---|
ww3_tp1.1 | 1D propagation around the world along the equator (no land). |
ww3_tp1.2 | 1D propagation, along meridian (no land). |
ww3_tp1.3 | 1D propagation, shoaling test. |
ww3_tp1.4 | 1D propagation, spectral refraction (x). |
ww3_tp1.5 | 1D propagation, spectral refraction (y). |
ww3_tp1.6 | 1D propagation, wave blocking by current. |
ww3_tp1.7 | 1D propagation, IG wave generation. |
ww3_tp1.8 | 1D propagation, wave breaking on a beach. |
ww3_tp1.9 | 1D propagation, Beji and Battjes (1993) barred flume case. |
ww3_tp1.10 | 1D propagation, Bottom scattering beach. |
ww3_tp1.11 | 1D propagation, Test for spectral interpolation in ww3_bounc. |
ww3_tp2.1 | 2D propagation under angle with grid. |
ww3_tp2.2 | 2D propagation over half the globe without land (with directional spread). |
ww3_tp2.3 | 2D propagation, GSE test. |
ww3_tp2.4 | 2D propagation, East Pacific curvilinear grid test. |
ww3_tp2.5 | 2D propagation, Arctic Grid, curvilinear grid test. |
ww3_tp2.6 | 2D propagation, Limon Harbor unstructured grid test. |
ww3_tp2.7 | Reflection on a 2D unstructured grid. |
ww3_tp2.8 | Tidal constituents on a 2D regular grid. |
ww3_tp2.9 | Tests for obstruction grids. |
ww3_tp2.10 | Tests for SMC grid. |
ww3_tp2.11 | Tests for rotated grid. |
ww3_tp2.12 | Test for system tracking. |
ww3_tp2.13 | Test for propagation under angle with grid (tripole). |
ww3_tp2.14 | Test for toy-model using OASIS coupler. |
ww3_tp2.15 | Test for space-time extremes parameters. |
ww3_tp2.16 | Test for two-dimensional SMC propagation with Arctic pole handling. |
ww3_tp2.17 | Unstructured grid with Card Deck vs Domain Decomposition for Explicit vs Implicit schemes; grid integration (ww3_gint); grib2 outputs (ww3_grib). |
ww3_tp2.18 | Test for tidal constituents in ww3_prnc/ww3_prtide. |
ww3_tp2.19 | Unstructured grid with Domain Decomposition/Implicit schemes with Neumann Boundary Condition for Depth Breaking and Triad source terms (Boers 1996). |
ww3_tp2.20 | Vegetation source term (Anderson and Smith 2012). |
ww3_tp2.21 | Global Unstrucured Grid (periodicity and obstruction). |
ww3_ts1 | Source term test, time limited growth. |
ww3_ts2 | Source term test, fetch limited growth. |
ww3_ts3 | Source term test, hurricane with single moving grid. |
ww3_ts4 | Source term test, unresolved obstacles. |
ww3_tic1.1 | Wave-ice interaction, 1D test of S_{ice}. |
ww3_tic1.2 | Wave-ice interaction, 1D test of “shoaling” effect. |
ww3_tic1.3 | Wave-ice interaction, 1D test of refraction effect. |
ww3_tic1.4 | Wave-ice interaction, 1D test with ice floes and ice thickness. |
ww3_tic2.1 | Wave-ice interaction, 2D test of S_ice. |
ww3_tic2.2 | Wave-ice interaction, 2D test with non-uniform ice. |
ww3_tic2.3 | Wave-ice interaction, 2D test with uniform ice with increasing thickness. |
ww3_tbt1.1 | Wave-mud interaction, 1D test of S_mud. |
ww3_tbt2.1 | Wave-mud interaction, 2D test of S_mud. |
ww3_tpt1.1 | Tests for alternative spectral partitioning methods. |
ww3_ta1 | ww3_uprstrt, update the restart file of homogeneous conditions (1 point model). |
mww3_test_01 | Test for expanded grid mask with wetting and drying, etc. |
mww3_test_02 | Two-way nesting test with single inner grid. |
mww3_test_03 | Overlapping grids and two-way nesting tests (6-grid version with beach in high-resolution |
mww3_test_04 | Current or sea-mount test for two-way nesting with stationary swell conditions. |
mww3_test_05 | Three nested hurricane grids with moving grids test. |
mww3_test_06 | Tests for irregular grid(s) w/ ww3_multi. |
mww3_test_07 | Tests for unstructured grid(s) w/ ww3_multi. |
mww3_test_08 | Tests with wind and ice input. |
ww3_ufs1.1 | Tests for global 1deg grid w/ ww3_multi/ww3_multi_esmf; wind/current/ice inputs; ww3_grib outputs; grid integration (ww3_gint); restart/MPI task/thread reproducibility (ufs app). |
ww3_ufs1.2 | Tests for GFSv16 setup w/ ww3_multi/ww3_multi_esmf; wind/current/ice inputs; ww3_grib outputs; grid integration (ww3_gint); restart reproducibility (ufs app). |
ww3_ufs1.3 | Tests for GEFSv12 setup w/ ww3_multi; wind/ice inputs; ww3_grib outputs; grid integration (ww3_gint); restart reproducibility (ufs app). |
The above tests are contained in directories with the indicated tags within the regtest directory. A description of each test is summarized in the info file and required materials are in the input directories. A separate set of large input files should be downloaded from NOAA ftp site using the following script:
./model/bin/ww3_from_ftp.sh
Regression tests are run using the run_test script in the regtests/bin directory. How to run this script, including options, is shown by running run_test -h.
Note, in the transition from GNU to CMAKE regression testing an additional run_cmake_test exists. It is recommended to use this instead.
The Matrix: Comprehensive Regression Testing
A matrix of regression tests can be prepared in order to run a full suit of regression tests with different compiler options and HPC environment. This framework provides a way to run a larger set of regression tests, using a wider range of configurations. The practice is encouraged to ensure that changes made to the code will not unintentionally affect other parts of the code.
The list of required test can be modified in regtests/bin/matrix.base. Up to this point, there are two matrix_<machine> (matrix_ncep and matrix_datarmor) in regtests/bin/ to generate a matrix for the selected tests, defined in matrix.base. So far, these scripts are compatible with supercomputers used at NCEP and Ifremer/Datamor. Trusted institutions are encouraged to create their own versions of the matrix, which we will add to the bin directory in the future. The matrix_* scripts generate a batch-queue-ready script with the required modules for compilers, corresponding NetCDF and MPI libraries, and paths to METIS/PARMETIS/NC4, as well as the number of required cores used to execute the tests.
As part of the development framework in WAVEWATCH III®, prior to reintegrating feature/bugfix branches to the main or develop branches via a pull request, code managers at trusted institutions should check proposed code changes, comparing a matrix run made with the new branch with the stable develop branch, to ensure reproducibility of results and compilation. A set of scripts is available to assist in this process.
The following steps should be taken s part of the matrix comprehensive regression testing procedure:
- Clone the WW3 repository in (i.e. bf_branch or develop).
- Checkout the desired branch (develop/main if the control or the feature or bugfix branch to be tested. Make sure the feature or bugfix branch is up to date with Develop.
- Download the large binary files from ftp site by executing ./model/bin/ww3_from_ftp.sh
- If you do not have access to a machine with an existing matrix file, create your own by copying and existing matrix_<machine>.
- Edit the new matrix_<machine> to select the test list, required modules, set path and compiler option.
- Generate matrix by executing matrix_<machine>.
- Submit the matrix.
The matrix takes a while to complete, so it is recommended to split the matrix into multiple subsets and then run the matrix to shorten the total runtime of regression tests.
During runtime, a matrix log file is stored in a file determined by the wrapper script (default: matrix.out). This log file can be checked for compilation or other runtime errors by using a command such as “grep nri error matrix.out”. In case errors are found, which can be labeled “error”, “Error” and “ERROR” within matrix.out, the code manager/developer should debug the problem and repeat the process until a successful outcome is achieved.
After a successful matrix run, regression test outputs for the new feature/bugfix branch should be compared with the develop branch matrix outputs. The following steps are available:
- edit the path to the output of the regression test s for the develop branch in ./bin/matrix.comp
- execute ./bin/matrix.comp all, which compares all the regression tests and generates summary and full comparison.
If the differences are justified as a consequence of the new developments/changes in the feature branch, the code is ready for a pull request to the NOAA-EMC repo, or if from the latter, for a new release tag. If differences are unexpected, the proposed changes should be debugged until a successful outcome is attained.
Quick Links