#include #include #include #include "model_switch.h" #include "synapse.h" #include "neuron.h" #include "topology.h" #include "reward.h" #include "tracepoints.h" #include "fileutils.h" #include "log.h" #include "simulate.h" // include cpp files to allow all otpimizations to take place across all files #include "synapse.cpp" #include "neuron.cpp" #include "topology.cpp" #include "fileutils.cpp" #include "event.cpp" #include "reward.cpp" #include "bin.cpp" #include "tracepoints.cpp" // should be excluded to speed up compilation Simulation::Simulation() : // debug related stuff #ifdef DEBUG_STATUSLINE numSpikes(0), charCount(0), #endif // init globals currentTime(0.0), { // set the initial dopamin level da_history.push_front(pair(0.0, g.dopamin_level)); } bool Simulation::Step() { // check if there are pending events if (pendingSpikes.empty()) return false; // retrieve and check next event Event *e = pendingSpikes.top(); pendingSpikes.pop(); // proceed to the new time if (currentTime > e->time) DIE("tried to execute event of the past"); currentTime = e->time; #ifdef DEBUG_STATUSLINE if (numSpikes % 16384 == 0) { // remove old line while (charCount-- > 0) fprintf(stderr, " "); fprintf(stderr, "\r"); // print new line charCount += fprintf(stderr, "%f s, %d, %lld events (%d\tpending:", e->type, currentTime, numSpikes, pendingSpikes.size()); for (map::iterator i = eventCount.begin(); i != eventCount.end(); i++) { charCount += fprintf(stderr, "\t%d: %d", i->first, i->second); charCount += 7; // tab } charCount += fprintf(stderr, ")\r"); charCount += 7; // tab } fflush(stderr); numSpikes++; eventCount[e->type]--; #endif // execute event e->execute(); e->free(); return true; } bool Simulation::proceedTime(double targetTime) { // insert an intrinsic event for each neuron to have it computed up to exactly targetTime for (int i=0; i < numNeurons; i++) { addEvent(new IntrinsicNeuron(targetTime, i)); } // proceed until no event is left before the time-point to be reached // then also currentTime == targetTime holds while (!pendingSpikes.empty() && (pendingSpikes.top()-> time <= targetTime)) { Step(); } // check if there are events left ... with the new event system this should always be the case // and does not anymore indicate that the network is alive return !pendingSpikes.empty(); } void Simulation::addEvent(Event *e) { pendingSpikes.push(e); #ifdef DEBUG_STATUSLINE eventCount[e->type]++; #endif } void initStaticVars() { Synapse::numSynapses = 0; } int main(int argc, char **argv) { // ignore broken pipe signals (they should be handled by stdio file handlers and our usual error functions) signal(SIGPIPE, SIG_IGN); initStaticVars(); // load the network // tp_load(s.fd_isynapse); // neuron_load(s.fd_ineuron); // init services implemented via events by adding one of them to the event population s.addEvent(new ExternalNoise(0.0)); s.addEvent(new Reward(0.0)); // check for autoexciting events (and init neurons btw) s.proceedTime(0.0); // pass control to the tracepoint parser // this allows to run the simulation interactively executeTracepoints(s.fd_trace, s.fd_ispike, s.fd_iglobal); return 0; }