Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement finalization and various enhancements for MPAS dynamical core #327

Open
wants to merge 20 commits into
base: development
Choose a base branch
from

Conversation

kuanchihwang
Copy link
Collaborator

@kuanchihwang kuanchihwang commented Dec 3, 2024

Tag name (required for release branches):

None

Originator(s):

kuanchihwang

Descriptions (include the issue title, and the keyword ['closes', 'fixes', 'resolves'] followed by the issue number):

This PR implements finalization for MPAS dynamical core.

This PR also implements various enhancements for MPAS dynamical core:

  • Comply with CAM(-SIMA) coding standards by moving use statements to the smallest scope possible.
  • Support MPAS dynamical core in single precision mode. Running in single precision mode improves performance and reduces memory usage at the cost of accuracy.
  • Reorganize directory structure for better clarity. Files that are not source code are now placed in the assets directory.
  • Prefix all MPAS namelist group and option names with mpas_. They are now easily distinguishable from CAM-SIMA ones. The possibility of name collisions with CAM-SIMA ones is also resolved once and for all.
  • Add Python script for generating namelist definition. Closes Add script to create namelist_definition_mpas_dycore.xml from MPAS-A Registry.xml #252.
  • Update namelist definition so that MPAS dynamical core should now be able to run analytic cases out of the box.
  • Various code improvements.

Describe any changes made to the build system:

Due to the slight reorganization of directory structure, cime_config/buildlib is updated with the new paths.

Describe any changes made to the namelist:

The namelist options for running analytic cases with MPAS dynamical core are updated to match CAM.

List any changes to the defaults for the input datasets (e.g., boundary datasets):

The input files for running analytic cases with MPAS dynamical core are updated to match CAM. The supported resolutions are:

  • Horizontal resolutions of mpasa480, mpasa120, mpasa60, and mpasa30 with 32 vertical layers.
  • Horizontal resolutions of mpasa480, mpasa120, and mpasa60 with 58 vertical layers.
  • Horizontal resolutions of mpasa480, mpasa120, and mpasa60 with 93 vertical layers.

List all files eliminated and why:

None

List all files added and what they do:

  • A src/dynamics/mpas/assets/0001-Prefix-all-MPAS-namelist-group-and-option-names.patch
    • Patch that prefixes all MPAS namelist group and option names
  • A src/dynamics/mpas/assets/0002-Disable-physics-for-MPAS-dycore-only-build.patch
    • Patch that disables physics for MPAS dycore-only build
  • A src/dynamics/mpas/assets/0003-Declare-constants-at-the-native-precision-of-MPAS.patch
    • Patch that declares constants at the native precision of MPAS
  • A src/dynamics/mpas/assets/generate_namelist_definition.py
    • Add Python script for generating namelist definition

List all existing files that have been modified, and describe the changes:

  • M cime_config/buildlib
    • Reorganize directory structure for better clarity
  • M cime_config/namelist_definition_cam.xml
    • Update namelist definition for CAM-SIMA
  • M src/dynamics/mpas/driver/dyn_mpas_subdriver.F90
    • Add support for MPAS output stream
    • Relax restrictions on mixed precision
    • Use existing functionality to access MPAS configuration
    • Implement finalization for MPAS dynamical core
    • Move use statements to the smallest scope possible
    • Support MPAS dynamical core in single precision mode
  • M src/dynamics/mpas/dyn_comp.F90
    • Implement dyn_final
    • Move use statements to the smallest scope possible
    • Support MPAS dynamical core in single precision mode
    • Add protected attribute to grid/mesh variables
    • Change some wording to plural
    • Include argument keyword for better clarity
  • M src/dynamics/mpas/dyn_coupling.F90
    • Move use statements to the smallest scope possible
    • Support MPAS dynamical core in single precision mode
    • Change some wording to plural
    • Include argument keyword for better clarity
  • M src/dynamics/mpas/dyn_grid.F90
    • Move use statements to the smallest scope possible
    • Support MPAS dynamical core in single precision mode
    • Nullify pointers that are no longer needed
    • Add protected attribute to grid/mesh variables
  • M src/dynamics/mpas/namelist_definition_mpas_dycore.xml
    • Update namelist definition for MPAS dynamical core
  • M src/dynamics/mpas/stepon.F90
    • Wire up dyn_final
    • Move use statements to the smallest scope possible
  • R src/dynamics/mpas/assets/Makefile.in.CESM
    • Reorganize directory structure for better clarity
    • Remove hacky sed commands from Makefile
    • Apply patches before building
  • R src/dynamics/mpas/assets/Makefile
    • Reorganize directory structure for better clarity

Regression tests:

New baseline for MPAS dynamical core.

  SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho (Overall: DIFF) details:
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho CREATE_NEWCASE
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho XML
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho SETUP
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho SHAREDLIB_BUILD time=10
    FAIL SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho NLCOMP
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho MODEL_BUILD time=137
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho SUBMIT
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho RUN time=17
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho GENERATE
    FAIL SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho BASELINE
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho MEMLEAK
    PASS SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho SHORT_TERM_ARCHIVER

No changes to other existing tests.

@kuanchihwang
Copy link
Collaborator Author

kuanchihwang commented Dec 3, 2024

Additional comments:

Note to reviewers: It might be easier to review the PR commit by commit. The commit messages provide the context and rationale behind each set of changes.

You should be able to run analytic cases currently supported by CAM-SIMA (e.g., FHS94, FKESSLER) with MPAS dynamical core. No tinkering with user_nl_cam or XML files is required.

You are also encouraged to test MPAS dynamical core in single precision mode. From the following benchmarks, MPAS dynamical core in single precision mode is ~40% faster and uses ~25% less memory than in double precision mode. A reference CAM run with the same configuration is also provided for completeness.

figure_cam_vs_cam_sima_mem_timing_365d_opt
figure_cam_vs_cam_sima_mem_timing_365d_opt_zoomed

@kuanchihwang kuanchihwang force-pushed the staging/implement-dyn-final branch 3 times, most recently from cd464ea to 90fc72a Compare December 10, 2024 19:36
* Adjust wording and keep code comments up-to-date
* Concentrate all calls to `mark_as_initialized` in one place
* Fix up code style inconsistencies
Also fix variable rank information.
Relax restrictions on mixed precision between MPAS dynamical core and
its input data.
`get_variable_pointer` also works for accessing MPAS configuration.
It has built-in error checking so no need to do it manually.
Comply with CAM(-SIMA) coding standards. However, kind and length parameters
are exempt from this rule. They are better at module level.
It is now possible to run CAM-SIMA with MPAS dynamical core in single precision
mode. It can be enabled by defining the `SINGLE_PRECISION` macro in `CPPFLAGS`.
Protect these variables from being modified externally.
Manipulating source code by running `sed` commands during building
is neither elegant nor obvious. Downstream modifications like these are
better achieved and communicated through patches. This is also the
standard practice in open source software.
These patches are applied before building.
This Python script generates the XML namelist definition file of MPAS dynamical core
from MPAS registry. Optionally, if an XML schema is provided, the generated file can
also be validated for correctness.
From now on, it can be generated automatically from MPAS registry.
Add MPAS initial files for running analytic cases.
@kuanchihwang kuanchihwang force-pushed the staging/implement-dyn-final branch from 90fc72a to e36fcdb Compare December 16, 2024 23:42
@kuanchihwang kuanchihwang marked this pull request as ready for review December 17, 2024 01:06
Copy link
Collaborator

@nusbaume nusbaume left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great @kuanchihwang! I just have a few questions and some very minor requests, mostly to move some remaining module-level use statements to their respective subroutines. Of course if any of my requests are problematic just let me know. Thanks!

Comment on lines +54 to +55
# Uncomment below for single precision mode support. There is currently no corresponding option in CIME to enable this.
# export CPPFLAGS += -DSINGLE_PRECISION
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not worth trying to resolve in this PR, but I believe we could make the use of single precision an option in the CAM_CONFIG_OPTS variable in the CIME env_build.xml file, where then the CAM-SIMA configuration system can set an environment variable that this Makefile then queries to set the relevant CPP Flag (or alternatively we could just add it directly to the full CAM-SIMA Makefile). This would provide a way for the average user to change the precision used in their own simulation without having to modify any source files.

Does this sound reasonable to you? If so then we should make a Github issue to remind us to implement it in a later PR.

Comment on lines +83 to +87
@for file in *.patch; do \
if git apply --check -p2 "$${file}"; then \
echo "Applying $${file}"; \
git apply -p2 "$${file}"; \
fi; \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any sense what the medium or long-term maintainability of this method will be? For example, will we need to create new patch files every time we update the MPAS submodule in CAM-SIMA, or are the targeted files rarely ever modified?

I don't think it matters for this PR, but if you think that it could require an abnormal amount of work to maintain then it might be worth opening a Github issue so we can remember to try and figure out alternative methods in the future.

default='Namelist.xml',
type=str,
required=False,
help='XML namelist definition file.',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might specify that this is a CAM-SIMA namelist definition file here:

Suggested change
help='XML namelist definition file.',
help='XML CAM-SIMA namelist definition file.',

INDENT_PER_LEVEL * 2 + 'MPAS dycore' + '\n' +
'\n' +
INDENT_PER_LEVEL * 2 + 'Note to developers/maintainers:' + '\n' +
INDENT_PER_LEVEL * 2 + 'This file is auto-generated from MPAS registry. Do not edit directly.' + '\n' +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor grammar nit-pick:

Suggested change
INDENT_PER_LEVEL * 2 + 'This file is auto-generated from MPAS registry. Do not edit directly.' + '\n' +
INDENT_PER_LEVEL * 2 + 'This file is auto-generated from the MPAS registry. Do not edit directly.' + '\n' +

use time_manager, only: get_step_size

! Modules from CCPP.
! Module(s) from CCPP.
use ccpp_kinds, only: kind_phys
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this use statement can be passed down to the subroutine scope as well (i.e. there don't appear to be any module-level variables that need it).

Comment on lines +2 to +6
! Module(s) from CESM Share.
use shr_kind_mod, only: kind_r8 => shr_kind_r8, &
len_cx => shr_kind_cx
! Module(s) from MPAS.
use dyn_mpas_subdriver, only: kind_dyn_mpas => mpas_dynamical_core_real_kind
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all of these can be moved to the subroutine scope as well.

Comment on lines +2 to +4
! Module(s) from CESM Share.
use shr_kind_mod, only: kind_r8 => shr_kind_r8, &
len_cs => shr_kind_cs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this use shr_kind_mod statement can be moved to the subroutine scope.

Comment on lines +1004 to +1010
call dyn_debug_print('ncells_global = ' // stringify([ncells_global]))
call dyn_debug_print('nedges_global = ' // stringify([nedges_global]))
call dyn_debug_print('nvertices_global = ' // stringify([nvertices_global]))
call dyn_debug_print('nvertlevels = ' // stringify([nvertlevels]))
call dyn_debug_print('ncells_max = ' // stringify([ncells_max]))
call dyn_debug_print('nedges_max = ' // stringify([nedges_max]))
call dyn_debug_print('sphere_radius = ' // stringify([sphere_radius]))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we provide debuging print outs for the local mesh dimensions as well?

Comment on lines +1093 to +1095
! Quick hack for dumping variables from MPAS dynamical core.
! Remove it once history and restart are wired up in CAM-SIMA.
call dyn_variable_dump()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an FYI that CAM-SIMA does have history infrastructure now for any diagnostic variable that can be output instantaneously (i.e. doesn't need to be accumulated over multiple timesteps, like an average). You can find a description and user guide for this new history infrastructure in the official CAM-SIMA developer documentation here:

https://escomp.github.io/CAM-SIMA-docs/design/history/#capturing-history-output

We sadly don't have restart functionality enabled yet, but hopefully this can provide at least some guidance for how to start replacing this "hack" in the future.

use mpas_io_streams, only: mpas_createstream, mpas_closestream, mpas_streamaddfield, &
mpas_readstream, mpas_writestream, mpas_writestreamatt
! Module(s) from MPAS.
use mpas_derived_types, only: core_type, domain_type
use mpas_kind_types, only: rkind, r4kind, r8kind, strkind
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe r4kind and r8kind can be moved to the subroutine scope (as they appear to only be used in dyn_mpas_check_variable_status).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants