Skip to content

binding/fortran: initialize sentinel common blocks in libmpifort - #8027

Open
hzhou-muse wants to merge 2 commits into
pmodels:mainfrom
hzhou-muse:f77-common-data
Open

hzhou-muse wants to merge 2 commits into
pmodels:mainfrom
hzhou-muse:f77-common-data

Conversation

@hzhou-muse

@hzhou-muse hzhou-muse commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Pull Request Description

The Fortran sentinels (MPI_IN_PLACE, MPI_BOTTOM, MPI_STATUS_IGNORE, etc.) are recognized by the addresses of the MPIPRIV*/MPIFCMB* common blocks. These blocks were uninitialized, so they were in .bss in libmpifort.so, and a shared library that includes mpif.h (or uses the mpi module) got its own private copy. When such a library is loaded with RTLD_DEEPBIND, it uses its own copy, and MPICH treats MPI_IN_PLACE as a buffer (#8020).

This PR adds a BLOCK DATA in setbotf.f that initializes the blocks, so libmpifort defines them in .data. GNU ld (bfd) then resolves the consumer's common blocks to libmpifort (U instead of a private B). The BLOCK DATA includes mpifnoext.h, so the block layout always matches mpif.h.

  • Generate mpifnoext.h in mpif_h/ instead of use_mpi/, so the f77 binding can include it.

Tested with the reproducer from #8020 (stand-alone Fortran build against 5.1.0a1):

consumer linked with before after
bfd WRONG with RTLD_DEEPBIND OK
gold / lld WRONG with RTLD_DEEPBIND still WRONG (these linkers keep the private copy)

Fixes #8020

Author Checklist

  • Provide Description
  • Commits Follow Good Practice
  • Passes All Tests
  • Contribution Agreement

🤖 Generated with Claude Code

hzhou-muse and others added 2 commits October 15, 2026 21:21
Generate mpifnoext.h next to mpif.h in mpif_h/, so that the f77
binding can include it. The mpi module adds mpif_h to its include
path. Previously it was generated in use_mpi/ and only used by the mpi
module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a BLOCK DATA in setbotf.f that initializes the common blocks
holding the Fortran sentinels (MPI_IN_PLACE, MPI_BOTTOM, etc.), so
libmpifort defines them as initialized data. GNU ld then resolves the
common blocks of shared libraries that include mpif.h or use the mpi
module to libmpifort's definitions instead of giving them private
copies. Previously, such a library loaded with RTLD_DEEPBIND used its
own copy, and MPICH did not recognize the sentinels it passed.

Fixes pmodels#8020

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hzhou-muse

hzhou-muse commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor Author

test:mpich/ch3/tcp ✔️ 1 unrelated failure fixed in #8030

@hzhou

hzhou commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

@eschnett Can you review?

!
subroutine mpirinitf( )
include 'mpif.h'
! make sure the block data is linked, e.g. from a static library

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think that's how external is working. I don't think it's doing anything for linking. (Maybe it does, but only for some compilers?) Anyway, the block data definition is in the same file so it is linked anyway.

@eschnett eschnett left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This looks good. I left a comment because I think one comment in the code is wrong, but not in a consequential way.

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.

Fortran sentinels (MPI_IN_PLACE etc.) are in .bss in libmpifort.so, so shared libraries using mpif.h get private copies

3 participants