Skip to content

Emit MPI Standard ABI handles in MPI_T event payloads - #14306

Open
hppritcha wants to merge 3 commits into
open-mpi:mainfrom
hppritcha:mpi_t_events_abi_patch
Open

Emit MPI Standard ABI handles in MPI_T event payloads#14306
hppritcha wants to merge 3 commits into
open-mpi:mainfrom
hppritcha:mpi_t_events_abi_patch

Conversation

@hppritcha

Copy link
Copy Markdown
Member

Open MPI's MPI_T event producers publish MPI object handles (communicator, window, session, error handler, file) in their event payloads. Those values were always the internal object pointer, which is correct only for a tool built against the Open MPI ABI. A tool built against the MPI Standard ABI expects the integer handle instead, so every producer raise site had a placeholder that set the Standard-ABI handle to 0 pending this work.

Record the process ABI at initialization and convert handles at each raise site accordingly. The Standard-ABI variants of MPI_Init, MPI_Init_thread, and MPI_Session_init set the process-global flag ompi_mpit_callback_abi to OMPI_MPIT_ABI_STANDARD (the Open MPI ABI keeps the default). Keying off process init, rather than callback registration, also covers the world-model initialization event, which is raised during MPI_Init before any tool can register a callback.

The intern-to-ABI converters are generated only into libmpi_abi, a higher layer than the producer raise sites in libopen_mpi, so a raise site cannot call them directly without violating the one-way OPAL/OMPI linker boundary. Resolve this with the same downward callback-registration pattern the tree already uses for ompi_mpiext_init: the Standard-ABI init path installs a converter function pointer into libopen_mpi via ompi_mpit_register_abi_handle_convert(), and the raise sites reach it through ompi_mpit_abi_handle(). The converter itself lives in the new libmpi_abi-only translation unit mpit_abi_handle_convert.c and dispatches on the object's MPI_T_BIND_* kind to the appropriate generated reverse converter. When no converter is registered (the Open MPI ABI never installs one), ompi_mpit_abi_handle() returns 0, matching the previous placeholder rather than emitting a wrong pointer value.

Rewrite all handle-emitting raise sites (communicator create/free/ name-set, window create/free, instance init/finalize, and error-handler invocation, including both the error-handler handle and the invoking object converted per its binding kind) to use the new helper in the Standard-ABI branch. Make the Standard-ABI copy of MPI_T_event_register_callback re-assert the flag as well, and drop its stale comment claiming the feature was unimplemented.

Add an MPI Standard ABI test probe (callback_mpit_event_handle) to the mpi-abi harness: under a libmpi_abi-linked process it drives the communicator-created event and asserts the payload carries the Standard-ABI integer handle of the new communicator, exercising the downward converter registration and the raise-site conversion end to end.

Update the MPI_T events specification to describe the registered converter and the init-time flag, and add a v6.1.x changelog entry.

Open MPI's MPI_T event producers publish MPI object handles
(communicator, window, session, error handler, file) in their event
payloads. Those values were always the internal object pointer, which is
correct only for a tool built against the Open MPI ABI. A tool built
against the MPI Standard ABI expects the integer handle instead, so every
producer raise site had a placeholder that set the Standard-ABI handle to
0 pending this work.

Record the process ABI at initialization and convert handles at each
raise site accordingly. The Standard-ABI variants of MPI_Init,
MPI_Init_thread, and MPI_Session_init set the process-global flag
ompi_mpit_callback_abi to OMPI_MPIT_ABI_STANDARD (the Open MPI ABI keeps
the default). Keying off process init, rather than callback registration,
also covers the world-model initialization event, which is raised during
MPI_Init before any tool can register a callback.

The intern-to-ABI converters are generated only into libmpi_abi, a higher
layer than the producer raise sites in libopen_mpi, so a raise site
cannot call them directly without violating the one-way OPAL/OMPI linker
boundary. Resolve this with the same downward callback-registration
pattern the tree already uses for ompi_mpiext_init: the Standard-ABI init
path installs a converter function pointer into libopen_mpi via
ompi_mpit_register_abi_handle_convert(), and the raise sites reach it
through ompi_mpit_abi_handle(). The converter itself lives in the new
libmpi_abi-only translation unit mpit_abi_handle_convert.c and dispatches
on the object's MPI_T_BIND_* kind to the appropriate generated reverse
converter. When no converter is registered (the Open MPI ABI never
installs one), ompi_mpit_abi_handle() returns 0, matching the previous
placeholder rather than emitting a wrong pointer value.

Rewrite all handle-emitting raise sites (communicator create/free/
name-set, window create/free, instance init/finalize, and error-handler
invocation, including both the error-handler handle and the invoking
object converted per its binding kind) to use the new helper in the
Standard-ABI branch. Make the Standard-ABI copy of
MPI_T_event_register_callback re-assert the flag as well, and drop its
stale comment claiming the feature was unimplemented.

Add an MPI Standard ABI test probe (callback_mpit_event_handle) to the
mpi-abi harness: under a libmpi_abi-linked process it drives the
communicator-created event and asserts the payload carries the
Standard-ABI integer handle of the new communicator, exercising the
downward converter registration and the raise-site conversion end to end.

Update the MPI_T events specification to describe the registered converter
and the init-time flag, and add a v6.1.x changelog entry.

Signed-off-by: Howard Pritchard <howardp@lanl.gov>
@hppritcha

Copy link
Copy Markdown
Member Author

this can't be backported till #14307 is merged in to 6.0.x

Comment thread docs/release-notes/changelog/v6.1.x.rst Outdated

@jsquyres jsquyres left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review Summary

Verdict: REQUEST_CHANGES

Findings (4 validated from 12 raw)

  • Agreed (cross-source): 0
  • codex-reviewer: 1
  • v3-reviewer: 3
  • Description accuracy: 0

Filter Pipeline

  • Dropped (no quote): 0
  • Dropped (hallucination): 0 (path: 0, quote: 0, deleted: 0)
  • Suppressed (dedup): 0
  • Dropped (below cutoff): 8

codex-reviewer

[Edge cases and error handling | MEDIUM] ompi/mpi/c/session_init.c.in:74see inline comment

v3-reviewer

[Bugs and logic errors | HIGH] ompi/errhandler/errhandler_invoke.c:87see inline comment

[Cross-file consistency | MEDIUM] ompi/communicator/comm.c:2366see inline comment

[Edge cases and error handling | MEDIUM] ompi/mpi/tool/event_register_callback.c.in:47see inline comment

Comment thread ompi/mpi/c/session_init.c.in Outdated
* converter downward into libopen_mpi (the converter lives here in
* libmpi_abi; see mpit_abi_handle_convert.c), mirroring the mpiext_init
* registration above. */
ompi_mpit_callback_abi = OMPI_MPIT_ABI_STANDARD;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Converter installation occurs after the earlier parameter-validation branches that jump to fn_exit. A Standard-ABI tool may legally initialize MPI_T and register the errhandler-invoked callback before initializing MPI. If a subsequent MPI_Session_init fails those early checks, fn_exit invokes the error handler while event_register_callback has already selected OMPI_MPIT_ABI_STANDARD but no converter has been installed; ompi_mpit_abi_handle() consequently publishes 0 for handles such as the predefined error handler. Install the converter when the Standard-ABI MPI_T interface is initialized or when its callback is registered, or move this installation ahead of all Session_init error exits.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

should be addressed by commit b26d9a1

handler routed before MPI_INIT) has object_bind == NO_OBJECT and
a 0 object_handle, matching the Open MPI ABI's "0 when not
available" behavior. */
payload.errhandler_handle

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The Standard-ABI branch converts the two handle elements of the errhandler_invoked payload but leaves the other two elements — payload.err_code = (int32_t) err_code; and payload.object_type = object_bind; (lines 72-73, set unconditionally before the branch) — in Open MPI internal representation. Both differ from the MPI Standard ABI's mandated values. Verified against docs/mpi-standard-5.0-abi.json: the Standard ABI's MPI_T_BIND_* values are exactly internal+1 (MPI_T_BIND_NO_OBJECT=1, MPI_T_BIND_MPI_COMM=2, ..., MPI_T_BIND_MPI_SESSION=12, vs. the internal enum in ompi/include/mpi.h.in which starts at 0), so a Standard-ABI tool reading object_type misclassifies every event — e.g. an errhandler invoked on a communicator publishes 1, which the tool's mpi.h defines as MPI_T_BIND_NO_OBJECT. Likewise 20 of 64 MPI_ERR_* codes have different values in the Standard ABI (e.g. internal MPI_ERR_PENDING=19 is the Standard ABI's MPI_ERR_IN_STATUS, and vice versa), so err_code is also misread for a third of the error space. The generated converters for both already exist (ompi_convert_t_bind_ompi_to_standard, ompi_convert_intern_error_abi_error in ompi_bindings/consts.py); the fix is to extend the downward-registered converter interface (or register companion value-converter callbacks) so the Standard-ABI branch converts err_code and object_type too, moving those two assignments into the per-ABI branches.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

should be addressed by commit b26d9a1

Comment thread ompi/communicator/comm.c
/* TODO ABI (#13280): set the MPI Standard ABI handle value. */
payload.handle = 0;
/* MPI Standard ABI: publish the integer MPI_Comm handle. */
payload.handle = ompi_mpit_abi_handle(comm, MPI_T_BIND_MPI_COMM);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The communicator_name_set event is object-bound: a tool can only receive this (now correctly converted) payload after binding a registration to a specific communicator via MPI_T_event_handle_alloc's obj_handle. That binding-side conversion is still missing: ompi/mpi/tool/event_handle_alloc.c.in passes obj_handle straight to mca_base_event_handle_alloc with no Standard-ABI-to-internal conversion (and the spec's sec. 6.1 bullet retained in this diff still says "The Standard ABI must convert"). Under the Standard ABI, binding works for user-created communicators only by accident (their ABI handle happens to equal the internal pointer) and silently never matches for predefined handles such as MPI_COMM_WORLD, whose Standard-ABI handle is a small reserved integer. If the binding side is deliberately deferred to a follow-up, the spec's sec. 10 test-coverage claim of "end to end" Standard-ABI coverage overstates what is exercised; either close the gap or note it explicitly as remaining work in specs/mpi-t-events/spec.md.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

should be addressed by commit b26d9a1

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sorry this event_handle_alloc.c.in changes will be deferred to a separate PR. Comment about deferring solution concerning event_register_callback.c.in is incorrect.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

addressed by PR #14358

Standard-ABI tool registering after an intervening reinit is still seen
correctly; this is idempotent with the init-time set. */
#if OMPI_ABI_SRC
ompi_mpit_callback_abi = OMPI_MPIT_ABI_STANDARD;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A Standard-ABI tool may legally call MPI_T_init_thread + MPI_T_event_register_callback before MPI_Init (MPI_T is init-independent, and the producers are registered from the MPI_T_init_thread path). In that window this re-assert correctly sets ompi_mpit_callback_abi = OMPI_MPIT_ABI_STANDARD, but the handle converter is only installed by the init entry points (init.c.in / init_thread.c.in / session_init.c.in), so any event raised before MPI init — notably ompi.mpi.errhandler_invoked for errors routed to a predefined handler pre-init, a case the code's own comments call out — publishes handle 0 via the ompi_mpit_abi_handle() NULL-converter fallback, even though the predefined errhandler has a well-defined Standard-ABI handle. Since this Standard-ABI copy of the template is compiled into the same library (libmpi_abi) as ompi_mpit_abi_handle_convert_impl, the converter could also be installed here (or in the Standard-ABI copy of MPI_T_init_thread) under the same #if OMPI_ABI_SRC guard, closing the window with two lines.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

deferring solution to this problem till a later PR. We'll solve this by adding more types and a new convertor to the bindings framework

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this should have been address by commit b26d9a1

Signed-off-by: Howard Pritchard <howardp@lanl.gov>
…it gaps

The initial Standard-ABI MPI_T event work converted object handles in
event payloads but left several gaps that a Standard-ABI MPI_T tool would
observe as wrong values or missed deliveries. Address the review feedback
on that work.

Install converters before Session_init error exits. In the Standard-ABI
copy of MPI_Session_init the process-ABI flag and the handle converter
were installed after the MPI_PARAM_CHECK branches that jump to fn_exit.
A failing check routes through OMPI_ERRHANDLER_RETURN on MPI_SESSION_NULL,
which can invoke an error handler and raise ompi.mpi.errhandler_invoked
before any converter is installed, publishing 0 for handles such as the
predefined error handler. Move the whole registration block to the top
of the function, ahead of all early error exits.

Install converters in the Standard-ABI event_register_callback. MPI_T is
init-independent: a tool may call MPI_T_init_thread and
MPI_T_event_register_callback before MPI_Init, and events can be raised
in that window. The re-assert of the process-ABI flag was already here,
but the converters were installed only by the init entry points, so
pre-init events fell back to the NULL-converter (handle 0). Install the
converters here too, under the same OMPI_ABI_SRC guard; this Standard-ABI
copy is compiled into libmpi_abi alongside the converter implementations,
and the registration is idempotent with the init-time set.

Convert the err_code and object_type payload fields, not just handles.
The errhandler_invoked payload also carries an MPI error code and an
MPI_T_BIND_* object-binding kind, whose numeric encodings differ between
the Open MPI ABI and the MPI Standard ABI (roughly a third of the
MPI_ERR_* space differs, and the Standard-ABI MPI_T_BIND_* values are the
internal values + 1). These were left in internal representation, so a
Standard-ABI tool misread them. The generated value converters live in
libmpi_abi (the upper layer), so plumb them downward the same way as the
handle converter: add ompi_mpit_register_abi_error_convert() /
ompi_mpit_register_abi_bind_convert() function-pointer slots in
libopen_mpi and ompi_mpit_abi_error() / ompi_mpit_abi_bind() forwarders
(which return the value unchanged when unregistered, correct for the Open
MPI ABI). The implementations wrap the generated
ompi_convert_intern_error_abi_error() and
ompi_convert_t_bind_ompi_to_standard(). All Standard-ABI init entry
points and the event_register_callback copy install them, and the
errhandler_invoke raise site converts both fields.

Document the remaining binding-side gap. Object-bound delivery still
lacks a Standard-ABI-to-internal conversion of the tool's obj_handle in
event_handle_alloc.c.in, so predefined handles such as MPI_COMM_WORLD
never match under the Standard ABI. Record this as deferred work in the
MPI_T events spec and qualify the "end to end" test-coverage claim
accordingly.

Signed-off-by: Howard Pritchard <howardp@lanl.gov>
@hppritcha

Copy link
Copy Markdown
Member Author

@jsquyres pushed some changes please rereview.

@hppritcha
hppritcha requested a review from jsquyres August 18, 2026 18:46
@hppritcha

Copy link
Copy Markdown
Member Author

@jsquyres ping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants