Repository navigation
abi: clean up mpix.h, mpi_legacy.h and ABI exports - #8131
Conversation
|
@dalcinl Thanks for the libabigail review in #7938 and the proposal in #7948. This PR addresses both:
This PR takes over #7948, so I think #7948 can be closed once this is merged. |
fefe6ce to
be96b2d
Compare
|
Local testing results (be96b2d). Builds (autogen + configure, Fixed while testing (folded into their commits):
Results
Not covered: Pre-existing issues on main, not addressed here:
|
6bc227e to
16e9ee1
Compare
|
@dalcinl @hppritcha One issue after another, the PR got more complex than its initial scope. The end results for MPI ABI build:
|
|
test:mpich/ch3/most |
| - [Overriding Collective Functions](Overriding_Collective_Functions.md) | ||
|
|
||
| - Language Bindings | ||
| - [The mpi.h Header](MPI_Header.md) |
There was a problem hiding this comment.
| - [The mpi.h Header](MPI_Header.md) | |
| - [The `mpi.h` Header](MPI_Header.md) |
There was a problem hiding this comment.
Applied, and the page heading now matches.
| #include "mpix.h" | ||
| #include <mpi_proto.h> | ||
| mpicxx.h (C++) |
There was a problem hiding this comment.
Although probably inconsequential, why is mpix.h first here? Comparing to the ABI path, it should be after the standard prototypes. Also, why isn't mpi_proto.h included with quotes as all the other headers?
In short, shouldn't all be the following way?
| #include "mpix.h" | |
| #include <mpi_proto.h> | |
| mpicxx.h (C++) | |
| #include "mpi_proto.h" | |
| #include "mpix.h" | |
| #include "mpicxx.h" if C++ |
Of course, any changes to this doc file should be applied to mpi.h.in.
There was a problem hiding this comment.
The order is intentional: in the MPICH ABI, mpi_proto.h also declares the MPIX functions, whose types (MPIX_Stream, MPIX_Iov, ...) are defined in mpix.h, so mpix.h must come first. I added a note to the doc. Switched mpi_proto.h to quotes in mpi.h.in and the doc, and replaced the mpicxx.h line with a proper include.
| #define MPI_COMBINER_HVECTOR_INTEGER MPI_COMBINER_HVECTOR | ||
| #define MPI_COMBINER_HINDEXED_INTEGER MPI_COMBINER_HINDEXED | ||
| #define MPI_COMBINER_STRUCT_INTEGER MPI_COMBINER_STRUCT |
There was a problem hiding this comment.
@hzhou Please look at this comment from Copilot AI.
mpi-forum/mpi-abi-stubs#103 (comment)
I think the complaint is valid, having duplicate combiner values in a switch statement will lead to compile errors.
There are two options here:
- Do not provide these defines, like done for MPI_LB/UB
- Define them to values that will not overlap with other combiners. Look for example what I'v done in Add header collecting backward compatibility for removed MPI APIs mpi-forum/mpi-abi-stubs#103
#define MPI_COMBINER_HVECTOR_INTEGER (MPI_COMBINER_NAMED-1)
#define MPI_COMBINER_HINDEXED_INTEGER (MPI_COMBINER_NAMED-2)
#define MPI_COMBINER_STRUCT_INTEGER (MPI_COMBINER_NAMED-3)I think this is fine, we know that MPI ABI implementations will NEVER produce datatypes with these combiner values. Any outdated switch statement will keep compiling and the case statements will simply be runtime-uncovered code.
There was a problem hiding this comment.
Agreed. Went with option 2, using the same values as mpi-forum/mpi-abi-stubs#103, so legacy switch cases compile and are simply never taken.
|
@hzhou The MPICH test suite assumes at least MPI 2.0, right? If that is correct, then maybe this PR is a good opportunity to fix some or all of the following: $ git grep MPI_NULL_ test/
test/mpi/attr/attrdelete.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key1, NULL);
test/mpi/attr/attrdelete.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, key2_delete_fn, &key2, NULL);
test/mpi/attr/attrdelete.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key3, NULL);
test/mpi/attr/attrdeleteget.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, delete_fn, &key, &errs);
test/mpi/attr/attrend.c: MPI_Keyval_create(MPI_NULL_COPY_FN, delete_fn, &exit_key, (void *) 0);
test/mpi/attr/attric.c: MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key_3, &value);
test/mpi/attr/attrorder.c: MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key[i], (void *) 0);
test/mpi/attr/attrordercomm.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key[i], (void *) 0);
test/mpi/attr/attrt.c: MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key_3, &value);
test/mpi/attr/fkeyval.c: MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key[i], (void *) 0);
test/mpi/attr/fkeyvalcomm.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key[i], (void *) 0);
test/mpi/attr/keyval_double_free.c: MPI_Keyval_create(MPI_NULL_COPY_FN, delete_fn, &keyval, NULL);
test/mpi/attr/keyval_double_free_comm.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, delete_fn, &keyval, NULL);
test/mpi/f77/attr/attrmpi1f.f: call mpi_keyval_create( MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN,
test/mpi/f77/attr/commattr4f.f: $ MPI_NULL_DELETE_FN,
test/mpi/impls/mpich/threads/threadcomm/threadcomm_attr.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, key_delete_fn, &key, NULL);
test/mpi/init/attrself.c: MPI_Comm_create_keyval(MPI_NULL_COPY_FN, delete_fn, &key[nkeys], (void *) 0); |
I am not sure. I think we are still supporting MPI 1 applications. |
But then some of the tests should fail to compile, For example |
AI help me 🤣 : Where the two of you are talking past each other:
A possible reply: agree that the test suite assumes MPI-2, and fix the mixed cases, i.e. MPI-2 create_keyval calls that pass MPI_NULL_FN. Keep the tests that deliberately exercise the MPI-1 API, such as MPI_Keyval_create in attrt.c, attric.c, attrorder.c, fkeyval.c, attrend.c, keyval_double_free.c and f77/attr/attrmpi1f.f, because they're what tests MPICH's [From me]: I am not insisting of such tests, but I see some plausibility of keep testing old APIs. As I said, I am not sure yet. |
Model: Claude Opus 5.5
mpix.h now defines the MPIX constants for the MPI ABI together under "#ifdef MPI_ABI_VERSION", with values that follow the MPI ABI encoding as if they were standard constants: MPIX_C_FLOAT16 and MPIX_BFLOAT16 in the 2-byte C datatype category, and MPIX_EQUAL in the other-operations category. They go through the regular gen_abi conversions; mpi.h keeps the native values. MPIX constants that are passed through unconverted and don't conflict with either ABI are defined once in mpix.h for both ABIs, moved from mpi.h: the MPIX error classes, which stay at 101-107 since MPICH encodes error classes in 7 bits, and MPIX_COMM_TYPE_NEIGHBORHOOD (5). mpix.h also declares MPIX_Stream_toint, MPIX_Stream_fromint and MPIX_Async_get_state, and gen_abi.py recognizes prototypes returning MPIX types and void *, so they are declared with MPICH_API_PUBLIC in mpi_abi_internal.h. maint/extracterrmsgs reads the MPIX error classes from mpix.h as well. Previously the ABI constants were guarded by "#ifndef MPICH", which has been dead since mpi.h always defines MPICH, and MPIX_STREAM_NULL, MPIX_COMM_TYPE_NEIGHBORHOOD and MPIX_ERR_* were missing in MPI ABI mode. Model: Claude Opus 5.5
Functions removed from the MPI standard are declared only in mpi_legacy.h for the MPI ABI, and in mpi_proto.h for the MPICH native ABI. mpix.h is for MPIX extensions only. Update the mpi_legacy.h header comment to match. Previously mpix.h declared a subset of the removed functions, so an MPI ABI user with only -mpi-mpix got half of the legacy API, and both headers declared them with -mpi-mpix -mpi-legacy. Model: Claude Opus 5.5
In the MPI ABI, MPIX_Stream and MPIX_Grequest_class are now opaque handles like the standard handles. MPIX_STREAM_NULL is in handle category 0b0001_11111 and MPIX_Grequest_class takes 0b0001_11110, without predefined handles: MPIX handle categories are allocated from the back to avoid collisions with new standard handles. libmpi_abi converts them with ABI_Stream_to_mpi/from_mpi and ABI_Grequest_class_to_mpi/from_mpi, and the binding generators treat them as handle types. The native typedefs move to mpi.h, next to MPIX_STREAM_NULL. Fix the stream_multiplex test, whose forward declaration of test_stream_send took an MPIX_Stream instead of the MPI_Comm of its definition. Previously both were ints in both modes, and the MPI ABI used the native MPIX_STREAM_NULL value. Model: Claude Opus 5.5
libmpi_abi now provides all the MPIX functions. The generated ABI wrappers convert their handle arguments like the standard ones; the callbacks that take handles are already converted where the library calls them. MPIX_Waitall_enqueue is added to the request-array conversions. The Fortran configure now identifies the MPI ABI by the library it picked rather than by the absence of MPIX functions, and still keeps MPIX off in the Fortran binding on the MPI ABI. Previously libmpi_abi only had the MPIX functions ROMIO needs (MPIX_Grequest_* and MPIX_Type_iov*), so MPI ABI programs using "mpicc -mpi-mpix" failed to link. Model: Claude Opus 5.5
The Fortran binding now uses the MPIX callbacks (MPIX_Op_create_x, MPIX_*_create_keyval_x, MPIX_*_create_errhandler_x) for its user-function proxies whenever the C library provides them, including libmpi_abi, and independent of --disable-fortran-mpix, which only controls the MPIX routines for Fortran users. MPI_MPIX is defined with them so that mpi.h provides the declarations on the MPI ABI. Previously the callbacks were off on the MPI ABI, so a Fortran user op received an MPI ABI datatype handle instead of a Fortran integer, and the keyval and errhandler proxies had no cleanup. Model: Claude Opus 5.5
Remove usage of: * MPI_Copy_function * MPI_Delete_function * MPI_NULL_COPY_FN
libmpi_abi no longer has wrappers for the functions removed from the MPI standard, such as MPI_Address, MPI_Type_extent and MPI_Attr_get. The MPI ABI does not include them, and a program built against the MPI ABI should not depend on them. This temporarily breaks "mpicc -mpi-legacy" for the MPI ABI: mpi_legacy.h still declares the removed functions, so programs using them, including the removed-API tests in test/mpi, fail to link. The next commit maps them to their replacements in mpi_legacy.h. Previously libmpi_abi exported the removed functions, which made programs that use them run only on MPICH's libmpi_abi. Model: Claude Opus 5.5
The pvfs2 driver checks for the MPI_LB and MPI_UB markers only when mpi.h provides them. They were removed from the MPI standard and the MPI ABI does not have them, so without them no datatype can contain the markers. Previously the driver required MPI_LB and MPI_UB to compile. Model: Claude Opus 5.5
16e9ee1 to
00adf7f
Compare
In the MPI ABI, mpi_legacy.h now maps the APIs removed from the MPI standard to their replacements with macros, and implements MPI_Type_extent/lb/ub as static inline functions, so a program built with "mpicc -mpi-legacy" needs no removed symbol from the library and stays portable across MPI ABI implementations. MPI_LB and MPI_UB are not provided, so using them is a compile-time error: the markers only work if the library interprets them, which a standard libmpi_abi need not do. In the MPICH native ABI the removed APIs, including MPI_LB and MPI_UB, stay real and always available, declared in mpi.h and mpi_proto.h. gen_abi.py no longer reads mpi_legacy.h, which has nothing the libmpi_abi build needs. The header follows the one proposed in pmodels#7948, with the PMPI_Get_address and PMPI_Comm_create_errhandler names fixed. Previously mpi_legacy.h declared the removed functions as prototypes of functions in libmpi_abi, and gave MPI_LB and MPI_UB MPI ABI handle values. Co-authored-by: Lisandro Dalcin <dalcinl@gmail.com> Model: Claude Opus 5.5
configure checks whether mpi.h provides MPI_LB and MPI_UB, which the MPI ABI does not even with -mpi-legacy, and builds and runs lbub_oldapi, typename_oldapi and struct_no_real_types only when it does. Previously these tests failed to compile against the MPI ABI. Model: Claude Opus 5.5
The compiler wrappers now accept -mpix as a shorter form of -mpi-mpix, which makes mpi.h include mpix.h on the MPI ABI. Model: Claude Opus 5.5
MPIR_Err_create_code and the MPIR_Err_return_* functions are no longer exported from libmpi and libmpi_abi. Their only users outside the error handling code are ROMIO and io_abi.c, which are linked into the same library. Also remove the declaration of MPIR_Err_return_file, which is not defined anywhere and was guarded by the never-defined MPI__FILE_DEFINED. Previously these internal functions were exported for the language binding libraries, which no longer use them. Model: Claude Opus 5.5
The C++ binding now creates keyvals with MPIX_*_create_keyval_x, passing the user's C++ copy and delete functions in the extra_state and freeing it in the destructor, as it already does for user ops and errhandlers. The proxies handle NULL_COPY_FN and NULL_DELETE_FN themselves, since MPIX_*_create_keyval_x requires non-null callbacks. MPII_Keyval_set_proxy has no other user and is removed, so libmpi no longer exports it. Previously the C++ binding installed its proxies with the internal MPII_Keyval_set_proxy, which libmpi had to export. Model: Claude Opus 5.5
mpicxx links libmpicxx when the C++ binding is built, and only for the MPICH ABI, since the C++ binding does not exist for the MPI ABI (mpicxx_abi, mpicxx -mpi-abi). Previously configure tested the literal string "enable_cxx" instead of $enable_cxx, so LMPICXXLIBNAME was always empty and C++ programs using the C++ binding failed to link. Model: Claude Opus 5.5
The MPI ABI version of get_file_errhand now returns the result of MPIR_ROMIO_Get_file_errhand, and initializes the errhandler so that it is not read uninitialized when the call fails. Previously the function had no return statement (-Wreturn-type in the MPI ABI build). Model: Claude Opus 5.5
ABI_Comm_rank and ABI_Comm_peer_size, which the MPI ABI wrappers use to size the per-peer arrays of collectives such as MPI_Alltoallw, now count threads on a threadcomm, as MPI_Comm_rank and MPI_Comm_size do. Previously they returned the process rank and size, so MPI_Alltoallw on a threadcomm converted too few datatypes and failed with "Invalid datatype". Model: Claude Opus 5.5
When testing MPICH's MPI ABI, configure checks that the MPIX functions link with -mpi-mpix, then adds the flag and enables the impls/mpich tests, which exercise the MPIX extensions. Previously impls/mpich was enabled only for the MPICH ABI, since libmpi_abi did not provide the MPIX functions. Model: Claude Opus 5.5
Include mpi_proto.h with quotes, like the other MPICH headers mpi.h includes. Previously it used angle brackets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a design page describing the three modes in which mpi.h is consumed: the MPI ABI header, the MPICH ABI header, and the header for building libmpi_abi, how mpi.h.in is laid out for them, what the generated mpi_abi_internal.h provides in the library build, and the rules for editing mpi.h.in and mpix.h. Describe how -mpi-legacy maps the removed APIs to their replacements on the MPI ABI and that MPI_LB and MPI_UB are not available there, and add a CHANGES entry. Mention the -mpix alias of -mpi-mpix. Update the stand-alone Fortran binding page for the MPIX callbacks now being independent of --disable-fortran-mpix. Model: Claude Opus 5.5
00adf7f to
e0a0bde
Compare
|
LGTM. Now abidiff is happy. The following check could be easily incorporated in CI. $ cat mpiabi.suppr
[suppress_function]
change_kind = added-function
name_regexp = ^(P?MPIX|QMPI)_.*
$ abidiff --suppr=mpiabi.suppr ~/Devel/mpi-abi-stubs/lib/libmpi_abi.so /home/devel/mpi/mpich/dev/lib/libmpi_abi.so
Functions changes summary: 0 Removed, 0 Changed, 0 Added (75 filtered out) functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
$ echo $? # to confirm abidiff succeeds if there is no diff after filtering out MPIX/QMPI functions
0 |
Pull Request Description
In the MPI ABI build, the headers next to
mpi.hdid not fit together:mpix.handmpi_legacy.hboth declared removed MPI functions, several MPIX constants were missing or used values outside the MPI ABI encoding, andlibmpi_abihad almost none of the MPIX functions, sompicc -mpi-mpixprograms failed to link.libmpi_abialso exported some removed MPI functions and internalMPIR_/MPII_symbols (#7938).This PR:
mpix.his MPIX only, with an explicit#ifdef MPI_ABI_VERSIONbranch. MPIX constants follow the MPI ABI encoding as if they were standard,MPIX_StreamandMPIX_Grequest_classbecome MPI ABI handles, andlibmpi_abiprovides all MPIX functions. The Fortran binding uses the MPIX callbacks on both ABIs.mpi_legacy.hmaps them to their replacements (the approach from binding/abi: update upstream mpi_abi.h #7948) andlibmpi_abiexports none of them;MPI_LB/MPI_UBare not available there.MPIR_Err_*andMPII_Keyval_set_proxyare no longer exported; the C++ binding now uses the MPIX keyval callbacks.Additional changes:
MPI_LB/MPI_UB.MPI_LB/MPI_UBtests whenmpi.hlacks them.mpicc -mpixas an alias of-mpi-mpix.doc/wiki/design/MPI_Header.mdon the three waysmpi.his used; docs and CHANGES updated.mpicxxnow linkslibmpicxx(configure tested the stringenable_cxx), the MPI ABIget_file_errhand()returns its result, and the MPI ABI collective wrappers size per-peer arrays by threads on a threadcomm.impls/mpich(MPIX) tests on MPICH's MPI ABI, with-mpi-mpix.Addresses #7938. Supersedes #7948.
plan.md
MPI ABI header cleanup: mpix.h, mpi_legacy.h, mpi_fortran.h
Plan and notes for this PR, with local testing results.
Header layout (on the branch)
-DMPI_ABI)mpix.hMPI_MPIXforced)mpicc -mpi-mpixmpi_legacy.hmpi.h/mpi_proto.hmpicc -mpi-legacy: macros + static inlinempi_fortran.hmpicc -mpi-fortranmpicc -mpi-fortranmpi.h: MPI ABI header, MPICH ABI header, libmpi_abi build(
MPICH_BUILD_MPI_ABI); documented indoc/wiki/design/MPI_Header.md.libmpi_abiwrappers convert handle types; everything else passes through. The library iscompiled with the ABI integer constants (
mpi_abi_internal.h, generated bygen_abi.pyfrommpi_abi.handmpix.h) and native handles. Callbacks taking handles are converted at theircall sites (
reduce_local.c,errutil.c,attrutil.c).Decisions
mpix.his MPIX only; removed APIs are only inmpi_legacy.h(MPI ABI) /mpi_proto.h(native).MPICHidentifies MPICH headers in every mode;MPI_ABI_VERSIONidentifies the MPI ABI.No
MPICH_NATIVE_ABIfor now.mpix.h: explicit#ifdef MPI_ABI_VERSION/#else. The ABI branch defines the MPIX constantsthat differ between ABIs (converted handles); the native branch is a comment (values in
mpi.h). Pass-through constants with no conflict are defined once in the common section.regular conversions.
MPIX_C_FLOAT16/MPIX_BFLOAT160x24a/0x24b (2-byte C),MPIX_EQUAL0x3e.MPIX handle categories are allocated from the back:
MPIX_Stream11111 (MPIX_STREAM_NULL0x1f8),
MPIX_Grequest_class11110 (no null constant; generator initializes outputs with 0).MPIX_ERR_*101-107 (MPICH encodes error classes in 7 bits, so not above 16384 as MPI 5.0asks);
MPIX_COMM_TYPE_NEIGHBORHOOD5 in both ABIs (no clash with 1-4 native, 221-224 ABI).libmpi_abiprovides all MPIX functions. The Fortran binding uses the MPIX callbacks on bothABIs (
HAS_MPIX_CALLBACKS, independent of--disable-fortran-mpix); Fortran MPIX routines onthe MPI ABI are a follow-up.
mpi_legacy.hmaps them to replacements (from binding/abi: update upstream mpi_abi.h #7948) andlibmpi_abiexports none of them.MPI_LB/MPI_UBare not provided in the MPI ABI (compile-time error).Commits
See the commit list of the PR.
#7938 internal exports (done in the errhan and binding/cxx commits; checked with nm): the
MPICH_API_PUBLICmarkers on
MPIR_Err_*andMPII_Keyval_set_proxydate from 29fb99d (2016, for the bindinglibraries); their users are now inside the same library (ROMIO, io_abi.c) or moved to MPIX callbacks
(C++).
MPIR_fortran_{true,false}were already hidden (27d6d79). Intentionally exported:MPID_Recvq_*_head_ptr(debugger),MPIR_F08_MPI_STATUS(ES)_IGNORE_OBJ(libmpifort, bound fromthe f08 module),
QMPI_*,MPIR_Call_world_errhand/MPIR_CXX_InitDatatypeNames(libmpicxx,referenced from mpicxx.h). The C++ attr proxies in libmpicxx are
static.Open
sit in ranges the standard reserves. Ask the Forum for an implementation range?
mpi.hdoes not defineMPI_Fintby default — is this intended and what should packages do? #7973MPI_Fint: packages can't detect the need for-mpi-fortran(feature macro? CMakeFindMPIguidance).mpix.handmpi_proto.hboth declare them; compatible,but two lists to keep in sync (they match now).
Follow-ups (probably outside this PR)
MPIX_Stream/MPIX_Grequest_class(pointers in the ABI;
binding_f08.pydefaults toc_int),*_attr_as_fortranpaths.-mpi-legacyis targeted).allctypesf.f/allctypesf08.f90useMPI_LB, which the Fortran binding never had onthe MPI ABI (pre-existing).
-mpi-mpix,-mpi-legacy,-mpi-fortran(wiki and CHANGES done).Testing plan
Done so far (generator only, no build): c_binding_abi.c checked before/after each generator
change — unchanged except the intended wrappers (MPIX_Stream handle and removed-function commits); mpi_abi_internal.h
diffs checked for the MPIX constants and mpi_legacy.h commits.
Modes
-mpi-mpix(mpicc_abi) — no MPIX symbol visible.-mpi-mpix(mpicc_abi -mpi-mpix).mpicc; also the libmpi build).-DMPICH_BUILD_MPI_ABI;mpi_abi_internal.h+ native mpi.h).MPIX coverage table (expected; verify against it)
MPIX_Streamstruct MPIX_ABI_Stream *(mpix.h ABI branch)int(mpi.h.in)int;ABI_Streamfor wrappersMPIX_STREAM_NULLABI_STREAM_NULL0x1f8MPIX_C_FLOAT16,MPIX_BFLOAT16ABI_*in datatype tableMPIX_EQUALABI_EQUALin op tableMPIX_Grequest_classstruct MPIX_ABI_Grequest_class *(category 11110)int(mpi.h.in)int;ABI_Grequest_classfor wrappersMPIX_Async_thingMPIX_IovMPIX_User_function_x,MPIX_{Comm,Win,File,Session}_errhandler_function_xABI_types; handles converted at call sitesMPIX_Destructor_function,MPIX_Grequest_{poll,wait}_function,MPIX_Async_poll_functionMPIX_ERR_*(101-107),MPICH_ERR_FIRST/LAST_MPIX(100/107)MPIX_COMM_TYPE_NEIGHBORHOODMPIX_GPU_SUPPORT_*(0-2),MPIX_ASYNC_*(0-1)ABI_types +MPICH_API_PUBLICMPIX_Stream_c2f/f2c-mpi-fortran)-mpi-legacy: macros/inline, no MPI_LB/UB (compile error)Libraries: libmpi exports all MPIX_/PMPIX_ (incl.
_c); libmpi_abi the same except thec2f/f2c functions (Fortran binding). Fortran: MPIX routines on the MPICH ABI only (unless
--disable-fortran-mpix);HAS_MPIX_CALLBACKSon both ABIs.T0 Builds (end-to-end matrix)
--enable-mpi-abi=no(default)--enable-mpi-abi=yes--enable-mpi-abi=dualsrc/binding/fortranagainst the MPI ABI install, and with--disable-fortran-mpixEach build with
--enable-strict; check no macro redefinition warnings frommpi_abi_internal.h.T1 Header symbol exposure (per mode, C and C++)
Generate a probe from the coverage table:
#ifndef X / #errorfor each macro,_Static_asserton each value,sizeof/_Genericon each type,(void)&MPIX_fnfor eachprototype (all 66+ MPIX and PMPIX). Compile in 1a (expect every MPIX symbol absent), 1b, 2 with
mpicc/mpicc_abi/mpicxx. Mode 3: compile the probe with the library's CPPFLAGS(
-DMPICH_BUILD_MPI_ABI) and inspectmpi_abi_internal.h.T2 Binary symbol check (nm)
nm -D --defined-onlyon libmpi.so and libmpi_abi.so: diff the MPIX_/PMPIX_ set against thegenerator's function list (incl.
_cvariants; c2f/f2c excluded for libmpi_abi).libmpifort on the MPI ABI:
nm -ushowsMPIX_Op_create_x,MPIX_Comm_create_keyval_x,MPIX_Comm_create_errhandler_x(HAS_MPIX_CALLBACKS); noMPIX_Fortran routines exported.No removed-API symbol in libmpi_abi.so (MPI_Address, MPI_Type_extent, MPI_Attr_, MPI_Keyval_,
MPI_Errhandler_{create,get,set}, MPI_Type_{hindexed,hvector,struct,lb,ub}); libmpi.so still has them.
No
MPIR_/MPII_symbol exported from libmpi.so or libmpi_abi.so.T3 Spot-check APIs (run on libmpi and libmpi_abi; dual build covers both)
Existing tests:
impls/mpich/comm/stream.c,stream_comm.c,stream_multiplex.c(MPIX_Stream arrays);
impls/mpich/misc/type_float16.c(MPIX_C_FLOAT16);comm/cmsplit_type.c(NEIGHBORHOOD);ft/revoke_nofail.c(ULFM, MPIX_ERR_*);impls/mpich/misc/gpu_query.c. Fortran user op/attr on the ABI:f77/coll/uallreducef.f,reducelocalf.f,f77/attr/commattrf.f.New small tests (no existing coverage):
MPIX_Op_create_x(callback datatype equals thecaller's
MPI_INT),MPIX_Comm_create_errhandler_x(callback comm equals the caller's comm),MPIX_Comm_create_keyval_x(copy/delete/destructor called),MPIX_Async_start,MPIX_Grequest_class_create,MPIX_Info_set_hex,MPIX_Stream_toint(MPIX_STREAM_NULL).C++ keyvals via MPIX keyval_x (MPICH ABI):
cxx/attr/attrtx,fkeyvalcommx,cxx/rma/fkeyvalwinx,incl. NULL_COPY_FN/DUP_FN and Free_keyval.
Removed APIs on the MPI ABI (
mpicc_abi -mpi-legacy): the attr/, errhan/commcall_oldapi,datatype/oldapi and errors/datatype/type_nullarg tests build and pass via the macro mapping;
MPI_LBin a test program fails to compile; lbub_oldapi, typename_oldapi, struct_no_real_typesare skipped (configure reports
MPI_LB and MPI_UB... no).T4 CI
test:mpich/customwithconfig: mpi-abi,test:mpich/ch4/ofi,test:mpich/ch3/tcp.Testing results
Builds (autogen + configure,
--enable-strict, dataloop): ch3 MPICH ABI (Fortran, C++), ch3 MPI ABI(in-tree Fortran), ch3 dual (
--disable-fortran), ch4:ofi dual; stand-alone Fortran against thedual install (
--enable-mpi-abi) and against the MPICH install (--disable-fortran-mpix).No new warnings (pre-existing: type_create* maybe-uninitialized; ABI-only errhan_file.c, type_debug.c).
Found and fixed (folded into their commits, pushed):
maint/extracterrmsgsread MPICH_ERR_LAST_MPIX from mpi.h.in -> autogen failed; now reads mpix.h too(generated error table identical to main).
MPIX_Async_get_state(returnsvoid *) was missing from mpix.h, its ABI wrapper returnedvoid(compile error), and gen_abi didn't mark
void *prototypes public.MPIX_*_create_keyval_xrejects NULL callbacks, so NULL_COPY_FN/NULL_DELETE_FN broke;the proxies now handle them.
test/mpi/impls/mpich/comm/stream_multiplex.c: forward declaration of test_stream_send had thewrong parameter type (MPIX_Stream vs MPI_Comm), exposed by MPIX_Stream being a pointer in the ABI.
Results:
-mpi-mpix,-mpix,-mpi-legacy,mpicc_abi,mpicc -mpi-abi); MPI_LB is a compile error on the MPI ABI only; C++ compiles in all.no MPIR_/MPII_; libmpi.so: 30 removed-API symbols, MPIR_Dup_fn only (MPI_DUP_FN); libmpicxx and
libmpifort (both ABIs) use the MPIX
_xcallbacks.test suite: attr/*, _oldapi, errhan/commcall_oldapi, errors/datatype/_nullarg, cmsplit_type,
f77 user op/attr tests pass on both ABIs; MPI_LB tests skipped on the MPI ABI by the new gate;
cxx/attr + cxx/rma keyval tests pass; impls/mpich stream, stream_comm, stream_multiplex,
type_float16, gpu_query pass on libmpi_abi with
-mpix; f77 tests built on one libmpi_abi run onthe stand-alone libmpifort + the dual build's libmpi_abi.
dies (SIGBUS/kill) on both ABIs in this container, so streams ran with 1-2 reserved VCIs.
Pre-existing issues found on main, fixed in this PR (commits after the C++ keyval commit):
added only on the MPICH ABI (mpicxx_abi / mpicxx -mpi-abi link only -lmpi_abi). Verified: link
lines, test-suite C++ probe "yes", cxx/attr, cxx/rma, cxx/coll tests pass.
binding/abi: ABI_Comm_rank/ABI_Comm_peer_size ignored threadcomms, so MPI_Alltoallw on a
threadcomm failed ("Invalid datatype"); fixed. impls on the MPI ABI: ch3 20/20, ch4 28/29; the one
failure, comm_info_hint, fails the same way on the MPICH ABI (pre-existing, not addressed).
Author Checklist
Model: Claude Opus 5.5