Skip to content

refactor: 🧹 use hwloc instead of custom topology discovery - #208

Open
robertodr wants to merge 4 commits into
refactor-split-implsfrom
refactor-use-hwloc
Open

refactor: 🧹 use hwloc instead of custom topology discovery#208
robertodr wants to merge 4 commits into
refactor-split-implsfrom
refactor-use-hwloc

Conversation

@robertodr

Copy link
Copy Markdown
Member

Summary

The CPU topology discovery and thread pinning used a custom implementation that was not really portable. hwloc is the standard tool for this job.

Changes

  • Add and integrate hwloc as dependency for cross-platform CPU topology discovery.

Checklist

  • Tests added or updated to cover the changes
  • Documentation updated (docstrings, docs/, CONTRIBUTING.md) if needed
  • CHANGELOG / release notes updated if applicable

AI/LLM disclosure

  • I did not use LLM tooling, or used it only privately for ideation
  • I used the following tool to help write this PR description:
  • I used the following tool to generate or modify code: GitHub Copilot gpt-5.6-sol (plan), claude-haiku-4.5/claude-sonnet-4.6 (execute)

Important

By opening this PR I confirm that I have read CONTRIBUTING.md and I agree to the terms of the Contributor License Agreement.

Warning

If you're contributing on behalf of your employer, contact cla@algorithmiq.fi to arrange a Corporate CLA.

@robertodr
robertodr changed the base branch from main to refactor-split-impls August 5, 2026 12:35
@robertodr robertodr changed the title Refactor use hwloc refactor: 🧹 use hwloc instead of custom topology discovery Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Docs preview: https://pr-208.monoprop-docs.pages.dev

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.58%. Comparing base (0a38197) to head (43084d9).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@                  Coverage Diff                  @@
##           refactor-split-impls     #208   +/-   ##
=====================================================
  Coverage                 97.58%   97.58%           
=====================================================
  Files                        14       14           
  Lines                       745      745           
  Branches                     99       99           
=====================================================
  Hits                        727      727           
  Misses                       13       13           
  Partials                      5        5           
Flag Coverage Δ
cpp 97.58% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

🤖 AI text below 🤖

Refactors the CPU-topology discovery and partition thread pinning in monoprop to use hwloc, aiming for more portable and consistent topology enumeration and affinity binding across supported platforms.

Changes:

  • Replace the custom /sys-parsing topology logic with an hwloc-backed implementation (CpuTopology.*) and expose a deterministic placement-policy helper for unit testing.
  • Integrate hwloc into the C++ build (CMake + pkg-config) and update C++ unit tests accordingly.
  • Update developer tooling and CI environments to install hwloc (scripts, workflows, devcontainer) and refresh related documentation.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/install-deps.sh Adds optional hwloc installation and broadens OS detection for the dependency installer script.
pyproject.toml Updates macOS cibuildwheel pre-build dependencies to include hwloc.
docs/content/docs/features/parallelism.mdx Updates documentation to reflect hwloc-based pinning support beyond Linux.
cpp/tests/cpu_topology_tests.cpp Reworks CPU-topology tests for hwloc and adds deterministic placement-policy unit tests.
cpp/tests/CMakeLists.txt Links unit tests against hwloc via PkgConfig::HWLOC.
cpp/monoprop/detail/partition/CpuTopology.h Updates the public topology/pinning API docs and types for an hwloc implementation.
cpp/monoprop/detail/partition/CpuTopology.cpp Implements topology discovery and thread pinning via hwloc, plus shared placement-policy logic.
cpp/monoprop/CMakeLists.txt Adds pkg-config discovery for hwloc and wires PkgConfig::HWLOC into library linkage.
AGENTS.md Documents hwloc as a required system dependency and where it’s used.
.github/workflows/test.yml Ensures CI runners install hwloc on macOS and Ubuntu.
.github/workflows/qa-analysis.yml Adds libhwloc-dev to QA workflow dependency installs.
.github/workflows/docpages.yml Adds libhwloc-dev to docs build workflow dependency installs.
.github/workflows/copilot-setup-steps.yml Adds libhwloc-dev to Copilot setup steps.
.devcontainer/Dockerfile Installs libhwloc-dev in the devcontainer image.
Suppressed comments (1)

tools/install-deps.sh:217

  • The script advises setting only CMAKE_PREFIX_PATH, but the build now discovers hwloc via pkg-config (pkg_check_modules(HWLOC …)), which typically requires PKG_CONFIG_PATH to include the install prefix when using a non-system INSTALL_PREFIX. Without that, a custom-prefix hwloc installed by this script may still not be found by CMake.
echo "Dependencies installation completed successfully!"
echo "Install location: $INSTALL_PREFIX"
echo "Make sure to set CMAKE_PREFIX_PATH=$INSTALL_PREFIX when building monoprop"

Comment on lines 105 to +109
INTERFACE
Boost::boost
Threads::Threads
$<$<TARGET_EXISTS:MPI::MPI_CXX>:MPI::MPI_CXX>
PRIVATE
Comment on lines 83 to +86
const auto rank0 = partition::partition_cpusets(/*n=*/1, /*group_index=*/0, /*group_count=*/2);
const auto rank1 = partition::partition_cpusets(/*n=*/1, /*group_index=*/1, /*group_count=*/2);
// Off Linux there is no pinning, so both come back empty (unpinned, still disjoint by the scheduler).
#if defined(__linux__)
BOOST_CHECK_EQUAL(rank0.size(), 1u);
BOOST_CHECK_EQUAL(rank1.size(), 1u);
#else
BOOST_CHECK(rank0.empty());
BOOST_CHECK(rank1.empty());
#endif
BOOST_REQUIRE_EQUAL(rank0.size(), 1u);
BOOST_REQUIRE_EQUAL(rank1.size(), 1u);
@robertodr robertodr added the test-in-draft Run CI even in Draft mode label Aug 5, 2026
@robertodr
robertodr marked this pull request as draft August 5, 2026 13:27
@robertodr

This comment was marked as resolved.

@robertodr
robertodr force-pushed the refactor-use-hwloc branch from 842359c to f810a4e Compare August 5, 2026 14:10
@robertodr
robertodr force-pushed the refactor-use-hwloc branch from f810a4e to 7a8322a Compare August 5, 2026 14:42
@robertodr
robertodr force-pushed the refactor-use-hwloc branch 2 times, most recently from aeda5c8 to 8a20dde Compare August 5, 2026 17:51
@robertodr
robertodr force-pushed the refactor-use-hwloc branch from 8a20dde to 746e541 Compare August 6, 2026 09:18
@robertodr
robertodr force-pushed the refactor-use-hwloc branch from 746e541 to 03ce849 Compare August 6, 2026 09:20
@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file labels Aug 6, 2026
@robertodr
robertodr force-pushed the refactor-use-hwloc branch from 03ce849 to 4344a7c Compare August 6, 2026 10:04
@robertodr
robertodr force-pushed the refactor-use-hwloc branch from 4344a7c to b400bce Compare August 6, 2026 11:47
@robertodr
robertodr force-pushed the refactor-use-hwloc branch from b400bce to 6ddac83 Compare August 6, 2026 11:48
@github-actions github-actions Bot added the python label Aug 6, 2026
@robertodr
robertodr marked this pull request as ready for review August 6, 2026 14:18
@robertodr
robertodr requested a balanced review from Copilot August 7, 2026 07:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

docs/content/docs/features/parallelism.mdx:32

  • 🤖 AI text below 🤖

The macOS claim is incorrect. hwloc can discover Darwin topology, but its own binding implementation states that Darwin has no CPU-binding facilities, so hwloc_set_cpubind() here fails and the worker remains unpinned. Document macOS as topology-discovery-only rather than presenting thread pinning as supported.

| `monoprop_PARTITION_PINNING` | `on` | `0`/`false`/`no` disables pinning each partition to a core. Supported on platforms where hwloc can bind threads (Linux, macOS). |

Comment thread AGENTS.md Outdated
Comment on lines +17 to +21
#include <hwloc.h>

#include <pthread.h>
#include <algorithm>
#include <map>
#include <vector>

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.

Suggested change
#include <hwloc.h>
#include <pthread.h>
#include <algorithm>
#include <map>
#include <vector>
#include <algorithm>
#include <map>
#include <vector>
#include <hwloc.h>

Assisted-by: GitHub Copilot: gpt-5.6-sol (plan), claude-haiku-4.5/claude-sonnet-4.6 (execute)
with before-build we re-ran the same installation script before every build.
@robertodr
robertodr force-pushed the refactor-use-hwloc branch from 500a915 to ed369bf Compare August 7, 2026 08:17
@sonarqubecloud

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

@robertodr

Copy link
Copy Markdown
Member Author

Running just bench on this branch and comparing to main. No glaring regression.

Heisenberg

Time

Operation main refactor-use-hwloc
model / hubbard 634.404 ms 630.797 ms
model / pauli 210.296 ms 207.732 ms
random / build_graph 9.231 ms 9.364 ms
random / energy 1.520 ms 1.287 ms
random / gradient 6.759 ms 3.730 ms
random / inplace 8.002 ms 8.480 ms
random / pare 4.028 ms 4.726 ms

Memory (peak RSS)

Operation main refactor-use-hwloc
model / hubbard 217.61 MiB 216.95 MiB
model / pauli 159.72 MiB 161.11 MiB
random / build_graph 176.58 MiB 178.06 MiB
random / energy 175.51 MiB 177.03 MiB
random / gradient 181.27 MiB 182.75 MiB
random / inplace 197.15 MiB 198.59 MiB
random / pare 176.03 MiB 177.57 MiB

Schrödinger

Time

Operation main refactor-use-hwloc
random / build_graph 162.400 ms 157.514 ms
random / energy 19.136 ms 19.069 ms
random / gradient 40.633 ms 40.594 ms
random / inplace 111.969 ms 111.968 ms
random / pare 10.478 ms 14.105 ms

Memory (peak RSS)

Operation main refactor-use-hwloc
random / build_graph 23580.09 MiB 24484.79 MiB
random / energy 1919.83 MiB 1922.77 MiB
random / gradient 1953.00 MiB 1955.44 MiB
random / inplace 28983.84 MiB 30060.64 MiB
random / pare 1865.67 MiB 1867.07 MiB

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

Labels

ci cpp dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation python test-in-draft Run CI even in Draft mode tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants