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

Switch E3SM build system to CMake! #3043

Merged
merged 50 commits into from
Nov 18, 2019
Merged

Conversation

jgfouca
Copy link
Member

@jgfouca jgfouca commented Jul 5, 2019

This is the big one! This PR switches E3SM's default build-system to be cmake-based. This will be the most significant change to CIME since the pythonization of the case control system. Note that this change only impacts components, builds of sharedlibs will not change.

I had been attempting to integrate this work in smaller chunks, but I had to suspend these integrations in order not to disrupt things before the code freeze. This PR will also need to not be integrated until the code freeze is over.

At a high level, we are going from this:
before_cmake

To this:
after_cmake

Plot legend for above images:

  • Squares = callstacks
  • Ovals = input/output files
  • Green = python
  • Blue = perl
  • Black = raw text
  • Red = Make
  • Purple = CMake

Motivations

  • Get the developer much "closer" to their builds. Instead of significant layers of CIME magic in-between the developer and their build, they can now simply cd to their builddir and type "ninja" (assuming .env_mach_specific.sh has been loaded).
  • Reduce latency in development cycle. Due to being able to invoke ninja/make directly, all the overhead of case.build can be avoided, including all the namelist stuff.
  • Reduce complexity/technical-debt of the existing system:
    • We have about 750 lines of CMake in components (compared to 1030 just in scripts/Tools/Makefile)
    • The old system had up to 4 process "layers" (python->perl->Make->perl), new has 2 (python->CMake, python->Ninja (auto-generated))
    • MPAS went from ~2k lines of Make to 640 lines of CMake
  • Improve overall build times
    • Building components for test SMS_P12x2.ne4_oQU240.A_WCYCL1850.melvin_gnu.allactive-mach_mods went from 281 seconds to 178 seconds on melvin.
  • The system no longer relies on any magic environment settings in CIME, so cmake/ninja calls should be trivial to replicate in a shell
  • Bring E3SM closer in-line with other code bases
  • Improve understanding of the E3SM build system
  • Put E3SM on a more sustainable path going into the future. It will be much easier to integrate new codes (Kokkos) and components (SCREAM) into our build system.

User impacts

  • There is no longer separate build dirs, logs for each component. Since it all goes through a single CMake invocation, there's only one log file (e3sm.bldlog.XXX) and one build directory ($EXEROOT/bld). Each component will have it's own build subdirectory ($EXEROOT/bld/$compclass).
  • All machines will need to have at least cmake-3.9 loaded in their config_machines.xml entry.
  • If you decide to build your case outside of CIME (using Cmake and ninja directly), you'll still need to call case.build at the end of your dev-cycle in order to allow CIME to do various post-build bookkeeping.
  • The CMake command used to configure the build will be the first thing in the e3sm.bldlog file. I've had success copy/pasting that command into a shell, allowing me to tinker with both CMake (and ninja) directly without having to go through CIME.
  • Each component now has a build_cmake script in it's cime_config.
  • You can go back to the "classic" build system by providing the --use-old options to case.build, this should work as long as the old buildlib scripts are maintained. Depending on how long CESM stays on the classic system, the cime/scripts/Tools/Makefile will likely be supported for quite a while.
  • MPAS developers will need to keep their Make and CMake files in sync.
  • We can now support various CMake backends. Ninja is our default backend since it's faster than make (especially for incremental builds) and its backend handles fortran dependencies correctly in the presence of preprocessor directives whereas the gmake does not always. You can force the gmake backed via --use-gmake to case.build.
  • Component developers should never have to worry about fortran mod dependencies again, CMake takes care of that automatically (E3SM components were using a custom mkDepends script for this, MPAS was doing it by-hand in their Makefiles).

XML changes

This PR disambiguates the selection of component specific flags in config_compiles.xml. We used to support the MODEL selector, IE:

<FFLAGS>
    <append MODEL="cam"> -qspill=6000 </append>
</FFLAGS>

But it was unclear whether MODEL referred to the component name ("cam") or component class ("atm"). The interpretation of MODEL was not even consistent across components. So MODEL is gone. Instead, please use COMP_NAME and COMP_CLASS.

<FFLAGS>
    <append COMP_NAME="cam"> -qspill=6000 </append>
</FFLAGS>

Testing:

  • As I switched each component over to the cmake system, I used the new bld_diff tool to confirm that the same files were being compiled with the same flags (with some expected exceptions). Now that cmake only has one log file, things are a bit harder to verify, but the flag logic is all the same as it was before this PR.
  • With the current PR, e3sm_developer passes on melvin and is BFB.
  • e3sm_integration builds on melvin (some fails, but they are on master too).

Future work:

  • The impact of the classic system is still felt in the new system and therefore our system still looks a bit unusual compared a "normal" code base. In particular, the interaction between the component/bld/configure perl scripts providing key inputs (Filepath, CCSM_cppdefs) to Cmake is a bit unusual. The jury is still out on the best path forward. The perl configure scripts are huge and CMake is not really a great general-purpose programming language, so it may not make sense to convert all this logic to CMake. @wlin7 is leading the effort to clean-up these scripts.
  • The classic system also imposes outdated ways of thinking about a build system that will make it challenging to adopt more modern build system patterns. We are forced to think of things in terms of flags and directories. Modern CMake patterns encourage developers to think of things in terms of targets (each with public and private properties) and language features.
  • It might be worth looking at the sharedlib builds to see if that can be cleaned-up as well

I would be super happy if others took the time to help me beta-test this. You'll need to be on this branch and set your mpas-source submodule to 20d6cdb0, which you can fetch from git@github.com:jgfouca/MPAS-Model.git.

In the meantime, please avoid (or consult with me) changes to the classic system.

@jedwards4b , @mvertens , @billsacks , @bmpersc

[BFB]

Also, clarify things by using better names: COMP_CLASS and COMP_NAME
@jhkennedy jhkennedy removed their request for review November 4, 2019 17:53
…uild_use_old

Upstream to pick up new MPAS submodule

* origin/master: (69 commits)
  Upon further thought
  create_test: fix baseline_root for non-default compiler
  rename anvil-centos7 back to anvil
  Fix py3 issue with floating point data in env_batch
  Update Theta module after PM
  Update mpas-source to include new cmake scripts
  adding melving settings for ne4np4pg2
  Add strict to compy debug queue
  Revert "Adds two regression tests for inline interpolation"
  Set SCM to run with netcdf
  Add other machines to use the tri-grid pe-layouts specified for sandiatoss3
  Fix time limits for queues on anvil
  add 'strict' keyword for anvil queues
  update anvil queues for time limits depending on size
  Add fsurdat file definition for new 20TR compset as well
  Update Theta modules
  Update HOMME Theta machine file
  Update tri-grid I-case pelayout for sandiatoss3
  Modified walltimemax for both queues
  Try larger pe-layouts for tri-grid tests on sandiatoss3
  ...
@jgfouca
Copy link
Member Author

jgfouca commented Nov 15, 2019

Did another upstream merge and quick re-test on melvin. All looks good! Merging to next.

jgfouca added a commit that referenced this pull request Nov 15, 2019
Switch E3SM build system to CMake!

See the GitHub PR for details.

[BFB]

* jgfouca/cime/case_build_use_old: (45 commits)
  e3sm no longer uses MODEL in config_compilers
  Add dry-run capability to case.build
  Fixes for cori
  Make sure ninja builds are verbose
  Make ninja the default backend
  Add comment pertaining to MPAS
  MPAS' mandatory use of PIO2 should be caputured in make cmake files, not config_compilers.xml
  Significant refactor to support per-component macro settings
  Fixes for summit + pgiacc
  Fix summit cxx linking
  Fix comment
  Disable compiler checks that happen upon cmake launch
  Fix paths to cime files in Depends.intel.cmake
  Fix generation of cmake macros for negated string checks
  Add helper for setting flags for indv files.
  change cmake bld dir
  Fix pylint warnings
  Only E3SM needs --use-old option to case.build
  With separate build dirs, special handling of xshare is no longer needed
  Progress towards separate build dirs for components
  ...
jgfouca added a commit that referenced this pull request Nov 15, 2019
Merge 2 for this PR.

[BFB]

* jgfouca/cime/case_build_use_old:
  Forgot to push these compy fixes
jgfouca added a commit that referenced this pull request Nov 16, 2019
Switch E3SM build system to CMake!

Merge three for this PR.

[BFB]

* jgfouca/cime/case_build_use_old:
  Switch back to gmake as default backend
jgfouca added a commit that referenced this pull request Nov 18, 2019
Switch E3SM build system to CMake

Merge four for this pr.

[BFB]

* jgfouca/cime/case_build_use_old:
  No need to set CMAKE_EXE_LINKER flags, target_link_libs already was handling that
jgfouca added a commit that referenced this pull request Nov 18, 2019
Switch E3SM build system to CMake!

See github PR for in-depth description.

[BFB]

* jgfouca/cime/case_build_use_old: (48 commits)
  No need to set CMAKE_EXE_LINKER flags, target_link_libs already was handling that
  Switch back to gmake as default backend
  Forgot to push these compy fixes
  e3sm no longer uses MODEL in config_compilers
  Add dry-run capability to case.build
  Fixes for cori
  Make sure ninja builds are verbose
  Make ninja the default backend
  Add comment pertaining to MPAS
  MPAS' mandatory use of PIO2 should be caputured in make cmake files, not config_compilers.xml
  Significant refactor to support per-component macro settings
  Fixes for summit + pgiacc
  Fix summit cxx linking
  Fix comment
  Disable compiler checks that happen upon cmake launch
  Fix paths to cime files in Depends.intel.cmake
  Fix generation of cmake macros for negated string checks
  Add helper for setting flags for indv files.
  change cmake bld dir
  Fix pylint warnings
  ...
@jgfouca jgfouca merged commit 9b74244 into master Nov 18, 2019
@jgfouca jgfouca deleted the jgfouca/cime/case_build_use_old branch November 18, 2019 02:38
jgfouca added a commit that referenced this pull request Oct 6, 2021
)

Major build system enhancement: deprecate config_compilers.xml!

This is the most significant change to the case-control system since
the cmake-ification (#3043) effort 2 years ago. This PR is a natural
follow-on to that effort that further cmake-ifies our build system and
reduces technical debt / complexity in the build system by stripping
away layers of CIME magic that were not adding much value for
us. Specifically, the config_compilers.xml file, which CIME uses to
generate the Macros.make and Macros.cmake casedir files (specifies
compilers, flags, link flags etc), will be replaced with hierarchical
CMake cache files that are persistently stored in our repo.

[BFB]

* jgfouca/replace_xml_with_cmake_macros:
  Fix handling of '\!'
  Add CIME hotfix
  Use COMP_NAME, not MODEL
  Sync with latest config_compilers.xml
  Add support for compiler_os.cmake macros
  Improve dox for compare-flags
  compare-flags: make tool more flexible and better output
  Refresh cache files after upstream merge
  Add some helper scripts for this effort
  Update CIME with latest
  Add support for universal macro
  Update CIME to bring in new macro capability
  Remove obsolete comment
  Add new cmake-based macros
jgfouca added a commit that referenced this pull request Oct 7, 2021
…4537)

Major build system enhancement: deprecate config_compilers.xml!

This is the most significant change to the case-control system since
the cmake-ification (#3043) effort 2 years ago. This PR is a natural
follow-on to that effort that further cmake-ifies our build system and
reduces technical debt / complexity in the build system by stripping
away layers of CIME magic that were not adding much value for
us. Specifically, the config_compilers.xml file, which CIME uses to
generate the Macros.make and Macros.cmake casedir files (specifies
compilers, flags, link flags etc), will be replaced with hierarchical
CMake cache files that are persistently stored in our repo.

[BFB]

* jgfouca/replace_xml_with_cmake_macros:
  Fix handling of '\!'
  Add CIME hotfix
  Use COMP_NAME, not MODEL
  Sync with latest config_compilers.xml
  Add support for compiler_os.cmake macros
  Improve dox for compare-flags
  compare-flags: make tool more flexible and better output
  Refresh cache files after upstream merge
  Add some helper scripts for this effort
  Update CIME with latest
  Add support for universal macro
  Update CIME to bring in new macro capability
  Remove obsolete comment
  Add new cmake-based macros
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.