Auryn simulator  v0.8.1-206-gb56e451
Plastic Spiking Neural Network Simulator
Public Member Functions | List of all members
auryn::SyncBuffer Class Reference

Buffer object to capsulate native MPI_Allgather for SpikingGroups. More...

#include <SyncBuffer.h>

Public Member Functions

 SyncBuffer (mpi::communicator *com)
 The default contructor. More...
 
virtual ~SyncBuffer ()
 The default destructor. More...
 
void sync ()
 Synchronize spikes and additional information across ranks. More...
 
void push (SpikeDelay *delay, const NeuronID size)
 Pushes a spike delay with all its spikes to the SyncBuffer. More...
 
void null_terminate_send_buffer ()
 Terminate send buffer. More...
 
void pop (SpikeDelay *delay, const NeuronID size)
 Rerieves a spike delay with all its spikes from the SyncBuffer. More...
 
int get_max_send_buffer_size ()
 Return max_send_size value which determines the size of the MPI AllGather operation. More...
 
unsigned int get_sync_count ()
 Return sync count since object instantiation. More...
 
unsigned int get_overflow_count ()
 Return overflow count since object instantiation. More...
 

Detailed Description

Buffer object to capsulate native MPI_Allgather for SpikingGroups.

The class stores the recent history of transmission buffer sizes and tries to determine an optimal size on-line.

Constructor & Destructor Documentation

◆ SyncBuffer()

SyncBuffer::SyncBuffer ( mpi::communicator *  com)

The default contructor.

33 {
34  mpicom = com;
35  init();
36 }

◆ ~SyncBuffer()

SyncBuffer::~SyncBuffer ( )
virtual

The default destructor.

39 {
40  delete [] pop_offsets;
41  delete [] pop_delta_spikes;
42  delete [] last_spike_pos;
43 
44  delete [] rank_send_sum;
45  delete [] rank_send_sum2;
46  delete [] rank_recv_count;
47  delete [] rank_displs;
48 }

Member Function Documentation

◆ get_max_send_buffer_size()

int SyncBuffer::get_max_send_buffer_size ( )

Return max_send_size value which determines the size of the MPI AllGather operation.

532 {
533  return max_send_size;
534 }

◆ get_overflow_count()

unsigned int SyncBuffer::get_overflow_count ( )

Return overflow count since object instantiation.

537 {
538  return overflow_counter;
539 }

◆ get_sync_count()

unsigned int SyncBuffer::get_sync_count ( )

Return sync count since object instantiation.

542 {
543  return sync_counter;
544 }

◆ null_terminate_send_buffer()

void SyncBuffer::null_terminate_send_buffer ( )

Terminate send buffer.

155 {
156  // puts a "delta spike" just behind the last unrolled delay of the last group
157  // std::cout << " term " << carry_offset << std::endl;
158  send_buf.push_back(carry_offset);
159 }

◆ pop()

void SyncBuffer::pop ( SpikeDelay delay,
const NeuronID  size 
)

Rerieves a spike delay with all its spikes from the SyncBuffer.

186 {
187  // TODO consider passing the current rank, because in principle it should not require the sync
188 
190 
191  // clear all receiving buffers in the relevant time range
192  for (NeuronID i = 1 ; i < MINDELAY+1 ; ++i ) {
193  delay->get_spikes(i)->clear();
194  delay->get_attributes(i)->clear();
195  }
196 
197  // loop over different rank input segments in recv_buf
198  for (int r = 0 ; r < mpicom->size() ; ++r ) {
199 
200  // when we enter this function we know this is a new group
201  last_spike_pos[r] = 0;
202 
203  //read current difference element from buffer and interpret as unrolled
204  NeuronID * iter = &recv_buf[r*max_send_size+pop_offsets[r]]; // first spike
205 
206  while ( true ) {
207 
208  // std::cout << "have " << pop_delta_spikes[r] << std::endl;
209 
210  if ( pop_delta_spikes[r] == undefined_delta_size ) {
211  // read delta spike value from buffer and update iterator
212  iter = read_delta_spike_from_buffer(iter, pop_delta_spikes[r]);
213  }
214 
215  SYNCBUFFER_DELTA_DATATYPE unrolled_spike = last_spike_pos[r] + pop_delta_spikes[r];
216  if ( unrolled_spike < grid_size ) {
217 
218  // decode spike positon on time slice grid
219  const int slice = unrolled_spike/size;
220  const NeuronID spike = unrolled_spike%size;
221 
222  // push spike to appropriate time slice
223  delay->get_spikes(slice+1)->push_back(spike);
224  // std::cout << "slice " << slice << " spike " << spike << std::endl;
225 
226  // save last position
227  last_spike_pos[r] = unrolled_spike;
228  pop_delta_spikes[r] = undefined_delta_size;
229 
230  // now that we know where the spike belongs we read the spike attributes from the buffer
231  for ( int k = 0 ; k < delay->get_num_attributes() ; ++k ) { // loop over attributes
232  AurynFloat attrib;
233  iter = read_attribute_from_buffer(iter, attrib);
234  delay->get_attributes(slice+1)->push_back(attrib);
235  // std::cout << "read " << std::scientific << attrib << std::endl;
236  }
237 
238  } else {
239  pop_delta_spikes[r] -= (grid_size-last_spike_pos[r]);
240  // std::cout << "keep " << pop_delta_spikes[r] << std::endl;
241  break;
242  }
243  }
244  pop_offsets[r] = iter - &recv_buf[r*max_send_size]; // save offset in recv_buf section
245  }
246 
247  // // TEST TODO comment after testing
248  // for (NeuronID i = 1 ; i < MINDELAY+1 ; ++i ) {
249  // SpikeContainer * myvector = delay->get_spikes(i);
250  // std::sort (myvector->begin(), myvector->end());
251  // }
252 
253 #ifdef DEBUG
254  if ( mpicom->rank() == 0 ) {
255  for ( NeuronID slice = 0 ; slice < MINDELAY ; ++slice ) {
256  if ( delay->get_attributes(slice+1)->size() != delay->get_num_attributes()*delay->get_spikes(slice+1)->size() ) {
257  std::cout << " " << delay->get_spikes(slice+1)->size() << " spikes extracted in time slice " << slice+1 << std::endl
258  << " " << delay->get_attributes(slice+1)->size() << " attributes extracted in time slice " << slice+1
259  << std::endl;
260  }
261  }
262  }
263 #endif // DEBUG
264 }
r
Definition: mkpat.py:9
int get_num_attributes()
Returns the number of spike attributes per spike.
Definition: SpikeDelay.cpp:139
float AurynFloat
Low precision floating point datatype.
Definition: auryn_definitions.h:157
SpikeContainer * get_spikes(unsigned int pos=1)
Returns the spikes at a given delay position.
Definition: SpikeDelay.cpp:85
#define MINDELAY
Switches collection of timing stats in some classes like SyncBuffer and system.
Definition: auryn_definitions.h:82
#define SYNCBUFFER_DELTA_DATATYPE
Datatype used for delta computation should be a "long" for large nets with sparse activity otherwise ...
Definition: SyncBuffer.h:38
AttributeContainer * get_attributes(unsigned int pos=1)
Like get_spikes but returns the spike attributes.
Definition: SpikeDelay.cpp:95
unsigned int NeuronID
NeuronID is an unsigned integeger type used to index neurons in Auryn.
Definition: auryn_definitions.h:151
Here is the call graph for this function:

◆ push()

void SyncBuffer::push ( SpikeDelay delay,
const NeuronID  size 
)

Pushes a spike delay with all its spikes to the SyncBuffer.

102 {
103  // DEBUG
104  // std::cout << "Rank " << mpicom->rank() << "push\n";
105  // delay->print();
106 
108 
109  SYNCBUFFER_DELTA_DATATYPE unrolled_last_pos = 0;
110  // circular loop over different delay bins
111  for (int slice = 0 ; slice < MINDELAY ; ++slice ) {
112  SpikeContainer * sc = delay->get_spikes(slice+1);
113  AttributeContainer * ac = delay->get_attributes(slice+1);
114 
115  // loop over all spikes in current delay time slice
116  for (int i = 0 ;
117  i < sc->size() ;
118  ++i ) {
119  NeuronID spike = sc->at(i);
120  // compute unrolled position in current delay
122  // compute vertical unrolled difference from last spike
123  SYNCBUFFER_DELTA_DATATYPE spike_delta = unrolled_pos + carry_offset - unrolled_last_pos;
124  // memorize current position in slice
125  unrolled_last_pos = unrolled_pos;
126  // discard carry_offset since its only added to the first spike_delta
127  carry_offset = 0;
128 
129  // overflow managment -- should only ever kick in for very very large SpikingGroups and very very sparse activity
130  while ( spike_delta >= max_delta_size ) {
131  send_buf.push_back( max_delta_size );
132  spike_delta -= max_delta_size;
133  }
134 
135  // storing the spike delta (or its remainder) to buffer
136  send_buf.push_back(spike_delta);
137 
138  // append spike attributes here in buffer
139  for ( int k = 0 ; k < delay->get_num_attributes() ; ++k ) { // loop over attributes
140  NeuronID cast_attrib = *(NeuronID*)(&(ac->at(i*delay->get_num_attributes()+k)));
141  send_buf.push_back(cast_attrib);
142  // std::cout << "store " << std::scientific << ac->at(i*delay->get_num_attributes()+k) << " int " << cast_attrib << std::endl;
143  }
144  }
145  }
146 
147  // set save carry_offset which is the remaining difference from the present group
148  // plus because there might be more than one group without a spike ...
149  carry_offset += grid_size-unrolled_last_pos;
150 
151 }
int get_num_attributes()
Returns the number of spike attributes per spike.
Definition: SpikeDelay.cpp:139
std::vector< NeuronID > SpikeContainer
Spike container type. Used for storing spikes.
Definition: auryn_definitions.h:161
std::vector< float > AttributeContainer
Attribute container type. Used for storing spike attributes that are needed for efficient STP impleme...
Definition: auryn_definitions.h:162
SpikeContainer * get_spikes(unsigned int pos=1)
Returns the spikes at a given delay position.
Definition: SpikeDelay.cpp:85
#define MINDELAY
Switches collection of timing stats in some classes like SyncBuffer and system.
Definition: auryn_definitions.h:82
#define SYNCBUFFER_DELTA_DATATYPE
Datatype used for delta computation should be a "long" for large nets with sparse activity otherwise ...
Definition: SyncBuffer.h:38
AttributeContainer * get_attributes(unsigned int pos=1)
Like get_spikes but returns the spike attributes.
Definition: SpikeDelay.cpp:95
unsigned int NeuronID
NeuronID is an unsigned integeger type used to index neurons in Auryn.
Definition: auryn_definitions.h:151
Here is the call graph for this function:

◆ sync()

void SyncBuffer::sync ( )

Synchronize spikes and additional information across ranks.

501 {
502  // allgather seems to be faster on the standard sim_background benchmark
503  // however, replacing the following line by synchronize will run the new
504  // code using Allgatherv in which each rank can send different amounts of data.
505  sync_allgather();
506 }

The documentation for this class was generated from the following files: