Run the restarts to the hard deadline and give FlowCutter the reserve - #52
Merged
Conversation
…eserve The portfolio's soft deadline stopped the sampled restarts and the hedge's weighted stages, and the trailing FlowCutter candidate then had the whole second stage of the window to itself. On residuals small enough for the expensive orders, more restart time lowers width on far more graphs than a longer FlowCutter tail does, so the restart phase now runs to the hard deadline less a 1.5 second reserve and FlowCutter runs in the reserve. The initial candidates keep the soft deadline. So do the restarts on a residual above the 10,000 vertex cutoff, and on any run with no hard deadline; the soft deadline also stands where the reserve would fall before it, on a hard window shorter than the reserve. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two candidates could end past the hard deadline, which left the caller no time to write the decomposition. On a 1,728-vertex primal graph under a 4.75-second budget the restarts ran to their 8-second stop, the trailing FlowCutter candidate returned at 9,626 ms against a 9,500 ms hard deadline, and the result was lost. The backend tests its deadline between restarts, so it returns up to one restart after the timeout it was handed. The candidate now takes what is left of the hard window less one estimated restart, from the same work-unit model the metered path charges the backend with, and both the too-short window check and the too-large graph check are made against that window. The restart loop starts one more restart only while what the previous one cost still fits before the restart deadline and the hard deadline. A restart that runs into its deadline is stopped part-way and leaves nothing behind, so the time is better left to the FlowCutter candidate. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…er SIGTERM The trailing FlowCutter candidate was given the hard window less one restart at the work model's own rate. On a machine running one solve per core a restart costs several times that, so the candidate returned after the deadline it was sized for and the caller had no time to write the result. On a 1,728-vertex primal graph under a 4.75-second budget, 11 of 16 copies run side by side on a 32-core box were killed at the ten-second wall with nothing written; the one copy run alone returned 206 ms past its window. The reserve is now two estimated restarts, which covers the restart the backend can return late plus copying the result out of it a bag at a time, and it is taken at the rate the run has actually been going: the wall time spent divided by the graph work charged, never below the model's own rate. Under an armed meter both numbers come from the same clock and the reserve is unchanged. `stop_flag` ends a run from outside it. Once set, every deadline check answers as an expired hard deadline does, in the vendored backend as well as in the Rust code, and the caller gets the best decomposition found so far. The command-line tool sets it from a SIGTERM handler that stores one byte and does nothing else, so a caller running the tool under a wall clock of its own still gets a decomposition rather than an empty file. That needs `libc` on Unix for `sigaction`; the library itself makes no platform call. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
guyvdbroeck
force-pushed
the
whole-wall-exp
branch
from
September 4, 2026 06:12
c8916e9 to
79edfcd
Compare
Every solver's row is remeasured on the field where each baseline runs at its documented best setting.
guyvdbroeck
marked this pull request as ready for review
September 4, 2026 16:29
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.
On a residual at or under the threshold for the expensive orders, the restart
phase now runs to the hard deadline less a reserve for the trailing FlowCutter
candidate, not to the soft budget. The reserve is two estimated restarts scaled
by the rate the run has actually been going, so a loaded machine gets a bigger
reserve. The library also has a process-wide stop flag: once set, the deadline
checks answer as though the hard deadline had passed, and the separator loop and
the vendored backend read it too, the backend before its "we have a
decomposition" guard, so a run holding nothing is dropped. The command-line
tool sets the flag from a SIGTERM handler, so goatd writes its incumbent when
the harness stops it.
The reserve used to come from a fixed work-rate constant, the rate of an
unloaded machine, and the trailing candidate overran its window every time: on a
1,728 vertex primal graph, 206 ms over alone and 700 ms or more under load,
against a modelled restart of 172 ms. Under sixteen-way load, eleven of sixteen
runs of that graph were killed with nothing written; after the fix, ten returned
inside the deadline and two more wrote on the signal.
The only new public item is
stop_flag() -> &'static AtomicBool: store true tostop a solve, false before the next. No new builder methods.
PortfolioConfig::with_restarts_to_deadlineand--capped-restartskeep theirsignatures, but the restarts now end at the restart deadline rather than the
soft one. The handler adds a Unix-only
libcdependency the binary alone uses.Both arms on the field where each baseline runs at the setting its documentation
recommends:
Over the 9,413 selected graphs, against main: 876 narrower, 8,387 equal, 81
wider; coverage gained 3, lost none; total bag size at equal width 1,857 better
against 1 worse, and under width 100, 768 better against 6. The
identical-binary repeat moves 46 views one way and 75 the other, so the
direction is far outside it. Against the branch's previous revision the width is
a wash inside that spread, 60 narrower and 99 wider; what it buys is the two
recovered graphs and a wall edge falling from 373 to 322 at or past 9,500 ms.
#53 has merged; both tables here are measured on its corrected field. #50 and
#51 are still open and will each regenerate their table after this one merges.