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

Merged

Conversation

kuanchihwang
Copy link
Collaborator

@kuanchihwang kuanchihwang commented Dec 3, 2024

Tag name (required for release branches):

sima0_01_001

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:
    FAIL SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho NLCOMP
    FAIL SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_gnu.cam-outfrq_kessler_mpas_derecho BASELINE
  SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_intel.cam-outfrq_kessler_mpas_derecho (Overall: DIFF) details:
    FAIL SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_intel.cam-outfrq_kessler_mpas_derecho NLCOMP
    FAIL SMS_Ln9.mpasa480_mpasa480.FKESSLER.derecho_intel.cam-outfrq_kessler_mpas_derecho BASELINE

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!

src/dynamics/mpas/assets/Makefile.in.CESM Show resolved Hide resolved
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.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm also wondering whether we might be incurring greater maintenance work with the patch file approach. For example, I'm currently working on some changes in the MPAS registry tool's gen_inc.c code, and I suspect that after those changes make their way into the MPAS-A develop branch, we'd need to create a new patch file for that same file in CAM-SIMA during the next update of the MPAS-A dycore.

@kuanchihwang I'd be glad to work with you on incorporating generalizations upstream in the MPAS-Dev/MPAS-Model repository to support CAM-SIMA -- for example, for modifying the prefix of namelist options.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For 0001-Prefix-all-MPAS-namelist-group-and-option-names.patch, I will work with @mgduda to integrate the namelist transformation logic natively into the code generation utility of MPAS, so we no longer have to patch it here in the future.

I think both 0002-Disable-physics-for-MPAS-dycore-only-build.patch and 0003-Declare-constants-at-the-native-precision-of-MPAS.patch are fairly straightforward to upstream. I will open their respective PRs at the MPAS repository, so we can also drop those patches in the future.

Finally, for the patching mechanism, it is a common practice in open source software. Take Python 3.12 for example, Debian Linux maintains ~35 downstream patches, while Rocky Linux, an RHEL clone, also has ~10. When the upstream project gets updated, the patches will get rebased and refreshed as needed. But I agree, we definitely should keep the number of downstream patches as few as possible.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This sounds like a good plan to me! Please let me know if there is anything that I can do to help, especially on the CAM-SIMA-side.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This sounds fine to me as well. We can create PRs to CAM-SIMA to remove the need for specific patches once the upstream MPAS-Model code has suitable modifications in place.

src/dynamics/mpas/assets/generate_namelist_definition.py Outdated Show resolved Hide resolved
src/dynamics/mpas/assets/generate_namelist_definition.py Outdated Show resolved Hide resolved
src/dynamics/mpas/stepon.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_coupling.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Show resolved Hide resolved
src/dynamics/mpas/driver/dyn_mpas_subdriver.F90 Outdated Show resolved Hide resolved
@mgduda
Copy link
Collaborator

mgduda commented Jan 3, 2025

@kuanchihwang I recognize that it's taken me an awfully long time to review CAM-SIMA PRs related to MPAS in the past, and that's probably been a motivation for creating fewer but larger PRs. However, I'm wondering whether it would be feasible to split this PR into five or six smaller PRs, each with a specific purpose? For example, we could have the following as individual PRs:

  1. For existing MPAS dycore code, comply with CAM(-SIMA) coding standards.
  2. Reorganize directory structure for better clarity.
  3. Add Python script for generating namelist definition.
  4. Prefix all MPAS namelist group and option names with mpas_.
  5. Update namelist definition so that MPAS dynamical core should now be able to run analytic cases out of the box.
  6. Support MPAS dynamical core in single precision mode.

Personally, I find it much easier to review PRs when they are smaller and have a single purpose; and consequently, I think I'm more likely to review them sooner.

If splitting this PR up would require significant work, we can definitely keep it as is. But in case the changes are easily separable, I thought it might be worth considering a set of smaller PRs.

@kuanchihwang
Copy link
Collaborator Author

@mgduda

I agree that smaller PRs are easier to review, and I am definitely guilty of making large PRs. As you might notice, when I incrementally brought MPAS functionalities from CAM to CAM-SIMA, a lot of code redesign and refactoring were involved. During the development, the code design evolved continuously as I progressed into different stages of MPAS dycore. The turnaround time was not fast enough and my code changes started to pile up. I apologize for that.

However, I did make every effort to organize the commit history such that each commit serves a single purpose, and the commit messages provide the context and rationale behind each set of changes. Hopefully it helps even if this PR is large.

I believe that MPAS dycore will reach a stable state after this PR. Future ones should be a lot smaller and more focused to one theme for each.

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.

Thanks for the review responses and code updates! Everything looks great to me now.

@kuanchihwang kuanchihwang merged commit fb0e870 into ESCOMP:development Jan 14, 2025
8 checks passed
@kuanchihwang kuanchihwang deleted the staging/implement-dyn-final branch January 14, 2025 08:23
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.

3 participants