/***************************************************************************
* TimeDrivenInternalSpike.cpp *
* ------------------- *
* copyright : (C) 2014 by Francisco Naveros *
* email : fnaveros@ugr.es *
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "../../include/spike/TimeDrivenInternalSpike.h"
#include "../../include/spike/Interconnection.h"
#include "../../include/spike/Neuron.h"
#include "../../include/spike/PropagatedSpike.h"
#include "../../include/spike/TimeDrivenPropagatedSpike.h"
#include "../../include/spike/NeuronModelPropagationDelayStructure.h"
#include "../../include/neuron_model/VectorNeuronState.h"
#include "../../include/neuron_model/NeuronModel.h"
#include "../../include/neuron_model/EventDrivenNeuronModel.h"
#include "../../include/simulation/Simulation.h"
#include "../../include/simulation/EventQueue.h"
#include "../../include/communication/OutputSpikeDriver.h"
#include "../../include/learning_rules/LearningRule.h"
#include "../../include/spike/Neuron.h"
#include "../../include/openmp/openmp.h"
TimeDrivenInternalSpike::TimeDrivenInternalSpike(double NewTime, VectorNeuronState * NewState, NeuronModelPropagationDelayStructure * NewPropagationStructure, Neuron ** NewNeurons, int NewOpenMP_index) : Spike(NewTime, NULL), State(NewState), PropagationStructure(NewPropagationStructure), Neurons(NewNeurons), OpenMP_index(NewOpenMP_index){
timeDrivenPropagatedSpike=(TimeDrivenPropagatedSpike***) new TimeDrivenPropagatedSpike ** [NumberOfOpenMPQueues];
for(int i=0; i<NumberOfOpenMPQueues; i++){
timeDrivenPropagatedSpike[i]=(TimeDrivenPropagatedSpike**)new TimeDrivenPropagatedSpike**[PropagationStructure->GetSize(i)];
for(int j=0; j<PropagationStructure->GetSize(i); j++){
timeDrivenPropagatedSpike[i][j]=new TimeDrivenPropagatedSpike(NewTime+PropagationStructure->GetDelayAt(i,j),i, PropagationStructure->GetEventSize(i, j));
}
}
}
TimeDrivenInternalSpike::~TimeDrivenInternalSpike(){
for(int i=0; i<NumberOfOpenMPQueues; i++){
delete timeDrivenPropagatedSpike[i];
}
delete timeDrivenPropagatedSpike;
}
void TimeDrivenInternalSpike::ProcessInternalSpikeEvent(Simulation * CurrentSimulation, int index){
Neuron * neuron = Neurons[index];
this->SetSource(neuron);
CurrentSimulation->IncrementTotalSpikeCounter( neuron->get_OpenMP_queue_index());
CurrentSimulation->WriteSpike(this);
CurrentSimulation->WriteState(neuron->GetVectorNeuronState()->GetLastUpdateTime(neuron->GetIndex_VectorNeuronState()), neuron);
// Generate the output activity
for (int i = 0; i<NumberOfOpenMPQueues; i++){
for (int j=0; j<neuron->PropagationStructure->NDifferentDelays[i]; j++){
int index=neuron->PropagationStructure->IndexSynapseDelay[i][j];
//Include the new source and checks if the TimeDrivenPropagatedSpike event is full
if(timeDrivenPropagatedSpike[i][index]->IncludeNewSource(neuron->PropagationStructure->NSynapsesWithEqualDelay[i][j],neuron->PropagationStructure->OutputConnectionsWithEquealDealy[i][j])){
if (i == this->OpenMP_index){
CurrentSimulation->GetQueue()->InsertEvent(i, timeDrivenPropagatedSpike[i][index]);
}
else{
CurrentSimulation->GetQueue()->InsertEventInBuffer(this->OpenMP_index, i, timeDrivenPropagatedSpike[i][index]);
}
//Create a new TimeDrivenPropagatedSpike event
PropagationStructure->IncrementEventSize(i, index);
timeDrivenPropagatedSpike[i][index]=new TimeDrivenPropagatedSpike(timeDrivenPropagatedSpike[i][index]->GetTime(),i,PropagationStructure->GetEventSize(i, index));
}
}
}
if (neuron->GetInputNumberWithPostSynapticLearning()>0){
#ifdef _OPENMP
#if _OPENMP >= OPENMPVERSION30
#pragma omp task
#endif
#endif
{
for (int i = 0; i < neuron->GetInputNumberWithPostSynapticLearning(); ++i){
Interconnection * inter = neuron->GetInputConnectionWithPostSynapticLearningAt(i);
inter->GetWeightChange_withPost()->ApplyPostSynapticSpike(inter, this->time);
}
}
}
}
void TimeDrivenInternalSpike::ProcessEvent(Simulation * CurrentSimulation, int RealTimeRestriction){
if(RealTimeRestriction<2){
//CPU write in this array if an internal spike must be generated.
bool * generateInternalSpike = State->getInternalSpike();
Neuron * Cell;
//We check if some neuron inside the model is monitored
if (State->Get_Is_Monitored()){
for (int t = 0; t<State->GetSizeState(); t++){
Cell = Neurons[t];
if (generateInternalSpike[t] == true){
ProcessInternalSpikeEvent(CurrentSimulation, t);
}
if (Cell->IsMonitored()){
CurrentSimulation->WriteState(this->GetTime(), Cell);
}
}
}
else{
for (int t = 0; t<State->GetSizeState(); t++){
if (generateInternalSpike[t] == true){
Cell = Neurons[t];
ProcessInternalSpikeEvent(CurrentSimulation, t);
}
}
}
for (int i = 0; i<NumberOfOpenMPQueues; i++){
for (int j=0; j<this->PropagationStructure->GetSize(i); j++){
//Check if the each TimeDrivenPropagatedSpike event is empty.
if(timeDrivenPropagatedSpike[i][j]->GetN_Elementes()>0){
if (i == this->OpenMP_index){
CurrentSimulation->GetQueue()->InsertEvent(i, timeDrivenPropagatedSpike[i][j]);
}
else{
CurrentSimulation->GetQueue()->InsertEventInBuffer(this->OpenMP_index, i, timeDrivenPropagatedSpike[i][j]);
}
}else{
delete timeDrivenPropagatedSpike[i][j];
}
}
}
#ifdef _OPENMP
#if _OPENMP >= OPENMPVERSION30
#pragma omp taskwait
#endif
#endif
}
}
void TimeDrivenInternalSpike::ProcessEvent(Simulation * CurrentSimulation){
//CPU write in this array if an internal spike must be generated.
bool * generateInternalSpike = State->getInternalSpike();
Neuron * Cell;
//We check if some neuron inside the model is monitored
if (State->Get_Is_Monitored()){
for (int t = 0; t<State->GetSizeState(); t++){
Cell = Neurons[t];
if (generateInternalSpike[t] == true){
ProcessInternalSpikeEvent(CurrentSimulation, t);
}
if (Cell->IsMonitored()){
CurrentSimulation->WriteState(this->GetTime(), Cell);
}
}
}
else{
for (int t = 0; t<State->GetSizeState(); t++){
if (generateInternalSpike[t] == true){
Cell = Neurons[t];
ProcessInternalSpikeEvent(CurrentSimulation, t);
}
}
}
for (int i = 0; i<NumberOfOpenMPQueues; i++){
for (int j=0; j<this->PropagationStructure->GetSize(i); j++){
//Check if the each TimeDrivenPropagatedSpike event is empty.
if(timeDrivenPropagatedSpike[i][j]->GetN_Elementes()>0){
if (i == this->OpenMP_index){
CurrentSimulation->GetQueue()->InsertEvent(i, timeDrivenPropagatedSpike[i][j]);
}
else{
CurrentSimulation->GetQueue()->InsertEventInBuffer(this->OpenMP_index, i, timeDrivenPropagatedSpike[i][j]);
}
}else{
delete timeDrivenPropagatedSpike[i][j];
}
}
}
#ifdef _OPENMP
#if _OPENMP >= OPENMPVERSION30
#pragma omp taskwait
#endif
#endif
}
void TimeDrivenInternalSpike::PrintType(){
cout<<"TimeDrivenInternalSpike"<<endl;
}
//TimeDrivenInternalSpike::TimeDrivenInternalSpike(double NewTime, VectorNeuronState * NewState, Neuron ** NewNeurons, int NewOpenMP_index) : Spike(NewTime, NULL), State(NewState), Neurons(NewNeurons), OpenMP_index(NewOpenMP_index){
//}
//
//TimeDrivenInternalSpike::~TimeDrivenInternalSpike(){
//}
//
//void TimeDrivenInternalSpike::ProcessInternalSpikeEvent(Simulation * CurrentSimulation, int index){
// Neuron * neuron = Neurons[index];
// this->SetSource(neuron);
// CurrentSimulation->IncrementTotalSpikeCounter( neuron->get_OpenMP_queue_index());
//
// CurrentSimulation->WriteSpike(this);
// CurrentSimulation->WriteState(neuron->GetVectorNeuronState()->GetLastUpdateTime(neuron->GetIndex_VectorNeuronState()), neuron);
//
//
// // Generate the output activity
// for (int i = 0; i<NumberOfOpenMPQueues; i++){
// if (neuron->IsOutputConnected(i)){
// PropagatedSpike * spike = new PropagatedSpike(this->GetTime() + neuron->SynapseDelays[i][0], neuron, 0, i);
// if(i==neuron->get_OpenMP_queue_index()){
// CurrentSimulation->GetQueue()->InsertEvent(i,spike);
// }else{
// CurrentSimulation->GetQueue()->InsertEventInBuffer(omp_get_thread_num(),i,spike);
// }
// }
// }
//
// if (neuron->GetInputNumberWithPostSynapticLearning()>0){
// #ifdef _OPENMP
// #if _OPENMP >= OPENMPVERSION30
// #pragma omp task
// #endif
// #endif
//
// {
// for (int i = 0; i < neuron->GetInputNumberWithPostSynapticLearning(); ++i){
// Interconnection * inter = neuron->GetInputConnectionWithPostSynapticLearningAt(i);
// inter->GetWeightChange_withPost()->ApplyPostSynapticSpike(inter, this->time);
// }
// }
//
// }
//}
//
//void TimeDrivenInternalSpike::ProcessEvent(Simulation * CurrentSimulation, int RealTimeRestriction){
//
// if(RealTimeRestriction<2){
//
// //CPU write in this array if an internal spike must be generated.
// bool * generateInternalSpike = State->getInternalSpike();
//
// Neuron * Cell;
//
// //We check if some neuron inside the model is monitored
// if (State->Get_Is_Monitored()){
// for (int t = 0; t<State->GetSizeState(); t++){
// Cell = Neurons[t];
// if (generateInternalSpike[t] == true){
// ProcessInternalSpikeEvent(CurrentSimulation, t);
// }
// if (Cell->IsMonitored()){
// CurrentSimulation->WriteState(this->GetTime(), Cell);
// }
// }
// }
// else{
// for (int t = 0; t<State->GetSizeState(); t++){
// if (generateInternalSpike[t] == true){
// Cell = Neurons[t];
// ProcessInternalSpikeEvent(CurrentSimulation, t);
// }
// }
//
// }
//
// #ifdef _OPENMP
// #if _OPENMP >= OPENMPVERSION30
// #pragma omp taskwait
// #endif
// #endif
// }
//}
//
//void TimeDrivenInternalSpike::ProcessEvent(Simulation * CurrentSimulation){
//
// //CPU write in this array if an internal spike must be generated.
// bool * generateInternalSpike = State->getInternalSpike();
//
// Neuron * Cell;
//
// //We check if some neuron inside the model is monitored
// if (State->Get_Is_Monitored()){
// for (int t = 0; t<State->GetSizeState(); t++){
// Cell = Neurons[t];
// if (generateInternalSpike[t] == true){
// ProcessInternalSpikeEvent(CurrentSimulation, t);
// }
// if (Cell->IsMonitored()){
// CurrentSimulation->WriteState(this->GetTime(), Cell);
// }
// }
// }
// else{
// for (int t = 0; t<State->GetSizeState(); t++){
// if (generateInternalSpike[t] == true){
// Cell = Neurons[t];
// ProcessInternalSpikeEvent(CurrentSimulation, t);
// }
// }
//
// }
//
// #ifdef _OPENMP
// #if _OPENMP >= OPENMPVERSION30
// #pragma omp taskwait
// #endif
// #endif
//}
//
//void TimeDrivenInternalSpike::PrintType(){
// cout<<"TimeDrivenInternalSpike"<<endl;
//}