def initialize_gpu(self): # Select integration scheme according to method if self.method == 'Euler': scheme = euler_scheme elif self.method == 'RK': scheme = rk2_scheme elif self.method == 'exponential_Euler': scheme = exp_euler_scheme else: raise Exception("The numerical integration method is not valid") self.mf = GPUModelFitting(self.group, self.model, self.criterion_object, self.input_var, self.neurons/self.groups, self.onset, statemonitor_var = self.statemonitor_var, spikemonitor = self.spikemonitor, nbr_spikes = self.nbr_spikes, duration = self.sliced_duration, precision=self.precision, scheme=scheme)
class Simulator(object): def __init__( self, model, reset, threshold, inputs, input_var='I', dt=defaultclock.dt, refractory=0 * ms, max_refractory=None, spikes=None, traces=None, groups=1, slices=1, overlap=0 * second, onset=0 * second, neurons=1000, # = nodesize = number of neurons on this node = total number of neurons/slices initial_values=None, unit_type='CPU', stepsize=100 * ms, precision='double', criterion=None, statemonitor_var=None, method='Euler'): self.model = model self.reset = reset self.threshold = threshold self.inputs = inputs self.input_var = input_var self.dt = dt self.refractory = refractory self.max_refractory = max_refractory self.spikes = spikes self.traces = traces self.initial_values = initial_values self.groups = groups self.slices = slices self.overlap = overlap self.onset = onset self.neurons = neurons self.unit_type = unit_type self.statemonitor_var = statemonitor_var self.stepsize = stepsize self.precision = precision self.criterion = criterion self.method = method self.use_gpu = self.unit_type == 'GPU' if self.statemonitor_var is not None: self.statemonitor_values = zeros(self.neurons) self.initialize_neurongroup() self.transform_data() self.inject_input() self.initialize_criterion(delays=zeros(self.neurons)) if self.use_gpu: self.initialize_gpu() def initialize_neurongroup(self): # Add 'refractory' parameter on the CPU only if not self.use_gpu: if self.max_refractory is not None: refractory = 'refractory' self.model.add_param('refractory', second) else: refractory = self.refractory else: if self.max_refractory is not None: refractory = 0 * ms else: refractory = self.refractory # Must recompile the Equations : the functions are not transfered after pickling/unpickling self.model.compile_functions() self.group = NeuronGroup(self.neurons, model=self.model, reset=self.reset, threshold=self.threshold, refractory=refractory, max_refractory=self.max_refractory, method=self.method, clock=Clock(dt=self.dt)) if self.initial_values is not None: for param, value in self.initial_values.iteritems(): self.group.state(param)[:] = value def initialize_gpu(self): # Select integration scheme according to method if self.method == 'Euler': scheme = euler_scheme elif self.method == 'RK': scheme = rk2_scheme elif self.method == 'exponential_Euler': scheme = exp_euler_scheme else: raise Exception("The numerical integration method is not valid") self.mf = GPUModelFitting(self.group, self.model, self.criterion_object, self.input_var, self.onset, statemonitor_var=self.statemonitor_var, duration=self.sliced_duration, precision=self.precision, scheme=scheme) def transform_data(self): self.transformer = DataTransformer(self.neurons, self.inputs, spikes=self.spikes, traces=self.traces, dt=self.dt, slices=self.slices, overlap=self.overlap, groups=self.groups) self.total_steps = self.transformer.total_steps self.sliced_duration = self.transformer.sliced_duration self.sliced_inputs = self.transformer.slice_traces(self.inputs) self.inputs_inline, self.inputs_offset = self.transformer.transform_traces( self.sliced_inputs) if self.traces is not None: self.sliced_traces = self.transformer.slice_traces(self.traces) self.traces_inline, self.traces_offset = self.transformer.transform_traces( self.sliced_traces) else: self.sliced_traces, self.traces_inline, self.traces_offset = None, None, None if self.spikes is not None: self.sliced_spikes = self.transformer.slice_spikes(self.spikes) self.spikes_inline, self.spikes_offset = self.transformer.transform_spikes( self.sliced_spikes) else: self.sliced_spikes, self.spikes_inline, self.spikes_offset = None, None, None def inject_input(self): # Injects current in consecutive subgroups, where I_offset have the same value # on successive intervals I_offset = self.inputs_offset k = -1 for i in hstack((nonzero(diff(I_offset))[0], len(I_offset) - 1)): I_offset_subgroup_value = I_offset[i] I_offset_subgroup_length = i - k sliced_subgroup = self.group.subgroup(I_offset_subgroup_length) input_sliced_values = self.inputs_inline[ I_offset_subgroup_value:I_offset_subgroup_value + self.total_steps] sliced_subgroup.set_var_by_array( self.input_var, TimedArray(input_sliced_values, clock=self.group.clock)) k = i def initialize_criterion(self, **criterion_params): # general criterion parameters params = dict(group=self.group, traces=self.sliced_traces, spikes=self.sliced_spikes, targets_count=self.groups * self.slices, duration=self.sliced_duration, onset=self.onset, spikes_inline=self.spikes_inline, spikes_offset=self.spikes_offset, traces_inline=self.traces_inline, traces_offset=self.traces_offset) for key, val in criterion_params.iteritems(): params[key] = val criterion_name = self.criterion.__class__.__name__ # criterion-specific parameters if criterion_name == 'GammaFactor': params['delta'] = self.criterion.delta params[ 'coincidence_count_algorithm'] = self.criterion.coincidence_count_algorithm self.criterion_object = GammaFactorCriterion(**params) if criterion_name == 'LpError': params['p'] = self.criterion.p params['varname'] = self.criterion.varname self.criterion_object = LpErrorCriterion(**params) def update_neurongroup(self, **param_values): """ Inject fitting parameters into the NeuronGroup """ # Sets the parameter values in the NeuronGroup object self.group.reinit() for param, value in param_values.iteritems(): self.group.state(param)[:] = kron(value, ones( self.slices)) # kron param_values if slicing # Reinitializes the model variables if self.initial_values is not None: for param, value in self.initial_values.iteritems(): self.group.state(param)[:] = value def combine_sliced_values(self, values): if type(values) is tuple: combined_values = tuple( [sum(reshape(v, (self.slices, -1)), axis=0) for v in values]) else: combined_values = sum(reshape(values, (self.slices, -1)), axis=0) return combined_values def run(self, **param_values): delays = param_values.pop('delays', zeros(self.neurons)) refractory = param_values.pop('refractory', zeros(self.neurons)) self.update_neurongroup(**param_values) # repeat spike delays and refractory to take slices into account delays = kron(delays, ones(self.slices)) refractory = kron(refractory, ones(self.slices)) # TODO: add here parameters to criterion_params if a criterion must use some parameters criterion_params = dict(delays=delays) self.update_neurongroup(**param_values) self.initialize_criterion(**criterion_params) if self.use_gpu: # Reinitializes the simulation object self.mf.reinit_vars(self.criterion_object, self.inputs_inline, self.inputs_offset, self.spikes_inline, self.spikes_offset, self.traces_inline, self.traces_offset, delays, refractory) # LAUNCHES the simulation on the GPU self.mf.launch(self.sliced_duration, self.stepsize) # Synchronize the GPU values with a call to gpuarray.get() self.criterion_object.update_gpu_values() else: # set the refractory period if self.max_refractory is not None: self.group.refractory = refractory # Launch the simulation on the CPU self.group.clock.reinit() net = Network(self.group, self.criterion_object) if self.statemonitor_var is not None: self.statemonitor = StateMonitor(self.group, self.statemonitor_var, record=True) net.add(self.statemonitor) net.run(self.sliced_duration) sliced_values = self.criterion_object.get_values() combined_values = self.combine_sliced_values(sliced_values) values = self.criterion_object.normalize(combined_values) return values def get_statemonitor_values(self): if not self.use_gpu: return self.statemonitor.values else: return self.mf.get_statemonitor_values()
class Simulator(object): def __init__(self, model, reset, threshold, inputs, input_var = 'I', dt = defaultclock.dt, refractory = 0*ms, max_refractory = None, spikes = None, traces = None, groups = 1, slices = 1, overlap = 0*second, onset = 0*second, neurons = 1000, # = nodesize = number of neurons on this node = (total number of neurons on this node)/(number of slices) initial_values = None, unit_type = 'CPU', stepsize = 128*ms, precision = 'double', criterion = None, statemonitor_var=None, spikemonitor = False, nbr_spikes = 200, ntrials=1, method = 'Euler', # stand_alone=False, # neuron_group=None, # given_neuron_group=False ): # print refractory, max_refractory # self.neuron_group = neuron_group # self.given_neuron_group = False # self.stand_alone = given_neuron_group self.model = model self.reset = reset self.threshold = threshold self.inputs = inputs self.input_var = input_var self.dt = dt self.refractory = refractory self.max_refractory = max_refractory self.spikes = spikes self.traces = traces self.initial_values = initial_values self.groups = groups self.slices = slices self.overlap = overlap self.ntrials=ntrials self.onset = onset self.neurons = neurons self.unit_type = unit_type if type(statemonitor_var) is not list and statemonitor_var is not None: statemonitor_var = [statemonitor_var] self.statemonitor_var = statemonitor_var self.spikemonitor=spikemonitor self.nbr_spikes = nbr_spikes self.stepsize = stepsize self.precision = precision self.criterion = criterion self.method = method self.use_gpu = self.unit_type=='GPU' if self.statemonitor_var is not None: self.statemonitor_values = [zeros(self.neurons)]*len(statemonitor_var) self.initialize_neurongroup() self.transform_data() self.inject_input() if self.criterion.__class__.__name__ == 'Brette': self.initialize_criterion(delays=zeros(self.neurons),tau_metric=zeros(self.neurons)) else: self.initialize_criterion(delays=zeros(self.neurons)) if self.use_gpu: self.initialize_gpu() def initialize_neurongroup(self): # Add 'refractory' parameter on the CPU only if not self.use_gpu: if self.max_refractory is not None: refractory = 'refractory' self.model.add_param('refractory', second) else: refractory = self.refractory else: if self.max_refractory is not None: refractory = 0*ms else: refractory = self.refractory # Must recompile the Equations : the functions are not transfered after pickling/unpickling self.model.compile_functions() # print refractory, self.max_refractory if type(refractory) is double: refractory=refractory*second # if self.give_neuron_group == False: self.group = NeuronGroup(self.neurons, # TODO: * slices? model=self.model, reset=self.reset, threshold=self.threshold, refractory=refractory, max_refractory = self.max_refractory, method = self.method, clock=Clock(dt=self.dt)) if self.initial_values is not None: for param, value in self.initial_values.iteritems(): self.group.state(param)[:] = value # else: # self.group = self.neuron_group def initialize_gpu(self): # Select integration scheme according to method if self.method == 'Euler': scheme = euler_scheme elif self.method == 'RK': scheme = rk2_scheme elif self.method == 'exponential_Euler': scheme = exp_euler_scheme else: raise Exception("The numerical integration method is not valid") self.mf = GPUModelFitting(self.group, self.model, self.criterion_object, self.input_var, self.neurons/self.groups, self.onset, statemonitor_var = self.statemonitor_var, spikemonitor = self.spikemonitor, nbr_spikes = self.nbr_spikes, duration = self.sliced_duration, precision=self.precision, scheme=scheme) def transform_data(self): self.transformer = DataTransformer(self.neurons, self.inputs, spikes = self.spikes, traces = self.traces, dt = self.dt, slices = self.slices, overlap = self.overlap, groups = self.groups,ntrials=self.ntrials) self.total_steps = self.transformer.total_steps self.sliced_duration = self.transformer.sliced_duration if self.ntrials>1: self.inputs_inline = self.inputs.flatten() self.sliced_inputs = self.inputs self.inputs_offset = zeros(self.neurons) else: self.sliced_inputs = self.transformer.slice_traces(self.inputs) self.inputs_inline, self.inputs_offset = self.transformer.transform_traces(self.sliced_inputs) if self.traces is not None: self.sliced_traces = self.transformer.slice_traces(self.traces) self.traces_inline, self.traces_offset = self.transformer.transform_traces(self.sliced_traces) else: self.sliced_traces, self.traces_inline, self.traces_offset = None, None, None if self.spikes is not None: if self.ntrials>1: self.sliced_spikes = self.transformer.slice_spikes(self.spikes) self.spikes_inline, self.trials_offset = self.transformer.transform_trials(self.spikes) self.spikes_offset = zeros((self.neurons),dtype=int) else: self.sliced_spikes = self.transformer.slice_spikes(self.spikes) self.spikes_inline, self.spikes_offset = self.transformer.transform_spikes(self.sliced_spikes) self.trials_offset=[0] else: self.sliced_spikes, self.spikes_inline, self.spikes_offset,self.trials_offset = None, None, None, None def inject_input(self): # Injects current in consecutive subgroups, where I_offset have the same value # on successive intervals I_offset = self.inputs_offset k = -1 for i in hstack((nonzero(diff(I_offset))[0], len(I_offset) - 1)): I_offset_subgroup_value = I_offset[i] I_offset_subgroup_length = i - k sliced_subgroup = self.group.subgroup(I_offset_subgroup_length) input_sliced_values = self.inputs_inline[I_offset_subgroup_value:I_offset_subgroup_value + self.total_steps] sliced_subgroup.set_var_by_array(self.input_var, TimedArray(input_sliced_values, clock=self.group.clock)) k = i def initialize_criterion(self, **criterion_params): # general criterion parameters params = dict(group=self.group, traces=self.sliced_traces, spikes=self.sliced_spikes, targets_count=self.groups*self.slices, duration=self.sliced_duration, onset=self.onset, spikes_inline=self.spikes_inline, spikes_offset=self.spikes_offset, traces_inline=self.traces_inline, traces_offset=self.traces_offset,trials_offset=self.trials_offset) for key,val in criterion_params.iteritems(): params[key] = val criterion_name = self.criterion.__class__.__name__ # criterion-specific parameters if criterion_name == 'GammaFactor': params['delta'] = self.criterion.delta params['coincidence_count_algorithm'] = self.criterion.coincidence_count_algorithm params['fr_weight'] = self.criterion.fr_weight self.criterion_object = GammaFactorCriterion(**params) if criterion_name == 'GammaFactor2': params['delta'] = self.criterion.delta params['coincidence_count_algorithm'] = self.criterion.coincidence_count_algorithm params['fr_weight'] = self.criterion.fr_weight params['nlevels'] = self.criterion.nlevels params['level_duration'] = self.criterion.level_duration self.criterion_object = GammaFactorCriterion2(**params) if criterion_name == 'LpError': params['p'] = self.criterion.p params['varname'] = self.criterion.varname params['method'] = self.criterion.method params['insets'] = self.criterion.insets params['outsets'] = self.criterion.outsets params['points'] = self.criterion.points self.criterion_object = LpErrorCriterion(**params) if criterion_name == 'VanRossum': params['tau'] = self.criterion.tau self.criterion_object = VanRossumCriterion(**params) if criterion_name == 'Brette': self.criterion_object = BretteCriterion(**params) def update_neurongroup(self, **param_values): """ Inject fitting parameters into the NeuronGroup """ # Sets the parameter values in the NeuronGroup object self.group.reinit() for param, value in param_values.iteritems(): self.group.state(param)[:] = kron(value, ones(self.slices)) # kron param_values if slicing # Reinitializes the model variables if self.initial_values is not None: for param, value in self.initial_values.iteritems(): self.group.state(param)[:] = value def combine_sliced_values(self, values): if type(values) is tuple: combined_values = tuple([sum(reshape(v, (self.slices, -1)), axis=0) for v in values]) else: combined_values = sum(reshape(values, (self.slices, -1)), axis=0) return combined_values def run(self, **param_values): delays = param_values.pop('delays', zeros(self.neurons)) # print self.refractory,self.max_refractory if self.max_refractory is not None: refractory = param_values.pop('refractory', zeros(self.neurons)) else: refractory = self.refractory*ones(self.neurons) tau_metric = param_values.pop('tau_metric', zeros(self.neurons)) self.update_neurongroup(**param_values) # repeat spike delays and refractory to take slices into account delays = kron(delays, ones(self.slices)) refractory = kron(refractory, ones(self.slices)) tau_metric = kron(tau_metric, ones(self.slices)) # TODO: add here parameters to criterion_params if a criterion must use some parameters criterion_params = dict(delays=delays) if self.criterion.__class__.__name__ == 'Brette': criterion_params['tau_metric'] = tau_metric self.update_neurongroup(**param_values) self.initialize_criterion(**criterion_params) if self.use_gpu: # Reinitializes the simulation object self.mf.reinit_vars(self.criterion_object, self.inputs_inline, self.inputs_offset, self.spikes_inline, self.spikes_offset, self.traces_inline, self.traces_offset, delays, refractory ) # LAUNCHES the simulation on the GPU self.mf.launch(self.sliced_duration, self.stepsize) # Synchronize the GPU values with a call to gpuarray.get() self.criterion_object.update_gpu_values() else: # set the refractory period if self.max_refractory is not None: self.group.refractory = refractory # Launch the simulation on the CPU self.group.clock.reinit() net = Network(self.group, self.criterion_object) if self.statemonitor_var is not None: self.statemonitors = [] for state in self.statemonitor_var: monitor = StateMonitor(self.group, state, record=True) self.statemonitors.append(monitor) net.add(monitor) net.run(self.sliced_duration) sliced_values = self.criterion_object.get_values() combined_values = self.combine_sliced_values(sliced_values) values = self.criterion_object.normalize(combined_values) return values def get_statemonitor_values(self): if not self.use_gpu: return [monitor.values for monitor in self.statemonitors] else: return self.mf.get_statemonitor_values() def get_spikemonitor_values(self): if not self.use_gpu: return [monitor.values for monitor in self.statemonitors] else: return self.mf.get_spikemonitor_values()
class Simulator(object): def __init__( self, model, reset, threshold, inputs, input_var="I", dt=defaultclock.dt, refractory=0 * ms, max_refractory=None, spikes=None, traces=None, groups=1, slices=1, overlap=0 * second, onset=0 * second, neurons=1000, # = nodesize = number of neurons on this node = total number of neurons/slices initial_values=None, unit_type="CPU", stepsize=100 * ms, precision="double", criterion=None, statemonitor_var=None, method="Euler", ): self.model = model self.reset = reset self.threshold = threshold self.inputs = inputs self.input_var = input_var self.dt = dt self.refractory = refractory self.max_refractory = max_refractory self.spikes = spikes self.traces = traces self.initial_values = initial_values self.groups = groups self.slices = slices self.overlap = overlap self.onset = onset self.neurons = neurons self.unit_type = unit_type self.statemonitor_var = statemonitor_var self.stepsize = stepsize self.precision = precision self.criterion = criterion self.method = method self.use_gpu = self.unit_type == "GPU" if self.statemonitor_var is not None: self.statemonitor_values = zeros(self.neurons) self.initialize_neurongroup() self.transform_data() self.inject_input() self.initialize_criterion(delays=zeros(self.neurons)) if self.use_gpu: self.initialize_gpu() def initialize_neurongroup(self): # Add 'refractory' parameter on the CPU only if not self.use_gpu: if self.max_refractory is not None: refractory = "refractory" self.model.add_param("refractory", second) else: refractory = self.refractory else: if self.max_refractory is not None: refractory = 0 * ms else: refractory = self.refractory # Must recompile the Equations : the functions are not transfered after pickling/unpickling self.model.compile_functions() self.group = NeuronGroup( self.neurons, model=self.model, reset=self.reset, threshold=self.threshold, refractory=refractory, max_refractory=self.max_refractory, method=self.method, clock=Clock(dt=self.dt), ) if self.initial_values is not None: for param, value in self.initial_values.iteritems(): self.group.state(param)[:] = value def initialize_gpu(self): # Select integration scheme according to method if self.method == "Euler": scheme = euler_scheme elif self.method == "RK": scheme = rk2_scheme elif self.method == "exponential_Euler": scheme = exp_euler_scheme else: raise Exception("The numerical integration method is not valid") self.mf = GPUModelFitting( self.group, self.model, self.criterion_object, self.input_var, self.onset, statemonitor_var=self.statemonitor_var, duration=self.sliced_duration, precision=self.precision, scheme=scheme, ) def transform_data(self): self.transformer = DataTransformer( self.neurons, self.inputs, spikes=self.spikes, traces=self.traces, dt=self.dt, slices=self.slices, overlap=self.overlap, groups=self.groups, ) self.total_steps = self.transformer.total_steps self.sliced_duration = self.transformer.sliced_duration self.sliced_inputs = self.transformer.slice_traces(self.inputs) self.inputs_inline, self.inputs_offset = self.transformer.transform_traces(self.sliced_inputs) if self.traces is not None: self.sliced_traces = self.transformer.slice_traces(self.traces) self.traces_inline, self.traces_offset = self.transformer.transform_traces(self.sliced_traces) else: self.sliced_traces, self.traces_inline, self.traces_offset = None, None, None if self.spikes is not None: self.sliced_spikes = self.transformer.slice_spikes(self.spikes) self.spikes_inline, self.spikes_offset = self.transformer.transform_spikes(self.sliced_spikes) else: self.sliced_spikes, self.spikes_inline, self.spikes_offset = None, None, None def inject_input(self): # Injects current in consecutive subgroups, where I_offset have the same value # on successive intervals I_offset = self.inputs_offset k = -1 for i in hstack((nonzero(diff(I_offset))[0], len(I_offset) - 1)): I_offset_subgroup_value = I_offset[i] I_offset_subgroup_length = i - k sliced_subgroup = self.group.subgroup(I_offset_subgroup_length) input_sliced_values = self.inputs_inline[ I_offset_subgroup_value : I_offset_subgroup_value + self.total_steps ] sliced_subgroup.set_var_by_array(self.input_var, TimedArray(input_sliced_values, clock=self.group.clock)) k = i def initialize_criterion(self, **criterion_params): # general criterion parameters params = dict( group=self.group, traces=self.sliced_traces, spikes=self.sliced_spikes, targets_count=self.groups * self.slices, duration=self.sliced_duration, onset=self.onset, spikes_inline=self.spikes_inline, spikes_offset=self.spikes_offset, traces_inline=self.traces_inline, traces_offset=self.traces_offset, ) for key, val in criterion_params.iteritems(): params[key] = val criterion_name = self.criterion.__class__.__name__ # criterion-specific parameters if criterion_name == "GammaFactor": params["delta"] = self.criterion.delta params["coincidence_count_algorithm"] = self.criterion.coincidence_count_algorithm self.criterion_object = GammaFactorCriterion(**params) if criterion_name == "LpError": params["p"] = self.criterion.p params["varname"] = self.criterion.varname self.criterion_object = LpErrorCriterion(**params) def update_neurongroup(self, **param_values): """ Inject fitting parameters into the NeuronGroup """ # Sets the parameter values in the NeuronGroup object self.group.reinit() for param, value in param_values.iteritems(): self.group.state(param)[:] = kron(value, ones(self.slices)) # kron param_values if slicing # Reinitializes the model variables if self.initial_values is not None: for param, value in self.initial_values.iteritems(): self.group.state(param)[:] = value def combine_sliced_values(self, values): if type(values) is tuple: combined_values = tuple([sum(reshape(v, (self.slices, -1)), axis=0) for v in values]) else: combined_values = sum(reshape(values, (self.slices, -1)), axis=0) return combined_values def run(self, **param_values): delays = param_values.pop("delays", zeros(self.neurons)) refractory = param_values.pop("refractory", zeros(self.neurons)) self.update_neurongroup(**param_values) # repeat spike delays and refractory to take slices into account delays = kron(delays, ones(self.slices)) refractory = kron(refractory, ones(self.slices)) # TODO: add here parameters to criterion_params if a criterion must use some parameters criterion_params = dict(delays=delays) self.update_neurongroup(**param_values) self.initialize_criterion(**criterion_params) if self.use_gpu: # Reinitializes the simulation object self.mf.reinit_vars( self.criterion_object, self.inputs_inline, self.inputs_offset, self.spikes_inline, self.spikes_offset, self.traces_inline, self.traces_offset, delays, refractory, ) # LAUNCHES the simulation on the GPU self.mf.launch(self.sliced_duration, self.stepsize) # Synchronize the GPU values with a call to gpuarray.get() self.criterion_object.update_gpu_values() else: # set the refractory period if self.max_refractory is not None: self.group.refractory = refractory # Launch the simulation on the CPU self.group.clock.reinit() net = Network(self.group, self.criterion_object) if self.statemonitor_var is not None: self.statemonitor = StateMonitor(self.group, self.statemonitor_var, record=True) net.add(self.statemonitor) net.run(self.sliced_duration) sliced_values = self.criterion_object.get_values() combined_values = self.combine_sliced_values(sliced_values) values = self.criterion_object.normalize(combined_values) return values def get_statemonitor_values(self): if not self.use_gpu: return self.statemonitor.values else: return self.mf.get_statemonitor_values()