diff --git a/tox.ini b/tox.ini index aaa6118..d149506 100644 --- a/tox.ini +++ b/tox.ini @@ -29,6 +29,25 @@ passenv = OMP_NUM_THREADS PATH LD_LIBRARY_PATH +# Work around Qiskit/qiskit#17213: with qiskit 2.6.0 installed, importing our +# extension fails on Linux with "cannot allocate memory in static TLS block". +# +# glibc sizes the per-thread TLS block at startup and keeps only a small surplus for +# libraries dlopen'ed afterwards that need initial-exec TLS. Every Python extension +# arrives that way, so they all draw on that surplus. qiskit 2.6.0's _accelerate grew +# from 736 to 1544 bytes of it (matrixmultiply 0.3.11 enabling AVX-512 kernels, which +# quadruple one thread-local buffer), which leaves too little for the libgomp our +# extension pulls in. The error names libgomp, but it is whoever asks last that fails. +# +# Raising the surplus restores the headroom. It is reserved per thread and only commits +# the pages actually used, so a generous value costs little. Drop this once 17213 is +# fixed upstream. +# +# Linux-only: this is a glibc mechanism, and macOS links libomp with no equivalent +# limit. Note glibc silently ignores an unrecognized tunable name, so a typo here looks +# like a working config. +setenv = + linux: GLIBC_TUNABLES = glibc.rtld.optional_static_tls=65536 extras = test commands = @@ -52,6 +71,9 @@ allowlist_externals = mpirun setenv = SBD_TEST_NPROCS = {env:SBD_TEST_NPROCS:2} + # setenv is replaced, not merged, in a child environment, so repeat the + # static-TLS headroom [testenv] sets; see the comment there. + linux: GLIBC_TUNABLES = glibc.rtld.optional_static_tls=65536 commands = mpirun -n {env:SBD_TEST_NPROCS} pytest --only-mpi {posargs}