Skip to content
Draft
Show file tree
Hide file tree
Changes from 140 commits
Commits
Show all changes
146 commits
Select commit Hold shift + click to select a range
7e425a4
Add initial ABI generation code and new libraries
jtronge Sep 28, 2023
eebd824
Move ABI support into big count binding code
hppritcha May 10, 2025
1881940
bindings: fix up makefile for c interfaces
hppritcha May 28, 2025
20c973b
makefile fixes
hppritcha May 29, 2025
772b08c
checkpoint
hppritcha Jun 2, 2025
50e1f7d
some fixes and start of a wrapper method
hppritcha Jul 2, 2025
5a652c6
attributes: add wrapper infrastructure
hppritcha Jul 7, 2025
3257cb5
abi: move converter functions to a persistent file
hppritcha Jul 29, 2025
a449c28
minor compiler complaint fix
hppritcha Jul 29, 2025
2b9eaa8
temp commit with comments notes
hppritcha Aug 12, 2025
2302419
Switch to using MPI Standard ABI values
Joe-Downs Jun 26, 2025
d40150d
distcheck fix and more
hppritcha Aug 21, 2025
3a65c12
git ignore additions
hppritcha Aug 23, 2025
44b620e
ABI library: don't include functions in 19.3.4/5
hppritcha Aug 23, 2025
a6da325
fixes to handle count/offset/aint in abi.h
hppritcha Aug 25, 2025
5fac420
fix req converter abi to ompi
hppritcha Aug 26, 2025
39491dd
fix problem with request_get_status_some
hppritcha Aug 26, 2025
fbd0788
bindings: fix up REQUEST_CONST for abi
hppritcha Aug 26, 2025
03250b6
tools: first steps to add support for ABI
hppritcha Sep 2, 2025
fca68c3
fix problem with undefined symbols in libmpi_abi
hppritcha Sep 2, 2025
360a2d7
hack on abi json file
hppritcha Sep 3, 2025
9bd8e9f
abi.h template - add MPI_T related structs
hppritcha Sep 3, 2025
143e5b3
binding framework: fixes for MPI T stuff
hppritcha Sep 3, 2025
3ba5c08
binding framework: add a TS_LEVEL type
hppritcha Sep 3, 2025
fa5de6a
more hacks on the mpi-standard-5.0-abi.json
hppritcha Sep 3, 2025
e0c4614
fix for enable-mca-dso
hppritcha Sep 3, 2025
76265a4
makefile changes to add symbols to libmpi_abi
hppritcha Sep 16, 2025
b99a3af
abi: fix problems with error handler converters
hppritcha Sep 17, 2025
479147b
fix problems with makefiles and some symbols
hppritcha Sep 17, 2025
5981a87
abi: move mpi_type_get_envelope etc. into templates
hppritcha Sep 18, 2025
e0af62a
rebase fixup
hppritcha Sep 19, 2025
2231aab
add abi variantes of mpi_aint_diff and add
hppritcha Sep 19, 2025
5d15192
add abi_set/get_fortran_info
hppritcha Sep 19, 2025
d9c25b7
abi_fortran_stuff: fix up the imp of these
hppritcha Sep 22, 2025
2df3922
abi_converters: add fortran datatypes to
hppritcha Sep 22, 2025
a584be1
fix for mac-os CI
hppritcha Sep 23, 2025
fcd00af
pr feedback on add/diff for aints
hppritcha Sep 23, 2025
126c14a
configury: discover fortran logical false
hppritcha Sep 23, 2025
acebae0
configury fix
hppritcha Sep 23, 2025
5a3d235
squashme: temporary commit
hppritcha Sep 23, 2025
79385ef
add abi_get/set_fortran_booleans c interfaces
hppritcha Sep 25, 2025
73ba61b
abi_fortran: add support for LOGICAL16
hppritcha Sep 25, 2025
d7d0d9b
logical16 patch
hppritcha Sep 29, 2025
e525beb
add comm_from/toint
hppritcha Sep 29, 2025
908d1b8
complete toint/fromint interfaces
hppritcha Oct 1, 2025
c837bbb
fix error return values for ABI routines
hppritcha Oct 1, 2025
c3c500b
minor fixup for toint/fromint
hppritcha Oct 1, 2025
1ac6657
rebase fix
hppritcha Oct 1, 2025
12c623f
handle TAG more correctly
hppritcha Oct 1, 2025
6650e86
squash compiler warning
hppritcha Oct 1, 2025
a444b9b
add hooks for TAG_OUT type
hppritcha Oct 1, 2025
026df5f
add better support for MPI_ROOT and source
hppritcha Oct 1, 2025
ae72028
squash a compiler warning
hppritcha Oct 2, 2025
9eba648
some fixes to comm attributes wrappers
hppritcha Oct 3, 2025
47a6e9e
fix bug in comm attr copy code
hppritcha Oct 3, 2025
931430f
some fixes for attributes and more
hppritcha Oct 7, 2025
528e5e9
checkpoint
hppritcha Oct 9, 2025
47f9c3b
fix for datatype converters
hppritcha Oct 9, 2025
8385db5
distcheck fix
hppritcha Oct 9, 2025
c3a4451
EVENT_INSTANCE: arg type cast fix
hppritcha Oct 9, 2025
b8f8e4c
MPI_ROOT: capture proc null type too
hppritcha Oct 9, 2025
667db71
requests: fixes to some multirequest test functions
hppritcha Oct 10, 2025
97c71d2
weights and source out support/fixes
hppritcha Oct 10, 2025
1f0254a
some fixes for message related functions
hppritcha Oct 11, 2025
d86c6e4
fix mpi4py break
hppritcha Oct 11, 2025
949868f
fix a few problems with datatype bindings
hppritcha Oct 11, 2025
b86d21e
update gitignore
hppritcha Oct 11, 2025
d0b9d14
add replacements to code bodies for various string lengths
hppritcha Oct 13, 2025
b18a8a5
add support for distrib array and order
hppritcha Oct 13, 2025
117356e
add support for mode bits - in only
hppritcha Oct 13, 2025
fd1a0a8
add support for amode out
hppritcha Oct 13, 2025
57094ab
add support for whence
hppritcha Oct 14, 2025
311eadd
add support for some win attributes
hppritcha Oct 14, 2025
e8ea562
handle special case of MPI_DISPLACEMENT_CURRENT
hppritcha Oct 14, 2025
5df6bae
add support for combiner, typeclass, win lock assert
hppritcha Oct 14, 2025
8f7628b
c_header: comment out deprecated functions
hppritcha Oct 15, 2025
6009f50
fix problem with special attrs for windows
hppritcha Oct 15, 2025
4f2aecf
fix for win_shared_query
hppritcha Oct 15, 2025
869c1a2
fixes to rget/rget_accumulate
hppritcha Oct 16, 2025
e08a17a
fix problem with code gen for win create keyval
hppritcha Oct 16, 2025
12e750a
fix rank problem in rput/raccumulate
hppritcha Oct 16, 2025
4fcf510
add MPI_GROUP_EMPTY to predefined group handles
hppritcha Oct 16, 2025
f707467
handle user error classes and codes
hppritcha Oct 16, 2025
220739a
temporary WAR for non-blocking alltoallw
hppritcha Oct 20, 2025
7d6fa88
add support for comm topos
hppritcha Oct 20, 2025
e39a31b
support INOUT attribute for all handles
hppritcha Oct 20, 2025
db8111c
fix problem with attribute callback handling
hppritcha Oct 20, 2025
e342404
catch use of special buffer consts
hppritcha Oct 21, 2025
353ad35
remove some debug statements
hppritcha Oct 21, 2025
43624b7
swat nit
hppritcha Oct 21, 2025
b691dac
patch get_address
hppritcha Oct 21, 2025
1a962e6
add new type to handle out void stars
hppritcha Oct 21, 2025
f3bfbf3
fixes for datatypes for neighbor collectives
hppritcha Oct 21, 2025
dc5e23d
add inouts for op, errhandler, info
hppritcha Oct 22, 2025
a3c7260
cleanup datatype tmps for ialltoallw and friends
hppritcha Oct 22, 2025
3375287
a logical16 fix
hppritcha Oct 22, 2025
0a36325
abi_get_version/get_info add to ompi abi lib
hppritcha Oct 22, 2025
0c3cbde
toint fixes
hppritcha Oct 23, 2025
f9f6acd
fix issue with ASYNC data arrays cleanup
hppritcha Oct 24, 2025
ddb6d74
various fixes from dalcinl
hppritcha Oct 24, 2025
27c2e6a
fix a problem
hppritcha Oct 24, 2025
15092ef
ompi-codegen.patch from dalcinl
hppritcha Oct 24, 2025
d165aed
ompi-abiinfo.patch from dalcinl
hppritcha Oct 24, 2025
3126f86
ompi-status.patch from dalcinl
hppritcha Oct 25, 2025
d56b5e6
move some deprecated funcs out of libmpi-abi
hppritcha Oct 27, 2025
4694f63
add support for typeclass
hppritcha Oct 27, 2025
ce93d8c
ops: convert data from internal to abi
hppritcha Oct 27, 2025
5f27c44
split rdma modes out from modes for files
hppritcha Oct 27, 2025
f738ba1
add SOURCE_ARRAY type
hppritcha Oct 27, 2025
0704146
fixes to abi_get_fortran_info
hppritcha Oct 28, 2025
d6baa28
apply patch omp-op-inout.patch
hppritcha Oct 29, 2025
0b710d6
apply patch ompi-abi-fortran.patch
hppritcha Oct 29, 2025
34df931
fix for FD_INOUT
hppritcha Oct 29, 2025
9e79d60
fix for isend dst arg
hppritcha Oct 29, 2025
1688d76
apply patch ompi-query-thread.patch
hppritcha Oct 29, 2025
06cc3ea
various pt2pt fixes to handle proc_null etc.
hppritcha Oct 30, 2025
edbe8e5
rma: updates to args to handle proc_null etc
hppritcha Oct 30, 2025
bc73bac
adjustments for improbe and iprobe
hppritcha Oct 30, 2025
9153ff7
fix for status array for MPI_Request_testsome
hppritcha Oct 30, 2025
60275b5
switch to using a malloc wrapper
hppritcha Nov 2, 2025
eeca33f
plug memory leak handling REQUEST_INOUT type
hppritcha Nov 2, 2025
a33ccb8
patch status out to handle copy in
hppritcha Nov 3, 2025
7b7f032
handle dargs for darray_create correctly
hppritcha Nov 4, 2025
b8535be
fixes for spawn multiple - array of info args
hppritcha Nov 4, 2025
53dc796
disable async NBC-based cleanup for now
hppritcha Nov 4, 2025
4a10921
turn back on async array cleanup stuff
hppritcha Nov 7, 2025
7fced6c
cleanup: patch the coll libnbc to free data arrays
hppritcha Nov 7, 2025
2ab7ec9
small patch from dalcinl
hppritcha Nov 8, 2025
7d9a631
info array tweak from dalcinl (ompi-info-array.patch)
hppritcha Nov 10, 2025
742d99c
MPI_Info_toint/fromint allow to be calleable
hppritcha Nov 10, 2025
0307fe0
first pass at errhandler support
hppritcha Nov 11, 2025
d581080
gitignore - add a file
hppritcha Nov 13, 2025
eb15f01
simplify python support for user-defined err handlers
hppritcha Nov 13, 2025
c766023
minor compiler warning cleanups
hppritcha Nov 16, 2025
1e9f54f
VERSION - add support for versioning libmpi_abi
hppritcha Nov 16, 2025
590e08e
add man pages for new MPI_Abi and fromint/toint functions
hppritcha Nov 16, 2025
979e947
attributes - clean up extra helper data
hppritcha Nov 17, 2025
c10ad8f
minor cleanup
hppritcha Nov 17, 2025
6f61c18
a bit more cleanup
hppritcha Nov 17, 2025
43a3314
add a readme about the MPI ABI support
hppritcha Nov 17, 2025
3f18ae2
add short blurb for users about c ABI support
hppritcha Nov 17, 2025
ffa676e
fix up blurb about libmpi_abi versioning
hppritcha Nov 18, 2025
1d1cf81
fortran: add the MPI_Abi entry points
hppritcha Nov 25, 2025
a566ddf
python framework: improve debugging
hppritcha Nov 25, 2025
c3d6e57
fortran: fix it
hppritcha Nov 25, 2025
874bbd1
pr feedback
hppritcha Nov 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ ompi/tools/ompi_info/ompi_info

ompi/tools/wrappers/mpic++-wrapper-data.txt
ompi/tools/wrappers/mpicc-wrapper-data.txt
ompi/tools/wrappers/mpicc_abi-wrapper-data.txt
ompi/tools/wrappers/mpifort-wrapper-data.txt
ompi/tools/wrappers/ompi_wrapper_script
ompi/tools/wrappers/ompi.pc
Expand Down Expand Up @@ -534,6 +535,13 @@ docs/man

# Generated C Bindings
ompi/mpi/c/*_generated*.c
ompi/mpi/c/standard_*.c
ompi/mpi/c/abi.h
ompi/mpi/c/abi_get_info.c
ompi/mpi/c/abi_converters.h
ompi/mpi/c/abi_converters.c
ompi/mpi/c/standard_abi
ompi/mpi/tool/*_generated*.c

# Generated Fortran Bindings
ompi/mpi/fortran/use-mpi-f08/*_generated.F90
Expand Down
7 changes: 7 additions & 0 deletions VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ date="Unreleased developer copy"
# but they are "public" within the OMPI code base and select 3rd party
# software packages.

# The current and age values of the libmpi_abi shared library are defined by the
# specification of the ABI for the version of the MPI standard supported
# by this Open MPI release. One would hope that these always move in
# sync. We assume we have flexibility with the revision number as
# bugs are fixed, etc.

# Version numbers are described in the Libtool current:revision:age
# format.

Expand All @@ -100,6 +106,7 @@ libmpi_mpifh_so_version=0:0:0
libmpi_usempi_tkr_so_version=0:0:0
libmpi_usempi_ignore_tkr_so_version=0:0:0
libmpi_usempif08_so_version=0:0:0
libmpi_abi_so_version=0:0:0
Copy link
Member

Choose a reason for hiding this comment

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

I built MPICH 5.0b1 and see that it installs libmpi_abi.so.0[.0.0].

Per our conventions, will we be shifting this CRA value to something other than 0:0:0 on release branches (e.g., 0:1:0, so that C-A is still 0, and we still produce libmpi_abi.so.0 to match MPICH)? I ask this only because Libtool recommends not shipping 0:0:0.

Thinking a little further down this rabbit hole: does having both ABI-enabled Open MPI and MPICH allow installing Open MPI and MPICH into the same $prefix (with all default sub directories, like $includedir being $prefix/include)? I'm thinking "no" for at least the following reasons:

  1. mpi.h will have all the ABI things being identical, but we'll have other differences from MPICH's mpi.h (right?).
    • Bottom line: package managers would conflict on $prefix/include/mpi.h.
    • That being said, perhaps creative use of ./configure --includedir=... could workaround that.
  2. There's nothing to distinguish between libmpi_abi.so.* -- you couldn't tell if it was from Open MPI or MPICH. From a user perspective, that might be ok, but from a package manager and/or system administrator point of view -- that might get a little weird. For example, what if we both ship libmpi_abi.so.0.a.b with the same a and b values?
    • Bottom line: package managers would conflict if we both ship -- for example -- libmpi_abi.so.0.0.0.
    • Put differently, should we ensure that our libmpi_abi shared library a and b values are different than MPICH's somehow? (I really haven't thought this through to know if this is even possible in a sustainable way over time -- nor what the consequences are outside of Linux)

I guess I'm wondering if it's useful to build Open MPI and MPICH with something like:

# Open MPI
$ ./configure --prefix=/opt/mpi --includedir=/opt/mpi/openmpi ...
# MPICH
$ ./configure --prefix=/opt/mpi --includedir=/opt/mpi/mpich --enable-mpi-abi ...

This would keep a single libdir so that we don't introduce (more) LD_LIBRARY_PATH complexity, but still allow unique mpi.h.

But then again, there's still problems with mpirun and mpiexec filename clashes in $bindir (not to mention CLI flag differences). Maybe something like Linux-style alternatives could be useful here...? Shrug.

I understand how ABI between MPI libraries solves some perceived problems for users, but trying to go the next steps to actually hide the differences between MPI implementations gets pretty tricky pretty quickly.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thinking a little further down this rabbit hole: does having both ABI-enabled Open MPI and MPICH allow installing Open MPI and MPICH into the same $prefix (with all default sub directories, like $includedir being $prefix/include)? I'm thinking "no" for at least the following reasons:

The point of having a unique ABI is to be able to switch between different backends, which effectively requires same sonames (and filenames), so that's pretty much by design. You'd either have a single MPI library at a time in a single-prefix scenario, or as many as you want in a multiple-prefix scenario (think of Spack).

Copy link
Member Author

Choose a reason for hiding this comment

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

another use case I could see is the usual "modules" setup on an HPC cluster. the user could just switch between the mpich module and the openmpi module without needing to recompile/relink. that's basically how one would use spack modules system.

Copy link
Contributor

Choose a reason for hiding this comment

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

You cannot just blindly switch from one module to another UNLESS the ABI's are an exact match - in other words, you have to ensure that the version of the ABI you are switching to is the same as the one you currently are using. An ABI is a rigid specification - there is no such thing as a minor revision to it. Any change - be it an addition, subtraction, or (heaven forbid) a modification - results in a new ABI, and the version number (in libtool parlance, the .so number) must change.

That's the entire point of the libtool .so number - to guide the linker to picking the library that matches the signature required by the executable. In this case, that's the ABI.

People who have been building ABIs learned this the hard way. As @jsquyres pointed out, there are a ton of other problems - but setting the .so number to the ABI version is a basic necessity. Having an unchanging .so number even when the ABI changes is a disaster. The linker will basically be playing russian roulette, and users will rapidly find it...let's politely say, less than useful.

In this case, you want the ABI library to have a .so that matches the ABI it supports. You benefit from having a second library - the actual backend implementation - that can change as it is modified. Key is to tie the ABI library to the matching backend, and then change that connection as you update backends. In other words, you update the ABI-backend combination when the backend gets updated.

So the "module" is an ABI-backend combination, and the user picks the ABI they want supported along with the underlying implementation that supports that ABI. In other words, "give me MPI v2 ABI and the OMPI v6.2.1 backend". If you don't care about ABI, then just pick the implementation library. If you don't care about backend, then select the ABI module and let it pick the default backend.

Copy link
Contributor

@dalcinl dalcinl Nov 27, 2025

Choose a reason for hiding this comment

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

Per our conventions, will we be shifting this CRA value to something other than 0:0:0 on release branches (e.g., 0:1:0, so that C-A is still 0, and we still produce libmpi_abi.so.0 to match MPICH)?

@jsquyres IMHO, the way this should be handled is the following: The CURRENT and AGE number are implicitly defined from the MPI_ABI_VERSION/MPI_ABI_SUBVERSION numbers, that is, by the set of backward-compatible additions or the backward-incompatible changes. I am assuming that MPI_ABI_VERSION will stay at 1 as long as there are no backward-incompatible changes, and MPI_ABI_SUBVERSION will bump on backward-compatible additions/updates.
The REVISION number could be left for use by the MPI implementation, this way multiple revisions can be installed in the same prefix location, with ldconfig going through its usual cache update rules.

I tried to layout the rules here mpi-forum/mpi-abi-stubs#28. The "formulas" there would produce a soname libmpi_abi.so.1, but if we want a .0 suffix, that's trivial to fix by subtracting 1 from the formula for current.

I ask this only because Libtool recommends not shipping 0:0:0.

Can you point me to such recommendation?

Copy link
Member

Choose a reason for hiding this comment

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

Just to be clear: I know what the use cases are for ABI (e.g., env modules-style or spack-style environments). My question about whether two installs could share a common $prefix was probably more of a hypothetical musing more than anything else. I even answered my own question -- the answer is probably "no", for the reasons already discussed.


@jsquyres IMHO, the way this should be handled is the following: The CURRENT and AGE number are implicitly defined from the MPI_ABI_VERSION/MPI_ABI_SUBVERSION numbers,

I admit that I don't quite understand the purpose of MPI_ABI_VERSION and MPI_ABI_SUBVERSION. As you pointed out earlier in this thread, there's essentially 2 common styles of maintaining binary compatibility these days:

  1. The Libtool CRA triple
  2. MacOS linker-style single-integer versioning

How exactly do a pair of compile-time constants fit into either of those schemes? It's not described in MPI-5.0, nor is an alternate (i.e., 3rd) scheme described. MPI-5.0:20.2 loosely implies that MPI_ABI_SUBVERSION can be used as a proxy for MPI_VERSION and MPI_SUBVERSION (i.e., be used for conditional compilation of various MPI symbols / types / functions / etc.). But that seems odd -- why have new constants for a mechanism that has worked for decades?

Sure, MPI_ABI_VERSION could be a proxy for a Linux SONAME. But then what's the point of MPI_ABI_SUBVERSION at compile time (or even run time, via MPI_ABI_GET_VERSION())?

If we intend MPI_ABI_VERSION to be a proxy for Linux SONAME, that seems fine. Is there a scheme for how MPI_ABI_SUBVERSION should factor in here? The way that MPI_ABI_SUBVERSION is (loosely) defined in MPI-5.0 does not seem like a hypothetical scheme such as -- for example -- (MPI_ABI_VERSION * 100 + MPI_ABI_SUBVERSION) would be a good candidate as a proxy for the Linux SONAME. So what do implementations and/or users use MPI_ABI_SUBVERSION for?

I'm digressing from the main question here, and I don't mean to open a whole debate about these 2 compile-time constants here in OMPI -- such issues can be discussed at the Forum level.

For an ABI to satisfy the use cases described above (e.g., swapping out the back end), the questions of how to create linker-compatible shared library versions should really be resolved into some kind of scheme that both Open MPI and MPICH -- and our various derivative implementations -- follow. This doesn't necessarily have to be in the MPI spec itself; it's probably better as an agreement between the Open MPI and MPICH communities. My point: we need to have the discussion and then publicly document the scheme so that anyone can follow it (e.g., even outside of Open MPI and MPICH).

I ask this only because Libtool recommends not shipping 0:0:0.

Can you point me to such recommendation?

Doh! I just re-read the LT docs and I cannot find such a recommendation. So I guess I'm wrong here. Perhaps I'm remembering some super-old conversation about how we (OMPI?) didn't want to release with 0:0:0 because that's what's on main and we don't release off main (similar to the project version number) -- i.e., more of a release philosophy kind of thing than a strict technical requirement.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am assuming that MPI_ABI_VERSION will stay at 1 as long as there are no backward-incompatible changes, and MPI_ABI_SUBVERSION will bump on backward-compatible additions/updates.

My assumption at that time is now part of the standard, MPI 5.0 says (sec 20.2 pp 844):

Backwards-compatible changes, such as the addition of new handle types, will incre-
ment the minor version. Backwards-incompatible changes will increment the major version.
The addition of new functions to the MPI API does not change the ABI version.

Copy link
Member

Choose a reason for hiding this comment

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

Backwards-compatible changes, such as the addition of new handle types, will incre-
ment the minor version. Backwards-incompatible changes will increment the major version.
The addition of new functions to the MPI API does not change the ABI version.

Yes, I saw that. But can you provide an example of how it would be useful / used?

I.e., how exactly is it different than MPI_VERSION an MPI_SUBVERSION?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I saw that. But can you provide an example of how it would be useful / used?

Long ago, somewhere, I claimed that MPI_ABI_VERSION/SUBVERSION was not that useful. As usual, I was ignored ;'-), and now we have these version numbers in the standard. Anyway, now I believe it is still good to have the version defined (though not necessary the C macros). The MPI ABI version/subversion values are to be updated following similar rules as libtool, therefore we can use them to define the C/R/A tuple the following way:

C := MPI_ABI_VERSION + MPI_ABI_SUBVERSION - 1
R := <free for MPI implementations to update at will>
A := MPI_ABI_SUBVERSION

and then under these rules we get a SONAME libmpi_abi.so.0 and then all the planets are aligned.

Could you please give a bit of though to this claim of mine? Think again about the rules for updating the MPI ABI version/subversion, the libtool c/r/a update rules, my formulas above, my claim about the SONAME, and confirm whether am I right?

The other obvious uses if conditional compilation with the macros. I use the presence of MPI_ABI_VERSION in mpi4py to conditionally-compile if building against the MPI standard ABI. Regarding the use of the values of MPI_ABI_VERSION/SUBVERSION, there is definitely some overlap with MPI_VERSION/SUBVERSION.

I.e., how exactly is it different than MPI_VERSION an MPI_SUBVERSION?

MPI_VERSION/SUBVERSION follow the version of the MPI standard, this is unrelated to ABI or even API. The MPI standard version is not only about API but also about runtime behavior changes. MPI_VERSION/SUBVERSION evolve in ways that are totally unrelated to whether the API/ABI changes are backward compatible or not, while MPI_ABI_VERSION will stay at 1 for as long as the MPI Forum does not introduce backward incompatible changes.

Copy link
Member

@jsquyres jsquyres Nov 27, 2025

Choose a reason for hiding this comment

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

Interesting CRA proposal. I don't think it's quite right, though -- I think you have to give the MPI_ABI_[SUB]VERSION their own distinct digits (somewhat akin to bit mapping). E.g.:

// Give subversion its own 2 digits.  I.e., the Forum should never allow SUBVERSION>99
C := (MPI_ABI_VERSION * 100) + MPI_ABI_SUBVERSION
R := <free for MPI implementations to update at will>
A := MPI_ABI_SUBVERSION

This gives you unique values. Otherwise, you could end up with

  • Version X, with:
    • MPI_ABI_VERSION=1, MPI_ABI_SUBVERSION=2
    • Original scheme yields C=2, A=2 --> Linux SONAME == 0
    • New scheme yields C=102, A=2 --> Linux SONAME == 100
  • Version Y with:
    • MPI_ABI_VERSION=2, MPI_ABI_SUBVERSION=0
    • Original scheme yields C=1, A=0
      • C went backwards compared to version X, which seems bad --> Linux SONAME == 1
    • New scheme yields C=200, A=0 --> Linux SONAME == 200
      • This seems appropriate because changing MPI_ABI_VERSION to 2 indicates that a backwards-incompatible change was made.

Put differently: the original scheme only works if MPI_ABI_VERSION never increases (which would be morally equivalent to hard-coding C=MPI_ABI_SUBVERSION-1, A=MPI_ABI_SUBVERSION). Otherwise, we can get repeat C and A values for different values of MPI_ABI_[SUB]VERSION.

MPI_VERSION/SUBVERSION follow the version of the MPI standard, this is unrelated to ABI or even API.

I guess what I'm asking for: can you give an example of something you'd need to #if on that is based on ABI and not API. This might be a failure of imagination on my part to come up with a useful example here...

And FWIW, I tend to prefer always defining preprocessor macros (as opposed to undefining them vs. defining them). If you always define them, you protect against typos:

// Both of these result in true
#if !defined(MPI_ABI_VERSION)
#if !defined(MPI_ABI_VERSIONBUT_I_HAVE_A_TYPO_HERE)

whereas this will result in a compilation error:

#if MPI_ABI_VERSIONBUT_I_HAVE_A_TYPO_HERE > 0

libopen_pal_so_version=0:0:0
libmpi_java_so_version=0:0:0
liboshmem_so_version=0:0:0
Expand Down
1 change: 1 addition & 0 deletions config/ompi_config_files.m4
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ AC_DEFUN([OMPI_CONFIG_FILES],[
ompi/tools/ompi_info/Makefile
ompi/tools/wrappers/Makefile
ompi/tools/wrappers/mpicc-wrapper-data.txt
ompi/tools/wrappers/mpicc_abi-wrapper-data.txt
ompi/tools/wrappers/mpic++-wrapper-data.txt
ompi/tools/wrappers/mpifort-wrapper-data.txt
ompi/tools/wrappers/ompi.pc
Expand Down
26 changes: 25 additions & 1 deletion config/ompi_configure_options.m4
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,29 @@ AM_CONDITIONAL(OMPI_OMPIO_SUPPORT, test "$ompi_want_ompio" = "1")
AC_ARG_ENABLE([deprecate-mpif-h],
[AS_HELP_STRING([--enable-deprecate-mpif-h],
[Mark the mpif.h bindings as deprecated (default: enabled)])])

# If the binding source files don't exist, then we need Python to generate them
AM_PATH_PYTHON([3.6],,[:])
binding_file="${srcdir}/ompi/mpi/c/ompi_send_generated.c"
AS_IF([! test -e "$binding_file" && test "$PYTHON" = ":"],
[AC_MSG_ERROR([Open MPI requires Python >=3.6 for generating the bindings. Aborting])])
AM_CONDITIONAL(OMPI_GENERATE_BINDINGS,[test "$PYTHON" != ":"])

AC_MSG_CHECKING([if want to enable standard ABI library])
AC_ARG_ENABLE([standard-abi],
[AS_HELP_STRING([--enable-standard-abi],
[Enable building the standard ABI library (default: enabled)])])
if test "$enable_standard_abi" = "no"; then
AC_MSG_RESULT([no])
ompi_standard_abi=0
else
AC_MSG_RESULT([yes])
ompi_standard_abi=1
fi
AC_DEFINE_UNQUOTED([OMPI_STANDARD_ABI],[$ompi_standard_abi],
[Whether we want to build the standard ABI library])
AM_CONDITIONAL(OMPI_STANDARD_ABI,[test $ompi_standard_abi = 1])
AS_IF([test $ompi_standard_abi -eq 1],
[gen_abi="yes"],
[gen_abi="no"])
OPAL_SUMMARY_ADD([Miscellaneous], [MPI Standard ABI support], [], [$gen_abi])
])dnl
4 changes: 3 additions & 1 deletion config/ompi_fortran_check_logical_array.m4
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ dnl All rights reserved.
dnl Copyright (c) 2011-2012 Cisco Systems, Inc. All rights reserved.
dnl Copyright (c) 2015 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl Copyright (c) 2025 Triad National Security, LLC. All rights
dnl reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
Expand Down Expand Up @@ -64,7 +66,7 @@ void ompi_check_f(ompi_fortran_logical_t * logical)
FILE *f=fopen("conftestval", "w");
if (!f) exit(1);

if (logical[[0]] == 0 &&
if (logical[[0]] == $ompi_cv_fortran_false_value &&
logical[[1]] == $ompi_cv_fortran_true_value)
result = 1;
fprintf(f, "%d\n", result);
Expand Down
60 changes: 56 additions & 4 deletions config/ompi_fortran_get_value_true.m4
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ dnl All rights reserved.
dnl Copyright (c) 2011-2012 Cisco Systems, Inc. All rights reserved.
dnl Copyright (c) 2015 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl Copyright (c) 2025 Triad National Security, LLC. All rights
dnl reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
Expand All @@ -27,16 +29,22 @@ AC_DEFUN([OMPI_FORTRAN_GET_VALUE_TRUE],[
if test "$ompi_cv_fortran_true_value" = "0" ; then
unset ompi_cv_fortran_true_value
fi
if test "$ompi_cv_fortran_false_value" = "0" ; then
unset ompi_cv_fortran_false_value
fi

AS_VAR_PUSHDEF([fortran_true_var],
[ompi_cv_fortran_true_value])
AS_VAR_PUSHDEF([fortran_false_var],
[ompi_cv_fortran_false_value])

AC_CACHE_CHECK([Fortran value for .TRUE. logical type],
fortran_true_var,
[if test "$1" = "none" || \
test $OMPI_TRY_FORTRAN_BINDINGS -eq $OMPI_FORTRAN_NO_BINDINGS || \
test $ompi_fortran_happy -eq 0 ; then
value=77
tvalue=77
fvalue=77
else
#
# C module
Expand Down Expand Up @@ -98,6 +106,14 @@ EOF
CALL ompi_print(value)
end
EOF
cat > conftestf2.f <<EOF
program main
logical value
value=.FALSE.
CALL ompi_print(value)
end
EOF


#
# Try the compilation and run.
Expand All @@ -114,11 +130,40 @@ EOF
AS_IF([test "$cross_compiling" = "yes"],
[AC_MSG_ERROR([Can not determine value of .TRUE. when cross-compiling])],
[OPAL_LOG_COMMAND([./conftest],
[value=`sed 's/ *//' conftestval`],
[tvalue=`sed 's/ *//' conftestval`],
[AC_MSG_ERROR([Could not determine value of Fotran .TRUE.. Aborting.])])])

cat > conftestf.f <<EOF
program main
logical value
value=.FALSE.
CALL ompi_print(value)
end
EOF

#
# Try the compilation and run.
#
OPAL_LOG_COMMAND([$CC $CFLAGS -I. -c conftest.c],
[OPAL_LOG_COMMAND([$FC $FCFLAGS -o conftest conftest.o conftestf.f $LDFLAGS $LIBS],
[happy=1], [happy=0])],
[happy=0])

AS_IF([test $happy -eq 0 && test $ompi_fortran_happy -eq 1],
[AC_MSG_ERROR([Could not compile Fortran .FALSE. test. Aborting.])
])

AS_IF([test "$cross_compiling" = "yes"],
[AC_MSG_ERROR([Can not determine value of .FALSE. when cross-compiling])],
[OPAL_LOG_COMMAND([./conftest],
[fvalue=`sed 's/ *//' conftestval`],
[AC_MSG_ERROR([Could not determine value of Fotran .FALSE.. Aborting.])])])
fi
AS_VAR_SET(fortran_true_var, [$value])
unset value
AS_VAR_SET(fortran_true_var, [$tvalue])
unset tvalue
AS_VAR_SET(fortran_false_var, [$fvalue])
unset fvalue

])

AS_VAR_COPY([ompi_fortran_true_value], [fortran_true_var])
Expand All @@ -127,6 +172,13 @@ EOF
[Fortran value for LOGICAL .TRUE. value])
AS_VAR_POPDEF([fortran_true_var])

AS_VAR_COPY([ompi_fortran_false_value], [fortran_false_var])
AC_DEFINE_UNQUOTED([OMPI_FORTRAN_VALUE_FALSE],
[$ompi_fortran_false_value],
[Fortran value for LOGICAL .FALSE. value])
AS_VAR_POPDEF([fortran_false_var])


unset happy ompi_print_logical_fn
rm -rf conftest*
])dnl
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ OPAL_SAVE_VERSION([OPAL], [Open Portable Access Layer], [$srcdir/VERSION],

m4_ifdef([project_ompi],
[AC_SUBST(libmpi_so_version)
AC_SUBST(libmpi_abi_so_version)
AC_SUBST(libmpi_mpifh_so_version)
AC_SUBST(libmpi_usempi_tkr_so_version)
AC_SUBST(libmpi_usempi_ignore_tkr_so_version)
Expand Down
30 changes: 30 additions & 0 deletions docs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ OMPI_MAN1 = \
opal_wrapper.1

OMPI_MAN3 = \
MPI_Abi_get_fortran_booleans.3 \
MPI_Abi_get_fortran_info.3 \
MPI_Abi_get_info.3 \
MPI_Abi_get_version.3 \
MPI_Abi_set_fortran_booleans.3 \
MPI_Abi_set_fortran_info.3 \
MPI_Abort.3 \
MPI_Accumulate.3 \
MPI_Add_error_class.3 \
Expand Down Expand Up @@ -151,6 +157,7 @@ OMPI_MAN3 = \
MPI_Comm_flush_buffer.3 \
MPI_Comm_free.3 \
MPI_Comm_free_keyval.3 \
MPI_Comm_fromint.3 \
MPI_Comm_get_attr.3 \
MPI_Comm_get_errhandler.3 \
MPI_Comm_get_info.3 \
Expand All @@ -174,6 +181,7 @@ OMPI_MAN3 = \
MPI_Comm_split.3 \
MPI_Comm_split_type.3 \
MPI_Comm_test_inter.3 \
MPI_Comm_toint.3 \
MPI_Compare_and_swap.3 \
MPI_Dims_create.3 \
MPI_Dist_graph_create.3 \
Expand All @@ -182,8 +190,10 @@ OMPI_MAN3 = \
MPI_Dist_graph_neighbors_count.3 \
MPI_Errhandler_create.3 \
MPI_Errhandler_free.3 \
MPI_Errhandler_fromint.3 \
MPI_Errhandler_get.3 \
MPI_Errhandler_set.3 \
MPI_Errhandler_toint.3 \
MPI_Error_class.3 \
MPI_Error_string.3 \
MPI_Errors.3 \
Expand All @@ -196,6 +206,7 @@ OMPI_MAN3 = \
MPI_File_create_errhandler.3 \
MPI_File_delete.3 \
MPI_File_f2c.3 \
MPI_File_fromint.3 \
MPI_File_get_amode.3 \
MPI_File_get_atomicity.3 \
MPI_File_get_byte_offset.3 \
Expand Down Expand Up @@ -239,6 +250,7 @@ OMPI_MAN3 = \
MPI_File_set_size.3 \
MPI_File_set_view.3 \
MPI_File_sync.3 \
MPI_File_toint.3 \
MPI_File_write.3 \
MPI_File_write_all.3 \
MPI_File_write_all_begin.3 \
Expand Down Expand Up @@ -282,13 +294,15 @@ OMPI_MAN3 = \
MPI_Group_excl.3 \
MPI_Group_f2c.3 \
MPI_Group_free.3 \
MPI_Group_fromint.3 \
MPI_Group_from_session_pset.3 \
MPI_Group_incl.3 \
MPI_Group_intersection.3 \
MPI_Group_range_excl.3 \
MPI_Group_range_incl.3 \
MPI_Group_rank.3 \
MPI_Group_size.3 \
MPI_Group_toint.3 \
MPI_Group_translate_ranks.3 \
MPI_Group_union.3 \
MPI_Iallgather.3 \
Expand Down Expand Up @@ -317,12 +331,14 @@ OMPI_MAN3 = \
MPI_Info_env.3 \
MPI_Info_f2c.3 \
MPI_Info_free.3 \
MPI_Info_fromint.3 \
MPI_Info_get.3 \
MPI_Info_get_nkeys.3 \
MPI_Info_get_nthkey.3 \
MPI_Info_get_string.3 \
MPI_Info_get_valuelen.3 \
MPI_Info_set.3 \
MPI_Info_toint.3 \
MPI_Init.3 \
MPI_Initialized.3 \
MPI_Init_thread.3 \
Expand All @@ -348,6 +364,8 @@ OMPI_MAN3 = \
MPI_Lookup_name.3 \
MPI_Message_c2f.3 \
MPI_Message_f2c.3 \
MPI_Message_fromint.3 \
MPI_Message_toint.3 \
MPI_Mprobe.3 \
MPI_Mrecv.3 \
MPI_Neighbor_allgather.3 \
Expand All @@ -366,6 +384,8 @@ OMPI_MAN3 = \
MPI_Open_port.3 \
MPI_Op_f2c.3 \
MPI_Op_free.3 \
MPI_Op_fromint.3 \
MPI_Op_toint.3 \
MPI_Pack.3 \
MPI_Pack_external.3 \
MPI_Pack_external_size.3 \
Expand Down Expand Up @@ -398,10 +418,12 @@ OMPI_MAN3 = \
MPI_Request_c2f.3 \
MPI_Request_f2c.3 \
MPI_Request_free.3 \
MPI_Request_fromint.3 \
MPI_Request_get_status.3 \
MPI_Request_get_status_all.3 \
MPI_Request_get_status_any.3 \
MPI_Request_get_status_some.3 \
MPI_Request_toint.3 \
MPI_Rget.3 \
MPI_Rget_accumulate.3 \
MPI_Rput.3 \
Expand All @@ -423,12 +445,14 @@ OMPI_MAN3 = \
MPI_Session_f2c.3 \
MPI_Session_finalize.3 \
MPI_Session_flush_buffer.3 \
MPI_Session_fromint.3 \
MPI_Session_get_info.3 \
MPI_Session_get_nth_pset.3 \
MPI_Session_get_num_psets.3 \
MPI_Session_get_pset_info.3 \
MPI_Session_iflush_buffer.3 \
MPI_Session_init.3 \
MPI_Session_toint.3 \
MPI_Sizeof.3 \
MPI_Ssend.3 \
MPI_Ssend_init.3 \
Expand All @@ -440,6 +464,7 @@ OMPI_MAN3 = \
MPI_Status_f082f.3 \
MPI_Status_f2c.3 \
MPI_Status_f2f08.3 \
MPI_Status_fromint.3 \
MPI_Status_get_error.3 \
MPI_Status_get_source.3 \
MPI_Status_get_tag.3 \
Expand All @@ -449,6 +474,7 @@ OMPI_MAN3 = \
MPI_Status_set_error.3 \
MPI_Status_set_source.3 \
MPI_Status_set_tag.3 \
MPI_Status_toint.3 \
MPI_T.3 \
MPI_T_category_changed.3 \
MPI_T_category_get_categories.3 \
Expand Down Expand Up @@ -525,6 +551,7 @@ OMPI_MAN3 = \
MPI_Type_f2c.3 \
MPI_Type_free.3 \
MPI_Type_free_keyval.3 \
MPI_Type_fromint.3 \
MPI_Type_get_attr.3 \
MPI_Type_get_contents.3 \
MPI_Type_get_envelope.3 \
Expand All @@ -544,6 +571,7 @@ OMPI_MAN3 = \
MPI_Type_size.3 \
MPI_Type_size_x.3 \
MPI_Type_struct.3 \
MPI_Type_toint.3 \
MPI_Type_ub.3 \
MPI_Type_vector.3 \
MPI_Unpack.3 \
Expand Down Expand Up @@ -573,6 +601,7 @@ OMPI_MAN3 = \
MPI_Win_flush_local_all.3 \
MPI_Win_free.3 \
MPI_Win_free_keyval.3 \
MPI_Win_fromint.3 \
MPI_Win_get_attr.3 \
MPI_Win_get_errhandler.3 \
MPI_Win_get_group.3 \
Expand All @@ -589,6 +618,7 @@ OMPI_MAN3 = \
MPI_Win_start.3 \
MPI_Win_sync.3 \
MPI_Win_test.3 \
MPI_Win_toint.3 \
MPI_Win_unlock.3 \
MPI_Win_unlock_all.3 \
MPI_Win_wait.3 \
Expand Down
Loading