Ejemplo n.º 1
0
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;

}
Ejemplo n.º 2
0
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;
}