Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/numexpr-2.8.7.dev1-py3.8-linux-x86_64.egg/numexpr/utils.py: 47%
96 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-19 06:05 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-19 06:05 +0000
1###################################################################
2# Numexpr - Fast numerical array expression evaluator for NumPy.
3#
4# License: MIT
5# Author: See AUTHORS.txt
6#
7# See LICENSE.txt and LICENSES/*.txt for details about copyright and
8# rights to use.
9####################################################################
11import logging
12log = logging.getLogger(__name__)
14import os
15import subprocess
16import platform
18from numexpr.interpreter import _set_num_threads, _get_num_threads, MAX_THREADS
19from numexpr import use_vml
20from . import version
22if use_vml:
23 from numexpr.interpreter import (
24 _get_vml_version, _set_vml_accuracy_mode, _set_vml_num_threads,
25 _get_vml_num_threads)
28def get_vml_version():
29 """
30 Get the VML/MKL library version.
31 """
32 if use_vml:
33 return _get_vml_version()
34 else:
35 return None
38def set_vml_accuracy_mode(mode):
39 """
40 Set the accuracy mode for VML operations.
42 The `mode` parameter can take the values:
43 - 'high': high accuracy mode (HA), <1 least significant bit
44 - 'low': low accuracy mode (LA), typically 1-2 least significant bits
45 - 'fast': enhanced performance mode (EP)
46 - None: mode settings are ignored
48 This call is equivalent to the `vmlSetMode()` in the VML library.
49 See:
51 http://www.intel.com/software/products/mkl/docs/webhelp/vml/vml_DataTypesAccuracyModes.html
53 for more info on the accuracy modes.
55 Returns old accuracy settings.
56 """
57 if use_vml:
58 acc_dict = {None: 0, 'low': 1, 'high': 2, 'fast': 3}
59 acc_reverse_dict = {1: 'low', 2: 'high', 3: 'fast'}
60 if mode not in list(acc_dict.keys()):
61 raise ValueError(
62 "mode argument must be one of: None, 'high', 'low', 'fast'")
63 retval = _set_vml_accuracy_mode(acc_dict.get(mode, 0))
64 return acc_reverse_dict.get(retval)
65 else:
66 return None
69def set_vml_num_threads(nthreads):
70 """
71 Suggests a maximum number of threads to be used in VML operations.
73 This function is equivalent to the call
74 `mkl_domain_set_num_threads(nthreads, MKL_DOMAIN_VML)` in the MKL
75 library. See:
77 http://www.intel.com/software/products/mkl/docs/webhelp/support/functn_mkl_domain_set_num_threads.html
79 for more info about it.
80 """
81 if use_vml:
82 _set_vml_num_threads(nthreads)
83 pass
85def get_vml_num_threads():
86 """
87 Gets the maximum number of threads to be used in VML operations.
89 This function is equivalent to the call
90 `mkl_domain_get_max_threads (MKL_DOMAIN_VML)` in the MKL
91 library. See:
93 http://software.intel.com/en-us/node/522118
95 for more info about it.
96 """
97 if use_vml:
98 return _get_vml_num_threads()
99 return None
101def set_num_threads(nthreads):
102 """
103 Sets a number of threads to be used in operations.
105 DEPRECATED: returns the previous setting for the number of threads.
107 During initialization time NumExpr sets this number to the number
108 of detected cores in the system (see `detect_number_of_cores()`).
109 """
110 old_nthreads = _set_num_threads(nthreads)
111 return old_nthreads
113def get_num_threads():
114 """
115 Gets the number of threads currently in use for operations.
116 """
117 return _get_num_threads()
119def _init_num_threads():
120 """
121 Detects the environment variable 'NUMEXPR_MAX_THREADS' to set the threadpool
122 size, and if necessary the slightly redundant 'NUMEXPR_NUM_THREADS' or
123 'OMP_NUM_THREADS' env vars to set the initial number of threads used by
124 the virtual machine.
125 """
126 # Any platform-specific short-circuits
127 if 'sparc' in version.platform_machine:
128 log.warning('The number of threads have been set to 1 because problems related '
129 'to threading have been reported on some sparc machine. '
130 'The number of threads can be changed using the "set_num_threads" '
131 'function.')
132 set_num_threads(1)
133 return 1
135 env_configured = False
136 n_cores = detect_number_of_cores()
137 if 'NUMEXPR_MAX_THREADS' in os.environ:
138 # The user has configured NumExpr in the expected way, so suppress logs.
139 env_configured = True
140 n_cores = MAX_THREADS
141 else:
142 # The use has not set 'NUMEXPR_MAX_THREADS', so likely they have not
143 # configured NumExpr as desired, so we emit info logs.
144 if n_cores > MAX_THREADS:
145 log.info('Note: detected %d virtual cores but NumExpr set to maximum of %d, check "NUMEXPR_MAX_THREADS" environment variable.'%(n_cores, MAX_THREADS))
146 if n_cores > 8:
147 # The historical 'safety' limit.
148 log.info('Note: NumExpr detected %d cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.'%n_cores)
149 n_cores = 8
151 # Now we check for 'NUMEXPR_NUM_THREADS' or 'OMP_NUM_THREADS' to set the
152 # actual number of threads used.
153 if 'NUMEXPR_NUM_THREADS' in os.environ:
154 requested_threads = int(os.environ['NUMEXPR_NUM_THREADS'])
155 elif 'OMP_NUM_THREADS' in os.environ:
156 requested_threads = int(os.environ['OMP_NUM_THREADS'])
157 else:
158 requested_threads = n_cores
159 if not env_configured:
160 log.info('NumExpr defaulting to %d threads.'%n_cores)
162 # The C-extension function performs its own checks against `MAX_THREADS`
163 set_num_threads(requested_threads)
164 return requested_threads
167def detect_number_of_cores():
168 """
169 Detects the number of cores on a system. Cribbed from pp.
170 """
171 # Linux, Unix and MacOS:
172 if hasattr(os, "sysconf"):
173 if "SC_NPROCESSORS_ONLN" in os.sysconf_names:
174 # Linux & Unix:
175 ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
176 if isinstance(ncpus, int) and ncpus > 0:
177 return ncpus
178 else: # OSX:
179 return int(subprocess.check_output(["sysctl", "-n", "hw.ncpu"]))
180 # Windows:
181 try:
182 ncpus = int(os.environ.get("NUMBER_OF_PROCESSORS", ""))
183 if ncpus > 0:
184 return ncpus
185 except ValueError:
186 pass
187 return 1 # Default
190def detect_number_of_threads():
191 """
192 DEPRECATED: use `_init_num_threads` instead.
193 If this is modified, please update the note in: https://github.com/pydata/numexpr/wiki/Numexpr-Users-Guide
194 """
195 log.warning('Deprecated, use `init_num_threads` instead.')
196 try:
197 nthreads = int(os.environ.get('NUMEXPR_NUM_THREADS', ''))
198 except ValueError:
199 try:
200 nthreads = int(os.environ.get('OMP_NUM_THREADS', ''))
201 except ValueError:
202 nthreads = detect_number_of_cores()
204 # Check that we don't surpass the MAX_THREADS in interpreter.cpp
205 if nthreads > MAX_THREADS:
206 nthreads = MAX_THREADS
207 return nthreads
210class CacheDict(dict):
211 """
212 A dictionary that prevents itself from growing too much.
213 """
215 def __init__(self, maxentries):
216 self.maxentries = maxentries
217 super(CacheDict, self).__init__(self)
219 def __setitem__(self, key, value):
220 # Protection against growing the cache too much
221 if len(self) > self.maxentries:
222 # Remove a 10% of (arbitrary) elements from the cache
223 entries_to_remove = self.maxentries // 10
224 for k in list(self.keys())[:entries_to_remove]:
225 super(CacheDict, self).__delitem__(k)
226 super(CacheDict, self).__setitem__(key, value)