/
__init__.py
227 lines (183 loc) · 6.4 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
"""
Brian 2
"""
import logging
def _check_dependencies():
"""Check basic dependencies"""
import sys
missing = []
try:
import numpy
except ImportError as ex:
sys.stderr.write(f"Importing numpy failed: '{ex}'\n")
missing.append("numpy")
try:
import sympy
except ImportError as ex:
sys.stderr.write(f"Importing sympy failed: '{ex}'\n")
missing.append("sympy")
try:
import pyparsing
except ImportError as ex:
sys.stderr.write(f"Importing pyparsing failed: '{ex}'\n")
missing.append("pyparsing")
try:
import jinja2
except ImportError as ex:
sys.stderr.write(f"Importing Jinja2 failed: '{ex}'\n")
missing.append("jinja2")
if len(missing):
raise ImportError(
f"Some required dependencies are missing:\n{', '.join(missing)}"
)
_check_dependencies()
try:
from pylab import *
except ImportError:
# Do the non-matplotlib pylab imports manually
# don't let numpy's datetime hide stdlib
import datetime
import numpy.ma as ma
from numpy import *
from numpy.fft import *
from numpy.linalg import *
from numpy.random import *
# Make sure that Brian's unit-aware functions are used, even when directly
# using names prefixed with numpy or np
import brian2.numpy_ as numpy
import brian2.numpy_ as np
try:
from ._version import __version__, __version_tuple__
except ImportError:
try:
from setuptools_scm import get_version
__version__ = get_version(
root="..",
relative_to=__file__,
version_scheme="post-release",
local_scheme="no-local-version",
)
__version_tuple__ = tuple(int(x) for x in __version__.split(".")[:3])
except ImportError:
logging.getLogger("brian2").warn(
"Cannot determine Brian version, running from source and "
"setuptools_scm is not installed."
)
__version__ = "unknown"
__version_tuple__ = (0, 0, 0)
# delete some annoying names from the namespace
if "x" in globals():
del x
if "f" in globals():
del f
if "rate" in globals():
del rate
__docformat__ = "restructuredtext en"
from brian2.only import *
from brian2.only import test
# Check for outdated dependency versions
def _check_dependency_version(name, version):
import sys
from packaging.version import Version
from .core.preferences import prefs
from .utils.logger import get_logger
logger = get_logger(__name__)
module = sys.modules[name]
if not isinstance(module.__version__, str): # mocked module
return
if not Version(module.__version__) >= Version(version):
message = (
f"{name} is outdated (got version {module.__version__}, need version"
f" {version})"
)
if prefs.core.outdated_dependency_error:
raise ImportError(message)
else:
logger.warn(message, "outdated_dependency")
def _check_dependency_versions():
for name, version in [("numpy", "1.10"), ("sympy", "1.2"), ("jinja2", "2.7")]:
_check_dependency_version(name, version)
_check_dependency_versions()
# Initialize the logging system
BrianLogger.initialize()
logger = get_logger(__name__)
# Check the caches
def _get_size_recursively(dirname):
import os
total_size = 0
for dirpath, _, filenames in os.walk(dirname):
for fname in filenames:
# When other simulations are running, files may disappear while
# we walk through the directory (in particular with Cython, where
# we delete the source files after compilation by default)
try:
size = os.path.getsize(os.path.join(dirpath, fname))
total_size += size
except OSError:
pass # ignore the file
return total_size
#: Stores the cache directory for code generation targets
_cache_dirs_and_extensions = {}
def check_cache(target):
cache_dir, _ = _cache_dirs_and_extensions.get(target, (None, None))
if cache_dir is None:
return
size = _get_size_recursively(cache_dir)
size_in_mb = int(round(size / 1024.0 / 1024.0))
if size_in_mb > prefs.codegen.max_cache_dir_size:
logger.info(
f"Cache size for target '{target}': {size_in_mb} MB.\n"
f"You can call clear_cache('{target}') to delete all "
"files from the cache or manually delete files in the "
f"'{cache_dir}' directory."
)
else:
logger.debug(f"Cache size for target '{target}': {size_in_mb} MB")
def clear_cache(target):
"""
Clears the on-disk cache with the compiled files for a given code generation
target.
Parameters
----------
target : str
The code generation target (e.g. ``'cython'``)
Raises
------
ValueError
If the given code generation target does not have an on-disk cache
IOError
If the cache directory contains unexpected files, suggesting that
deleting it would also delete files unrelated to the cache.
"""
import os
import shutil
cache_dir, extensions = _cache_dirs_and_extensions.get(target, (None, None))
if cache_dir is None:
raise ValueError(f'No cache directory registered for target "{target}".')
cache_dir = os.path.abspath(cache_dir) # just to make sure...
for folder, _, files in os.walk(cache_dir):
for f in files:
for ext in extensions:
if f.endswith(ext):
break
else:
raise OSError(
f"The cache directory for target '{target}' contains "
f"the file '{os.path.join(folder, f)}' of an unexpected type and "
"will therefore not be removed. Delete files in "
f"'{cache_dir}' manually"
)
logger.debug(f"Clearing cache for target '{target}' (directory '{cache_dir}').")
shutil.rmtree(cache_dir)
def _check_caches():
from brian2.codegen.runtime.cython_rt.extension_manager import (
get_cython_cache_dir,
get_cython_extensions,
)
for target, (dirname, extensions) in [
("cython", (get_cython_cache_dir(), get_cython_extensions()))
]:
_cache_dirs_and_extensions[target] = (dirname, extensions)
if prefs.codegen.max_cache_dir_size > 0:
check_cache(target)
_check_caches()