GeNN  4.9.0
GPU enhanced Neuronal Networks (GeNN)
modelSpec.h
Go to the documentation of this file.
1 /*--------------------------------------------------------------------------
2  Author: Thomas Nowotny
3 
4  Institute: Center for Computational Neuroscience and Robotics
5  University of Sussex
6  Falmer, Brighton BN1 9QJ, UK
7 
8  email to: T.Nowotny@sussex.ac.uk
9 
10  initial version: 2010-02-07
11 
12  This file contains neuron model declarations.
13 
14 --------------------------------------------------------------------------*/
15 
16 //--------------------------------------------------------------------------
23 //--------------------------------------------------------------------------
24 #pragma once
25 
26 // Standard C++ includes
27 #include <map>
28 #include <set>
29 #include <string>
30 #include <vector>
31 
32 // GeNN includes
33 #include "currentSourceInternal.h"
34 #include "customUpdateInternal.h"
35 #include "gennExport.h"
36 #include "neuronGroupInternal.h"
37 #include "synapseGroupInternal.h"
38 
39 #define NO_DELAY 0
40 
41 enum FloatType
43 {
44  GENN_FLOAT,
45  GENN_DOUBLE,
47 };
48 
50 enum class TimePrecision
51 {
52  DEFAULT,
53  FLOAT,
54  DOUBLE,
55 };
56 
58 
61 template<typename S>
62 inline Models::VarInit initVar(const typename S::ParamValues &params)
63 {
64  return Models::VarInit(S::getInstance(), params.getInitialisers());
65 }
66 
68 
70 template<typename S>
71 inline typename std::enable_if<std::is_same<typename S::ParamValues, Snippet::ValueBase<0>>::value, Models::VarInit>::type initVar()
72 {
73  return Models::VarInit(S::getInstance(), {});
74 }
75 
77 
80 {
81  return Models::VarInit(InitVarSnippet::Uninitialised::getInstance(), {});
82 }
83 
85 
88 template<typename S>
89 inline InitSparseConnectivitySnippet::Init initConnectivity(const typename S::ParamValues &params)
90 {
91  return InitSparseConnectivitySnippet::Init(S::getInstance(), params.getInitialisers());
92 }
93 
95 
97 template<typename S>
98 inline typename std::enable_if<std::is_same<typename S::ParamValues, Snippet::ValueBase<0>>::value, InitSparseConnectivitySnippet::Init>::type initConnectivity()
99 {
100  return InitSparseConnectivitySnippet::Init(S::getInstance(), {});
101 }
102 
104 
108 {
109  return InitSparseConnectivitySnippet::Init(InitSparseConnectivitySnippet::Uninitialised::getInstance(), {});
110 }
111 
113 
116 template<typename S>
117 inline InitToeplitzConnectivitySnippet::Init initToeplitzConnectivity(const typename S::ParamValues &params)
118 {
119  return InitToeplitzConnectivitySnippet::Init(S::getInstance(), params.getInitialisers());
120 }
121 
123 
125 template<typename S>
126 inline typename std::enable_if<std::is_same<typename S::ParamValues, Snippet::ValueBase<0>>::value, InitToeplitzConnectivitySnippet::Init>::type initToeplitzConnectivity()
127 {
128  return InitToeplitzConnectivitySnippet::Init(S::getInstance(), {});
129 }
130 
132 inline Models::VarReference createVarRef(const NeuronGroup *ng, const std::string &varName)
133 {
134  return Models::VarReference::createVarRef(ng, varName);
135 }
136 
138 inline Models::VarReference createVarRef(const CurrentSource *cs, const std::string &varName)
139 {
140  return Models::VarReference::createVarRef(cs, varName);
141 }
142 
144 inline Models::VarReference createVarRef(const CustomUpdate *cu, const std::string &varName)
145 {
146  return Models::VarReference::createVarRef(cu, varName);
147 }
148 
150 inline Models::VarReference createPSMVarRef(const SynapseGroup *sg, const std::string &varName)
151 {
152  return Models::VarReference::createPSMVarRef(sg, varName);
153 }
154 
156 inline Models::VarReference createWUPreVarRef(const SynapseGroup *sg, const std::string &varName)
157 {
158  return Models::VarReference::createWUPreVarRef(sg, varName);
159 }
160 
162 inline Models::VarReference createWUPostVarRef(const SynapseGroup *sg, const std::string &varName)
163 {
164  return Models::VarReference::createWUPostVarRef(sg, varName);
165 }
166 
168 inline Models::WUVarReference createWUVarRef(const SynapseGroup *sg, const std::string &varName,
169  const SynapseGroup *transposeSG = nullptr, const std::string &transposeVarName = "")
170 {
171  return Models::WUVarReference(sg, varName, transposeSG, transposeVarName);
172 }
173 
175 inline Models::WUVarReference createWUVarRef(const CustomUpdateWU *cu, const std::string &varName)
176 {
177  return Models::WUVarReference(cu, varName);
178 }
179 
181 inline Models::EGPReference createEGPRef(const NeuronGroup *ng, const std::string &egpName)
182 {
183  return Models::EGPReference::createEGPRef(ng, egpName);
184 }
185 
187 inline Models::EGPReference createEGPRef(const CurrentSource *cs, const std::string &egpName)
188 {
189  return Models::EGPReference::createEGPRef(cs, egpName);
190 }
191 
193 inline Models::EGPReference createEGPRef(const CustomUpdate *cu, const std::string &egpName)
194 {
195  return Models::EGPReference::createEGPRef(cu, egpName);
196 }
197 
199 inline Models::EGPReference createEGPRef(const CustomUpdateWU *cu, const std::string &egpName)
200 {
201  return Models::EGPReference::createEGPRef(cu, egpName);
202 }
203 
205 inline Models::EGPReference createPSMEGPRef(const SynapseGroup *sg, const std::string &egpName)
206 {
207  return Models::EGPReference::createPSMEGPRef(sg, egpName);
208 }
209 
211 inline Models::EGPReference createWUEGPRef(const SynapseGroup *sg, const std::string &egpName)
212 {
213  return Models::EGPReference::createWUEGPRef(sg, egpName);
214 }
215 
216 //----------------------------------------------------------------------------
217 // ModelSpec
218 //----------------------------------------------------------------------------
221 {
222 public:
223  // Typedefines
224  //=======================
225  typedef std::map<std::string, NeuronGroupInternal>::value_type NeuronGroupValueType;
226  typedef std::map<std::string, SynapseGroupInternal>::value_type SynapseGroupValueType;
227  typedef std::map<std::string, CurrentSourceInternal>::value_type CurrentSourceValueType;
228  typedef std::map<std::string, CustomUpdateInternal>::value_type CustomUpdateValueType;
229  typedef std::map<std::string, CustomUpdateWUInternal>::value_type CustomUpdateWUValueType;
230 
231  //typedef std::map<std::string, CustomUpdateInternal>::value_type CustomUpdateValueType;
232 
233  ModelSpec();
234  ModelSpec(const ModelSpec&) = delete;
235  ModelSpec &operator=(const ModelSpec &) = delete;
236  ~ModelSpec();
237 
238  // PUBLIC MODEL FUNCTIONS
239  //=======================
241  void setName(const std::string &name){ m_Name = name; }
242 
244  void setPrecision(FloatType);
245 
247  void setTimePrecision(TimePrecision timePrecision){ m_TimePrecision = timePrecision; }
248 
250  void setDT(double dt){ m_DT = dt; }
251 
253  void setTiming(bool timingEnabled){ m_TimingEnabled = timingEnabled; }
254 
256  void setSeed(unsigned int rngSeed){ m_Seed = rngSeed; }
257 
259 
260  void setDefaultVarLocation(VarLocation loc){ m_DefaultVarLocation = loc; }
261 
263 
264  void setDefaultExtraGlobalParamLocation(VarLocation loc){ m_DefaultExtraGlobalParamLocation = loc; }
265 
267 
268  void setDefaultSparseConnectivityLocation(VarLocation loc){ m_DefaultSparseConnectivityLocation = loc; }
269 
271  void setDefaultNarrowSparseIndEnabled(bool enabled){ m_DefaultNarrowSparseIndEnabled = enabled; }
272 
274 
275  void setMergePostsynapticModels(bool merge){ m_ShouldFusePostsynapticModels = merge; }
276 
278 
279  void setFusePostsynapticModels(bool fuse) { m_ShouldFusePostsynapticModels = fuse; }
280 
282 
283  void setFusePrePostWeightUpdateModels(bool fuse){ m_ShouldFusePrePostWeightUpdateModels = fuse; }
284 
285  void setBatchSize(unsigned int batchSize) { m_BatchSize = batchSize; }
286 
288  const std::string &getName() const{ return m_Name; }
289 
291  const std::string &getPrecision() const{ return m_Precision; }
292 
294  std::string getTimePrecision() const;
295 
297  double getDT() const { return m_DT; }
298 
300  unsigned int getSeed() const { return m_Seed; }
301 
303  bool isTimingEnabled() const{ return m_TimingEnabled; }
304 
305  unsigned int getBatchSize() const { return m_BatchSize; }
306 
307  // PUBLIC NEURON FUNCTIONS
308  //========================
310  unsigned int getNumNeurons() const;
311 
313  NeuronGroup *findNeuronGroup(const std::string &name){ return static_cast<NeuronGroup*>(findNeuronGroupInternal(name)); }
314 
316 
323  template<typename NeuronModel>
324  NeuronGroup *addNeuronPopulation(const std::string &name, unsigned int size, const NeuronModel *model,
325  const typename NeuronModel::ParamValues &paramValues,
326  const typename NeuronModel::VarValues &varInitialisers)
327  {
328  // Add neuron group to map
329  auto result = m_LocalNeuronGroups.emplace(std::piecewise_construct,
330  std::forward_as_tuple(name),
331  std::forward_as_tuple(name, size, model,
332  paramValues.getInitialisers(), varInitialisers.getInitialisers(),
333  m_DefaultVarLocation, m_DefaultExtraGlobalParamLocation));
334 
335  if(!result.second) {
336  throw std::runtime_error("Cannot add a neuron population with duplicate name:" + name);
337  }
338  else {
339  return &result.first->second;
340  }
341  }
342 
344 
350  template<typename NeuronModel>
351  NeuronGroup *addNeuronPopulation(const std::string &name, unsigned int size,
352  const typename NeuronModel::ParamValues &paramValues, const typename NeuronModel::VarValues &varInitialisers)
353  {
354  return addNeuronPopulation<NeuronModel>(name, size, NeuronModel::getInstance(), paramValues, varInitialisers);
355  }
356 
357  // PUBLIC SYNAPSE FUNCTIONS
358  //=========================
360  SynapseGroup *findSynapseGroup(const std::string &name);
361 
363 
383  template<typename WeightUpdateModel, typename PostsynapticModel>
384  SynapseGroup *addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string& src, const std::string& trg,
385  const WeightUpdateModel *wum, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers,
386  const PostsynapticModel *psm, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers,
387  const InitSparseConnectivitySnippet::Init &connectivityInitialiser = uninitialisedConnectivity())
388  {
389  auto uninitialisedToeplitz = InitToeplitzConnectivitySnippet::Init(InitToeplitzConnectivitySnippet::Uninitialised::getInstance(), {});
390  return addSynapsePopulation(name, mtype, delaySteps, src, trg,
391  wum, weightParamValues, weightVarInitialisers, weightPreVarInitialisers, weightPostVarInitialisers,
392  psm, postsynapticParamValues, postsynapticVarInitialisers,
393  connectivityInitialiser, uninitialisedToeplitz);
394  }
395 
397 
416  template<typename WeightUpdateModel, typename PostsynapticModel>
417  SynapseGroup *addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string& src, const std::string& trg,
418  const WeightUpdateModel *wum, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers,
419  const PostsynapticModel *psm, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers,
420  const InitToeplitzConnectivitySnippet::Init &connectivityInitialiser)
421  {
422  auto uninitialisedToeplitz = InitToeplitzConnectivitySnippet::Init(InitToeplitzConnectivitySnippet::Uninitialised::getInstance(), {});
423  return addSynapsePopulation(name, mtype, delaySteps, src, trg,
424  wum, weightParamValues, weightVarInitialisers, weightPreVarInitialisers, weightPostVarInitialisers,
425  psm, postsynapticParamValues, postsynapticVarInitialisers,
426  uninitialisedConnectivity(), connectivityInitialiser);
427  }
428 
430 
445  template<typename WeightUpdateModel, typename PostsynapticModel>
446  SynapseGroup *addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string& src, const std::string& trg,
447  const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers,
448  const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers,
449  const InitSparseConnectivitySnippet::Init &connectivityInitialiser = uninitialisedConnectivity())
450  {
451  // Create empty pre and postsynaptic weight update variable initialisers
452  typename WeightUpdateModel::PreVarValues weightPreVarInitialisers;
453  typename WeightUpdateModel::PostVarValues weightPostVarInitialisers;
454 
455  return addSynapsePopulation(name, mtype, delaySteps, src, trg,
456  WeightUpdateModel::getInstance(), weightParamValues, weightVarInitialisers, weightPreVarInitialisers, weightPostVarInitialisers,
457  PostsynapticModel::getInstance(), postsynapticParamValues, postsynapticVarInitialisers,
458  connectivityInitialiser);
459  }
460 
462 
476  template<typename WeightUpdateModel, typename PostsynapticModel>
477  SynapseGroup *addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string& src, const std::string& trg,
478  const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers,
479  const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers,
480  const InitToeplitzConnectivitySnippet::Init &connectivityInitialiser)
481  {
482  // Create empty pre and postsynaptic weight update variable initialisers
483  typename WeightUpdateModel::PreVarValues weightPreVarInitialisers;
484  typename WeightUpdateModel::PostVarValues weightPostVarInitialisers;
485 
486  return addSynapsePopulation(name, mtype, delaySteps, src, trg,
487  WeightUpdateModel::getInstance(), weightParamValues, weightVarInitialisers, weightPreVarInitialisers, weightPostVarInitialisers,
488  PostsynapticModel::getInstance(), postsynapticParamValues, postsynapticVarInitialisers,
489  connectivityInitialiser);
490  }
491 
493 
510  template<typename WeightUpdateModel, typename PostsynapticModel>
511  SynapseGroup *addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string& src, const std::string& trg,
512  const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers,
513  const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers,
514  const InitSparseConnectivitySnippet::Init &connectivityInitialiser = uninitialisedConnectivity())
515  {
516  return addSynapsePopulation(name, mtype, delaySteps, src, trg,
517  WeightUpdateModel::getInstance(), weightParamValues, weightVarInitialisers, weightPreVarInitialisers, weightPostVarInitialisers,
518  PostsynapticModel::getInstance(), postsynapticParamValues, postsynapticVarInitialisers,
519  connectivityInitialiser);
520 
521  }
522 
524 
540  template<typename WeightUpdateModel, typename PostsynapticModel>
541  SynapseGroup *addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string& src, const std::string& trg,
542  const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers,
543  const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers,
544  const InitToeplitzConnectivitySnippet::Init &connectivityInitialiser)
545  {
546  return addSynapsePopulation(name, mtype, delaySteps, src, trg,
547  WeightUpdateModel::getInstance(), weightParamValues, weightVarInitialisers, weightPreVarInitialisers, weightPostVarInitialisers,
548  PostsynapticModel::getInstance(), postsynapticParamValues, postsynapticVarInitialisers,
549  connectivityInitialiser);
550 
551  }
552 
553 
555 
565  template<typename PostsynapticModel>
566  SynapseGroup *addSlaveSynapsePopulation(const std::string &name, const std::string &weightSharingMasterName, unsigned int delaySteps, const std::string &src, const std::string &trg,
567  const PostsynapticModel *psm, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers)
568  {
569  // Get source and target neuron groups
570  auto srcNeuronGrp = findNeuronGroupInternal(src);
571  auto trgNeuronGrp = findNeuronGroupInternal(trg);
572 
573  // Find weight sharing master group
574  auto masterGrp = findSynapseGroupInternal(weightSharingMasterName);
575  const auto *wum = masterGrp->getWUModel();
576 
577  // If the weight sharing master has individuak weights and any are read-write, give error
578  const auto wumVars = wum->getVars();
579  if((masterGrp->getMatrixType() & SynapseMatrixWeight::INDIVIDUAL) &&
580  std::any_of(wumVars.cbegin(), wumVars.cend(),
581  [](const Models::Base::Var &v)
582  {
583  return (v.access == VarAccess::READ_WRITE);
584  }))
585  {
586  throw std::runtime_error("Individual synapse variables can only be shared if they are read-only");
587  }
588 
589  // Check that population sizes match
590  if ((srcNeuronGrp->getNumNeurons() != masterGrp->getSrcNeuronGroup()->getNumNeurons())
591  || (trgNeuronGrp->getNumNeurons() != masterGrp->getTrgNeuronGroup()->getNumNeurons()))
592  {
593  throw std::runtime_error("Size of populations connected by shared weights must match");
594  }
595 
596  // If weight update model has any pre or postsynaptic variables, give error
597  // **THINK** this could be supported but quite what the semantics are is ambiguous
598  if(!wum->getPreVars().empty() || !wum->getPostVars().empty()) {
599  throw std::runtime_error("Synapse groups with pre and postsynpatic variables cannot be shared");
600  }
601 
602  // Add synapse group to map
603  auto uninitialisedToeplitz = InitToeplitzConnectivitySnippet::Init(InitToeplitzConnectivitySnippet::Uninitialised::getInstance(), {});
604  auto result = m_LocalSynapseGroups.emplace(
605  std::piecewise_construct,
606  std::forward_as_tuple(name),
607  std::forward_as_tuple(name, masterGrp, masterGrp->getMatrixType(), delaySteps,
608  wum, masterGrp->getWUParams(), masterGrp->getWUVarInitialisers(), masterGrp->getWUPreVarInitialisers(), masterGrp->getWUPostVarInitialisers(),
609  psm, postsynapticParamValues.getInitialisers(), postsynapticVarInitialisers.getInitialisers(),
610  srcNeuronGrp, trgNeuronGrp, masterGrp->getConnectivityInitialiser(), uninitialisedToeplitz,
611  m_DefaultVarLocation, m_DefaultExtraGlobalParamLocation, m_DefaultSparseConnectivityLocation, m_DefaultNarrowSparseIndEnabled));
612 
613  if(!result.second) {
614  throw std::runtime_error("Cannot add a synapse population with duplicate name:" + name);
615  }
616  else {
617  return &result.first->second;
618  }
619  }
620 
622 
631  template<typename PostsynapticModel>
632  SynapseGroup *addSlaveSynapsePopulation(const std::string &name, const std::string &weightSharingMasterName, unsigned int delaySteps, const std::string &src, const std::string &trg,
633  const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers)
634  {
635  return addSlaveSynapsePopulation(name, weightSharingMasterName, delaySteps, src, trg,
636  PostsynapticModel::getInstance(), postsynapticParamValues, postsynapticVarInitialisers);
637  }
638 
639  // PUBLIC CURRENT SOURCE FUNCTIONS
640  //================================
642  CurrentSource *findCurrentSource(const std::string &name);
643 
645 
652  template<typename CurrentSourceModel>
653  CurrentSource *addCurrentSource(const std::string &currentSourceName, const CurrentSourceModel *model,
654  const std::string &targetNeuronGroupName,
655  const typename CurrentSourceModel::ParamValues &paramValues,
656  const typename CurrentSourceModel::VarValues &varInitialisers)
657  {
658  auto targetGroup = findNeuronGroupInternal(targetNeuronGroupName);
659 
660  // Add current source to map
661  auto result = m_LocalCurrentSources.emplace(std::piecewise_construct,
662  std::forward_as_tuple(currentSourceName),
663  std::forward_as_tuple(currentSourceName, model, paramValues.getInitialisers(),
664  varInitialisers.getInitialisers(), targetGroup,
665  m_DefaultVarLocation, m_DefaultExtraGlobalParamLocation));
666 
667  if(!result.second) {
668  throw std::runtime_error("Cannot add a current source with duplicate name:" + currentSourceName);
669  }
670  else {
671  targetGroup->injectCurrent(&result.first->second);
672  return &result.first->second;
673  }
674  }
675 
677 
683  template<typename CurrentSourceModel>
684  CurrentSource *addCurrentSource(const std::string &currentSourceName, const std::string &targetNeuronGroupName,
685  const typename CurrentSourceModel::ParamValues &paramValues,
686  const typename CurrentSourceModel::VarValues &varInitialisers)
687  {
688  return addCurrentSource<CurrentSourceModel>(currentSourceName, CurrentSourceModel::getInstance(),
689  targetNeuronGroupName, paramValues, varInitialisers);
690  }
691 
693 
701  template<typename CustomUpdateModel>
702  CustomUpdate *addCustomUpdate(const std::string &name, const std::string &updateGroupName, const CustomUpdateModel *model,
703  const typename CustomUpdateModel::ParamValues &paramValues,
704  const typename CustomUpdateModel::VarValues &varInitialisers,
705  const typename CustomUpdateModel::VarReferences &varReferences,
706  const typename CustomUpdateModel::EGPReferences &egpReferences = {})
707  {
708  // Add neuron group to map
709  auto result = m_CustomUpdates.emplace(std::piecewise_construct,
710  std::forward_as_tuple(name),
711  std::forward_as_tuple(name, updateGroupName, model,
712  paramValues.getInitialisers(), varInitialisers.getInitialisers(), varReferences.getInitialisers(),
713  egpReferences.getInitialisers(), m_DefaultVarLocation, m_DefaultExtraGlobalParamLocation));
714 
715  if(!result.second) {
716  throw std::runtime_error("Cannot add a custom update with duplicate name:" + name);
717  }
718  else {
719  return &result.first->second;
720  }
721  }
722 
725 
734  template<typename CustomUpdateModel>
735  CustomUpdateWU *addCustomUpdate(const std::string &name, const std::string &updateGroupName,
736  const CustomUpdateModel *model, const typename CustomUpdateModel::ParamValues &paramValues,
737  const typename CustomUpdateModel::VarValues &varInitialisers,
738  const typename CustomUpdateModel::WUVarReferences &varReferences,
739  const typename CustomUpdateModel::EGPReferences &egpReferences = {})
740  {
741  // Add neuron group to map
742  auto result = m_CustomWUUpdates.emplace(std::piecewise_construct,
743  std::forward_as_tuple(name),
744  std::forward_as_tuple(name, updateGroupName, model,
745  paramValues.getInitialisers(), varInitialisers.getInitialisers(), varReferences.getInitialisers(),
746  egpReferences.getInitialisers(), m_DefaultVarLocation, m_DefaultExtraGlobalParamLocation));
747 
748  if(!result.second) {
749  throw std::runtime_error("Cannot add a custom update with duplicate name:" + name);
750  }
751  else {
752  return &result.first->second;
753  }
754  }
755 
758 
765  template<typename CustomUpdateModel>
766  CustomUpdate *addCustomUpdate(const std::string &name, const std::string &updateGroupName,
767  const typename CustomUpdateModel::ParamValues &paramValues,
768  const typename CustomUpdateModel::VarValues &varInitialisers,
769  const typename CustomUpdateModel::VarReferences &varReferences,
770  const typename CustomUpdateModel::EGPReferences &egpReferences = {})
771  {
772  return addCustomUpdate<CustomUpdateModel>(name, updateGroupName, CustomUpdateModel::getInstance(),
773  paramValues, varInitialisers, varReferences, egpReferences);
774  }
775 
776 
779 
787  template<typename CustomUpdateModel>
788  CustomUpdateWU *addCustomUpdate(const std::string &name, const std::string &updateGroupName,
789  const typename CustomUpdateModel::ParamValues &paramValues,
790  const typename CustomUpdateModel::VarValues &varInitialisers,
791  const typename CustomUpdateModel::WUVarReferences &varReferences,
792  const typename CustomUpdateModel::EGPReferences &egpReferences = {})
793  {
794  return addCustomUpdate<CustomUpdateModel>(name, updateGroupName, CustomUpdateModel::getInstance(),
795  paramValues, varInitialisers, varReferences, egpReferences);
796  }
797 
798 protected:
799  //--------------------------------------------------------------------------
800  // Protected methods
801  //--------------------------------------------------------------------------
803  void finalize();
804 
805  //--------------------------------------------------------------------------
806  // Protected const methods
807  //--------------------------------------------------------------------------
809  std::string scalarExpr(double) const;
810 
812  bool zeroCopyInUse() const;
813 
815  bool isRecordingInUse() const;
816 
818  boost::uuids::detail::sha1::digest_type getHashDigest() const;
819 
821  const std::map<std::string, NeuronGroupInternal> &getNeuronGroups() const{ return m_LocalNeuronGroups; }
822 
824  const std::map<std::string, SynapseGroupInternal> &getSynapseGroups() const{ return m_LocalSynapseGroups; }
825 
827  const std::map<std::string, CurrentSourceInternal> &getLocalCurrentSources() const{ return m_LocalCurrentSources; }
828 
830  const std::map<std::string, CustomUpdateInternal> &getCustomUpdates() const { return m_CustomUpdates; }
831  const std::map<std::string, CustomUpdateWUInternal> &getCustomWUUpdates() const { return m_CustomWUUpdates; }
832 
833 private:
834  //--------------------------------------------------------------------------
835  // Private methods
836  //--------------------------------------------------------------------------
838  NeuronGroupInternal *findNeuronGroupInternal(const std::string &name);
839 
841  SynapseGroupInternal *findSynapseGroupInternal(const std::string &name);
842 
843  template<typename WeightUpdateModel, typename PostsynapticModel>
844  SynapseGroup *addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string& src, const std::string& trg,
845  const WeightUpdateModel *wum, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers,
846  const PostsynapticModel *psm, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers,
847  const InitSparseConnectivitySnippet::Init &connectivityInitialiser, const InitToeplitzConnectivitySnippet::Init &toeplitzConnectivityInitialiser)
848  {
849  // Get source and target neuron groups
850  auto srcNeuronGrp = findNeuronGroupInternal(src);
851  auto trgNeuronGrp = findNeuronGroupInternal(trg);
852 
853  // Add synapse group to map
854  auto result = m_LocalSynapseGroups.emplace(
855  std::piecewise_construct,
856  std::forward_as_tuple(name),
857  std::forward_as_tuple(name, nullptr, mtype, delaySteps,
858  wum, weightParamValues.getInitialisers(), weightVarInitialisers.getInitialisers(), weightPreVarInitialisers.getInitialisers(), weightPostVarInitialisers.getInitialisers(),
859  psm, postsynapticParamValues.getInitialisers(), postsynapticVarInitialisers.getInitialisers(),
860  srcNeuronGrp, trgNeuronGrp,
861  connectivityInitialiser, toeplitzConnectivityInitialiser,
862  m_DefaultVarLocation, m_DefaultExtraGlobalParamLocation,
863  m_DefaultSparseConnectivityLocation, m_DefaultNarrowSparseIndEnabled));
864 
865  if(!result.second) {
866  throw std::runtime_error("Cannot add a synapse population with duplicate name:" + name);
867  }
868  else {
869  return &result.first->second;
870  }
871  }
872 
873  //--------------------------------------------------------------------------
874  // Private members
875  //--------------------------------------------------------------------------
877  std::map<std::string, NeuronGroupInternal> m_LocalNeuronGroups;
878 
880  std::map<std::string, SynapseGroupInternal> m_LocalSynapseGroups;
881 
883  std::map<std::string, CurrentSourceInternal> m_LocalCurrentSources;
884 
886  std::map<std::string, CustomUpdateInternal> m_CustomUpdates;
887  std::map<std::string, CustomUpdateWUInternal> m_CustomWUUpdates;
888 
890  std::string m_Name;
891 
893  std::string m_Precision;
894 
896  TimePrecision m_TimePrecision;
897 
899  double m_DT;
900 
902  bool m_TimingEnabled;
903 
905  unsigned int m_Seed;
906 
908  VarLocation m_DefaultVarLocation;
909 
911  VarLocation m_DefaultExtraGlobalParamLocation;
912 
914  VarLocation m_DefaultSparseConnectivityLocation;
915 
917  bool m_DefaultNarrowSparseIndEnabled;
918 
920 
921  bool m_ShouldFusePostsynapticModels;
922 
924 
925  bool m_ShouldFusePrePostWeightUpdateModels;
926 
928  unsigned int m_BatchSize;
929 };
930 
931 // Typedefine NNmodel for backward compatibility
NeuronGroup * addNeuronPopulation(const std::string &name, unsigned int size, const typename NeuronModel::ParamValues &paramValues, const typename NeuronModel::VarValues &varInitialisers)
Adds a new neuron group to the model using a singleton neuron model created using standard DECLARE_MO...
Definition: modelSpec.h:351
void setBatchSize(unsigned int batchSize)
Definition: modelSpec.h:285
Definition: neuronGroup.h:21
Definition: neuronGroupInternal.h:9
std::map< std::string, CustomUpdateInternal >::value_type CustomUpdateValueType
Definition: modelSpec.h:228
const std::map< std::string, SynapseGroupInternal > & getSynapseGroups() const
Get std::map containing local named SynapseGroup objects in model.
Definition: modelSpec.h:824
SynapseGroup * addSlaveSynapsePopulation(const std::string &name, const std::string &weightSharingMasterName, unsigned int delaySteps, const std::string &src, const std::string &trg, const PostsynapticModel *psm, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers)
Adds a synapse population to the model using shared per-synapse variables and a postsynaptic model ma...
Definition: modelSpec.h:566
ModelSpec NNmodel
Definition: modelSpec.h:932
bool isTimingEnabled() const
Are timers and timing commands enabled.
Definition: modelSpec.h:303
VarLocation
< Flags defining which memory space variables should be allocated in
Definition: variableMode.h:10
Time uses default model precision.
unsigned int getBatchSize() const
Definition: modelSpec.h:305
Models::VarInit uninitialisedVar()
Mark a variable as uninitialised.
Definition: modelSpec.h:79
TimePrecision
Precision to use for variables which store time.
Definition: modelSpec.h:50
Models::WUVarReference createWUVarRef(const SynapseGroup *sg, const std::string &varName, const SynapseGroup *transposeSG=nullptr, const std::string &transposeVarName="")
Creates a reference to a weight update model variable.
Definition: modelSpec.h:168
static EGPReference createWUEGPRef(const SynapseGroup *sg, const std::string &egpName)
Definition: models.cc:214
Definition: customUpdate.h:199
Definition: initSparseConnectivitySnippet.h:81
void setSeed(unsigned int rngSeed)
Set the random seed (disables automatic seeding if argument not 0).
Definition: modelSpec.h:256
void setDefaultSparseConnectivityLocation(VarLocation loc)
What is the default location for sparse synaptic connectivity?
Definition: modelSpec.h:268
#define GENN_EXPORT
Definition: gennExport.h:13
CurrentSource * addCurrentSource(const std::string &currentSourceName, const CurrentSourceModel *model, const std::string &targetNeuronGroupName, const typename CurrentSourceModel::ParamValues &paramValues, const typename CurrentSourceModel::VarValues &varInitialisers)
Adds a new current source to the model using a current source model managed by the user...
Definition: modelSpec.h:653
CustomUpdateWU * addCustomUpdate(const std::string &name, const std::string &updateGroupName, const CustomUpdateModel *model, const typename CustomUpdateModel::ParamValues &paramValues, const typename CustomUpdateModel::VarValues &varInitialisers, const typename CustomUpdateModel::WUVarReferences &varReferences, const typename CustomUpdateModel::EGPReferences &egpReferences={})
Definition: modelSpec.h:735
CustomUpdateWU * addCustomUpdate(const std::string &name, const std::string &updateGroupName, const typename CustomUpdateModel::ParamValues &paramValues, const typename CustomUpdateModel::VarValues &varInitialisers, const typename CustomUpdateModel::WUVarReferences &varReferences, const typename CustomUpdateModel::EGPReferences &egpReferences={})
Definition: modelSpec.h:788
double getDT() const
Gets the model integration step size.
Definition: modelSpec.h:297
Time uses single precision - not suitable for long simulations.
Definition: customUpdate.h:252
SynapseGroup * addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string &src, const std::string &trg, const WeightUpdateModel *wum, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers, const PostsynapticModel *psm, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers, const InitToeplitzConnectivitySnippet::Init &connectivityInitialiser)
Adds a synapse population to the model using weight update and postsynaptic models managed by the use...
Definition: modelSpec.h:417
Definition: initToeplitzConnectivitySnippet.h:66
static VarReference createWUPreVarRef(const SynapseGroup *sg, const std::string &varName)
Definition: models.cc:62
Models::VarReference createWUPreVarRef(const SynapseGroup *sg, const std::string &varName)
Creates a reference to a weight update model presynaptic variable.
Definition: modelSpec.h:156
Definition: synapseGroupInternal.h:9
Object used for specifying a neuronal network model.
Definition: modelSpec.h:220
std::map< std::string, CustomUpdateWUInternal >::value_type CustomUpdateWUValueType
Definition: modelSpec.h:229
Models::EGPReference createEGPRef(const NeuronGroup *ng, const std::string &egpName)
Creates a reference to a neuron group extra global parameter.
Definition: modelSpec.h:181
const std::string & getName() const
Gets the name of the neuronal network model.
Definition: modelSpec.h:288
static VarReference createWUPostVarRef(const SynapseGroup *sg, const std::string &varName)
Definition: models.cc:72
CustomUpdate * addCustomUpdate(const std::string &name, const std::string &updateGroupName, const CustomUpdateModel *model, const typename CustomUpdateModel::ParamValues &paramValues, const typename CustomUpdateModel::VarValues &varInitialisers, const typename CustomUpdateModel::VarReferences &varReferences, const typename CustomUpdateModel::EGPReferences &egpReferences={})
Adds a new custom update with references to the model using a custom update model managed by the user...
Definition: modelSpec.h:702
Models::EGPReference createWUEGPRef(const SynapseGroup *sg, const std::string &egpName)
Creates a reference to a weight update model extra global parameter.
Definition: modelSpec.h:211
static VarReference createVarRef(const NeuronGroup *ng, const std::string &varName)
Definition: models.cc:33
CurrentSource * addCurrentSource(const std::string &currentSourceName, const std::string &targetNeuronGroupName, const typename CurrentSourceModel::ParamValues &paramValues, const typename CurrentSourceModel::VarValues &varInitialisers)
Adds a new current source to the model using a singleton current source model created using standard ...
Definition: modelSpec.h:684
static EGPReference createEGPRef(const NeuronGroup *ng, const std::string &egpName)
Definition: models.cc:184
A variable has a name, a type and an access type.
Definition: models.h:58
Definition: synapseGroup.h:24
Models::VarReference createVarRef(const NeuronGroup *ng, const std::string &varName)
Creates a reference to a neuron group variable.
Definition: modelSpec.h:132
void setName(const std::string &name)
Method to set the neuronal network model name.
Definition: modelSpec.h:241
InitSparseConnectivitySnippet::Init initConnectivity(const typename S::ParamValues &params)
Initialise connectivity using a sparse connectivity snippet.
Definition: modelSpec.h:89
Definition: models.h:151
void setMergePostsynapticModels(bool merge)
Should compatible postsynaptic models and dendritic delay buffers be fused?
Definition: modelSpec.h:275
NeuronGroup * addNeuronPopulation(const std::string &name, unsigned int size, const NeuronModel *model, const typename NeuronModel::ParamValues &paramValues, const typename NeuronModel::VarValues &varInitialisers)
Adds a new neuron group to the model using a neuron model managed by the user.
Definition: modelSpec.h:324
const std::map< std::string, NeuronGroupInternal > & getNeuronGroups() const
Get std::map containing local named NeuronGroup objects in model.
Definition: modelSpec.h:821
SynapseGroup * addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string &src, const std::string &trg, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers, const InitSparseConnectivitySnippet::Init &connectivityInitialiser=uninitialisedConnectivity())
Adds a synapse population to the model using singleton weight update and postsynaptic models created ...
Definition: modelSpec.h:511
void setDefaultVarLocation(VarLocation loc)
What is the default location for model state variables?
Definition: modelSpec.h:260
unsigned int getSeed() const
Get the random seed.
Definition: modelSpec.h:300
void setFusePostsynapticModels(bool fuse)
Should compatible postsynaptic models and dendritic delay buffers be fused?
Definition: modelSpec.h:279
Models::EGPReference createPSMEGPRef(const SynapseGroup *sg, const std::string &egpName)
Creates a reference to a postsynaptic model extra global parameter.
Definition: modelSpec.h:205
void setTiming(bool timingEnabled)
Set whether timers and timing commands are to be included.
Definition: modelSpec.h:253
void setDT(double dt)
Set the integration step size of the model.
Definition: modelSpec.h:250
std::map< std::string, CurrentSourceInternal >::value_type CurrentSourceValueType
Definition: modelSpec.h:227
Models::VarReference createPSMVarRef(const SynapseGroup *sg, const std::string &varName)
Creates a reference to a postsynaptic model variable.
Definition: modelSpec.h:150
InitToeplitzConnectivitySnippet::Init initToeplitzConnectivity(const typename S::ParamValues &params)
Initialise toeplitz connectivity using a toeplitz connectivity snippet.
Definition: modelSpec.h:117
const std::map< std::string, CustomUpdateInternal > & getCustomUpdates() const
Get std::map containing named CustomUpdate objects in model.
Definition: modelSpec.h:830
Definition: models.h:210
SynapseMatrixType
Supported combinations of SynapticMatrixConnectivity and SynapticMatrixWeight.
Definition: synapseMatrixType.h:27
Definition: models.h:295
static VarReference createPSMVarRef(const SynapseGroup *sg, const std::string &varName)
Definition: models.cc:48
Models::VarInit initVar(const typename S::ParamValues &params)
Initialise a variable using an initialisation snippet.
Definition: modelSpec.h:62
Time uses double precision - may reduce performance.
SynapseGroup * addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string &src, const std::string &trg, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers, const InitToeplitzConnectivitySnippet::Init &connectivityInitialiser)
Adds a synapse population to the model using singleton weight update and postsynaptic models created ...
Definition: modelSpec.h:541
const std::map< std::string, CustomUpdateWUInternal > & getCustomWUUpdates() const
Definition: modelSpec.h:831
Definition: models.h:258
void setFusePrePostWeightUpdateModels(bool fuse)
Should compatible pre and postsynaptic weight update model variables and updates be fused...
Definition: modelSpec.h:283
static EGPReference createPSMEGPRef(const SynapseGroup *sg, const std::string &egpName)
Definition: models.cc:208
FloatType
Floating point precision to use for models.
Definition: modelSpec.h:42
std::map< std::string, SynapseGroupInternal >::value_type SynapseGroupValueType
Definition: modelSpec.h:226
void setTimePrecision(TimePrecision timePrecision)
Set numerical precision for time.
Definition: modelSpec.h:247
std::map< std::string, NeuronGroupInternal >::value_type NeuronGroupValueType
Definition: modelSpec.h:225
const std::map< std::string, CurrentSourceInternal > & getLocalCurrentSources() const
Get std::map containing local named CurrentSource objects in model.
Definition: modelSpec.h:827
void setDefaultExtraGlobalParamLocation(VarLocation loc)
What is the default location for model extra global parameters?
Definition: modelSpec.h:264
Definition: modelSpec.h:46
SynapseGroup * addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string &src, const std::string &trg, const WeightUpdateModel *wum, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename WeightUpdateModel::PreVarValues &weightPreVarInitialisers, const typename WeightUpdateModel::PostVarValues &weightPostVarInitialisers, const PostsynapticModel *psm, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers, const InitSparseConnectivitySnippet::Init &connectivityInitialiser=uninitialisedConnectivity())
Adds a synapse population to the model using weight update and postsynaptic models managed by the use...
Definition: modelSpec.h:384
SynapseGroup * addSlaveSynapsePopulation(const std::string &name, const std::string &weightSharingMasterName, unsigned int delaySteps, const std::string &src, const std::string &trg, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers)
Adds a synapse population to the model using shared per-synapse variables and a singleton postsynapti...
Definition: modelSpec.h:632
const std::string & getPrecision() const
Gets the floating point numerical precision.
Definition: modelSpec.h:291
Models::VarReference createWUPostVarRef(const SynapseGroup *sg, const std::string &varName)
Creates a reference to a weight update model postsynapticvariable.
Definition: modelSpec.h:162
NeuronGroup * findNeuronGroup(const std::string &name)
Find a neuron group by name.
Definition: modelSpec.h:313
SynapseGroup * addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string &src, const std::string &trg, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers, const InitSparseConnectivitySnippet::Init &connectivityInitialiser=uninitialisedConnectivity())
Adds a synapse population to the model using singleton weight update and postsynaptic models created ...
Definition: modelSpec.h:446
CustomUpdate * addCustomUpdate(const std::string &name, const std::string &updateGroupName, const typename CustomUpdateModel::ParamValues &paramValues, const typename CustomUpdateModel::VarValues &varInitialisers, const typename CustomUpdateModel::VarReferences &varReferences, const typename CustomUpdateModel::EGPReferences &egpReferences={})
Definition: modelSpec.h:766
void setDefaultNarrowSparseIndEnabled(bool enabled)
Sets default for whether narrow i.e. less than 32-bit types are used for sparse matrix indices...
Definition: modelSpec.h:271
InitSparseConnectivitySnippet::Init uninitialisedConnectivity()
Mark a synapse group&#39;s sparse connectivity as uninitialised.
Definition: modelSpec.h:107
Definition: currentSource.h:20
SynapseGroup * addSynapsePopulation(const std::string &name, SynapseMatrixType mtype, unsigned int delaySteps, const std::string &src, const std::string &trg, const typename WeightUpdateModel::ParamValues &weightParamValues, const typename WeightUpdateModel::VarValues &weightVarInitialisers, const typename PostsynapticModel::ParamValues &postsynapticParamValues, const typename PostsynapticModel::VarValues &postsynapticVarInitialisers, const InitToeplitzConnectivitySnippet::Init &connectivityInitialiser)
Adds a synapse population to the model using singleton weight update and postsynaptic models created ...
Definition: modelSpec.h:477