Clamp GetThreadLimit by the live OpenMP thread limit#1224
Open
bnaras wants to merge 1 commit into
Open
Conversation
OpenFHEParallelControls::GetThreadLimit(n) returned min(n, machineThreads), where machineThreads is latched once from omp_get_max_threads() at static init and never refreshed. Every parallel hot region emits num_threads(GetThreadLimit(...)), and an explicit num_threads clause overrides the runtime OpenMP ICV -- so a post-init omp_set_num_threads(), including one made through OpenFHEParallelControls::SetNumThreads(), is silently ignored and the library cannot be capped to fewer threads in-process. Also clamp by the live omp_get_max_threads() so a runtime thread limit is honored on every platform. The added call is a cheap ICV read; when the runtime limit is left at the machine default the result is unchanged.
bnaras
force-pushed
the
pr/thread-limit-clamp
branch
from
July 19, 2026 14:42
d4ae500 to
a14924a
Compare
Author
|
Rebased onto |
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.
Summary
OpenFHEParallelControls::SetNumThreads(n)(and any other runtimeomp_set_num_threads(n)) is silently ignored by the library's parallel hotregions: the process keeps using every core. This makes it impossible to cap
OpenFHE to fewer threads once the library is loaded.
The cause is a one-line issue in
GetThreadLimit, and the fix is one line.The bug
GetThreadLimit(n)returnsmin(n, machineThreads), wheremachineThreadsislatched once from
omp_get_max_threads()at static-init (library load) andnever refreshed. Every parallel hot region is emitted as:
#pragma omp parallel for num_threads(OpenFHEParallelControls.GetThreadLimit(size))Per the OpenMP spec, an explicit
num_threads(...)clause overrides theruntime
nthreadsICV. So even after a caller sets the limit at runtime — viathe library's own
OpenFHEParallelControls::SetNumThreads(), which callsomp_set_num_threads()—GetThreadLimitstill returns the stalemachineThreads, and the region runs on all cores anyway. There is noin-process way to cap the library.
The fix
Also clamp by the live
omp_get_max_threads():The added call is a cheap ICV read. When the runtime limit is left at the
machine default,
GetThreadLimitreturns exactly what it did before — nofunctional change to an uncapped build.
Reproduction (measured, not inferred)
Both builds below are stock upstream
main(ed361af); the only difference isthis one-line patch. Same machine (16 cores), both call
OpenFHEParallelControls.SetNumThreads(2), and the reprex counts the threadsactually spawned by OpenFHE's exact
num_threads(GetThreadLimit(size))clause:
GetThreadLimit(32768)The capped run is slower (4.87 s vs 2.22 s) precisely because it now uses 2
cores instead of 16 — the cap is real.
Zero-dependency reproduction of the mechanism
No OpenFHE needed — this replicates the exact
num_threads(GetThreadLimit(n))pattern and counts threads before/after the one-line change:
On a 16-core machine this prints
UPSTREAM -> 16,PATCHED -> 2.Full library-level reproduction
A self-contained program that drives the real library (calls
OpenFHEParallelControls.SetNumThreads(2), counts the threads OpenFHE's hotregion spawns, and runs a heavy CKKS
EvalMultworkload) is attached asthread_cap_repro.cpp. Build it against a stock install and a patched installand run both; the numbers above are its output.
Compatibility
machine default.
omp_get_max_threads()is a per-region ICV read. If its cost is aconcern for very fine-grained regions, it can be cached with an explicit
refresh hook — happy to adjust to your preference.