Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-threadpoolctl for
openSUSE:Factory checked in at 2022-07-26 19:42:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-threadpoolctl (Old)
and /work/SRC/openSUSE:Factory/.python-threadpoolctl.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-threadpoolctl"
Tue Jul 26 19:42:04 2022 rev:5 rq:990867 version:3.1.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-threadpoolctl/python-threadpoolctl.changes
2021-10-20 20:24:24.145382450 +0200
+++
/work/SRC/openSUSE:Factory/.python-threadpoolctl.new.1533/python-threadpoolctl.changes
2022-07-26 19:42:06.977204832 +0200
@@ -1,0 +2,12 @@
+Sun Jul 24 08:40:55 UTC 2022 - Dirk M??ller <[email protected]>
+
+- update to 3.1.0:
+ * 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.
+
+-------------------------------------------------------------------
Old:
----
threadpoolctl-3.0.0.tar.gz
New:
----
threadpoolctl-3.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-threadpoolctl.spec ++++++
--- /var/tmp/diff_new_pack.l9i1ed/_old 2022-07-26 19:42:07.473128199 +0200
+++ /var/tmp/diff_new_pack.l9i1ed/_new 2022-07-26 19:42:07.481126963 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-threadpoolctl
#
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-threadpoolctl
-Version: 3.0.0
+Version: 3.1.0
Release: 0
Summary: Thread-pool Controls
License: BSD-3-Clause
@@ -27,6 +27,9 @@
URL: https://github.com/joblib/threadpoolctl
Source:
https://files.pythonhosted.org/packages/source/t/threadpoolctl/threadpoolctl-%{version}.tar.gz
BuildRequires: %{python_module devel}
+BuildRequires: %{python_module flit-core}
+BuildRequires: %{python_module pep517}
+BuildRequires: %{python_module pip}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
@@ -43,10 +46,10 @@
%setup -q -n threadpoolctl-%{version}
%build
-%python_build
+%pyproject_wheel
%install
-%python_install
+%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
++++++ threadpoolctl-3.0.0.tar.gz -> threadpoolctl-3.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/threadpoolctl-3.0.0/.azure_pipeline.yml
new/threadpoolctl-3.1.0/.azure_pipeline.yml
--- old/threadpoolctl-3.0.0/.azure_pipeline.yml 2021-09-24 10:58:15.330052900
+0200
+++ new/threadpoolctl-3.1.0/.azure_pipeline.yml 2022-01-31 16:08:24.277708800
+0100
@@ -6,6 +6,14 @@
JUNITXML: 'test-data.xml'
CODECOV_TOKEN: 'cee0e505-c12e-4139-aa43-621fb16a2347'
+schedules:
+- cron: "0 1 * * *" # 1am UTC
+ displayName: Run nightly build
+ branches:
+ include:
+ - master
+ always: true
+
stages:
- stage:
jobs:
@@ -13,11 +21,16 @@
- template: continuous_integration/windows.yml
parameters:
name: Windows
- vmImage: vs2017-win2016
+ vmImage: windows-latest
matrix:
- pylatest_conda:
+ pylatest_conda_forge_mkl:
VERSION_PYTHON: '*'
- PACKAGER: 'conda'
+ PACKAGER: 'conda-forge'
+ BLAS: 'mkl'
+ py39_conda_forge_openblas:
+ VERSION_PYTHON: '3.9'
+ PACKAGER: 'conda-forge'
+ BLAS: 'openblas'
py37_conda:
VERSION_PYTHON: '3.7'
PACKAGER: 'conda'
@@ -76,11 +89,12 @@
VERSION_PYTHON: '3.8'
CC_OUTER_LOOP: 'gcc'
CC_INNER_LOOP: 'clang-10'
- # Linux environment with numpy from conda-forge channel
+ # Linux environment with numpy from conda-forge channel and
openblas-openmp
pylatest_conda_forge:
PACKAGER: 'conda-forge'
VERSION_PYTHON: '*'
BLAS: 'openblas'
+ OPENBLAS_THREADING_LAYER: 'openmp'
CC_OUTER_LOOP: 'gcc'
CC_INNER_LOOP: 'gcc'
LINT: 'true'
@@ -123,7 +137,7 @@
- template: continuous_integration/posix.yml
parameters:
name: macOS
- vmImage: macOS-10.14
+ vmImage: macOS-10.15
matrix:
# MacOS environment with OpenMP installed through homebrew
py36_conda_homebrew_libomp:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/threadpoolctl-3.0.0/CHANGES.md
new/threadpoolctl-3.1.0/CHANGES.md
--- old/threadpoolctl-3.0.0/CHANGES.md 2021-10-01 13:56:45.369609800 +0200
+++ new/threadpoolctl-3.1.0/CHANGES.md 2022-01-31 17:25:14.640525300 +0100
@@ -1,3 +1,16 @@
+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)
==================
@@ -50,7 +63,7 @@
2.0.0 (2019-12-05)
==================
-- Expose MKL, BLIS and OpenBLAS threading layer in informations displayed by
+- 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/threadpoolctl-3.0.0/PKG-INFO
new/threadpoolctl-3.1.0/PKG-INFO
--- old/threadpoolctl-3.0.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/threadpoolctl-3.1.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: threadpoolctl
-Version: 3.0.0
+Version: 3.1.0
Summary: threadpoolctl
Home-page: https://github.com/joblib/threadpoolctl
License: BSD-3-Clause
@@ -177,7 +177,7 @@
The threadpools can also be controlled via the object oriented API, which is
especially
useful to avoid searching through all the loaded shared libraries each time.
It will
-however not act on libraries loaded after the instanciation of the
+however not act on libraries loaded after the instantiation of the
`ThreadpoolController`:
```python
@@ -211,6 +211,13 @@
...
```
+### Sequential BLAS within OpenMP parallel region
+
+When one wants to have sequential BLAS calls within an OpenMP parallel region,
it's
+safer to set `limits="sequential_blas_under_openmp"` since setting `limits=1`
and `user_api="blas"` might not lead to the expected behavior in some
configurations
+(e.g. OpenBLAS with the OpenMP threading layer
+https://github.com/xianyi/OpenBLAS/issues/2985).
+
### Known Limitations
- `threadpool_limits` can fail to limit the number of inner threads when
nesting
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/threadpoolctl-3.0.0/README.md
new/threadpoolctl-3.1.0/README.md
--- old/threadpoolctl-3.0.0/README.md 2021-10-01 10:32:57.836148700 +0200
+++ new/threadpoolctl-3.1.0/README.md 2022-01-31 16:08:24.277708800 +0100
@@ -158,7 +158,7 @@
The threadpools can also be controlled via the object oriented API, which is
especially
useful to avoid searching through all the loaded shared libraries each time.
It will
-however not act on libraries loaded after the instanciation of the
+however not act on libraries loaded after the instantiation of the
`ThreadpoolController`:
```python
@@ -192,6 +192,13 @@
...
```
+### Sequential BLAS within OpenMP parallel region
+
+When one wants to have sequential BLAS calls within an OpenMP parallel region,
it's
+safer to set `limits="sequential_blas_under_openmp"` since setting `limits=1`
and `user_api="blas"` might not lead to the expected behavior in some
configurations
+(e.g. OpenBLAS with the OpenMP threading layer
+https://github.com/xianyi/OpenBLAS/issues/2985).
+
### Known Limitations
- `threadpool_limits` can fail to limit the number of inner threads when
nesting
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/threadpoolctl-3.0.0/continuous_integration/install.cmd
new/threadpoolctl-3.1.0/continuous_integration/install.cmd
--- old/threadpoolctl-3.0.0/continuous_integration/install.cmd 2021-09-15
15:26:21.489843100 +0200
+++ new/threadpoolctl-3.1.0/continuous_integration/install.cmd 2022-01-20
18:05:26.048133900 +0100
@@ -18,8 +18,11 @@
pip --version
@rem Install dependencies with either conda or pip.
-if "%PACKAGER%" == "conda" (%CONDA_INSTALL% numpy scipy pytest cython)
-if "%PACKAGER%" == "pip" (%PIP_INSTALL% numpy scipy pytest cython)
+set TO_INSTALL=numpy scipy cython pytest
+
+if "%PACKAGER%" == "conda" (%CONDA_INSTALL% %TO_INSTALL%)
+if "%PACKAGER%" == "conda-forge" (%CONDA_INSTALL% -c conda-forge %TO_INSTALL%
blas[build=%BLAS%])
+if "%PACKAGER%" == "pip" (%PIP_INSTALL% %TO_INSTALL%)
@rem Install extra developer dependencies
pip install -q -r dev-requirements.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/threadpoolctl-3.0.0/continuous_integration/install.sh
new/threadpoolctl-3.1.0/continuous_integration/install.sh
--- old/threadpoolctl-3.0.0/continuous_integration/install.sh 2021-09-24
13:00:01.009218500 +0200
+++ new/threadpoolctl-3.1.0/continuous_integration/install.sh 2022-01-31
16:08:24.277708800 +0100
@@ -50,6 +50,9 @@
conda config --prepend channels conda-forge
conda config --set channel_priority strict
TO_INSTALL="python=$VERSION_PYTHON numpy scipy blas[build=$BLAS]"
+ if [[ "$BLAS" == "openblas" && "$OPENBLAS_THREADING_LAYER" == "openmp" ]];
then
+ TO_INSTALL="$TO_INSTALL libopenblas=*=*openmp*"
+ fi
make_conda $TO_INSTALL
elif [[ "$PACKAGER" == "pip" ]]; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/threadpoolctl-3.0.0/continuous_integration/install_with_blis.sh
new/threadpoolctl-3.1.0/continuous_integration/install_with_blis.sh
--- old/threadpoolctl-3.0.0/continuous_integration/install_with_blis.sh
2021-09-24 13:00:01.009218500 +0200
+++ new/threadpoolctl-3.1.0/continuous_integration/install_with_blis.sh
2022-01-20 18:05:26.048133900 +0100
@@ -35,6 +35,7 @@
# build & install numpy
git clone https://github.com/numpy/numpy.git
pushd numpy
+git submodule update --init
echo "[blis]
libraries = blis
library_dirs = $ABS_PATH/BLIS_install/lib
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/threadpoolctl-3.0.0/continuous_integration/test_script.cmd
new/threadpoolctl-3.1.0/continuous_integration/test_script.cmd
--- old/threadpoolctl-3.0.0/continuous_integration/test_script.cmd
2021-09-15 15:26:21.493843300 +0200
+++ new/threadpoolctl-3.1.0/continuous_integration/test_script.cmd
2022-01-20 18:05:26.048133900 +0100
@@ -2,6 +2,6 @@
# Use the CLI to display the effective runtime environment prior to
# launching the tests:
-python -m threadpoolctl -i numpy scipy.linalg tests._openmp_test_helper
+python -m threadpoolctl -i numpy scipy.linalg
tests._openmp_test_helper.openmp_helpers_inner
pytest -vlrxXs --junitxml=%JUNITXML% --cov=threadpoolctl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/threadpoolctl-3.0.0/continuous_integration/test_script.sh
new/threadpoolctl-3.1.0/continuous_integration/test_script.sh
--- old/threadpoolctl-3.0.0/continuous_integration/test_script.sh
2021-09-15 15:26:21.493843300 +0200
+++ new/threadpoolctl-3.1.0/continuous_integration/test_script.sh
2022-01-20 18:05:26.048133900 +0100
@@ -15,6 +15,6 @@
# Use the CLI to display the effective runtime environment prior to
# launching the tests:
-python -m threadpoolctl -i numpy scipy.linalg tests._openmp_test_helper
+python -m threadpoolctl -i numpy scipy.linalg
tests._openmp_test_helper.openmp_helpers_inner
pytest -vlrxXs -W error -k "$TESTS" --junitxml=$JUNITXML --cov=threadpoolctl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/threadpoolctl-3.0.0/pyproject.toml
new/threadpoolctl-3.1.0/pyproject.toml
--- old/threadpoolctl-3.0.0/pyproject.toml 2021-09-24 10:58:15.330052900
+0200
+++ new/threadpoolctl-3.1.0/pyproject.toml 2022-01-31 16:08:24.277708800
+0100
@@ -1,6 +1,6 @@
[build-system]
-requires = ["flit"]
-build-backend = "flit.buildapi"
+requires = ["flit_core"]
+build-backend = "flit_core.buildapi"
[tool.flit.metadata]
module = "threadpoolctl"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/threadpoolctl-3.0.0/setup.py
new/threadpoolctl-3.1.0/setup.py
--- old/threadpoolctl-3.0.0/setup.py 1970-01-01 01:00:00.000000000 +0100
+++ new/threadpoolctl-3.1.0/setup.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-# setup.py generated by flit for tools that don't yet use PEP 517
-
-from distutils.core import setup
-
-
-setup(name='threadpoolctl',
- version='3.0.0',
- description='threadpoolctl',
- author='Thomas Moreau',
- author_email='[email protected]',
- url='https://github.com/joblib/threadpoolctl',
- py_modules=['threadpoolctl'],
- python_requires='>=3.6',
- )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/threadpoolctl-3.0.0/tests/_openmp_test_helper/openmp_helpers_inner.pyx
new/threadpoolctl-3.1.0/tests/_openmp_test_helper/openmp_helpers_inner.pyx
--- old/threadpoolctl-3.0.0/tests/_openmp_test_helper/openmp_helpers_inner.pyx
2021-09-15 15:26:21.493843300 +0200
+++ new/threadpoolctl-3.1.0/tests/_openmp_test_helper/openmp_helpers_inner.pyx
2021-12-31 17:52:30.808669800 +0100
@@ -22,7 +22,7 @@
OpenMP runtime.
This function is expected to run without the GIL and can be called
- by an outer OpenMP / prange loop written in Cython in anoter file.
+ by an outer OpenMP / prange loop written in Cython in another file.
"""
cdef long n_sum = 0
cdef int i, num_threads
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/threadpoolctl-3.0.0/tests/test_threadpoolctl.py
new/threadpoolctl-3.1.0/tests/test_threadpoolctl.py
--- old/threadpoolctl-3.0.0/tests/test_threadpoolctl.py 2021-10-01
10:59:48.573305600 +0200
+++ new/threadpoolctl-3.1.0/tests/test_threadpoolctl.py 2022-01-31
16:08:24.277708800 +0100
@@ -208,8 +208,42 @@
for lib_controller in blas_controller.lib_controllers
)
# original_blas_controller contains only blas libraries so no opemp
library
- # should be impacted.
- assert openmp_info == original_openmp_info
+ # should be impacted. This is not True for OpenBLAS with the OpenMP
threading
+ # layer.
+ if not any(
+ lib_controller.internal_api == "openblas"
+ and lib_controller.threading_layer == "openmp"
+ for lib_controller in blas_controller.lib_controllers
+ ):
+ assert openmp_info == original_openmp_info
+
+
+def test_get_params_for_sequential_blas_under_openmp():
+ # Test for the behavior of get_params_for_sequential_blas_under_openmp.
+ controller = ThreadpoolController()
+ original_info = controller.info()
+
+ params = controller._get_params_for_sequential_blas_under_openmp()
+
+ if controller.select(
+ internal_api="openblas", threading_layer="openmp"
+ ).lib_controllers:
+ assert params["limits"] is None
+ assert params["user_api"] is None
+
+ with controller.limit(limits="sequential_blas_under_openmp"):
+ assert controller.info() == original_info
+
+ else:
+ assert params["limits"] == 1
+ assert params["user_api"] == "blas"
+
+ with controller.limit(limits="sequential_blas_under_openmp"):
+ assert all(
+ lib_info["num_threads"] == 1
+ for lib_info in controller.info()
+ if lib_info["user_api"] == "blas"
+ )
def test_nested_limits():
@@ -245,7 +279,7 @@
threadpool_limits(limits=1, user_api="wrong")
with pytest.raises(
- TypeError, match="limits must either be an int, a list or a dict"
+ TypeError, match="limits must either be an int, a list, a dict, or"
):
threadpool_limits(limits=(1, 2, 3))
@@ -552,8 +586,11 @@
# XXX: add more as needed by CI or developer laptops
"armv8",
"Haswell",
+ "Prescott", # see: https://github.com/xianyi/OpenBLAS/pull/3485
"SkylakeX",
"Sandybridge",
+ "VORTEX",
+ "Zen",
)
expected_blis_architectures = (
# XXX: add more as needed by CI or developer laptops
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/threadpoolctl-3.0.0/threadpoolctl.py
new/threadpoolctl-3.1.0/threadpoolctl.py
--- old/threadpoolctl-3.0.0/threadpoolctl.py 2021-10-01 13:56:45.369609800
+0200
+++ new/threadpoolctl-3.1.0/threadpoolctl.py 2022-01-31 17:25:14.640525300
+0100
@@ -7,7 +7,7 @@
# License: BSD 3-Clause
# The code to introspect dynamically loaded libraries on POSIX systems is
-# adapted from code by Intel developper @anton-malakhov available at
+# adapted from code by Intel developer @anton-malakhov available at
# https://github.com/IntelPython/smp (Copyright (c) 2017, Intel Corporation)
# and also published under the BSD 3-Clause license
import os
@@ -21,7 +21,7 @@
from functools import lru_cache
from contextlib import ContextDecorator
-__version__ = "3.0.0"
+__version__ = "3.1.0"
__all__ = ["threadpool_limits", "threadpool_info", "ThreadpoolController"]
@@ -61,9 +61,11 @@
# List of the supported libraries. The items are indexed by the name of the
-# class to instanciate to create the library controller objects. The items hold
+# class to instantiate to create the library controller objects. The items hold
# the possible prefixes of loaded shared objects, the name of the internal_api
-# to call and the name of the user_api.
+# to call, the name of the user_api and potentially some symbols that the
library is
+# expected to have (this is necessary to distinguish between the blas
implementations
+# when they are all renamed "libblas.dll" on conda-forge on windows).
_SUPPORTED_LIBRARIES = {
"OpenMPController": {
"user_api": "openmp",
@@ -73,28 +75,33 @@
"OpenBLASController": {
"user_api": "blas",
"internal_api": "openblas",
- "filename_prefixes": ("libopenblas",),
+ "filename_prefixes": ("libopenblas", "libblas"),
+ "check_symbols": ("openblas_get_num_threads",
"openblas_get_num_threads64_"),
},
"MKLController": {
"user_api": "blas",
"internal_api": "mkl",
- "filename_prefixes": ("libmkl_rt", "mkl_rt"),
+ "filename_prefixes": ("libmkl_rt", "mkl_rt", "libblas"),
+ "check_symbols": ("MKL_Get_Max_Threads",),
},
"BLISController": {
"user_api": "blas",
"internal_api": "blis",
- "filename_prefixes": ("libblis",),
+ "filename_prefixes": ("libblis", "libblas"),
+ "check_symbols": ("bli_thread_get_num_threads",),
},
}
# Helpers for the doc and test names
_ALL_USER_APIS = list(set(lib["user_api"] for lib in
_SUPPORTED_LIBRARIES.values()))
_ALL_INTERNAL_APIS = [lib["internal_api"] for lib in
_SUPPORTED_LIBRARIES.values()]
-_ALL_PREFIXES = [
- prefix
- for lib in _SUPPORTED_LIBRARIES.values()
- for prefix in lib["filename_prefixes"]
-]
+_ALL_PREFIXES = list(
+ set(
+ prefix
+ for lib in _SUPPORTED_LIBRARIES.values()
+ for prefix in lib["filename_prefixes"]
+ )
+)
_ALL_BLAS_LIBRARIES = [
lib["internal_api"]
for lib in _SUPPORTED_LIBRARIES.values()
@@ -151,10 +158,10 @@
"""
def __init__(self, controller, *, limits=None, user_api=None):
+ self._controller = controller
self._limits, self._user_api, self._prefixes = self._check_params(
limits, user_api
)
- self._controller = controller
self._original_info = self._controller.info()
self._set_threadpool_limits()
@@ -219,6 +226,13 @@
def _check_params(self, limits, user_api):
"""Suitable values for the _limits, _user_api and _prefixes
attributes"""
+
+ if isinstance(limits, str) and limits ==
"sequential_blas_under_openmp":
+ (
+ limits,
+ user_api,
+ ) =
self._controller._get_params_for_sequential_blas_under_openmp().values()
+
if limits is None or isinstance(limits, int):
if user_api is None:
user_api = _ALL_USER_APIS
@@ -250,8 +264,8 @@
if not isinstance(limits, dict):
raise TypeError(
- "limits must either be an int, a list or a "
- f"dict. Got {type(limits)} instead"
+ "limits must either be an int, a list, a dict, or "
+ f"'sequential_blas_under_openmp'. Got {type(limits)}
instead"
)
# With a dictionary, can set both specific limit for given
@@ -326,7 +340,7 @@
Parameters
----------
- limits : int, dict or None (default=None)
+ limits : int, dict, 'sequential_blas_under_openmp' or None (default=None)
The maximal number of threads that can be used in thread pools
- If int, sets the maximum number of threads to `limits` for each
@@ -336,6 +350,11 @@
custom maximum number of threads for each `key` which can be either a
`user_api` or a `prefix` for a specific library.
+ - If 'sequential_blas_under_openmp', it will chose the appropriate
`limits`
+ and `user_api` parameters for the specific use case of sequential
BLAS
+ calls within an OpenMP parallel region. The `user_api` parameter is
+ ignored.
+
- If None, this function does not do anything.
user_api : {USER_APIS} or None (default=None)
@@ -421,6 +440,18 @@
return ThreadpoolController._from_controllers(lib_controllers)
+ def _get_params_for_sequential_blas_under_openmp(self):
+ """Return appropriate params to use for a sequential BLAS call in an
OpenMP loop
+
+ 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:
+ return {"limits": None, "user_api": None}
+ return {"limits": 1, "user_api": "blas"}
+
@_format_docstring(
USER_APIS=", ".join('"{}"'.format(api) for api in _ALL_USER_APIS),
BLAS_LIBS=", ".join(_ALL_BLAS_LIBRARIES),
@@ -444,7 +475,7 @@
Parameters
----------
- limits : int, dict or None (default=None)
+ limits : int, dict, 'sequential_blas_under_openmp' or None
(default=None)
The maximal number of threads that can be used in thread pools
- If int, sets the maximum number of threads to `limits` for each
@@ -454,6 +485,11 @@
custom maximum number of threads for each `key` which can be
either a
`user_api` or a `prefix` for a specific library.
+ - If 'sequential_blas_under_openmp', it will chose the appropriate
`limits`
+ and `user_api` parameters for the specific use case of
sequential BLAS
+ calls within an OpenMP parallel region. The `user_api` parameter
is
+ ignored.
+
- If None, this function does not do anything.
user_api : {USER_APIS} or None (default=None)
@@ -526,7 +562,7 @@
"""Loop through loaded libraries and return binders on supported ones
This function is expected to work on POSIX system only.
- This code is adapted from code by Intel developper @anton-malakhov
+ This code is adapted from code by Intel developer @anton-malakhov
available at https://github.com/IntelPython/smp
Copyright (c) 2017, Intel Corporation published under the BSD 3-Clause
@@ -660,6 +696,26 @@
if prefix is None:
continue
+ # workaround for BLAS libraries packaged by conda-forge on
windows, which
+ # are all renamed "libblas.dll". We thus have to check to which
BLAS
+ # implementation it actually corresponds looking for implementation
+ # specific symbols.
+ if prefix == "libblas":
+ if filename.endswith(".dll"):
+ libblas = ctypes.CDLL(filepath, _RTLD_NOLOAD)
+ if not any(
+ hasattr(libblas, func)
+ for func in candidate_lib["check_symbols"]
+ ):
+ continue
+ else:
+ # We ignore libblas on other platforms than windows
because there
+ # might be a libblas dso comming with openblas for
instance that
+ # can't be used to instantiate a pertinent LibController
(many
+ # symbols are missing) and would create confusion by
making a
+ # duplicate entry in threadpool_info.
+ continue
+
# filename matches a prefix. Create and store the library
# controller.
user_api = candidate_lib["user_api"]