Skip to content

yac: link LAPACKE when YAC is used for coupling - #1022

Open
k202077 wants to merge 2 commits into
FESOM:mainfrom
k202077:fix_yac_lapacke
Open

yac: link LAPACKE when YAC is used for coupling#1022
k202077 wants to merge 2 commits into
FESOM:mainfrom
k202077:fix_yac_lapacke

Conversation

@k202077

@k202077 k202077 commented Aug 25, 2026

Copy link
Copy Markdown

Linking fesom.x fails with undefined LAPACKE_dgesv, LAPACKE_dsytrf_work
and LAPACKE_dsytri_work whenever YAC ends up on the link line via one of the
two cmake modules below. YAC's C core calls the LAPACKE C interface, which
lives in a different library from the Fortran LAPACK that
find_package(LAPACK) reports, and neither module put that library on the
line.

The failure surfaces at 100% of the build with no indication of the cause,
which is what makes it worth fixing rather than documenting.

What changed

Two commits, one per route into the same gap:

  • cmake/BuildYAC.cmakeBUILD_YAC=ON. Only ${LAPACK_LIBRARIES} was
    on YAC::yac's interface. The LAPACKE library is now appended, landing
    after the YAC static archives that reference it.
  • cmake/FindOASISYAC.cmakeOASIS_WITH_YAC=ON. Same gap reached
    through OASIS: libyac_core.a comes from the OASIS tree and nothing else
    defines those symbols. Appended to YACCORE_Fortran_LIBRARIES.

Both lookups are optional by design. YAC also resolves the interface
through MKL, or falls back to building its bundled clapack, and in both of
those cases the symbols are already satisfied and no extra library is needed.
When LAPACKE is genuinely missing, cmake now says so at configure time instead
of leaving it to the linker.

Why this did not surface earlier

Four things had to line up, and until recently they rarely did.

The default YAC route was never affected. With a pre-installed YAC
(yac_DIR), FindYAC.cmake goes through pkg-config and takes
${PC_yac_LDFLAGS} verbatim from yac.pc — which already carries whatever
LAPACKE flags YAC's own configure settled on. That path gets this right for
free. Only the two modules touched here assemble the library list by hand, and
so only they could omit it.

Those hand-rolled paths are new. BUILD_YAC and BuildYAC.cmake landed
in 6e00c208 (#776) on 2026-03-03, so the from-source route has had a few
months of exposure, mostly through the CI preset.

BuildYAC.cmake cannot use the file that has the answer. YAC's configure
records its LAPACKE flags in yac.pc, but under BUILD_YAC the yac-external
ExternalProject is built at build time — yac.pc does not exist yet when
this cmake code runs. Hence the separate find_library rather than reusing
pkg-config as FindYAC.cmake does.

Every environment that does exercise these paths already supplies LAPACKE.
The coupled_yac preset is in the CI matrix and builds green, so the LAPACK in
ghcr.io/fesom/fesom2_docker:fesom2_ci-master evidently resolves the LAPACKE
symbols. HPC targets are covered too, since MKL provides the interface. What is
left is the case that actually broke: a distro-package host where Netlib ships
LAPACKE separately from LAPACK (liblapacke-dev vs liblapack-dev on
Debian/Ubuntu) and YAC's configure selects the Netlib LAPACKE instead of
falling back to its bundled clapack.

Notes for reviewers

  • No behaviour change for anyone whose build already links — this only ever
    appends a library that was previously missing, and skips it when absent.
  • Not covered by the test suites either: coupled builds register no
    integration tests (tests/integration/CMakeLists.txt skips them under
    USE_YAC), so this is build-time verification by construction.
  • Because CI's image masks the bug, a green coupled_yac run does not confirm
    the fix. Verifying it means a host with liblapack-dev but without
    liblapacke-dev installed (reproduce), then with it (fix).

Moritz Hanke added 2 commits August 25, 2026 13:37
YAC's C core calls the LAPACKE C interface (LAPACKE_dgesv,
LAPACKE_dsytrf_work, LAPACKE_dsytri_work), which lives in a different
library from the Fortran LAPACK that find_package(LAPACK) reports.
BuildYAC.cmake only put ${LAPACK_LIBRARIES} on YAC::yac's interface, so
on a system where YAC's own configure selects the Netlib LAPACKE those
symbols stayed undefined in libyac.a/libyac_core.a and linking fesom.x
failed at 100% with no indication of the cause.

Look for the LAPACKE library and append it, so it lands after the YAC
static archives that reference it. Keep it optional: YAC also resolves
the interface through MKL or falls back to its bundled clapack, and in
both of those cases no extra library is needed. When it is missing, say
so at configure time instead of leaving the failure to the linker.

Not caught by CI because the preset builds run in the fesom2_ci
container, whose LAPACK already covers LAPACKE.

Assisted-by: Claude Code:claude-opus-5
Same gap as the previous commit, reached through the other route. When
OASIS3-MCT is built against YAC instead of SCRIP, FindOASISYAC.cmake puts
OASIS's libyac_core.a on the link line, and that archive calls
LAPACKE_dgesv, LAPACKE_dsytrf_work and LAPACKE_dsytri_work. Nothing else
on the line defines them, so linking fesom.x fails with undefined
LAPACKE_* symbols.

Look for the LAPACKE library and append it to YACCORE_Fortran_LIBRARIES,
and keep it optional for the same reason as in BuildYAC.cmake: a YAC
built against MKL, or one using its bundled clapack, needs no extra
library.

Assisted-by: Claude Code:claude-opus-5
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