def test_brianpreference(): # check default args pref = BrianPreference(1. / 3, 'docs') assert not pref.validator(1) assert pref.docs == 'docs' assert pref.default == 1. / 3 assert pref.representor(pref.default) == repr(1. / 3)
def test_str_repr(): # Just test whether str and repr do not throw an error and return something gp = BrianGlobalPreferences() gp.register_preferences('main', 'main category', name=BrianPreference(True, 'some preference')) assert len(str(gp)) assert len(repr(gp)) assert len(str(gp.main)) assert len(repr(gp.main))
def test_preference_name_checking(): ''' Test that you cannot set illegal preference names. ''' gp = BrianGlobalPreferences() # Name that starts with an underscore assert_raises(PreferenceError, lambda: gp.register_preferences('dummy', 'dummy doc', _notalegalname=BrianPreference(True, 'some preference') )) # Name that clashes with a method name assert_raises(PreferenceError, lambda: gp.register_preferences('dummy', 'dummy doc', update=BrianPreference(True, 'some preference') )) gp.register_preferences('a', 'dummy doc', b=BrianPreference(True, 'some preference')) #Trying to register a subcategory that would shadow a preference assert_raises(PreferenceError, lambda: gp.register_preferences('a.b', 'dummy doc', name=BrianPreference(True, 'some preference') )) gp.register_preferences('b.c', 'dummy doc', name=BrianPreference(True, 'some preference')) #Trying to register a preference that clashes with an existing category assert_raises(PreferenceError, lambda: gp.register_preferences('b', 'dummy doc', c=BrianPreference(True, 'some preference') ))
from ...codeobject import CodeObject from ...templates import Templater from ...generators.cpp_generator import CPPCodeGenerator from ...targets import codegen_targets __all__ = ['WeaveCodeObject', 'WeaveCodeGenerator', 'make_weave_function'] # Preferences brian_prefs.register_preferences( 'codegen.runtime.weave', 'Weave runtime codegen preferences', compiler = BrianPreference( default='gcc', validator=lambda pref: pref=='gcc', docs=''' Compiler to use for weave. ''' ), extra_compile_args = BrianPreference( default=['-w', '-O3'], docs=''' Extra compile arguments to pass to compiler ''' ), include_dirs = BrianPreference( default=[], docs=''' Include directories to use. Note that ``$prefix/include`` will be appended to the end automatically, where ``$prefix`` is Python's site-specific directory prefix as returned by `sys.prefix`.
elif dtype == numpy.bool_ or dtype is bool: dtype = 'bool' else: raise ValueError("dtype " + str(dtype) + " not known.") return dtype # Preferences prefs.register_preferences( 'codegen.generators.cpp', 'C++ codegen preferences', restrict_keyword=BrianPreference( default='__restrict', docs=''' The keyword used for the given compiler to declare pointers as restricted. This keyword is different on different compilers, the default works for gcc and MSVS. ''', ), flush_denormals=BrianPreference( default=False, docs=''' Adds code to flush denormals to zero. The code is gcc and architecture specific, so may not compile on all platforms. The code, for reference is:: #define CSR_FLUSH_TO_ZERO (1 << 15) unsigned csr = __builtin_ia32_stmxcsr(); csr |= CSR_FLUSH_TO_ZERO;
get_numpy_dtype) from ...targets import codegen_targets from ...cpp_prefs import get_compiler_and_args from .extension_manager import cython_extension_manager __all__ = ['CythonCodeObject'] logger = get_logger(__name__) # Preferences prefs.register_preferences( 'codegen.runtime.cython', 'Cython runtime codegen preferences', multiprocess_safe=BrianPreference(default=True, docs=''' Whether to use a lock file to prevent simultaneous write access to cython .pyx and .so files. '''), cache_dir=BrianPreference( default=None, validator=lambda x: x is None or isinstance(x, basestring), docs=''' Location of the cache directory for Cython files. By default, will be stored in a ``brian_extensions`` subdirectory where Cython inline stores its temporary files (the result of ``get_cython_cache_dir()``). '''), ) class CythonCodeObject(NumpyCodeObject):
from .codeobject import CodeObject # Preferences prefs.register_preferences( 'codegen', 'Code generation preferences', target=BrianPreference( default='auto', docs=""" Default target for code generation. Can be a string, in which case it should be one of: * ``'auto'`` the default, automatically chose the best code generation target available. * ``'cython'``, uses the Cython package to generate C++ code. Needs a working installation of Cython and a C++ compiler. * ``'numpy'`` works on all platforms and doesn't need a C compiler but is often less efficient. Or it can be a ``CodeObject`` class. """, validator=lambda target: isinstance(target, str) or issubclass( target, CodeObject), ), string_expression_target=BrianPreference( default='numpy', docs=""" Default target for the evaluation of string expressions (e.g. when indexing state variables). Should normally not be changed from the default numpy target, because the overhead of compiling code is not
from brian2.core.functions import Function from ...codeobject import CodeObject, constant_or_scalar, check_compiler_kwds from ...templates import Templater from ...generators.numpy_generator import NumpyCodeGenerator from ...targets import codegen_targets __all__ = ['NumpyCodeObject'] # Preferences prefs.register_preferences('codegen.runtime.numpy', 'Numpy runtime codegen preferences', discard_units=BrianPreference(default=False, docs=''' Whether to change the namespace of user-specifed functions to remove units. ''')) class LazyArange(Iterable): ''' A class that can be used as a `~numpy.arange` replacement (with an implied step size of 1) but does not actually create an array of values until necessary. It is somewhat similar to the ``range()`` function in Python 3, but does not use a generator. It is tailored to a special use case, the ``_vectorisation_idx`` variable in numpy templates, and not meant for general use. The ``_vectorisation_idx`` is used for stateless function calls such as ``rand()`` and for the numpy codegen target determines the number of values produced by such a call. This will often be the number of neurons or synapses, and this class avoids creating a new array of that size
from ...cpp_prefs import get_compiler_and_args from .extension_manager import cython_extension_manager __all__ = ['CythonCodeObject'] logger = get_logger(__name__) # Preferences prefs.register_preferences( 'codegen.runtime.cython', 'Cython runtime codegen preferences', multiprocess_safe = BrianPreference( default=True, docs=''' Whether to use a lock file to prevent simultaneous write access to cython .pyx and .so files. ''' ), cache_dir = BrianPreference( default=None, validator=lambda x: x is None or isinstance(x, basestring), docs=''' Location of the cache directory for Cython files. By default, will be stored in a ``brian_extensions`` subdirectory where Cython inline stores its temporary files (the result of ``get_cython_cache_dir()``). ''' ), delete_source_files = BrianPreference( default=True,
from ...cpp_prefs import get_compiler_and_args from .extension_manager import cython_extension_manager __all__ = ['CythonCodeObject'] logger = get_logger(__name__) # Preferences prefs.register_preferences( 'codegen.runtime.cython', 'Cython runtime codegen preferences', multiprocess_safe = BrianPreference( default=True, docs=''' Whether to use a lock file to prevent simultaneous write access to cython .pyx and .so files. ''' ) ) class CythonCodeObject(NumpyCodeObject): ''' Execute code using Cython. ''' templater = Templater('brian2.codegen.runtime.cython_rt', env_globals={'cpp_dtype': get_cpp_dtype, 'numpy_dtype': get_numpy_dtype, 'dtype': numpy.dtype}) generator_class = CythonCodeGenerator
'DEBUG': logging.DEBUG, 'DIAGNOSTIC': DIAGNOSTIC } logging.addLevelName(DIAGNOSTIC, 'DIAGNOSTIC') if 'logging' not in prefs.pref_register: # Duplicate import of this module can happen when the documentation is built prefs.register_preferences( 'logging', 'Logging system preferences', delete_log_on_exit=BrianPreference( default=True, docs=''' Whether to delete the log and script file on exit. If set to ``True`` (the default), log files (and the copy of the main script) will be deleted after the brian process has exited, unless an uncaught exception occurred. If set to ``False``, all log files will be kept. ''', ), file_log_level=BrianPreference(default='DIAGNOSTIC', docs=''' What log level to use for the log written to the log file. In case file logging is activated (see `logging.file_log`), which log level should be used for logging. Has to be one of CRITICAL, ERROR, WARNING, INFO, DEBUG or DIAGNOSTIC. ''', validator=log_level_validator), console_log_level=BrianPreference(default='INFO',
from .codeobject import CUDAStandaloneCodeObject from brian2.devices.cpp_standalone.device import CPPWriter, CPPStandaloneDevice from brian2.monitors.statemonitor import StateMonitor from brian2.groups.neurongroup import Thresholder __all__ = [] logger = get_logger('brian2.devices.cuda_standalone') # Preferences prefs.register_preferences( 'devices.cuda_standalone', 'CUDA standalone preferences', SM_multiplier=BrianPreference( default=1, docs=''' The number of blocks per SM. By default, this value is set to 1. ''', ), random_number_generator_type=BrianPreference( docs= '''Generator type (str) that cuRAND uses for random number generation. Setting the generator type automatically resets the generator ordering (prefs.devices.cuda_standalone.random_number_generator_ordering) to its default value. See cuRAND documentation for more details on generator types and orderings.''', validator=lambda v: v in [ 'CURAND_RNG_PSEUDO_DEFAULT', 'CURAND_RNG_PSEUDO_XORWOW', 'CURAND_RNG_PSEUDO_MRG32K3A', 'CURAND_RNG_PSEUDO_MTGP32', 'CURAND_RNG_PSEUDO_PHILOX4_32_10', 'CURAND_RNG_PSEUDO_MT19937', 'CURAND_RNG_QUASI_DEFAULT', 'CURAND_RNG_QUASI_SOBOL32', 'CURAND_RNG_QUASI_SCRAMBLED_SOBOL32', 'CURAND_RNG_QUASI_SOBOL64', 'CURAND_RNG_QUASI_SCRAMBLED_SOBOL64'
else: sys_prefix = sys.prefix if sys.platform == 'win32': prefix_dir = os.path.join(sys_prefix, 'Library') else: prefix_dir = sys_prefix # Preferences prefs.register_preferences( 'codegen.cpp', 'C++ compilation preferences', compiler=BrianPreference(default='', docs=""" Compiler to use (uses default if empty). Should be ``'unix'`` or ``'msvc'``. To specify a specific compiler binary on unix systems, set the `CXX` environment variable instead. """), extra_compile_args=BrianPreference(default=None, validator=lambda v: True, docs=""" Extra arguments to pass to compiler (if None, use either ``extra_compile_args_gcc`` or ``extra_compile_args_msvc``). """), extra_compile_args_gcc=BrianPreference(default=default_buildopts, docs=""" Extra compile arguments to pass to GCC compiler """), extra_compile_args_msvc=BrianPreference( default=['/Ox', '/w', msvc_arch_flag, '/MP'],
from ...templates import Templater from ...languages.cpp_lang import CPPLanguage from ..targets import runtime_targets from brian2.core.preferences import brian_prefs, BrianPreference __all__ = ['WeaveCodeObject'] # Preferences brian_prefs.register_preferences( 'codegen.runtime.weave', 'Weave runtime codegen preferences', compiler = BrianPreference( default='gcc', validator=lambda pref: pref=='gcc', docs=''' Compiler to use for weave. ''', ), extra_compile_args = BrianPreference( default=['-w', '-O3', '-ffast-math'], docs=''' Extra compile arguments to pass to compiler ''', ), ) def weave_data_type(dtype): ''' Gives the C language specifier for numpy data types using weave. For example,
try: eval(formatted) except Exception: logger.error(f"Can't evaluate expression '{string}'") return False return True # Preferences prefs.register_preferences( 'devices.cuda_standalone', 'Brian2CUDA preferences', SM_multiplier=BrianPreference( default=1, docs='The number of blocks per SM. By default, this value is set to 1.', ), parallel_blocks=BrianPreference( docs= '''The total number of parallel blocks to use. If ``None``, the number of parallel blocks equals the number streaming multiprocessors on the GPU.''', validator=lambda v: v is None or (isinstance(v, int) and v > 0), default=1), launch_bounds=BrianPreference( docs= 'Wether or not to use ``__launch_bounds__`` to optimise register usage in kernels.', default=False), syn_launch_bounds=BrianPreference( docs= 'Wether or not to use ``__launch_bounds__`` in synapses and synapses_push to optimise register usage in kernels.', default=False),
from brian2.utils.logger import get_logger, std_silent from .codeobject import CPPStandaloneCodeObject, openmp_pragma __all__ = [] logger = get_logger(__name__) # Preferences prefs.register_preferences( 'devices.cpp_standalone', 'C++ standalone preferences ', openmp_threads=BrianPreference( default=0, docs=''' The number of threads to use if OpenMP is turned on. By default, this value is set to 0 and the C++ code is generated without any reference to OpenMP. If greater than 0, then the corresponding number of threads are used to launch the simulation. ''', ), ) def freeze(code, ns): # this is a bit of a hack, it should be passed to the template somehow for k, v in ns.items(): if (isinstance(v, Variable) and not isinstance(v, AttributeVariable) and v.scalar and v.constant and v.read_only): try: v = v.get_value() except NotImplementedError:
from brian2.core.preferences import brian_prefs, BrianPreference # Preferences brian_prefs.register_preferences( 'codegen', 'Code generation preferences', target=BrianPreference( default='numpy', docs=''' Default target for code generation. Can be a string, in which case it should be one of: * `'numpy'` by default because this works on all platforms, but may not be maximally efficient. * `'weave`' uses ``scipy.weave`` to generate and compile C++ code, should work anywhere where ``gcc`` is installed and available at the command line. Or it can be a ``CodeObject`` class. ''', ), )
def test_preference_name_access(): ''' Test various ways of accessing preferences ''' gp = BrianGlobalPreferences() gp.register_preferences('main', 'main category', name=BrianPreference(True, 'some preference')) gp.register_preferences('main.sub', 'subcategory', name2=BrianPreference(True, 'some preference')) gp.register_preferences('main.sub_no_pref', 'subcategory without preference') gp.register_preferences('main.sub_no_pref.sub', 'deep subcategory', name=BrianPreference(True, 'some preference')) # Keyword based access assert gp['main.name'] assert gp['main.sub.name2'] assert gp['main.sub_no_pref.sub.name'] gp['main.name'] = False gp['main.sub.name2'] = False gp['main.sub_no_pref.sub.name'] = False # Attribute based access assert not gp.main.name # we set it to False above assert not gp.main.sub.name2 assert not gp.main.sub_no_pref.sub.name gp.main.name = True gp.main.sub.name2 = True gp.main.sub_no_pref.sub.name = True # Mixed access assert gp.main['name'] assert gp['main'].name assert gp.main['sub'].name2 assert gp['main'].sub['name2'] # Accessing categories assert isinstance(gp['main'], BrianGlobalPreferencesView) assert isinstance(gp['main.sub'], BrianGlobalPreferencesView) assert isinstance(gp.main, BrianGlobalPreferencesView) assert isinstance(gp.main.sub, BrianGlobalPreferencesView) # Setting categories shouldn't work with pytest.raises(PreferenceError): gp.__setitem__('main', None) with pytest.raises(PreferenceError): gp.__setattr__('main', None) with pytest.raises(PreferenceError): gp.main.__setitem__('sub', None) with pytest.raises(PreferenceError): gp.main.__setattr__('sub', None) # Neither should deleting categories or preferences with pytest.raises(PreferenceError): gp.__delitem__('main') with pytest.raises(PreferenceError): gp.__delattr__('main') with pytest.raises(PreferenceError): gp.main.__delitem__('name') with pytest.raises(PreferenceError): gp.main.__delattr__('name') with pytest.raises(PreferenceError): gp.main.__delitem__('sub') with pytest.raises(PreferenceError): gp.main.__delattr__('sub') #Errors for accessing non-existing preferences with pytest.raises(KeyError): gp['main.doesnotexist'] with pytest.raises(KeyError): gp['nonexisting.name'] with pytest.raises(KeyError): gp.main.doesnotexist with pytest.raises(KeyError): gp.nonexisting.name # Check dictionary functionality for name, value in gp.items(): assert gp[name] == value for name, value in gp.main.items(): assert gp.main[name] == value assert len(gp) == 3 # three preferences in total assert len(gp['main']) == 3 # all preferences are in the main category assert len(gp['main.sub']) == 1 # one preference in main.sub assert 'main.name' in gp assert 'name' in gp['main'] assert 'name2' in gp['main.sub'] assert not 'name' in gp['main.sub'] gp['main.name'] = True gp.update({'main.name': False}) assert not gp['main.name'] gp.main.update({'name': True}) assert gp['main.name'] # Class based functionality assert 'main' in dir(gp) assert 'sub' in dir(gp.main) assert 'name' in dir(gp.main) # Check that the fiddling with getattr and setattr did not destroy the # access to standard attributes assert len(gp.prefs) assert gp.main._basename == 'main'
logger = get_logger('brian2.codegen.generators.cuda_generator') __all__ = ['CUDACodeGenerator', 'c_data_type' ] # Preferences prefs.register_preferences( 'codegen.generators.cuda', 'CUDA codegen preferences', default_functions_integral_convertion=BrianPreference( docs='''The floating point precision to which integral types will be converted when passed as arguments to default functions that have no integral type overload in device code (sin, cos, tan, sinh, cosh, tanh, exp, log, log10, sqrt, ceil, floor, arcsin, arccos, arctan)." NOTE: Convertion from 32bit and 64bit integral types to single precision (32bit) floating-point types is not type safe. And convertion from 64bit integral types to double precision (64bit) floating-point types neither. In those cases the closest higher or lower (implementation defined) representable value will be selected.''', validator=lambda v: v in ['single_precision', 'double_precision'], default='double_precision') ) # CUDA does not support modulo arithmetics for long double. Since we can't give a warning, we let the # compilation fail, which gives an error message of type # error: more than one instance of overloaded function "_brian_mod" matches the argument list: ... # TODO: can we produce a more informative error message? mod_support_code = '' typestrs = ['unsigned char', 'char', 'unsigned short', 'short', 'unsigned int', 'int', 'unsigned long', 'long', 'unsigned long long', 'long long', 'float', 'double']#, 'long double'] floattypestrs = ['float', 'double']#, 'long double']
def test_brianglobalpreferences(): # test that pre-setting a nonexistent preference in a subsequently # existing base name raises an error at the correct point gp = BrianGlobalPreferences() # This shouldn't work, in user code only registered preferences can be set with pytest.raises(PreferenceError): gp.__setitem__('a.b', 5) # This uses the method that is used when reading preferences from a file gp._set_preference('a.b', 5) gp._set_preference('a.c', 5) with pytest.raises(PreferenceError): gp.register_preferences('a', 'docs for a', b=BrianPreference(5, 'docs for b')) # test that post-setting a nonexistent preference in an existing base # name raises an error gp = BrianGlobalPreferences() gp.register_preferences('a', 'docs for a', b=BrianPreference(5, 'docs for b')) with pytest.raises(PreferenceError): gp.__setitem__('a.c', 5) # Test pre and post-setting some correct names but valid and invalid values gp = BrianGlobalPreferences() gp._set_preference('a.b', 5) gp.register_preferences( 'a', 'docs for a', b=BrianPreference(5, 'docs for b'), c=BrianPreference(1 * volt, 'docs for c'), d=BrianPreference(0, 'docs for d', validator=lambda x: x >= 0), e=BrianPreference(float64, 'docs for e', representor=lambda x: x.__name__), ) assert gp['a.c'] == 1 * volt gp['a.c'] = 2 * volt with pytest.raises(PreferenceError): gp.__setitem__('a.c', 3 * amp) gp['a.d'] = 2.0 with pytest.raises(PreferenceError): gp.__setitem__('a.d', -1) gp['a.e'] = float32 with pytest.raises(PreferenceError): gp.__setitem__('a.e', 0) # test backup and restore gp._backup() gp['a.d'] = 10 assert gp['a.d'] == 10 gp._restore() assert gp['a.d'] == 2.0 # test that documentation and as_file generation runs without error, but # don't test for values because we might change the organisation of it assert len(gp.get_documentation()) gp.as_file gp.defaults_as_file # test that reading a preference file works as expected pref_file = StringIO(u''' # a comment a.b = 10 [a] c = 5*volt d = 1 e = float64 ''') gp.read_preference_file(pref_file) assert gp['a.b'] == 10 assert gp['a.c'] == 5 * volt assert gp['a.d'] == 1 assert gp['a.e'] == float64 # test that reading a badly formatted prefs file fails pref_file = StringIO(u''' [a b = 10 ''') with pytest.raises(PreferenceError): gp.read_preference_file(pref_file) # test that reading a well formatted prefs file with an invalid value fails pref_file = StringIO(u''' a.b = 'oh no, not a string' ''') with pytest.raises(PreferenceError): gp.read_preference_file(pref_file) # assert that writing the prefs to a file and loading them gives the # same values gp = BrianGlobalPreferences() gp.register_preferences( 'a', 'docs for a', b=BrianPreference(5, 'docs for b'), ) gp._backup() gp['a.b'] = 10 str_modified = gp.as_file str_defaults = gp.defaults_as_file gp['a.b'] = 15 gp.read_preference_file(StringIO(str_modified)) assert gp['a.b'] == 10 gp.read_preference_file(StringIO(str_defaults)) assert gp['a.b'] == 5 # check that load_preferences works, but nothing about its values gp = BrianGlobalPreferences() gp.load_preferences()
LOG_LEVELS = { 'CRITICAL': logging.CRITICAL, 'ERROR': logging.ERROR, 'WARNING': logging.WARNING, 'INFO': logging.INFO, 'DEBUG': logging.DEBUG } brian_prefs.register_preferences( 'logging', 'Logging system preferences', delete_log_on_exit=BrianPreference( default=True, docs=''' Whether to delete the log and script file on exit. If set to ``True`` (the default), log files (and the copy of the main script) will be deleted after the brian process has exited, unless an uncaught exception occured. If set to ``False``, all log files will be kept. ''', ), file_log_level=BrianPreference(default='DEBUG', docs=''' What log level to use for the log written to the log file. In case file logging is activated (see `logging.file_log`), which log level should be used for logging. Has to be one of CRITICAL, ERROR, WARNING, INFO or DEBUG. ''', validator=log_level_validator), console_log_level=BrianPreference(default='WARNING', docs='''
from brian2.core.preferences import prefs, BrianPreference from .base import device_override __all__ = ['Network', 'profiling_summary'] logger = get_logger(__name__) prefs.register_preferences('core.network', 'Network preferences', default_schedule=BrianPreference(default=[ 'start', 'groups', 'thresholds', 'synapses', 'resets', 'end', ], docs=''' Default schedule used for networks that don't specify a schedule. ''')) def _format_time(time_in_s): ''' Helper function to format time in seconds, minutes, hours, days, depending on the magnitude. Examples -------- >>> from brian2.core.network import _format_time
__all__ = [] def dtype_repr(dtype): return dtype.__name__ def default_float_dtype_validator(dtype): return dtype in [float32, float64] prefs.register_preferences('core', 'Core Brian preferences', default_float_dtype=BrianPreference( default=float64, docs=''' Default dtype for all arrays of scalars (state variables, weights, etc.). ''', representor=dtype_repr, validator=default_float_dtype_validator, ), default_integer_dtype=BrianPreference( default=int32, docs=''' Default dtype for all arrays of integer scalars. ''', representor=dtype_repr, ), outdated_dependency_error=BrianPreference( default=True, docs=''' Whether to raise an error for outdated dependencies (``True``) or just a warning (``False``).
''' from numpy import float64, int32 from brian2.core.preferences import BrianPreference, prefs def dtype_repr(dtype): return dtype.__name__ prefs.register_preferences('core', 'Core Brian preferences', default_float_dtype=BrianPreference( default=float64, docs=''' Default dtype for all arrays of scalars (state variables, weights, etc.). ''', representor=dtype_repr, ), default_integer_dtype=BrianPreference( default=int32, docs=''' Default dtype for all arrays of integer scalars. ''', representor=dtype_repr, ), outdated_dependency_error=BrianPreference( default=True, docs=''' Whether to raise an error for outdated dependencies (``True``) or just a warning (``False``).
'INFO': logging.INFO, 'DEBUG': logging.DEBUG, 'DIAGNOSTIC': DIAGNOSTIC } logging.addLevelName(DIAGNOSTIC, 'DIAGNOSTIC') if 'logging' not in prefs.pref_register: # Duplicate import of this module can happen when the documentation is built prefs.register_preferences( 'logging', 'Logging system preferences', delete_log_on_exit=BrianPreference( default=True, docs=''' Whether to delete the log and script file on exit. If set to ``True`` (the default), log files (and the copy of the main script) will be deleted after the brian process has exited, unless an uncaught exception occured. If set to ``False``, all log files will be kept. ''', ), file_log_level=BrianPreference(default='DIAGNOSTIC', docs=''' What log level to use for the log written to the log file. In case file logging is activated (see `logging.file_log`), which log level should be used for logging. Has to be one of CRITICAL, ERROR, WARNING, INFO, DEBUG or DIAGNOSTIC. ''', validator=log_level_validator), console_log_level=BrianPreference(default='INFO', docs='''
if 'sse' in res['flags']: msvc_arch_flag = '/arch:SSE' if 'sse2' in res['flags']: msvc_arch_flag = '/arch:SSE2' if 'avx' in res['flags']: msvc_arch_flag = '/arch:AVX' if 'avx2' in res['flags']: msvc_arch_flag = '/arch:AVX2' # Preferences prefs.register_preferences( 'codegen.cpp', 'C++ compilation preferences', compiler=BrianPreference(default='', docs=''' Compiler to use (uses default if empty) Should be gcc or msvc. '''), extra_compile_args=BrianPreference(default=None, validator=lambda v: True, docs=''' Extra arguments to pass to compiler (if None, use either ``extra_compile_args_gcc`` or ``extra_compile_args_msvc``). '''), extra_compile_args_gcc=BrianPreference( default=['-w', '-O3', '-ffast-math', '-march=native'], docs=''' Extra compile arguments to pass to GCC compiler '''), extra_compile_args_msvc=BrianPreference( default=['/Ox', '/EHsc', '/w', '/fp:fast', msvc_arch_flag],
class ParallelisationError(Exception): pass # Preferences prefs.register_preferences( 'codegen.generators.cuda', 'CUDA codegen preferences', default_functions_integral_convertion=BrianPreference( docs='''The floating point precision to which integral types will be converted when passed as arguments to default functions that have no integral type overload in device code (sin, cos, tan, sinh, cosh, tanh, exp, log, log10, sqrt, ceil, floor, arcsin, arccos, arctan)." NOTE: Convertion from 32bit and 64bit integral types to single precision (32bit) floating-point types is not type safe. And convertion from 64bit integral types to double precision (64bit) floating-point types neither. In those cases the closest higher or lower (implementation defined) representable value will be selected.''', validator=default_float_dtype_validator, representor=dtype_repr, default=np.float64), use_atomics=BrianPreference( docs='''Weather to try to use atomic operations for synaptic effect application. Since this avoids race conditions, effect application can be parallelised.''', validator=lambda v: isinstance(v, bool), default=True) ) #TODO: Check from python side the CC and CUDA runtime version and only add
'has to be existing directory' % (val))) if any(not os.path.isfile(os.path.join(val, 'gsl', filename)) for filename in ['gsl_odeiv2.h', 'gsl_errno.h', 'gsl_matrix.h']): raise PreferenceError(('Illegal value for GSL directory: %s, ' 'has to contain gsl_odeiv2.h, gsl_errno.h ' 'and gsl_matrix.h' % (val))) return True prefs.register_preferences( 'GSL', 'Directory containing GSL code', directory=BrianPreference( validator=valid_gsl_dir, docs= ("Set path to directory containing GSL header files (gsl_odeiv2.h etc.)" "\nIf this directory is already in Python's include (e.g. because of " "conda installation), this path can be set to None."), default=None)) class GSLCodeGenerator(object): ''' GSL code generator. Notes ----- Approach is to first let the already existing code generator for a target language do the bulk of the translating from abstract_code to actual code. This generated code is slightly adapted to render it GSL compatible. The most critical part here is that the vector_code that is normally
''' Definitions, documentation, default values and validation functions for core Brian preferences. ''' from numpy import float64 from brian2.core.preferences import BrianPreference, brian_prefs def dtype_repr(dtype): return dtype.__name__ brian_prefs.register_preferences('core', 'Core Brian preferences', default_scalar_dtype=BrianPreference( default=float64, docs=''' Default dtype for all arrays of scalars (state variables, weights, etc.).' ''', representor=dtype_repr, ) )