Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions ompi/communicator/comm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2362,8 +2362,8 @@ int ompi_comm_set_name (ompi_communicator_t *comm, const char *name )
if (OMPI_MPIT_ABI_OMPI == ompi_mpit_callback_abi) {
payload.handle = (uint64_t) (uintptr_t) comm;
} else {
/* 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

}
mca_base_event_raise_bound(ompi_event_comm_name_set, NULL, comm, &payload);
}
Expand Down Expand Up @@ -2528,9 +2528,8 @@ int ompi_comm_free( ompi_communicator_t **comm )
if (OMPI_MPIT_ABI_OMPI == ompi_mpit_callback_abi) {
payload.handle = (uint64_t) (uintptr_t) *comm;
} else {
/* TODO ABI (#13280): set the MPI Standard ABI handle value for the
communicator *comm. */
payload.handle = 0;
/* MPI Standard ABI: publish the integer MPI_Comm handle. */
payload.handle = ompi_mpit_abi_handle(*comm, MPI_T_BIND_MPI_COMM);
}
mca_base_event_raise(ompi_event_comm_freed, NULL, &payload);
}
Expand Down
5 changes: 2 additions & 3 deletions ompi/communicator/comm_cid.c
Original file line number Diff line number Diff line change
Expand Up @@ -948,9 +948,8 @@ static int ompi_comm_activate_complete (ompi_comm_cid_context_t *context)
if (OMPI_MPIT_ABI_OMPI == ompi_mpit_callback_abi) {
payload.handle = (uint64_t) (uintptr_t) *newcomm;
} else {
/* TODO ABI (#13280): set the MPI Standard ABI handle value for the
communicator *newcomm. */
payload.handle = 0;
/* MPI Standard ABI: publish the integer MPI_Comm handle. */
payload.handle = ompi_mpit_abi_handle(*newcomm, MPI_T_BIND_MPI_COMM);
}
mca_base_event_raise(ompi_event_comm_created, NULL, &payload);
}
Expand Down
28 changes: 21 additions & 7 deletions ompi/errhandler/errhandler_invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,31 @@ int ompi_errhandler_invoke(ompi_errhandler_t *errhandler, void *mpi_object,
}
payload.err_code = (int32_t) err_code;
payload.object_type = object_bind;
/* XXX ABI: the MPI_Errhandler handle and the invoking object's handle
must match the registering MPI_T tool's ABI (ompi_mpit_callback_abi). */
/* The MPI_Errhandler handle and the invoking object's handle must match
the registering MPI_T tool's ABI (ompi_mpit_callback_abi). So must
the err_code and object_type integer values, whose encodings differ
between the two ABIs. */
if (OMPI_MPIT_ABI_OMPI == ompi_mpit_callback_abi) {
payload.errhandler_handle = (uint64_t) (uintptr_t) errhandler;
payload.object_handle = (uint64_t) (uintptr_t) mpi_object;
} else {
/* TODO ABI (#13280): set the MPI Standard ABI handle values -- the
MPI_Errhandler, and mpi_object converted per object_type
(MPI_Comm / MPI_Win / MPI_File / MPI_Session). */
payload.errhandler_handle = 0;
payload.object_handle = 0;
/* MPI Standard ABI: publish integer handles and Standard-ABI
integer values. The errhandler is converted as an
MPI_Errhandler; the invoking object is converted per its binding
kind (MPI_Comm / MPI_Win / MPI_File / MPI_Session). An object
with no binding (e.g. a predefined 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. The
err_code and object_type integer values are remapped to their
Standard-ABI encodings. */
payload.err_code = ompi_mpit_abi_error((int32_t) err_code);
payload.object_type = ompi_mpit_abi_bind(object_bind);
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

= ompi_mpit_abi_handle(errhandler, MPI_T_BIND_MPI_ERRHANDLER);
payload.object_handle
= (MPI_T_BIND_NO_OBJECT == object_bind)
? 0
: ompi_mpit_abi_handle(mpi_object, object_bind);
}
mca_base_event_raise(ompi_event_errhandler_invoked, NULL, &payload);
}
Expand Down
12 changes: 6 additions & 6 deletions ompi/instance/instance.c
Original file line number Diff line number Diff line change
Expand Up @@ -1132,9 +1132,9 @@ int ompi_mpi_instance_init (int ts_level, opal_info_t *info, ompi_errhandler_t
if (OMPI_MPIT_ABI_OMPI == ompi_mpit_callback_abi) {
payload.instance_id = (uint64_t) (uintptr_t) new_instance;
} else {
/* TODO ABI (#13280): set the MPI Standard ABI handle value for the
session new_instance. */
payload.instance_id = 0;
/* MPI Standard ABI: publish the integer MPI_Session handle. */
payload.instance_id = ompi_mpit_abi_handle(new_instance,
MPI_T_BIND_MPI_SESSION);
}
mca_base_event_raise(ompi_event_initialization, NULL, &payload);
}
Expand Down Expand Up @@ -1269,9 +1269,9 @@ int ompi_mpi_instance_finalize (ompi_instance_t **instance)
if (OMPI_MPIT_ABI_OMPI == ompi_mpit_callback_abi) {
payload.instance_id = (uint64_t) (uintptr_t) *instance;
} else {
/* TODO ABI (#13280): set the MPI Standard ABI handle value for the
session *instance. */
payload.instance_id = 0;
/* MPI Standard ABI: publish the integer MPI_Session handle. */
payload.instance_id = ompi_mpit_abi_handle(*instance,
MPI_T_BIND_MPI_SESSION);
}
mca_base_event_raise(ompi_event_finalization, NULL, &payload);
}
Expand Down
2 changes: 2 additions & 0 deletions ompi/mpi/c/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ EXTRA_DIST = $(prototype_sources) \
abi_converters.h \
abi_converters.c \
abi_handle_convert.h \
mpit_abi_handle_convert.h \
mpit_abi_handle_convert.c \
abi_get_info.c.in \
abi.h.in

Expand Down
1 change: 1 addition & 0 deletions ompi/mpi/c/Makefile_abi.include
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ BUILT_SOURCES = abi.h abi_converters.h standard_abi/mpi.h

libmpi_c_abi_la_SOURCES = \
abi_converters.c \
mpit_abi_handle_convert.c \
attr_fn_abi.c \
ompi_isendrecv.c \
ompi_sendrecv.c \
Expand Down
17 changes: 17 additions & 0 deletions ompi/mpi/c/init.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
#include "ompi/errhandler/errhandler.h"
#include "ompi/constants.h"
#include "ompi/mpiext/mpiext.h"
#include "ompi/runtime/ompi_mpit_events.h"
/* Declares ompi_mpit_abi_handle_convert_impl(); only *referenced* in the
Standard-ABI compile (guarded by OMPI_ABI_SRC in the body below), but
included unconditionally because OMPI_ABI_SRC is not yet defined this early
in the generated file. */
#include "ompi/mpi/c/mpit_abi_handle_convert.h"

PROTOTYPE INT init(INT_OUT argc, ARGV argv)
{
Expand All @@ -55,6 +61,17 @@ PROTOTYPE INT init(INT_OUT argc, ARGV argv)
* through the registered function pointer, avoiding a direct symbol dependency on libmpi.
* MPI extensions are only supported in the OMPI ABI, not the MPI Forum ABI. */
ompi_mpi_instance_register_mpiext_init(ompi_mpiext_init);
#else
/* This is the MPI Standard ABI entry point, so a tool observing MPI_T
* events from this process must see Standard-ABI integer handles in event
* payloads. Record the process ABI and install the intern->ABI handle
* 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;
ompi_mpit_register_abi_handle_convert(ompi_mpit_abi_handle_convert_impl);
ompi_mpit_register_abi_error_convert(ompi_mpit_abi_error_convert_impl);
ompi_mpit_register_abi_bind_convert(ompi_mpit_abi_bind_convert_impl);
#endif

/* Call the back-end initialization function (we need to put as
Expand Down
17 changes: 17 additions & 0 deletions ompi/mpi/c/init_thread.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@
#include "ompi/mca/hook/base/base.h"
#include "ompi/instance/instance.h"
#include "ompi/mpiext/mpiext.h"
#include "ompi/runtime/ompi_mpit_events.h"
/* Declares ompi_mpit_abi_handle_convert_impl(); only *referenced* in the
Standard-ABI compile (guarded by OMPI_ABI_SRC in the body below), but
included unconditionally because OMPI_ABI_SRC is not yet defined this early
in the generated file. */
#include "ompi/mpi/c/mpit_abi_handle_convert.h"


PROTOTYPE ERROR_CLASS init_thread(INT_OUT argc, ARGV argv, TS_LEVEL required,
Expand Down Expand Up @@ -75,6 +81,17 @@ PROTOTYPE ERROR_CLASS init_thread(INT_OUT argc, ARGV argv, TS_LEVEL required,
* through the registered function pointer, avoiding a direct symbol dependency on libmpi.
* MPI extensions are only supported in the OMPI ABI, not the MPI Forum ABI. */
ompi_mpi_instance_register_mpiext_init(ompi_mpiext_init);
#else
/* This is the MPI Standard ABI entry point, so a tool observing MPI_T
* events from this process must see Standard-ABI integer handles in event
* payloads. Record the process ABI and install the intern->ABI handle
* 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;
ompi_mpit_register_abi_handle_convert(ompi_mpit_abi_handle_convert_impl);
ompi_mpit_register_abi_error_convert(ompi_mpit_abi_error_convert_impl);
ompi_mpit_register_abi_bind_convert(ompi_mpit_abi_bind_convert_impl);
#endif

/* Call the back-end initialization function (we need to put as
Expand Down
89 changes: 89 additions & 0 deletions ompi/mpi/c/mpit_abi_handle_convert.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2026 Triad National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*
* MPI Standard ABI handle converter for MPI_T event payloads.
*
* The MPI_T event producers in libopen_mpi publish MPI object handles
* (communicator, window, session, error handler, file) in their event
* payloads. Under the MPI Standard ABI a tool expects those handles as the
* Standard-ABI integer handle, not the internal object pointer. The
* intern->ABI converters (ompi_convert_comm_ompi_to_standard(), etc.) are
* generated into abi_converters.h and compiled only into libmpi_abi (the upper
* layer), so the raise sites in libopen_mpi cannot call them directly (the
* OPAL->OMPI layering forbids an upward link dependency).
*
* This translation unit lives in libmpi_abi and provides the converter. The
* Standard-ABI init entry points (MPI_Init / MPI_Init_thread / MPI_Session_init)
* install it downward with ompi_mpit_register_abi_handle_convert(), mirroring
* ompi_mpi_instance_register_mpiext_init().
*/

#include "ompi_config.h"

#include <stddef.h>
#include <stdint.h>

#include "ompi/communicator/communicator.h"
#include "ompi/win/win.h"
#include "ompi/file/file.h"
#include "ompi/instance/instance.h"
#include "ompi/errhandler/errhandler.h"

#include "ompi/mpi/c/abi.h"
#include "ompi/mpi/c/abi_converters.h"
#include "ompi/mpi/c/mpit_abi_handle_convert.h"

#include "ompi/runtime/ompi_mpit_events.h"

uint64_t ompi_mpit_abi_handle_convert_impl(void *object, int handle_kind)
{
if (NULL == object) {
return 0;
}

/* handle_kind is a public MPI_T_BIND_* binding constant naming the class of
the object; convert the internal object pointer to the Standard-ABI
integer handle with the matching generated intern->ABI converter, then
widen to uint64_t. Each converter returns a mangled *_ABI_INTERNAL
handle (a pointer-width value carrying either a small reserved-handle
index or the object pointer), so route it through uintptr_t. */
switch (handle_kind) {
case MPI_T_BIND_MPI_COMM:
return (uint64_t) (uintptr_t)
ompi_convert_comm_ompi_to_standard((ompi_communicator_t *) object);
case MPI_T_BIND_MPI_WIN:
return (uint64_t) (uintptr_t)
ompi_convert_win_ompi_to_standard((ompi_win_t *) object);
case MPI_T_BIND_MPI_SESSION:
return (uint64_t) (uintptr_t)
ompi_convert_session_ompi_to_standard((ompi_instance_t *) object);
case MPI_T_BIND_MPI_ERRHANDLER:
return (uint64_t) (uintptr_t)
ompi_convert_intern_errorhandler_abi_errorhandler(
(ompi_errhandler_t *) object);
case MPI_T_BIND_MPI_FILE:
return (uint64_t) (uintptr_t)
ompi_convert_file_ompi_to_standard((ompi_file_t *) object);
default:
return 0;
}
}

int32_t ompi_mpit_abi_error_convert_impl(int32_t err_code)
{
/* Map an internal MPI error code to its MPI Standard ABI value. */
return (int32_t) ompi_convert_intern_error_abi_error((int) err_code);
}

int32_t ompi_mpit_abi_bind_convert_impl(int32_t object_bind)
{
/* Map an internal MPI_T_BIND_* value to its MPI Standard ABI value. */
return (int32_t) ompi_convert_t_bind_ompi_to_standard((int) object_bind);
}
47 changes: 47 additions & 0 deletions ompi/mpi/c/mpit_abi_handle_convert.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2026 Triad National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*
* Declaration of the MPI Standard ABI handle converter for MPI_T event
* payloads. The implementation lives in mpit_abi_handle_convert.c and is
* compiled only into libmpi_abi. The Standard-ABI init entry points install
* it downward via ompi_mpit_register_abi_handle_convert() so the libopen_mpi
* producer raise sites can reach it without an upward link dependency.
*/

#ifndef OMPI_MPI_C_MPIT_ABI_HANDLE_CONVERT_H
#define OMPI_MPI_C_MPIT_ABI_HANDLE_CONVERT_H

#include "ompi_config.h"

#include <stdint.h>

BEGIN_C_DECLS

/* Convert an internal MPI object handle (pointer) to its MPI Standard ABI
integer handle, widened to uint64_t. `handle_kind` is a public MPI_T_BIND_*
binding constant (MPI_T_BIND_MPI_COMM / _WIN / _SESSION / _ERRHANDLER /
_FILE). This is the ompi_mpit_abi_handle_convert_fn_t installed via
ompi_mpit_register_abi_handle_convert(). */
OMPI_DECLSPEC uint64_t ompi_mpit_abi_handle_convert_impl(void *object,
int handle_kind);

/* Convert an internal MPI error code to its MPI Standard ABI value. This is
the ompi_mpit_abi_value_convert_fn_t installed via
ompi_mpit_register_abi_error_convert(). */
OMPI_DECLSPEC int32_t ompi_mpit_abi_error_convert_impl(int32_t err_code);

/* Convert an internal MPI_T_BIND_* binding kind to its MPI Standard ABI value.
This is the ompi_mpit_abi_value_convert_fn_t installed via
ompi_mpit_register_abi_bind_convert(). */
OMPI_DECLSPEC int32_t ompi_mpit_abi_bind_convert_impl(int32_t object_bind);

END_C_DECLS

#endif /* OMPI_MPI_C_MPIT_ABI_HANDLE_CONVERT_H */
40 changes: 32 additions & 8 deletions ompi/mpi/c/session_init.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
#include "ompi/errhandler/errhandler.h"
#include "ompi/instance/instance.h"
#include "ompi/mpiext/mpiext.h"
#include "ompi/runtime/ompi_mpit_events.h"
/* Declares ompi_mpit_abi_handle_convert_impl(); only *referenced* in the
Standard-ABI compile (guarded by OMPI_ABI_SRC in the body below), but
included unconditionally because OMPI_ABI_SRC is not yet defined this early
in the generated file. */
#include "ompi/mpi/c/mpit_abi_handle_convert.h"

PROTOTYPE ERROR_CLASS session_init (INFO info, ERRHANDLER errhandler, SESSION_OUT session)
{
Expand All @@ -25,6 +31,32 @@ PROTOTYPE ERROR_CLASS session_init (INFO info, ERRHANDLER errhandler, SESSION_OU
opal_cstring_t *info_value;
const char ts_level_multi[] = "MPI_THREAD_MULTIPLE";

#if !OMPI_ABI_SRC
/* Register the mpiext initialization function with libopen_mpi.
* This breaks the circular dependency: libopen_mpi calls ompi_mpiext_init indirectly
* through the registered function pointer, avoiding a direct symbol dependency on libmpi.
* MPI extensions are only supported in the OMPI ABI, not the MPI Forum ABI. */
ompi_mpi_instance_register_mpiext_init(ompi_mpiext_init);
#else
/* This is the MPI Standard ABI entry point, so a tool observing MPI_T
* events from this process must see Standard-ABI integer handles and
* Standard-ABI integer values in event payloads. Record the process ABI
* and install the intern->ABI converters downward into libopen_mpi (the
* converters live here in libmpi_abi; see mpit_abi_handle_convert.c),
* mirroring the mpiext_init registration above.
*
* This is done up front, before the parameter-validation branches below
* 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 the
* ompi.mpi.errhandler_invoked event. Installing the converters first
* ensures that event publishes correct Standard-ABI values (e.g. for the
* predefined error handler) instead of the 0 / internal fallbacks. */
ompi_mpit_callback_abi = OMPI_MPIT_ABI_STANDARD;
ompi_mpit_register_abi_handle_convert(ompi_mpit_abi_handle_convert_impl);
ompi_mpit_register_abi_error_convert(ompi_mpit_abi_error_convert_impl);
ompi_mpit_register_abi_bind_convert(ompi_mpit_abi_bind_convert_impl);
#endif

if ( MPI_PARAM_CHECK ) {
if (NULL == errhandler) {
rc = MPI_ERR_ERRHANDLER;
Expand Down Expand Up @@ -52,14 +84,6 @@ PROTOTYPE ERROR_CLASS session_init (INFO info, ERRHANDLER errhandler, SESSION_OU
}
}

#if !OMPI_ABI_SRC
/* Register the mpiext initialization function with libopen_mpi.
* This breaks the circular dependency: libopen_mpi calls ompi_mpiext_init indirectly
* through the registered function pointer, avoiding a direct symbol dependency on libmpi.
* MPI extensions are only supported in the OMPI ABI, not the MPI Forum ABI. */
ompi_mpi_instance_register_mpiext_init(ompi_mpiext_init);
#endif

rc = ompi_mpi_instance_init (ts_level, &info->super, errhandler, session, 0, NULL);
/* if an error occurred raise it on the null session */
fn_exit:
Expand Down
Loading
Loading