void STPConnection::push_attributes() { // need to push one attribute for each spike SpikeContainer * spikes = src->get_spikes_immediate(); for (SpikeContainer::const_iterator spike = spikes->begin() ; spike != spikes->end() ; ++spike ) { // dynamics NeuronID spk = src->global2rank(*spike); double x = auryn_vector_float_get( state_x, spk ); double u = auryn_vector_float_get( state_u, spk ); auryn_vector_float_set( state_x, spk, x-u*x ); auryn_vector_float_set( state_u, spk, u+Ujump*(1-u) ); // TODO spike translation or introduce local_spikes // function in SpikingGroup and implement this there ... (better option) src->push_attribute( x*u ); } // If we had two spike attributes in this connection we push // the second attribute for each spike here: // // SpikeContainer * spikes = src->get_spikes_immediate(); // for (SpikeContainer::const_iterator spike = spikes->begin() ; // spike != spikes->end() ; ++spike ) { // AurynFloat other_attribute = foo+bar; // src->push_attribute( other_attribute ); // } }
void SyncBuffer::push(SpikeDelay * delay, const NeuronID size) { // DEBUG // std::cout << "Rank " << mpicom->rank() << "push\n"; // delay->print(); const SYNCBUFFER_DELTA_DATATYPE grid_size = (SYNCBUFFER_DELTA_DATATYPE)size*MINDELAY; SYNCBUFFER_DELTA_DATATYPE unrolled_last_pos = 0; // circular loop over different delay bins for (int slice = 0 ; slice < MINDELAY ; ++slice ) { SpikeContainer * sc = delay->get_spikes(slice+1); AttributeContainer * ac = delay->get_attributes(slice+1); // loop over all spikes in current delay time slice for (int i = 0 ; i < sc->size() ; ++i ) { NeuronID spike = sc->at(i); // compute unrolled position in current delay SYNCBUFFER_DELTA_DATATYPE unrolled_pos = (SYNCBUFFER_DELTA_DATATYPE)(spike) + (SYNCBUFFER_DELTA_DATATYPE)size*slice; // compute vertical unrolled difference from last spike SYNCBUFFER_DELTA_DATATYPE spike_delta = unrolled_pos + carry_offset - unrolled_last_pos; // memorize current position in slice unrolled_last_pos = unrolled_pos; // discard carry_offset since its only added to the first spike_delta carry_offset = 0; // overflow managment -- should only ever kick in for very very large SpikingGroups and very very sparse activity while ( spike_delta >= max_delta_size ) { send_buf.push_back( max_delta_size ); spike_delta -= max_delta_size; } // storing the spike delta (or its remainder) to buffer send_buf.push_back(spike_delta); // append spike attributes here in buffer for ( int k = 0 ; k < delay->get_num_attributes() ; ++k ) { // loop over attributes NeuronID cast_attrib = *(NeuronID*)(&(ac->at(i*delay->get_num_attributes()+k))); send_buf.push_back(cast_attrib); // std::cout << "store " << std::scientific << ac->at(i*delay->get_num_attributes()+k) << " int " << cast_attrib << std::endl; } } } // set save carry_offset which is the remaining difference from the present group // plus because there might be more than one group without a spike ... carry_offset += grid_size-unrolled_last_pos; }
void STPConnection::push_attributes() { SpikeContainer * spikes = src->get_spikes_immediate(); for (SpikeContainer::const_iterator spike = spikes->begin() ; spike != spikes->end() ; ++spike ) { // dynamics NeuronID spk = src->global2rank(*spike); double x = auryn_vector_float_get( state_x, spk ); double u = auryn_vector_float_get( state_u, spk ); auryn_vector_float_set( state_x, spk, x-u*x ); auryn_vector_float_set( state_u, spk, u+Ujump*(1-u) ); // TODO spike translation or introduce local_spikes function in SpikingGroup and implement this there ... (better option) src->push_attribute( x*u ); } }
void VoltageMonitor::propagate() { if ( auryn::sys->get_clock() < tStop ) { // we output spikes irrespectively of the sampling interval, because // the membrane potential isn't a smooth function for most IF models when // they spike, so it's easy to "miss" a spike otherwise double voltage = src->mem->get(nid); if ( paste_spikes ) { SpikeContainer * spikes = src->get_spikes_immediate(); for ( int i = 0 ; i < spikes->size() ; ++i ) { if ( spikes->at(i) == gid ) { voltage = VOLTAGEMONITOR_PASTED_SPIKE_HEIGHT; outfile << (auryn::sys->get_time()) << " " << voltage << "\n"; return; } } } if ( (auryn::sys->get_clock())%ssize==0 ) outfile << (auryn::sys->get_time()) << " " << voltage << "\n"; } }
void SyncBuffer::push(SpikeDelay * delay, NeuronID size) { for (NeuronID i = 1 ; i < MINDELAY+1 ; ++i ) { SpikeContainer * sc = delay->get_spikes(i); // NeuronID s = (NeuronID) (sc->size()); // send_buf[0] += s; count[i-1] = 0; for (SpikeContainer::const_iterator spike = sc->begin() ; spike != sc->end() ; ++spike ) { NeuronID compressed = *spike + groupPushOffset1 + (i-1)*size; send_buf.push_back(compressed); count[i-1]++; } send_buf[0] += delay->get_spikes(i)->size(); // send the total number of spikes } // transmit get_num_attributes() attributes for count spikes for all time slices if ( delay->get_num_attributes() ) { for (NeuronID i = 1 ; i < MINDELAY+1 ; ++i ) { AttributeContainer * ac = delay->get_attributes(i); for ( NeuronID k = 0 ; k < delay->get_num_attributes() ; ++k ) { // loop over attributes for ( NeuronID s = 0 ; s < count[i-1] ; ++s ) { // loop over spikes send_buf.push_back(*(NeuronID*)(&(ac->at(s+count[i-1]*k)))); // if ( mpicom->rank() == 0 ) // cout << " pushing attr " << " " << i << " " << k << " " << s << " " // << scientific << ac->at(s+count[i-1]*k) << endl; } } } } groupPushOffset1 += size*MINDELAY; }
int main(int ac, char* av[]) { SpikeContainer * sc = new SpikeContainer(); cout << "Loading 1 2 3 ... " << endl; sc->push_back(1); sc->push_back(2); sc->push_back(3); cout << "Reading "; for ( NeuronID * iter = sc->begin() ; iter != sc->end() ; ++iter ) cout << *iter << " "; cout << endl; sc->clear(); cout << "Loading 5 6 7 ... " << endl; sc->push_back(5); sc->push_back(6); sc->push_back(7); cout << "Reading "; for ( NeuronID * iter = sc->begin() ; iter != sc->end() ; ++iter ) cout << *iter << " "; cout << endl; delete sc; return 0; }