bool SpikingGroup::write_to_file(const char * filename) { if ( !evolve_locally() ) return true; ofstream outfile; outfile.open(filename,ios::out); if (!outfile) { cerr << "Can't open output file " << filename << endl; throw AurynOpenFileException(); } outfile << "# Auryn SpikingGroup state file for n="<< get_rank_size() <<" neurons (ver. " << VERSION << ")" << endl; outfile << "# Field order: "; for ( map<string,gsl_vector_float *>::const_iterator iter = state_vector.begin() ; iter != state_vector.end() ; ++iter ) { outfile << scientific << iter->first << " "; } outfile << "(plus traces)"; outfile << endl; boost::archive::text_oarchive oa(outfile); oa << *(delay); outfile << endl; for ( NeuronID i = 0 ; i < get_rank_size() ; ++i ) { outfile << get_output_line(i); } outfile.close(); return true; }
bool SpikingGroup::localrank(NeuronID i) { bool t = ( (i+locked_rank)%locked_range==communicator->rank() ) && (int) communicator->rank() >= locked_rank && (int) communicator->rank() < (locked_rank+locked_range) && i/locked_range < get_rank_size(); return t; }
void TIFGroup::evolve() { for (NeuronID i = 0 ; i < get_rank_size() ; ++i ) { if (t_ref[i]==0) { const AurynFloat dg_mem = ( (e_rest-t_mem[i]) - t_g_ampa[i] * t_mem[i] - t_g_gaba[i] * (t_mem[i]-e_rev) + t_bg_cur[i] ); t_mem[i] += dg_mem*scale_mem; if (t_mem[i]>thr) { push_spike(i); t_mem[i] = e_rest ; t_ref[i] += refractory_time ; } } else { t_ref[i]-- ; t_mem[i] = e_rest ; } } auryn_vector_float_scale(scale_ampa,g_ampa); auryn_vector_float_scale(scale_gaba,g_gaba); }
bool SpikingGroup::load_from_file(const char * filename) { if ( !evolve_locally() ) return true; stringstream oss; oss << "Loading SpikingGroup from " << filename; logger->msg(oss.str(),NOTIFICATION); ifstream infile (filename); if (!infile) { stringstream oes; oes << "Can't open input file " << filename; logger->msg(oes.str(),ERROR); throw AurynOpenFileException(); } NeuronID count = 0; char buffer[1024]; infile.getline (buffer,1024); // skipping header TODO once could make this logic a bit smarter infile.getline (buffer,1024); // skipping header boost::archive::text_iarchive ia(infile); ia >> *delay; infile.getline (buffer,1024); // jumpting to next line while ( infile.getline (buffer,1024) ) { load_input_line(count,buffer); count++; } if ( get_rank_size() != count ) { // issue warning stringstream oes; oes << "SpikingGroup:: NeuronState file corrupted. Read " << count << " entries, but " << get_rank_size() << " expected in " << filename; logger->msg(oes.str(),WARNING); } infile.close(); return true; }
void StimulusGroup::init(string filename, StimulusGroupModeType stimulusmode, string outputfile, AurynFloat baserate) { sys->register_spiking_group(this); ttl = new AurynTime [get_rank_size()]; activity = new AurynFloat [get_rank_size()]; set_baserate(baserate); poisson_gen.seed(162346*communicator->rank()); mean_off_period = 1.0 ; mean_on_period = 0.2 ; stimulus_order = stimulusmode ; stimulus_active = false ; set_all( 0.0 ); scale = 2.0; randomintervals = true; binary_patterns = false; if ( !outputfile.empty() ) { tiserfile.open(outputfile.c_str(),ios::out); if (!tiserfile) { stringstream oss; oss << "StimulusGroup:: Can't open output file " << filename; logger->msg(oss.str(),ERROR); exit(1); } tiserfile.setf(ios::fixed); // tiserfile.precision(5); } stringstream oss; oss << "StimulusGroup:: In mode " << stimulus_order; logger->msg(oss.str(),NOTIFICATION); cur_stim_index = 0; next_action_time = 0; active = true; off_pattern = -1; load_patterns(filename); }
void SpikingGroup::init(NeuronID n, double loadmultiplier, NeuronID total ) { group_name = "SpikingGroup"; unique_id = unique_id_count++; size = n; effective_load_multiplier = loadmultiplier; if ( total > 0 ) { anticipated_total = total; stringstream oss; oss << get_name() << ":: Anticipating " << anticipated_total << " units in total." ; logger->msg(oss.str(),NOTIFICATION); } // setting up default values evolve_locally_bool = true; locked_rank = 0; locked_range = communicator->size(); rank_size = calculate_rank_size(); // set the rank size double fraction = (double)calculate_rank_size(0)*effective_load_multiplier/DEFAULT_MINDISTRIBUTEDSIZE; if ( anticipated_total > 0 ) fraction = (1.*size*effective_load_multiplier)/anticipated_total; if ( fraction >= 0 && fraction < 1. ) { lock_range( fraction ); } else { // ROUNDROBIN which is default locked_rank = 0; locked_range = communicator->size(); stringstream oss; oss << get_name() << ":: Size " << get_rank_size() << " (ROUNDROBIN)"; logger->msg(oss.str(),NOTIFICATION); } stringstream oss; oss << get_name() << ":: Registering delay (MINDELAY=" << MINDELAY << ")"; logger->msg(oss.str(),DEBUG); delay = new SpikeDelay( ); set_delay(MINDELAY+1); evolve_locally_bool = evolve_locally_bool && ( get_rank_size() > 0 ); }
void StimulusGroup::redraw() { boost::exponential_distribution<> dist(BASERATE); boost::variate_generator<boost::mt19937&, boost::exponential_distribution<> > die(poisson_gen, dist); for ( NeuronID i = 0 ; i < get_rank_size() ; ++i ) { ttl[i] = sys->get_clock() + (AurynTime)((AurynFloat)die()/((activity[i]+1e-9)*dt)); } }
void TIFGroup::clear() { clear_spikes(); for (NeuronID i = 0; i < get_rank_size(); i++) { gsl_vector_float_set (mem, i, e_rest); gsl_vector_ushort_set (ref, i, 0); gsl_vector_float_set (g_ampa, i, 0.); gsl_vector_float_set (g_gaba, i, 0.); gsl_vector_float_set (bg_current, i, 0.); } }
void IF2Group::clear() { clear_spikes(); for (NeuronID i = 0; i < get_rank_size(); i++) { auryn_vector_float_set (mem, i, e_rest); auryn_vector_float_set (thr, i, 0.); auryn_vector_float_set (g_ampa, i, 0.); auryn_vector_float_set (g_gaba, i, 0.); auryn_vector_float_set (g_nmda, i, 0.); } }
void StimulusGroup::redraw_softstart() { boost::exponential_distribution<> dist(BASERATE); boost::variate_generator<boost::mt19937&, boost::exponential_distribution<> > die(poisson_gen, dist); boost::uniform_real<> uniformdist(0, SOFTSTARTTIME ); boost::variate_generator<boost::mt19937&, boost::uniform_real<> > random(poisson_gen, uniformdist); for ( NeuronID i = 0 ; i < get_rank_size() ; ++i ) { ttl[i] = sys->get_clock() + (AurynTime)((AurynFloat)die()/((activity[i]+base_rate)*dt)+random()/dt); } }
void SpikingGroup::lock_range( double rank_fraction ) { locked_rank = last_locked_rank%communicator->size(); // TODO might cause a bug with the block lock stuff // TODO get the loads for the different ranks and try to minimize this if ( rank_fraction == 0 ) { // this is the classical rank lock to one single rank stringstream oss; oss << get_name() << ":: Groups demands to run on single rank only (RANKLOCK)."; logger->msg(oss.str(),NOTIFICATION); locked_range = 1; } else { // this is for multiple rank ranges unsigned int free_ranks = communicator->size()-last_locked_rank; locked_range = rank_fraction*communicator->size()+0.5; if ( locked_range == 0 ) { // needs at least one rank locked_range = 1; } if ( locked_range > free_ranks ) { stringstream oss; // oss << "SpikingGroup:: Not enough free ranks to put SpikingGroup defaulting to ROUNDROBIN distribution."; oss << get_name() << ":: Not enough free ranks for RANGELOCK. Starting to fill at zero again."; logger->msg(oss.str(),NOTIFICATION); locked_rank = 0; free_ranks = communicator->size(); // return; } } unsigned int rank = (unsigned int) communicator->rank(); evolve_locally_bool = ( rank >= locked_rank && rank < (locked_rank+locked_range) ); last_locked_rank = (locked_rank+locked_range)%communicator->size(); rank_size = calculate_rank_size(); // recalculate the rank size // logging if ( evolve_locally_bool ) { stringstream oss; oss << get_name() << ":: Size "<< get_rank_size() <<" (BLOCKLOCK: ["<< locked_rank << ":" << locked_rank+locked_range-1 << "] )"; logger->msg(oss.str(),NOTIFICATION); } else { stringstream oss; oss << get_name() << ":: Passive on this rank (BLOCKLOCK: ["<< locked_rank << ":" << locked_rank+locked_range-1 << "] )"; logger->msg(oss.str(),DEBUG); } }
void AIFGroup::random_adapt(AurynState mean, AurynState sigma) { boost::mt19937 ng_gen(42); // produces same series every time boost::normal_distribution<> dist((double)mean, (double)sigma); boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > die(ng_gen, dist); AurynState rv; for ( AurynLong i = 0 ; i<get_rank_size() ; ++i ) { rv = die(); if ( rv>0 ) set_val (g_adapt1, i, rv ); } init_state(); }
void IF2Group::check_thresholds() { auryn_vector_float_clip( mem, e_rev ); AurynState * thr_ptr = thr->data; for ( AurynState * i = mem->data ; i != mem->data+get_rank_size() ; ++i ) { // it's important to use rank_size here otherwise there might be spikes from units that do not exist if ( *i > ( thr_rest + *thr_ptr ) ) { NeuronID unit = i-mem->data; push_spike(unit); set_val (mem, unit, e_rest); // reset set_val (thr, unit, dthr); //refractory } thr_ptr++; } }
void SpikingGroup::randomize_state_vector_gauss(string state_vector_name, AurynState mean, AurynState sigma, int seed) { boost::mt19937 ng_gen(seed+communicator->rank()); // produces same series every time boost::normal_distribution<> dist((double)mean, (double)sigma); boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > die(ng_gen, dist); AurynState rv; auryn_vector_float * vec = get_state_vector(state_vector_name); for ( AurynLong i = 0 ; i<get_rank_size() ; ++i ) { rv = die(); auryn_vector_float_set( vec, i, rv ); } }
NeuronID SpikingGroup::get_vector_size() { return calculate_vector_size(get_rank_size()); }
void StimulusGroup::evolve() { if ( !active ) return; // detect and push spikes boost::exponential_distribution<> dist(BASERATE); boost::variate_generator<boost::mt19937&, boost::exponential_distribution<> > die(poisson_gen, dist); for ( NeuronID i = 0 ; i < get_rank_size() ; ++i ) { if ( ttl[i] < sys->get_clock() && activity[i]>0.0 ) { push_spike ( i ); ttl[i] = sys->get_clock() + (AurynTime)((AurynFloat)die()/((activity[i]+base_rate)*dt)); } } // update stimulus properties if ( sys->get_clock() >= next_action_time ) { write_sequence_file(dt*(sys->get_clock())); if ( stimulus_active ) { if ( off_pattern >= 0 ) { set_active_pattern( off_pattern ); // turn on "off-stimulus" cur_stim_index = off_pattern; } else set_all( 0.0 ); // turn off currently active stimulus stimulus_active = false ; if ( randomintervals ) { boost::exponential_distribution<> dist(1./mean_off_period); boost::variate_generator<boost::mt19937&, boost::exponential_distribution<> > die(order_gen, dist); next_action_time = sys->get_clock() + (AurynTime)(max(0.0,die())/dt); } else { next_action_time = sys->get_clock() + (AurynTime)(mean_off_period/dt); } } else { if ( active ) { // choose stimulus switch ( stimulus_order ) { case MANUAL: break; case SEQUENTIAL: cur_stim_index = (cur_stim_index+1)%stimuli.size(); break; case SEQUENTIAL_REV: --cur_stim_index; if ( cur_stim_index <= 0 ) cur_stim_index = stimuli.size() - 1 ; break; case RANDOM: default: double draw = order_die(); double cummulative = 0; // TODO make this less greedy and do not compute this every draw cur_stim_index = 0; // cout.precision(5); // cout << " draw " << draw << endl; for ( unsigned int i = 0 ; i < probabilities.size() ; ++i ) { cummulative += probabilities[i]; // cout << cummulative << endl; if ( draw <= cummulative ) { cur_stim_index = i; break; } } break; } set_active_pattern( cur_stim_index ); stimulus_active = true; if ( randomintervals ) { boost::normal_distribution<> dist(mean_on_period,mean_on_period/3); boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > die(order_gen, dist); next_action_time = sys->get_clock() + (AurynTime)(max(0.0,die())/dt); } else { next_action_time = sys->get_clock() + (AurynTime)(mean_on_period/dt); } } } write_sequence_file(dt*(sys->get_clock()+1)); } }
void StimulusGroup::set_all(AurynFloat val) { for ( unsigned int i = 0 ; i < get_rank_size() ; ++i ) activity[i] = val; }
AurynDouble SpikingGroup::get_effective_load() { return get_rank_size()*effective_load_multiplier; }
NeuronID SpikingGroup::get_post_size() { return get_rank_size(); }
NeuronID SpikingGroup::ranksize() { return get_rank_size(); }