SingleThreadNetwork.cpp

Go to the documentation of this file.
00001 
00002 #include "SingleThreadNetwork.h"
00003 #include "SpikeSender.h"
00004 #include "PCSIMException.h"
00005 #include "RandomDistribution.h"
00006 
00007 #include <boost/format.hpp>
00008 
00009 #include <string>
00010 using std::string;
00011 
00012 #include <iostream>
00013 using std::cerr;
00014 using std::endl;
00015 
00016 // ------------------------------ constructor  / destructor --------------------------------------- //
00017 
00018 SingleThreadNetwork::SingleThreadNetwork( SimParameter sp ) :
00019         SimNetwork(MPI::COMM_WORLD, sp, &localRoundRobin)
00020 {
00021     init();
00022 }
00023 
00024 SingleThreadNetwork::SingleThreadNetwork(MPI::Intracomm &comm, SimParameter sp ) :
00025         SimNetwork(comm, sp, &localRoundRobin)
00026 {
00027     init();
00028 }
00029 
00030 void SingleThreadNetwork::init()
00031 {
00032     spikeBuffer = new PropagatedSpikeBuffer(simParam.minDelay.in_steps( get_dt() ), simParam.maxDelay.in_steps( get_dt() ) );
00033     delayMap = new LocalDelayMap;
00034     stgPool = new SpikeTargetGroupPool;
00035     spikeScheduler = new SingleThreadSpikeScheduler(*delayMap, *stgPool, *spikeBuffer, simParam ) ;
00036     analogMsgDispatcher = new SingleThreadAnalogMsgDispatcher;
00037     simEngine = new SingleThreadSimEngine(0, *spikeScheduler, *analogMsgDispatcher, *this );
00038     analogDelayObjectsMap = new AnalogDelayObjectMap;
00039 
00040     analogMsgCreator = new STAnalogMessageCreator(*analogMsgDispatcher,
00041                        *simEngine,
00042                        *analogDelayObjectsMap,
00043                        (delay_t)simParam.minDelay.in_steps( get_dt() ) );
00044 
00045 
00046     setupConstructRNGEngines();
00047     SingleThreadNetwork::seed_noise_rng( makeSeed( simParam.simulationRNGSeed ) );
00048  
00049 }
00050 
00051 SingleThreadNetwork::~SingleThreadNetwork()
00052 {
00053     delete spikeBuffer;
00054     delete delayMap;
00055     delete spikeScheduler;
00056     delete simEngine;
00057     delete stgPool;
00058     delete analogMsgDispatcher;
00059     delete analogMsgCreator;
00060     if (!initialized) {
00061         delete analogDelayObjectsMap;
00062     }
00063 }
00064 
00065 void SingleThreadNetwork::seed_noise_rng( uint32 noiseRNGseed )
00066 {
00067     simEngine->seed( noiseRNGseed );
00068     objectVariationRNDEngine->seed( makeSeed( simParam.constructionRNGSeed ) ) ;
00069 }
00070 
00071 // ------------------------- adding objects ----------------------- //
00072 
00073 /*void SingleThreadNetwork::addObject(SimObject * o, SimObject::ID &id)
00074 {
00075     id.node    = _mpi_rank;
00076     id.eng     = 0;
00077     id.type    = o->getObjectTypeID();
00078     simEngine->addObject( o, id );
00079 }
00080  
00081 void SingleThreadNetwork::addObject( SimObject *obj, const engineid_t eng, SimObject::ID &id)
00082 {
00083     if( eng == 0 ) {
00084         addObject( obj, id );
00085     } else {
00086         id = SimObject::ID::Invalid;
00087         throw( PCSIM::ConstructionException( "SingleThreadNetwork::addObject", str( boost::format("Specified engine (%1%) out of range.") % eng) ) );
00088     }
00089 } */
00090 
00091 void SingleThreadNetwork::_addObject_( const SimObjectFactory &objFactory, const SimEngine::ID &loc, SimObject::ID &oid )
00092 {
00093     if( loc.node == _mpi_rank && loc.engine == 0 ) {
00094         addObject( objFactory, oid );
00095     } else {
00096         // cerr << boost::format("Specified node (%1%) does not match mpi rank (%2%)") % loc.node % _mpi_rank << endl;
00097         oid = SimObject::ID::Invalid;
00098         if( loc.node != _mpi_rank )
00099             throw( PCSIM::ConstructionException( "SingleThreadNetwork::addObject", str( boost::format("Specified node (%1%) does not mach mpi rank (%2%)") % loc.node % _mpi_rank ) ) );
00100         else
00101             throw( PCSIM::ConstructionException( "SingleThreadNetwork::addObject", str( boost::format("Specified engine (%1%) not zero") % loc.engine ) ) );
00102     }
00103 }
00104 
00105 void SingleThreadNetwork::_addObject_( const SimObjectFactory &objFactory, SimObject::ID &gid )
00106 {
00107     simEngine->addObject( objFactory, gid );
00108     gid.node    = _mpi_rank;
00109     gid.eng     = 0;
00110 }
00111 
00112 void SingleThreadNetwork::_mount_( const SimObjectFactory &objFactory, const SimObject::ID &mountpoint, SimObject::ID &gid )
00113 {
00114     simEngine->mount( objFactory, mountpoint, gid );
00115     gid.node    = _mpi_rank;
00116     gid.eng     = 0;
00117 }
00118 
00119 void SingleThreadNetwork::_insert_( const SimObjectFactory &objFactory, const SimObject::ID &container, SimObject::ID &gid )
00120 {
00121     simEngine->insert( objFactory, container, gid );
00122     gid.node    = _mpi_rank;
00123     gid.eng     = 0;
00124 }
00125 
00126 SimObject * SingleThreadNetwork::_getObject_(const SimObject::ID &id)
00127 {
00128     return simEngine->getObject(id);
00129 }
00130 
00131 
00132 // ----------------------------------  connections ---------------------------------------- //
00133 
00134 void SingleThreadNetwork::_connect_( SimObject::ID const& src, port_t out, const SimObject::ID &dst, port_t in, int delay )
00135 {
00136     SimObject *src_obj = simEngine->getObject(src);
00137     SimObject *dst_obj = simEngine->getObject(dst);
00138 
00139     // SpikeSender     *ss;
00140 
00141     Time delay_to_use;
00142     if( delay < 0 ) {
00143         delay_to_use = Time::sec( dst_obj->getManagedDelay() );
00144     } else {
00145         delay_to_use = Time::steps( delay, get_dt() );
00146     }
00147 
00148     if( src_obj->outputPortType(out) == SimObject::spiking && dst_obj->inputPortType( in ) == SimObject::spiking ) {
00149         addSpikeMessage( src, out, dst, in, delay_to_use );
00150     } else if ( src_obj->outputPortType(out) == SimObject::analog && dst_obj->inputPortType( in ) == SimObject::analog ) {
00151         addAnalogMessage( src, out, dst, in, delay_to_use );
00152     } else {
00153         cerr << " output port = " << int(src_obj->outputPortType(out)) << " input port " << in << " = " << int(dst_obj->inputPortType( in )) << " spiking constant = " << int(SimObject::spiking) << endl;
00154         throw( PCSIM::ConstructionException(
00155                    "SingleThreadNetwork::_connect_",
00156                    str( boost::format("Can not connect specified source (%1%) and destination object (%2%): no matching in (%3%) and out (%4%) ports.") % src.toString() % dst.toString() % in % out )
00157                ) );
00158     }
00159 }
00160 
00161 // ---------------------------------- spike messages -------------------------------------- //
00162 
00163 void SingleThreadNetwork::_addSpikeMessage_(const SimObject::ID &sender, const port_t out, const SimObject::ID &receiver, const port_t in_port, const Time &delay)
00164 {
00165     if( delay > simParam.maxDelay ) {
00166         throw( PCSIM::ConstructionException( "SingleThreadNetwork::addSpikeMessage", str( boost::format("Specified delay (%1% ms) larger then maximum delay (%2% ms)") % delay.in_ms() % simParam.maxDelay.in_ms() ) ) );
00167     }
00168 
00169     SimObject *src_obj = simEngine->getObject(sender);
00170     SpikeSender *ss = dynamic_cast<SpikeSender*>( src_obj );
00171 
00172     if( ss == NULL ) {
00173         throw( PCSIM::ConstructionException( "SingleThreadNetwork::addSpikeMessage", str( boost::format("Specified simulation object (%1%,%2%) is not a spike sender.") % sender.toString() % typeid(*src_obj).name() ) ) );
00174     }
00175 
00176     if( ss->getSpikePort( out ) != NULL ) {
00177         addLocalSpikeMessage( delayMap, stgPool, simEngine, ss->getSpikePort( out )->ID(), receiver, in_port, delay.in_steps( get_dt() ) );
00178         _nSpikeMessages++;
00179     } else {
00180         throw(
00181             PCSIM::ConstructionException (
00182                 "SingleThreadNetwork::addSpikeMessage",
00183                 str( boost::format("Specified spike output port (%1%) of %s with ID=%2% does not exist") % out % typeid(*src_obj).name() % sender.toString() )
00184             )
00185         );
00186     }
00187 }
00188 
00189 void SingleThreadNetwork::addLocalSpikeMessage(
00190     LocalDelayMap *arg_delayMap, SpikeTargetGroupPool *arg_stgPool, SimEngine *arg_simEng,
00191     const spike_port_id_t sender_port, const SimObject::ID &receiver, port_t in_port, step_t delay )
00192 {
00193     SimObject       *rec_obj    = arg_simEng->getObject(receiver);
00194     spikegroupid_t   tg          = arg_delayMap->find(sender_port, (delaystep_t)delay);
00195     if( tg == no_spikegroup ) {
00196         tg = arg_stgPool->addSpikeTarget( rec_obj, in_port ); // receiver, port
00197         arg_delayMap->insert( sender_port, (delaystep_t)delay, tg ); // sender_port, delay, targetgroup
00198     } else {
00199         arg_stgPool->addSpikeTarget( tg, rec_obj, in_port);
00200     }
00201 }
00202 
00203 // ------------------------------------ analog messages -------------------------------------- //
00204 
00205 void SingleThreadNetwork::_addAnalogMessage_(const SimObject::ID &sender, int sender_port, const SimObject::ID &receiver, int recv_port, const Time &delay)
00206 {
00207     _nAnalogMessages++;
00208     analogMsgCreator->addAnalogMessage(sender, sender_port, receiver, recv_port, (delay_t)delay.in_steps( get_dt() ) );
00209 }
00210 //
00211 void SingleThreadNetwork::_addAnalogMessage_(const SimObject::ID &sender, int sender_port, const SimObject::ID &receiver, string destfield, const Time &delay)
00212 {
00213     _nAnalogMessages++;
00214     analogMsgCreator->addAnalogMessage(sender, sender_port, receiver, destfield, (delay_t)delay.in_steps( get_dt() ) );
00215 }
00216 
00217 void SingleThreadNetwork::_addAnalogMessage_(const SimObject::ID &sender, string srcfield, const SimObject::ID &receiver, int recv_port, const Time &delay)
00218 {
00219     _nAnalogMessages++;
00220     analogMsgCreator->addAnalogMessage(sender, srcfield, receiver, recv_port, (delay_t)delay.in_steps( get_dt() ) );
00221 }
00222 
00223 void SingleThreadNetwork::_addAnalogMessage_(const SimObject::ID &sender, string srcfield, const SimObject::ID &receiver, string destfield, const Time &delay)
00224 {
00225     _nAnalogMessages++;
00226     analogMsgCreator->addAnalogMessage(sender, srcfield, receiver, destfield, (delay_t)delay.in_steps( get_dt() ) );
00227 }
00228 
00229 // -------------------------- running the simulation messages -------------------------------- //
00230 
00231 void SingleThreadNetwork::_initialize_()
00232 {
00233     if (!initialized) {
00234         simEngine->initialize();
00235         delete analogDelayObjectsMap;
00236         initialized = true;
00237     }
00238 }
00239 
00240 void SingleThreadNetwork::_reset_()
00241 {
00242     if( ! initialized ) initialize();
00243     spikeScheduler->reset();
00244     simEngine->reset();
00245     reseted = true;
00246 }
00247 
00248 void SingleThreadNetwork::_advance_( int nSteps )
00249 {
00250     if( ! reseted ) reset();
00251     simEngine->advance( nSteps );
00252 }

Generated on Wed Jul 9 16:34:38 2008 for PCSIM by  doxygen 1.5.5