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