diff options
Diffstat (limited to 'code/core/simulate.cpp')
-rw-r--r-- | code/core/simulate.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/code/core/simulate.cpp b/code/core/simulate.cpp new file mode 100644 index 0000000..69252bb --- /dev/null +++ b/code/core/simulate.cpp @@ -0,0 +1,134 @@ +#include <utility> +#include <map> +#include <signal.h> + +#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<double, double>(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<int, int>::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; +} |