diff --git a/CHANGES.md b/CHANGES.md index 1194fef1..673ddfc0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,12 @@ ``"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 + 3.7.0 (2026-09-15) ================== diff --git a/tests/test_threadpoolctl.py b/tests/test_threadpoolctl.py index fc2c491f..922d6e76 100644 --- a/tests/test_threadpoolctl.py +++ b/tests/test_threadpoolctl.py @@ -299,9 +299,11 @@ def test_get_params_for_sequential_blas_under_openmp(): params = controller._get_params_for_sequential_blas_under_openmp() - if controller.select( - internal_api="openblas", threading_layer="openmp" - ).lib_controllers: + if any( + lib_info["internal_api"] == "openblas" + and lib_info.get("threading_layer") == "openmp" + for lib_info in original_info + ): assert params["limits"] is None assert params["user_api"] is None diff --git a/threadpoolctl.py b/threadpoolctl.py index b883cae0..6f2da642 100644 --- a/threadpoolctl.py +++ b/threadpoolctl.py @@ -1054,9 +1054,12 @@ def _get_params_for_sequential_blas_under_openmp(self): This function takes into account the unexpected behavior of OpenBLAS with the OpenMP threading layer. """ - if self.select( - internal_api="openblas", threading_layer="openmp" - ).lib_controllers: + # select() matches any of its kwargs: chain two calls to require both. + if ( + self.select(internal_api="openblas") + .select(threading_layer="openmp") + .lib_controllers + ): # Don't change anything: OpenBLAS is already sequential by default when it # is called from an OpenMP parallel region, and limiting it would also # limit the OpenMP parallel regions of the calling thread.