44 #if (_WIN32 || _WIN64)
50 #define isnan(x) _isnan(x)
54 #define isinf(x) (!_finite(x))
58 #define srand48(x) srand(x)
62 #define drand48() (double(rand())/RAND_MAX)
67 #define strcmpi(s1,s2) strcasecmp(s1,s2)
76 #if defined(CREATE_SPIKEDIR_IF_NOT_EXISTS)
80 #if ! (_WIN32 || _WIN64)
88 void CpuSNN::resetPointers()
100 postSynapticIds = NULL;
101 postDelayInfo = NULL;
108 firingTableD2 = NULL;
109 firingTableD1 = NULL;
122 intrinsicWeight=NULL;
124 tmp_SynapticDelay=NULL;
130 void CpuSNN::resetCurrent()
132 carlsim_assert(current != NULL);
133 memset(current, 0,
sizeof(
float)*numNReg);
136 void CpuSNN::resetCounters()
138 carlsim_assert(numNReg <= numN);
139 memset( curSpike, 0,
sizeof(
bool)*numN);
142 void CpuSNN::resetConductances()
144 if (sim_with_conductances) {
145 carlsim_assert(gAMPA != NULL);
146 memset(gAMPA, 0,
sizeof(
float)*numNReg);
147 memset(gNMDA, 0,
sizeof(
float)*numNReg);
148 memset(gGABAa, 0,
sizeof(
float)*numNReg);
149 memset(gGABAb, 0,
sizeof(
float)*numNReg);
153 void CpuSNN::resetTimingTable()
155 memset(timeTableD2, 0,
sizeof(
int)*(CARLSIM_STEP_SIZE+D+1));
156 memset(timeTableD1, 0,
sizeof(
int)*(CARLSIM_STEP_SIZE+D+1));
159 void CpuSNN::CpuSNNInit(
unsigned int _numN,
unsigned int _numPostSynapses,
unsigned int _numPreSynapses,
unsigned int _D)
162 numPostSynapses = _numPostSynapses;
164 numPreSynapses = _numPreSynapses;
166 voltage =
new float[numNReg];
167 recovery =
new float[numNReg];
168 Izh_a =
new float[numNReg];
169 Izh_b =
new float[numNReg];
170 Izh_c =
new float[numNReg];
171 Izh_d =
new float[numNReg];
172 current =
new float[numNReg];
173 cpuSnnSz.neuronInfoSize += (
sizeof(int)*numNReg*12);
175 if (sim_with_conductances) {
176 for (
int g=0;g<numGrp;g++)
177 if (!grp_Info[g].WithConductances && ((grp_Info[g].Type&POISSON_NEURON)==0)) {
178 printf(
"If one group enables conductances then all groups, except for generators, must enable conductances. Group '%s' is not enabled.\n", grp_Info2[g].Name.c_str());
179 carlsim_assert(
false);
182 gAMPA =
new float[numNReg];
183 gNMDA =
new float[numNReg];
184 gGABAa =
new float[numNReg];
185 gGABAb =
new float[numNReg];
186 cpuSnnSz.neuronInfoSize +=
sizeof(int)*numNReg*4;
192 lastSpikeTime =
new uint32_t[numN];
193 cpuSnnSz.neuronInfoSize +=
sizeof(int)*numN;
194 memset(lastSpikeTime,0,
sizeof(lastSpikeTime[0]*numN));
196 curSpike =
new bool[numN];
197 nSpikeCnt =
new unsigned int[numN];
199 avgFiring =
new float[numN];
200 baseFiring =
new float[numN];
202 intrinsicWeight =
new float[numN];
203 memset(intrinsicWeight,0,
sizeof(
float)*numN);
204 cpuSnnSz.neuronInfoSize += (
sizeof(int)*numN*2+
sizeof(
bool)*numN);
207 stpu =
new float[numN*STP_BUF_SIZE];
208 stpx =
new float[numN*STP_BUF_SIZE];
209 for (
int i=0; i < numN*STP_BUF_SIZE; i++) {
214 cpuSnnSz.synapticInfoSize += (
sizeof(stpu[0])*numN*STP_BUF_SIZE);
217 Npre =
new unsigned short[numN];
218 Npre_plastic =
new unsigned short[numN];
219 Npost =
new unsigned short[numN];
220 cumulativePost =
new unsigned int[numN];
221 cumulativePre =
new unsigned int[numN];
222 cpuSnnSz.networkInfoSize += (int)(
sizeof(
int)*numN*3.5);
226 for(
int g=0; g < numGrp; g++) {
228 carlsim_assert(postSynCnt < UINT_MAX - (grp_Info[g].SizeN*grp_Info[g].numPostSynapses));
229 carlsim_assert(preSynCnt < UINT_MAX - (grp_Info[g].SizeN*grp_Info[g].numPreSynapses));
230 postSynCnt += (grp_Info[g].SizeN*grp_Info[g].numPostSynapses);
231 preSynCnt += (grp_Info[g].SizeN*grp_Info[g].numPreSynapses);
233 carlsim_assert(postSynCnt/numN <= numPostSynapses);
235 tmp_SynapticDelay =
new uint8_t[postSynCnt+100];
237 cpuSnnSz.networkInfoSize += ((
sizeof(
post_info_t)+
sizeof(uint8_t))*postSynCnt+100) + (
sizeof(
delay_info_t)*numN*(D+1));
238 carlsim_assert(preSynCnt/numN <= numPreSynapses);
240 wt =
new float[preSynCnt+100];
241 maxSynWt =
new float[preSynCnt+100];
245 cpuSnnSz.synapticInfoSize += ((2*
sizeof(float)+
sizeof(
post_info_t))*(preSynCnt+100));
247 timeTableD2 =
new unsigned int[CARLSIM_STEP_SIZE+D+1];
248 timeTableD1 =
new unsigned int[CARLSIM_STEP_SIZE+D+1];
250 cpuSnnSz.spikingInfoSize +=
sizeof(int)*2*(CARLSIM_STEP_SIZE+D+1);
257 cpuSnnSz.neuronInfoSize += (
sizeof(int)*numNPois);
259 tmp_SynapseMatrix_fixed = NULL;
260 tmp_SynapseMatrix_plastic = NULL;
263 void CpuSNN::makePtrInfo()
266 cpuNetPtrs.voltage = voltage;
267 cpuNetPtrs.recovery = recovery;
268 cpuNetPtrs.current = current;
269 cpuNetPtrs.
Npre = Npre;
270 cpuNetPtrs.
Npost = Npost;
271 cpuNetPtrs.cumulativePost = cumulativePost;
272 cpuNetPtrs.cumulativePre = cumulativePre;
273 cpuNetPtrs.synSpikeTime = synSpikeTime;
275 cpuNetPtrs.wtChange = wtChange;
277 cpuNetPtrs.curSpike = curSpike;
278 cpuNetPtrs.firingTableD2 = firingTableD2;
279 cpuNetPtrs.firingTableD1 = firingTableD1;
281 cpuNetPtrs.avgFiring = avgFiring;
282 cpuNetPtrs.baseFiring = baseFiring;
283 cpuNetPtrs.gAMPA = gAMPA;
284 cpuNetPtrs.gNMDA = gNMDA;
285 cpuNetPtrs.gGABAa = gGABAa;
286 cpuNetPtrs.gGABAb = gGABAb;
288 cpuNetPtrs.memType = CPU_MODE;
289 cpuNetPtrs.stpu = stpu;
290 cpuNetPtrs.stpx = stpx;
295 int startGrp, endGrp;
297 if(!doneReorganization)
300 if (my_grpId == -1) {
306 endGrp = my_grpId+numConfig;
309 for(
int grpId=startGrp; grpId < endGrp; grpId++) {
310 int startN = grp_Info[grpId].StartN;
311 int endN = grp_Info[grpId].EndN+1;
312 for (
int i=startN; i < endN; i++)
320 int startGrp, endGrp;
322 if(!doneReorganization)
325 if(currentMode == GPU_MODE){
327 if (my_grpId == -1) {
333 endGrp = my_grpId+numConfig;
339 if (my_grpId == -1) {
345 endGrp = my_grpId+numConfig;
348 for(
int grpId=startGrp; grpId < endGrp; grpId++) {
349 int startN = grp_Info[grpId].StartN;
350 int endN = grp_Info[grpId].EndN+1;
351 for (
int i=startN; i < endN; i++)
356 CpuSNN::CpuSNN(
const string& _name,
int _numConfig,
int _randSeed,
int _mode)
358 fprintf(stdout,
"************************************************\n");
360 fprintf(stdout,
"************************************************\n");
365 numConfig = _numConfig;
366 finishedPoissonGroup =
false;
367 carlsim_assert(numConfig > 0);
368 carlsim_assert(numConfig < 100);
371 numN = 0; numPostSynapses = 0; D = 0;
372 memset(&cpuSnnSz, 0,
sizeof(cpuSnnSz));
373 enableSimLogs =
false;
374 simLogDirName =
"logs";
376 fpLog=fopen(
"tmp_debug.log",
"w");
380 showGrpFiringInfo =
true;
391 #define VIEW_DOTTY false
393 showDotty = VIEW_DOTTY;
396 for (
int i=0; i < MAX_GRP_PER_SNN; i++) {
397 grp_Info[i].Type = UNKNOWN_NEURON;
399 grp_Info[i].MonitorId = -1;
400 grp_Info[i].FiringCount1sec=0;
401 grp_Info[i].numPostSynapses = 0;
402 grp_Info[i].numPreSynapses = 0;
403 grp_Info[i].WithSTP =
false;
404 grp_Info[i].WithSTDP =
false;
405 grp_Info[i].FixedInputWts =
true;
407 grp_Info[i].WithConductances =
false;
408 grp_Info[i].isSpikeGenerator =
false;
409 grp_Info[i].RatePtr = NULL;
411 grp_Info[i].homeoId = -1;
412 grp_Info[i].avgTimeScale = 10000.0;
418 grp_Info[i].dAMPA=1-(1.0/5);
419 grp_Info[i].dNMDA=1-(1.0/150);
420 grp_Info[i].dGABAa=1-(1.0/6);
421 grp_Info[i].
dGABAb=1-(1.0/150);
423 grp_Info[i].spikeGen = NULL;
425 grp_Info[i].StartN = -1;
426 grp_Info[i].EndN = -1;
428 grp_Info2[i].numPostConn = 0;
429 grp_Info2[i].numPreConn = 0;
431 grp_Info2[i].maxPostConn = 0;
432 grp_Info2[i].maxPreConn = 0;
433 grp_Info2[i].sumPostConn = 0;
434 grp_Info2[i].sumPreConn = 0;
441 simTimeMs = 0; simTimeSec = 0; simTime = 0;
442 spikeCountAll1sec = 0; secD1fireCntHost = 0; secD2fireCntHost = 0;
443 spikeCountAll = 0; spikeCountD2Host = 0; spikeCountD1Host = 0;
454 simulatorDeleted =
false;
455 enableGPUSpikeCntPtr =
false;
460 doneReorganization =
false;
461 memoryOptimized =
false;
470 if (_randSeed == -1) {
471 randSeed = time(NULL);
473 else if(_randSeed==0) {
477 getRand.seed(randSeed*2);
478 getRandClosed.seed(randSeed*3);
480 fpParam = fopen(
"param.txt",
"w");
482 fprintf(stderr,
"WARNING !!! Unable to open/create parameter file 'param.txt'; check if current directory is writable \n");
483 #ifdef USE_EXCEPTIONS
484 throw std::runtime_error(
"WARNING !!! Unable to open/create parameter file 'param.txt'; check if current directory is writable \n");
490 fprintf(fpParam,
"// *****************************************\n");
491 time_t rawtime;
struct tm * timeinfo;
492 time ( &rawtime ); timeinfo = localtime ( &rawtime );
493 fprintf ( fpParam,
"// program name : %s \n", _name.c_str());
494 fprintf ( fpParam,
"// rand val : %d \n", randSeed);
495 fprintf ( fpParam,
"// Current local time and date: %s\n", asctime (timeinfo));
498 CUDA_CREATE_TIMER(timer);
499 CUDA_RESET_TIMER(timer);
500 cumExecutionTime = 0.0;
502 spikeRateUpdated =
false;
504 sim_with_fixedwts =
true;
505 sim_with_conductances =
false;
506 sim_with_stdp =
false;
507 sim_with_stp =
false;
509 maxSpikesD2 = maxSpikesD1 = 0;
510 readNetworkFID = NULL;
513 CpuSNNinitGPUparams();
518 void CpuSNN::deleteObjects()
541 if (voltage!=NULL)
delete[] voltage;
542 if (recovery!=NULL)
delete[] recovery;
543 if (Izh_a!=NULL)
delete[] Izh_a;
544 if (Izh_b!=NULL)
delete[] Izh_b;
545 if (Izh_c!=NULL)
delete[] Izh_c;
546 if (Izh_d!=NULL)
delete[] Izh_d;
547 if (current!=NULL)
delete[] current;
549 if (Npre!=NULL)
delete[] Npre;
550 if (Npre_plastic!=NULL)
delete[] Npre_plastic;
551 if (Npost!=NULL)
delete[] Npost;
553 if (cumulativePre!=NULL)
delete[] cumulativePre;
554 if (cumulativePost!=NULL)
delete[] cumulativePost;
556 if (gAMPA!=NULL)
delete[] gAMPA;
557 if (gNMDA!=NULL)
delete[] gNMDA;
558 if (gGABAa!=NULL)
delete[] gGABAa;
559 if (gGABAb!=NULL)
delete[] gGABAb;
561 if (stpu!=NULL)
delete[] stpu;
562 if (stpx!=NULL)
delete[] stpx;
564 if (lastSpikeTime!=NULL)
delete[] lastSpikeTime;
565 if (synSpikeTime !=NULL)
delete[] synSpikeTime;
566 if (curSpike!=NULL)
delete[] curSpike;
567 if (nSpikeCnt!=NULL)
delete[] nSpikeCnt;
568 if (intrinsicWeight!=NULL)
delete[] intrinsicWeight;
570 if (postDelayInfo!=NULL)
delete[] postDelayInfo;
571 if (preSynapticIds!=NULL)
delete[] preSynapticIds;
572 if (postSynapticIds!=NULL)
delete[] postSynapticIds;
573 if (tmp_SynapticDelay!=NULL)
delete[] tmp_SynapticDelay;
575 if(wt!=NULL)
delete[] wt;
576 if(maxSynWt!=NULL)
delete[] maxSynWt;
577 if(wtChange !=NULL)
delete[] wtChange;
579 if (firingTableD2)
delete[] firingTableD2;
580 if (firingTableD1)
delete[] firingTableD1;
581 if (timeTableD2!=NULL)
delete[] timeTableD2;
582 if (timeTableD1!=NULL)
delete[] timeTableD1;
587 while (connectBegin) {
590 connectBegin = nextConn;
593 for (
int i = 0; i < numSpikeMonitor; i++) {
594 delete[] monBufferFiring[i];
595 delete[] monBufferTimeCnt[i];
598 if(spikeGenBits)
delete[] spikeGenBits;
603 CUDA_DELETE_TIMER(timer);
605 simulatorDeleted =
true;
609 fprintf(stderr,
"Unknown exception ...\n");
613 void CpuSNN::exitSimulation(
int val,
const char *errorString)
615 fprintf(stderr, errorString);
619 #ifdef USE_EXCEPTIONS
620 throw std::runtime_error(errorString);
628 if (!simulatorDeleted)
632 void CpuSNN::setSTDP(
int grpId,
bool enable,
int configId)
634 carlsim_assert(enable==
false);
635 setSTDP(grpId,
false,0,0,0,0,configId);
638 void CpuSNN::setSTDP(
int grpId,
bool enable,
float ALPHA_LTP,
float TAU_LTP,
float ALPHA_LTD,
float TAU_LTD,
int configId)
640 carlsim_assert(TAU_LTP >= 0.0);
641 carlsim_assert(TAU_LTD >= 0.0);
643 if (grpId == ALL && configId == ALL) {
644 for(
int g=0; g < numGrp; g++)
645 setSTDP(g, enable, ALPHA_LTP,TAU_LTP,ALPHA_LTD,TAU_LTD, 0);
646 }
else if (grpId == ALL) {
647 for(
int grpId1=0; grpId1 < numGrp; grpId1 += numConfig) {
648 int g = getGroupId(grpId1, configId);
649 setSTDP(g, enable, ALPHA_LTP,TAU_LTP,ALPHA_LTD,TAU_LTD, configId);
651 }
else if (configId == ALL) {
652 for(
int c=0; c < numConfig; c++)
653 setSTDP(grpId, enable, ALPHA_LTP,TAU_LTP,ALPHA_LTD,TAU_LTD, c);
655 int cGrpId = getGroupId(grpId, configId);
657 sim_with_stdp |= enable;
659 grp_Info[cGrpId].WithSTDP = enable;
660 grp_Info[cGrpId].ALPHA_LTP = ALPHA_LTP;
661 grp_Info[cGrpId].ALPHA_LTD = ALPHA_LTD;
662 grp_Info[cGrpId].TAU_LTP_INV = 1.0/TAU_LTP;
663 grp_Info[cGrpId].TAU_LTD_INV = 1.0/TAU_LTD;
667 fprintf(stderr,
"STDP %s for %d (%s): %f, %f, %f, %f\n", enable?
"enabled":
"disabled",
668 cGrpId, grp_Info2[cGrpId].Name.c_str(), ALPHA_LTP, ALPHA_LTD, TAU_LTP, TAU_LTD);
672 void CpuSNN::setSTP(
int grpId,
bool enable,
int configId)
674 carlsim_assert(enable==
false);
675 setSTP(grpId,
false,0,0,0,configId);
678 void CpuSNN::setSTP(
int grpId,
bool enable,
float STP_U,
float STP_tD,
float STP_tF,
int configId)
680 if (grpId == ALL && configId == ALL) {
681 for(
int g=0; g < numGrp; g++)
682 setSTP(g, enable, STP_U, STP_tD, STP_tF, 0);
683 }
else if (grpId == ALL) {
684 for(
int grpId1=0; grpId1 < numGrp; grpId1 += numConfig) {
685 int g = getGroupId(grpId1, configId);
686 setSTP(g, enable, STP_U, STP_tD, STP_tF, configId);
688 }
else if (configId == ALL) {
689 for(
int c=0; c < numConfig; c++)
690 setSTP(grpId, enable, STP_U, STP_tD, STP_tF, c);
692 int cGrpId = getGroupId(grpId, configId);
694 sim_with_stp |= enable;
696 grp_Info[cGrpId].WithSTP = enable;
697 grp_Info[cGrpId].STP_U=STP_U;
698 grp_Info[cGrpId].STP_tD=STP_tD;
699 grp_Info[cGrpId].STP_tF=STP_tF;
703 fprintf(stderr,
"STP %s for %d (%s): %f, %f, %f\n", enable?
"enabled":
"disabled",
704 cGrpId, grp_Info2[cGrpId].Name.c_str(), STP_U, STP_tD, STP_tF);
708 void CpuSNN::setConductances(
int grpId,
bool enable,
int configId)
710 carlsim_assert(enable==
false);
711 setConductances(grpId,
false,0,0,0,0,configId);
714 void CpuSNN::setConductances(
int grpId,
bool enable,
float tAMPA,
float tNMDA,
float tGABAa,
float tGABAb,
int configId)
716 if (grpId == ALL && configId == ALL) {
717 for(
int g=0; g < numGrp; g++)
718 setConductances(g, enable, tAMPA, tNMDA, tGABAa, tGABAb, 0);
719 }
else if (grpId == ALL) {
720 for(
int grpId1=0; grpId1 < numGrp; grpId1 += numConfig) {
721 int g = getGroupId(grpId1, configId);
722 setConductances(g, enable, tAMPA, tNMDA, tGABAa, tGABAb, configId);
724 }
else if (configId == ALL) {
725 for(
int c=0; c < numConfig; c++)
726 setConductances(grpId, enable, tAMPA, tNMDA, tGABAa, tGABAb, c);
728 int cGrpId = getGroupId(grpId, configId);
730 sim_with_conductances |= enable;
732 grp_Info[cGrpId].WithConductances = enable;
734 grp_Info[cGrpId].dAMPA=1-(1.0/tAMPA);
735 grp_Info[cGrpId].dNMDA=1-(1.0/tNMDA);
736 grp_Info[cGrpId].dGABAa=1-(1.0/tGABAa);
737 grp_Info[cGrpId].
dGABAb=1-(1.0/tGABAb);
741 fprintf(stderr,
"Conductances %s for %d (%s): %f, %f, %f, %f\n", enable?
"enabled":
"disabled",
742 cGrpId, grp_Info2[cGrpId].Name.c_str(), tAMPA, tNMDA, tGABAa, tGABAb);
748 carlsim_assert(enable==
false);
754 if (grpId == ALL && configId == ALL) {
755 for(
int g=0; g < numGrp; g++)
757 }
else if (grpId == ALL) {
758 for(
int grpId1=0; grpId1 < numGrp; grpId1 += numConfig) {
759 int g = getGroupId(grpId1, configId);
760 setHomeostasis(g, enable, homeostasisScale, avgTimeScale, configId);
762 }
else if (configId == ALL) {
763 for(
int c=0; c < numConfig; c++)
766 int cGrpId = getGroupId(grpId, configId);
768 grp_Info[cGrpId].WithHomeostasis = enable;
769 grp_Info[cGrpId].homeostasisScale = homeostasisScale;
770 grp_Info[cGrpId].avgTimeScale = avgTimeScale;
771 grp_Info[cGrpId].avgTimeScaleInv = 1/avgTimeScale;
772 grp_Info[cGrpId].avgTimeScale_decay = (avgTimeScale*1000-1)/(avgTimeScale*1000);
773 fprintf(stderr,
"Homeostasis parameters set for cGrpId: %d (%s)\n", cGrpId, grp_Info2[cGrpId].Name.c_str());
781 int cGrpId = getGroupId(groupId, configId);
782 grp_Info2[cGrpId].baseFiring = _baseFiring;
783 grp_Info2[cGrpId].baseFiringSD = _baseFiringSD;
789 if (configId == ALL) {
790 for(
int c=0; c < numConfig; c++)
792 return (numGrp-numConfig);
794 carlsim_assert(numGrp < MAX_GRP_PER_SNN);
796 if ( (!(_nType&TARGET_AMPA) && !(_nType&TARGET_NMDA) &&
797 !(_nType&TARGET_GABAa) && !(_nType&TARGET_GABAb)) || (_nType&POISSON_NEURON)) {
798 exitSimulation(1,
"Invalid type using createGroup...\ncan not create poisson generators here...\n");
801 grp_Info[numGrp].SizeN = _numN;
802 grp_Info[numGrp].Type = _nType;
803 grp_Info[numGrp].WithConductances =
false;
804 grp_Info[numGrp].WithSTP =
false;
805 grp_Info[numGrp].WithSTDP =
false;
806 grp_Info[numGrp].WithHomeostasis =
false;
808 if ( (_nType&TARGET_GABAa) || (_nType&TARGET_GABAb)) {
809 grp_Info[numGrp].
MaxFiringRate = INHIBITORY_NEURON_MAX_FIRING_RATE;
812 grp_Info[numGrp].
MaxFiringRate = EXCITATORY_NEURON_MAX_FIRING_RATE;
814 grp_Info2[numGrp].ConfigId = configId;
815 grp_Info2[numGrp].Name = _name;
816 grp_Info[numGrp].isSpikeGenerator =
false;
817 grp_Info[numGrp].MaxDelay = 1;
819 grp_Info2[numGrp].IzhGen = NULL;
820 grp_Info2[numGrp].Izh_a = -1;
822 std::stringstream outStr;
826 grp_Info2[numGrp].Name = _name;
828 grp_Info2[numGrp].Name = _name +
"_" + outStr.str();
830 finishedPoissonGroup =
true;
840 if (configId == ALL) {
841 for(
int c=0; c < numConfig; c++)
843 return (numGrp-numConfig);
845 grp_Info[numGrp].SizeN = size_n;
846 grp_Info[numGrp].Type = type | POISSON_NEURON;
847 grp_Info[numGrp].WithConductances =
false;
848 grp_Info[numGrp].WithSTP =
false;
849 grp_Info[numGrp].WithSTDP =
false;
850 grp_Info[numGrp].WithHomeostasis =
false;
851 grp_Info[numGrp].isSpikeGenerator =
true;
852 grp_Info2[numGrp].ConfigId = configId;
853 grp_Info2[numGrp].Name = _name;
855 std::stringstream outStr ;
859 grp_Info2[numGrp].Name = _name +
"_" + outStr.str();
868 int CpuSNN::getGroupId(
int groupId,
int configId)
870 carlsim_assert(configId < numConfig);
871 int cGrpId = (groupId+configId);
872 carlsim_assert(cGrpId < numGrp);
877 int CpuSNN::getNextGroupId(
int groupId) {
878 return (groupId+numConfig);
886 connectId = getConnectionId (connectId, configId);
888 carlsim_assert(connectId >= 0); carlsim_assert(connectId < numConnections);
892 if (nextConn->connId == connectId) {
893 nextConn->newUpdates =
true;
896 nextConn = nextConn->next;
899 fprintf(stderr,
"Total Connections = %d\n", numConnections);
900 fprintf(stderr,
"ConnectId (%d) cannot be recognized\n", connectId);
904 int CpuSNN::getConnectionId(
int connId,
int configId)
906 if(configId >= numConfig) {
907 fprintf(stderr,
"getConnectionId(int, int): Assertion `configId(%d) < numConfig(%d)' failed\n", configId, numConfig);
910 connId = connId+configId;
911 if (connId >= numConnections) {
912 fprintf(stderr,
"getConnectionId(int, int): Assertion `connId(%d) < numConnections(%d)' failed\n", connId, numConnections);
923 void CpuSNN::setNeuronParameters(
int groupId,
float _a,
float a_sd,
float _b,
float b_sd,
float _c,
float c_sd,
float _d,
float d_sd,
int configId)
925 if (configId == ALL) {
926 for(
int c=0; c < numConfig; c++)
929 int cGrpId = getGroupId(groupId, configId);
930 grp_Info2[cGrpId].Izh_a = _a;
931 grp_Info2[cGrpId].Izh_a_sd = a_sd;
932 grp_Info2[cGrpId].Izh_b = _b;
933 grp_Info2[cGrpId].Izh_b_sd = b_sd;
934 grp_Info2[cGrpId].Izh_c = _c;
935 grp_Info2[cGrpId].Izh_c_sd = c_sd;
936 grp_Info2[cGrpId].Izh_d = _d;
937 grp_Info2[cGrpId].Izh_d_sd = d_sd;
943 if (configId == ALL) {
944 for(
int c=0; c < numConfig; c++)
947 int cGrpId = getGroupId(groupId, configId);
949 grp_Info2[cGrpId].IzhGen = IzhGen;
953 void CpuSNN::setGroupInfo(
int grpId,
group_info_t info,
int configId)
955 if (configId == ALL) {
956 for(
int c=0; c < numConfig; c++)
957 setGroupInfo(grpId, info, c);
959 int cGrpId = getGroupId(grpId, configId);
960 grp_Info[cGrpId] = info;
964 group_info_t CpuSNN::getGroupInfo(
int grpId,
int configId)
966 int cGrpId = getGroupId(grpId, configId);
967 return grp_Info[cGrpId];
970 void CpuSNN::buildPoissonGroup(
int grpId)
972 carlsim_assert(grp_Info[grpId].StartN == -1);
973 grp_Info[grpId].StartN = allocatedN;
974 grp_Info[grpId].EndN = allocatedN + grp_Info[grpId].SizeN - 1;
976 fprintf(fpLog,
"Allocation for %d(%s), St=%d, End=%d\n",
977 grpId, grp_Info2[grpId].Name.c_str(), grp_Info[grpId].StartN, grp_Info[grpId].EndN);
980 allocatedN = allocatedN + grp_Info[grpId].SizeN;
981 carlsim_assert(allocatedN <= numN);
983 for(
int i=grp_Info[grpId].StartN; i <= grp_Info[grpId].EndN; i++) {
984 resetPoissonNeuron(i, grpId);
988 cumulativePost[i] = allocatedPost;
989 cumulativePre[i] = allocatedPre;
990 allocatedPost += grp_Info[grpId].numPostSynapses;
991 allocatedPre += grp_Info[grpId].numPreSynapses;
993 carlsim_assert(allocatedPost <= postSynCnt);
994 carlsim_assert(allocatedPre <= preSynCnt);
997 void CpuSNN::resetPoissonNeuron(
unsigned int nid,
int grpId)
999 carlsim_assert(nid < numN);
1000 lastSpikeTime[nid] = MAX_SIMULATION_TIME;
1001 avgFiring[nid] = 0.0;
1003 if(grp_Info[grpId].WithSTP) {
1004 for (
int j=0; j < STP_BUF_SIZE; j++) {
1005 int ind=STP_BUF_POS(nid,j);
1006 stpu[ind] = grp_Info[grpId].STP_U;
1012 void CpuSNN::resetNeuron(
unsigned int nid,
int grpId)
1014 carlsim_assert(nid < numNReg);
1015 if (grp_Info2[grpId].IzhGen == NULL) {
1016 if (grp_Info2[grpId].Izh_a == -1) {
1017 printf(
"setNeuronParameters must be called for group %s (%d)\n",grp_Info2[grpId].Name.c_str(),grpId);
1018 #ifdef USE_EXCEPTIONS
1019 std::ostringstream stringStream;
1020 stringStream <<
"setNeuronParameters must be called for group " << grp_Info2[grpId].Name.c_str() <<
"(" << grpId <<
")\n";
1021 throw std::runtime_error(stringStream.str().c_str());
1027 Izh_a[nid] = grp_Info2[grpId].Izh_a + grp_Info2[grpId].Izh_a_sd*(float)getRandClosed();
1028 Izh_b[nid] = grp_Info2[grpId].Izh_b + grp_Info2[grpId].Izh_b_sd*(float)getRandClosed();
1029 Izh_c[nid] = grp_Info2[grpId].Izh_c + grp_Info2[grpId].Izh_c_sd*(float)getRandClosed();
1030 Izh_d[nid] = grp_Info2[grpId].Izh_d + grp_Info2[grpId].Izh_d_sd*(float)getRandClosed();
1032 grp_Info2[grpId].IzhGen->set(
this, grpId, nid, Izh_a[nid], Izh_b[nid], Izh_c[nid], Izh_d[nid]);
1035 voltage[nid] = Izh_c[nid];
1036 recovery[nid] = 0.2f*voltage[nid];
1041 baseFiring[nid] = grp_Info2[grpId].baseFiring + grp_Info2[grpId].baseFiringSD*-log(drand48());
1044 baseFiring[nid] = grp_Info2[grpId].baseFiring - grp_Info2[grpId].baseFiringSD*-log(drand48());
1045 if(baseFiring[nid] < 0.1) baseFiring[nid] = 0.1;
1048 if( grp_Info2[grpId].baseFiring != 0.0) {
1049 avgFiring[nid] = baseFiring[nid];
1052 baseFiring[nid] = 0.0;
1056 lastSpikeTime[nid] = MAX_SIMULATION_TIME;
1058 if(grp_Info[grpId].WithSTP) {
1059 for (
int j=0; j < STP_BUF_SIZE; j++) {
1060 int ind=STP_BUF_POS(nid,j);
1061 stpu[ind] = grp_Info[grpId].STP_U;
1067 void CpuSNN::buildGroup(
int grpId)
1069 carlsim_assert(grp_Info[grpId].StartN == -1);
1070 grp_Info[grpId].StartN = allocatedN;
1071 grp_Info[grpId].EndN = allocatedN + grp_Info[grpId].SizeN - 1;
1073 fprintf(fpLog,
"Allocation for %d(%s), St=%d, End=%d\n",
1074 grpId, grp_Info2[grpId].Name.c_str(), grp_Info[grpId].StartN, grp_Info[grpId].EndN);
1078 allocatedN = allocatedN + grp_Info[grpId].SizeN;
1079 carlsim_assert(allocatedN <= numN);
1081 for(
int i=grp_Info[grpId].StartN; i <= grp_Info[grpId].EndN; i++) {
1082 resetNeuron(i, grpId);
1083 Npre_plastic[i] = 0;
1086 cumulativePost[i] = allocatedPost;
1087 cumulativePre[i] = allocatedPre;
1088 allocatedPost += grp_Info[grpId].numPostSynapses;
1089 allocatedPre += grp_Info[grpId].numPreSynapses;
1092 carlsim_assert(allocatedPost <= postSynCnt);
1093 carlsim_assert(allocatedPre <= preSynCnt);
1097 inline void CpuSNN::setConnection(
int srcGrp,
int destGrp,
unsigned int src,
unsigned int dest,
float synWt,
float maxWt, uint8_t dVal,
int connProp)
1099 carlsim_assert(dest<=CONN_SYN_NEURON_MASK);
1100 carlsim_assert((dVal >=1) && (dVal <= D));
1103 if(Npost[src] >= grp_Info[srcGrp].numPostSynapses) {
1104 fprintf(stderr,
"setConnection(%d (Grp=%s), %d (Grp=%s), %f, %d)\n", src, grp_Info2[srcGrp].Name.c_str(), dest, grp_Info2[destGrp].Name.c_str(), synWt, dVal);
1105 fprintf(stderr,
"(Npost[%d] = %d ) >= (numPostSynapses = %d) value given for the network very less\n", src, Npost[src], grp_Info[srcGrp].numPostSynapses);
1106 fprintf(stderr,
"Large number of postsynaptic connections is established\n");
1107 fprintf(stderr,
"Increase the numPostSynapses value for the Group = %s \n", grp_Info2[srcGrp].Name.c_str());
1111 if(Npre[dest] >= grp_Info[destGrp].numPreSynapses) {
1112 fprintf(stderr,
"setConnection(%d (Grp=%s), %d (Grp=%s), %f, %d)\n", src, grp_Info2[srcGrp].Name.c_str(), dest, grp_Info2[destGrp].Name.c_str(), synWt, dVal);
1113 fprintf(stderr,
"(Npre[%d] = %d) >= (numPreSynapses = %d) value given for the network very less\n", dest, Npre[dest], grp_Info[destGrp].numPreSynapses);
1114 fprintf(stderr,
"Large number of presynaptic connections established\n");
1115 fprintf(stderr,
"Increase the numPostSynapses for the Grp = %s value \n", grp_Info2[destGrp].Name.c_str());
1121 carlsim_assert(Npost[src] >= 0);
1122 carlsim_assert(Npre[dest] >= 0);
1123 carlsim_assert((src*numPostSynapses+p)/numN < numPostSynapses);
1125 unsigned int post_pos = cumulativePost[src] + Npost[src];
1126 unsigned int pre_pos = cumulativePre[dest] + Npre[dest];
1128 carlsim_assert(post_pos < postSynCnt);
1129 carlsim_assert(pre_pos < preSynCnt);
1131 postSynapticIds[post_pos] = SET_CONN_ID(dest, Npre[dest], destGrp);
1132 tmp_SynapticDelay[post_pos] = dVal;
1134 preSynapticIds[pre_pos] = SET_CONN_ID(src, Npost[src], srcGrp);
1135 wt[pre_pos] = synWt;
1136 maxSynWt[pre_pos] = maxWt;
1138 bool synWtType = GET_FIXED_PLASTIC(connProp);
1140 if (synWtType == SYN_PLASTIC) {
1141 sim_with_fixedwts =
false;
1142 Npre_plastic[dest]++;
1144 if (grp_Info[destGrp].WithHomeostasis && grp_Info[destGrp].homeoId ==-1)
1145 grp_Info[destGrp].homeoId = dest;
1151 grp_Info2[srcGrp].numPostConn++;
1152 grp_Info2[destGrp].numPreConn++;
1154 if (Npost[src] > grp_Info2[srcGrp].maxPostConn)
1155 grp_Info2[srcGrp].maxPostConn = Npost[src];
1157 if (Npre[dest] > grp_Info2[destGrp].maxPreConn)
1158 grp_Info2[destGrp].maxPreConn = Npre[src];
1168 int pre_nid, pos_ij;
1169 int numPre, numPost;
1172 printf(
"Invalid configId. You can not pass the ALL (ALL=-1) argument.\n");
1173 carlsim_assert(
false);
1176 int cGrpIdPre = getGroupId(grpPreId, configId);
1177 int cGrpIdPost = getGroupId(grpPostId, configId);
1179 numPre = grp_Info[cGrpIdPre].SizeN;
1180 numPost = grp_Info[cGrpIdPost].SizeN;
1186 for (
int i=grp_Info[cGrpIdPost].StartN; i<=grp_Info[cGrpIdPost].EndN; i++) {
1188 pos_ij = cumulativePre[i];
1190 for(
int j=0; j<Npre[i]; pos_ij++,j++) {
1191 preId = &preSynapticIds[pos_ij];
1192 pre_nid = GET_CONN_NEURON_ID((*preId));
1193 if (pre_nid<grp_Info[cGrpIdPre].StartN || pre_nid>grp_Info[cGrpIdPre].EndN)
1199 weights =
new float[matrixSize];
1204 for (
int i=grp_Info[cGrpIdPost].StartN; i<=grp_Info[cGrpIdPost].EndN; i++) {
1206 pos_ij = cumulativePre[i];
1208 if(currentMode==GPU_MODE){
1209 copyWeightsGPU(i,cGrpIdPre);
1212 for(
int j=0; j<Npre[i]; pos_ij++,j++) {
1216 preId = &preSynapticIds[pos_ij];
1217 pre_nid = GET_CONN_NEURON_ID((*preId));
1218 if (pre_nid<grp_Info[cGrpIdPre].StartN || pre_nid>grp_Info[cGrpIdPre].EndN)
1221 weights[curr] = wt[pos_ij];
1232 int numPre, numPost;
1233 fid = fopen(fname.c_str(),
"wb");
1234 carlsim_assert(fid != NULL);
1236 if(!doneReorganization){
1237 printf(
"Simulation has not been run yet, cannot output weights.\n");
1238 carlsim_assert(
false);
1242 int pre_nid, pos_ij;
1245 printf(
"Invalid configId. You can not pass the ALL (ALL=-1) argument.\n");
1246 carlsim_assert(
false);
1249 int cGrpIdPre = getGroupId(grpPreId, configId);
1250 int cGrpIdPost = getGroupId(grpPostId, configId);
1253 numPre = grp_Info[cGrpIdPre].SizeN;
1254 numPost = grp_Info[cGrpIdPost].SizeN;
1260 for (
int i=grp_Info[cGrpIdPost].StartN; i<=grp_Info[cGrpIdPost].EndN; i++) {
1262 pos_ij = cumulativePre[i];
1264 for(
int j=0; j<Npre[i]; pos_ij++,j++) {
1265 preId = &preSynapticIds[pos_ij];
1266 pre_nid = GET_CONN_NEURON_ID((*preId));
1267 if (pre_nid<grp_Info[cGrpIdPre].StartN || pre_nid>grp_Info[cGrpIdPre].EndN)
1273 weights =
new float[matrixSize];
1277 for (
int i=grp_Info[cGrpIdPost].StartN; i<=grp_Info[cGrpIdPost].EndN; i++) {
1279 pos_ij = cumulativePre[i];
1281 if(currentMode==GPU_MODE){
1282 copyWeightsGPU(i,cGrpIdPre);
1285 for(
int j=0; j<Npre[i]; pos_ij++,j++) {
1286 preId = &preSynapticIds[pos_ij];
1287 pre_nid = GET_CONN_NEURON_ID((*preId));
1288 if (pre_nid<grp_Info[cGrpIdPre].StartN || pre_nid>grp_Info[cGrpIdPre].EndN)
1290 weights[curr] = wt[pos_ij];
1295 fwrite(weights,
sizeof(
float),matrixSize,fid);
1306 float CpuSNN::getWeights(
int connProp,
float initWt,
float maxWt,
unsigned int nid,
int grpId)
1309 bool setRandomWeights = GET_INITWTS_RANDOM(connProp);
1310 bool setRampDownWeights = GET_INITWTS_RAMPDOWN(connProp);
1311 bool setRampUpWeights = GET_INITWTS_RAMPUP(connProp);
1313 if ( setRandomWeights )
1314 actWts=initWt*drand48();
1315 else if (setRampUpWeights)
1316 actWts=(initWt+((nid-grp_Info[grpId].StartN)*(maxWt-initWt)/grp_Info[grpId].SizeN));
1317 else if (setRampDownWeights)
1318 actWts=(maxWt-((nid-grp_Info[grpId].StartN)*(maxWt-initWt)/grp_Info[grpId].SizeN));
1328 int grpSrc = info->grpSrc;
1329 int grpDest = info->grpDest;
1330 for(
int pre_nid=grp_Info[grpSrc].StartN; pre_nid<=grp_Info[grpSrc].EndN; pre_nid++) {
1331 for(
int post_nid=grp_Info[grpDest].StartN; post_nid<=grp_Info[grpDest].EndN; post_nid++) {
1332 if (getRand() < info->p) {
1333 uint8_t dVal = info->minDelay + (int)(0.5+(getRandClosed()*(info->maxDelay-info->minDelay)));
1334 carlsim_assert((dVal >= info->minDelay) && (dVal <= info->maxDelay));
1335 float synWt = getWeights(info->connProp, info->initWt, info->maxWt, pre_nid, grpSrc);
1336 setConnection(grpSrc, grpDest, pre_nid, post_nid, synWt, info->maxWt, dVal, info->connProp);
1337 info->numberOfConnections++;
1342 grp_Info2[grpSrc].sumPostConn += info->numberOfConnections;
1343 grp_Info2[grpDest].sumPreConn += info->numberOfConnections;
1348 int grpSrc = info->grpSrc;
1349 int grpDest = info->grpDest;
1350 carlsim_assert( grp_Info[grpDest].SizeN == grp_Info[grpSrc].SizeN );
1353 for(
int nid=grp_Info[grpSrc].StartN,j=grp_Info[grpDest].StartN; nid<=grp_Info[grpSrc].EndN; nid++, j++) {
1354 uint8_t dVal = info->minDelay + (int)(0.5+(getRandClosed()*(info->maxDelay-info->minDelay)));
1355 carlsim_assert((dVal >= info->minDelay) && (dVal <= info->maxDelay));
1356 float synWt = getWeights(info->connProp, info->initWt, info->maxWt, nid, grpSrc);
1357 setConnection(grpSrc, grpDest, nid, j, synWt, info->maxWt, dVal, info->connProp);
1359 info->numberOfConnections++;
1367 grp_Info2[grpSrc].sumPostConn += info->numberOfConnections;
1368 grp_Info2[grpDest].sumPreConn += info->numberOfConnections;
1376 int grpSrc = info->grpSrc;
1377 int grpDest = info->grpDest;
1379 for(
int nid=grp_Info[grpSrc].StartN; nid<=grp_Info[grpSrc].EndN; nid++) {
1380 for(
int nid2=grp_Info[grpDest].StartN; nid2 <= grp_Info[grpDest].EndN; nid2++) {
1381 int srcId = nid - grp_Info[grpSrc].StartN;
1382 int destId = nid2 - grp_Info[grpDest].StartN;
1383 float weight, maxWt, delay;
1386 info->conn->
connect(
this, grpSrc, srcId, grpDest, destId, weight, maxWt, delay, connected);
1388 if (GET_FIXED_PLASTIC(info->connProp) == SYN_FIXED) maxWt = weight;
1390 carlsim_assert(delay>=1);
1391 carlsim_assert(delay<=MAX_SynapticDelay);
1392 carlsim_assert(weight<=maxWt);
1394 setConnection(grpSrc, grpDest, nid, nid2, weight, maxWt, delay, info->connProp);
1395 info->numberOfConnections++;
1396 if(delay > info->maxDelay)
1397 info->maxDelay = delay;
1407 grp_Info2[grpSrc].sumPostConn += info->numberOfConnections;
1408 grp_Info2[grpDest].sumPreConn += info->numberOfConnections;
1414 int grpSrc = info->grpSrc;
1415 int grpDest = info->grpDest;
1416 bool noDirect = (info->type == CONN_FULL_NO_DIRECT);
1418 for(
int nid=grp_Info[grpSrc].StartN; nid<=grp_Info[grpSrc].EndN; nid++) {
1419 for(
int j=grp_Info[grpDest].StartN; j <= grp_Info[grpDest].EndN; j++) {
1420 if((noDirect) && (nid - grp_Info[grpSrc].StartN) == (j - grp_Info[grpDest].StartN))
1422 uint8_t dVal = info->minDelay + (int)(0.5+(getRandClosed()*(info->maxDelay-info->minDelay)));
1423 carlsim_assert((dVal >= info->minDelay) && (dVal <= info->maxDelay));
1424 float synWt = getWeights(info->connProp, info->initWt, info->maxWt, nid, grpSrc);
1426 setConnection(grpSrc, grpDest, nid, j, synWt, info->maxWt, dVal, info->connProp);
1427 info->numberOfConnections++;
1439 grp_Info2[grpSrc].sumPostConn += info->numberOfConnections;
1440 grp_Info2[grpDest].sumPreConn += info->numberOfConnections;
1446 for (
int i=0;i<mat->count;i++) {
1447 int nIDpre = mat->preIds[i];
1448 int nIDpost = mat->postIds[i];
1449 float weight = mat->weights[i];
1450 float maxWeight = mat->maxWeights[i];
1452 int gIDpre = findGrpId(nIDpre);
1453 int gIDpost = findGrpId(nIDpost);
1455 setConnection(gIDpre, gIDpost, nIDpre, nIDpost, weight, maxWeight, delay, connProp);
1457 grp_Info2[gIDpre].sumPostConn++;
1458 grp_Info2[gIDpost].sumPreConn++;
1460 if (delay > grp_Info[gIDpre].MaxDelay) grp_Info[gIDpre].MaxDelay = delay;
1466 string fname(networkName+
".dot");
1467 fpDotty = fopen(fname.c_str(),
"w");
1471 \t\tnode [style=filled];\n\
1472 \t\tcolor=blue;\n");
1474 for(
int g=0; g < numGrp; g++) {
1476 char stype = grp_Info[g].Type;
1477 carlsim_assert(grp_Info2[g].numPostConn == grp_Info2[g].sumPostConn);
1478 carlsim_assert(grp_Info2[g].numPreConn == grp_Info2[g].sumPreConn);
1483 fprintf (fpDotty,
"\t\tg%d [%s label=\"id=%d:%s \\n numN=%d avgPost=%3.2f avgPre=%3.2f \\n maxPost=%d maxPre=%d\"];\n", g,
1484 (stype&POISSON_NEURON) ?
"shape = box, ":
" ", g, grp_Info2[g].Name.c_str(),
1485 grp_Info[g].SizeN, grp_Info2[g].numPostConn*1.0/grp_Info[g].SizeN,
1486 grp_Info2[g].numPreConn*1.0/grp_Info[g].SizeN, grp_Info2[g].maxPostConn, grp_Info2[g].maxPreConn);
1509 int grpSrc = info->grpSrc;
1510 int grpDest = info->grpDest;
1512 float avgPostM = info->numberOfConnections/grp_Info[grpSrc].SizeN;
1513 float avgPreM = info->numberOfConnections/grp_Info[grpDest].SizeN;
1515 fprintf(fpDotty,
"\t\tg%d -> g%d [style=%s, arrowType=%s, label=\"avgPost=%3.2f, avgPre=%3.2f, wt=%3.3f, maxD=%d \"]\n",
1516 grpSrc, grpDest, (info->initWt > 0)?
"bold":
"dotted", (info->initWt > 0)?
"normal":
"dot", avgPostM, avgPreM, info->maxWt, info->maxDelay);
1524 fprintf(fpDotty,
"\n}\n");
1530 int dbg = sprintf(cmd,
"kgraphviewer %s.dot", networkName.c_str());
1534 retVal = system(cmd);
1535 carlsim_assert(retVal >= 0);
1538 fprintf(stdout,
"\trun cmd to view graph: %s\n", cmd);
1546 for(
int c=0; c < numConfig; c++, grpId1++, grpId2++) {
1548 carlsim_assert(grpId1 < numGrp);
1549 carlsim_assert(grpId2 < numGrp);
1552 maxM = grp_Info[grpId2].SizeN;
1555 maxPreM = grp_Info[grpId1].SizeN;
1557 if (maxM > MAX_numPostSynapses) {
1558 printf(
"Connection from %s (%d) to %s (%d) exceeded the maximum number of output synapses (%d), has %d.\n",grp_Info2[grpId1].Name.c_str(),grpId1,grp_Info2[grpId2].Name.c_str(), grpId2, MAX_numPostSynapses,maxM);
1559 carlsim_assert(maxM <= MAX_numPostSynapses);
1562 if (maxPreM > MAX_numPreSynapses) {
1563 printf(
"Connection from %s (%d) to %s (%d) exceeded the maximum number of input synapses (%d), has %d.\n",grp_Info2[grpId1].Name.c_str(), grpId1,grp_Info2[grpId2].Name.c_str(), grpId2,MAX_numPreSynapses,maxPreM);
1564 carlsim_assert(maxPreM <= MAX_numPreSynapses);
1569 newInfo->grpSrc = grpId1;
1570 newInfo->grpDest = grpId2;
1571 newInfo->initWt = 1;
1573 newInfo->maxDelay = 1;
1574 newInfo->minDelay = 1;
1575 newInfo->connProp = SET_CONN_PRESENT(1) | SET_FIXED_PLASTIC(synWtType);
1576 newInfo->type = CONN_USER_DEFINED;
1577 newInfo->numPostSynapses = maxM;
1578 newInfo->numPreSynapses = maxPreM;
1579 newInfo->conn = conn;
1581 newInfo->next = connectBegin;
1582 connectBegin = newInfo;
1585 grp_Info[grpId1].numPostSynapses += newInfo->numPostSynapses;
1586 grp_Info[grpId2].numPreSynapses += newInfo->numPreSynapses;
1588 if (showLogMode >= 1)
1589 printf(
"grp_Info[%d, %s].numPostSynapses = %d, grp_Info[%d, %s].numPreSynapses = %d\n",grpId1,grp_Info2[grpId1].Name.c_str(),grp_Info[grpId1].numPostSynapses,grpId2,grp_Info2[grpId2].Name.c_str(),grp_Info[grpId2].numPreSynapses);
1591 newInfo->connId = numConnections++;
1593 retId = newInfo->connId;
1595 carlsim_assert(retId != -1);
1600 int CpuSNN::connect(
int grpId1,
int grpId2,
const string& _type,
float initWt,
float maxWt,
float p, uint8_t minDelay, uint8_t maxDelay,
bool synWtType,
const string& wtType)
1603 for(
int c=0; c < numConfig; c++, grpId1++, grpId2++) {
1604 carlsim_assert(grpId1 < numGrp);
1605 carlsim_assert(grpId2 < numGrp);
1606 carlsim_assert(minDelay <= maxDelay);
1608 bool useRandWts = (wtType.find(
"random") != string::npos);
1609 bool useRampDownWts = (wtType.find(
"ramp-down") != string::npos);
1610 bool useRampUpWts = (wtType.find(
"ramp-up") != string::npos);
1611 uint32_t connProp = SET_INITWTS_RANDOM(useRandWts)
1612 | SET_CONN_PRESENT(1)
1613 | SET_FIXED_PLASTIC(synWtType)
1614 | SET_INITWTS_RAMPUP(useRampUpWts)
1615 | SET_INITWTS_RAMPDOWN(useRampDownWts);
1618 newInfo->grpSrc = grpId1;
1619 newInfo->grpDest = grpId2;
1620 newInfo->initWt = initWt;
1621 newInfo->maxWt = maxWt;
1622 newInfo->maxDelay = maxDelay;
1623 newInfo->minDelay = minDelay;
1624 newInfo->connProp = connProp;
1626 newInfo->type = CONN_UNKNOWN;
1627 newInfo->numPostSynapses = 1;
1629 newInfo->next = connectBegin;
1630 connectBegin = newInfo;
1633 if ( _type.find(
"random") != string::npos) {
1634 newInfo->type = CONN_RANDOM;
1635 newInfo->numPostSynapses = MIN(grp_Info[grpId2].SizeN,((
int) (p*grp_Info[grpId2].SizeN +5*sqrt(p*(1-p)*grp_Info[grpId2].SizeN)+0.5)));
1636 newInfo->numPreSynapses = MIN(grp_Info[grpId1].SizeN,((
int) (p*grp_Info[grpId1].SizeN +5*sqrt(p*(1-p)*grp_Info[grpId1].SizeN)+0.5)));
1640 else if ( _type.find(
"full") != string::npos) {
1641 newInfo->type = CONN_FULL;
1642 newInfo->numPostSynapses = grp_Info[grpId2].SizeN;
1643 newInfo->numPreSynapses = grp_Info[grpId1].SizeN;
1645 else if ( _type.find(
"full-no-direct") != string::npos) {
1646 newInfo->type = CONN_FULL_NO_DIRECT;
1647 newInfo->numPostSynapses = grp_Info[grpId2].SizeN-1;
1648 newInfo->numPreSynapses = grp_Info[grpId1].SizeN-1;
1650 else if ( _type.find(
"one-to-one") != string::npos) {
1651 newInfo->type = CONN_ONE_TO_ONE;
1652 newInfo->numPostSynapses = 1;
1653 newInfo->numPreSynapses = 1;
1656 exitSimulation(-1,
"Invalid connection type (should be 'random', 'full', 'one-to-one', or 'full-no-direct')\n");
1659 if (newInfo->numPostSynapses > MAX_numPostSynapses) {
1660 printf(
"Connection exceeded the maximum number of output synapses (%d), has %d.\n",MAX_numPostSynapses,newInfo->numPostSynapses);
1661 carlsim_assert(newInfo->numPostSynapses <= MAX_numPostSynapses);
1664 if (newInfo->numPreSynapses > MAX_numPreSynapses) {
1665 printf(
"Connection exceeded the maximum number of input synapses (%d), has %d.\n",MAX_numPreSynapses,newInfo->numPreSynapses);
1666 carlsim_assert(newInfo->numPreSynapses <= MAX_numPreSynapses);
1673 grp_Info[grpId1].numPostSynapses += newInfo->numPostSynapses;
1674 grp_Info[grpId2].numPreSynapses += newInfo->numPreSynapses;
1676 if (showLogMode >= 1)
1677 printf(
"grp_Info[%d, %s].numPostSynapses = %d, grp_Info[%d, %s].numPreSynapses = %d\n",grpId1,grp_Info2[grpId1].Name.c_str(),grp_Info[grpId1].numPostSynapses,grpId2,grp_Info2[grpId2].Name.c_str(),grp_Info[grpId2].numPreSynapses);
1679 newInfo->connId = numConnections++;
1681 retId = newInfo->connId;
1683 carlsim_assert(retId != -1);
1687 int CpuSNN::updateSpikeTables()
1695 grpSrc = newInfo->grpSrc;
1696 if (newInfo->maxDelay > curD)
1697 curD = newInfo->maxDelay;
1702 if (newInfo->maxDelay > grp_Info[grpSrc].MaxDelay)
1703 grp_Info[grpSrc].MaxDelay = newInfo->maxDelay;
1704 newInfo = newInfo->next;
1707 for(
int g=0; g < numGrp; g++) {
1708 if ( grp_Info[g].MaxDelay == 1)
1709 maxSpikesD1 += (grp_Info[g].SizeN*grp_Info[g].
MaxFiringRate);
1711 maxSpikesD2 += (grp_Info[g].SizeN*grp_Info[g].
MaxFiringRate);
1717 if ((maxSpikesD1+maxSpikesD2) < (numNExcReg+numNInhReg+numNPois)*UNKNOWN_NEURON_MAX_FIRING_RATE) {
1718 exitSimulation(1,
"Insufficient amount of buffer allocated...\n");
1724 firingTableD2 =
new unsigned int[maxSpikesD2];
1725 firingTableD1 =
new unsigned int[maxSpikesD1];
1726 cpuSnnSz.spikingInfoSize +=
sizeof(int)*((maxSpikesD2+maxSpikesD1) + 2*(1000+D+1));
1731 void CpuSNN::buildNetwork()
1734 int curN = 0, curD = 0, numPostSynapses = 0, numPreSynapses = 0;
1736 carlsim_assert(numConfig > 0);
1739 updateParameters(&curN, &numPostSynapses, &numPreSynapses, numConfig);
1741 curD = updateSpikeTables();
1743 carlsim_assert((curN > 0)&& (curN == numNExcReg + numNInhReg + numNPois));
1744 carlsim_assert(numPostSynapses > 0);
1745 carlsim_assert(numPreSynapses > 0);
1748 fprintf(stdout,
">>>>>>>>>>>>>> NUM_CONFIGURATIONS = %d <<<<<<<<<<<<<<<<<<\n", numConfig);
1749 fprintf(stdout,
"**********************************\n");
1750 fprintf(stdout,
"numN = %d, numPostSynapses = %d, numPreSynapses = %d, D = %d\n", curN, numPostSynapses, numPreSynapses, curD);
1751 fprintf(stdout,
"**********************************\n");
1753 fprintf(fpLog,
"**********************************\n");
1754 fprintf(fpLog,
"numN = %d, numPostSynapses = %d, numPreSynapses = %d, D = %d\n", curN, numPostSynapses, numPreSynapses, curD);
1755 fprintf(fpLog,
"**********************************\n");
1757 carlsim_assert(curD != 0); carlsim_assert(numPostSynapses != 0); carlsim_assert(curN != 0); carlsim_assert(numPreSynapses != 0);
1759 if (showLogMode >= 1)
1760 for (
int g=0;g<numGrp;g++)
1761 printf(
"grp_Info[%d, %s].numPostSynapses = %d, grp_Info[%d, %s].numPreSynapses = %d\n",g,grp_Info2[g].Name.c_str(),grp_Info[g].numPostSynapses,g,grp_Info2[g].Name.c_str(),grp_Info[g].numPreSynapses);
1763 if (numPostSynapses > MAX_numPostSynapses) {
1764 for (
int g=0;g<numGrp;g++)
1765 if (grp_Info[g].numPostSynapses>MAX_numPostSynapses) printf(
"Grp: %s(%d) has too many output synapses (%d), max %d.\n",grp_Info2[g].Name.c_str(),g,grp_Info[g].numPostSynapses,MAX_numPostSynapses);
1766 carlsim_assert(numPostSynapses <= MAX_numPostSynapses);
1768 if (numPreSynapses > MAX_numPreSynapses) {
1769 for (
int g=0;g<numGrp;g++)
1770 if (grp_Info[g].numPreSynapses>MAX_numPreSynapses) printf(
"Grp: %s(%d) has too many input synapses (%d), max %d.\n",grp_Info2[g].Name.c_str(),g,grp_Info[g].numPreSynapses,MAX_numPreSynapses);
1771 carlsim_assert(numPreSynapses <= MAX_numPreSynapses);
1773 carlsim_assert(curD <= MAX_SynapticDelay); carlsim_assert(curN <= 1000000);
1776 CpuSNNInit(curN, numPostSynapses, numPreSynapses, curD);
1782 int allocatedGrp = 0;
1783 for(
int order=0; order < 4; order++) {
1784 for(
int configId=0; configId < numConfig; configId++) {
1785 for(
int g=0; g < numGrp; g++) {
1786 if (grp_Info2[g].ConfigId == configId) {
1787 if (IS_EXCITATORY_TYPE(grp_Info[g].Type) && (grp_Info[g].Type&POISSON_NEURON) && order==3) {
1788 buildPoissonGroup(g);
1790 }
else if (IS_INHIBITORY_TYPE(grp_Info[g].Type) && (grp_Info[g].Type&POISSON_NEURON) && order==2) {
1791 buildPoissonGroup(g);
1793 }
else if (IS_EXCITATORY_TYPE(grp_Info[g].Type) && !(grp_Info[g].Type&POISSON_NEURON) && order==0) {
1796 }
else if (IS_INHIBITORY_TYPE(grp_Info[g].Type) && !(grp_Info[g].Type&POISSON_NEURON) && order==1) {
1804 carlsim_assert(allocatedGrp == numGrp);
1806 if (readNetworkFID != NULL) {
1808 #if READNETWORK_ADD_SYNAPSES_FROM_FILE
1810 carlsim_assert(readNetwork_internal(
true) >= 0);
1813 carlsim_assert(readNetwork_internal(
false) >= 0);
1815 carlsim_assert(readNetwork_internal() >= 0);
1817 connectFromMatrix(tmp_SynapseMatrix_plastic, SET_FIXED_PLASTIC(SYN_PLASTIC));
1819 connectFromMatrix(tmp_SynapseMatrix_fixed, SET_FIXED_PLASTIC(SYN_FIXED));
1828 for(
int con=0; con < 2; con++) {
1829 newInfo = connectBegin;
1831 bool synWtType = GET_FIXED_PLASTIC(newInfo->connProp);
1832 if (synWtType == SYN_PLASTIC) {
1833 grp_Info[newInfo->grpDest].FixedInputWts =
false;
1836 if( ((con == 0) && (synWtType == SYN_PLASTIC)) ||
1837 ((con == 1) && (synWtType == SYN_FIXED)))
1839 switch(newInfo->type)
1842 connectRandom(newInfo);
1845 connectFull(newInfo);
1847 case CONN_FULL_NO_DIRECT:
1848 connectFull(newInfo);
1850 case CONN_ONE_TO_ONE:
1851 connectOneToOne(newInfo);
1853 case CONN_USER_DEFINED:
1854 connectUserDefined(newInfo);
1857 printf(
"Invalid connection type( should be 'random', or 'full')\n");
1860 float avgPostM = newInfo->numberOfConnections/grp_Info[newInfo->grpSrc].SizeN;
1861 float avgPreM = newInfo->numberOfConnections/grp_Info[newInfo->grpDest].SizeN;
1863 fprintf(stderr,
"connect(%s(%d) => %s(%d), iWt=%f, mWt=%f, numPostSynapses=%d, numPreSynapses=%d, minD=%d, maxD=%d, %s)\n",
1864 grp_Info2[newInfo->grpSrc].Name.c_str(), newInfo->grpSrc, grp_Info2[newInfo->grpDest].Name.c_str(),
1865 newInfo->grpDest, newInfo->initWt, newInfo->maxWt, (int)avgPostM, (
int)avgPreM,
1866 newInfo->minDelay, newInfo->maxDelay, synWtType?
"Plastic":
"Fixed");
1868 newInfo = newInfo->next;
1874 int CpuSNN::findGrpId(
int nid)
1876 for(
int g=0; g < numGrp; g++) {
1878 if(nid >=grp_Info[g].StartN && (nid <=grp_Info[g].EndN)) {
1882 fprintf(stderr,
"findGrp(): cannot find the group for neuron %d\n", nid);
1888 unsigned int version = 1;
1889 fwrite(&version,
sizeof(
int),1,fid);
1890 fwrite(&numGrp,
sizeof(
int),1,fid);
1893 for (
int g=0;g<numGrp;g++) {
1894 fwrite(&grp_Info[g].StartN,
sizeof(
int),1,fid);
1895 fwrite(&grp_Info[g].EndN,
sizeof(
int),1,fid);
1897 strncpy(name,grp_Info2[g].Name.c_str(),100);
1898 fwrite(name,1,100,fid);
1902 fwrite(&nrCells,
sizeof(
int),1,fid);
1904 for (
unsigned int i=0;i<nrCells;i++) {
1905 unsigned int offset = cumulativePost[i];
1907 unsigned int count = 0;
1908 for (
int t=0;t<D;t++) {
1911 for(
int idx_d = dPar.delay_index_start; idx_d < (dPar.delay_index_start + dPar.delay_length); idx_d = idx_d+1)
1915 fwrite(&count,
sizeof(
int),1,fid);
1917 for (
int t=0;t<D;t++) {
1920 for(
int idx_d = dPar.delay_index_start; idx_d < (dPar.delay_index_start + dPar.delay_length); idx_d = idx_d+1) {
1923 post_info_t post_info = postSynapticIds[offset + idx_d];
1927 unsigned int p_i = GET_CONN_NEURON_ID(post_info);
1928 carlsim_assert(p_i<numN);
1931 unsigned int s_i = GET_CONN_SYN_ID(post_info);
1933 carlsim_assert(s_i<(Npre[p_i]));
1936 unsigned int pos_i = cumulativePre[p_i] + s_i;
1938 uint8_t delay = t+1;
1939 uint8_t plastic = s_i < Npre_plastic[p_i];
1941 fwrite(&i,
sizeof(
int),1,fid);
1942 fwrite(&p_i,
sizeof(
int),1,fid);
1943 fwrite(&(wt[pos_i]),
sizeof(
float),1,fid);
1944 fwrite(&(maxSynWt[pos_i]),
sizeof(
float),1,fid);
1945 fwrite(&delay,
sizeof(uint8_t),1,fid);
1946 fwrite(&plastic,
sizeof(uint8_t),1,fid);
1954 readNetworkFID = fid;
1958 #if READNETWORK_ADD_SYNAPSES_FROM_FILE
1959 int CpuSNN::readNetwork_internal(
bool onlyPlastic)
1961 int CpuSNN::readNetwork_internal()
1964 long file_position = ftell(readNetworkFID);
1965 unsigned int version;
1967 if (!fread(&version,
sizeof(
int),1,readNetworkFID))
return -11;
1969 if (version > 1)
return -10;
1972 if (!fread(&_numGrp,
sizeof(
int),1,readNetworkFID))
return -11;
1974 if (numGrp != _numGrp)
return -1;
1979 for (
int g=0;g<numGrp;g++) {
1980 if (!fread(&startN,
sizeof(
int),1,readNetworkFID))
return -11;
1981 if (!fread(&endN,
sizeof(
int),1,readNetworkFID))
return -11;
1983 if (startN != grp_Info[g].StartN)
return -2;
1984 if (endN != grp_Info[g].EndN)
return -3;
1986 if (!fread(name,1,100,readNetworkFID))
return -11;
1988 if (strcmp(name,grp_Info2[g].Name.c_str()) != 0)
return -4;
1992 if (!fread(&nrCells,
sizeof(
int),1,readNetworkFID))
return -11;
1994 if (nrCells != numN)
return -5;
1999 for (
unsigned int i=0;i<nrCells;i++) {
2000 unsigned int nrSynapses = 0;
2001 if (!fread(&nrSynapses,
sizeof(
int),1,readNetworkFID))
return -11;
2003 for (
int j=0;j<nrSynapses;j++) {
2004 unsigned int nIDpre;
2005 unsigned int nIDpost;
2006 float weight, maxWeight;
2010 if (!fread(&nIDpre,
sizeof(
int),1,readNetworkFID))
return -11;
2012 if (nIDpre != i)
return -6;
2014 if (!fread(&nIDpost,
sizeof(
int),1,readNetworkFID))
return -11;
2016 if (nIDpost >= nrCells)
return -7;
2018 if (!fread(&weight,
sizeof(
float),1,readNetworkFID))
return -11;
2020 int gIDpre = findGrpId(nIDpre);
2021 if (IS_INHIBITORY_TYPE(grp_Info[gIDpre].Type) && (weight>0) || !IS_INHIBITORY_TYPE(grp_Info[gIDpre].Type) && (weight<0))
return -8;
2023 if (!fread(&maxWeight,
sizeof(
float),1,readNetworkFID))
return -11;
2025 if (IS_INHIBITORY_TYPE(grp_Info[gIDpre].Type) && (maxWeight>=0) || !IS_INHIBITORY_TYPE(grp_Info[gIDpre].Type) && (maxWeight<=0))
return -8;
2027 if (!fread(&delay,
sizeof(uint8_t),1,readNetworkFID))
return -11;
2029 if (delay > MAX_SynapticDelay)
return -9;
2031 if (!fread(&plastic,
sizeof(uint8_t),1,readNetworkFID))
return -11;
2033 #if READNETWORK_ADD_SYNAPSES_FROM_FILE
2034 if ((plastic && onlyPlastic) || (!plastic && !onlyPlastic)) {
2035 int gIDpost = findGrpId(nIDpost);
2036 int connProp = SET_FIXED_PLASTIC(plastic?SYN_PLASTIC:SYN_FIXED);
2038 setConnection(gIDpre, gIDpost, nIDpre, nIDpost, weight, maxWeight, delay, connProp);
2040 grp_Info2[gIDpre].sumPostConn++;
2041 grp_Info2[gIDpost].sumPreConn++;
2043 if (delay > grp_Info[gIDpre].MaxDelay) grp_Info[gIDpre].MaxDelay = delay;
2048 tmp_SynapseMatrix_plastic->add(nIDpre,nIDpost,weight,maxWeight,delay,plastic);
2050 tmp_SynapseMatrix_fixed->add(nIDpre,nIDpost,weight,maxWeight,delay,plastic);
2055 #if READNETWORK_ADD_SYNAPSES_FROM_FILE
2056 fseek(readNetworkFID,file_position,SEEK_SET);
2064 float* CpuSNN::getWeights(
int gIDpre,
int gIDpost,
int& Npre,
int& Npost,
float* weights) {
2065 Npre = grp_Info[gIDpre].SizeN;
2066 Npost = grp_Info[gIDpost].SizeN;
2068 if (weights==NULL) weights =
new float[Npre*Npost];
2069 memset(weights,0,Npre*Npost*
sizeof(
float));
2073 if (currentMode == GPU_MODE)
2074 copyWeightState(&cpuNetPtrs, &cpu_gpuNetPtrs, cudaMemcpyDeviceToHost,
false, gIDpost);
2076 for (
int i=grp_Info[gIDpre].StartN;i<grp_Info[gIDpre].EndN;i++) {
2077 unsigned int offset = cumulativePost[i];
2079 for (
int t=0;t<D;t++) {
2082 for(
int idx_d = dPar.delay_index_start; idx_d < (dPar.delay_index_start + dPar.delay_length); idx_d = idx_d+1) {
2085 post_info_t post_info = postSynapticIds[offset + idx_d];
2089 int p_i = GET_CONN_NEURON_ID(post_info);
2090 carlsim_assert(p_i<numN);
2092 if (p_i >= grp_Info[gIDpost].StartN && p_i <= grp_Info[gIDpost].EndN) {
2094 int s_i = GET_CONN_SYN_ID(post_info);
2097 unsigned int pos_i = cumulativePre[p_i] + s_i;
2099 weights[i+Npre*(p_i-grp_Info[gIDpost].StartN)] = cpuNetPtrs.
wt[pos_i];
2109 float* CpuSNN::getWeightChanges(
int gIDpre,
int gIDpost,
int& Npre,
int& Npost,
float* weightChanges) {
2110 Npre = grp_Info[gIDpre].SizeN;
2111 Npost = grp_Info[gIDpost].SizeN;
2113 if (weightChanges==NULL) weightChanges =
new float[Npre*Npost];
2114 memset(weightChanges,0,Npre*Npost*
sizeof(
float));
2118 if (currentMode == GPU_MODE)
2119 copyWeightState(&cpuNetPtrs, &cpu_gpuNetPtrs, cudaMemcpyDeviceToHost,
false, gIDpost);
2121 for (
int i=grp_Info[gIDpre].StartN;i<grp_Info[gIDpre].EndN;i++) {
2122 unsigned int offset = cumulativePost[i];
2124 for (
int t=0;t<D;t++) {
2127 for(
int idx_d = dPar.delay_index_start; idx_d < (dPar.delay_index_start + dPar.delay_length); idx_d = idx_d+1) {
2130 post_info_t post_info = postSynapticIds[offset + idx_d];
2134 int p_i = GET_CONN_NEURON_ID(post_info);
2135 carlsim_assert(p_i<numN);
2137 if (p_i >= grp_Info[gIDpost].StartN && p_i <= grp_Info[gIDpost].EndN) {
2139 int s_i = GET_CONN_SYN_ID(post_info);
2142 unsigned int pos_i = cumulativePre[p_i] + s_i;
2145 if (grp_Info[gIDpost].FixedInputWts)
2146 weightChanges[i+Npre*(p_i-grp_Info[gIDpost].StartN)] = 0.0f;
2148 weightChanges[i+Npre*(p_i-grp_Info[gIDpost].StartN)] = wtChange[pos_i];
2154 return weightChanges;
2159 uint8_t* CpuSNN::getDelays(
int gIDpre,
int gIDpost,
int& Npre,
int& Npost, uint8_t* delays) {
2160 Npre = grp_Info[gIDpre].SizeN;
2161 Npost = grp_Info[gIDpost].SizeN;
2163 if (delays == NULL) delays =
new uint8_t[Npre*Npost];
2164 memset(delays,0,Npre*Npost);
2166 for (
int i=grp_Info[gIDpre].StartN;i<grp_Info[gIDpre].EndN;i++) {
2167 unsigned int offset = cumulativePost[i];
2169 for (
int t=0;t<D;t++) {
2172 for(
int idx_d = dPar.delay_index_start; idx_d < (dPar.delay_index_start + dPar.delay_length); idx_d = idx_d+1) {
2175 post_info_t post_info = postSynapticIds[offset + idx_d];
2179 int p_i = GET_CONN_NEURON_ID(post_info);
2180 carlsim_assert(p_i<numN);
2182 if (p_i >= grp_Info[gIDpost].StartN && p_i <= grp_Info[gIDpost].EndN) {
2184 int s_i = GET_CONN_SYN_ID(post_info);
2187 unsigned int pos_i = cumulativePre[p_i] + s_i;
2189 delays[i+Npre*(p_i-grp_Info[gIDpost].StartN)] = t+1;
2201 void CpuSNN::updateStateAndFiringTable()
2205 for(
int p=timeTableD2[CARLSIM_STEP_SIZE-1],k=0;p<timeTableD2[CARLSIM_STEP_SIZE-1+D+1];p++,k++) {
2206 firingTableD2[k]=firingTableD2[p];
2209 for(
int i=0; i < D; i++) {
2210 timeTableD2[i+1] = timeTableD2[CARLSIM_STEP_SIZE+i+1]-timeTableD2[CARLSIM_STEP_SIZE];
2216 for(
int g=0; g < numGrp; g++) {
2218 if(grp_Info[g].FixedInputWts || !(grp_Info[g].WithSTDP)) {
2224 for(
int i=grp_Info[g].StartN; i <= grp_Info[g].EndN; i++) {
2226 carlsim_assert(i < numNReg);
2227 unsigned int offset = cumulativePre[i];
2228 float diff_firing = 0.0;
2229 float homeostasisScale = 1.0;
2231 if(grp_Info[g].WithHomeostasis) {
2232 carlsim_assert(baseFiring[i]>0);
2233 diff_firing = 1-avgFiring[i]/baseFiring[i];
2234 homeostasisScale = grp_Info[g].homeostasisScale;
2237 if ((showLogMode >= 1) && (i==grp_Info[g].StartN))
2238 fprintf(fpProgLog,
"Weights, Change at %lu (diff_firing:%f) \n", simTimeSec, diff_firing);
2240 for(
int j=0; j < Npre_plastic[i]; j++) {
2242 if ((showLogMode >= 1) && (i==grp_Info[g].StartN))
2243 fprintf(fpProgLog,
"%1.2f %1.2f \t", wt[offset+j]*10, wtChange[offset+j]*10);
2245 if(grp_Info[g].WithHomeostasis) {
2246 if ((showLogMode >= 3) && (i==grp_Info[g].StartN))
2247 fprintf(fpProgLog,
"%f\t",(diff_firing*(0.0+wt[offset+j]) + wtChange[offset+j])/10/(Npre_plastic[i]+10)/(grp_Info[g].avgTimeScale*2/1000.0)*baseFiring[i]/(1+fabs(diff_firing)*50));
2249 wt[offset+j] += (diff_firing*wt[offset+j]*homeostasisScale + wtChange[offset+j])*baseFiring[i]/grp_Info[g].avgTimeScale/(1+fabs(diff_firing)*50);
2252 wt[offset+j] += wtChange[offset+j];
2259 wtChange[offset+j] = 0;
2262 if (maxSynWt[offset+j] >= 0) {
2263 if (wt[offset+j]>=maxSynWt[offset+j])
2264 wt[offset+j] = maxSynWt[offset+j];
2268 if (wt[offset+j]<=maxSynWt[offset+j])
2269 wt[offset+j] = maxSynWt[offset+j];
2275 if ((showLogMode >= 1) && (i==grp_Info[g].StartN))
2276 fprintf(fpProgLog,
"\n");
2280 spikeCountAll += spikeCountAll1sec;
2281 spikeCountD2Host += (secD2fireCntHost-timeTableD2[D]);
2282 spikeCountD1Host += secD1fireCntHost;
2284 secD1fireCntHost = 0;
2285 spikeCountAll1sec = 0;
2286 secD2fireCntHost = timeTableD2[D];
2288 for(
int i=0; i < numGrp; i++) {
2289 grp_Info[i].FiringCount1sec=0;
2296 void CpuSNN::doD2CurrentUpdate()
2298 int k = secD2fireCntHost-1;
2299 int k_end = timeTableD2[simTimeMs+1];
2300 int t_pos = simTimeMs;
2302 while((k>=k_end)&& (k >=0)) {
2305 int i = firingTableD2[k];
2308 while (!((k >= timeTableD2[t_pos+D])&&(k < timeTableD2[t_pos+D+1]))) {
2310 carlsim_assert((t_pos+D-1)>=0);
2315 int tD = simTimeMs - t_pos;
2317 carlsim_assert((tD<D)&&(tD>=0));
2318 carlsim_assert(i<numN);
2322 unsigned int offset = cumulativePost[i];
2325 for(
int idx_d = dPar.delay_index_start;
2326 idx_d < (dPar.delay_index_start + dPar.delay_length);
2328 generatePostSpike( i, idx_d, offset, tD);
2337 void CpuSNN::doD1CurrentUpdate()
2339 int k = secD1fireCntHost-1;
2340 int k_end = timeTableD1[simTimeMs+D];
2342 while((k>=k_end) && (k>=0)) {
2344 int neuron_id = firingTableD1[k];
2345 carlsim_assert(neuron_id<numN);
2349 unsigned int offset = cumulativePost[neuron_id];
2351 for(
int idx_d = dPar.delay_index_start;
2352 idx_d < (dPar.delay_index_start + dPar.delay_length);
2354 generatePostSpike( neuron_id, idx_d, offset, 0);
2360 void CpuSNN::generatePostSpike(
unsigned int pre_i,
unsigned int idx_d,
unsigned int offset,
unsigned int tD)
2363 post_info_t post_info = postSynapticIds[offset + idx_d];
2366 unsigned int p_i = GET_CONN_NEURON_ID(post_info);
2367 carlsim_assert(p_i<numN);
2370 int s_i = GET_CONN_SYN_ID(post_info);
2371 carlsim_assert(s_i<(Npre[p_i]));
2374 unsigned int pos_i = cumulativePre[p_i] + s_i;
2376 carlsim_assert(p_i < numNReg);
2380 int pre_grpId = findGrpId(pre_i);
2381 char type = grp_Info[pre_grpId].Type;
2384 int ind = STP_BUF_POS(pre_i,(simTime-tD-1));
2387 if (grp_Info[pre_grpId].WithSTP) {
2388 change = wt[pos_i]*stpx[ind]*stpu[ind];
2392 if (grp_Info[pre_grpId].WithConductances) {
2393 if (type & TARGET_AMPA) gAMPA [p_i] += change;
2394 if (type & TARGET_NMDA) gNMDA [p_i] += change;
2395 if (type & TARGET_GABAa) gGABAa[p_i] -= change;
2396 if (type & TARGET_GABAb) gGABAb[p_i] -= change;
2398 current[p_i] += change;
2400 int post_grpId = findGrpId(p_i);
2401 if ((showLogMode >= 3) && (p_i==grp_Info[post_grpId].StartN))
2402 printf(
"%d => %d (%d) am=%f ga=%f wt=%f stpu=%f stpx=%f td=%d\n",
2403 pre_i, p_i, findGrpId(p_i), gAMPA[p_i], gGABAa[p_i],
2404 wt[pos_i],(grp_Info[post_grpId].WithSTP?stpx[ind]:1.0),(grp_Info[post_grpId].WithSTP?stpu[ind]:1.0),tD);
2407 if (grp_Info[post_grpId].WithSTDP) {
2410 int stdp_tDiff = (simTime-lastSpikeTime[p_i]);
2412 if (stdp_tDiff >= 0) {
2413 #ifdef INHIBITORY_STDP
2414 if ((type & TARGET_GABAa) || (type & TARGET_GABAb))
2417 if ((stdp_tDiff*grp_Info[post_grpId].TAU_LTD_INV)<25)
2418 wtChange[pos_i] -= (STDP(stdp_tDiff, grp_Info[post_grpId].ALPHA_LTP, grp_Info[post_grpId].TAU_LTP_INV) - STDP(stdp_tDiff, grp_Info[post_grpId].ALPHA_LTD*1.5, grp_Info[post_grpId].TAU_LTD_INV));
2424 if ((stdp_tDiff*grp_Info[post_grpId].TAU_LTD_INV)<25)
2425 wtChange[pos_i] -= STDP(stdp_tDiff, grp_Info[post_grpId].ALPHA_LTD, grp_Info[post_grpId].TAU_LTD_INV);
2429 carlsim_assert(!((stdp_tDiff < 0) && (lastSpikeTime[p_i] != MAX_SIMULATION_TIME)));
2432 synSpikeTime[pos_i] = simTime;
2435 void CpuSNN::globalStateUpdate()
2440 for(
int g=0; g < numGrp; g++) {
2441 if (grp_Info[g].Type&POISSON_NEURON){
2442 for(
int i=grp_Info[g].StartN; i <= grp_Info[g].EndN; i++)
2443 avgFiring[i] *= grp_Info[g].avgTimeScale_decay;
2447 for(
int i=grp_Info[g].StartN; i <= grp_Info[g].EndN; i++) {
2448 carlsim_assert(i < numNReg);
2449 avgFiring[i] *= grp_Info[g].avgTimeScale_decay;
2451 if (grp_Info[g].WithConductances) {
2455 for (
int j=0; j<COND_INTEGRATION_SCALE; j++) {
2456 float NMDAtmp = (voltage[i]+80)*(voltage[i]+80)/60/60;
2461 float tmpI = - ( gAMPA[i]*(voltage[i]-0)
2462 + MIN(8.0f,gNMDA[i])*NMDAtmp/(1+NMDAtmp)*(voltage[i]-0)
2463 + gGABAa[i]*(voltage[i]+70)
2464 + MIN(2.0f,gGABAb[i])*(voltage[i]+90));
2469 float noiseI = -intrinsicWeight[i]*log(getRand());
2470 if (isnan(noiseI) || isinf(noiseI)) noiseI = 0;
2474 voltage[i]+=((0.04f*voltage[i]+5)*voltage[i]+140-recovery[i]+tmpI)/COND_INTEGRATION_SCALE;
2475 carlsim_assert(!isnan(voltage[i]) && !isinf(voltage[i]));
2477 if (voltage[i] > 30) {
2479 j=COND_INTEGRATION_SCALE;
2481 if (voltage[i] < -90) voltage[i] = -90;
2482 recovery[i]+=Izh_a[i]*(Izh_b[i]*voltage[i]-recovery[i])/COND_INTEGRATION_SCALE;
2486 voltage[i]+=0.5f*((0.04f*voltage[i]+5)*voltage[i]+140-recovery[i]+current[i]);
2487 voltage[i]+=0.5f*((0.04f*voltage[i]+5)*voltage[i]+140-recovery[i]+current[i]);
2488 if (voltage[i] > 30) voltage[i] = 30;
2489 if (voltage[i] < -90) voltage[i] = -90;
2490 recovery[i]+=Izh_a[i]*(Izh_b[i]*voltage[i]-recovery[i]);
2493 if ((showLogMode >= 2) && (i==grp_Info[g].StartN))
2494 fprintf(stdout,
"%d: voltage=%0.3f, recovery=%0.5f, AMPA=%0.5f, NMDA=%0.5f\n",
2495 i, voltage[i], recovery[i], gAMPA[i], gNMDA[i]);
2500 void CpuSNN::printWeight(
int grpId,
const char *str)
2512 for(
int g=stg; (g < endg) ; g++) {
2513 fprintf(stderr,
"%s", str);
2514 if (!grp_Info[g].FixedInputWts) {
2516 if (currentMode == GPU_MODE) {
2517 copyWeightState (&cpuNetPtrs, &cpu_gpuNetPtrs, cudaMemcpyDeviceToHost,
false, g);
2519 int i=grp_Info[g].StartN;
2520 unsigned int offset = cumulativePre[i];
2522 for(
int j=0; j < Npre[i]; j++) {
2524 fprintf(stdout,
"%1.3f,%1.3f\t", cpuNetPtrs.
wt[offset+j], cpuNetPtrs.wtChange[offset+j]);
2526 fprintf(stdout,
"\n");
2533 void CpuSNN::showStatus(
int simType)
2535 DBG(2, fpLog, AT,
"showStatus() called");
2537 printState(
"showStatus\n");
2539 if(simType == GPU_MODE) {
2546 fpVal[1] = fpProgLog;
2548 for(
int k=0; k < 2; k++) {
2553 fprintf(fpVal[k],
"(time=%lld) =========\n\n", (
unsigned long long) simTimeSec);
2558 if((spikeCountAll1sec*1.0f/numN) < 1.0) {
2559 fprintf(fpVal[k],
" SIMULATION WARNING !!! Very Low Firing happened...\n");
2568 if(spikeCountAll1sec == 0) {
2569 fprintf(stderr,
" SIMULATION ERROR !!! Very Low or no firing happened...\n");
2575 void CpuSNN::startCPUTiming()
2577 prevCpuExecutionTime = cumExecutionTime;
2580 void CpuSNN::resetCPUTiming()
2582 prevCpuExecutionTime = cumExecutionTime;
2583 cpuExecutionTime = 0.0;
2586 void CpuSNN::stopCPUTiming()
2588 cpuExecutionTime += (cumExecutionTime - prevCpuExecutionTime);
2589 prevCpuExecutionTime = cumExecutionTime;
2592 void CpuSNN::startGPUTiming()
2594 prevGpuExecutionTime = cumExecutionTime;
2597 void CpuSNN::resetGPUTiming()
2599 prevGpuExecutionTime = cumExecutionTime;
2600 gpuExecutionTime = 0.0;
2603 void CpuSNN::stopGPUTiming()
2605 gpuExecutionTime += (cumExecutionTime - prevGpuExecutionTime);
2606 prevGpuExecutionTime = cumExecutionTime;
2612 void CpuSNN::setupNetwork(
int simType,
int ithGPU,
bool removeTempMem)
2614 if(!doneReorganization)
2615 reorganizeNetwork(removeTempMem, simType);
2617 if((simType == GPU_MODE) && (cpu_gpuNetPtrs.
allocated ==
false))
2618 allocateSNN_GPU(ithGPU);
2624 bool finishedOneSec =
false;
2628 if(++simTimeMs == CARLSIM_STEP_SIZE) {
2631 finishedOneSec =
true;
2635 if(simTime >= MAX_SIMULATION_TIME){
2637 updateAfterMaxTime();
2640 return finishedOneSec;
2646 DBG(2, fpLog, AT,
"runNetwork() called");
2648 carlsim_assert(_nmsec >= 0);
2649 carlsim_assert(_nsec >= 0);
2651 carlsim_assert(simType == CPU_MODE || simType == GPU_MODE);
2653 int runDuration = _nsec*1000 + _nmsec;
2655 setGrpTimeSlice(ALL, MAX(1,MIN(runDuration,PROPAGATED_BUFFER_SIZE-1)));
2660 setupNetwork(simType,ithGPU);
2662 currentMode = simType;
2664 CUDA_RESET_TIMER(timer);
2666 CUDA_START_TIMER(timer);
2668 bool end_stepping =
false;
2671 for(
int i=0; i < runDuration && !end_stepping; i++) {
2675 if(simType == CPU_MODE)
2688 if(showLogCycle==showLog++) {
2689 showStatus(currentMode);
2693 updateSpikeMonitor();
2695 if(simType == CPU_MODE)
2696 updateStateAndFiringTable();
2698 updateStateAndFiringTable_GPU();
2701 stepFeedback->updateMonitors(
this, i);
2704 if(enableGPUSpikeCntPtr==
true && simType == CPU_MODE){
2705 fprintf(stderr,
"Error: the enableGPUSpikeCntPtr flag cannot be set in CPU_MODE\n");
2706 carlsim_assert(currentMode==GPU_MODE);
2708 if(enableGPUSpikeCntPtr==
true && simType == GPU_MODE){
2709 copyFiringStateFromGPU();
2713 end_stepping = stepFeedback->
stepUpdate(
this, i);
2717 for(
int g=0; g < numGrp; g++) {
2718 if ((!grp_Info[g].isSpikeGenerator) && (currentMode==GPU_MODE)) {
2719 copyNeuronState(&cpuNetPtrs, &cpu_gpuNetPtrs, cudaMemcpyDeviceToHost,
false, g);
2725 CUDA_STOP_TIMER(timer);
2726 lastExecutionTime = CUDA_GET_TIMER_VALUE(timer);
2728 fprintf(fpLog,
"(t%s = %2.2f sec)\n", (currentMode == GPU_MODE)?
"GPU":
"CPU", lastExecutionTime/1000);
2729 fprintf(stdout,
"(t%s = %2.2f sec)\n", (currentMode == GPU_MODE)?
"GPU":
"CPU", lastExecutionTime/1000);
2731 cumExecutionTime += lastExecutionTime;
2735 void CpuSNN::updateAfterMaxTime()
2737 fprintf(stderr,
"Maximum Simulation Time Reached...Resetting simulation time\n");
2741 unsigned int cutOffTime = (MAX_SIMULATION_TIME - 10*1000);
2743 for(
int g=0; g < numGrp; g++) {
2745 if (grp_Info[g].isSpikeGenerator) {
2746 int diffTime = (grp_Info[g].SliceUpdateTime - cutOffTime);
2747 grp_Info[g].SliceUpdateTime = (diffTime < 0) ? 0 : diffTime;
2751 if(!grp_Info[g].FixedInputWts) {
2755 for(
int k=0, nid = grp_Info[g].StartN; nid <= grp_Info[g].EndN; nid++,k++) {
2756 carlsim_assert(nid < numNReg);
2758 signed diffTime = (lastSpikeTime[nid] - cutOffTime);
2759 lastSpikeTime[nid] = (diffTime < 0) ? 0 : diffTime;
2762 unsigned* synTime = &synSpikeTime[cumulativePre[nid]];
2763 for(
int i=0; i < Npre[nid]; i++, synTime++) {
2765 signed diffTime = (synTime[0] - cutOffTime);
2766 synTime[0] = (diffTime < 0) ? 0 : diffTime;
2771 simTime = MAX_SIMULATION_TIME - cutOffTime;
2772 resetPropogationBuffer();
2775 void CpuSNN::resetPropogationBuffer()
2777 pbuf->
reset(0, 1023);
2780 unsigned int poissonSpike(
unsigned int currTime,
float frate,
int refractPeriod)
2783 unsigned int nextTime = 0;
2784 carlsim_assert(refractPeriod>0);
2788 float randVal = drand48();
2789 unsigned int tmpVal = -log(randVal)/frate;
2790 nextTime = currTime + tmpVal;
2792 if ((nextTime - currTime) >= (
unsigned) refractPeriod)
2796 carlsim_assert(nextTime != 0);
2801 void CpuSNN::updateSpikeGeneratorsInit()
2804 for(
int g=0; (g < numGrp); g++) {
2805 if (grp_Info[g].isSpikeGenerator) {
2811 if (grp_Info[g].spikeGen) {
2812 grp_Info[g].Noffset = NgenFunc;
2813 NgenFunc += grp_Info[g].SizeN;
2816 updateSpikesFromGrp(g);
2818 carlsim_assert(cnt <= numSpikeGenGrps);
2823 carlsim_assert(spikeGenBits == NULL);
2826 spikeGenBits =
new uint32_t[NgenFunc/32+1];
2827 cpuNetPtrs.spikeGenBits = spikeGenBits;
2829 cpuSnnSz.addInfoSize +=
sizeof(spikeGenBits[0])*(NgenFunc/32+1);
2833 void CpuSNN::updateSpikeGenerators()
2835 for(
int g=0; (g < numGrp); g++) {
2836 if (grp_Info[g].isSpikeGenerator) {
2841 if(((simTime-grp_Info[g].SliceUpdateTime) >= (
unsigned) grp_Info[g].CurrTimeSlice))
2842 updateSpikesFromGrp(g);
2847 void CpuSNN::generateSpikesFromFuncPtr(
int grpId)
2852 unsigned int currTime = simTime;
2854 for(
int i=grp_Info[grpId].StartN;i<=grp_Info[grpId].EndN;i++) {
2856 unsigned int nextTime = lastSpikeTime[i];
2857 if (nextTime == MAX_SIMULATION_TIME)
2863 nextTime = spikeGen->
nextSpikeTime(
this, grpId, i-grp_Info[grpId].StartN, nextTime);
2866 if (nextTime < (currTime+timeSlice)) {
2867 if (nextTime >= currTime) {
2881 void CpuSNN::generateSpikesFromRate(
int grpId)
2885 float refPeriod = grp_Info[grpId].RefractPeriod;
2887 unsigned int currTime = simTime;
2890 if (rate == NULL)
return;
2893 printf(
"specifying rates on the GPU but using the CPU SNN is not supported.\n");
2897 const float* ptr = rate->rates;
2898 for (
int cnt=0;cnt<rate->len;cnt++,ptr++) {
2901 unsigned int nextTime = lastSpikeTime[grp_Info[grpId].StartN+cnt];
2902 if (nextTime == MAX_SIMULATION_TIME)
2906 while (!done && frate>0) {
2907 nextTime = poissonSpike (nextTime, frate/1000.0, refPeriod);
2909 if (nextTime < (currTime+timeSlice)) {
2910 if (nextTime >= currTime) {
2911 int nid = grp_Info[grpId].StartN+cnt;
2923 void CpuSNN::updateSpikesFromGrp(
int grpId)
2925 carlsim_assert(grp_Info[grpId].isSpikeGenerator==
true);
2929 unsigned int currTime = simTime;
2931 int timeSlice = grp_Info[grpId].CurrTimeSlice;
2932 grp_Info[grpId].SliceUpdateTime = simTime;
2936 if (((uint64_t) currTime + timeSlice) >= MAX_SIMULATION_TIME)
2939 if (grp_Info[grpId].spikeGen) {
2940 generateSpikesFromFuncPtr(grpId);
2944 #if !TESTING_CPU_GPU_POISSON
2945 if(currentMode == GPU_MODE)
2949 generateSpikesFromRate(grpId);
2953 inline int CpuSNN::getPoissNeuronPos(
int nid)
2955 int nPos = nid-numNReg;
2956 carlsim_assert(nid >= numNReg);
2957 carlsim_assert(nid < numN);
2958 carlsim_assert((nid-numNReg) < numNPois);
2962 void CpuSNN::setSpikeRate(
int grpId,
PoissonRate* ratePtr,
int refPeriod,
int configId)
2964 if (configId == ALL) {
2965 for(
int c=0; c < numConfig; c++)
2966 setSpikeRate(grpId, ratePtr, refPeriod,c);
2968 int cGrpId = getGroupId(grpId, configId);
2969 if(grp_Info[cGrpId].RatePtr==NULL) {
2970 fprintf(fpParam,
" // refPeriod = %d\n", refPeriod);
2973 carlsim_assert(ratePtr);
2974 if (ratePtr->len != grp_Info[cGrpId].SizeN) {
2975 fprintf(stderr,
"The PoissonRate length did not match the number of neurons in group %s(%d).\n", grp_Info2[cGrpId].Name.c_str(),grpId);
2979 assert (grp_Info[cGrpId].isSpikeGenerator);
2980 grp_Info[cGrpId].RatePtr = ratePtr;
2981 grp_Info[cGrpId].RefractPeriod = refPeriod;
2982 spikeRateUpdated =
true;
2987 void CpuSNN::setSpikeGenerator(
int grpId,
SpikeGenerator* spikeGen,
int configId)
2989 if (configId == ALL) {
2990 for(
int c=0; c < numConfig; c++)
2991 setSpikeGenerator(grpId, spikeGen,c);
2993 int cGrpId = getGroupId(grpId, configId);
2995 carlsim_assert(spikeGen);
2997 assert (grp_Info[cGrpId].isSpikeGenerator);
2998 grp_Info[cGrpId].spikeGen = spikeGen;
3002 void CpuSNN::generateSpikes()
3009 int nid = srg_iter->stg;
3012 int g = findGrpId(nid);
3014 addSpikeToTable (nid, g);
3016 spikeCountAll1sec++;
3027 void CpuSNN::setGrpTimeSlice(
int grpId,
int timeSlice)
3030 for(
int g=0; (g < numGrp); g++) {
3031 if (grp_Info[g].isSpikeGenerator)
3032 setGrpTimeSlice(g, timeSlice);
3035 carlsim_assert((timeSlice > 0 ) && (timeSlice < PROPAGATED_BUFFER_SIZE));
3037 grp_Info[grpId].NewTimeSlice = timeSlice;
3038 grp_Info[grpId].CurrTimeSlice = timeSlice;
3042 int CpuSNN::addSpikeToTable(
int nid,
int g)
3044 int spikeBufferFull = 0;
3045 lastSpikeTime[nid] = simTime;
3046 curSpike[nid] =
true;
3048 avgFiring[nid] += 1000/(grp_Info[g].avgTimeScale*1000);
3050 if(showLogMode >= 3)
3051 if (nid<128) printf(
"spiked: %d\n",nid);
3053 if (currentMode == GPU_MODE) {
3054 carlsim_assert(grp_Info[g].isSpikeGenerator ==
true);
3055 setSpikeGenBit_GPU(nid, g);
3059 if (grp_Info[g].WithSTP) {
3061 int ind = STP_BUF_POS(nid,simTime);
3062 int ind_1 = STP_BUF_POS(nid,(simTime-1));
3063 stpx[ind] = stpx[ind] - stpu[ind_1]*stpx[ind_1];
3064 stpu[ind] = stpu[ind] + grp_Info[g].STP_U*(1-stpu[ind_1]);
3067 if (grp_Info[g].MaxDelay == 1) {
3068 carlsim_assert(nid < numN);
3069 firingTableD1[secD1fireCntHost] = nid;
3071 grp_Info[g].FiringCount1sec++;
3072 if (secD1fireCntHost >= maxSpikesD1) {
3073 spikeBufferFull = 2;
3074 secD1fireCntHost = maxSpikesD1-1;
3078 carlsim_assert(nid < numN);
3079 firingTableD2[secD2fireCntHost] = nid;
3080 grp_Info[g].FiringCount1sec++;
3082 if (secD2fireCntHost >= maxSpikesD2) {
3083 spikeBufferFull = 1;
3084 secD2fireCntHost = maxSpikesD2-1;
3087 return spikeBufferFull;
3090 void CpuSNN::findFiring()
3092 int spikeBufferFull = 0;
3094 for(
int g=0; (g < numGrp) & !spikeBufferFull; g++) {
3096 if (grp_Info[g].Type&POISSON_NEURON)
3100 for(
int i=grp_Info[g].StartN; i <= grp_Info[g].EndN; i++) {
3102 carlsim_assert(i < numNReg);
3104 if (grp_Info[g].WithConductances) {
3105 gAMPA[i] *= grp_Info[g].dAMPA;
3106 gNMDA[i] *= grp_Info[g].dNMDA;
3107 gGABAa[i] *= grp_Info[g].dGABAa;
3108 gGABAb[i] *= grp_Info[g].dGABAb;
3113 if (voltage[i] >= 30.0) {
3114 voltage[i] = Izh_c[i];
3115 recovery[i] += Izh_d[i];
3117 spikeBufferFull = addSpikeToTable(i, g);
3119 if (spikeBufferFull)
break;
3121 if (grp_Info[g].WithSTDP) {
3122 unsigned int pos_ij = cumulativePre[i];
3123 for(
int j=0; j < Npre_plastic[i]; pos_ij++, j++) {
3125 int stdp_tDiff = (simTime-synSpikeTime[pos_ij]);
3126 carlsim_assert(!((stdp_tDiff < 0) && (synSpikeTime[pos_ij] != MAX_SIMULATION_TIME)));
3130 #ifdef INHIBITORY_STDP
3132 if (maxSynWt[pos_ij] >= 0)
3134 if ((stdp_tDiff*grp_Info[g].TAU_LTP_INV)<25)
3135 wtChange[pos_ij] += STDP(stdp_tDiff, grp_Info[g].ALPHA_LTP, grp_Info[g].TAU_LTP_INV);
3137 #ifdef INHIBITORY_STDP
3139 if ((stdp_tDiff > 0) && ((stdp_tDiff*grp_Info[g].TAU_LTD_INV)<25))
3140 wtChange[pos_ij] -= (STDP(stdp_tDiff, grp_Info[g].ALPHA_LTP, grp_Info[g].TAU_LTP_INV) - STDP(stdp_tDiff, grp_Info[g].ALPHA_LTD*1.5, grp_Info[g].TAU_LTD_INV));
3144 spikeCountAll1sec++;
3150 void CpuSNN::doSTPUpdates()
3152 int spikeBufferFull = 0;
3155 for(
int g=0; (g < numGrp) & !spikeBufferFull; g++) {
3156 if (grp_Info[g].WithSTP) {
3157 for(
int i=grp_Info[g].StartN; i <= grp_Info[g].EndN; i++) {
3158 int ind = 0, ind_1 = 0;
3159 ind = STP_BUF_POS(i,simTime);
3160 ind_1 = STP_BUF_POS(i,(simTime-1));
3161 stpx[ind] = stpx[ind_1] + (1-stpx[ind_1])/grp_Info[g].STP_tD;
3162 stpu[ind] = stpu[ind_1] + (grp_Info[g].STP_U - stpu[ind_1])/grp_Info[g].STP_tF;
3168 void CpuSNN::doSnnSim()
3174 updateSpikeGenerators();
3179 if(0) fprintf(fpProgLog,
"\nLTP time=%d, \n", simTime);
3184 timeTableD2[simTimeMs+D+1] = secD2fireCntHost;
3185 timeTableD1[simTimeMs+D+1] = secD1fireCntHost;
3187 if(0) fprintf(fpProgLog,
"\nLTD time=%d,\n", simTime);
3189 doD2CurrentUpdate();
3191 doD1CurrentUpdate();
3193 globalStateUpdate();
3201 void CpuSNN::swapConnections(
int nid,
int oldPos,
int newPos)
3203 unsigned int cumN=cumulativePost[nid];
3207 postSynapticIds[cumN+oldPos]= postSynapticIds[cumN+newPos];
3208 postSynapticIds[cumN+newPos]= tmp;
3211 uint8_t tmp_delay = tmp_SynapticDelay[cumN+oldPos];
3212 tmp_SynapticDelay[cumN+oldPos] = tmp_SynapticDelay[cumN+newPos];
3213 tmp_SynapticDelay[cumN+newPos] = tmp_delay;
3216 post_info_t postInfo = postSynapticIds[cumN+oldPos];
3217 int post_nid = GET_CONN_NEURON_ID(postInfo);
3218 int post_sid = GET_CONN_SYN_ID(postInfo);
3220 post_info_t* preId = &preSynapticIds[cumulativePre[post_nid]+post_sid];
3221 int pre_nid = GET_CONN_NEURON_ID((*preId));
3222 int pre_sid = GET_CONN_SYN_ID((*preId));
3223 int pre_gid = GET_CONN_GRP_ID((*preId));
3224 assert (pre_nid == nid);
3225 assert (pre_sid == newPos);
3226 *preId = SET_CONN_ID( pre_nid, oldPos, pre_gid);
3229 postInfo = postSynapticIds[cumN+newPos];
3230 post_nid = GET_CONN_NEURON_ID(postInfo);
3231 post_sid = GET_CONN_SYN_ID(postInfo);
3233 preId = &preSynapticIds[cumulativePre[post_nid]+post_sid];
3234 pre_nid = GET_CONN_NEURON_ID((*preId));
3235 pre_sid = GET_CONN_SYN_ID((*preId));
3236 pre_gid = GET_CONN_GRP_ID((*preId));
3237 assert (pre_nid == nid);
3238 assert (pre_sid == oldPos);
3239 *preId = SET_CONN_ID( pre_nid, newPos, pre_gid);
3245 void CpuSNN::reorganizeDelay()
3247 for(
int grpId=0; grpId < numGrp; grpId++) {
3248 for(
int nid=grp_Info[grpId].StartN; nid <= grp_Info[grpId].EndN; nid++) {
3249 unsigned int jPos=0;
3250 unsigned int cumN=cumulativePost[nid];
3251 unsigned int cumDelayStart=0;
3252 for(
int td = 0; td < D; td++) {
3253 unsigned int j=jPos;
3255 while(j < Npost[nid]) {
3258 if(td==(tmp_SynapticDelay[cumN+j]-1)) {
3259 carlsim_assert(jPos<Npost[nid]);
3260 swapConnections(nid, j, jPos);
3269 postDelayInfo[nid*(D+1)+td].delay_length = cnt;
3270 postDelayInfo[nid*(D+1)+td].delay_index_start = cumDelayStart;
3271 cumDelayStart += cnt;
3273 carlsim_assert(cumDelayStart <= Npost[nid]);
3277 carlsim_assert(cumDelayStart == Npost[nid]);
3278 for(
unsigned int j=1; j < Npost[nid]; j++) {
3279 unsigned int cumN=cumulativePost[nid];
3280 if( tmp_SynapticDelay[cumN+j] < tmp_SynapticDelay[cumN+j-1]) {
3281 fprintf(stderr,
"Post-synaptic delays not sorted correctly...\n");
3282 fprintf(stderr,
"id=%d, delay[%d]=%d, delay[%d]=%d\n",
3283 nid, j, tmp_SynapticDelay[cumN+j], j-1, tmp_SynapticDelay[cumN+j-1]);
3284 carlsim_assert( tmp_SynapticDelay[cumN+j] >= tmp_SynapticDelay[cumN+j-1]);
3292 char* extractFileName(
char *fname)
3294 char* varname = strrchr(fname,
'\\');
3295 size_t len1 = strlen(varname+1);
3296 char* extname = strchr(varname,
'.');
3297 size_t len2 = strlen(extname);
3298 varname[len1-len2]=
'\0';
3302 #define COMPACTION_ALIGNMENT_PRE 16
3303 #define COMPACTION_ALIGNMENT_POST 0
3305 #define SETPOST_INFO(name, nid, sid, val) name[cumulativePost[nid]+sid]=val;
3307 #define SETPRE_INFO(name, nid, sid, val) name[cumulativePre[nid]+sid]=val;
3312 void CpuSNN::initSynapticWeights()
3315 wtChange =
new float[preSynCnt];
3316 synSpikeTime =
new uint32_t[preSynCnt];
3318 cpuSnnSz.synapticInfoSize =
sizeof(float)*(preSynCnt*2);
3320 resetSynapticConnections(
false);
3325 void CpuSNN::compactConnections()
3327 unsigned int* tmp_cumulativePost =
new unsigned int[numN];
3328 unsigned int* tmp_cumulativePre =
new unsigned int[numN];
3329 unsigned int lastCnt_pre = 0;
3330 unsigned int lastCnt_post = 0;
3332 tmp_cumulativePost[0] = 0;
3333 tmp_cumulativePre[0] = 0;
3335 for(
int i=1; i < numN; i++) {
3336 lastCnt_post = tmp_cumulativePost[i-1]+Npost[i-1];
3337 lastCnt_pre = tmp_cumulativePre[i-1]+Npre[i-1];
3338 #if COMPACTION_ALIGNMENT_POST
3339 lastCnt_post= lastCnt_post + COMPACTION_ALIGNMENT_POST-lastCnt_post%COMPACTION_ALIGNMENT_POST;
3340 lastCnt_pre = lastCnt_pre + COMPACTION_ALIGNMENT_PRE- lastCnt_pre%COMPACTION_ALIGNMENT_PRE;
3342 tmp_cumulativePost[i] = lastCnt_post;
3343 tmp_cumulativePre[i] = lastCnt_pre;
3344 carlsim_assert(tmp_cumulativePost[i] <= cumulativePost[i]);
3345 carlsim_assert(tmp_cumulativePre[i] <= cumulativePre[i]);
3349 unsigned int tmp_postSynCnt = tmp_cumulativePost[numN-1]+Npost[numN-1];
3350 unsigned int tmp_preSynCnt = tmp_cumulativePre[numN-1]+Npre[numN-1];
3351 carlsim_assert(tmp_postSynCnt <= allocatedPost);
3352 carlsim_assert(tmp_preSynCnt <= allocatedPre);
3353 carlsim_assert(tmp_postSynCnt <= postSynCnt);
3354 carlsim_assert(tmp_preSynCnt <= preSynCnt);
3355 fprintf(fpLog,
"******************\n");
3356 fprintf(fpLog,
"CompactConnection: \n");
3357 fprintf(fpLog,
"******************\n");
3358 fprintf(fpLog,
"old_postCnt = %d, new_postCnt = %d\n", postSynCnt, tmp_postSynCnt);
3359 fprintf(fpLog,
"old_preCnt = %d, new_postCnt = %d\n", preSynCnt, tmp_preSynCnt);
3366 float* tmp_wt =
new float[tmp_preSynCnt+100];
3367 float* tmp_maxSynWt =
new float[tmp_preSynCnt+100];
3369 for(
int i=0; i < numN; i++) {
3370 carlsim_assert(tmp_cumulativePost[i] <= cumulativePost[i]);
3371 carlsim_assert(tmp_cumulativePre[i] <= cumulativePre[i]);
3372 for(
int j=0; j < Npost[i]; j++) {
3373 unsigned int tmpPos = tmp_cumulativePost[i]+j;
3374 unsigned int oldPos = cumulativePost[i]+j;
3375 tmp_postSynapticIds[tmpPos] = postSynapticIds[oldPos];
3376 tmp_SynapticDelay[tmpPos] = tmp_SynapticDelay[oldPos];
3378 for(
int j=0; j < Npre[i]; j++) {
3379 unsigned int tmpPos = tmp_cumulativePre[i]+j;
3380 unsigned int oldPos = cumulativePre[i]+j;
3381 tmp_preSynapticIds[tmpPos] = preSynapticIds[oldPos];
3382 tmp_maxSynWt[tmpPos] = maxSynWt[oldPos];
3383 tmp_wt[tmpPos] = wt[oldPos];
3388 delete[] postSynapticIds;
3389 postSynapticIds = tmp_postSynapticIds;
3390 cpuSnnSz.networkInfoSize -= (
sizeof(
post_info_t)*postSynCnt);
3391 cpuSnnSz.networkInfoSize += (
sizeof(
post_info_t)*(tmp_postSynCnt+100));
3393 delete[] cumulativePost;
3394 cumulativePost = tmp_cumulativePost;
3396 delete[] cumulativePre;
3397 cumulativePre = tmp_cumulativePre;
3400 maxSynWt = tmp_maxSynWt;
3401 cpuSnnSz.synapticInfoSize -= (
sizeof(float)*preSynCnt);
3402 cpuSnnSz.synapticInfoSize += (
sizeof(int)*(tmp_preSynCnt+100));
3406 cpuSnnSz.synapticInfoSize -= (
sizeof(float)*preSynCnt);
3407 cpuSnnSz.synapticInfoSize += (
sizeof(int)*(tmp_preSynCnt+100));
3409 delete[] preSynapticIds;
3410 preSynapticIds = tmp_preSynapticIds;
3411 cpuSnnSz.synapticInfoSize -= (
sizeof(
post_info_t)*preSynCnt);
3412 cpuSnnSz.synapticInfoSize += (
sizeof(
post_info_t)*(tmp_preSynCnt+100));
3414 preSynCnt = tmp_preSynCnt;
3415 postSynCnt = tmp_postSynCnt;
3418 void CpuSNN::updateParameters(
int* curN,
int* numPostSynapses,
int* numPreSynapses,
int nConfig)
3420 carlsim_assert(nConfig > 0);
3421 numNExcPois = 0; numNInhPois = 0; numNExcReg = 0; numNInhReg = 0;
3422 *numPostSynapses = 0; *numPreSynapses = 0;
3426 for(
int g=0; g < numGrp; g++) {
3427 if (grp_Info[g].Type==UNKNOWN_NEURON) {
3428 std::ostringstream stringStream;
3429 stringStream <<
"Unknown group for " << g <<
"(" << grp_Info2[g].Name <<
")\n";
3430 exitSimulation(1, stringStream.str().c_str());
3433 if (IS_INHIBITORY_TYPE(grp_Info[g].Type) && !(grp_Info[g].Type&POISSON_NEURON))
3434 numNInhReg += grp_Info[g].SizeN;
3435 else if (IS_EXCITATORY_TYPE(grp_Info[g].Type) && !(grp_Info[g].Type&POISSON_NEURON))
3436 numNExcReg += grp_Info[g].SizeN;
3437 else if (IS_EXCITATORY_TYPE(grp_Info[g].Type) && (grp_Info[g].Type&POISSON_NEURON))
3438 numNExcPois += grp_Info[g].SizeN;
3439 else if (IS_INHIBITORY_TYPE(grp_Info[g].Type) && (grp_Info[g].Type&POISSON_NEURON))
3440 numNInhPois += grp_Info[g].SizeN;
3444 if (grp_Info[g].numPostSynapses >= *numPostSynapses)
3445 *numPostSynapses = grp_Info[g].numPostSynapses;
3446 if (grp_Info[g].numPreSynapses >= *numPreSynapses)
3447 *numPreSynapses = grp_Info[g].numPreSynapses;
3450 *curN = numNExcReg + numNInhReg + numNExcPois + numNInhPois;
3451 numNPois = numNExcPois + numNInhPois;
3452 numNReg = numNExcReg +numNInhReg;
3459 void CpuSNN::resetSynapticConnections(
bool changeWeights)
3463 for(
int destGrp=0; destGrp < numGrp; destGrp++) {
3464 const char* updateStr = (grp_Info[destGrp].newUpdates ==
true)?
"(**)":
"";
3465 fprintf(stdout,
"Grp: %d:%s s=%d e=%d %s\n", destGrp, grp_Info2[destGrp].Name.c_str(), grp_Info[destGrp].StartN, grp_Info[destGrp].EndN, updateStr);
3466 fprintf(fpLog,
"Grp: %d:%s s=%d e=%d %s\n", destGrp, grp_Info2[destGrp].Name.c_str(), grp_Info[destGrp].StartN, grp_Info[destGrp].EndN, updateStr);
3468 for(
int nid=grp_Info[destGrp].StartN; nid <= grp_Info[destGrp].EndN; nid++) {
3469 unsigned int offset = cumulativePre[nid];
3470 for (j=0;j<Npre[nid]; j++) wtChange[offset+j] = 0.0;
3471 for (j=0;j<Npre[nid]; j++) synSpikeTime[offset+j] = MAX_SIMULATION_TIME;
3472 post_info_t *preIdPtr = &preSynapticIds[cumulativePre[nid]];
3473 float* synWtPtr = &wt[cumulativePre[nid]];
3474 float* maxWtPtr = &maxSynWt[cumulativePre[nid]];
3475 int prevPreGrp = -1;
3478 for (j=0; j < Npre[nid]; j++,preIdPtr++, synWtPtr++, maxWtPtr++) {
3479 int preId = GET_CONN_NEURON_ID((*preIdPtr));
3480 carlsim_assert(preId < numN);
3481 int srcGrp = findGrpId(preId);
3484 while(connIterator){
3485 if(connIterator->grpSrc == srcGrp && connIterator->grpDest == destGrp){
3487 connInfo=connIterator;
3491 connIterator=connIterator->next;
3493 carlsim_assert(connInfo != NULL);
3494 int connProp = connInfo->connProp;
3495 bool synWtType = GET_FIXED_PLASTIC(connProp);
3497 if( prevPreGrp != srcGrp) {
3498 if(nid==grp_Info[destGrp].StartN) {
3499 const char* updateStr = (connInfo->newUpdates==
true)?
"(**)":
"";
3500 fprintf(stdout,
"\t%d (%s) start=%d, type=%s maxWts = %f %s\n", srcGrp,
3501 grp_Info2[srcGrp].Name.c_str(), j, (j<Npre_plastic[nid]?
"P":
"F"), connInfo->maxWt, updateStr);
3502 fprintf(fpLog,
"\t%d (%s) start=%d, type=%s maxWts = %f %s\n", srcGrp,
3503 grp_Info2[srcGrp].Name.c_str(), j, (j<Npre_plastic[nid]?
"P":
"F"), connInfo->maxWt, updateStr);
3505 prevPreGrp = srcGrp;
3513 if ((synWtType == SYN_PLASTIC) || connInfo->newUpdates) {
3514 *synWtPtr = getWeights(connInfo->connProp, connInfo->initWt, connInfo->maxWt, nid, srcGrp);
3515 *maxWtPtr = connInfo->maxWt;
3520 grp_Info[destGrp].newUpdates =
false;
3526 connInfo->newUpdates =
false;
3527 connInfo = connInfo->next;
3531 void CpuSNN::resetGroups()
3533 for(
int g=0; (g < numGrp); g++) {
3535 if (grp_Info[g].isSpikeGenerator) {
3536 grp_Info[g].CurrTimeSlice = grp_Info[g].NewTimeSlice;
3537 grp_Info[g].SliceUpdateTime = 0;
3538 for(
int nid=grp_Info[g].StartN; nid <= grp_Info[g].EndN; nid++)
3539 resetPoissonNeuron(nid, g);
3543 for(
int nid=grp_Info[g].StartN; nid <= grp_Info[g].EndN; nid++)
3544 resetNeuron(nid, g);
3552 resetConductances();
3558 void CpuSNN::resetFiringInformation()
3564 spikeCountAll1sec = 0;
3565 spikeCountD2Host = 0;
3566 spikeCountD1Host = 0;
3568 secD1fireCntHost = 0;
3569 secD2fireCntHost = 0;
3571 for(
int i=0; i < numGrp; i++) {
3572 grp_Info[i].FiringCount1sec = 0;
3581 resetPropogationBuffer();
3590 if(!doneReorganization)
3594 resetSynapticConnections(
true);
3600 resetFiringInformation();
3608 if(!doneReorganization){
3609 fprintf(stderr,
"UpdateNetwork function was called but nothing was done because reorganizeNetwork must be called first.\n");
3614 resetSynapticConnections(
true);
3616 resetSynapticConnections(
false);
3622 resetFiringInformation();
3624 if(currentMode==GPU_MODE){
3633 void CpuSNN::printTuningLog()
3636 fprintf(fpTuningLog,
"Generating Tuning log %d\n", cntTuning);
3637 printParameters(fpTuningLog);
3644 void CpuSNN::reorganizeNetwork(
bool removeTempMemory,
int simType)
3647 if(doneReorganization)
3650 fprintf(stdout,
"Beginning reorganization of network....\n");
3656 compactConnections();
3668 initSynapticWeights();
3673 updateSpikeGeneratorsInit();
3676 doneReorganization =
true;
3679 printParameters(fpLog);
3692 if(simType==GPU_MODE)
3693 fprintf(stdout,
"Starting GPU-SNN Simulations ....\n");
3695 fprintf(stdout,
"Starting CPU-SNN Simulations ....\n");
3700 if (simType == GPU_MODE)
3701 fconn = fopen(
"gpu_conn.txt",
"w");
3703 fconn = fopen(
"conn.txt",
"w");
3709 printPreConnection(fconn);
3720 if(removeTempMemory) {
3721 memoryOptimized =
true;
3722 delete[] tmp_SynapticDelay;
3723 tmp_SynapticDelay = NULL;
3727 void CpuSNN::setDefaultParameters(
float alpha_ltp,
float tau_ltp,
float alpha_ltd,
float tau_ltd)
3729 printf(
"Warning: setDefaultParameters() is deprecated and may be removed in the future.\nIt is recommended that you set the desired parameters explicitly.\n");
3730 #define DEFAULT_COND_tAMPA 5.0
3731 #define DEFAULT_COND_tNMDA 150.0
3732 #define DEFAULT_COND_tGABAa 6.0
3733 #define DEFAULT_COND_tGABAb 150.0
3735 #define DEFAULT_STP_U_Inh 0.5
3736 #define DEFAULT_STP_tD_Inh 800
3737 #define DEFAULT_STP_tF_Inh 1000
3738 #define DEFAULT_STP_U_Exc 0.2
3739 #define DEFAULT_STP_tD_Exc 700
3740 #define DEFAULT_STP_tF_Exc 20
3741 #define DEFAULT_HOMEO_SCALE 0.1
3742 #define DEFAULT_AVG_TIME_SCALE 10
3745 setConductances(ALL,
true, DEFAULT_COND_tAMPA, DEFAULT_COND_tNMDA, DEFAULT_COND_tGABAa, DEFAULT_COND_tGABAb);
3748 for(
int g=0; g < getNumGroups(); g++) {
3753 if(!isPoissonGroup(g))
3754 setHomeostasis(g,
true, DEFAULT_HOMEO_SCALE, DEFAULT_AVG_TIME_SCALE);
3756 setHomeostasis(g,
false, DEFAULT_HOMEO_SCALE, DEFAULT_AVG_TIME_SCALE);
3758 if(isExcitatoryGroup(g)) {
3759 setSTP(g,
true, DEFAULT_STP_U_Exc, DEFAULT_STP_tD_Exc, DEFAULT_STP_tF_Exc);
3760 if ((alpha_ltp!=0.0) && (!isPoissonGroup(g)))
3761 setSTDP(g,
true, alpha_ltp, tau_ltp, alpha_ltd, tau_ltd);
3764 setSTP(g,
true, DEFAULT_STP_U_Inh, DEFAULT_STP_tD_Inh, DEFAULT_STP_tF_Inh);
3769 #if ! (_WIN32 || _WIN64)
3771 #define strcmpi(s1,s2) strcasecmp(s1,s2)
3774 #define PROBE_CURRENT (1 << 1)
3775 #define PROBE_VOLTAGE (1 << 2)
3776 #define PROBE_FIRING_RATE (1 << 3)
3778 void CpuSNN::setProbe(
int g,
const string& type,
int startId,
int cnt, uint32_t _printProbe)
3781 carlsim_assert(startId >= 0);
3782 carlsim_assert(startId <= grp_Info[g].SizeN);
3785 int i=grp_Info[g].StartN+startId;
3787 endId = grp_Info[g].EndN;
3789 endId = i + cnt - 1;
3791 if(endId > grp_Info[g].EndN)
3792 endId = grp_Info[g].EndN;
3794 for(; i <= endId; i++) {
3796 probeParam_t* n =
new probeParam_t;
3797 memset(n, 0,
sizeof(probeParam_t));
3798 n->next = neuronProbe;
3800 if(type.find(
"current") != string::npos) {
3801 n->type |= PROBE_CURRENT;
3802 n->bufferI =
new float[CARLSIM_STEP_SIZE];
3803 cpuSnnSz.probeInfoSize +=
sizeof(float)*CARLSIM_STEP_SIZE;
3806 if(type.find(
"voltage") != string::npos) {
3807 n->type |= PROBE_VOLTAGE;
3808 n->bufferV =
new float[CARLSIM_STEP_SIZE];
3809 cpuSnnSz.probeInfoSize +=
sizeof(float)*CARLSIM_STEP_SIZE;
3812 if(type.find(
"firing-rate") != string::npos) {
3813 n->type |= PROBE_FIRING_RATE;
3814 n->spikeBins =
new bool[CARLSIM_STEP_SIZE];
3815 n->bufferFRate =
new float[CARLSIM_STEP_SIZE];
3816 cpuSnnSz.probeInfoSize += (
sizeof(float)+
sizeof(
bool))*CARLSIM_STEP_SIZE;
3820 n->vmax = 40.0; n->vmin = -80.0;
3821 n->imax = 50.0; n->imin = -50.0;
3823 n->printProbe = _printProbe;
3830 void CpuSNN::updateMonitors()
3833 probeParam_t* n = neuronProbe;
3870 if (n->type & PROBE_CURRENT)
3871 n->bufferI[simTimeMs] = current[nid];
3873 if (n->type & PROBE_VOLTAGE)
3874 n->bufferV[simTimeMs] = voltage[nid];
3877 #define BIN_SIZE 0.001
3879 if (n->type & PROBE_FIRING_RATE) {
3881 if (simTime >= NUM_BIN)
3882 oldSpike = n->spikeBins[simTimeMs%NUM_BIN];
3883 int newSpike = (voltage[nid] >= 30.0 ) ? 1 : 0;
3884 n->cumCount = n->cumCount - oldSpike + newSpike;
3885 float frate = n->cumCount/(NUM_BIN*BIN_SIZE);
3886 n->spikeBins[simTimeMs % NUM_BIN] = newSpike;
3887 if (simTime >= NUM_BIN)
3888 n->bufferFRate[(simTime-NUM_BIN)%CARLSIM_STEP_SIZE] = frate;
3897 carlsim_assert(cnt==numProbe);
3906 void update(
CpuSNN* s,
int grpId,
unsigned int* Nids,
unsigned int* timeCnts,
unsigned int total_spikes,
float firing_Rate)
3910 for (
int t=0; t < CARLSIM_STEP_SIZE; t++) {
3911 for(
int i=0; i<timeCnts[t];i++,pos++) {
3912 int time = t + s->getSimTime() - CARLSIM_STEP_SIZE;
3914 int cnt = fwrite(&time,
sizeof(
int),1,fid);
3915 carlsim_assert(cnt != 0);
3916 cnt = fwrite(&
id,
sizeof(
int),1,fid);
3917 carlsim_assert(cnt != 0);
3928 FILE* fid = fopen(fname.c_str(),
"wb");
3932 #if defined(CREATE_SPIKEDIR_IF_NOT_EXISTS)
3938 strcpy(fchar,fname.c_str());
3940 #if defined(_WIN32) || defined(_WIN64) // TODO: test it
3941 status = _mkdir(fname.c_str());
3943 status = mkdir(dirname(fchar), 0777);
3945 if (status==-1 && errno!=EEXIST) {
3946 fprintf(stderr,
"ERROR %d: could not create spike file '%s', directory '%%CARLSIM_ROOT%%/results/' does not exist\n",errno,fname.c_str());
3947 #ifdef USE_EXCEPTIONS
3948 std::ostringstream stringStream;
3949 stringStream <<
"ERROR " << errno <<
": could not create spike file '" << fname <<
"', directory '%%CARLSIM_ROOT%%/results/' does not exist\n";
3950 throw std::runtime_error(stringStream.str().c_str());
3958 fid = fopen(fname.c_str(),
"wb");
3961 fprintf(stderr,
"ERROR: File \"%s\" could not be opened, please check if it exists.\n",fname.c_str());
3962 fprintf(stderr,
" Enable option CREATE_SPIKEDIR_IF_NOT_EXISTS in config.h to attempt creating the "
3963 "specified subdirectory automatically.\n");
3965 #ifdef USE_EXCEPTIONS
3966 std::ostringstream stringStream;
3967 stringStream <<
"ERROR " << errno <<
" File \"" << fname <<
"\" could not be opened, please check if it exists.\n Enable option CREATE_SPIKEDIR_IF_NOT_EXISTS in config.h to attempt creating thespecified subdirectory automatically.\n";
3968 throw std::runtime_error(stringStream.str().c_str());
3976 carlsim_assert(configId != ALL);
3983 if (configId == ALL) {
3984 for(
int c=0; c < numConfig; c++)
3987 int cGrpId = getGroupId(grpId, configId);
3988 DBG(2, fpLog, AT,
"spikeMonitor Added");
3991 monGrpId[numSpikeMonitor] = cGrpId;
3994 grp_Info[cGrpId].MonitorId = numSpikeMonitor;
3996 float maxRate = grp_Info[cGrpId].MaxFiringRate;
4000 int buffSize = (int)(maxRate*grp_Info[cGrpId].SizeN);
4003 monBufferSize[numSpikeMonitor] = buffSize;
4006 monBufferPos[numSpikeMonitor] = 0;
4008 monBufferCallback[numSpikeMonitor] = spikeMon;
4011 monBufferFiring[numSpikeMonitor] =
new unsigned int[buffSize];
4012 monBufferTimeCnt[numSpikeMonitor]=
new unsigned int[CARLSIM_STEP_SIZE];
4013 memset(monBufferTimeCnt[numSpikeMonitor],0,
sizeof(
int)*(CARLSIM_STEP_SIZE));
4019 cpuSnnSz.monitorInfoSize +=
sizeof(int)*buffSize;
4020 cpuSnnSz.monitorInfoSize +=
sizeof(int)*(CARLSIM_STEP_SIZE);
4024 void CpuSNN::updateSpikeMonitor()
4027 if(numSpikeMonitor==0)
4030 bool bufferOverFlow[MAX_GRP_PER_SNN];
4031 memset(bufferOverFlow,0,
sizeof(bufferOverFlow));
4034 for(
int i=0; i < numSpikeMonitor; i++)
4035 memset(monBufferTimeCnt[i],0,
sizeof(
int)*(CARLSIM_STEP_SIZE));
4038 memset(monBufferPos,0,
sizeof(
int)*numSpikeMonitor);
4040 if(currentMode == GPU_MODE) {
4041 updateSpikeMonitor_GPU();
4048 for(
int k=0; k < 2; k++) {
4049 unsigned int* timeTablePtr = (k==0)?timeTableD2:timeTableD1;
4050 unsigned int* fireTablePtr = (k==0)?firingTableD2:firingTableD1;
4051 for(
int t=0; t < CARLSIM_STEP_SIZE; t++) {
4052 for(
int i=timeTablePtr[t+D]; i<timeTablePtr[t+D+1];i++) {
4054 int nid = fireTablePtr[i];
4055 if (currentMode == GPU_MODE)
4056 nid = GET_FIRING_TABLE_NID(nid);
4058 carlsim_assert(nid < numN);
4060 int grpId = findGrpId(nid);
4061 int monitorId = grp_Info[grpId].MonitorId;
4062 if(monitorId!= -1) {
4063 carlsim_assert(nid >= grp_Info[grpId].StartN);
4064 carlsim_assert(nid <= grp_Info[grpId].EndN);
4065 int pos = monBufferPos[monitorId];
4066 if((pos >= monBufferSize[monitorId]))
4068 if(!bufferOverFlow[monitorId])
4069 fprintf(stderr,
"Buffer Monitor size (%d) is small. Increase buffer firing rate for %s\n", monBufferSize[monitorId], grp_Info2[grpId].Name.c_str());
4070 bufferOverFlow[monitorId] =
true;
4073 monBufferPos[monitorId]++;
4074 monBufferFiring[monitorId][pos] = nid-grp_Info[grpId].StartN;
4076 monBufferTimeCnt[monitorId][t]++;
4083 for (
int grpId=0;grpId<numGrp;grpId++) {
4084 int monitorId = grp_Info[grpId].MonitorId;
4085 if(monitorId!= -1) {
4086 unsigned int total_spikes = monBufferPos[monitorId];
4087 float firing_rate = (((float)monBufferPos[monitorId])/(grp_Info[grpId].SizeN)/((
float) (CARLSIM_STEP_SIZE*CARLSIM_STEP_INCREMENT)));
4088 fprintf(stderr,
"Spike Monitor for Group %s has %d spikes (%f Hz)\n",grp_Info2[grpId].Name.c_str(),total_spikes,firing_rate);
4091 if (monBufferCallback[monitorId])
4092 monBufferCallback[monitorId]->
update(
this,grpId,monBufferFiring[monitorId],monBufferTimeCnt[monitorId], total_spikes, firing_rate);
4102 if (configId == ALL) {
4103 for(
int c=0; c < numConfig; c++)
4109 connInfo = getConnectInfo(connectId,configId);
4111 bool synWtType = GET_FIXED_PLASTIC(connInfo->connProp);
4112 if(synWtType == SYN_PLASTIC){
4113 printf(
"The synapses in this connection must be SYN_FIXED in order to use this function.\n");
4114 carlsim_assert(
false);
4117 if(connInfo->numberOfConnections != sizeMatrix){
4118 printf(
"The size of the input weight matrix and the number of synaptic connections in this connection do not match.\n");
4119 carlsim_assert(
false);
4123 int destGrp = connInfo->grpDest;
4124 int srcGrp = connInfo->grpSrc;
4126 for(
int postId=grp_Info[destGrp].StartN; postId <= grp_Info[destGrp].EndN; postId++) {
4127 int offset = cumulativePre[postId];
4128 float* synWtPtr = &wt[cumulativePre[postId]];
4131 for (j=0; j < Npre[postId]; j++,preIdPtr++, synWtPtr++) {
4132 int preId = GET_CONN_NEURON_ID((*preIdPtr));
4133 carlsim_assert(preId < numN);
4134 int currentSrcId = findGrpId(preId);
4137 if(currentSrcId == srcGrp){
4139 *synWtPtr = (*weightMatrix);
4148 if(currentMode == GPU_MODE)
4157 while(connIterator){
4158 if(connIterator->connId == connectionId){
4160 return connIterator->numberOfConnections;
4163 connIterator=connIterator->next;
4166 printf(
"Connection ID was not found. Quitting.\n");
4167 carlsim_assert(
false);
unsigned int * delay_opts
first 8 bits are delay, higher are for Fixed/Plastic and any other future options ...
static const unsigned int MAJOR_VERSION
major release version, as in CARLsim X
void nextTimeStep()
Must be called to tell the buffer that it should move on to the next time step.
virtual void update(CpuSNN *s, int grpId, unsigned int *Nids, unsigned int *timeCnts, unsigned int total_spikes, float firing_Rate)
Controls actions that are performed when certain neurons fire (user-defined).
int createGroup(const string &_name, unsigned int _numN, int _nType, int configId=ALL)
creates a group of Izhikevich spiking neurons
float dGABAb
homeostatic plasticity variables
int getNumConnections(int connectionId)
Input: connectionID. Output: the number of connections associated with that connection ID...
int connect(int gIDpre, int gIDpost, const string &_type, float initWt, float maxWt, float _C, uint8_t minDelay, uint8_t maxDelay, bool synWtType=SYN_FIXED, const string &wtType=" ")
make from each neuron in grpId1 to 'numPostSynapses' neurons in grpId2
void reset(int minDelay, int maxDelay)
Must be called at the begin (reset) of a simulation.
void setSpikeMonitor(int gid, SpikeMonitor *spikeMon=NULL, int configId=ALL)
float * wt
stores the synaptic weight and weight change of a synaptic connection
virtual void connect(CpuSNN *s, int srcGrpId, int i, int destGrpId, int j, float &weight, float &maxWt, float &delay, bool &connected)
specifies which synaptic connections (per group, per neuron, per synapse) should be made ...
void resetSpikeCnt(int grpId=-1)
Resets the spike count for a particular group.
unsigned int * nSpikeCnt
homeostatic plasticity variables
used for fine-grained control over spike generation, using a callback mechanism
bool updateTime()
returns true when a new second is started
used for fine-grained control over spike generation, using a callback mechanism
int allocated
true if all data has been allocated..
int runNetwork(int _nsec, int _tstep=0, int simType=CPU_MODE, int ithGPU=0, bool enablePrint=false, int copyState=false)
run the simulation for n sec simType can either be CPU_MODE or GPU_MODE ithGPU: specify on which CUDA...
int createSpikeGeneratorGroup(const string &_name, int unsigned size_n, int stype, int configId=ALL)
creates a spike generator group (dummy-neurons, not Izhikevich spiking neurons).
Schedule/Store spikes to be delivered at a later point in the simulation.
void CpuSNNInit(unsigned int _numN, unsigned int _numPostSynapses, unsigned int _numPreSynapses, unsigned int _D)
void setNeuronParameters(int groupId, float _a, float a_sd, float _b, float b_sd, float _c, float c_sd, float _d, float d_sd, int configId=ALL)
Sets the Izhikevich parameters a, b, c, and d of a neuron group.
unsigned short * Npost
stores the number of output connections from a neuron.
void printMemoryInfo(FILE *fp=stdout)
prints memory info to file
unsigned short * Npre
stores the number of input connections to the neuron
virtual unsigned int nextSpikeTime(CpuSNN *s, int grpId, int i, unsigned int currentTime)
controls spike generation using a callback
bool enablePrint
when we call print state, should the group properties be printed. default is false and we do not want...
virtual bool stepUpdate(CpuSNN *s, int step)
void resetSpikeCnt_GPU(int _startGrp, int _endGrp)
Utility function to clear spike counts in the GPU code.
bool newUpdates
FIXME this flag has mixed meaning and is not rechecked after the simulation is started.
void printPostConnection(FILE *fp=stdout)
print all the connections...
void readNetwork(FILE *fid)
reads the network state from file
void updateNetwork()
Original updateNetwork() function used by JMN.
short int MaxFiringRate
this is for the monitoring mechanism, it needs to know what is the maximum firing rate in order to al...
Iterator to loop over the scheduled spikes at a certain delay.
static const unsigned int MINOR_VERSION
minor release version, as in CARLsim 2.X
void writeNetwork(FILE *fid)
stores the pre and post synaptic neuron ids with the weight and delay
void updateNetwork_GPU(bool resetFiringInfo)
const_iterator beginSpikeTargetGroups(int stepOffset=0)
Returns an iterator to loop over all scheduled spike target groups.
void getPopWeights(int gIDpre, int gIDpost, float *&weights, int &size, int configId=0)
Writes weights from synaptic connections from gIDpre to gIDpost. Returns a pointer to the weights and...
void update(CpuSNN *s, int grpId, unsigned int *Nids, unsigned int *timeCnts, unsigned int total_spikes, float firing_Rate)
Controls actions that are performed when certain neurons fire (user-defined).
void printDotty()
prints a network graph using Dotty (GraphViz)
void setHomeostasis(int g, bool enable, int configId=0)
Sets the homeostasis parameters. g is the grpID, enable=true(false) enables(disables) homeostasis...
void scheduleSpikeTargetGroup(spikegroupid_t stg, delaystep_t delay)
Schedule a group of spike targets to get a spike at time t + delay.
void resetSpikeCntUtil(int grpId=-1)
Resets the spike count for a particular neuron group. Input: group ID variable named grpID...
void printSimSummary(FILE *fp=stdout)
prints a simulation summary to file
void writePopWeights(string fname, int gIDpre, int gIDpost, int configId=0)
function writes population weights from gIDpre to gIDpost to file fname in binary.
const_iterator endSpikeTargetGroups()
End iterator corresponding to beginSynapseGroups.
can be used to create a custom spike monitor
void setBaseFiring(int groupId, int configId, float _baseFiring, float _baseFiringSD)
Sets the homeostatic target firing rate. Neurons will try to attain this firing rate using homeostati...
void copyUpdateVariables_GPU()
int CurrTimeSlice
timeSlice is used by the Poisson generators in order to note generate too many or too few spikes with...
Contains all of CARLsim's core functionality.
void reassignFixedWeights(int connectId, float weightMatrix[], int matrixSize, int configId=ALL)
Reassigns fixed weights to values passed into the function in a single 1D float matrix called weightM...