Changeset 2907

Show
Ignore:
Timestamp:
01/12/12 17:03:15 (17 months ago)
Author:
thesamovar
Message:
 
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/brian/experimental/cuda/briantonemo.py

    r2906 r2907  
    2828 
    2929_created_connection = False 
     30 
     31_created_network = False 
    3032 
    3133class NemoConnection(DelayConnection): 
     
    109111            self.target._S[self.nstate] += inh 
    110112 
     113 
     114class NemoNetworkPropagate(NetworkOperation): 
     115    def __init__(self, net): 
     116        self.net = net 
     117        self.when = 'after_connections' 
     118    def __call__(self): 
     119        spikes = hstack(self.net.nemo_spikes, dtype=uint32) 
     120        self.net.nemo_spikes = [] 
     121        spikes_ptr = spikes.ctypes.data 
     122        spikes_len = len(spikes) 
     123        exc_ptr, inh_ptr = tuple(self.nemo_sim.propagate(spikes_ptr, spikes_len)) 
     124        N = self.net.total_neurons 
     125        exc = numpy_array_from_memory(exc_ptr, N, float32) 
     126        inh = numpy_array_from_memory(inh_ptr, N, float32) 
     127        for G in self.net.groups: 
     128            target_offset = self.net.group_offset[id(G)] 
     129            #TODO: need to handle different target states with different neurons 
     130            #self.target._S[self.nstate] += exc 
     131            #self.target._S[self.nstate] += inh 
     132 
     133class NemoNetworkConnectionPropagate(object): 
     134    def __init__(self, net, source_offset, target_offset): 
     135        set.net = net 
     136        self.source_offset = source_offset 
     137        self.target_offset = target_offset 
     138    def __call__(self, C, spikes): 
     139        self.net.nemo_spikes.append(spikes+self.source_offset) 
     140 
     141class NemoNetwork(Network): 
     142    def prepare(self): 
     143        global _created_network 
     144        if _created_network: 
     145            raise NotImplementedError("Current version only supports a single run.") 
     146        _created_network = True 
     147 
     148        # add a NetworkOperation that will be used to carry out the propagation 
     149        # by NeMo 
     150        nemo_propagate = NemoNetworkPropagate(self) 
     151        self.add(nemo_propagate) 
     152        self.nemo_spikes = [] 
     153         
     154        Network.prepare(self) 
     155         
     156        if hasattr(self, 'clocks') and len(self.clocks)>1: 
     157            raise NotImplementedError("Current version only supports a single clock.") 
     158         
     159        # combine all groups into one meta-group for NeMo, store the offsets 
     160        self.group_offset = group_offset = {} 
     161        self.total_neurons = total_neurons = 0 
     162        for G in self.groups: 
     163            group_offset[id(G)] = total_neurons 
     164            total_neurons += len(G) 
     165 
     166        # now upload to nemo 
     167        self.nemo_net = nemo.Network() 
     168        if pycuda is not None: 
     169            self.nemo_use_gpu = False 
     170            log_warn('brian.experimental.cuda.briantonemo', 
     171                     'GPU available but not yet supported, using CPU.') 
     172        else: 
     173            self.nemo_use_gpu = False 
     174 
     175        # create dummy neurons 
     176        self.nemo_input_neuron_idx = self.nemo_net.add_neuron_type('Input') 
     177        self.nemo_net.add_neuron(self.nemo_input_neuron_idx, 
     178                                 range(total_neurons)) 
     179 
     180        # add connections and upload synapses to nemo 
     181        for C in self.connections: 
     182            # check limitations 
     183            if C.__class__ is not DelayConnection: 
     184                raise NotImplementedError("Only DelayConnections supported at the moment.") 
     185            if not isinstance(C.W[0, :], SparseConnectionVector): 
     186                raise NotImplementedError("Current version only supports sparse matrix types.") 
     187             
     188            source_offset = group_offset[id(C.source)] 
     189            target_offset = group_offset[id(C.target)] 
     190            dt = C.source.clock.dt 
     191            C.propagate = NemoNetworkConnectionPropagate(self, source_offset, 
     192                                                         target_offset) 
     193            # create synapses 
     194            for i in xrange(len(C.source)): 
     195                Wrow = self.W[i, :] 
     196                Wdelay = self.delay[i, :] 
     197                ind = (Wrow.ind+target_offset).tolist() 
     198                delay = asarray(Wdelay/dt, dtype=int).tolist() 
     199                if amax(delay)>=64: 
     200                    raise NotImplementedError("Current version of NeMo has a maximum delay of 64 steps.") 
     201                weight = asarray(Wrow, dtype=float32).tolist() 
     202                if len(ind): 
     203                    self.nemo_net.add_synapse(i+source_offset, ind, delay, 
     204                                              weight, False) 
     205 
     206        # configure 
     207        self.nemo_conf = nemo.Configuration() 
     208        if self.nemo_use_gpu: 
     209            self.nemo_conf.set_cuda_backend(0) 
     210        else: 
     211            self.nemo_conf.set_cpu_backend() 
     212        # simulation object 
     213        self.nemo_sim = nemo.Simulation(self.nemo_net, self.nemo_conf)