Skip to content

Commit

Permalink
Merge pull request #14441 from rgommers/testhook-threadpoolctl
Browse files Browse the repository at this point in the history
ENH: TST: add a threadpoolctl hook to limit OpenBLAS parallelism
  • Loading branch information
tylerjereddy committed Dec 2, 2021
2 parents e5da8c3 + a659b84 commit c0815e3
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
python3.8-dbg -c 'import sys; print("Python debug build:", hasattr(sys, "gettotalrefcount"))'
python3.8-dbg -m pip install --upgrade pip 'setuptools<58.5' wheel
python3.8-dbg -m pip install --upgrade numpy cython pytest pytest-xdist pybind11
python3.8-dbg -m pip install --upgrade mpmath gmpy2==2.1.0rc1 pythran
python3.8-dbg -m pip install --upgrade mpmath gmpy2==2.1.0rc1 pythran threadpoolctl
python3.8-dbg -m pip uninstall -y nose
cd ..
- name: Building SciPy
Expand Down
1 change: 1 addition & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ stages:
pytest-env
pytest-timeout
pytest-xdist==1.34.0
threadpoolctl
displayName: 'Install dependencies'
# DLL resolution mechanics were changed in
# Python 3.8: https://bugs.python.org/issue36085
Expand Down
1 change: 1 addition & 0 deletions ci/azure-travis-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ steps:
pip install ${{parameters.other_spec}}
cython
gmpy2==2.1.0rc1
threadpoolctl
mpmath
pythran
pybind11
Expand Down
4 changes: 3 additions & 1 deletion doc/source/dev/core-dev/distributing.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ are:
- Pillow_ (for image loading/saving)
- scikits.umfpack_ (optionally used in ``sparse.linalg``)
- mpmath_ (for more extended tests in ``special``)
- pydata/sparse (compatibility support in ``scipy.sparse``)
- pydata/sparse (compatibility support in ``scipy.sparse``)
- threadpoolctl_ (to control BLAS/LAPACK threading in test suite)

*Unconditional build-time dependencies:*

Expand Down Expand Up @@ -221,3 +222,4 @@ Wheelhouse_, see at the wheel_ and Wheelhouse_ docs.
.. _six: https://pypi.org/project/six
.. _decorator: https://github.com/micheles/decorator
.. _manylinux: https://github.com/pypa/manylinux/
.. _threadpoolctl: https://github.com/joblib/threadpoolctl
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ dependencies:
# Some optional test dependencies
- mpmath
- gmpy2=2.1.0rc1
- threadpoolctl
3 changes: 3 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ ignore_missing_imports = True
[mypy-mpmath]
ignore_missing_imports = True

[mypy-threadpoolctl]
ignore_missing_imports = True

#
# Extension modules without stubs.
#
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ test = [
"asv",
"mpmath",
"gmpy2==2.1.0rc1",
"threadpoolctl",
"scikit-umfpack",
]
doc = [
Expand Down
35 changes: 35 additions & 0 deletions scipy/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from distutils.version import LooseVersion
import numpy as np
import numpy.testing as npt
from scipy._lib._fpumode import get_fpu_mode
from scipy._lib._testutils import FPUModeChangeWarning

Expand Down Expand Up @@ -39,6 +40,40 @@ def pytest_runtest_setup(item):
if mark is not None and np.intp(0).itemsize < 8:
pytest.xfail('Fails on our 32-bit test platform(s): %s' % (mark.args[0],))

# Older versions of threadpoolctl have an issue that may lead to this
# warning being emitted, see gh-14441
with npt.suppress_warnings() as sup:
sup.filter(pytest.PytestUnraisableExceptionWarning)

try:
from threadpoolctl import threadpool_limits

HAS_THREADPOOLCTL = True
except Exception: # observed in gh-14441: (ImportError, AttributeError)
# Optional dependency only. All exceptions are caught, for robustness
HAS_THREADPOOLCTL = False

if HAS_THREADPOOLCTL:
# Set the number of openmp threads based on the number of workers
# xdist is using to prevent oversubscription. Simplified version of what
# sklearn does (it can rely on threadpoolctl and its builtin OpenMP helper
# functions)
try:
xdist_worker_count = int(os.environ['PYTEST_XDIST_WORKER_COUNT'])
except KeyError:
# raises when pytest-xdist is not installed
return

if not os.getenv('OMP_NUM_THREADS'):
max_openmp_threads = os.cpu_count() // 2 # use nr of physical cores
threads_per_worker = max(max_openmp_threads // xdist_worker_count, 1)
try:
threadpool_limits(threads_per_worker, user_api='blas')
except Exception:
# May raise AttributeError for older versions of OpenBLAS.
# Catch any error for robustness.
return


@pytest.fixture(scope="function", autouse=True)
def check_fpu_mode(request):
Expand Down

0 comments on commit c0815e3

Please sign in to comment.