00001 #include "MultiThreadSpikeScheduler.h"
00002
00003 MultiThreadSpikeScheduler::MultiThreadSpikeScheduler(
00004 int numThreads,
00005 MTSpikeRoutingTables &tables,
00006 vector<PropagatedSpikeBuffer*> &stBuffers,
00007 SimParameter &sp)
00008 : _numThreads(numThreads),
00009 rtables(tables),
00010 mTDelayMap(tables.mTDelayMap),
00011 tgtGrpPool(tables.stgPool),
00012 _simParam(sp),
00013 STbuffers(stBuffers),
00014 mTSpikeBuffers(numThreads, sp.minDelay.in_steps( sp.dt ), sp.maxDelay.in_steps( sp.dt ))
00015 {
00016
00017 int i;
00018
00019
00020 STschedulers.reserve(_numThreads);
00021 for (i = 0 ; i < _numThreads ; i++ ) {
00022 SingleThreadSpikeScheduler scheduler(rtables.localDelayMaps[i], tgtGrpPool, *STbuffers[i], _simParam);
00023 STschedulers.push_back(scheduler);
00024 }
00025
00026 nCycleSteps = _simParam.minDelay.in_steps( _simParam.dt );
00027
00028 engineSteps = new int[_numThreads];
00029
00030 for (i = 0 ; i < _numThreads ; i++ ) {
00031 engineSteps[i] = 0;
00032 }
00033 }
00034
00035 MultiThreadSpikeScheduler::~MultiThreadSpikeScheduler()
00036 {
00037 delete [] engineSteps;
00038 }
00039
00040 void MultiThreadSpikeScheduler::scheduleSpike(local_objectid_t localid, float offsetFraction, engineid_t engine)
00041 {
00042
00043 STschedulers[engine].scheduleSpike(localid, offsetFraction);
00044
00045
00046
00047 int last_dest_eng = mTDelayMap.lastDestEngine(engine, localid);
00048 for (int desteng = 0; desteng <= last_dest_eng; ++desteng) {
00049 NodeLocalMultiTargetDelayMap::const_iterator delay_iter = mTDelayMap.beginDelays(engine, localid, desteng);
00050 NodeLocalMultiTargetDelayMap::const_iterator delay_end_iter = mTDelayMap.endDelays(engine, localid, desteng);
00051 while (delay_iter != delay_end_iter) {
00052
00053 mTSpikeBuffers.buffers[desteng][engine]->scheduleSpikeTargetGroup(delay_iter->second, delay_iter->first + engineSteps[engine], offsetFraction);
00054 ++delay_iter ;
00055 }
00056 }
00057 }
00058
00059 void MultiThreadSpikeScheduler::advance(engineid_t engine)
00060 {
00061 STschedulers[engine].advance();
00062 engineSteps[engine] ++;
00063 }
00064
00065 void MultiThreadSpikeScheduler::reset()
00066 {
00067
00068 for (int i = 0; i < _numThreads; ++i ) {
00069 for (int j = 0; j < _numThreads; ++j ) {
00070 mTSpikeBuffers.buffers[i][j]->reset(_simParam.minDelay.in_steps( _simParam.dt ), _simParam.maxDelay.in_steps( _simParam.dt ));
00071 }
00072
00073 engineSteps[i] = 0;
00074
00075
00076 STschedulers[i].reset();
00077 }
00078 }
00079
00080 void MultiThreadSpikeScheduler::nextCycle()
00081 {
00082 int eSteps = engineSteps[0] ;
00083 for (int i = 0; i < _numThreads; ++i ) {
00084 for (int j = 0; j < _numThreads; ++j ) {
00085
00086
00087 for (int k = 0 ; k < eSteps ; ++k ) {
00088
00089 mTSpikeBuffers.buffers[i][j]->nextTimeStep();
00090 }
00091 }
00092
00093 engineSteps[i] = 0;
00094 }
00095 }
00096
00097 void MultiThreadSpikeScheduler::deliverSpikes(SpikeReceiverList &listActiveSynapses,
00098 engineid_t engine = 0, double simTime = -1, int stepOffset)
00099 {
00100 PropagatedSpikeBuffer::const_iterator srg_iter;
00101 PropagatedSpikeBuffer::const_iterator srg_iter_end;
00102
00103 SpikeTargetGroupPool::const_iterator target_syn_iter;
00104 SpikeTargetGroupPool::const_iterator target_syn_iter_end;
00105
00106 STschedulers[engine].deliverSpikes(listActiveSynapses, engine, simTime, stepOffset);
00107
00108 SpikeEvent spike( simTime, 1.0, 1.0, _simParam.dt );
00109
00110 for (int srceng = 0 ; srceng < _numThreads ; ++srceng) {
00111
00112 srg_iter_end = mTSpikeBuffers.buffers[engine][srceng]->endSpikeTargetGroups(stepOffset+engineSteps[engine]);
00113 for (srg_iter = mTSpikeBuffers.buffers[engine][srceng]->beginSpikeTargetGroups(stepOffset+engineSteps[engine]);
00114 srg_iter != srg_iter_end; ++srg_iter) {
00115
00116 target_syn_iter_end = tgtGrpPool.endSpikeTargetGroup(*srg_iter);
00117 for (target_syn_iter = tgtGrpPool.beginSpikeTargetGroup(*srg_iter); target_syn_iter != target_syn_iter_end; ++target_syn_iter ) {
00118
00119
00120 spike.delta = _simParam.dt.in_sec() * srg_iter->offsetFraction;
00121 if( ( target_syn_iter->receiver->spikeHit( target_syn_iter->port, spike ) ) & SPIKEHITFLAG_ACTIVATE ) {
00122 listActiveSynapses.push_back( target_syn_iter->receiver );
00123 SimObject *obj = target_syn_iter->receiver;
00124 while ( (obj = obj->getChainedObject()) != NULL) {
00125 if (obj->toBeActivated()) listActiveSynapses.push_back( obj );
00126 }
00127 }
00128 }
00129 }
00130 }
00131 }