예제 #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;

}
예제 #2
0
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";
	}
}