00001 #include "SingleThreadSimEngine.h"
00002
00003 #include "SpikeSender.h"
00004 #include "SimNetwork.h"
00005 #include "SimObjectRegistry.h"
00006
00007 #include <algorithm>
00008 using std::make_heap;
00009 using std::sort_heap;
00010
00011 #include <iostream>
00012 using std::cout;
00013 using std::endl;
00014 using std::cerr;
00015
00016 SingleThreadSimEngine::SingleThreadSimEngine(int ID, SpikeScheduler &scheduler, AnalogMessageDispatcher &analogMsgDispatcher, SimNetwork &net):
00017 SimEngine(ID,scheduler, net),
00018 activeSpikeReceiver(0), t( Time::ms(0) ), step(0), dtHasChanged(false),
00019 initialized(false),
00020 isReset(false),
00021 objectListsDirty(true),
00022 analog_msg_dispatcher(analogMsgDispatcher),
00023 objPool(20),
00024 nSpikeOutputPorts(0)
00025 {
00026
00027 noiseRNDEngine = new ThreadSpecificRandomEngineType;
00028 noiseRNDEngine->seed( net.simParameter().simulationRNGSeed );
00029
00030 }
00031
00032 SingleThreadSimEngine::~SingleThreadSimEngine()
00033 {
00034 theThreadSpecificRandomEngine.unset( noiseRNDEngine );
00035 delete noiseRNDEngine;
00036 }
00037
00038 void SingleThreadSimEngine::seed( vector<uint32> const& noiseSeed )
00039 {
00040 noiseRNDEngine->seed( noiseSeed[0] );
00041 }
00042
00043 void SingleThreadSimEngine::seed( uint32 noiseSeed )
00044 {
00045 noiseRNDEngine->seed( noiseSeed );
00046 }
00047
00048 void SingleThreadSimEngine::addObject( SimObjectFactory const& objFactory, SimObject::ID &id )
00049 {
00050 objectListsDirty = true;
00051 id.type = objFactory.getObjectTypeID();
00052 id.localid = objPool.addObject( objFactory, network.getObjectVariationRNDEngine() );
00053 addSpikePorts( objPool.getObject( id.type, id.localid ), id );
00054 }
00055
00056 void SingleThreadSimEngine::addSpikePorts( SimObject *obj, SimObject::ID &id )
00057 {
00058 SingleOutputSpikeSender *single_out = dynamic_cast< SingleOutputSpikeSender *>( obj );
00059 if( single_out != NULL ) {
00060 single_out->getSpikePort()->setID( (spike_port_id_t)nSpikeOutputPorts );
00061 nSpikeOutputPorts++;
00062 } else {
00063 MultipleOutputSpikeSender *multi_out = dynamic_cast< MultipleOutputSpikeSender *>( obj );
00064 if( multi_out != NULL ) {
00065 for( int p = 0; p < ( obj->nSpikeOutputPorts() + obj->nAnalogOutputPorts() ); p++ ) {
00066 if( obj->outputPortType( p ) == SimObject::spiking ) {
00067 multi_out->getSpikePort(p)->setID( nSpikeOutputPorts );
00068 nSpikeOutputPorts++;
00069 }
00070 }
00071 }
00072 }
00073 }
00074
00075 void SingleThreadSimEngine::mount( const SimObjectFactory &objFactory, const SimObject::ID &mountpoint, SimObject::ID &gid )
00076 {
00077 addObject( objFactory, gid );
00078 one_way_link( gid, mountpoint );
00079 }
00080
00081 void SingleThreadSimEngine::insert( const SimObjectFactory &objFactory, const SimObject::ID &mountpoint, SimObject::ID &gid )
00082 {
00083 addObject( objFactory, gid );
00084 two_way_link( gid, mountpoint );
00085 }
00086
00087 void SingleThreadSimEngine::two_way_link( const SimObject::ID &id1, const SimObject::ID &id2 )
00088 {
00089
00090 SimObject *obj1 = objPool.getObject( id1.type, id1.localid );
00091 SimObject *obj2 = objPool.getObject( id2.type, id2.localid );
00092
00093 obj1->incoming( obj2, id2, id1, network );
00094 obj2->outgoing( obj1, id1, id2, network );
00095
00096 obj2->incoming( obj1, id1, id2, network );
00097 obj1->outgoing( obj2, id2, id1, network );
00098 }
00099
00100 void SingleThreadSimEngine::one_way_link( const SimObject::ID &src, const SimObject::ID &dst )
00101 {
00102 SimObject *s = objPool.getObject( src.type, src.localid );
00103 SimObject *d = objPool.getObject( dst.type, dst.localid );
00104
00105 d->incoming( s, src, dst, network );
00106 s->outgoing( d, dst, src, network );
00107 }
00108
00109 void SingleThreadSimEngine::reset()
00110 {
00111 if (!initialized)
00112 initialize();
00113
00114
00115 theThreadSpecificRandomEngine.set( noiseRNDEngine );
00116
00117
00118 double dt = network.get_dt().in_sec();
00119 objPool.updateObjects( dtHasChanged, dt );
00120
00121
00122 t = Time::ms(0);
00123 step = 0;
00124
00125
00126 activeSpikeReceiver.resize(0);
00127
00128 SimObjectPool::SimObjectIterator oit;
00129
00130 int nTypes = objPool.numOfTypes();
00131 for( int t = 0; t < nTypes; t++ ) {
00132 for( oit = objPool.beginObject(t); oit != objPool.endObject(t); ++oit ) {
00133 if( (*oit)->reset( dt ) & RESETFLAG_ACTIVATE ) {
00134 activeSpikeReceiver.push_back( *oit );
00135 };
00136 }
00137 }
00138
00139
00140 isReset = 1;
00141 }
00142
00143 void SingleThreadSimEngine::initialize()
00144 {
00145
00146
00147 if (!initialized) {
00148
00149 theThreadSpecificRandomEngine.set( noiseRNDEngine );
00150
00151 SimObjectPool::SimObjectIterator oit;
00152 InitializeInfo ii( &network, this );
00153 int nTypes = objPool.numOfTypes();
00154 for( int t = 0; t < nTypes; t++ ) {
00155 for( oit = objPool.beginObject(t); oit != objPool.endObject(t); ++oit ) {
00156 (*oit)->init(&ii);
00157 }
00158 }
00159 initialized = true;
00160 }
00161 }
00162
00163
00164
00165 void SingleThreadSimEngine::advance(int nSteps)
00166 {
00167
00168 if( !isReset ) {
00169 reset();
00170 }
00171
00172
00173
00174 theThreadSpecificRandomEngine.set( noiseRNDEngine );
00175
00176 SimObjectPool::SimObjectIterator oit;
00177
00178 int type;
00179
00180 AdvanceInfo adv_inf( &network, this );
00181
00182 for( int s=0; s<nSteps; s++ ) {
00183
00184 adv_inf.t = this->t;
00185
00186
00187 analog_msg_dispatcher.dispatchAnalogMsgs();
00188
00189
00190 for( type = 0; type < SimObjectRegistry::FirstIndexOf::SpikeDriven ; type++ ) {
00191 for( oit = objPool.beginObject(type); oit != objPool.endObject(type); ++oit ) {
00192 (*oit)->advance(adv_inf);
00193 }
00194 }
00195
00196
00197 spikeScheduler.deliverSpikes( activeSpikeReceiver, this->eid, t.in_sec() );
00198
00199
00200 size_t i=0;
00201 while( i < activeSpikeReceiver.size() ) {
00202
00203 if( activeSpikeReceiver[i]->advance(adv_inf) & ADVANCEFLAG_DEACTIVATE ) {
00204 activeSpikeReceiver[i] = activeSpikeReceiver.back();
00205 activeSpikeReceiver.resize( activeSpikeReceiver.size() - 1);
00206 } else {
00207 i++;
00208 }
00209 }
00210
00211
00212 for( type = SimObjectRegistry::FirstIndexOf::AdvancePhase2; type < SimObjectRegistry::FirstIndexOf::NoAdvance; type++ ) {
00213 for( oit = objPool.beginObject(type); oit != objPool.endObject(type); ++oit ) {
00214 (*oit)->advance(adv_inf);
00215 }
00216 }
00217
00218
00219 spikeScheduler.advance(eid);
00220
00221
00222 t += network.get_dt();
00223 step++;
00224
00225 }
00226
00227 }
00228
00229 void SingleThreadSimEngine::advanceOneFullCycle()
00230 {
00231 advance(default_steps_per_cycle);
00232 spikeScheduler.nextCycle();
00233 }
00234
00235 void SingleThreadSimEngine::advanceSeveralStepsWithinACycle(int nsteps)
00236 {
00237 advance(nsteps);
00238 }
00239
00240 void SingleThreadSimEngine::finalizeCycle() {}