NEST  2.6.0,not_revisioned_source_dir@0
stdp_connection_facetshw_hom.h
Go to the documentation of this file.
1 /*
2  * stdp_connection_facetshw_hom.h
3  *
4  * This file is part of NEST.
5  *
6  * Copyright (C) 2004 The NEST Initiative
7  *
8  * NEST is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * NEST is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef STDP_CONNECTION_FACETSHW_HOM_H
24 #define STDP_CONNECTION_FACETSHW_HOM_H
25 
26 /* BeginDocumentation
27  Name: stdp_facetshw_synapse_hom - Synapse type for spike-timing dependent
28  plasticity using homogeneous parameters, i.e. all synapses have the same parameters.
29 
30  Description:
31  stdp_facetshw_synapse is a connector to create synapses with spike-timing
32  dependent plasticity (as defined in [1]).
33  This connector is a modified version of stdp_synapse.
34  It includes constraints of the hardware developed in the FACETS (BrainScaleS) project [2,3],
35  as e.g. 4-bit weight resolution, sequential updates of groups of synapses
36  and reduced symmetric nearest-neighbor spike pairing scheme. For details see [3].
37  The modified spike pairing scheme requires the calculation of tau_minus_
38  within this synapse and not at the neuron site via Kplus_ like in stdp_connection_hom.
39 
40  Parameters:
41  Common properties:
42  tau_plus double - Time constant of STDP window, causal branch in ms
43  tau_minus_stdp double - Time constant of STDP window, anti-causal branch in ms
44  Wmax double - Maximum allowed weight
45 
46  no_synapses long - total number of synapses
47  synapses_per_driver long - number of synapses updated at once
48  driver_readout_time double - time for processing of one synapse row (synapse line driver)
49  readout_cycle_duration double - duration between two subsequent updates of same synapse (synapse line driver)
50  lookuptable_0 vector<long> - three look-up tables (LUT)
51  lookuptable_1 vector<long>
52  lookuptable_2 vector<long>
53  configbit_0 vector<long> - configuration bits for evaluation function.
54  For details see code in function eval_function_ and [4]
55  (configbit[0]=e_cc, ..[1]=e_ca, ..[2]=e_ac, ..[3]=e_aa).
56  Depending on these two sets of configuration bits
57  weights are updated according LUTs (out of three: (1,0), (0,1), (1,1)).
58  For (0,0) continue without reset.
59  configbit_1 vector<long>
60  reset_pattern vector<long> - configuration bits for reset behaviour.
61  Two bits for each LUT (reset causal and acausal).
62  In hardware only (all false; never reset)
63  or (all true; always reset) is allowed.
64 
65  Individual properties:
66  a_causal double - causal and anti-causal spike pair accumulations
67  a_acausal double
68  a_thresh_th double - two thresholds used in evaluation function.
69  No common property, because variation of analog synapse circuitry can be applied here
70  a_thresh_tl double
71  synapse_id long - synapse ID, used to assign synapses to groups (synapse drivers)
72 
73  Notes:
74  The synapse IDs are assigned to each synapse in an ascending order (0,1,2, ...) according their first
75  presynaptic activity and is used to group synapses that are updated at once.
76  It is possible to avoid activity dependent synapse ID assignments by manually setting the no_synapses
77  and the synapse_id(s) before running the simulation.
78  The weights will be discretized after the first presynaptic activity at a synapse.
79 
80  Transmits: SpikeEvent
81 
82  References:
83  [1] Morrison, A., Diesmann, M., and Gerstner, W. (2008).
84  Phenomenological models of synaptic plasticity based on
85  spike-timing, Biol. Cybern., 98,459--478
86 
87  [2] Schemmel, J., Gruebl, A., Meier, K., and Mueller, E. (2006).
88  Implementing synaptic plasticity in a VLSI spiking neural
89  network model, In Proceedings of the 2006 International
90  Joint Conference on Neural Networks, pp.1--6, IEEE Press
91 
92  [3] Pfeil, T., Potjans, T. C., Schrader, S., Potjans, W., Schemmel, J., Diesmann, M., & Meier, K. (2012).
93  Is a 4-bit synaptic weight resolution enough? -
94  constraints on enabling spike-timing dependent plasticity in neuromorphic hardware.
95  Front. Neurosci. 6 (90).
96 
97  [4] Friedmann, S. in preparation
98 
99 
100  FirstVersion: July 2011
101  Author: Thomas Pfeil (TP), Moritz Helias, Abigail Morrison
102  SeeAlso: stdp_synapse, synapsedict, tsodyks_synapse, static_synapse
103 */
104 
105 #include "connection.h"
107 #include <cmath>
108 
109 namespace nest
110 {
111 
112  // template class forward declaration required by common proterties friend definition
113  template<typename targetidentifierT> class STDPFACETSHWConnectionHom;
114 
118  template<typename targetidentifierT>
120  {
121  friend class STDPFACETSHWConnectionHom<targetidentifierT>;
122 
123  public:
124 
130 
134  void get_status(DictionaryDatum & d) const;
135 
139  void set_status(const DictionaryDatum & d, ConnectorModel& cm);
140 
141  // overloaded for all supported event types
143 
144  private:
149 
150 
151  // data members common to all connections
156 
157  //STDP controller parameters
162  std::vector<long_t> lookuptable_0_; //TODO: TP: size in memory could be reduced
163  std::vector<long_t> lookuptable_1_;
164  std::vector<long_t> lookuptable_2_; //TODO: TP: to save memory one could introduce vector<bool> & BoolVectorDatum
165  std::vector<long_t> configbit_0_;
166  std::vector<long_t> configbit_1_;
167  std::vector<long_t> reset_pattern_;
168  };
169 
170 
171 
175  template<typename targetidentifierT>
176  class STDPFACETSHWConnectionHom : public Connection<targetidentifierT>
177  {
178 
179  public:
180 
183 
189 
195 
196  // Explicitly declare all methods inherited from the dependent base ConnectionBase.
197  // This avoids explicit name prefixes in all places these functions are used.
198  // Since ConnectionBase depends on the template parameter, they are not automatically
199  // found in the base class.
204 
208  void get_status(DictionaryDatum & d) const;
209 
213  void set_status(const DictionaryDatum & d, ConnectorModel &cm);
214 
221 
222 
224  {
225  public:
226  // Ensure proper overriding of overloaded virtual functions.
227  // Return values from functions are ignored.
230  };
231 
232 
233  /*
234  * This function calls check_connection on the sender and checks if the receiver
235  * accepts the event type and receptor type requested by the sender.
236  * Node::check_connection() will either confirm the receiver port by returning
237  * true or false if the connection should be ignored.
238  * We have to override the base class' implementation, since for STDP
239  * connections we have to call register_stdp_connection on the target neuron
240  * to inform the Archiver to collect spikes for this connection.
241  *
242  * \param s The source node
243  * \param r The target node
244  * \param receptor_type The ID of the requested receptor type
245  * \param t_lastspike last spike produced by presynaptic neuron (in ms)
246  */
248  {
249  ConnTestDummyNode dummy_target;
250 
251  ConnectionBase::check_connection_(dummy_target, s, t, receptor_type);
252 
253  t.register_stdp_connection(t_lastspike - get_delay());
254  }
255 
257 
258  private:
259  bool eval_function_(double_t a_causal, double_t a_acausal, double_t a_thresh_th, double_t a_thresh_tl, std::vector<long_t> configbit);
260 
261  // transformation biological weight <-> discrete weight (represented in index of look-up table)
262  uint_t weight_to_entry_(double_t weight, double_t weight_per_lut_entry);
263  double_t entry_to_weight_(uint_t discrete_weight, double_t weight_per_lut_entry);
264 
265  uint_t lookup_(uint_t discrete_weight_, std::vector<long_t> table);
266 
267  // data members of each connection
273 
277  uint_t discrete_weight_; //TODO: TP: only needed in send, move to common properties or "static"?
278  };
279 
280 template<typename targetidentifierT>
281 inline
282 bool STDPFACETSHWConnectionHom<targetidentifierT>::eval_function_(double_t a_causal, double_t a_acausal, double_t a_thresh_th, double_t a_thresh_tl, std::vector<long_t> configbit)
283 {
284  // compare charge on capacitors with thresholds and return evaluation bit
285  return (a_thresh_tl + configbit[2] * a_causal + configbit[1] * a_acausal)
286  / (1 + configbit[2] + configbit[1])
287  > (a_thresh_th + configbit[0] * a_causal + configbit[3] * a_acausal)
288  / (1 + configbit[0] + configbit[3]);
289 }
290 
291 template<typename targetidentifierT>
292 inline
294 {
295  // returns the discrete weight in terms of the look-up table index
296  return round(weight / weight_per_lut_entry);
297 }
298 
299 template<typename targetidentifierT>
300 inline
302 {
303  // returns the continuous weight
304  return discrete_weight * weight_per_lut_entry;
305 }
306 
307 template<typename targetidentifierT>
308 inline
309 uint_t STDPFACETSHWConnectionHom<targetidentifierT>::lookup_(uint_t discrete_weight_, std::vector<long_t> table)
310 {
311  // look-up in table
312  return table[discrete_weight_];
313 }
314 
315 
322 template<typename targetidentifierT>
323 inline
325 {
326  // synapse STDP dynamics
327 
329 
330  // remove const-ness of common properties
331  // this is not a nice solution, but only a workaround
332  // anyway the current implementation will presumably
333  // generate wring results on distributed systems,
334  // because the number of synapses counted is only
335  // the number of synapses local to the current machine
338 
339  //init the readout time
340  if(init_flag_ == false){
341  synapse_id_ = cp.no_synapses_;
342  ++cp_nonconst.no_synapses_;
343  cp_nonconst.calc_readout_cycle_duration_();
344  next_readout_time_ = int(synapse_id_ / cp_nonconst.synapses_per_driver_) * cp_nonconst.driver_readout_time_;
345  std::cout << "init synapse " << synapse_id_ << " - first readout time: " << next_readout_time_ << std::endl;
346  init_flag_ = true;
347  }
348 
349  //STDP controller is processing this synapse (synapse driver)?
350  if(t_spike > next_readout_time_)
351  {
352  //transform weight to discrete representation
353  discrete_weight_ = weight_to_entry_(weight_, cp_nonconst.weight_per_lut_entry_);
354 
355  //obtain evaluation bits
356  bool eval_0 = eval_function_(a_causal_, a_acausal_, a_thresh_th_, a_thresh_tl_, cp.configbit_0_);
357  bool eval_1 = eval_function_(a_causal_, a_acausal_, a_thresh_th_, a_thresh_tl_, cp.configbit_1_);
358 
359  //select LUT, update weight and reset capacitors
360  if(eval_0 == true && eval_1 == false){
361  discrete_weight_ = lookup_(discrete_weight_, cp.lookuptable_0_);
362  if(cp.reset_pattern_[0]) a_causal_ = 0;
363  if(cp.reset_pattern_[1]) a_acausal_ = 0;
364  } else if(eval_0 == false && eval_1 == true){
365  discrete_weight_ = lookup_(discrete_weight_, cp.lookuptable_1_);
366  if(cp.reset_pattern_[2]) a_causal_ = 0;
367  if(cp.reset_pattern_[3]) a_acausal_ = 0;
368  } else if(eval_0 == true && eval_1 == true){
369  discrete_weight_ = lookup_(discrete_weight_, cp.lookuptable_2_);
370  if(cp.reset_pattern_[4]) a_causal_ = 0;
371  if(cp.reset_pattern_[5]) a_acausal_ = 0;
372  }
373  //do nothing, if eval_0 == false and eval_1 == false
374 
375  while(t_spike > next_readout_time_){
376  next_readout_time_ += cp_nonconst.readout_cycle_duration_;
377  }
378  //std::cout << "synapse " << synapse_id_ << " updated at " << t_spike << ", next readout time: " << next_readout_time_ << std::endl;
379 
380  //back-transformation to continuous weight space
381  weight_ = entry_to_weight_(discrete_weight_, cp.weight_per_lut_entry_);
382  }
383 
384  // t_lastspike_ = 0 initially
385 
386  double_t dendritic_delay = Time(Time::step( get_delay_steps() )).get_ms();
387 
388  //get spike history in relevant range (t1, t2] from post-synaptic neuron
389  std::deque<histentry>::iterator start;
390  std::deque<histentry>::iterator finish;
391  get_target(t)->get_history(t_lastspike - dendritic_delay, t_spike - dendritic_delay,
392  &start, &finish);
393  //facilitation due to post-synaptic spikes since last pre-synaptic spike
394  double_t minus_dt = 0;
395  double_t plus_dt = 0;
396 
397  if(start != finish) //take only first postspike after last prespike
398  {
399  minus_dt = t_lastspike - (start->t_ + dendritic_delay);
400  }
401 
402  if(start != finish) //take only last postspike before current spike
403  {
404  --finish;
405  plus_dt = (finish->t_ + dendritic_delay) - t_spike;
406  }
407 
408  if(minus_dt != 0){
409  a_causal_ += std::exp(minus_dt / cp.tau_plus_);
410  }
411 
412  if(plus_dt != 0){
413  a_acausal_ += std::exp(plus_dt / cp.tau_minus_);
414  }
415 
416  e.set_receiver(*get_target(t));
417  e.set_weight(weight_);
418  e.set_delay(get_delay_steps());
419  e.set_rport(get_rport());
420  e();
421 
422  }
423 } // of namespace nest
424 
425 #endif // of #ifndef STDP_CONNECTION_HOM_H
void get_status(DictionaryDatum &d) const
Get all properties and put them into a dictionary.
Definition: stdp_connection_facetshw_hom_impl.h:125
double_t readout_cycle_duration_
Definition: stdp_connection_facetshw_hom.h:161
void set_rport(rport p)
Set the receiver port number (r-port).
Definition: event.h:817
double_t weight
Weight of a connection.
Definition: nest.h:170
void set_receiver(Node &)
Change pointer to receiving Node.
Definition: event.h:708
const Name receptor_type("receptor_type")
Connection parameters.
Definition: nest_names.h:240
const Name d("d")
Specific to Izhikevich 2003.
Definition: nest_names.h:83
double_t weight_per_lut_entry_
Definition: stdp_connection_facetshw_hom.h:155
long_t get_delay_steps() const
Return the delay of the connection in steps.
Definition: connection.h:126
void check_connection_(Node &dummy_target, Node &source, Node &target, rport receptor_type)
This function calls check_connection() on the sender to check if the receiver accepts the event type ...
Definition: connection.h:183
bool init_flag_
Definition: stdp_connection_facetshw_hom.h:274
const rport invalid_port_
Value for invalid connection port number.
Definition: nest.h:160
Class representing an STDP connection with homogeneous parameters, i.e.
Definition: stdp_connection_facetshw_hom.h:113
Encapsulates information which is sent between Nodes.
Definition: event.h:73
void set_weight(double_t w)
Definition: stdp_connection_facetshw_hom.h:256
Definition: nest_time.h:230
Connection< targetidentifierT > ConnectionBase
Definition: stdp_connection_facetshw_hom.h:182
bool eval_function_(double_t a_causal, double_t a_acausal, double_t a_thresh_th, double_t a_thresh_tl, std::vector< long_t > configbit)
Definition: stdp_connection_facetshw_hom.h:282
long_t synapses_per_driver_
Definition: stdp_connection_facetshw_hom.h:159
std::vector< long_t > lookuptable_1_
Definition: stdp_connection_facetshw_hom.h:163
void set_weight(weight t)
Set weight of the event.
Definition: event.h:751
long_t synapse_id_
Definition: stdp_connection_facetshw_hom.h:275
std::vector< long_t > configbit_1_
Definition: stdp_connection_facetshw_hom.h:166
std::vector< long_t > reset_pattern_
Definition: stdp_connection_facetshw_hom.h:167
long_t rport
Connection port number to distinguish incoming connections, also called receiver port.
Definition: nest.h:147
void set_status(const DictionaryDatum &d, ConnectorModel &cm)
Set properties of this connection from the values given in dictionary.
Definition: stdp_connection_facetshw_hom_impl.h:297
double_t a_thresh_tl_
Definition: stdp_connection_facetshw_hom.h:272
long_t no_synapses_
Definition: stdp_connection_facetshw_hom.h:158
void get_status(DictionaryDatum &d) const
Get all properties of this connection and put them into a dictionary.
Definition: stdp_connection_facetshw_hom_impl.h:277
Node * get_target(thread t) const
Definition: connection.h:155
double_t tau_minus_
Definition: stdp_connection_facetshw_hom.h:153
void set_status(const DictionaryDatum &d, ConnectorModel &cm)
Set properties from the values given in dictionary.
Definition: stdp_connection_facetshw_hom_impl.h:148
double_t a_causal_
Definition: stdp_connection_facetshw_hom.h:269
uint_t discrete_weight_
Definition: stdp_connection_facetshw_hom.h:277
double_t get_delay() const
Return the delay of the connection in ms.
Definition: connection.h:121
double_t weight_
Definition: stdp_connection_facetshw_hom.h:268
const Name w("w")
Specific to Brette & Gerstner 2005 (aeif_cond-*)
Definition: nest_names.h:343
STDPFACETSHWHomCommonProperties< targetidentifierT > CommonPropertiesType
Definition: stdp_connection_facetshw_hom.h:181
Definition: nest_time.h:130
void send(Event &e, thread t, double_t t_lastspike, const STDPFACETSHWHomCommonProperties< targetidentifierT > &)
Send an event to the receiver of this connection.
Definition: stdp_connection_facetshw_hom.h:324
void set_delay(delay)
Set the transmission delay of the event.
Definition: event.h:781
double_t Wmax_
Definition: stdp_connection_facetshw_hom.h:154
double_t a_acausal_
Definition: stdp_connection_facetshw_hom.h:270
double_t driver_readout_time_
Definition: stdp_connection_facetshw_hom.h:160
Time const & get_stamp() const
Return time stamp of the event.
Definition: event.h:757
double_t next_readout_time_
Definition: stdp_connection_facetshw_hom.h:276
const Name start("start")
Device parameters.
Definition: nest_names.h:263
Base class for dummy nodes used in connection testing.
Definition: connection.h:64
Class containing the common properties for all synapses of type STDPFACETSHWConnectionHom.
Definition: stdp_connection_facetshw_hom.h:119
virtual void register_stdp_connection(double_t)
Register a STDP connection.
Definition: node.cpp:178
long_t port
Connection port number to distinguis outgoing connections.
Definition: nest.h:155
double_t tau_plus_
Definition: stdp_connection_facetshw_hom.h:152
double double_t
Double precision floating point numbers.
Definition: nest.h:93
std::vector< long_t > lookuptable_0_
Definition: stdp_connection_facetshw_hom.h:162
rport get_rport() const
Definition: connection.h:156
virtual port handles_test_event(SpikeEvent &, rport receptor_type)
Check if the node can handle a particular event and receptor type.
Definition: node.cpp:203
double_t get_ms() const
Definition: nest_time.h:389
void check_connection(Node &s, Node &t, rport receptor_type, double_t t_lastspike, const CommonPropertiesType &)
Definition: stdp_connection_facetshw_hom.h:247
uint_t lookup_(uint_t discrete_weight_, std::vector< long_t > table)
Definition: stdp_connection_facetshw_hom.h:309
unsigned int uint_t
Unsigned int_t.
Definition: nest.h:97
Class containing the common properties for all connections of a certain type.
Definition: common_synapse_properties.h:44
std::vector< long_t > lookuptable_2_
Definition: stdp_connection_facetshw_hom.h:164
Base class for representing connections.
Definition: connection.h:85
Event for spike information.
Definition: event.h:320
STDPFACETSHWHomCommonProperties()
Default constructor.
Definition: stdp_connection_facetshw_hom_impl.h:37
Base class for all NEST network objects.
Definition: node.h:96
STDPFACETSHWConnectionHom()
Default Constructor.
Definition: stdp_connection_facetshw_hom_impl.h:249
std::vector< long_t > configbit_0_
Definition: stdp_connection_facetshw_hom.h:165
double_t entry_to_weight_(uint_t discrete_weight, double_t weight_per_lut_entry)
Definition: stdp_connection_facetshw_hom.h:301
port handles_test_event(SpikeEvent &, rport)
Check if the node can handle a particular event and receptor type.
Definition: stdp_connection_facetshw_hom.h:229
Definition: connector_model.h:38
int_t thread
Thread index type.
Definition: nest.h:133
double_t a_thresh_th_
Definition: stdp_connection_facetshw_hom.h:271
long long_t
Integer number with at least 32 bit.
Definition: nest.h:96
Definition: stdp_connection_facetshw_hom.h:223
const double e
Definition: numerics.cpp:62
void check_event(SpikeEvent &)
Definition: stdp_connection_facetshw_hom.h:142
void calc_readout_cycle_duration_()
Calculate the readout cycle duration.
Definition: stdp_connection_facetshw_hom_impl.h:118
const Name t_spike("t_spike")
Time of last spike.
Definition: nest_names.h:281
uint_t weight_to_entry_(double_t weight, double_t weight_per_lut_entry)
Definition: stdp_connection_facetshw_hom.h:293