ArrayDatum
ConnectionManager::get_connections( DictionaryDatum params ) const
{
  ArrayDatum connectome;

  const Token& source_t = params->lookup( names::source );
  const Token& target_t = params->lookup( names::target );
  const Token& syn_model_t = params->lookup( names::synapse_model );
  const TokenArray* source_a = 0;
  const TokenArray* target_a = 0;

  if ( not source_t.empty() )
    source_a = dynamic_cast< TokenArray const* >( source_t.datum() );
  if ( not target_t.empty() )
    target_a = dynamic_cast< TokenArray const* >( target_t.datum() );

  size_t syn_id = 0;

#ifdef _OPENMP
  std::string msg;
  msg = String::compose( "Setting OpenMP num_threads to %1.", net_.get_num_threads() );
  net_.message( SLIInterpreter::M_DEBUG, "ConnectionManager::get_connections", msg );
  omp_set_num_threads( net_.get_num_threads() );
#endif

  // First we check, whether a synapse model is given.
  // If not, we will iterate all.
  if ( not syn_model_t.empty() )
  {
    Name synmodel_name = getValue< Name >( syn_model_t );
    const Token synmodel = synapsedict_->lookup( synmodel_name );
    if ( !synmodel.empty() )
      syn_id = static_cast< size_t >( synmodel );
    else
      throw UnknownModelName( synmodel_name.toString() );
    get_connections( connectome, source_a, target_a, syn_id );
  }
  else
  {
    for ( syn_id = 0; syn_id < prototypes_[ 0 ].size(); ++syn_id )
    {
      ArrayDatum conn;
      get_connections( conn, source_a, target_a, syn_id );
      if ( conn.size() > 0 )
        connectome.push_back( new ArrayDatum( conn ) );
    }
  }

  return connectome;
}
Beispiel #2
0
bool nest::ac_poisson_generator::
Parameters_::extract_array_(const DictionaryDatum &d, 
			    const std::string& dname,
			    std::valarray<double>& data) const
{
  if ( d->known(dname) )
  {
    ArrayDatum *ad = dynamic_cast<ArrayDatum *>((*d)[dname].datum());
    if ( ad == 0 )
      throw BadProperty();

    const size_t nd = ad->size();
    data.resize(nd);
    for ( size_t n = 0 ; n < nd ; ++n )
      {
	data[n] = getValue<double>((*ad)[n]);
      }

    return true;
  }
  else
    return false;
}
void
nest::RNGManager::set_status( const DictionaryDatum& d )
{
  // have those two for later asking, whether threads have changed:
  long n_threads;
  bool n_threads_updated =
    updateValue< long >( d, "local_num_threads", n_threads );

  // set RNGs --- MUST come after n_threads_ is updated
  if ( d->known( "rngs" ) )
  {
    // this array contains pre-seeded RNGs, so they can be used
    // directly, no seeding required
    ArrayDatum* ad = dynamic_cast< ArrayDatum* >( ( *d )[ "rngs" ].datum() );
    if ( ad == 0 )
      throw BadProperty();

    // n_threads_ is the new value after a change of the number of
    // threads
    if ( ad->size()
      != ( size_t )( kernel().vp_manager.get_num_virtual_processes() ) )
    {
      LOG( M_ERROR,
        "RNGManager::set_status",
        "Number of RNGs must equal number of virtual processes "
        "(threads*processes). RNGs "
        "unchanged." );
      throw DimensionMismatch(
        ( size_t )( kernel().vp_manager.get_num_virtual_processes() ),
        ad->size() );
    }

    // delete old generators, insert new generators this code is
    // robust under change of thread number in this call to
    // set_status, as long as it comes AFTER n_threads_ has been
    // upated
    rng_.clear();
    for ( index i = 0; i < ad->size(); ++i )
      if ( kernel().vp_manager.is_local_vp( i ) )
        rng_.push_back( getValue< librandom::RngDatum >(
          ( *ad )[ kernel().vp_manager.suggest_vp( i ) ] ) );
  }
  else if ( n_threads_updated && kernel().node_manager.size() == 0 )
  {
    LOG( M_WARNING,
      "RNGManager::set_status",
      "Equipping threads with new default RNGs" );
    create_rngs_();
  }

  if ( d->known( "rng_seeds" ) )
  {
    ArrayDatum* ad =
      dynamic_cast< ArrayDatum* >( ( *d )[ "rng_seeds" ].datum() );
    if ( ad == 0 )
      throw BadProperty();

    if ( ad->size()
      != ( size_t )( kernel().vp_manager.get_num_virtual_processes() ) )
    {
      LOG( M_ERROR,
        "RNGManager::set_status",
        "Number of seeds must equal number of virtual processes "
        "(threads*processes). RNGs unchanged." );
      throw DimensionMismatch(
        ( size_t )( kernel().vp_manager.get_num_virtual_processes() ),
        ad->size() );
    }

    // check if seeds are unique
    std::set< ulong_t > seedset;
    for ( index i = 0; i < ad->size(); ++i )
    {
      long s = ( *ad )[ i ]; // SLI has no ulong tokens
      if ( !seedset.insert( s ).second )
      {
        LOG( M_WARNING,
          "RNGManager::set_status",
          "Seeds are not unique across threads!" );
        break;
      }
    }

    // now apply seeds, resets generators automatically
    for ( index i = 0; i < ad->size(); ++i )
    {
      long s = ( *ad )[ i ];

      if ( kernel().vp_manager.is_local_vp( i ) )
        rng_[ kernel().vp_manager.vp_to_thread(
                kernel().vp_manager.suggest_vp( i ) ) ]->seed( s );

      rng_seeds_[ i ] = s;
    }
  } // if rng_seeds

  // set GRNG
  if ( d->known( "grng" ) )
  {
    // pre-seeded grng that can be used directly, no seeding required
    updateValue< librandom::RngDatum >( d, "grng", grng_ );
  }
  else if ( n_threads_updated && kernel().node_manager.size() == 0 )
  {
    LOG( M_WARNING,
      "RNGManager::set_status",
      "Equipping threads with new default GRNG" );
    create_grng_();
  }

  if ( d->known( "grng_seed" ) )
  {
    const long gseed = getValue< long >( d, "grng_seed" );

    // check if grng seed is unique with respect to rng seeds
    // if grng_seed and rng_seeds given in one SetStatus call
    std::set< ulong_t > seedset;
    seedset.insert( gseed );
    if ( d->known( "rng_seeds" ) )
    {
      ArrayDatum* ad_rngseeds =
        dynamic_cast< ArrayDatum* >( ( *d )[ "rng_seeds" ].datum() );
      if ( ad_rngseeds == 0 )
        throw BadProperty();
      for ( index i = 0; i < ad_rngseeds->size(); ++i )
      {
        const long vpseed = ( *ad_rngseeds )[ i ]; // SLI has no ulong tokens
        if ( !seedset.insert( vpseed ).second )
        {
          LOG( M_WARNING,
            "RNGManager::set_status",
            "Seeds are not unique across threads!" );
          break;
        }
      }
    }
    // now apply seed, resets generator automatically
    grng_seed_ = gseed;
    grng_->seed( gseed );

  } // if grng_seed
}