Repository navigation
Give the static TLS block enough headroom for libgomp (backport #64) - #65
Merged
Merged
Conversation
Since qiskit 2.6.0 reached PyPI, every Linux CI job fails before running a test: importing our extension raises "cannot allocate memory in static TLS block" from libgomp, and the whole suite errors out. macOS is unaffected. glibc sizes the per-thread TLS block at startup and keeps only a small surplus for libraries dlopen'ed later that need initial-exec TLS. Every Python extension module arrives that way, so they all compete for that one surplus, and the library that fails is whichever asks last rather than whichever took the space. qiskit 2.6.0's _accelerate grew from 736 to 1544 bytes of it, which leaves too little for the libgomp we pull in afterwards. The growth is matrixmultiply 0.3.11 enabling its AVX-512 kernels, which quadruple one thread-local scratch buffer; it takes effect at rustc >= 1.89, and 2.6.0 also raised its MSRV to exactly that. Raising the surplus restores the headroom. It goes in tox.ini rather than the workflows so local runs get it too; passenv would only forward the variable when the caller already set it, which is no help in CI. tox replaces setenv rather than merging it in a child environment, so the mpi env repeats the setting. Measured on glibc 2.42: a single later dlopen can claim 1664 bytes of initial-exec TLS, so 2.6.0 clears it by about seven bytes once alignment is counted. That thin margin is why the same build fails in one environment and passes in another. Preloading libgomp also works, but only for libgomp, since it removes it from the queue without enlarging the surplus. Reported upstream as Qiskit/qiskit#17213; revert this once that is fixed. Assisted-by: Claude Opus 5 (cherry picked from commit ca78f4c)
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.
Every Linux CI job has been failing since qiskit 2.6.0 reached PyPI. Importing our extension raises
cannot allocate memory in static TLS blockfrom libgomp, so the whole suite errors out before a single test runs. macOS is unaffected.glibc sizes the per-thread TLS block at startup and keeps only a small surplus for libraries
dlopened afterwards that need initial-exec TLS. Every Python extension module arrives that way, so they all draw on that one surplus, and the library that fails is whichever asks last rather than whichever consumed the space — which is why the error names libgomp and not the actual cause.qiskit 2.6.0's
_accelerategrew from 736 to 1544 bytes of initial-exec TLS, leaving too little for the libgomp we pull in afterwards. The growth ismatrixmultiply0.3.11 enabling its AVX-512 kernels, which quadruple one thread-local scratch buffer. That path activates at rustc >= 1.89, and 2.6.0 also raised its MSRV to exactly that, so both changes had to land together.This raises the surplus via
GLIBC_TUNABLES. It goes intox.inirather than the workflows so local runs are covered too.passenvwould only forward the variable when the caller already set it, which is no help in CI. Note that tox replacessetenvrather than merging it in a child environment, so thempienv repeats the setting.Measured on glibc 2.42, x86-64: a single later
dlopencan claim 1664 bytes, so 2.6.0 clears it by roughly seven bytes once alignment is counted. A margin that thin is why the same build fails in one environment and passes in another. Preloading libgomp also works, but only for libgomp — it removes libgomp from the queue without enlarging the surplus, so anything else wanting initial-exec TLS stays exposed.Reported upstream as Qiskit/qiskit#17213, with the measurements. Revert this once that is fixed.
This pull request was drafted by Claude Opus 5 under my guidance.
This is an automatic backport of pull request #64 done by [Mergify](https://mergify.com).