Main Page | Namespace List | Alphabetical List | Class List | Directories | File List | Class Members | File Members

SpikeStreamSimulation.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   SpikeStream Simulation                                                *
00003  *   Copyright (C) 2007 by David Gamez                                     *
00004  *   david@davidgamez.eu                                                   *
00005  *   Version 0.1                                                           *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 
00023 #ifndef SPIKESTREAMSIMULATION_H
00024 #define SPIKESTREAMSIMULATION_H
00025 
00026 //SpikeStream includes
00027 #include "DBInterface.h"
00028 #include "Neuron.h"
00029 #include "Synapse.h"
00030 #include "TaskHolder.h"
00031 #include "DeviceManager.h"
00032 #include "PatternManager.h"
00033 #include "ClassLoader.h"
00034 #include "SimulationClock.h"
00035 #include "PerformanceTimer.h"
00036 
00037 //Other includes
00038 #include <stack>
00039 #include <google/dense_hash_map> 
00040 using HASH_NAMESPACE::hash;
00041 using GOOGLE_NAMESPACE::dense_hash_map;
00042 
00043 
00044 /*! Struct to hold messages that arrive early out of sequence.*/
00045 struct EarlyMessage {
00046         int senderTID;
00047         int bufferID;
00048         int timeStep;
00049 };
00050 
00051 
00052 /*! Struct to hold statistics about simulation.*/
00053 struct Statistics {
00054         int startTimeStep;
00055         int neuronFireTotal;
00056         int spikeTotal;
00057 };
00058 
00059 
00060 //---------------------- SpikeStream Simulation ----------------------------
00061 /*! The main class for the control of the simulation. This class is spawned 
00062         from an initiating parent class which acts as the central node for the 
00063         simulation. Each instance of this class is responsible for simulating 
00064         part of the neural network - generally a neuron group. */
00065 
00066 /* FIXME AT SOME POINT SPLIT THIS HUGE CLASS UP INTO SUB CLASSES, SUCH AS
00067         NEURON MANAGER, SYNAPSE MANAGER MESSAGE HANDLER ETC. */
00068 //--------------------------------------------------------------------------
00069 
00070 class SpikeStreamSimulation {
00071 
00072         public:
00073                 SpikeStreamSimulation();
00074                 SpikeStreamSimulation(int argc, char **argv);
00075                 ~SpikeStreamSimulation();
00076                 static unsigned int getNeuronGrpID();
00077                 static void systemError(const char* message);
00078                 static void systemError(const string &message);
00079                 static void systemError_double(const string &message, double messageData1);
00080                 static void systemError_int(const string &message, int messageData1);
00081                 static void systemError(const char *message, int messageData1);
00082                 static void systemInfo(const char *message);
00083                 static void systemInfo(const char *message, bool messageData1);
00084                 static void systemInfo(const char *message, int messageData1);
00085 
00086 
00087                 //======================== PUBLIC VARIABLES ======================
00088                 /*! Clock for the simulation.*/
00089                 static SimulationClock *simulationClock;
00090 
00091         
00092                 #ifdef RECORD_STATISTICS
00093 
00094                         /*! Period in microseconds in over which statistics are gathered 
00095                                 before simulation is stopped.*/
00096                         #define STATS_MONITORING_PERIOD 300000000
00097 
00098                         /*! Struct to hold statistics.*/
00099                         static Statistics statistics;
00100 
00101                         /*! Timer for monitoring period.*/
00102                         PerformanceTimer statisticsTimer;
00103 
00104                 #endif//RECORD_STATISTICS
00105                 
00106         
00107 
00108         private:
00109                 //========================= VARIABLES ============================
00110                 /*! Task ID of this task.*/
00111                 static int thisTaskID;
00112                 
00113                 /*! Task ID of the task that spawned this task.*/
00114                 static int parentTaskID;
00115 
00116                 /*! In the run method this controls whether the simulation should stop.*/
00117                 bool stop;
00118 
00119                 /*! When the simulation has an error it enters error state, waits 
00120                         for an exit message and then exits. This is to enable the Simulation 
00121                         Manager to clean up properly.*/
00122                 static bool errorState;
00123                 
00124                 /*! Records whether all of the simulation data has been loaded.*/
00125                 bool simulationDataLoaded;
00126 
00127                 /*! Records whether the initial messages have been sent so that 
00128                         simulation can keep running.*/
00129                 bool simulationStarted;
00130 
00131                 /*! Records whether the simulation is running or not.*/
00132                 bool simulationRunning;
00133                 
00134                 /*! ID of the neuron group that is being simulated by this task.*/
00135                 static unsigned int neuronGrpID;
00136                 
00137                 /*! The type of neuron that is being simulated. This corresponds
00138                         to an entry in the NeuronTypes database and a class library
00139                         dynamically loaded at run time.*/
00140                 unsigned short neuronType;
00141                 
00142                 /*! Map holding all of the synapses. The key in the outer dense_hash_map
00143                         is the from neuron ID. The key in the inner dense_hash_map is the to 
00144                         neuron id. References to neurons are held within each synapse.*/
00145                 dense_hash_map<unsigned int, dense_hash_map<unsigned int, Synapse*, hash<unsigned int> >*, hash<unsigned int> > synapseMap;
00146 
00147                 /*! Map holding the synapse parameters for each of the connection groups
00148                         Key is the connection group id.*/
00149                 map<unsigned int, map<string, double>* > connParameterMap;
00150                 
00151                 /*! Array of all the neurons - held as references
00152                         Although the neuron references are also held in the synapses they need to be 
00153                         updated once all the post synaptic membrane potentials have been calculated.*/
00154                 Neuron** neuronArray;
00155                 
00156                 /*! Records the id of the first neuron in the group. Used to access a
00157                         neuron by neuronID in the neuronArray.*/
00158                 unsigned int startNeuronID;
00159                 
00160                 /*! Size of the neuron array.*/
00161                 unsigned int numberOfNeurons;
00162 
00163                 /*! Width of the neuron group being simulated by this task.*/
00164                 unsigned int neuronGrpWidth;
00165 
00166                 /*! Length of the neuron group being simulated by this task.*/
00167                 unsigned int neuronGrpLength;
00168 
00169                 /*! Keeps track of how many spike messages have been received. The spike list is sent
00170                         when all spike messages have been received from other tasks.*/
00171                 unsigned int spikeMessageCount;
00172 
00173                 /*! The sum of the taskIDs of the tasks that will be sending spike messages 
00174                         to this task within each update cycle.*/
00175                 unsigned int spikeMessageTotal;
00176                 
00177                 /*! Map holding references to all the task holders that handle spike
00178                         messages. Each task holder class is responsible for sending spikes 
00179                         to a particular task and any additional monitoring tasks
00180                         as well. Neurons hold a list of spike task holders that they use to 
00181                         add their spikes to the spike buffers held in this class.
00182                         The key of this map is the destinationTaskID.
00183                         The data of this map is the TaskHolder that sends messages.*/
00184                 map<int, TaskHolder*> spikeTaskHolderMap;
00185 
00186                 /*! Reference to a neuron task holder that holds the list of firing
00187                         neurons in this simulation and sends messages to any task that
00188                         want this information.*/
00189                 NeuronTaskHolder *neuronTaskHolder;
00190                 
00191                 /*! Holds the link between a connection group and a task.
00192                         The key is the connGrpID; the data is the taskID.*/
00193                 map<unsigned int, int> taskConnGrpMap;
00194 
00195                 /*! Holds the link between neuronGrpID and task ID
00196                         The key is the neuronGrpID; the data is the taskID.*/
00197                 map<unsigned int, int> taskNeurGrpMap;
00198 
00199                 /*! Holds the start neuron ID for each task processing neurons 
00200                         The key is the task id, the data is the start neuron id of that
00201                         neuron group.*/
00202                 map<int, unsigned int> startNeurIDTaskMap;
00203 
00204                 /*! Defines what type of simulation is being run in this task.
00205                         These are defined in SimulationTypes.h.*/
00206                 unsigned int simulationType;
00207                 
00208                 //References to the classes that handle database access
00209                 DBInterface *networkDBInterface;
00210                 DBInterface *patternDBInterface;
00211                 DBInterface *deviceDBInterface;
00212 
00213                 /*! Reference to class for handling devices.*/
00214                 DeviceManager *deviceManager;
00215 
00216                 /*! Reference to class for handling patterns.*/
00217                 PatternManager *patternManager;
00218 
00219                 /*! Reference to class loader, which is used to create new neurons 
00220                         and synapses by dynamically loading them from libraries.*/
00221                 ClassLoader *classLoader;
00222 
00223                 /*! How many time steps each pattern will be presented for.*/
00224                 unsigned int timeStepsPerPattern;
00225                 
00226                 /*! Used for synchronization - sets whether this layer has
00227                         delayed itself in the last time step.*/
00228                 bool delayInLastTimeStep;
00229 
00230                 /*! Holds the messages received one time step out of sequence.*/
00231                 stack<EarlyMessage> earlyMessageStack;
00232 
00233                 /*! Controls how the task id is displayed.*/
00234                 static const bool printTIDHex = true;
00235 
00236                 /*! Map holding all the neurons that have received a spike during this timestep
00237                         Neurons in this map are updated when all spikes have been received 
00238                         Map is used rather than vector to avoid filtering out multiple spikes
00239                         to the same neuron. The key is the full neuronID.*/
00240                 dense_hash_map<unsigned int, bool, hash<unsigned int> > neuronUpdateMap;
00241 
00242                 /*! Used to calculate the from neuron id from spike messages
00243                         stored here to avoid constant redeclaration.*/
00244                 unsigned int unpkFromNeurID;
00245 
00246                 /*! Used to calculate the to neuron id from spike messages
00247                         stored here to avoid constant redeclaration.*/
00248                 unsigned int unpkToNeurID;
00249 
00250                 /*! Array to unpack the list of spikes into.*/
00251                 unsigned int* unpackArray;
00252 
00253                 /*! Used to get information about PVM functions. Stored here both to save
00254                         redelcaring it and because it is sometimes not used when PVM_DEBUG is not
00255                         set and so generates a warning.*/
00256                 int info;
00257 
00258                 /*! Determines whether the compute time for each timestep is calculated.*/
00259                 bool calculateComputeTime;
00260 
00261                 /*! Time structure to measure how long each processing loop takes.*/
00262                 timeval startComputeTimeStruct;
00263 
00264                 /*! Time structure to measure how long each processing loop takes.*/
00265                 timeval endComputeTimeStruct;
00266 
00267                 /*! Time taken for each time step.*/
00268                 unsigned int timeStepComputeTime_us;
00269 
00270                 /*! The minimum time step duration. Used to slow the simulation down.*/
00271                 unsigned int minTimeStepDuration_us;
00272 
00273                 /*! Controls whether noise is injected into the neurons.*/
00274                 bool noiseEnabled;
00275 
00276                 /*! Percent of neurons fired at each time step by noise function.*/
00277                 double percentNeurons_noise;
00278 
00279                 /*! Set to true when the percentage of neurons selected for noise is random.*/
00280                 bool randomPercentNoise;
00281 
00282                 /*! Are the noise neurons fired directly or by injecting synaptic current?.*/
00283                 bool directFiring_noise;
00284 
00285                 /*! Amount of synaptic current used for neurons fired by noise.*/
00286                 double synapticWeight_noise;
00287 
00288                 /*! Controls whether all neuron classes are updated at each time step.*/
00289                 bool updateAllNeurons;
00290 
00291                 /*! Controls whether all synapse classes are updated at each time step.*/
00292                 bool updateAllSynapses;
00293 
00294                 /*! Controls whether we are sending neuron data back to the main application
00295                         for monitoring purposes.*/
00296                 bool neuronMonitorMode;
00297 
00298                 /*! The neurons that are being monitored. Use map to filter out duplicates.*/
00299                 dense_hash_map<unsigned int, bool, hash<unsigned int> >  neuronMonitorMap;
00300 
00301                 /*! Controls whether we are sending synapse data back to the main application
00302                         for monitoring purposes.*/
00303                 bool synapseMonitorMode;
00304 
00305                 /*! Map holding reference to the synapses that are being monitored. The key is 
00306                         an unsigned int array that is dynamically allocated on the heap.*/
00307                 map<unsigned int*, Synapse*, synapseKeyCompare> synapseMonitorMap;
00308 
00309 
00310                 //======================== METHODS ==============================
00311                 /*! Declare copy constructor private so it cannot be used inadvertently.*/
00312                 SpikeStreamSimulation (const SpikeStreamSimulation&);
00313 
00314                 /*! Declare assignment private so it cannot be used.*/
00315                 SpikeStreamSimulation operator = (const SpikeStreamSimulation&);
00316 
00317                 void addReceivingTask_Neurons(int taskID);
00318                 void addReceivingTask_Spikes(int taskID);
00319                 void addTaskIDToDatabase();
00320                 void cleanUpSimulation();
00321                 void fireRandomNeurons(double noiseAmount);
00322                 void fireRandomNeurons_synaptic(double noiseAmount);
00323                 void fireSpecifiedNeurons();
00324                 double getRandomPercentage();
00325                 void injectNoise();
00326                 bool loadGlobalParameters();
00327                 bool loadNeuronParameters();
00328                 void loadNeurons();
00329                 bool loadNoiseParameters();
00330                 void loadPreSynapticNeuronMaps();
00331                 void loadSimulationData();
00332                 bool loadSynapseParameters();
00333                 void loadSynapses();
00334                 void loadTasks();
00335                 void printSynapseMap();
00336                 static void printTID();
00337                 static void printTID(int taskID);
00338                 void processSpikeList(unsigned int senderTID, int msgTimeStep);
00339                 void reloadWeights();
00340                 void removeReceivingTask_Neurons(int removeTaskID);
00341                 void removeReceivingTask_Spikes(int removeTaskID);
00342                 void run();
00343                 void saveViewWeights();
00344                 void saveWeights();
00345                 static bool sendMessage(int taskID, int msgtag);//Static so it can be called from systemError()
00346                 static bool sendMessage(int taskID, int msgtag, const char* msgdata);//Static so it can be called from systemError()
00347                 static bool sendMessage(int taskID, int msgtag, unsigned int data1, const char* msgdata);
00348                 bool sendMessage(int taskID, int msgtag, unsigned int data1, unsigned int data2, const char* msgdata);
00349                 bool sendNeuronData(int taskID, int msgtag, unsigned int neuronID, double* dataArray, int arrayLength);
00350                 void sendSpikeMessages();
00351                 bool sendSynapseData(int taskID, int msgtag, unsigned int fromNeurID, unsigned int toNeurID, double* dataArray, int arrayLength);
00352                 void setDelayInLastTimeStep(bool dly);
00353                 void setMaxBufferSize();
00354                 void setMinTimeStepDuration(int senderTID);
00355                 void setUpdateMode(int senderTID);
00356                 void startNeuronMonitoring(int senderTID, bool restart);
00357                 void startSimulation();
00358                 void startSynapseMonitoring(int senderTID, bool restart);
00359                 void stepSimulation();
00360                 void stopSimulation();
00361                 void stopNeuronMonitoring(int senderTID);
00362                 void stopSynapseMonitoring(int senderTID);
00363 
00364 };
00365 
00366 
00367 #endif//SPIKESTREAMSIMULATION_H
00368 

Generated on Mon Sep 3 22:24:34 2007 for SpikeStream Simulation by  doxygen 1.4.4