00001 #include "SimNetwork.h"
00002 #include "WiringMethodSelector.h"
00003 #include <boost/date_time/posix_time/posix_time.hpp>
00004 #include <iostream>
00005 using std::cerr;
00006 using std::endl;
00007
00008
00009 SimNetwork::SimNetwork( MPI::Intracomm &mpiCommunicator, SimParameter sp, DistributionStrategy::DistributionFunction* df )
00010 : simParam(sp),
00011 distributionStrategy( df ),
00012 _mpi_rank( mpiCommunicator.Get_rank() ),
00013 _mpi_size( mpiCommunicator.Get_size() ),
00014 initialized(false),
00015 reseted(false),
00016 _nSpikeMessages(0),
00017 _nAnalogMessages(0)
00018 {
00019 wiringMethods = new WiringMethodSelector(this);
00020 PCSIM::init();
00021 }
00022
00023
00024 SimNetwork::~SimNetwork()
00025 {
00026 delete wiringMethods;
00027 delete constructMainRNDEngine;
00028 for (size_t i = 0; i < constructIncomingRNGEngines.size() ; ++i) {
00029 delete constructIncomingRNGEngines[i];
00030 delete constructOutgoingRNGEngines[i];
00031 }
00032 delete objectVariationRNDEngine;
00033 }
00034
00035
00037
00042 SimObject::ID::Vector SimNetwork::add( SimObjectFactory const& model, vector<SimEngine::ID> const& engines )
00043 {
00044 SimObject::ID::Vector ids( new vector<SimObject::ID::Packed>( engines.size() ) );
00045 SimObject::ID id;
00046 for( unsigned i=0; i<engines.size(); i++ ) {
00047 addObject( model, engines[i], id );
00048 (*ids)[i] = id.packed();
00049 }
00050 return ids;
00051 }
00052
00054
00059 SimObject::ID::Vector SimNetwork::add( const SimObjectFactory &model, const unsigned n)
00060 {
00061 SimObject::ID::Vector ids( new vector<SimObject::ID::Packed>(n) );
00062 SimObject::ID id;
00063 for( unsigned i=0; i<n; i++ ) {
00064 addObject( model, id );
00065 (*ids)[i] = id.packed();
00066 }
00067 return ids;
00068 }
00069
00070 SimObject::ID::Vector SimNetwork::mount( const SimObjectFactory &model, vector<SimObject::ID::Packed> const& mountpoints, bool collect )
00071 {
00072 size_t n = mountpoints.size();
00073 SimObject::ID::Vector collids( new vector<SimObject::ID::Packed> );
00074 if( collect ) {
00075 collids->reserve( n );
00076 for( size_t i=0; i < n; i++ ) {
00077 collids->push_back( mount( model, mountpoints[i] ) );
00078 }
00079 } else {
00080 for( size_t i=0; i < n; i++ ) {
00081 mount( model, mountpoints[i] );
00082 }
00083 collids->push_back( (SimObject::ID::Packed)(n) );
00084 }
00085 return collids;
00086 }
00087
00089
00093 unsigned SimNetwork::connect( vector<SimObject::ID::Packed> const& sources, vector<SimObject::ID::Packed> const& destinations, ConnectionIterator & decider )
00094 {
00095 return wiringMethods->simpleAllToAll().connect(sources, destinations, decider);
00096 }
00097
00099
00106 unsigned SimNetwork::connect( vector<SimObject::ID::Packed> const& sources, vector<SimObject::ID::Packed> const& destinations, const Time &delay )
00107 {
00108 return dynamic_cast<OneToOneWiringMethod &>(wiringMethods->oneToOne()).connect(sources, destinations, delay);
00109 }
00110
00111
00113
00121 SimObject::ID::Vector SimNetwork::connect( vector<SimObject::ID::Packed> const& sources, vector<SimObject::ID::Packed> const& destinations, const SimObjectFactory &model, ConnectionIterator & decider, bool collect)
00122 {
00123
00124 return wiringMethods->simpleAllToAll().connect(sources, destinations, model, decider, collect);
00125 }
00126
00127
00128 SimObject::ID::Vector SimNetwork::connectFast( vector<SimObject::ID::Packed> const& sources, vector<SimObject::ID::Packed> const& destinations, const SimObjectFactory &model, ConnectionIterator & decider, bool collect)
00129 {
00130 return wiringMethods->distributedAllToAll().connect(sources, destinations, model, decider, collect);
00131 }
00132
00133 uint32 SimNetwork::getUniqueSeedOverMpi( uint32 seed )
00134 {
00135 return seed;
00136 }
00137
00138 #ifdef _MSC_VER
00139 # pragma warning(disable:4244) // warning C4244: 'initializing' : conversion from 'boost::uint64_t' to 'boost::uint32_t', possible loss of data
00140 # undef min
00141 # undef max
00142 #endif
00143
00144 uint32 SimNetwork::makeSeed( uint32 noiseRNGseed )
00145 {
00146 uint32 seed = noiseRNGseed;
00147 if( seed == 0 ) {
00148 seed = microsec_clock::local_time().time_of_day().total_microseconds();
00149 }
00150 return seed ;
00151 }
00152
00153 void SimNetwork::fillSeedVector( uint32 noiseRNGseed, vector<uint32> &sim_seeds )
00154 {
00155 simRNGSeedGenerator.seed( (boost::uint32_t)noiseRNGseed );
00156 for( size_t t=0; t<sim_seeds.size(); t++ ) {
00157 sim_seeds[t] = getSeedFromGenerator();
00158 }
00159 }
00160
00161 uint32 SimNetwork::getSeedFromGenerator()
00162 {
00163 return (uint32)( 1.0e9 * ( simRNGSeedGenerator() - simRNGSeedGenerator.min() ) / simRNGSeedGenerator.max() );
00164 }
00165
00166 void SimNetwork::setupConstructRNGEngines()
00167 {
00168
00169 constructMainRNDEngine = new MersenneTwister19937;
00170 objectVariationRNDEngine = new MersenneTwister19937;
00171 constructIncomingRNGEngines.clear();
00172 constructOutgoingRNGEngines.clear();
00173 for (int i = 0; i < _mpi_size ; ++i) {
00174 constructIncomingRNGEngines.push_back( new MersenneTwister19937 );
00175 constructOutgoingRNGEngines.push_back( new MersenneTwister19937 );
00176 }
00177
00178 uint32 unique_seed = getUniqueSeedOverMpi( makeSeed( simParam.constructionRNGSeed ) );
00179 constructMainRNDEngine->seed( unique_seed );
00180 objectVariationRNDEngine->seed( unique_seed );
00181 simRNGSeedGenerator.seed( unique_seed );
00182
00183 for (int i = 0; i < _mpi_size ; ++i) {
00184 constructIncomingRNGEngines[i]->seed( simParam.constructionRNGSeed );
00185 constructOutgoingRNGEngines[i]->seed( simParam.constructionRNGSeed );
00186 }
00187
00188 uint32 s;
00189 for( int a = 0; a < _mpi_size; a ++ ) {
00190 for( int b = 0; b < _mpi_size; b ++ ) {
00191 s = getSeedFromGenerator();
00192 if( a == _mpi_rank ) {
00193 constructIncomingRNGEngines[ b ]->seed( s );
00194 }
00195 if( b == _mpi_rank ) {
00196 constructOutgoingRNGEngines[ a ]->seed( s );
00197 }
00198 }
00199 }
00200 }
00201
00202 #ifdef _MSC_VER
00203 # pragma warning(default:4244) // warning C4244: 'initializing' : conversion from 'boost::uint64_t' to 'boost::uint32_t', possible loss of data
00204 #endif
00205
00206