3.8.0 (under development) ========================= - Run faster on Linux, where the new `/proc/self/maps` mechanism in 3.7.0 added quite a bit of overhead. https://github.com/joblib/threadpoolctl/pull/250 - When OpenBLAS uses a non-OpenMP threading layer, you can only set the size of its thread pool from a single controlling thread; since it has a shared process-wide thread pool, having multiple Python threads fight over control wouldn't work well. A new API ``OpenBLASController.clear_controlling_thread()`` allows resetting which thread controlls OpenBLAS in these cases, and decorator and context manager limit APIs will automatically call that API when they are done. https://github.com/joblib/threadpoolctl/pull/275 https://github.com/joblib/threadpoolctl/pull/289 - Add a new API to get a cached `ThreadpoolController` instance (`get_cached_controller()`), as an optimization for cases where limits are set frequently. See the docstring for caveats. https://github.com/joblib/threadpoolctl/pull/257 https://github.com/joblib/threadpoolctl/pull/285 - Added official support for Python 3.15, and declared support for Python 3.14 in package metadata. https://github.com/joblib/threadpoolctl/issues/251 - Faster performance when creating a `ThreadpoolController`. https://github.com/joblib/threadpoolctl/pull/249 - Shared libraries are now cached across runs, whereas previously they would be unloaded after the `ThreadpoolController` was garbage collected. https://github.com/joblib/threadpoolctl/pull/249 - A single shared library can no longer have multiple `LibController` instances. https://github.com/joblib/threadpoolctl/pull/249 - When passing a list of dicts or a dict to `threadpool_limits(limit=...)` and related APIs, the `"filepath"` is used as the unique key identifying ``LibController``s, if available, falling back to ``"prefix"``. Previously the ``"prefix"`` was checked first. https://github.com/joblib/threadpoolctl/pull/278 - Fixed `limits="sequential_blas_under_openmp"`, which left all BLAS libraries unlimited as soon as OpenBLAS was loaded, whatever its threading layer, or a library used the OpenMP threading layer (e.g. BLIS). The limit is now only skipped when OpenBLAS uses the OpenMP threading layer, as documented. https://github.com/joblib/threadpoolctl/pull/283 - Dropped official support for Python 3.9. https://github.com/joblib/threadpoolctl/pull/255 3.7.0 (2026-09-15) ================== - Fixed an intermittent `OSError` on Windows when DLLs are loaded or unloaded concurrently during library discovery (for example when importing conda-forge OpenCV). On Python 3.14+, discovery uses `ctypes.util.dllist` when available. If `dllist` raises `OSError`, threadpoolctl emits a `RuntimeWarning` instead of crashing so the failure can be reported upstream with a minimal reproducer. Older Pythons use a Toolhelp snapshot enumerator, with graceful per-module fallbacks. https://github.com/joblib/threadpoolctl/pull/219 - Added the ability to check whether a limiting API affects just the current thread or the whole process. Mainly aimed at debugging and diagnostics, and somewhat unreliable, it is therefore enabled by default only for command-line usage. https://github.com/joblib/threadpoolctl/pull/213 - Only warn about simultaneous `libomp` and `libiomp` usage on Linux, where the incompatibility is known to cause crashes. https://github.com/joblib/threadpoolctl/pull/222 - Fixed a deadlock triggered by getting or setting MKL's number of threads from parallel threads when using MKL with libiomp (Intel threading) on Linux. https://github.com/joblib/threadpoolctl/pull/228 - Going forward, setting the number of threads will only have a thread-local impact if feasible (for example, at minimum the underlying library must support this option, and many don't.) https://github.com/joblib/threadpoolctl/pull/228 - For MKL, setting the number of threads is now thread-local, i.e. limiting the number of threads won't impact MKL's thread pool size when using MKL in other Python threads. https://github.com/joblib/threadpoolctl/pull/228 - For OpenBLAS compiled with OpenMP on Linux and macOS, setting the number of threads is now thread-local, i.e. won't impact OpenBLAS thread pool size in other Python threads. On Windows behavior is likely process-wide, but this may depend on how OpenBLAS was compiled with OpenMP. https://github.com/joblib/threadpoolctl/pull/228 - Fix OpenBLAS detection for conda package on Windows https://github.com/joblib/threadpoolctl/pull/240 - Fixed a deadlock on Linux when using threadpoolctl from multiple threads. https://github.com/joblib/threadpoolctl/pull/243 - Start using Python 3.14's built-in support for listing shared libraries. - On Linux, start using /proc/self/maps for listing shared libraries. - Avoid importing ``ctypes.util`` on Linux (and load libc with ``ctypes.CDLL(None)``) so ``threadpool_info()`` does not create libffi closures that can abort after ``os.fork()`` on some libffi builds. https://github.com/joblib/threadpoolctl/pull/242 3.6.0 (2025-03-13) ================== - Added support for libraries with a path longer than 260 on Windows. The supported path length is now 10 times higher but not unlimited for security reasons. https://github.com/joblib/threadpoolctl/pull/189 - Dropped official support for Python 3.8. https://github.com/joblib/threadpoolctl/pull/186 https://github.com/joblib/threadpoolctl/pull/191 3.5.0 (2024-04-29) ================== - Added support for the Scientific Python version of OpenBLAS (https://github.com/MacPython/openblas-libs), which exposes symbols with different names than the ones of the original OpenBLAS library. https://github.com/joblib/threadpoolctl/pull/175 3.4.0 (2024-03-20) ================== - Added support for Python interpreters statically linked against libc or linked against alternative implementations of libc like musl (on Alpine Linux for instance). https://github.com/joblib/threadpoolctl/pull/171 - Added support for Pyodide https://github.com/joblib/threadpoolctl/pull/169 3.3.0 (2024-02-14) ================== - Extended FlexiBLAS support to be able to switch backend at runtime. https://github.com/joblib/threadpoolctl/pull/163 - Added support for FlexiBLAS https://github.com/joblib/threadpoolctl/pull/156 - Fixed a bug where an unsupported library would be detected because it shares a common prefix with one of the supported libraries. Now the symbols are also checked to identify the supported libraries. https://github.com/joblib/threadpoolctl/pull/151 3.2.0 (2023-07-13) ================== - Dropped support for Python 3.6 and 3.7. - Added support for custom library controllers. Custom controllers must inherit from the `threadpoolctl.LibController` class and be registered to threadpoolctl using the `threadpoolctl.register` function. https://github.com/joblib/threadpoolctl/pull/138 - A warning is raised on macOS when threadpoolctl finds both Intel OpenMP and LLVM OpenMP runtimes loaded simultaneously by the same Python program. See details and workarounds at https://github.com/joblib/threadpoolctl/blob/master/multiple_openmp.md. https://github.com/joblib/threadpoolctl/pull/142 3.1.0 (2022-01-31) ================== - Fixed a detection issue of the BLAS libraires packaged by conda-forge on Windows. https://github.com/joblib/threadpoolctl/pull/112 - `threadpool_limits` and `ThreadpoolController.limit` now accept the string "sequential_blas_under_openmp" for the `limits` parameter. It should only be used for the specific case when one wants to have sequential BLAS calls within an OpenMP parallel region. It takes into account the unexpected behavior of OpenBLAS with the OpenMP threading layer. https://github.com/joblib/threadpoolctl/pull/114 3.0.0 (2021-10-01) ================== - New object `threadpooctl.ThreadpoolController` which holds controllers for all the supported native libraries. The states of these libraries is accessible through the `info` method (equivalent to `threadpoolctl.threadpool_info()`) and their number of threads can be limited with the `limit` method which can be used as a context manager (equivalent to `threadpoolctl.threadpool_limits()`). This is especially useful to avoid searching through all loaded shared libraries each time. https://github.com/joblib/threadpoolctl/pull/95 - Added support for OpenBLAS built for 64bit integers in Fortran. https://github.com/joblib/threadpoolctl/pull/101 - Added the possibility to use `threadpoolctl.threadpool_limits` and `threadpooctl.ThreadpoolController` as decorators through their `wrap` method. https://github.com/joblib/threadpoolctl/pull/102 - Fixed an attribute error when using old versions of OpenBLAS or BLIS that are missing version query functions. https://github.com/joblib/threadpoolctl/pull/88 https://github.com/joblib/threadpoolctl/pull/91 - Fixed an attribute error when python is run with -OO. https://github.com/joblib/threadpoolctl/pull/87 2.2.0 (2021-07-09) ================== - `threadpoolctl.threadpool_info()` now reports the architecture of the CPU cores detected by OpenBLAS (via `openblas_get_corename`) and BLIS (via `bli_arch_query_id` and `bli_arch_string`). - Fixed a bug when the version of MKL was not found. The "version" field is now set to None in that case. https://github.com/joblib/threadpoolctl/pull/82 2.1.0 (2020-05-29) ================== - New commandline interface: python -m threadpoolctl -i numpy will try to import the `numpy` package and then return the output of `threadpoolctl.threadpool_info()` on STDOUT formatted using the JSON syntax. This makes it easier to quickly introspect a Python environment. 2.0.0 (2019-12-05) ================== - Expose MKL, BLIS and OpenBLAS threading layer in information displayed by `threadpool_info`. This information is referenced in the `threading_layer` field. https://github.com/joblib/threadpoolctl/pull/48 https://github.com/joblib/threadpoolctl/pull/60 - When threadpoolctl finds libomp (LLVM OpenMP) and libiomp (Intel OpenMP) both loaded, a warning is raised to recall that using threadpoolctl with this mix of OpenMP libraries may cause crashes or deadlocks. https://github.com/joblib/threadpoolctl/pull/49 1.1.0 (2019-09-12) ================== - Detect libraries referenced by symlinks (e.g. BLAS libraries from conda-forge). https://github.com/joblib/threadpoolctl/pull/34 - Add support for BLIS. https://github.com/joblib/threadpoolctl/pull/23 - Breaking change: method `get_original_num_threads` on the `threadpool_limits` context manager to cheaply access the initial state of the runtime: - drop the `user_api` parameter; - instead return a dict `{user_api: num_threads}`; - fixed a bug when the limit parameter of `threadpool_limits` was set to `None`. https://github.com/joblib/threadpoolctl/pull/32 1.0.0 (2019-06-03) ================== Initial release.