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

Autoconf-based build framework #1197

Merged
merged 31 commits into from
Sep 17, 2020
Merged

Conversation

marshallward
Copy link
Collaborator

@marshallward marshallward commented Sep 2, 2020

This patch is a first draft of an autoconf-based build for MOM6.

This is a hybrid solution which relies on mkmf and list_paths to
automatically generate the model dependencies, but uses autoconf to
determine the necessary compiler flags for building the model.

Recommended instructions for testing the build system, as well as
instructions for new users, are shown below.

    # (Optional) Fetch mkmf and build FMS
    cd deps
    make -j
    cd ..

    # Set up the autoconf build files
    autoreconf

    # Configure and build the model in /build
    mkdir -p build
    cd build
    ../configure
    make -j

As with standard autoconf builds, compilers and flags can be configured
with prepended arguments, e.g.

    FC=mpifort FCFLAGS="-g -O0 -Wall -Wextra" ./configure
    make

Introduction of autoconf configuration should not interfere with any
existing mkmf-based build procedures.

A more detailed discussion is provided below.


At minimum, only the following instructions would be required:

    autoreconf
    ./configure
    make

but this requires that both mkmf and FMS be accessible in standard
searchable directories.

A more realistic MOM6-only build would be as shown below

    autoreconf
    PATH="path/to/mkmf/bin:${PATH}" \
      FCFLAGS="-Ipath/to/fms_mods" \
      LDFLAGS="-Lpath/to/fms_lib" \
      ./configure
    make

where path/to/xxx points to the location of the pre-installed content.

To alleviate this issue, a Makefile in the deps directory has been
provided, which checks out copies of mkmf and FMS and places them in the
deps directory. If the MOM6 ./configure script is unable to find
mkmf or FMS, then it will automatically continue to search inside of the
deps directory.


The deps directory provides templates for an autoconf build of FMS
resembling our MOM6 build.

The Makefile provides the following rules:

make or make all:
Fetch mkmf and FMS, build FMS, install module files to deps/include
and libFMS.a to deps/lib.

make clean
Delete the compiled FMS files in deps/fms/build but not the
installed libraries or module files.

make distclean
Delete all files produced by the Makefile.

Much of the FMS source configuration has been moved to the deps
Makefile. The available hooks and default values are shown below.

MKMF_URL ?= https://github.com/NOAA-GFDL/mkmf.git
MKMF_COMMIT ?= master
FMS_URL ?= https://github.com/NOAA-GFDL/FMS.git
FMS_COMMIT ?= 2019.01.03
FCFLAGS_FMS ?=

The FCFLAGS_FMS hook is provided to override the default autoconf value,
-g -O2.

Although FMS provides its own automake build framework, the 2019.01.03
release cannot be used with MOM6 due to missing components in its
libtool configuration (random_number). The build time is also
significantly longer due to incorrect dependencies in the automake
configuration.

Most of the issues describe above have either been or will soon be
resolved in newer FMS releases, and we may be able to transition to
the FMS automake in a future release.


The .testing directory has been reworked to use the autoconf builds of
MOM6 and FMS, but should otherwise work the same as before.

    cd .testing
    make -j
    make -j test

The changes required to use autoconf have been incorporated into the
.testing Makefile.

This can create issues with the management of FMS, which is now
configured inside of deps/Makefile rather than in .testing. Also, a
rebuild of FMS will require an explicit wipe of FMS in deps, which can
be done with the following command.

    make -C ../deps distclean

Platform-specific flags are now managed in the config.mk file rather
than in a mkmf template. The following hooks are provided, with default
values shown.

FCFLAGS_DEBUG ?= -g -O0
FCFLAGS_REPRO ?= -g -O2
FCFLAGS_INIT ?=
FCFLAGS_COVERAGE ?=

The intention is to provide some correspondence to the GFDL DEBUG and
REPRO production builds.

Any FMS build produced by make in .testing will use the
FCFLAGS_DEBUG variable.

Although FCFLAGS_INIT is intended for intialization, it acts as more
of a general-purpose flag which is applied to MOM6 but not FMS.


Other points of interest

  • This build system only uses autoconf. It does not use automake or libtools.

  • autoconf will determine any necessary flags required for building
    MOM6, but does not attempt to use optional flags for debugging or
    performance.

    Flags required for testing or production builds must still track or
    otherwise manage their own compiler flags (FCFLAGS, etc).

  • The MOM6 ./configure script requires a FMS library and module files as
    part of its build validation. This is why we must pre-build FMS
    before calling ./configure.

  • FCFLAGS defaults to -g -O2. Any explicit setting of FCFLAGS
    will remove and replace these flags. Other flags, such as
    -fdefault-real-8 will be appended as needed and do not need to be
    managed.

  • Support M4 macros have been tested on GCC, Intel, PGI, and Cray
    compilers. The macros can be extended to other compilers and older
    versions of these compilers if necessary.


Known issues

  • The macro used for the MPI launcher (AX_MPI) can potentially locate a
    MPIFC (e.g. mpif90) which does not match FC. For example, FC will
    tend to default to GFortran, but mpif90 may use Intel Fortran.

    While FC is quickly replaced with MPIFC, there are some initial tests
    which may fail if FCFLAGS was defined for the non-GFortran compiler.

    This can be resolved by explicitly setting both FC and FCFLAGS for the
    same compiler.

  • Since we use git for both development and distribution, we may want to
    pre-build the configure script and support files, eliminating the
    autoreconf step.

This patch is a first draft of an autoconf-based build for MOM6.

This is a hybrid solution which relies on mkmf and list_paths to
automatically generate the model dependencies, but uses autoconf to
determine the necessary compiler flags for building the model.

Recommended instructions for testing the build system, as well as
instructions for new users, are shown below.
```
    # (Optional) Fetch mkmf and build FMS
    cd deps
    make -j
    cd ..

    # Set up the autoconf build files
    autoreconf

    # Configure and build the model in /build
    mkdir -p build
    cd build
    ../configure
    make -j
```

As with standard autoconf builds, compilers and flags can be configured
with prepended arguments, e.g.
```
    FC=mpifort FCFLAGS="-g -O0 -Wall -Wextra" ./configure
    make
```

Introduction of autoconf configuration should not interfere with any
existing mkmf-based build procedures.

A more detailed discussion is provided below.

----

At minimum, only the following instructions would be required:
```
    autoreconf
    ./configure
    make
```
but this requires that both mkmf and FMS be accessible in standard
searchable directories.

A more realistic MOM6-only build would be as shown below
```
    autoreconf
    PATH="path/to/mkmf/bin:${PATH}" \
      FCFLAGS="-Ipath/to/fms_mods" \
      LDFLAGS="-Lpath/to/fms_lib" \
      ./configure
    make
```
where `path/to/xxx` points to the location of the pre-installed content.

To alleviate this issue, a Makefile in the `deps` directory has been
provided, which checks out copies of mkmf and FMS and places them in the
`deps` directory.  If the MOM6 `./configure` script is unable to find
mkmf or FMS, then it will automatically continue to search inside of the
`deps` directory.

----

The `deps` directory provides templates for an autoconf build of FMS
resembling our MOM6 build.

The Makefile provides the following rules:

`make` or `make all`:
  Fetch mkmf and FMS, build FMS, install module files to `deps/include`
  and `libFMS.a` to `deps/lib`.

`make clean`
  Delete the compiled FMS files in `deps/fms/build` but not the
  installed libraries or module files.

`make distclean`
  Delete all files produced by the Makefile.

Much of the FMS source configuration has been moved to the `deps`
Makefile.  The available hooks and default values are shown below.
```
MKMF_URL ?= https://github.com/NOAA-GFDL/mkmf.git
MKMF_COMMIT ?= master
FMS_URL ?= https://github.com/NOAA-GFDL/FMS.git
FMS_COMMIT ?= 2019.01.03
FCFLAGS_FMS ?=
```
The FCFLAGS_FMS hook is provided to override the default autoconf value,
`-g -O2`.

Although FMS provides its own automake build framework, the 2019.01.03
release cannot be used with MOM6 due to missing components in its
libtool configuration (`random_number`).  The build time is also
significantly longer due to incorrect dependencies in the automake
configuration.

Most of the issues describe above have either been or will soon be
resolved in newer FMS releases, and we may be able to transition to
the FMS automake in a future release.

----

The `.testing` directory has been reworked to use the autoconf builds of
MOM6 and FMS, but should otherwise work the same as before.
```
    cd .testing
    make -j
    make -j test
```
The changes required to use autoconf have been incorporated into the
`.testing` Makefile.

This can create issues with the management of FMS, which is now
configured inside of `deps/Makefile` rather than in `.testing`.  Also, a
rebuild of FMS will require an explicit wipe of FMS in `deps`, which can
be done with the following command.
```
    make -C ../deps distclean
```

Platform-specific flags are now managed in the `config.mk` file rather
than in a mkmf template.  The following hooks are provided, with default
values shown.
```
FCFLAGS_DEBUG ?= -g -O0
FCFLAGS_REPRO ?= -g -O2
FCFLAGS_INIT ?=
FCFLAGS_COVERAGE ?=
```
The intention is to provide some correspondence to the GFDL DEBUG and
REPRO production builds.

Any FMS build produced by `make` in `.testing` will use the
`FCFLAGS_DEBUG` variable.

Although `FCFLAGS_INIT` is intended for intialization, it acts as more
of a general-purpose flag which is applied to MOM6 but not FMS.

----

Other points of interest

- This build system only uses autoconf.  It does not use automake or libtools.

- autoconf will determine any necessary flags required for building
  MOM6, but does not attempt to use optional flags for debugging or
  performance.

  Flags required for testing or production builds must still track or
  otherwise manage their own compiler flags (FCFLAGS, etc).

- The MOM6 `./configure` script requires a FMS library and module files as
  part of its build validation.  This is why we must pre-build FMS
  before calling `./configure`.

- FCFLAGS defaults to `-g -O2`.  Any explicit setting of FCFLAGS
  will remove and replace these flags.  Other flags, such as
  `-fdefault-real-8` will be appended as needed and do not need to be
  managed.

- Support M4 macros have been tested on GCC, Intel, PGI, and Cray
  compilers.  The macros can be extended to other compilers and older
  versions of these compilers if necessary.

----

Known issues

- The macro used for the MPI launcher (AX_MPI) can potentially locate a
  MPIFC (e.g. mpif90) which does not match FC.  For example, FC will
  tend to default to GFortran, but mpif90 may use Intel Fortran.

  While FC is quickly replaced with MPIFC, there are some initial tests
  which may fail if FCFLAGS was defined for the non-GFortran compiler.

  This can be resolved by explicitly setting both FC and FCFLAGS for the
  same compiler.

- Since we use git for both development and distribution, we may want to
  pre-build the configure script and support files, eliminating the
  `autoreconf` step.
@marshallward
Copy link
Collaborator Author

I think there are two issues here, first with coverage (probably missing from LDFLAGS) and the other with the target build unable to find the local FMS library. I will try to sort these out in the next commit.

Minor fixes which include the FCFLAGS coverage flag into LDFLAGS for
gcov builds, as well as properly moving the target -L flag out of
FCFLAGS and into LDFLAGS.
@codecov-commenter
Copy link

codecov-commenter commented Sep 2, 2020

Codecov Report

Merging #1197 into dev/gfdl will decrease coverage by 0.01%.
The diff coverage is 35.37%.

Impacted file tree graph

@@             Coverage Diff              @@
##           dev/gfdl    #1197      +/-   ##
============================================
- Coverage     46.08%   46.07%   -0.02%     
============================================
  Files           214      224      +10     
  Lines         69399    70583    +1184     
============================================
+ Hits          31984    32518     +534     
- Misses        37415    38065     +650     
Impacted Files Coverage Δ
...g_src/external/GFDL_ocean_BGC/FMS_coupler_util.F90 0.00% <0.00%> (ø)
...fig_src/external/GFDL_ocean_BGC/generic_tracer.F90 0.00% <0.00%> (ø)
...c/external/GFDL_ocean_BGC/generic_tracer_utils.F90 0.00% <0.00%> (ø)
config_src/external/ODA_hooks/kdtree.f90 0.00% <0.00%> (ø)
config_src/external/ODA_hooks/ocean_da_core.F90 0.00% <0.00%> (ø)
config_src/external/ODA_hooks/ocean_da_types.F90 0.00% <0.00%> (ø)
config_src/external/ODA_hooks/write_ocean_obs.F90 0.00% <0.00%> (ø)
config_src/solo_driver/MESO_surface_forcing.F90 0.00% <0.00%> (ø)
config_src/solo_driver/user_surface_forcing.F90 0.00% <0.00%> (ø)
src/ALE/MOM_regridding.F90 31.47% <0.00%> (-0.17%) ⬇️
... and 213 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 51288ca...f0201a4. Read the comment docs.

Several build environment variables were redefined globally to be used
across all jobs, rather than repeating over every job.

The timer output was also redefined to be single line, rather than four,
to reduce logging output.
@marshallward marshallward requested a review from adcroft September 2, 2020 23:33
@adcroft adcroft requested review from adcroft and removed request for adcroft September 3, 2020 15:32
@marshallward marshallward reopened this Sep 4, 2020
@adcroft
Copy link
Collaborator

adcroft commented Sep 8, 2020

./configure got stuck at

checking for MPI_Init...

This is using the usual gnu environment on gaea login node.

@marshallward
Copy link
Collaborator Author

I saw this a few times, it appears to be a Lustre issue. I believe it's hanging because it cannot create the test file.

marshallward and others added 5 commits September 9, 2020 14:07
Because autoconf can cause fear and anger in some users, the
configuration files have now been delegated to a subdirectory, ac, which
can be invoked from an arbitrary directory.

This required some unconventional constructs in the file, but they have
luckily been relegated to a few introductory statements, and the bulk of
the code is unchanged.  The only pervasive change is the explicit
references to the ac directory, particularly ac/deps.

.testing also had to be updated to accommodate the autoconf changes.
Modified FMS to build libFMS.a in its build directory, rather than to
just target the eventual destination of it (../../lib/libFMS.a).  This
is because other builds (particularly .testing) may prefer a different
destination.
.testing no longer relies on the top-level ac/deps to build and hold its
FMS repository.  It now checks out its own source and builds its own FMS
library exclusively for testing.

Also fixed a few dependency bugs in the FMS makefile (and probably in
.testing as well).

Finally, the m4 macros for FMS were copied into deps, rather than
sharing with the top-level m4 macros, allowing it to exist more
independently.  (I will prune the FMS-specific macros from ac/m4 in a
future commit.)
@marshallward
Copy link
Collaborator Author

marshallward commented Sep 11, 2020

The behavior has been modified based on feedback from @adcroft.

Autoconf configuration has now been moved into the ac directory. This breaks convention as well as the expected ./configure && make ritual, but it isolates the build configuration files from the codebase. Pathing is occasionally awkward and redundant (e.g. <...>/ac/../ac/<...> but is otherwise robust to the usual autoconf pathing rules.

To create the configure script:

autoreconf -if ac/configure

We may also want to pre-commit the output files (configure, aclocal.m4, autom4te.cache/), even if they can be generated.

The deps directory has also been moved into this ac directory, isolating it from the source. To pre-build FMS and pre-fetch mkmf:

make -C ac/deps

To build MOM6:

cd path/to/some/dir
${codebase}/ac/configure

where ${codebase} points to wherever the MOM6 source was checked out.

For a more straightforward build:

mkdir build
cd build
../ac/configure

should also work.

MOM6 .testing has been updated to build its own FMS library, rather than rely on ac/deps, but otherwise should operate normally:

cd .testing
make -j
make -j test

While .testing has been refactored to use autoconf, none of the instructions above should be required to run the test suite.

marshallward and others added 7 commits September 11, 2020 16:14
The AX_FC_CRAY_POINTER macro was heavily updated to better use the
intrinsic Autoconf and M4 macros, as well as to introduce both pass/fail
macros and an additional PGI test (which doesn't seem needed but
*shrug*).

Additional processing is no longer needed when invoking this macro.  It
now automatically applies the Cray pointer flags to FCFLAGS if invoked,
and it now automatically aborts of such macros are not supported,
although both of these operations can be overridden if necessary.

Several FMS macros unused by MOM6 were also removed from the MOM6 m4
macro folder.
Resolved some bad string parsing issues of the Travis environment
variables.  Thanks to Inspector Adcroft for discovering this error.

Further cleanup of the Cray pointer test macro, should now be very close
to conformant Autoconf M4 format.
@marshallward
Copy link
Collaborator Author

This is passing now on Travis, but some debug/repro differences are occurring on Gaea which need further investigation.

marshallward and others added 3 commits September 15, 2020 16:14
This patch adds additional support for building FMS in deps on macOS
machines, specifically related to affinity.

Much of this can be phased out when we upgrade our target FMS from
2019.01.03 to a newer version.

Additional dependency errors in .testing/Makefile have also been fixed
related to building of the virtual Python environment.
@marshallward
Copy link
Collaborator Author

marshallward commented Sep 16, 2020

Recent changes include some improved support for macOS, as well as some bugfixes in the Makefile rule dependencies. Thanks very much to @raphaeldussin for his feedback.

I think this is close enough to be operational, assuming we are happy with how to use it. But it still needs documentation.

autoconf now defaults to using symmetric grids, rather than asymmetric
grids.

The DEBUG/REPRO build comparison is now disabled on default, since many
platforms do not produce equivalent results.  If this situation
improves, then it can be re-enabled.
@adcroft
Copy link
Collaborator

adcroft commented Sep 17, 2020

This is ready except for documentation.

Added several documentation READMEs to using the autoconf build.

Also added some changes to the Makefile template so that `make ac-clean`
wiped out the autoconf output (configure, aclocal.m4, autom4te.cache).
ac/README.md Outdated
## Coupled builds

The Autoconf build is currently only capable of building ocean-only
executables, and cannot yet be build as part of a coupled more, nor as a
Copy link
Contributor

Choose a reason for hiding this comment

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

-more +model ?

@adcroft adcroft merged commit dd28dea into mom-ocean:dev/gfdl Sep 17, 2020
@marshallward marshallward deleted the autoconf_draft branch January 18, 2021 12:42
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.

4 participants