Skip to content

mpi_t: register enum cvars with an MPI_T enum - #8040

Merged
hzhou merged 1 commit into
pmodels:mainfrom
hzhou-muse:mpit_cvar_enum
Oct 20, 2026
Merged

hzhou merged 1 commit into
pmodels:mainfrom
hzhou-muse:mpit_cvar_enum

Conversation

@hzhou-muse

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

Copy link
Copy Markdown
Contributor

Pull Request Description

Every CVAR was registered with MPI_T_ENUM_NULL, so MPI_T_cvar_get_info returned no enum for enum CVARs such as MPIR_CVAR_BCAST_INTRA_ALGORITHM. A tool could set them only by raw number, which depends on the order of values in the generated header. This matters for runtime tuning through MPI_T (see #8039).

extractcvars now creates an MPI_T enum for each enum CVAR, named after the CVAR, with one item per value, and registers the CVAR with it. A tool can then map value names to numbers with MPI_T_enum_get_item.

  • MPIR_T_CVAR_REGISTER_impl now stores its etype argument in the CVAR; it was taking it but never storing it.
  • enum_table holds pointers to the enums. An MPI_T_enum handle is the enum's address, and with the table storing the enums themselves, a handle went stale whenever the table grew. Nothing created enums before, so this never showed up.
  • MPIR_T_CVAR_REGISTER_STATIC takes an etype argument. extractcvars is its only user.

Author Checklist

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

🤖 Generated with Claude Code

@hzhou-muse

Copy link
Copy Markdown
Contributor Author

Performance impact. There's no overhead on any communication path. The cost is a one-time setup during initialization and a matching cleanup at finalize, and it's small.

  • When it runs. The enums are built in MPIR_T_cvar_init, which runs once per process from MPIR_T_env_init: in MPI_Init or MPI_Session_init, even when no tool uses MPI_T, or in MPI_T_init_thread. Everything is freed in MPIR_T_env_finalize. Collectives and everything else still read the CVARs as plain int globals and never look at the MPI_T enum.
  • How much work. The tree has 102 enum CVARs with roughly 435 values in total. Building them takes about 800 small allocations: for each enum, allocating the struct, copying its name and creating its item array, and for each value, copying its name.
  • Compared with before. Init already copies the name and the full description of every CVAR (several hundred CVARs, often hundreds of bytes of description each), so it already allocates on the order of 100 KB. The enums add roughly 20–30 KB and well under a millisecond. These sizes and times are estimates, not measurements.
  • Code size. The generated mpir_cvars.c gains about 540 lines of MPIR_T_enum_add_item calls plus the value names as string literals, a few KB in the library.
  • The enum_table change. Storing pointers adds one extra pointer step inside the MPI_T_enum_* query calls, and only tools call those.

To avoid the allocations, the enums and their item arrays could be generated as static constant tables instead of being built at init. That would need changes to the MPIR_T_enum_t type and its finalize code, which isn't worth it for this cost.

@hzhou-muse

hzhou-muse commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

test:mpich/ch3/tcp ✔️

1 TIMOUT ./coll/bcast 4 -type=MPI_INT:4+MPI_DOUBLE:8 -count=262144 -seed=16 -testsize=16 due to heavy load - unrelated.

@hzhou-muse

Copy link
Copy Markdown
Contributor Author

Tested locally with a debug build (--enable-g=dbg, ch4:ofi). There were no compiler warnings in mpir_cvars.c or the mpi_t files. The generated mpir_cvars.c has 435 MPIR_T_enum_add_item calls.

A small MPI_T test program walks every CVAR with MPI_T_cvar_get_info and reads each enum handle with MPI_T_enum_get_info and MPI_T_enum_get_item:

  • 102 of the 394 CVARs now have an enum. Each enum is named after its CVAR and has at least one value.
  • MPIR_CVAR_BCAST_INTRA_ALGORITHM lists all 10 values by name: auto=0 binomial=1 nb=2 circ_graph=3 smp=4 scatter_recursive_doubling_allgather=5 scatter_ring_allgather=6 pipelined_tree=7 tree=8 release_gather=9.
  • The first enum created, MPIR_CVAR_BARRIER_INTRA_ALGORITHM, still reads correctly after all 102 were created. This is the case the enum_table pointer change fixes; before it, that handle would have been left dangling.

valgrind reports 0 errors and no definite leaks through MPI_T_init_thread and MPI_T_finalize, so the new allocations are all freed.

The mpivars tool, which already supported enums, now prints a value list under each enum CVAR, e.g.:

Enum MPIR_CVAR_BCAST_INTRA_ALGORITHM (10) values: auto(0),binomial(1),nb(2),circ_graph(3),smp(4),scatter_recursive_doubling_allgather(5),scatter_ring_allgather(6),pipelined_tree(7),tree(8),release_gather(9)

extractcvars now creates an MPI_T enum for each enum cvar, with one item
per value, and registers the cvar with it, so MPI_T_cvar_get_info returns
an enum handle that a tool can use to map value names to numbers.
MPIR_T_CVAR_REGISTER_impl stores the enum in the cvar, and enum_table
holds pointers to the enums so that handles stay valid as it grows.

Previously every cvar was registered with MPI_T_ENUM_NULL, and a tool
could set an enum cvar only by its raw number.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@hzhou
hzhou merged commit 5069c96 into pmodels:main Oct 20, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants