Affinity mapping - #259
Open
Maff Glover (mo-mglover) wants to merge 23 commits into
Open
Conversation
Maff Glover (mo-mglover)
marked this pull request as draft
August 10, 2026 11:18
Maff Glover (mo-mglover)
marked this pull request as ready for review
August 10, 2026 20:24
Maff Glover (mo-mglover)
marked this pull request as draft
August 11, 2026 12:41
There was a problem hiding this comment.
Pull request overview
Adds an “affinity mapping” feature to Vernier so client applications (C++ and Fortran) can write an ASCII-art report showing where MPI ranks and threads are running/bound at runtime.
Changes:
- Introduces a new C++ affinity subsystem (
Affinity,AffinitySysCalls) and wires it into the Vernier public API (write_affinity*). - Extends Fortran and C interfaces to expose the affinity-writing entry points.
- Adds new C++/Fortran unit tests and updates the user guide API documentation.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit_tests/f/test_vernier_mod.pf | Adds Fortran unit tests for the new affinity-write routines and output filename behavior. |
| tests/unit_tests/c++/test_proftests.cpp | Adds C++ tests for affinity write error handling and output filenames. |
| tests/unit_tests/c++/test_affinity.cpp | New unit tests for affinity-map generation (with mocked syscalls). |
| tests/unit_tests/c++/CMakeLists.txt | Registers the new test_affinity target. |
| src/f/vernier_mod.F90 | Adds Fortran API bindings/wrappers for affinity map output. |
| src/c++/vernier.h | Exposes new C++ API methods for affinity writing. |
| src/c++/vernier.cpp | Implements Vernier affinity-writing entry points and filename construction. |
| src/c++/mpi_context.h | Extends MPIContext (const-correct getters, on_root(), default tag). |
| src/c++/mpi_context.cpp | Implements MPIContext const getters and on_root(). |
| src/c++/CMakeLists.txt | Adds affinity.cpp to the library build and installs affinity.h. |
| src/c++/affinity.h | Declares affinity reporting classes and syscall abstraction. |
| src/c++/affinity.cpp | Implements affinity map generation and MPI-IO output. |
| src/c/vernier_c.cpp | Adds C wrappers for the new affinity-write entry points. |
| documentation/Sphinx/user_guide/api/api.rst | Documents the new affinity-writing APIs for C++ and Fortran. |
| CONTRIBUTORS.md | Adds a new contributor entry. |
Suppressed comments (4)
src/c++/affinity.cpp:89
core_idis used to indexmaskwithout checking bounds. If CPU IDs are sparse orrunning_on_core()returns an unexpected value,mask.at(core_id)will throw and abort.
auto core_id = static_cast<std::size_t>(system_calls_->running_on_core());
char thread_id_char = thread_id_to_char(thread_id);
// If more than one thread is running on the same core, show that with a
// hash symbol.
#pragma omp critical
{
if (mask.at(core_id) == '.') {
mask.at(core_id) = thread_id_char;
} else {
mask.at(core_id) = '#';
}
src/c++/affinity.cpp:148
- The MPI-IO offset for each rank is computed using
record_length, but the view datatype and write size usemax_record_length. When record lengths differ across ranks (e.g., heterogeneous nodes / differentmax_cpus), this can cause overlapping writes and a corrupted file.
// Each rank computes its own offset.
MPI_Offset my_offset =
header_length +
(static_cast<MPI_Offset>(mpi_context.get_rank()) * record_length);
documentation/Sphinx/user_guide/api/api.rst:165
- Grammar: "The tag argument optional" is missing "is".
communicator. The tag argument optional and, if present, will be appended to
src/c++/vernier.cpp:18
write_affinity_with_contextusesstd::stringstream, but<sstream>is not included here. This can fail to compile depending on transitive includes.
#include "vernier.h"
#include "affinity.h"
#include "error_handler.h"
#include "hashvec_handler.h"
#include <cassert>
#include <chrono>
#include <iostream>
#ifdef _OPENMP
#include <omp.h>
#endif
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Maff Glover <78152252+mo-mglover@users.noreply.github.com>
Maff Glover (mo-mglover)
requested review from
Andrew Coughtrie (andrewcoughtrie) and
Sam Clarke-Green (t00sa)
August 20, 2026 13:55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Rather than take on-trust that MPI ranks and threads are bound to cores as expected, perhaps according to launcher flags or
OMP_environment variables, it is useful to be able to test this directly. More specifically, test the affinity from a running application on the platform / in the environment that an application might be running.Including this functionality in Vernier is useful because any client application will then have access to it. The new functionality is exposed via two new API calls (one C++, one Fortran). As with all Vernier calls, these can be built into an application, perhaps behind a switch.
Example:
lscpuwill give that information.Linked issues
No associated issue.
Type of change
How has this been tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
Checklist: