Developer Advanced JULES-Rose tutorial
This aims to explain the importance of:
It is expected that you have:
- Completed the Rose User Guide.
- Completed the User Tutorial.
- Completed the User Quiz.
- Completed the Developer Tutorial.
- Completed the Developer Quiz.
OR have:
- Experience running rose-stem and JULES-Rose suites.
- Made complex changes to JULES-Rose suites.
- Made complex changes to JULES code including testing with rose-stem.
- Experience with FCM commands.
UMDP3
Coding Standards
The UM Systems team provide detailed guidance on software standards, which can be found in their UMDP3 pdf.
Adding rose-stem tests
- The cause of the differences is well understood, for example, bug fix, initialisation error, improvement to science. These are at the discretion of the reviewers.
- New tests.
Overview
The suite in rose-stem
is a regression testing suite.
It is used to verify that science/code changes do not break
existing science/code within the JULES (with any new science
switched off).
It does this by checking that the results of the modified
code and comparing them with Known Good Output (KGO)
which is produced from the trunk of the JULES code.
It is occasionally acceptable tests to fail and therefore for results not to compare exactly with the KGO. generally changes are very small and well understood and reasoned. It is acceptable when:
Rose stem app should never be changed other than by applying
the upgrade_jules_test_apps
script.
The upgrade_jules_test_apps
script runs the
upgrade macro which should only modify the namelists enough
for rose-stem tasks to pass.
The script can be run my moving to the top the code directory, running:
./bin/upgrade_jules_test_apps vnX.X_txxxwhere vnX.X_txxx is the most recent upgrade macro. This variable can be found in the
rose-meta/jules-standalone/versions.py
file.
Rose stem tests
Once you have identified the rose-stem test that you want to create to safe guard a science configuration then please try to develop the test.
A good starting point it to see if there is already and existing rose-stem test that is similar and then use that to tweak for the desired configuration.
Rose stem test names should be as descriptive as possible while still being reasonably short. For example: gswp2_irrig_limit_low_river_storage .
This rose-stem test was developed to test: Rose stem test with irrigation supply limited. Starting with no water in the rivers and lots in the deep layer, therefore irrigation water should be mainly taken from the deep layer.
Change, rose-stem/include/
: meto
,
vm
, jasmin
, ceh
,
niwa
etc. runtime*.rc
and
graph*.rc
files.
runtime*.rc
should include tasks [[ ]]
for the jules run (gswp2_irrig_limit_low_river_storage), KGO compare (nccmp_gswp2_irrig_limit_low_river_storage), housekeeping task (housekeep_gswp2_irrig_limit_low_river_storage).
graph*.rc
should include graph dependencies, for example:
"gswp2_irrig_limit_low_river_storage" : "fcm_make_mpi => \ gswp2_trip_spinup => gswp2_irrig_limit_low_river_storage => \ nccmp_gswp2_irrig_limit_low_river_storage => housekeep_gswp2_trip_spinup => \ housekeep_gswp2_irrig_limit_low_river_storage",
and add it to the correct groups:
"gswp2" : ["gswp2_rivers", "gswp2_trip", "gswp2_trip_restart", "gswp2_irrig_limit_low_river_storage",...]
Add you new rose-app.conf, e.g.
rose-stem/app/gswp2_irrig_limit_low_river_storage/rose-app.conf
Don't forget to
fcm add rose-stem/app/gswp2_irrig_limit_low_river_storage/rose-app.confyour new file with its directory structure.
Testing new rose-stem tests
Before you test your new rose-stem tests please run:
rose macro --fix -M /path/to/JULES/metadata/dir/ and OR /path/to/JULES/metadata/dir/bin/upgrade_jules_test_apps vnX.X_t<ticket_num>
Where the vnX.X_t<ticket_num>
is given in
the file rose-meta/jules-standalone/versions.py
.
New rose-stem tests mean that their will be new KGO.
Creating KGO for the New rose-stem tests (and in general)
If you are using the JULES VM, you will need to generate the appropriate KGO for testing. This is done using the trunk at the version from which your branch is taken:
fcm co fcm:jules.x_tr@<version> jules_trunk cd jules_trunk
KGO generation is done by using the rose-stem system to generate
the output and then moving it to the KGO directory.
The KGO version can be found by looking at
rose-stem/include/variables.rc
file.
# Using HOUSEKEEPING=false means the output is not deleted when it is finished with rose stem --group=all -S HOUSEKEEPING=false --new # Move the output to the KGO directory mkdir -p /jules/rose-stem-kgo/<KGO version> mv ~/cylc-run/jules_trunk/work/1/*/output/* /jules/rose-stem-kgo/<KGO version>
Testing local KGO
As part of your rose-stem test you may expect the KGO to fail for example you have created new rose-stem tests so no previous rose-stem test KGO exists yet.
You may wish to test your new local test KGO, but it is not compulsory.
First, commit your changes to your branch of the repository.
rose stem --group=all --new -S HOUSEKEEPING=false
The suite will stop with waiting and have failures, this is as expected.
Now we need to copy the `local test` KGO to a directory for testing.
JULES_VERSION=vn#.# TICKET_NUMBER=t### TEST_KGO_DIR=~$USERNAME/jules/rose-test-kgo/${JULES_VERSION}_${TICKET_NUMBER} mkdir -p ${TEST_KGO_DIR}
then edit KGO_DIR in the appropriate files:
For example at the Met Office:
/include/meto/runtime-xc40-cce.rc /include/meto/runtime-linux.rc
at JASMIN
/include/jasmin/runtime.rc
to point to the new location.
Copy the local test
KGO to the new directories.
The new test files will be in ~/cylc-run/<suitename>/work/1/*/output/*
Now stop the suite using the cylc gcycl GUI or
rose suite-shutdown --name=<SUITE_NAME> -- --now y
Run rose-stem on this branch
rose stem --group=all --new
If the tests are bit reproducible they will all pass this time and if not then this needs to be addressed.
All changes to the local copy will need to be reverted, you can use:
fcm st fcm revert <FILENAMES> fcm st
Note new KGO will be added to the central directories by the System Administrator at or just after the code is committed to the trunk.
Adding a complex upgrade macro
Values in a namelist are consolidated
This example shows an addition to the rose-meta/jules-standalone/versions.py
file to use only rfm and trip and point um_rfm and um_trip to
to the respective river values.
class vn47_t417(rose.upgrade.MacroUpgrade): """Upgrade macro from JULES by Kerry Smout-Day""" BEFORE_TAG = "vn4.7_t413" AFTER_TAG = "vn4.7_t417" def upgrade(self, config, meta_config=None): """Upgrade a JULES runtime app configuration. Point um_trip to trip, um_rfm to rfm as the values have been removed. """ river_value = self.get_setting_value(config, ["namelist:jules_rivers", "rivers_type"]) if river_value == "'um_trip'": self.change_setting_value(config, ["namelist:jules_rivers", "rivers_type"], 'trip') trip_msg= """ !!!!! NOTE: um_trip is now replaced by trip see jls #417 !!!! """ self.add_report(info=trip_msg, is_warning=True) elif river_value == "'um_rfm'": self.change_setting_value(config, ["namelist:jules_rivers", "rivers_type"], 'rfm') rfm_msg= """ !!!!! NOTE: um_rfm is now replaced by rfm see jls #417 !!!! """ self.add_report(info=rfm_msg, is_warning=True) return config, self.reports
Search a value and apply logic statements
This example shows an addition to the rose-meta/jules-standalone/versions.py
file to search for a value, ncptf in the jules_surface_types
namelist and if present do one thing else do something
different.
class vnXX_tXXX(rose.upgrade.MacroUpgrade): """Upgrade macro from JULES by Firstname Surname""" BEFORE_TAG = "vnY.Y_tYYY" AFTER_TAG = "vnX.X_tXXX" def upgrade(self, config, meta_config=None): """Upgrade a JULES runtime app configuration.""" ncpft_in = self.get_setting_value(config, ["namelist:jules_surface_types", "ncpft"]) if ncpft_in: ncpft = int(ncpft_in) self.add_setting(config, ["namelist:jules_cropparm", "nu_io"], ','.join(['0.0'] * ncpft)) else: self.add_setting(config, ["namelist:jules_cropparm", "nu_io"], "-1e20") return config, self.reports
Testing upgrade macros
To create a test branch from an existing dev branch, type:
fcm branch-create -k <ticket> --branch-of-branch -t test <test_branch_name> https://code.metoffice.gov.uk/svn/jules/main/branches/dev/<user>/<dev_branch_name> #or using the shorthands and FCM keywords fcm bc -k <ticket> --bob -t test <test_branch_name> fcm:jules.x_br/dev/<user>/<dev_branch_name>Using a test branch allows you and the reviewers to separate the results of the upgrade macro and metadata changes from other changes.
Check out your test branch.
fcm:jules.x_br/test/<user>/<test_branch_name>Then run the following command to upgrade the apps in
benchmark
and rose-stem
:
cd /path/to/your/test_branch_name/ ./bin/upgrade_jules_test_apps vnX.X_txxxNow you can check the changes using the following:
#use the fcm graphical diff tool
fcm diff -g
#check the metadata via rose edit
cd rose-stem
rose edit
#select the Metadata tab -> Check fail-if, warn-f
#select the Metadata tab -> Auto-fix all configurations (if the option is avaliable)
#Close the rose edit GUI usign the "x".
#run the rose-stem tests and add the trac.log to the further testing section
# of the Ticket Summary for the ticket.
cd ..
rose stem --group=all --new
Adding diagnostics
control/shared/???_utils_mod.F90
control/shared/???_vars_mod.F90
initialisation/shared/allocate_jules_arrays.F90
io/model_interface/extract_var.inc
io/model_interface/model_interface_mod.F90
io/model_interface/variable_metadata.inc
science/????/???_mod.F90
control/shared/???_extra_mod.F90
control/shared/???_vars_mod.F90
control/um/diagnostics_???_mod.F90
initialisation/shared/allocate_jules_arrays.F90
io/model_interface/extract_var.inc
io/model_interface/model_interface_mod.F90
io/model_interface/variable_metadata.inc
science/????/???_jls.F90
STASHmaster-meta.conf
STASHmaster_A
New diagnostics in JULES and the required UM change
This will may be a JULES-UM combined ticket.
For the UM working practices please see there Working Practices for UM Development page.
JULES code specific files to change
To add a new diagnostic that only requires a JULES change the
files to be changed in JULES src
are:
To add a new diagnostic that require JULES and UM changes the
files to be changed in JULES src
are:
See #358 JULES for a JULES UM combined example ticket. Thanks to Andy Wiltshire for allowing me to share this, however please do not contact him for advice, please contact jules-support@metoffice.gov.uk .
JULES doc specific files to change
A documentation branch will be needed and the new diagnosic must
be add to the correct section in the
docs/user_guide/source/output-variables.rst
file.
UM specific files to change
You will need to seek permission from code owners and apparoval from the appropriate boards, which will include FieldsFile and PP (FFPP). PP is the file format that archiving use. FFPP must be added as a Keyword in the UM ticket and a review from FFPP board to be provided and it must be signed off in the UM Ticket Summary.
The files that you will have to change are the UM rose-meta/um-atmos/HEAD/etc/stash/STASHmaster/
JULES and UM ticket example
See #358 JULES and #1987 UM for an example ticket. Thanks to Andy Wiltshire for allowing me to share this, however please do not contact him for advice, please contact jules-support@metoffice.gov.uk .
UM-JULES tickets and tests
Testing JULES with the UM code
This section assumes that your JULES changes do not have linked UM changes.
# check that there are no uncommitted changes for your branch. cd /path/to/JULES/branch_for_testing/ fcm st # should return nothing. cd /to/directory/for/checking/out/UMtrunk/into/ fcm co fcm:um.x_tr cd trunk rose stem --group=jules,developer --new --name=umtr_jlst### --source=. --source=/path/tp/jules/branch_for_testing # trac.log will appear in the cylc-run/umtr_jlst### when the rose-stem tests have finished.
The trac.log needs to be added to the ticket summary for the ticket to prove that the change does not affect the UM and that a combined UM-JULES ticket is not needed.
If the UM rose-stem tests fail, it may be because your changes require UM meta-data changes and/or a UM upgrade macro. In this case, you will need to create a UM branch, following the working_practices UM working practices.
Linked UM-JULES changes
If you have linked UM changes, you should be following the working_practices UM working practices.
Further checks for tickets
- New Switch
- New Dimension
- New Science
- New Diagnostic
- Not making a new Module where appropriate.
- Not using a new indexing array variable when developing code especially DO loops.
- Upgrade macro must be checked in a test branch, see above.
- Upgrade macros must use integers and not character variables, e.g.
#Use Integers self.add_setting(config, ["namelist:jules_soil_biogeochem", "soil_bgc_model"], "2") #NOT Character variables self.add_setting(config, ["namelist:jules_soil_biogeochem", "soil_bgc_model"], "rothc")
- Upgrade macros must use the same namelist format as the others and not append
_mod
as this creates new and unwanted namelists.#Use self.add_setting(config, ["namelist:jules_soil_biogeochem", "soil_bgc_model"], "2") #Don't use appended "_mod" self.add_setting(config, ["namelist:jules_soil_biogeochem_mod", "soil_bgc_model"], "2")
- Compiler fcm_make warnings, please check the
fcm-make.log
. - New science means a new rose-stem test to safe guard the new science.
- Never use tabs, and please do not add trailing whitespaces, they can both cause problems with the code.
Documentation
Documentation needs updating if you have added a:
The documentation must be checked to make sure that changes compile correctly, with correct formatting. Move to the correct directory:
cd <branch_name>/docs/user_guide # Run make to build the documentation. #To build and view the html documentation: make html firefox build/html/index.html #To build and view the pdf documentation: make latexpdf acroread build/latex/JULES_User_Guide.pdf #or evince build/latex/JULES_User_Guide.pdf
Code
Code need to me the UMDP3 standard, see above. Common mistakes:
Documentation on tickets
Documentation changes
To make changes to the JULES documentation you need to create a branch, checkout your branch, make changes, commit your changes back and compile the documentation.
fcm bc <BRANCH_NAME> fcm:jules_doc.x_tr fcm co fcm:jules_doc.x_br/dev/<USER>/<BRANCH_NAME> #or longhand fcm branch-create <BRANCH_NAME> https://code.metoffice.gov.uk/svn/jules/doc/trunk fcm checkout https://code.metoffice.gov.uk/svn/jules/doc/branches/dev/<USER>/<BRANCH_NAME> #make changes #commit changes back to the to the repository of the branch fcm ci #compile the LaTeX and html and check them cd <branch_name>/docs/user_guide # Run make to build the documentation. #To build and view the html documentation: make html firefox build/html/index.html #To build and view the pdf documentation: make latexpdf acroread build/latex/JULES_User_Guide.pdf #or evince build/latex/JULES_User_Guide.pdfNow we can create or update the appropriate ticket to get the updated documentation on the JULES documentation trunk, for all to use.
If the ticket is a documentation ONLY change then you do not have to run the rose-stem tests, just compile the documentation. Now get an appropriate reviewer and assign the ticket to them.
If the ticket is a documentation and code change, as most are then you need to run rose-stem and compile the documentation. Now get an appropriate reviewer and assign the ticket to them.
Resolving FCM conflicts
FCM Text and Tree conflicts.
Sometimes when we merge branches into HoT branches we receive a
message at the end of the merge saying that we have
Text Conflicts
or Tree Conflicts
.
Text Conflicts
are easier to resolve than
Tree Conflicts
in general.
fcm conflicts
The command fcm conflicts|cf
is a graphical tool to help
resolve conflicts within the local/working copy.
Note it cannot help with all conflicts.
It works with the most effectively with Text Conflicts.
A type of conflict that we may come across are "Text conflicts".
These are returned via fcm st
as
C statusesC_text.txt
where column 1 has a "C" in it.
To resolve the text conflict we use the 3-way difference tool xxdiff.
For each file with a text conflict, the fcm conflicts
command
calls a graphical merge tool (i.e. xxdiff by default) to display a 3-way diff.
How to use xxdiff to help resolve text conflicts
The file on the left is our original file. The file in the middle is the common ancestor from the merge. The file on the right is the file containing the changes which we are merging in.
The image below shows an image of a text conflict.
Left click on the text option that we want to keep, it should change colour from yellow to purple.
Then press "m", or use the toolbar; File -> Exit with MERGED M.
Explanations of the three window split xxdiff:
The number on the far right panel of xxdiff tool is the number of unselected differences, known as "hunks" or "sections" and they are often seen in yellow. The correct term for the highlighted section is hunk, but here we will refer to it as the section as it is easier to understand and remember what we are talking about.
When this number is 0 then we are ready to save the merged file.
To see how the merged file will look with the current selections, click Windows->Toggle Merged View (keyboard shortcut: Alt+Y).
An extra window then appears showing the merged output that updates interactively as we make our selections.
If we just want to exit without making any decisions we can also just close the window.
If we have resolved all the conflicts in a file then we will be prompted on
whether to run svn resolved
on the file to signal that the file
is no longer in conflict.
fcm resolve
The fcm resolve
command can be used to resolve conflicts in
local/working copy files or directories.
Mainly tree conflicts.
A common way of using this command is:
fcm resolve --accept working <FILENAME>
This will try to resolve the tree conflict and ask you if you would like to go ahead with the merge? This is for you to decide.
A common way that a tree conflict occurs is after a merge when a file has been deleted or renamed on one branch, and modified on another. These are incompatible changes, therefore Subversion doesn't know which action to take. This is the cause of the tree conflict dilemma which the user must solve.
Example: choose to keep the local version or not?
[info] tree_conflict.txt: in tree conflict. Locally: deleted. Externally: edited. Answer (y) to accept the local delete. Answer (n) to keep the file. Keep the local version? Enter "y" or "n" (or just press <return> for "n") y Resolved conflicted state of 'tree_conflict.txt'
In this example, to keep the file as it was before (in a deleted state), enter y.
Otherwise, to accept the merge branch version of the file (adding it with the edited changes), enter n.
See a tutorial on FCM conflicts for more details.
Congratulations you have completed the Developer Advanced Tutorial!
This document is released under the British Open Government Licence.