diff --git a/.gitmodules b/.gitmodules index bf6221c8..128db7c6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ -[submodule "brian2_frozen"] - path = frozen_repos/brian2 - url = https://github.com/brian-team/brian2.git [submodule "genn_frozen"] path = frozen_repos/genn url = https://github.com/genn-team/genn.git [submodule "brian2genn_frozen"] path = frozen_repos/brian2genn url = https://github.com/brian-team/brian2genn.git +[submodule "frozen_repos/brian2"] + path = frozen_repos/brian2 + url = https://github.com/denisalevi/brian2.git diff --git a/brian2cuda/brianlib/spikequeue.h b/brian2cuda/brianlib/spikequeue.h index 01baf9b1..437cff3a 100644 --- a/brian2cuda/brianlib/spikequeue.h +++ b/brian2cuda/brianlib/spikequeue.h @@ -14,7 +14,6 @@ using namespace std; // variables (delays, dt) are assumed to use the same data type typedef int32_t DTYPE_int; -template class CudaSpikeQueue { private: @@ -74,7 +73,7 @@ class CudaSpikeQueue int tid, int num_threads, int _num_blocks, - scalar _dt, + double _dt, int _neuron_N, int _syn_N, int _num_queues, diff --git a/brian2cuda/cuda_generator.py b/brian2cuda/cuda_generator.py index 55c78411..c22f2fe2 100644 --- a/brian2cuda/cuda_generator.py +++ b/brian2cuda/cuda_generator.py @@ -33,8 +33,8 @@ 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') + validator=lambda v: v in ['float32', 'float64'], + default='float64') ) @@ -258,7 +258,7 @@ def translate_one_statement_sequence(self, statements, scalar=False): brian_funcs = re.search('_brian_(' + '|'.join(functions_C99) + ')', line) if brian_funcs is not None: for identifier in get_identifiers(line): - if convertion_pref == 'double_precision': + if convertion_pref == 'float64': # 64bit integer to floating-point conversions are not type safe int64_type = re.search(r'\bu?int64_t\s*{}\b'.format(identifier), code) if int64_type is not None: @@ -269,20 +269,20 @@ def translate_one_statement_sequence(self, statements, scalar=False): "statement:\n\t{}\nGenerated from abstract code statements:\n\t{}\n".format(line, statements), once=True) self.warned_integral_convertion = True - self.previous_convertion_pref = 'double_precision' - else: # convertion_pref = 'single_precision' + self.previous_convertion_pref = 'float64' + else: # convertion_pref = 'float32' # 32bit and 64bit integer to floating-point conversions are not type safe int32_64_type = re.search(r'\bu?int(32|64)_t\s*{}\b'.format(identifier), code) if int32_64_type is not None: logger.warn("Detected code statement with default function and 32bit or 64bit integer type in the same line and the " - "preference for default_functions_integral_convertion is 'single_precision'. " + "preference for default_functions_integral_convertion is 'float32'. " "Using 32bit or 64bit integer types as default function arguments is not type safe due to convertion of " "integer to single-precision floating-point types in device code. (relevant functions: sin, cos, tan, sinh, " "cosh, tanh, exp, log, log10, sqrt, ceil, floor, arcsin, arccos, arctan)\nDetected code " "statement:\n\t{}\nGenerated from abstract code statements:\n\t{}\n".format(line, statements), once=True) self.warned_integral_convertion = True - self.previous_convertion_pref = 'single_precision' + self.previous_convertion_pref = 'float32' return stripped_deindented_lines(code) def denormals_to_zero_code(self): @@ -374,10 +374,10 @@ def determine_keywords(self): support_code = '' hash_defines = '' # set convertion types for standard C99 functions in device code - if prefs.codegen.generators.cuda.default_functions_integral_convertion == 'double_precision': + if prefs.codegen.generators.cuda.default_functions_integral_convertion == 'float64': default_func_type = 'double' other_func_type = 'float' - else: # 'single_precision' + else: # 'float32' default_func_type = 'float' other_func_type = 'double' for varname, variable in self.variables.items(): diff --git a/brian2cuda/device.py b/brian2cuda/device.py index 07f88f00..8a8a5ac1 100644 --- a/brian2cuda/device.py +++ b/brian2cuda/device.py @@ -69,13 +69,6 @@ validator=lambda v: isinstance(v, int) and v >= 0, default=128), - curand_float_type=BrianPreference( - docs=''' - Floating point type of generated random numbers (float/double). - ''', - validator=lambda v: v in ['float', 'double'], - default='float'), - launch_bounds=BrianPreference( docs=''' Weather or not to use `__launch_bounds__` to optimise register usage in kernels. @@ -266,9 +259,9 @@ def code_object(self, owner, name, abstract_code, variables, template_name, for varname in variables.iterkeys(): if varname in read_write: idx = variable_indices[varname] - if idx == '_presynaptic_idx': + if idx == '_presynaptic_idx' or varname == 'i': self.delete_synaptic_pre[synaptic_pre_array_name] = False - if idx == '_postsynaptic_idx': + if idx == '_postsynaptic_idx' or varname == 'j': self.delete_synaptic_post[synaptic_post_array_name] = False if template_name == "synapses": prepost = template_kwds['pathway'].prepost @@ -343,7 +336,7 @@ def generate_objects_source(self, writer, arange_arrays, synapses, static_array_ num_parallel_blocks=num_parallel_blocks, curand_generator_type=curand_generator_type, curand_generator_ordering=curand_generator_ordering, - curand_float_type=prefs['devices.cuda_standalone.curand_float_type'], + curand_float_type=c_data_type(prefs['core.default_float_dtype']), eventspace_arrays=self.eventspace_arrays, multisynaptic_idx_vars=multisyn_vars, profiled_codeobjects=self.profiled_codeobjects) @@ -531,13 +524,13 @@ def generate_codeobj_source(self, writer): cudaMalloc((void**)&dev_array_randn, sizeof({dtype})*{number_elements}*{codeobj.randn_calls}) ); curandGenerateNormal{curand_suffix}(curand_generator, dev_array_randn, {number_elements}*{codeobj.randn_calls}, 0, 1); - '''.format(number_elements=number_elements, codeobj=codeobj, dtype=prefs['devices.cuda_standalone.curand_float_type'], - curand_suffix='Double' if prefs['devices.cuda_standalone.curand_float_type']=='double' else '') + '''.format(number_elements=number_elements, codeobj=codeobj, dtype=c_data_type(prefs['core.default_float_dtype']), + curand_suffix='Double' if prefs['core.default_float_dtype']=='float64' else '') additional_code.append(code_snippet) - line = "{dtype}* par_array_{name}_randn".format(dtype=prefs['devices.cuda_standalone.curand_float_type'], name=codeobj.name) + line = "{dtype}* par_array_{name}_randn".format(dtype=c_data_type(prefs['core.default_float_dtype']), name=codeobj.name) device_parameters_lines.append(line) - kernel_variables_lines.append("{dtype}* _ptr_array_{name}_randn = par_array_{name}_randn;".format(dtype=prefs['devices.cuda_standalone.curand_float_type'], - name=codeobj.name)) + kernel_variables_lines.append("{dtype}* _ptr_array_{name}_randn = par_array_{name}_randn;".format(dtype=c_data_type(prefs['core.default_float_dtype']), + name=codeobj.name)) host_parameters_lines.append("dev_array_randn") elif k == "_python_rand" and codeobj.runs_every_tick == False and codeobj.template_name != "synapses_create_generator": code_snippet = ''' @@ -547,13 +540,13 @@ def generate_codeobj_source(self, writer): cudaMalloc((void**)&dev_array_rand, sizeof({dtype})*{number_elements}*{codeobj.rand_calls}) ); curandGenerateUniform{curand_suffix}(curand_generator, dev_array_rand, {number_elements}*{codeobj.rand_calls}); - '''.format(number_elements=number_elements, codeobj=codeobj, dtype=prefs['devices.cuda_standalone.curand_float_type'], - curand_suffix='Double' if prefs['devices.cuda_standalone.curand_float_type']=='double' else '') + '''.format(number_elements=number_elements, codeobj=codeobj, dtype=c_data_type(prefs['core.default_float_dtype']), + curand_suffix='Double' if prefs['core.default_float_dtype']=='float64' else '') additional_code.append(code_snippet) - line = "{dtype}* par_array_{name}_rand".format(dtype=prefs['devices.cuda_standalone.curand_float_type'], name=codeobj.name) + line = "{dtype}* par_array_{name}_rand".format(dtype=c_data_type(prefs['core.default_float_dtype']), name=codeobj.name) device_parameters_lines.append(line) - kernel_variables_lines.append("{dtype}* _ptr_array_{name}_rand = par_array_{name}_rand;".format(dtype=prefs['devices.cuda_standalone.curand_float_type'], - name=codeobj.name)) + kernel_variables_lines.append("{dtype}* _ptr_array_{name}_rand = par_array_{name}_rand;".format(dtype=c_data_type(prefs['core.default_float_dtype']), + name=codeobj.name)) host_parameters_lines.append("dev_array_rand") elif isinstance(v, ArrayVariable): if k in ['t', 'timestep', '_clock_t', '_clock_timestep', '_source_t', '_source_timestep'] and v.scalar: # monitors have not scalar t variables @@ -605,15 +598,15 @@ def generate_codeobj_source(self, writer): # TODO can we just include this in the k == '_python_rand' test above? if codeobj.rand_calls >= 1 and codeobj.runs_every_tick: host_parameters_lines.append("dev_{name}_rand".format(name=codeobj.name)) - device_parameters_lines.append("{dtype}* par_array_{name}_rand".format(dtype=prefs['devices.cuda_standalone.curand_float_type'], + device_parameters_lines.append("{dtype}* par_array_{name}_rand".format(dtype=c_data_type(prefs['core.default_float_dtype']), name=codeobj.name)) - kernel_variables_lines.append("{dtype}* _ptr_array_{name}_rand = par_array_{name}_rand;".format(dtype=prefs['devices.cuda_standalone.curand_float_type'], + kernel_variables_lines.append("{dtype}* _ptr_array_{name}_rand = par_array_{name}_rand;".format(dtype=c_data_type(prefs['core.default_float_dtype']), name=codeobj.name)) if codeobj.randn_calls >= 1 and codeobj.runs_every_tick: host_parameters_lines.append("dev_{name}_randn".format(name=codeobj.name)) - device_parameters_lines.append("{dtype}* par_array_{name}_randn".format(dtype=prefs['devices.cuda_standalone.curand_float_type'], + device_parameters_lines.append("{dtype}* par_array_{name}_randn".format(dtype=c_data_type(prefs['core.default_float_dtype']), name=codeobj.name)) - kernel_variables_lines.append("{dtype}* _ptr_array_{name}_randn = par_array_{name}_randn;".format(dtype=prefs['devices.cuda_standalone.curand_float_type'], + kernel_variables_lines.append("{dtype}* _ptr_array_{name}_randn = par_array_{name}_randn;".format(dtype=c_data_type(prefs['core.default_float_dtype']), name=codeobj.name)) # Sometimes an array is referred to by to different keys in our @@ -663,7 +656,7 @@ def generate_rand_source(self, writer): codeobj_with_rand=codeobj_with_rand, codeobj_with_randn=codeobj_with_randn, profiled=self.enable_profiling, - curand_float_type=prefs['devices.cuda_standalone.curand_float_type']) + curand_float_type=c_data_type(prefs['core.default_float_dtype'])) writer.write('rand.*', rand_tmp) def copy_source_files(self, writer, directory): diff --git a/brian2cuda/templates/objects.cu b/brian2cuda/templates/objects.cu index 130394b0..a54cfdcf 100644 --- a/brian2cuda/templates/objects.cu +++ b/brian2cuda/templates/objects.cu @@ -75,7 +75,6 @@ const int brian::_num_{{name}} = {{N}}; //////////////// synapses ///////////////// {% for S in synapses | sort(attribute='name') %} // {{S.name}} -Synapses brian::{{S.name}}({{S.source|length}}, {{S.target|length}}); int32_t {{S.name}}_source_start_index; int32_t {{S.name}}_source_stop_index; bool brian::{{S.name}}_multiple_pre_post = false; @@ -95,7 +94,7 @@ __device__ int32_t** brian::{{path.name}}_synapse_ids_by_pre; __device__ int32_t* brian::{{path.name}}_synapse_ids; __device__ int* brian::{{path.name}}_unique_delay_start_idcs; __device__ int* brian::{{path.name}}_unique_delays_offset_by_pre; -__device__ SynapticPathway brian::{{path.name}}; +__device__ SynapticPathway brian::{{path.name}}; int brian::{{path.name}}_eventspace_idx = 0; int brian::{{path.name}}_delay; bool brian::{{path.name}}_scalar_delay; @@ -113,7 +112,6 @@ int brian::num_threads_per_warp; __global__ void {{path.name}}_init( int Nsource, int Ntarget, - double* delays, int32_t* sources, int32_t* targets, double dt, @@ -123,7 +121,7 @@ __global__ void {{path.name}}_init( { using namespace brian; - {{path.name}}.init(Nsource, Ntarget, delays, sources, targets, dt, start, stop); + {{path.name}}.init(Nsource, Ntarget, sources, targets, dt, start, stop); } {% endfor %} {% endfor %} @@ -186,7 +184,6 @@ void _init_arrays() {{path.name}}_init<<<1,1>>>( {{path.source|length}}, {{path.target|length}}, - thrust::raw_pointer_cast(&dev{{dynamic_array_specs[path.variables['delay']]}}[0]), thrust::raw_pointer_cast(&dev{{dynamic_array_specs[path.synapse_sources]}}[0]), thrust::raw_pointer_cast(&dev{{dynamic_array_specs[path.synapse_targets]}}[0]), 0, //was dt, maybe irrelevant? @@ -551,7 +548,6 @@ extern const int _num_{{name}}; //////////////// synapses ///////////////// {% for S in synapses | sort(attribute='name') %} // {{S.name}} -extern Synapses {{S.name}}; extern bool {{S.name}}_multiple_pre_post; {% for path in S._pathways | sort(attribute='name') %} extern __device__ int* {{path.name}}_num_synapses_by_pre; @@ -568,7 +564,7 @@ extern __device__ int32_t** {{path.name}}_synapse_ids_by_pre; extern __device__ int32_t* {{path.name}}_synapse_ids; extern __device__ int* {{path.name}}_unique_delay_start_idcs; extern __device__ int* {{path.name}}_unique_delays_offset_by_pre; -extern __device__ SynapticPathway {{path.name}}; +extern __device__ SynapticPathway {{path.name}}; extern int {{path.name}}_eventspace_idx; extern int {{path.name}}_delay; extern bool {{path.name}}_scalar_delay; diff --git a/brian2cuda/templates/ratemonitor.cu b/brian2cuda/templates/ratemonitor.cu index eef1670b..aa1632a7 100644 --- a/brian2cuda/templates/ratemonitor.cu +++ b/brian2cuda/templates/ratemonitor.cu @@ -41,8 +41,10 @@ __launch_bounds__(1024, {{sm_multiplier}}) {% endif %} kernel_{{codeobj_name}}( int32_t current_iteration, - double* ratemonitor_rate, - double* ratemonitor_t, + {% set c_type = c_data_type(variables['rate'].dtype) %} + {{c_type}}* ratemonitor_rate, + {% set c_type = c_data_type(variables['t'].dtype) %} + {{c_type}}* ratemonitor_t, ///// DEVICE_PARAMETERS ///// %DEVICE_PARAMETERS% ) diff --git a/brian2cuda/templates/synapses_classes.cu b/brian2cuda/templates/synapses_classes.cu index 235423ae..14172944 100644 --- a/brian2cuda/templates/synapses_classes.cu +++ b/brian2cuda/templates/synapses_classes.cu @@ -11,10 +11,6 @@ #include "brianlib/spikequeue.h" -template class Synapses; -template class SynapticPathway; - -template class SynapticPathway { public: @@ -22,7 +18,6 @@ public: int Nsource; int Ntarget; - scalar* dev_delay; int32_t* dev_sources; int32_t* dev_targets; @@ -31,23 +26,22 @@ public: int spikes_start; int spikes_stop; - scalar dt; - CudaSpikeQueue* queue; + double dt; + CudaSpikeQueue* queue; bool no_or_const_delay_mode; //our real constructor - __device__ void init(int _Nsource, int _Ntarget, scalar* d_delay, int32_t* _sources, - int32_t* _targets, scalar _dt, int _spikes_start, int _spikes_stop) + __device__ void init(int _Nsource, int _Ntarget, int32_t* _sources, + int32_t* _targets, double _dt, int _spikes_start, int _spikes_stop) { Nsource = _Nsource; Ntarget = _Ntarget; - dev_delay = d_delay; dev_sources = _sources; dev_targets = _targets; dt = _dt; spikes_start = _spikes_start; spikes_stop = _spikes_stop; - queue = new CudaSpikeQueue; + queue = new CudaSpikeQueue; }; //our real destructor @@ -57,29 +51,6 @@ public: delete queue; } }; - -template -class Synapses -{ -public: - int _N_value; - inline double _N() { return _N_value;}; - int Nsource; - int Ntarget; - std::vector< std::vector > _pre_synaptic; - std::vector< std::vector > _post_synaptic; - - Synapses(int _Nsource, int _Ntarget) - : Nsource(_Nsource), Ntarget(_Ntarget) - { - for(int i=0; i()); - for(int i=0; i()); - _N_value = 0; - }; -}; - #endif {% endmacro %} diff --git a/brian2cuda/tests/features/cuda_configuration.py b/brian2cuda/tests/features/cuda_configuration.py index 89fde343..9ddefd63 100644 --- a/brian2cuda/tests/features/cuda_configuration.py +++ b/brian2cuda/tests/features/cuda_configuration.py @@ -163,10 +163,6 @@ class CUDAStandaloneConfigurationNoAssert(CUDAStandaloneConfigurationBase): name = 'CUDA standalone (asserts disabled)' device_kwargs = {'disable_asserts': True} -class CUDAStandaloneConfigurationCurandDouble(CUDAStandaloneConfigurationBase): - name = 'CUDA standalone (curand_float_type = double)' - extra_prefs = {'devices.cuda_standalone.curand_float_type': 'double'} - class CUDAStandaloneConfigurationNoCudaOccupancyAPI(CUDAStandaloneConfigurationBase): name = 'CUDA standalone (not using cuda occupancy API)' extra_prefs = {'devices.cuda_standalone.calc_occupancy': False} diff --git a/brian2cuda/tests/test_cuda_generator.py b/brian2cuda/tests/test_cuda_generator.py index 1c55cbdf..03902306 100644 --- a/brian2cuda/tests/test_cuda_generator.py +++ b/brian2cuda/tests/test_cuda_generator.py @@ -1,4 +1,4 @@ -from nose import with_setup +from nose import with_setup, SkipTest from nose.plugins.attrib import attr from numpy.testing.utils import assert_allclose, assert_raises @@ -358,17 +358,20 @@ def test_default_function_implementations(): @with_setup(teardown=reinit_devices) def test_default_function_convertion_preference(): + if prefs.core.default_float_dtype is np.float32: + raise SkipTest('Need double precision for this test') + set_device('cuda_standalone', directory=None) unrepresentable_int = 2**24 + 1 # can't be represented as 32bit float - prefs.codegen.generators.cuda.default_functions_integral_convertion = 'single_precision' + prefs.codegen.generators.cuda.default_functions_integral_convertion = 'float32' G = NeuronGroup(1, 'v: 1') G.variables.add_array('myarr', dtype=np.int32, size=1) G.variables['myarr'].set_value(unrepresentable_int) G.v = 'floor(myarr)'.format(unrepresentable_int) - prefs.codegen.generators.cuda.default_functions_integral_convertion = 'double_precision' + prefs.codegen.generators.cuda.default_functions_integral_convertion = 'float64' G2 = NeuronGroup(1, 'v: 1') G2.variables.add_array('myarr', dtype=np.int32, size=1) G2.variables['myarr'].set_value(unrepresentable_int) @@ -377,7 +380,7 @@ def test_default_function_convertion_preference(): run(0*ms) assert G.v[0] != unrepresentable_int, G.v[0] - assert G2.v[0] == unrepresentable_int, G.v2[0] + assert G2.v[0] == unrepresentable_int, '{} != {}'.format(G2.v[0], unrepresentable_int) @attr('cuda_standalone', 'standalone-only') @@ -414,7 +417,7 @@ def test_default_function_convertion_warnings(): G4.variables.add_array('myarr', dtype=np.uint32, size=1) G4.v = 'arcsin(i*myarr)' - prefs.codegen.generators.cuda.default_functions_integral_convertion = 'single_precision' + prefs.codegen.generators.cuda.default_functions_integral_convertion = 'float32' BrianLogger._log_messages.clear() with catch_logs() as logs5: diff --git a/brian2cuda/tools/run_single_test.py b/brian2cuda/tools/run_single_test.py index 2423c153..bb4bcd59 100644 --- a/brian2cuda/tools/run_single_test.py +++ b/brian2cuda/tools/run_single_test.py @@ -12,13 +12,18 @@ choices=['cuda_standalone', 'genn', 'cpp_standalone'], help=("Which codegeneration targets to use, can be multiple. " "Only standalone targets. (default=['cuda_standalone'])")) +parser.add_argument('--float-dtype', nargs=1, default=['float64'], type=str, + choices=['float32', 'float64'], help=("The " + "prefs['core.default_float_dtype'] with which tests should be run.")) parser.add_argument('--reset-prefs', action='store_true', help="Weather to reset prefs between tests or not.") args = parser.parse_args() import sys from brian2.devices.device import set_device +from brian2 import prefs import nose +import numpy as np if 'cuda_standalone' in args.targets: import brian2cuda @@ -26,7 +31,9 @@ import brian2genn for target in args.targets: - sys.stderr.write('Running test(s) {} for device {} ...\n'.format(args.test[0], target)) + prefs['core.default_float_dtype'] = getattr(np, args.float_dtype[0]) + sys.stderr.write('Running test(s) {} for device {} with float type {} ' + '...\n'.format(args.test[0], target, args.float_dtype[0])) set_device(target, directory=None, with_output=False) argv = ['nosetests', args.test[0], '-c=', # no config file loading diff --git a/brian2cuda/tools/run_test_suite.py b/brian2cuda/tools/run_test_suite.py index 36a045bd..802459fe 100644 --- a/brian2cuda/tools/run_test_suite.py +++ b/brian2cuda/tools/run_test_suite.py @@ -8,6 +8,9 @@ choices=['cuda_standalone', 'genn', 'cpp_standalone'], help=("Which codegeneration targets to use, can be multiple. " "Only standalone targets. (default='cuda_standalone')")) +parser.add_argument('--float-dtype', nargs='*', default=['float32', 'float64'], + choices=['float32', 'float64'], help=("The " + "prefs['core.default_float_dtype'] with which tests should be run.")) parser.add_argument('--no-long-tests', action='store_false', help="Set to not run long tests. By default they are run.") parser.add_argument('--no-reset-prefs', action='store_false', @@ -26,6 +29,7 @@ import os from StringIO import StringIO import socket +import numpy as np from brian2 import test, prefs import brian2cuda @@ -55,18 +59,28 @@ if args.test_parallel is None: args.test_parallel = args.targets +dtypes = [] +for dtype in args.float_dtype: + dtypes.append(getattr(np, dtype)) + +stored_prefs = prefs.as_file + for target in args.targets: test_in_parallel = [] if target in args.test_parallel: test_in_parallel = [target] - test(codegen_targets=[], - long_tests=args.no_long_tests, - test_codegen_independent=False, - test_standalone=target, - reset_preferences=False, - fail_for_not_implemented=args.fail_not_implemented, - test_in_parallel=test_in_parallel, - extra_test_dirs=extra_test_dirs - ) + for dtype in dtypes: + test(codegen_targets=[], + long_tests=args.no_long_tests, + test_codegen_independent=False, + test_standalone=target, + reset_preferences=False, + fail_for_not_implemented=args.fail_not_implemented, + test_in_parallel=test_in_parallel, + extra_test_dirs=extra_test_dirs, + float_dtype=dtype + ) + + prefs.read_preference_file(StringIO(stored_prefs)) diff --git a/brian2cuda/tools/run_test_suite_on_current_state.sh b/brian2cuda/tools/run_test_suite_on_current_state.sh index 1403d85f..0545f360 100755 --- a/brian2cuda/tools/run_test_suite_on_current_state.sh +++ b/brian2cuda/tools/run_test_suite_on_current_state.sh @@ -2,7 +2,8 @@ # arguments: # $1: additional name for log_file # $2: commit hash or branch name to check out after cloning -# $3: number of cores used for parallel compilation (make -j $3) +# $3: float32 or float64 or both (default) +# $4: number of cores used for parallel compilation (make -j $4) # the directory of the script DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" @@ -23,11 +24,28 @@ function cleanup { # register the cleanup function to be called on the EXIT signal trap cleanup EXIT -if [ -z "$3" ] +if [ -z "$4" ] then J=12 else - J=$3 + J=$4 +fi + +if [ -z "$3" ] +then + FLOAT_DTYPE="float64 float32" +elif [ "$3" = "float32" ] +then + FLOAT_DTYPE="float32" +elif [ "$3" = "float64" ] +then + FLOAT_DTYPE="float64" +elif [ "$3" = "both" ] +then + FLOAT_DTYPE="float64 float32" +else + echo "ERROR, the third argument needs to be from {'float32'|'float64'|'both'}" + exit 1 fi source activate dev_b2c @@ -45,5 +63,5 @@ fi git rev-parse --abbrev-ref HEAD 2>&1 | tee -a "LOG_FILE" git rev-parse HEAD 2>&1 | tee -a "LOG_FILE" cd "brian2cuda/tools" -PYTHONPATH="../..:../../frozen_repos/brian2:$PYTHONPATH" python run_test_suite.py --fail-not-implemented -j"$J" 2>&1 | tee -a "$LOG_FILE" +PYTHONPATH="../..:../../frozen_repos/brian2:$PYTHONPATH" python run_test_suite.py --float-dtype $FLOAT_DTYPE --fail-not-implemented -j"$J" 2>&1 | tee -a "$LOG_FILE" diff --git a/frozen_repos/brian2 b/frozen_repos/brian2 index 320a5f6b..c4f28201 160000 --- a/frozen_repos/brian2 +++ b/frozen_repos/brian2 @@ -1 +1 @@ -Subproject commit 320a5f6b36e2aa5dfe7e6b22bd46c3652ad9cc99 +Subproject commit c4f28201fb406cc10807258f1cf09ac9c5dd7524