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 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"; } }