GeNN  1.1
GPU enhanced Neuronal Networks (GeNN)
 All Classes Files Functions Variables Typedefs Macros Pages
utils.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------
3  Author/Modifier: Thomas Nowotny
4 
5  Institute: Center for Computational Neuroscience and Robotics
6  University of Sussex
7  Falmer, Brighton BN1 9QJ, UK
8 
9  email to: T.Nowotny@sussex.ac.uk
10 
11  initial version: 2010-02-07
12 
13  This file contains neuron model definitions.
14 
15 --------------------------------------------------------------------------*/
16 
17 #ifndef _UTILS_H_
18 #define _UTILS_H_
19 
20 
21 //--------------------------------------------------------------------------
26 //--------------------------------------------------------------------------
27 
28 #include <cstdlib> // for exit() and EXIT_FAIL / EXIT_SUCCESS
29 #include <iostream>
30 #include <string>
31 #include <vector>
32 #include <map>
33 #include <memory>
34 #include <fstream>
35 #include <cmath>
36 
37 #include <cuda_runtime.h>
38 
39 #include "modelSpec.h"
40 #include "toString.h"
41 //--------------------------------------------------------------------------
42 /* \brief Macro for wrapping cuda runtime function calls and catching any errors that may be thrown.
43  */
44 //--------------------------------------------------------------------------
45 
46 #define CHECK_CUDA_ERRORS(call) \
47 { \
48  cudaError_t error = call; \
49  if (error != cudaSuccess) \
50  { \
51  fprintf(stderr, "%s: %i: cuda error %i: %s\n", \
52  __FILE__, __LINE__, (int)error, cudaGetErrorString(error)); \
53  exit(EXIT_FAILURE); \
54  } \
55 }
56 
57 //--------------------------------------------------------------------------
58 /* \brief Function to write the comment header denoting file authorship and contact details into the generated code.
59  */
60 //--------------------------------------------------------------------------
61 
62 void writeHeader(ostream &os)
63 {
64  string s;
65  ifstream is("header.src");
66  getline(is, s);
67  while (is.good()) {
68  os << s << endl;
69  getline(is, s);
70  }
71  os << endl;
72 }
73 
74 
75 //--------------------------------------------------------------------------
77 //--------------------------------------------------------------------------
78 
79 void substitute(string &s, const string trg, const string rep)
80 {
81  size_t found= s.find(trg);
82  while (found != string::npos) {
83  s.replace(found,trg.length(),rep);
84  found= s.find(trg);
85  }
86 }
87 
88 
89 //--------------------------------------------------------------------------
91 //--------------------------------------------------------------------------
92 
93 bool find(string &s, const string trg)
94 {
95  size_t found= s.find(trg);
96  return (found != string::npos);
97 }
98 
99 
100 //--------------------------------------------------------------------------
102 //--------------------------------------------------------------------------
103 
104 unsigned int theSize(string type)
105 {
106  unsigned int size = 0;
107  if (type == "int") size = sizeof(int);
108  if (type == "unsigned int") size = sizeof(unsigned int);
109  if (type == "float") size = sizeof(float);
110  if (type == "double") size = sizeof(double);
111  if (type == "long double") size = sizeof(long double);
112  return size;
113 }
114 
115 //--------------------------------------------------------------------------
117 //--------------------------------------------------------------------------
118 
119 
120 class rulkovdp : public dpclass
121 {
122 public:
123  float calculateDerivedParameter(int index, vector <float> pars, float dt = 1.0) {
124  switch (index) {
125  case 0:
126  return ip0(pars);
127  case 1:
128  return ip1(pars);
129  case 2:
130  return ip2(pars);
131  }
132  return -1;
133  }
134 
135  float ip0(vector<float> pars) {
136  return pars[0]*pars[0]*pars[1];
137  }
138  float ip1(vector<float> pars) {
139  return pars[0]*pars[2];
140  }
141  float ip2(vector<float> pars) {
142  return pars[0]*pars[1]+pars[0]*pars[2];
143  }
144 };
145 
146 //--------------------------------------------------------------------------
148 //--------------------------------------------------------------------------
149 
150 class expDecayDp : public dpclass
151 {
152 public:
153  float calculateDerivedParameter(int index, vector <float> pars, float dt = 1.0) {
154  switch (index) {
155  case 0:
156  return expDecay(pars, dt);
157  }
158  return -1;
159  }
160 
161  float expDecay(vector<float> pars, float dt) {
162  return expf(-dt/pars[0]);
163  }
164 };
165 
166 vector<neuronModel> nModels;
167 
168 //--------------------------------------------------------------------------
173 //--------------------------------------------------------------------------
174 //NOTE: calcSynapses takes the first variable of each model.neuronName[src] as an argument, of type float. If you add a neuron model, keep this in mind.
175 
177 {
178  neuronModel n;
179 
180  //Rulkov neurons
181  n.varNames.push_back(tS("V"));
182  n.varTypes.push_back(tS("float"));
183  n.varNames.push_back(tS("preV"));
184  n.varTypes.push_back(tS("float"));
185  n.pNames.push_back(tS("Vspike"));
186  n.pNames.push_back(tS("alpha"));
187  n.pNames.push_back(tS("y"));
188  n.pNames.push_back(tS("beta"));
189  n.dpNames.push_back(tS("ip0"));
190  n.dpNames.push_back(tS("ip1"));
191  n.dpNames.push_back(tS("ip2"));
192  n.simCode= tS(" if ($(V) <= 0.0) {\n\
193  $(preV)= $(V);\n\
194  $(V)= $(ip0)/(($(Vspike)) - $(V) - ($(beta))*$(Isyn)) +($(ip1));\n\
195  }\n\
196  else {\n\
197  if (($(V) < $(ip2)) && ($(preV) <= 0.0)) {\n\
198  $(preV)= $(V);\n\
199  $(V)= $(ip2);\n\
200  }\n\
201  else {\n\
202  $(preV)= $(V);\n\
203  $(V)= -($(Vspike));\n\
204  }\n\
205  }\n");
206 
207  n.thresholdConditionCode = tS("$(V) > $(ip2) - 0.01");
208 
209  n.dps = new rulkovdp();
210 
211  nModels.push_back(n);
212 
213  // Poisson neurons
214  n.varNames.clear();
215  n.varTypes.clear();
216  n.varNames.push_back(tS("V"));
217  n.varTypes.push_back(tS("float"));
218  n.varNames.push_back(tS("seed"));
219  n.varTypes.push_back(tS("unsigned int"));
220  n.varNames.push_back(tS("spikeTime"));
221  n.varTypes.push_back(tS("float"));
222  n.pNames.clear();
223  n.pNames.push_back(tS("therate"));
224  n.pNames.push_back(tS("trefract"));
225  n.pNames.push_back(tS("Vspike"));
226  n.pNames.push_back(tS("Vrest"));
227  n.dpNames.clear();
228  n.simCode= tS(" unsigned int theRnd;\n\
229  if ($(V) > $(Vrest)) {\n\
230  $(V)= $(Vrest);\n\
231  }\n\
232  else {\n\
233  if (t - $(spikeTime) > ($(trefract))) {\n\
234  RAND($(seed),theRnd);\n\
235  if (theRnd < lrate) {\n\
236  $(V)= $(Vspike);\n\
237  $(spikeTime)= t;\n\
238  }\n\
239  }\n\
240  }\n");
241 
242  n.thresholdConditionCode = tS("$(V) > $(Vspike) - 0.01");
243 
244  nModels.push_back(n);
245 
246 // Traub and Miles HH neurons
247  n.varNames.clear();
248  n.varTypes.clear();
249  n.varNames.push_back(tS("V"));
250  n.varTypes.push_back(tS("float"));
251  n.varNames.push_back(tS("m"));
252  n.varTypes.push_back(tS("float"));
253  n.varNames.push_back(tS("h"));
254  n.varTypes.push_back(tS("float"));
255  n.varNames.push_back(tS("n"));
256  n.varTypes.push_back(tS("float"));
257  n.pNames.clear();
258  n.pNames.push_back(tS("gNa"));
259  n.pNames.push_back(tS("ENa"));
260  n.pNames.push_back(tS("gK"));
261  n.pNames.push_back(tS("EK"));
262  n.pNames.push_back(tS("gl"));
263  n.pNames.push_back(tS("El"));
264  n.pNames.push_back(tS("C"));
265  n.dpNames.clear();
266  n.simCode= tS(" float Imem;\n\
267  unsigned int mt;\n\
268  float mdt= DT/25.0f;\n\
269  for (mt=0; mt < 25; mt++) {\n\
270  Imem= -($(m)*$(m)*$(m)*$(h)*$(gNa)*($(V)-($(ENa)))+\n\
271  $(n)*$(n)*$(n)*$(n)*$(gK)*($(V)-($(EK)))+\n\
272  $(gl)*($(V)-($(El)))-Isyn);\n\
273  float _a= 0.32f*(-52.0f-$(V)) / (exp((-52.0f-$(V))/4.0f)-1.0f);\n\
274  float _b= 0.28f*($(V)+25.0f)/(exp(($(V)+25.0f)/5.0f)-1.0f);\n\
275  $(m)+= (_a*(1.0f-$(m))-_b*$(m))*mdt;\n\
276  _a= 0.128*expf((-48.0f-$(V))/18.0f);\n\
277  _b= 4.0f / (expf((-25.0f-$(V))/5.0f)+1.0f);\n\
278  $(h)+= (_a*(1.0f-$(h))-_b*$(h))*mdt;\n\
279  _a= .032f*(-50.0f-$(V)) / (expf((-50.0f-$(V))/5.0f)-1.0f); \n\
280  _b= 0.5f*expf((-55.0f-$(V))/40.0f);\n\
281  $(n)+= (_a*(1.0-$(n))-_b*$(n))*mdt;\n\
282  $(V)+= Imem/$(C)*mdt;\n\
283  }\n");
284 
285  n.thresholdConditionCode = tS("$(V) > 20");//TODO check this, to get better value
286 
287  nModels.push_back(n);
288 
289  //Izhikevich neurons
290  n.varNames.clear();
291  n.varTypes.clear();
292  n.varNames.push_back(tS("V"));
293  n.varTypes.push_back(tS("float"));
294  n.varNames.push_back(tS("U"));
295  n.varTypes.push_back(tS("float"));
296  n.pNames.clear();
297  //n.pNames.push_back(tS("Vspike"));
298  n.pNames.push_back(tS("a")); // time scale of U
299  n.pNames.push_back(tS("b")); // sensitivity of U
300  n.pNames.push_back(tS("c")); // after-spike reset value of V
301  n.pNames.push_back(tS("d")); // after-spike reset value of U
302  n.dpNames.clear();
303  //TODO: replace the resetting in the following with BRIAN-like threshold and resetting
304  n.simCode= tS(" if ($(V) >= 30){\n\
305  $(V)=$(c);\n\
306  $(U)+=$(d);\n\
307  } \n\
308  $(V)+=0.5f*(0.04f*$(V)*$(V)+5*$(V)+140-$(U)+$(Isyn))*DT; //at two times for numerical stability\n\
309  $(V)+=0.5f*(0.04f*$(V)*$(V)+5*$(V)+140-$(U)+$(Isyn))*DT;\n\
310  $(U)+=$(a)*($(b)*$(V)-$(U))*DT;\n\
311  // if ($(V) > 30){ //keep this only for visualisation -- not really necessaary otherwise \n\
312  // $(V)=30; \n\
313  //}\n\
314  ");
315 
316  n.thresholdConditionCode = tS("$(V) >= 29.99");
317 
318  /* n.resetCode=tS("//reset code is here\n ");
319  $(V)=$(c);\n\
320  $(U)+=$(d);\n\
321  */
322  nModels.push_back(n);
323 
324 //Izhikevich neurons with variable parameters
325  n.varNames.clear();
326  n.varTypes.clear();
327  n.varNames.push_back(tS("V"));
328  n.varTypes.push_back(tS("float"));
329  n.varNames.push_back(tS("U"));
330  n.varTypes.push_back(tS("float"));
331  n.varNames.push_back(tS("a")); // time scale of U
332  n.varTypes.push_back(tS("float"));
333  n.varNames.push_back(tS("b")); // sensitivity of U
334  n.varTypes.push_back(tS("float"));
335  n.varNames.push_back(tS("c")); // after-spike reset value of V
336  n.varTypes.push_back(tS("float"));
337  n.varNames.push_back(tS("d")); // after-spike reset value of U
338  n.varTypes.push_back(tS("float"));
339  n.pNames.clear();
340  n.dpNames.clear();
341  //TODO: replace the resetting in the following with BRIAN-like threshold and resetting
342  n.simCode= tS(" if ($(V) >= 30){\n\
343  $(V)=$(c);\n\
344  $(U)+=$(d);\n\
345  } \n\
346  $(V)+=0.5f*(0.04f*$(V)*$(V)+5*$(V)+140-$(U)+$(Isyn))*DT; //at two times for numerical stability\n\
347  $(V)+=0.5f*(0.04f*$(V)*$(V)+5*$(V)+140-$(U)+$(Isyn))*DT;\n\
348  $(U)+=$(a)*($(b)*$(V)-$(U))*DT;\n\
349  //if ($(V) > 30){ //keep this only for visualisation -- not really necessaary otherwise \n\
350  // $(V)=30; \n\
351  //}\n\
352  ");
353  n.thresholdConditionCode = tS("$(V) > 29.99");
354  nModels.push_back(n);
355 
356  #include "extra_neurons.h"
357 
358 }
359 
360 
361 
362 
363 vector<postSynModel> postSynModels;
364 
365 //--------------------------------------------------------------------------
366 /* \brief Function that prepares the standard post-synaptic models, including their variables, parameters, dependent parameters and code strings.
367  */
368 //--------------------------------------------------------------------------
369 
370 void preparePostSynModels(){
371  postSynModel ps;
372 
373  //0: Exponential decay
374  ps.varNames.clear();
375  ps.varTypes.clear();
376 
377  //ps.varNames.push_back(tS("E"));
378  //ps.varTypes.push_back(tS("float"));
379 
380  ps.pNames.clear();
381  ps.dpNames.clear();
382 
383  ps.pNames.push_back(tS("tau"));
384  ps.pNames.push_back(tS("E"));
385  ps.dpNames.push_back(tS("expDecay"));
386 
387  ps.postSynDecay=tS(" $(inSyn)*=$(expDecay);\n");
388  ps.postSyntoCurrent=tS("$(inSyn)*($(E)-$(V))");
389 
390  ps.dps = new expDecayDp;
391 
392  postSynModels.push_back(ps);
393 
394 
395  //1: IZHIKEVICH MODEL (NO POSTSYN RULE)
396  ps.varNames.clear();
397  ps.varTypes.clear();
398 
399  ps.pNames.clear();
400  ps.dpNames.clear();
401 
402  ps.postSynDecay=tS("");
403  ps.postSyntoCurrent=tS("$(inSyn); $(inSyn)=0");
404 
405  postSynModels.push_back(ps);
406 
407  #include "extra_postsynapses.h"
408 }
409 
410 //--------------------------------------------------------------------------
411 /* \brief Function that prepares the standard (pre) synaptic models, including their variables, parameters, dependent parameters and code strings.
412  */
413 //--------------------------------------------------------------------------
414 
415 void prepareSynapseModels(){
416 }
417 // bit tool macros
418 #include "numlib/simpleBit.h"
419 
420 #endif // _UTILS_H_
float calculateDerivedParameter(int index, vector< float > pars, float dt=1.0)
Definition: utils.h:153
vector< string > varNames
Names of the variables in the postsynaptic model.
Definition: modelSpec.h:134
vector< postSynModel > postSynModels
Definition: utils.h:7
vector< string > pNames
Names of (independent) parameters of the model. These are assumed to be always of type "float"...
Definition: modelSpec.h:118
#define tS(X)
Macro providing the abbreviated syntax tS() instead of toString().
Definition: toString.h:43
Contains a template function for string conversion from const char* to C++ string.
vector< string > pNames
Names of (independent) parameters of the model. These are assumed to be always of type "float"...
Definition: modelSpec.h:136
void prepareSynapseModels()
Definition: utils.h:8
bool find(string &s, const string trg)
Tool for finding strings in another string.
Definition: utils.h:93
string simCode
Code that defines the execution of one timestep of integration of the neuron model.
Definition: modelSpec.h:109
Contains three macros that allow simple bit manipulations on an (presumably unsigned) 64 bit integer...
vector< neuronModel > nModels
Global c++ vector containing all neuron model descriptions.
Definition: utils.h:166
vector< string > dpNames
Names of dependent parameters of the model. These are assumed to be always of type "float"...
Definition: modelSpec.h:137
float ip0(vector< float > pars)
Definition: utils.h:135
void substitute(string &s, const string trg, const string rep)
Tool for substituting strings in the neuron code strings or other templates.
Definition: utils.h:79
Header file that contains the class (struct) definition of neuronModel for defining a neuron model an...
string thresholdConditionCode
Code evaluating to a bool (e.g. "V > 20") that defines the condition for a true spike in the describe...
Definition: modelSpec.h:112
Definition: modelSpec.h:99
void prepareStandardModels()
Function that defines standard neuron models.
Definition: utils.h:176
vector< string > varTypes
Types of the variable named above, e.g. "float". Names and types are matched by their order of occurr...
Definition: modelSpec.h:116
string postSyntoCurrent
Definition: modelSpec.h:132
void preparePostSynModels()
Definition: utils.h:14
float calculateDerivedParameter(int index, vector< float > pars, float dt=1.0)
Definition: utils.h:123
Definition: modelSpec.h:130
float ip1(vector< float > pars)
Definition: utils.h:138
string postSynDecay
Definition: modelSpec.h:133
float expDecay(vector< float > pars, float dt)
Definition: utils.h:161
dpclass * dps
Definition: modelSpec.h:138
unsigned int theSize(string type)
Tool for determining the size of variable types on the current architecture.
Definition: utils.h:104
vector< string > varTypes
Types of the variable named above, e.g. "float". Names and types are matched by their order of occurr...
Definition: modelSpec.h:135
class (struct) for specifying a neuron model.
Definition: modelSpec.h:107
void writeHeader(ostream &os)
Definition: utils.h:62
float ip2(vector< float > pars)
Definition: utils.h:141
Class defining the dependent parameters of teh Rulkov map neuron.
Definition: utils.h:120
vector< string > varNames
Names of the variables in the neuron model.
Definition: modelSpec.h:114
Class defining the dependent parameter for exponential decay.
Definition: utils.h:150
vector< string > dpNames
Names of dependent parameters of the model. These are assumed to be always of type "float"...
Definition: modelSpec.h:119
dpclass * dps
Definition: modelSpec.h:126