Releases
v4.2.0
June 16, 2026
A telemetry-on-real-clusters release. Watching a gempba run on an HPC compute node needs two things to be true at once: the per-node numbers have to be right, and you have to be able to reach them from your own machine. v4.2.0 delivers both — node telemetry now reports correct socket topology, CPU placement, and per-job memory on large multi-socket nodes, and the operator scripts can tunnel to a compute node through an MFA login node. The telemetry wire format only grows (additive cgroup-memory fields; schema version unchanged) and there are no public C++ API changes — additive on top of v4.1.3.
Fixed
- Every node reports its real socket topology, not just the center. Per-host topology is now gathered with a variable-length collective — each host's sentinel serializes its own layout, exchanged via
MPI_Allgathervand merged by hostname — so all nodes report their sockets, cores, and full per-socket CPU lists (including wide sockets such as 96-core EPYC), instead of only rank 0's (#327) - Workers land on their real socket, and CPUs past index 64 are no longer dropped. The per-worker affinity bitmap grew from a single 64-bit word to a
MAX_LOGICAL_CPUS-wide array, and each rank's primary socket is derived from its first allowed CPU through hwloc instead of being hardcoded to 0. On nodes with more than 64 logical CPUs this fixes the flat-zero per-allocation CPU% and the collapse of every rank onto socket 0 (#327) - Memory reflects the job, not the host. The node frame now carries the process's memory-cgroup usage and limit, resolved at the cgroup that actually enforces the allocation (scheduler-agnostic, cgroup v1 and v2), so a shared node shows gempba's own footprint against its allocation instead of the whole machine's memory. Falls back to host totals when the process is unconstrained (#327)
Added
- Reach telemetry on a compute node through an MFA login node.
telemetry_tunnel --jump-hostnests the tunnel instead of using SSHProxyJump: it forwards your machine to the login node, then runs the final hop on the login node so it rides the cluster's intra-cluster trust — one Duo prompt at the login node, no compute-node password, and gempba stays loopback-only.accept-newauto-trusts the per-job compute-node host key, and the readiness probe waits for a real byte rather than just a TCP accept. The mechanics are written up indocs/remote-connection.md(#325) - Bash ports of the operator scripts.
scripts/telemetry_tunnel.shandscripts/telemetry_view.shjoin the PowerShell versions, so the tunnel and live-watch workflows run the same from Linux and macOS shells (#325)
Changed
- The telemetry operator scripts were renamed and simplified. The helpers were renamed for clarity and the SLURM job-resolution path was dropped — pass the compute node directly (
--ssh-host/--jump-host) instead of--job <slurm-id>. Update any wrappers that called the old names or relied onsqueueresolution (#319)
Docs
- Corrected the release dates in the per-version release notes (#323)
v4.1.3
June 2, 2026
A telemetry-reachability release. Two fixes, both about getting at telemetry from outside the C++ runtime: C++ consumers can reach it through the umbrella header again, and the configure_port control is finally callable from the C ABI and Java. No runtime or scheduler API changes.
Fixed
gempba::telemetry::*is reachable through<gempba/gempba.hpp>again. The umbrella header didn't surface telemetry, so consumer code that included only<gempba/gempba.hpp>failed to compilegempba::telemetry::enable()withno member named 'telemetry' in namespace 'gempba'— and IDEs "fixed" it by inserting a deep, machine-specific include into the telemetry subheader. The umbrella now includes it, so the full public telemetry surface compiles from the one header consumers already use (#314)
Added
configure_portacross the bindings. The telemetry kill switch (enable/disable/is_enabled) was already mirrored in the C ABI, JNI, and Java, butconfigure_port— the call that moves the telemetry TCP port off the default127.0.0.1:9000— had been left behind. It is now exposed asgempba_telemetry_configure_port(C ABI) andGemPBA.configureTelemetryPort(int)(Java, both flavors, with a0..65535range check). As in C++, call it before the firstcreate_*: the hub captures the port once, when it installs (#315)
v4.1.2
May 31, 2026
A targeted bugfix release: multiprocessing now runs on macOS. MP-mode binaries aborted at startup on macOS — and only macOS — with mutex lock failed: Invalid argument, while the same build ran fine on Linux and Windows. If you only use MT mode, or don't run on macOS, nothing here affects you. No library or API changes.
Fixed
- macOS MP no longer aborts at startup. Both MPI schedulers passed a 128-byte buffer to
MPI_Get_processor_name, which OpenMPI requires to beMPI_MAX_PROCESSOR_NAME(256) — it fills the full field, overflowing the buffer and zeroing an adjacentstd::mutex. A zeroed mutex is a validPTHREAD_MUTEX_INITIALIZERon Linux/glibc, so the corruption stayed invisible there; macOS rejects it withEINVAL, so the first lock threwstd::system_error. The buffer is now sizedMPI_MAX_PROCESSOR_NAMEin both the semi-centralized and centralized schedulers (#310)
Removed
- Dropped an unused
m_processor_namefield fromnode_manager— declared but never read or written, and carrying the same undersized buffer (#310)
Docs
- Added a DeepWiki badge and callout to the README (#308)
Build / CI
- Split the Java binding workflow's native build from its tests, so a flaky Java test re-runs on its own without rebuilding the JNI library — the build job hands the native lib to the test job as a per-run artifact (#311)
- Extracted the duplicated gempba-examples branch resolver into a shared composite action, deduping the three C/C++ CI workflows (#311)
- Bumped the PKGBUILD
sha256for the v4.1.1 packaging artifact
v4.1.1
May 30, 2026
A pure install-fixes release. v4.1.0 shipped the packages, but several of the documented install paths didn't actually work on a clean machine — the Homebrew build failed in the sandbox, the apt repo's signing key was never published, the MSYS2 download link pointed at a filename that doesn't exist. v4.1.1 makes every install command in the README work end-to-end, on all three platforms.
No library or API changes. If v4.1.0 already installed and built for you, nothing here affects your code — upgrade only if you hit one of the install problems below.
Fixed
brew installnow works. The v4.1.0 formula died inside Homebrew's build sandbox — CPM/FetchContent tried to fetchBS_thread_poolover the network at build time, which the sandbox blocks. Those build deps are now vendored into the formula, so it builds offline (#288)apt installno longer fails signature verification. The signed APT repo never exposed its public key, soapt updaterejected it withNO_PUBKEY 7C5B392E…. The release now publishes the signing key (gempba-archive-keyring.gpg) alongside the index, so the documentedsigned-by=setup resolves (#286)- Dropped an unused OpenMP dependency the macOS formula pulled in for nothing (#289)
Docs
- Rewrote the README's pre-built-package install instructions — every platform's block was broken or misleading (#286):
- APT — added the one-time key-trust + repo-registration steps before
apt install. - MSYS2 — the old
releases/latest/download/<fixed-name>link 404'd (release asset names carry the version); now points at the Releases page +pacman -U. - Homebrew — fixed the literal
<owner>placeholder, and clarified that both flavors install side by side (only one is linked at a time; each project points at$(brew --prefix gempba)/gempba-mpi). - Named the two flavors (
mt/mpi/mp-mpi) up front so the section's recurring terms map to just two things.
- APT — added the one-time key-trust + repo-registration steps before
Build / CI
- The Homebrew formula is now built and
brew test-ed on a real macOS runner on every PR and release, so a non-installable formula blocks the release instead of shipping (#292) prepare-releasebumps the Homebrew formula templates in lockstep with the other manifests — and actually stages them, so the bump lands on the prep branch (#297)- Hardened the macOS formula-verify job: pinned Homebrew off mid-run auto-update (which broke its ephemeral tap) and serialized the two-flavor matrix so they stop colliding on the shared prefix (#303)
v4.1.0
May 28, 2026
Java. That's the headline.
gempba is now a Maven dependency. Drop it into a pom.xml, write import io.gempba.*, and call the same scheduler family, load balancer, and node manager you would from C++ — just from Java this time. One fat JAR per flavor (mt, mp-mpi) carries the native binaries for Linux, Windows, and macOS inside the artifact, so there is no per-platform build dance, no classifier juggling, no "first set LD_LIBRARY_PATH" footnote. You add the dependency, you build, you run.
That this is shippable at all is because of the second piece of v4.1.0: a stable C ABI underneath. The Java binding is the first consumer of it, but the same headers are what any future Python / Rust / .NET binding will sit on. If you have a JVM pipeline, a Spark job, an Airflow operator, an enterprise application — anywhere C++ was the wrong language but you still wanted gempba's scheduler — that bridge now exists.
Everything else in v4.1.0 is the surrounding work: the publish pipeline, the README the new Java audience needs, a couple of bug fixes. No public C++ API changes — additive on top of v4.0.0.
Added
- Stable C ABI (
<gempba/cabi/gempba.h>) — extern-C surface covering the full runtime: scheduler family, load balancer, node manager, factories, runnables, MP / MT entry points, per-node result retrieval. The same headers any non-C++ binding will reuse going forward (#185) - Java JNI binding (
io.gempba:gempba) — typed wrappers forNode,LoadBalancer,NodeManager,RankStats,Score/ScoreType,Goal,BalancingPolicy, the task / serializer / deserializer functional interfaces, the scheduler family (MP-only), andGemPBAentry points for both flavors (#186) - Multi-platform fat JAR — each published JAR carries
natives/<os>-<arch>/for Linuxx86_64, Windowsx86_64, and macOSaarch64.NativeLoaderpicks the right binary at runtime, so the same JAR runs unchanged on any supported platform. No per-OS classifier, no platform-specific Maven profiles (#274) - Maven publication to GitHub Packages on every
v*tag, with classifiersmt(multithreading) andmp-mpi(multiprocessing). Add the repo to yoursettings.xml, declare the dependency with the classifier you want, build (#187) - README "Maven dependency (Java)" subsection — repository +
settings.xml+ dependency snippet, plus a cutoff note that Maven artifacts start atv4.1.0(earlier tags predate the publish flow). Platforms section gains a per-OS architecture table (#283)
Fixed
default_mpi_stats_visitor::labels()was missing thetotal_thread_requestskey — values were emitted but the label vector didn't cover them, breaking downstream consumers that zipped labels with values (#262)set_thread_pool_sizecould race against in-flight construction; the resize now round-trips a no-op task to fence the pool's worker threads before returning (#277)
Build
- CI workflows split into mutually exclusive triggers:
ci-*.ymlruns on PRs and branch pushes,release-*.ymlruns on tags. Reusable building blocks factored out so tag-time publish reuses the exact build path CI exercises (#265) - Workflow folder reorganized with
ci-/release-prefixes, a.github/workflows/README.md, and shared composite actions extracted (#271) prepare-release.ymlnow bumpsbindings/java/pom.xml's<version>alongside the CMake / PKGBUILD bumps so the Java release version stays in lockstep with the C++ release version (#187)- Lint workflow bumped to LLVM 22; the modernizations clang-tidy 22 flagged were applied (#261)
v4.0.0
May 23, 2026
This is the release where gempba becomes a real distributed library you install instead of clone. Pick your flavor (multithreading or MPI), pick your platform (Linux, macOS, or Windows), and apt install / pacman -S / brew install your way to a working build. Telemetry, which landed in v3.3.0, ships in every flavor, so your production runs are observable out of the box without any wiring.
What's new
- Packages on every platform.
.debon Debian/Ubuntu, MSYS2 packages on Windows, and a brand-new Homebrew tap on macOS. Each platform ships two coexisting flavors: a default multithreading build and an MPI build that you install on top when you need it. - Telemetry is in the box. The v3.3.0 telemetry hub (worker / node frames, hwloc topology, local + TCP + MPI transports) is built into every published flavor. No extra dependency to add, no extra flag to flip.
- Same call site, both modes. Public namespaces were reshaped. Consumer code now reads the same whether you build against the multithreading or the MPI flavor:
gempba::create_load_balancer(...),gempba::create_node_manager(...). Mode is picked atfind_packagetime, not at every call site. - Examples moved out.
examples/left the source tree for a sibling repo, rapastranac/gempba-examples, where they consume gempba viafind_packageexactly like you would. Every example PR exercises the public API.
Breaking changes
- Public namespaces renamed:
gempba::mpis nowgempba::multiprocessing,gempba::mtis nowgempba::multithreading. - In a consumer build, exactly one of the two is
inline, selected byGEMPBA_MULTIPROCESSING. Code that hard-codes the explicit qualifier still compiles, but mixing both qualifiers in one consumer build no longer works. - The
gempba::multiprocessing::*facade (schedulers, MP factories, MPcreate_node_manager,get_default_mpi_stats_visitor,runnables::*, MP node creators) is gated onGEMPBA_MULTIPROCESSING=ON. Code that referenced these in an MT-only build will fail to compile. apt install libgempba-devpreviously gave you an MPI-enabled build. It now gives you multithreading only. MPI consumers additionallyapt install libgempba-mpi-dev.pacman -S mingw-w64-x86_64-gempbapreviously gave you an MPI-enabled build. Same shape: MPI consumers additionallypacman -S mingw-w64-x86_64-gempba-mpi.- The in-tree
examples/tree is gone. The migrated tree now lives in rapastranac/gempba-examples.
Migration
// Before (v3.x)
auto* lb = gempba::mp::create_load_balancer(policy, worker);
auto& nm = gempba::mp::create_node_manager(lb, worker);
// After (v4.0): short form, mode picked by GEMPBA_MULTIPROCESSING
auto* lb = gempba::create_load_balancer(policy, worker);
auto& nm = gempba::create_node_manager(lb, worker);
// (or the explicit form: gempba::multiprocessing::create_load_balancer(...))
# v4.0 consumer CMake
find_package(gempba REQUIRED) # default: mt
find_package(gempba REQUIRED COMPONENTS mt) # explicit mt
find_package(gempba REQUIRED COMPONENTS mpi) # mpi (requires libgempba-mpi-dev installed)
target_link_libraries(my_app PRIVATE gempba::gempba)
The two flavors are mutually exclusive within a single binary. They share mode-agnostic top-level symbols and would ODR-clash, so find_package(gempba COMPONENTS mt mpi) is rejected up front with a clear diagnostic. A project that genuinely needs both (say, an MT debug runner and an MPI cluster runner) splits into two executables, each find_package-ing one.
Added
- Top-level
gempba::create_load_balancer(std::unique_ptr<load_balancer>). Mode-agnostic BYO factory that works identically in MT and MP builds. gempbaConfig.cmakeis now a COMPONENTS-aware dispatcher. Defaults tomt, refuses themt+mpicombination, pullsfind_dependency(MPI)only on thempibranch.- Two
.debpackages:libgempba-dev(mt base, ships headers andgempbaConfig.cmake) andlibgempba-mpi-dev(mpi topping,Depends:the base pluslibopenmpi-dev). Installable side-by-side without conflict. - Two MSYS2 packages:
mingw-w64-x86_64-gempbaandmingw-w64-x86_64-gempba-mpi. Same shape, same dependency direction. - macOS Homebrew tap:
brew tap <owner>/gempba && brew install gempba(orgempba-mpi). - rapastranac/gempba-examples sister repo carrying the migrated example tree. Consumes gempba via
find_package(gempba)exactly as a downstream user would. - README sections "Installing" (apt / pacman / brew per flavor) and "Selecting a flavor" (the
COMPONENTSAPI, the mutual-exclusion guard, the two-executables pattern).
Build
find_package(MPI REQUIRED)andMPI::MPI_CXXlinkage are conditional onGEMPBA_MULTIPROCESSING=ON. MT-only builds no longer require an MPI installation.- Installed library output name is flavor-tagged:
libgempba.afor mt,libgempba_mpi.afor mpi. Both flavors export the same imported target namegempba::gempba, so your link line never changes between modes. - Per-flavor
pkg-configfile:gempba.pcfor mt,gempba-mpi.pcfor mpi.
v3.3.0
May 21, 2026
Runtime telemetry: process-wide hub with local / TCP / MPI transports, hwloc-backed topology probe, and a small set of read-only runtime accessors. Telemetry ships ON by default; opt out at runtime with gempba::telemetry::disable(). No API breaks.
Added
<gempba/telemetry/telemetry_hub.hpp>— process-wide telemetry hub that publishes worker / node frames and routes control messages. Singleton accessed viagempba::telemetry::get(); runtime kill switch viadisable()/enable()/is_enabled()(process-local, sticky, must be set symmetrically across MPI ranks)- Local in-process and TCP server transports; TCP binds
127.0.0.1:9000by default (configure_port()to change before the firstcreate_*call) - MPI transport on a private communicator (
MPI_Comm_dup) so telemetry traffic never collides with application traffic; auto-installed insidemp::create_schedulerso the collective install runs on every rank - hwloc-backed topology probe: per-socket physical / logical core counts, total memory, CPU brand, cpu-id list; multi-node topology assembled via
MPI_Allgatherof theworker_identityPOD - JSON serializer for telemetry frames; client-pushed interval-control protocol over the TCP socket so dashboards can throttle publish rate live
- Read-only runtime accessors:
gempba::try_get_scheduler(non-throwing variant ofget_scheduler),load_balancer::get_thread_pool_size,load_balancer::get_tasks_running_count,scheduler::get_pending_request_count scripts/connect_telemetry.sh— SSH-tunnel helper for inspecting a remote rank's telemetry socket from a local dashboard
Changed
- Default thread-pool size when no explicit size is set is now
1(was one-per-core viaBS::thread_pool's default). The concretequasi_horizontal_load_balancerandwork_stealing_load_balancerimpls constructBS::thread_pool<>{1}explicitly. Users who relied on the implicit default should pass the size explicitly through their scheduler init
Fixed
- Exported
gempbaConfig.cmakenow re-discovers hwloc behindGEMPBA_HWLOC, so downstreamfind_package(gempba)consumers resolvePkgConfig::HWLOCat link time instead of failing withtarget not found(latent since hwloc became a PRIVATE link dep on a STATIC library) mpi_semi_centralized_schedulerdouble-countedm_sent_task_count— increments fired on two paths for the same dispatch; consolidated to a single ownership point so the stats visitor and telemetry'srecord_sendsee consistent values
Build
- hwloc is a new runtime dependency, gated by the
GEMPBA_HWLOCCMake option (ON for releases, OFF for dev builds). Discovered viapkg-configon all three platforms;.deband MSYS2 packages declare it as a runtime dep - CI installs hwloc on Ubuntu 24.04 / macOS 26 / Windows 2025 (MSYS2) / lint runners
build_*.shscripts forwardGEMPBA_HWLOCso packagers can disable hwloc cleanly- Windows builds link
psapi(process-info probe) andws2_32(Winsock for the TCP server)
v3.2.0
May 21, 2026
CI hardening and release-flow automation. No library API or behavior changes.
Fixed
publish-apt-repono longer depends on the GitHub CLI being on the runner image — it consumes the.debfrom the same workflow's artifact instead ofgh release download, so self-hosted Linux runners can publish on tag pushes again
Build
BS::thread_poolpinned to release tagv5.1.0.1instead of trackingmasterfor reproducible builds- CI
clang-tidybumped from 18 to 19;bugprone-throwing-static-initializationenabled —debug_logger_initializer's ctor is nownoexceptwith thespdlogcalls wrapped intry/catch, preserving the static-init injection contract while making it honest update-pkgbuild.shaccepts-r / --remoteto select which git remote's tag to hash against (defaults toorigin); useful when cutting a release pointed at the public repo- New
Prepare releaseworkflow (workflow_dispatch): branchesprep/v<version>from the resolved target branch, bumpsCMakeLists.txt+packaging/msys2/PKGBUILD, draftsdocs/releases/release-notes-v<version>.mdfromgit log, and opens the prep PR. Auto-detects the target branch (or accepts atarget_branchinput /vars.RELEASE_TARGET_BRANCHoverride) so the same workflow runs on forks with onlymainand on forks with bothmainandrelease - New
Post-tag PKGBUILD sha256 cleanupworkflow (push tags: v*): replaces the prep PR's'SKIP'placeholder with the real sha of the source tarball; opens a follow-up PR. Auto-resolves the target branch via tag-commit reachability when bothmainandreleaseexist - New
set-release-bodyjob inc-cpp-ubuntu.yml: applies the curateddocs/releases/release-notes-v<tag>.mdto the GitHub Release body viagh release edit --notes-file; fails loudly if the notes file is missing so no tag ships without curated notes - New
setup-gh-clicomposite action: pinnedghon PATH for self-hosted Linux runners; no-op on github-hosted runners whereghis pre-installed
v3.1.1
May 19, 2026
Post-v3.1.0 hygiene release: packaging metadata, coverage scope, CI workflow polish, a test-coverage push, cross-platform fixes, and toolchain bumps. No public API changes.
Changed
gempba::create_custom_nodenow takes astd::shared_ptr<node_core>directly (no more wrapping at the call site)wall_timereimplemented on top ofstd::chrono(replacesgettimeofday) — same observable values, monotonic clock semanticsgempba::log_and_throwmarked[[noreturn]]so static analyzers and the compiler's flow analysis understand the call never returnsscore: cleaned up thekind/to_raw/from_rawpaths and added explicitunreachablemarkersnode_core_impl: lazy-init and result paths consolidated; redundant explicit destructor onnoderemoved; excessive debug logging trimmed- Codebase-wide
clang-tidyidentifier-naming pass (private members and locals only — no public API renames)
Removed
- Dead
prune()overload inwork_stealing_load_balancer - Unreachable defensive checks in
get_root_level_pending_node
Fixed
gempba::utils::get_nb_set_bitssigned-charoverflow on MinGW- MSYS2/MinGW build:
<windows.h>is now included before<psapi.h>sopsapi.hsees the types it needs centralized_utils.hpp:NOMINMAXredefinition guarded so headers that already define it don't trigger a warningnode.hpp:<stacktrace>inclusion gated on the__cpp_lib_stacktracefeature test, not just__has_include
Build
- MSYS2
PKGBUILDsha256updated to match the v3.1.0 source tarball - Codecov reporting now excludes
examples/,tests/, andexternal/so coverage numbers reflect only library code - New
clang-tidyandclang-formatidentifier-naming and configuration rules so future changes can't reintroduce the patterns just cleaned up - Ubuntu CI bumped to GCC 14;
<stacktrace>andstdc++explinkage gated accordingly so older toolchains still build the library - macOS CI defaults to the
macos-26runner image - Self-hosted runners are now matched by label set (multiple labels combined) rather than a single label
- MS-MPI runtime installed on the Windows CI runner so the multiprocessing test set actually runs
clang-formatdiagnostics surfaced with the colored summary;lint.shdiagnostics made readable on the terminal- Skip the
publish-test-resultsjob when the upstream build was cancelled runs-oninjected fromvars.RUNNER_*repository variables so runner targets can change without editing each workflow- New full-coverage tests for the
gempbafacade,node_manager,quasi_horizontal_load_balancer,work_stealing_load_balancer,node_core_impl,centralized_utils, plus branch coverage forqueue,utils,score, andnode - Thread pool readiness ordering tightened in throw/discard tests so the
send()race no longer deflakes them - Dropped flaky peak-vs-current RSS comparisons from the memory-usage tests
-Wunusedwarnings silenced on header-only helpers
v3.1.0
April 19, 2026
macOS support, system packaging (.deb, MSYS2, signed APT repo), and cross-platform portability fixes.
Breaking changes
gempba::Queuerenamed togempba::queue(header moved toinclude/gempba/utils/queue.hpp) — update any direct uses- Bundled
spdlogremoved; consumers must now provide a system-installedspdlog(andfmt) viafind_package GEMPBA_*build options (GEMPBA_MULTIPROCESSING,GEMPBA_BUILD_TESTS,GEMPBA_BUILD_EXAMPLES,GEMPBA_DEBUG_COMMENTS,GEMPBA_DEV_MODE) now honor-Doverrides when used as a subproject — previously hard-coded values shadowed user input
Added
- macOS officially supported (Apple Silicon, AppleClang/libc++, Homebrew Boost 1.90)
- Debian/Ubuntu
.debpackages (libgempba-dev) published on tagged releases - Signed APT repository at
apt-repo/withpubkey.gpgforapt-get install libgempba-dev - MSYS2
PKGBUILDatpackaging/msys2/formingw64/ucrt64/clang64builds, with a Windows CI publish job producing.pkg.tar.zstartifacts - CMake install rules and
gempbaConfig.cmake— consumers can nowfind_package(gempba 3.1.0 REQUIRED)and linkgempba::gempba - pkg-config file (
gempba.pc) for non-CMake build systems scripts/update-pkgbuild.shto regeneratepkgverandsha256for MSYS2 packagers
Changed
- README rewritten and trimmed; full reference moved to the docs site
- Build/run scripts relocated under
scripts/(build_linux.sh,build_windows.sh,run.sh, etc.); old top-levellinux_build.sh/win_build.shremoved -rdynamicis now applied only on Linux Debug builds (no longer leaks into Release or non-Linux targets)- CPM.cmake download hardened against silent corruption
Fixed
mpi_centralized_scheduler: misplaced parenthesis in theMPI_Wtime/diff_timecomparison broke the rate-limit on "center queue full" notifications, causing repeated worker contacts every loop iteration instead of at most once per second<bits/stdc++.h>removed fromnode_manager.hpp— header now compiles on libc++ / AppleClang / MSVC- C++23
<stacktrace>gated on__has_includeso libc++ targets without it still build gempba::scoretype-dispatch, comparison, andto_stringmade portable acrosslong doubleABIs- Dropped
-fconcepts(legacy GCC flag) and gatedstdc++expfor non-Linux toolchains BS_thread_poolinclude directory now propagated so private headers compile against installed packages<gempba/config.h>resolves correctly in all build layouts (now generated intobuild/gempba/)
Removed
- Private
node_managermethod that always returned zero (worker view returns zero directly)
v3.0.0
December 7, 2025
The largest release in the project's history: a ground-up redesign that replaces the heavy template-driven API with a single-header gempba:: facade. branch_handler becomes node_manager, the entire pre-v3 surface (result_holder, dynamic_load_balancer_handler, Pool, args_handler, all *2-suffixed members) is removed, and the public surface is reorganized under include/gempba/.
Breaking changes
gempba::branch_handlerrenamed togempba::node_manager(class and header) — the main user-facing classgempba::ResultHolder/gempba::result_holderremoved entirely; usegempba::nodeinstead — function signatures no longer take a holder templategempba::DLB_Handler/gempba::dynamic_load_balancer_handlerremoved; usegempba::load_balancer(interface) and the newcreate_load_balancerfactoriesgempba::Poolandgempba::args_handlerremoved- All
*2-suffixed members removed:is_done2,wait2,get_balancing_policy2, plus*2variants in MPI schedulers node_manager::lock()/unlock()removednode_managermember renames:try_push_mp→try_remote_submit,try_push_mt→try_local_submit,force_push→force_local_submit,push_multiprocess/push_multithreading→send,WTime→get_wall_time,try_top_holder→try_push_root_level_holder_remotely,pass_mpi_scheduler→pass_scheduler- Identifier renames on the public surface:
load_balancing_strategy→balancing_policy,print_mpi_debug_comments→print_ipc_debug_comments,FUNCTION_ARGS→TASK,gbitset→G_BITSET, "reference value" →scorethroughout MPI schedulers mpi_schedulerrenamed tompi_semi_centralized_schedulerschedulermembers supplanted byscheduler::worker/scheduler::centerviews:fetch_solution,fetch_result_vector,next_process,push,run_node,run_center,try_open_transmission_channel,close_transmission_channelscheduler::get_total_requestsremoved (now sourced from the new stats interface)- C++23 enforced in CMake (
CMAKE_CXX_STANDARD 23,CMAKE_CXX_STANDARD_REQUIRED ON, extensions off); C++20 compilers are no longer supported BS::thread_poolis now an external dependency; consumers using CPM mirror it automatically, manual integrations must add itGEMPBA_*compile definitions on thegempbatarget are nowPRIVATEinstead ofPUBLIC- Public headers reorganized under
include/gempba/(core/,utils/,stats/,defaults/,detail/); legacyinclude/utils/...paths are gone - Legacy
.csv/.datraw printing removed from examples; CSV log is now opt-in and off by default
Added
- Single-header facade
#include <gempba/gempba.hpp>exposinggempba::factories gempba::node— lightweight, copyable, template-free node handle (replacesresult_holder)gempba::shutdown()for explicit, controlled global cleanupgempba::node_managerfactories:multithreading::create_node_manager(load_balancer*)andmultiprocessing::create_node_manager(load_balancer*, scheduler::worker*)gempba::load_balancerpublic interface with two stock implementations:quasi_horizontal_load_balancer(recommended) andwork_stealing_load_balancermultithreading::create_load_balancer(balancing_policy)andmultiprocessing::create_load_balancer(balancing_policy, scheduler::worker*)factories, plus a BYO-implementation overloadgempba::schedulerpublic interface withscheduler::workerandscheduler::centerviews,scheduler_traits, andmultiprocessing::create_scheduler(scheduler_topology, timeout)(SEMI_CENTRALIZED,CENTRALIZED)gempba::node_coreextension point (include/gempba/core/node_core.hpp) plusnode_traitsand thedetail/nodes/node_core_impl.hpptemplate implementationgempba::statsandgempba::stats_visitorinterfaces;default_mpi_stats_visitorfor the bundled MPI schedulers (visitor pattern, string-keyed metrics)gempba::serial_runnableinterface withserial_runnable_void/serial_runnable_non_voidimpls andrunnables::return_none::create/runnables::return_value::createhelpers for MP task dispatchgempba::serializableinterface to split serialization responsibilities out of node tracegempba::task_bundleandgempba::transmission_guardutilities underinclude/gempba/utils/invokableC++23 concept that enforces task signatures of the formRet(std::thread::id, Args..., node)gempba::scoreextended withuint32_tandint64_tso it can carrystd::size_tand other common types; spaceshipoperator<=>ontask_packetutils::log_and_throw(replaces directspdlog::throw_spdlog_ex) with C++23<stacktrace>integration- Generated
gempba/config.h(fromconfig.h.in) so IDEs see the build flags - Multi-processing and multi-threading benchmark cases
- One-call Windows and Linux build scripts and helpers to run all graphs in a directory
Changed
- Module renames swept the codebase to snake_case:
BranchHandler→branch_handler(thennode_manager),ThreadPool→thread_pool,DLB→dynamic_load_balancer,MPI_Modules→schedulers,Resultholder→result_holder(then removed) gempba::scorenow has unsigned 32/64 specializations;score::make(...)acceptsstd::size_t- Schedulers now receive their timeout at construction (
create_scheduler(topology, timeout)) default_mpi_stats_visitorlives in thedefaultsmodule and is exposed viamultiprocessing::get_default_mpi_stats_visitor()- Internal
spdlog::infocalls demoted tospdlog::debug #ifdef GEMPBA_DEBUG_COMMENTSreplaced with#if GEMPBA_DEBUG_COMMENTS(matches the newcmakedefine01)- README rewritten for v3.0 (facade pattern, extensible architecture, updated requirements, Windows added to supported platforms)
Fixed
- Race condition that could let a worker thread throw
- Edge case in node pruning (children weren't cleared on prune)
- Critical guard fix in
quasi_horizontal_load_balancer
Build
- C++23 enforced (
CMAKE_CXX_STANDARD_REQUIRED ON,CMAKE_CXX_EXTENSIONS OFF) - Links
stdc++expon non-MSVC for C++23<stacktrace>support - New
GEMPBA_DEV_MODEtoggle in the rootCMakeLists.txt(auto-on when gempba is the root project) GEMPBA_*target flags scoped toPRIVATE(no longer leaks to consumers)BS::thread_pooladded via CPM (rapastranac/thread-pool);argparsemoved toexamples/externalsince it's only used by examplesGIT_SHALLOW TRUEset on CPM external clones- Per-test discovery in CTest (
gtest_discover_tests) and a separate test-artifact publish job in CI;FLAKY_test-name convention for flaky cases - Dropped redundant
git installstep from CI
v2.1.1
September 1, 2025
Single-fix patch release for the centralized MPI scheduler.
Fixed
mpi_centralized_schedulerworkerprobe_reference_value_comm()was probingREFVAL_PROPOSAL_TAG(the worker-to-center tag) instead ofREFVAL_UPDATE_TAG, so global reference-value updates broadcast by the center were never picked up by workers — leaving them with stale bounds and exploring branches that should have been pruned (#55)
v2.1.0
August 23, 2025
Source-level Windows support, alongside a dedicated Windows CI pipeline.
Added
- Windows build support: GemPBA now compiles on Windows with MSVC
run.ps1PowerShell launcher at the repo root for running multiprocessing (mpiexec.exe) and multithreading example binaries on Windows- Windows CI workflow (
.github/workflows/c-cpp-windows.yml) building on Windows Server 2022, with a matching status badge in the README
Changed
centralized_utils.hppnow definesNOMINMAX,WIN32_LEAN_AND_MEAN, andRPC_NO_WINDOWS_Hbefore includingwindows.hto avoidstd::byteambiguity andmin/maxmacro clashes against<windows.h>score::makefactory dispatches by integral size (int32_t/int64_t) instead of exact type, so scores constructed fromlongand other platform-dependent integer widths behave the same on Windows and Linux- Ubuntu workflow renamed from
c-cpp.ymltoc-cpp-ubuntu.yml(Ubuntu 24.04); README badge updated accordingly args_handler.hppswitched to angle-bracket includes and replacedstd::forward<nullptr_t>(nullptr)with a plainnullptrargument for portability
Fixed
- Corrected the closing namespace comment in
args_handler.hpp(} // namespace gempba)
Build
- Test executable renamed from
all_tests.outtoall_tests(drops the Linux-style suffix so the same target name works on Windows)
v2.0.0
August 17, 2025
Major release: new gempba::score, gempba::task_packet, and gempba::result public types replace string-based transport and the int reference value, alongside a sweeping clang-tidy rename of the public API (BranchHandler → branch_handler, MPI_Scheduler → mpi_scheduler, SchedulerParent → scheduler_parent, etc.).
Breaking changes
gempba::BranchHandler→gempba::branch_handler;getInstance()→get_instance();try_push_MT→try_push_mt; member methods renamed per.clang-tidy(e.g.refValue()is gone — useget_score().get<T>())gempba::MPI_Scheduler→gempba::mpi_scheduler;gempba::MPI_SchedulerCentralized→gempba::mpi_centralized_scheduler(headerMPI_Scheduler_Centralized.hpp→mpi_centralized_scheduler.hpp)gempba::SchedulerParent→gempba::scheduler_parent;fetchSolution()→fetch_solution()now returnstask_packetinstead ofstd::string;fetchResVec()→fetch_result_vector()returnsstd::vector<gempba::result>instead ofstd::vector<std::pair<int, std::string>>;push()now takes atask_packet&&instead ofstd::stringbranch_handler::set_score/get_score/set_goaland thegempba::resultconstructor:intreference value replaced withgempba::score.set_goalnow takes agempba::goalenum plusgempba::score_type(was abool)hold_solutionremoved — replaced bytry_update_result(solution, score): type-safe, parameters reordered, default parameter dropped, returnsboolindicating whether the update happenedupdate_reference_value→try_update_reference_value; further renamed totry_update_reference_value_and_invalidate_resultto reflect that it now clears any cached result when the score changesscore::get_looseremoved — usescore::to_string(logs print the value with its real underlying type) or the typedscore::get<T>()accessorset_ref_val_strategy_lookup→scheduler_parent::set_goal;lookup_strategyparameter →goalenumEMPTY_RESULTconstant removed — useresult::EMPTYm_reference_valuemember ofgempba::resultrenamed tom_score; scheduler membersm_ref_value_global→m_global_reference_value(and corresponding communicator member)- Examples no longer accept the
THREADS_PER_TASKargument on the command line GEMPBA_MULTIPROCESSINGis now a value macro (0/1), no longer a bare definition — examples and downstream consumers must use#if GEMPBA_MULTIPROCESSINGinstead of#ifdef
Added
gempba::task_packet(include/utils/ipc/task_packet.hpp) — raw-byte transport that replaces serializedstd::stringin the scheduler API; serializers now returntask_packetgempba::result(include/utils/ipc/result.hpp) — bundles ascoreplustask_packetfor shipping solutions between ranksgempba::score(include/utils/ipc/score.hpp) andgempba::score_typeenum (I32,I64,F32,F64,F128) — multi-primitive score support, formerly the integer-onlyreference_value(suggested by @Manuel-GithubAccount in #29)gempba::goalenum to replace the previous boolean min/max strategy flagscore::makefactory andscore::to_stringfor type-aware logging- README "Concepts" section documenting
goal,score, andscore_type
Changed
- Schedulers now exchange raw bytes (
task_packet) instead of serialized strings end-to-end throughbranch_handlerandscheduler_parent mpi_schedulerandmpi_centralized_schedulermade structurally parallel: sharedshould_broadcastlogic,utils::diff_timeadopted in both, analogous global-reference-value checkshandle_full_messaging→monitor_and_notify_center_status- Most
GEMPBA_DEBUG_COMMENTSmacro sites replaced with a single utility method - README updated for all renamed identifiers and the new
try_update_result/scoreusage batch.sh→run.sh
Fixed
- Communicator probing in
mpi_centralized_scheduler(matching the fix already inmpi_scheduler) openmpiinvocation now binds processes to the intended number of cores- A
try_update_resultpath that wasn't actually updating the stored reference value GEMPBA_MULTIPROCESSINGchecks (#49): switched from#ifdefto#if, and the macro is now injected as an explicit0/1value so non-MP examples see it defined as false rather than undefined
Build
CMakeLists.txtproject version bumped to2.0.0examples/CMakeLists.txt: definesGEMPBA_MULTIPROCESSING=1formp_*examples andGEMPBA_MULTIPROCESSING=0for the rest (previously only themp_*side was defined)
v1.1.0
August 4, 2025
Citation metadata, a refreshed README, and dependency-management changes that consumers need to mirror.
The git tag is
v.1.1.0(extra dot — original spelling preserved). Everywhere else the version is referred to asv1.1.0.
Added
CITATION.cffandCITATION.bibat the repo root for academic citation- README sections for Requirements, Platforms, Dependency Management, Copyright and citing
FUNCTION_ARGStag for routing serialized function arguments separately from other messagesREFERENCE_VAL_PROPOSALandREFERENCE_VAL_UPDATEtags (split from the former single reference-value tag)
Changed
- Inter-process tags in
MPI_Modules/MPI_Scheduler.hppare now anenum tags { ... }(CENTER_NODE,RUNNING_STATE,ASSIGNED_STATE,AVAILABLE_STATE,TERMINATION,REFERENCE_VAL_PROPOSAL,REFERENCE_VAL_UPDATE,NEXT_PROCESS,HAS_RESULT,NO_RESULT,FUNCTION_ARGS) replacing the previous#definemacros (STATE_RUNNING,STATE_ASSIGNED,STATE_AVAILABLE,TERMINATION_TAG,REFVAL_UPDATE_TAG,NEXT_PROCESS_TAG,HAS_RESULT_TAG,NO_RESULT_TAG); consumers relying on the old macro names must rename to the enum values - README installation walkthrough moved above the description; CMake snippet now sets
GEMPBA_MULTIPROCESSING,GEMPBA_DEBUG_COMMENTS,GEMPBA_BUILD_EXAMPLES,GEMPBA_BUILD_TESTScache variables and linksgempba::gempba
Fixed
examples/include/VertexCover.hppinclude switched fromfmt/core.hto<format>(matches the C++20 toolchain)
Build
- CMake project version bumped to
1.1.0 spdlogremoved from core CMake:find_package(spdlog REQUIRED)andspdlog::spdloglink are gone; consumers add it via CPM inexternal/CMakeLists.txt(pinned togabime/spdlog@1.15.1, built static)argparseCPM entry rewritten in long form (NAME argparse / GITHUB_REPOSITORY p-ranav/argparse / VERSION 3.0);external_libsnow also exportsspdlogexamples/CMakeLists.txtsetsBoost_USE_STATIC_LIBS ONso Boost is linked statically into the example binaries
v1.0.2
June 7, 2025
Easier external integration: GemPBA is now a consumable CMake library with a gempba::gempba target, a hook to inject a custom initial process topology, and CPM-based dependency fetch.
Added
gempba::gempbaALIAS target so consumers cantarget_link_libraries(... gempba::gempba)SchedulerParent::set_custom_initial_topology(tree&&)to inject a custom initial process topology- New CMake options
GEMPBA_BUILD_TESTSandGEMPBA_BUILD_EXAMPLES(defaultOFFwhen used as a subproject) - New CMake options
GEMPBA_MULTIPROCESSINGandGEMPBA_DEBUG_COMMENTSto drive compile-time macros from the build wall_time,diff_time,shift_leftutility functions inutils/utils.hppbuild_topologyextracted fromMPI_Schedulerintoutils/utils.hpp- Public
treetype atinclude/utils/tree.hpp(replacesMPI_Modules/Tree.hpp) - README section documenting CPM-based integration into a downstream project
- Filename is now included in "file not found" exception messages
Changed
- GemPBA now builds as a CMake library; examples and tests are separate subprojects gated by the new options
- Public include roots are
${workspace}/includeand${workspace}/GemPBA, exported viatarget_include_directories(BUILD_INTERFACE) - Macro renames:
MULTIPROCESSING_ENABLED→GEMPBA_MULTIPROCESSING;DEBUG_COMMENTS→GEMPBA_DEBUG_COMMENTS(consumers must update guards andtarget_compile_definitions) BranchHandlerAPI renamed to snake_case:setLookupStrategy→set_lookup_strategy,setLoadBalancingStrategy→set_load_balancing_strategy,getLoadBalancingStrategy→get_load_balancing_strategy- Enum types renamed:
LookupStrategy→lookup_strategy,LoadBalancingStrategy→load_balancing_strategy(enumerator names likeMAXIMISE,MINIMISE,QUASI_HORIZONTALare unchanged) scheduler_parent.hppnow includes<mpi.h>(wasmpi/mpi.h); fixes builds on MPI distributions that don't expose thempi/prefixargparseis now fetched via CPM instead ofFetchContent_Declare- Verbose
spdlog::infocalls in production code demoted tospdlog::debug - Project version bumped to 1.0.2; release built against C++23 (
CMAKE_CXX_STANDARD 23) - Default build type is
Debugwhen GemPBA is the root project, inherited from the parent otherwise - README rewritten with shields.io markdown badges; licence and version badges fixed
Removed
Boost(system,serialization,fiber) is no longer linked or required by the library target; consumers no longer need to provide itGTestis no longer required to build the library; it is now only needed whenGEMPBA_BUILD_TESTS=ON- Legacy headers
GemPBA/MPI_Modules/Tree.hpp,GemPBA/utils/Queue.hpp,GemPBA/utils/utils.hpp(replaced by their counterparts underinclude/utils/)
Fixed
- Source-file detection in the root
CMakeLists.txt - Hard-coded
-O0debug flags andadd_definitions(-DDEBUG_COMMENTS)no longer leak into Release builds; flags are now per-configuration via generator expressions
Build
clang-tidyandclang-formatconfigurations added at the repo root.vs/andCMakeSettings.jsonadded to.gitignore
v1.0.1
October 30, 2024
Restructured layout, C++23 build, typed strategy enums, and a scheduler base class so the semicentralized and centralized schedulers can coexist.
Added
gempba::SchedulerParent(MPI_Modules/scheduler_parent.hpp) — common abstract base forMPI_Schedulerand the centralized scheduler so both can be instantiated independentlygempba::ResultHolderParent(Resultholder/ResultHolderParent.hpp) — non-template base forResultHolderso virtual interfaces no longer leak template parametersgempba::LoadBalancingStrategyenum (QUASI_HORIZONTAL,WORK_STEALING) andgempba::LookupStrategyenum (MAXIMISE,MINIMISE) inutils/gempba_utils.hppBranchHandler::setLoadBalancingStrategy/getLoadBalancingStrategyBranchHandler::setLookupStrategy(gempba::LookupStrategy)— typed replacement for the string-keyword setterBranchHandler::getWorldRankDLB_Handler::getRoot(int threadId)THIRD-PARTY-LICENSESfile with CPTL credits (Apache 2.0)
Changed
- C++ standard bumped to C++23 (
CMAKE_CXX_STANDARD 23); minimum CMake bumped to 3.28 - Project layout reorganized: per-example executables under
bin/, examples and tests in dedicated trees, headers underGemPBA/utils/(wasGemPBA/Utils/) - Build now produces one executable per file under
examples/; sources matchingmp_*get-DMULTIPROCESSING_ENABLEDautomatically - The library is now built as a CMake target named
gempba(was a singlea.outexecutable) MPI_ENABLEDcompile macro renamed toMULTIPROCESSING_ENABLEDR_SEARCHmacro removed; load-balancing strategy is now a runtime enum onBranchHandler(so misuse becomes a compile error rather than a silent macro miss)- Centralized scheduler class renamed from
GemPBA::MPI_Scheduler(inMPI_Scheduler_Centralized.hpp) togempba::MPI_SchedulerCentralized, allowing both schedulers to be linked into the same binary - Public namespace renamed from
GemPBAtogempba(all classes and free functions moved) MPI_Scheduler::rank_me,elapsedTime,getWorldSize,tasksRecvd,tasksSent,nextProcessare nowconst;runNodesignature changed to takestd::functioncallbacks (no longer a templated lambda accepting aserializer)SchedulerParent::getTotalRequestsreturnssize_t(wasdoubleon the prior centralized scheduler)- Input data directory renamed from
input/todata/ - Logging migrated from
fmttospdlog(which uses fmt internally); debug prints go throughutils::print_mpi_debug_comments - README updated for the new namespace, strategy enums, and centralized-scheduler usage
Removed
BranchHandler::setRefValStrategyLookup(std::string)— replaced bysetLookupStrategy(gempba::LookupStrategy)R_SEARCHcompile-time flag
Build
- Root
CMakeLists.txtrewritten:find_package(spdlog REQUIRED)andfind_package(GTest REQUIRED)added; resources globbed recursively fmtdropped as a direct FetchContent dependency (pulled in transitively via spdlog)argparseFetchContent pin bumped from v2.9 to v3.0- Boost components
system,serialization,fiberlinked per-target via importedBoost::*targets instead ofCMAKE_EXE_LINKER_FLAGS - Tests promoted to a top-level
tests/subdirectory with its own CMake project, linking GTest/GMock and Boost;enable_testing()andadd_testregistered - New
.github/workflows/c-cpp.ymlCI pipeline triggered on pushes/merges tomain - Executable output directory moved to
${CMAKE_SOURCE_DIR}/bin
Fixed
- CMake resource discovery now recurses into subdirectories
- OpenMP made visible to the test target
- spdlog fetch / link wiring corrected
- Several macro-guarded code paths that broke when
MPI_ENABLEDwas off
v1.0.0
April 8, 2024
Initial stable release of GemPBA — a generic message-passing branch-and-bound framework for distributed C++ workloads.