Simple SNN for retina input

51 views
Skip to first unread message

Vaggelis Ntouros

unread,
Mar 9, 2022, 10:01:25 AM3/9/22
to SpiNNaker Users Group
Hello all,

I am using a DVS which is connected with SpiNN-3 board using an FPGA and spinnaker link. I used a custom implementation for the FPGA design which supports injecting spikes in SpiNN-3 but does not support outgoing packets. The virtual key is chosen as 0xFEFE.

I try now to set up a simple script that has the input population and one more that will send spikes through ethernet with live output mechanism.

So, I started the simulation and sent the packet 0xFEFE0202 4 times. The output log can be seen in log.txt file. I could not receive any live output from the population. Any ideas what might be wrong in my script? (seen in dvs_hello_world.py file)

To implement the script I followed the source code for ExternalFPGARetinaDevice seen here. https://spinnaker8manchester.readthedocs.io/en/latest/_modules/spynnaker/pyNN/external_devices_models/external_spinnaker_link_fpga_retina_device/#ExternalFPGARetinaDevice. During the implementation the following questions came up:

1) Since I have not implemented a bidirectional communication via the spinnaker link is it possible to avoid sending start and stop commands? I assumed these are optional if one can handle when the spikes are actually injected in SpiNN-3 board. But I saw in the logs that there is a wait for a start command.

2022-03-09 16:55:24 INFO: ** Awaiting for a response from an external source to state its ready for the simulation to start **
2022-03-09 16:55:24 INFO: ** Sending start / resume message to external sources to state the simulation has started or resumed. **
2022-03-09 16:55:24 INFO: ** Awaiting for a response from an external source to state its ready for the simulation to start **
2022-03-09 16:55:24 INFO: Application started; waiting 10.1s for it to stop
2022-03-09 16:55:34 INFO: ** Sending pause / stop message to external sources to state the simulation has been paused or stopped. **


2) This application is intended to be used in a robot. How can I make the script run forever? Should I give a big number of milliseconds, say p.run(1000000)?  

Vaggelis
dvs_hello_world.py
log.txt

Andrew Rowley

unread,
Mar 9, 2022, 10:43:58 AM3/9/22
to Vaggelis Ntouros, SpiNNaker Users Group

Hi,

 

The script looks OK and the log is showing no issues that I can see. 

 

The tools let you specify in your device which SpiNNaker link the device is connected to.  The SpiNN-3 boards have two: id 0 is the J2 and id 1 is J1 from memory (.  It may be worth checking which one you have connected to and making sure that the software has the right one selected (I can see you have selected 0 so far, so you could try switching to 1).  An additional issue could be that the output population is connected using a fixed probability connector.  A possibly simpler solution would be something like an all-to-all connector to ensure that every source connects to a target (though I can see that you should get at least one target for each source with the probability you have chosen).

 

1) You don’t need start and stop commands, they are just there to help you if you want them.  The only thing to be sure of is that you don’t send lots of packets into SpiNNaker before the simulation actually starts i.e. before the main executables are loaded and running, as this can stop the simulation working correctly e.g. you might find that it doesn’t boot or fails to load things.  If you have something external that can stop the sending until things start, you should be OK (and also stop sending when things stop as otherwise the same will be true for getting data back out).

 

2) There is a p.external_devices.run_forever() command.  This will freeze the script at this point.  It is possible to then manually stop the simulation with p.external_devices.request_stop() (which then has to be run from another thread, or else the run_forever command has to be called from another thread).

 

Let us know if you continue to have issues and we can see if we can help to debug them.

 

Andrew :)

 

--
You received this message because you are subscribed to the Google Groups "SpiNNaker Users Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to spinnakeruser...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/spinnakerusers/792b9d3a-d748-45dd-bf85-cf7925f6809bn%40googlegroups.com.

Vaggelis Ntouros

unread,
Mar 9, 2022, 2:10:47 PM3/9/22
to SpiNNaker Users Group
Andrew,

It seems that I missed the p.external_devices.activate_live_output_for() part. It receives spikes now, using a fixed probability connector. Anyway, your advice about the one to one connector is the next step now.

Since the input is 128*128*2 (128x128 retina) I can not have a population that large. So I tried to map the first, lets say 10 inputs to one neuron, then the next 10 to another etc. Unfortunatelly, I am a bit confused on how this would be implemented. I think that the confusion occurs because I am not sure how the input is driven to the neurons of the population in the first place.

Lets assume that the packet 0xfefe0202 arrives. That means (x,y,polarity) = (2,1,0). In Which neuron would this input go if there was a (theoretical) 128*128*2 population connected with one to one connection to the input?

Thanks,
Vaggelis

Andrew Rowley

unread,
Mar 10, 2022, 3:07:42 AM3/10/22
to Vaggelis Ntouros, SpiNNaker Users Group

Hi,

 

In the current software, the neurons are linearly numbered, so a packet 0xfefe0202 with routing mask 0xffff0000 will have source neuron id 0x0202 = 514.  I don’t think we have a connector that will connect the neurons 10-1, so you may be stuck with a FromListConnector for now.  This would then just be done as a list e.g.

connections = [(i, i // 10) for i in range(128*128*2)]

 

Andrew :)

 

Vaggelis Ntouros

unread,
Mar 10, 2022, 11:49:00 AM3/10/22
to SpiNNaker Users Group
Hi Andrew, thanks again for your assistance. I managed to implement a mapping from the input 128*128*2 to a population of 64*64*2 with weight=5 and delay=1.

I inject controlled spikes (I simulate a retina with an MCU) via spinnaker link. The rate is 1000 events per second and each input spike "goes" to the next neuron of the 64*64*2 population. So each neuron should spike once in a sweeping way.

As soon as the simulation is over I see the logging from live output and around 40 spikes have not been reported. Also I see the following

These log messages where generated at level WARNING or above
/home/giorgio/octopus/git_projects/spinnaker/reports has 7 old reports that have not been closed
19 packets from pop_1:0:255 on 1, 1, 2 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:256:511 on 1, 0, 2 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
20 packets from pop_1:512:767 on 0, 1, 2 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
15 packets from pop_1:768:1023 on 0, 0, 4 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
15 packets from pop_1:1024:1279 on 0, 0, 5 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:1280:1535 on 0, 1, 3 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
20 packets from pop_1:1536:1791 on 1, 0, 3 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:1792:2047 on 1, 1, 3 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:2048:2303 on 1, 1, 4 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:2304:2559 on 1, 0, 4 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:2560:2815 on 0, 1, 4 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
14 packets from pop_1:2816:3071 on 0, 0, 6 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
13 packets from pop_1:3072:3327 on 0, 0, 7 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
20 packets from pop_1:3328:3583 on 0, 1, 5 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:3584:3839 on 1, 0, 5 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:3840:4095 on 1, 1, 5 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:4096:4351 on 1, 1, 6 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:4352:4607 on 1, 0, 6 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:4608:4863 on 0, 1, 6 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
12 packets from pop_1:4864:5119 on 0, 0, 8 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
12 packets from pop_1:5120:5375 on 0, 0, 9 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
16 packets from pop_1:5376:5631 on 0, 1, 7 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:5632:5887 on 1, 0, 7 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
15 packets from pop_1:5888:6143 on 1, 1, 7 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:6144:6399 on 1, 1, 8 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
15 packets from pop_1:6400:6655 on 1, 0, 8 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
19 packets from pop_1:6656:6911 on 0, 1, 8 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:6912:7167 on 0, 0, 10 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
15 packets from pop_1:7168:7423 on 0, 0, 11 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:7424:7679 on 0, 1, 9 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:7680:7935 on 1, 0, 9 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.
18 packets from pop_1:7936:8191 on 1, 1, 9 were dropped from the input buffer, because they arrived too late to be processed in a given time step. Try increasing the time_scale_factor located within the .spynnaker.cfg file or in the pynn.setup() method.

What would that happen? I disabled live output and the warnings insist so they have to be relevant to the input from spinnaker link. It is weird since the event rate is fairly low and I do not even feed the same neuron again.

Vaggelis

Andrew Rowley

unread,
Mar 11, 2022, 3:46:39 AM3/11/22
to Vaggelis Ntouros, SpiNNaker Users Group

Hi,

 

Yes, I can see the issue.  This is because the timing between the devices isn’t likely to match up… The solution for now is to disable the dropping of spikes at the end of the timestep, which is done by modifying your .spynnaker.cfg file in your home directory, and adding:

[Simulation]

drop_late_spikes = False

 

This should then avoid dropping of spikes.

 

Andrew :)

 

ntouev

unread,
Mar 11, 2022, 10:44:20 AM3/11/22
to Andrew Rowley, SpiNNaker Users Group
Andrew,

that works fine! After you suggested change the late packets are not dropped. Though I would like to understand some things about that:

1) Is it normal to have timing issues? Does this happen with the verilog implementation of the interface you have developed too, or should I modify my design accordingly? This is more of a HW related question.
2) Now that the late packets are not dropped, are they routed correctly to the population in the next timestep?

Vaggelis

Andrew Rowley

unread,
Mar 11, 2022, 10:55:17 AM3/11/22
to ntouev, SpiNNaker Users Group

Hi,

 

In general when there are no external devices, we expect spikes from a certain time step to arrive within that time step.  We then hopefully can process them within the time step so that they are used in the next time step.  When you are using an external device, there is no synchronization with that device and generally you don’t care that much about the time step in which a spike arrives; the device sends when it wants to, so that could easily be the moment just before the cores decide the time step is finished and then flush received spikes (for reference before we had inter-board synchronization in the software, this would quite often happen with multi-board simulations as well).  So it isn’t something that you need to worry about, it is just an option in the software.  I guess we could make it so that adding a device will turn the option off by default, at least on cores that receive from the device.

 

In terms of the timing of the arrival of the spike, if the network on SpiNNaker is not too congested, spikes will likely arrive very quickly at the cores they are intended for.  The core will put it in a queue of all spikes received and process it as soon as it can, either in the “current” time step or the next one (and if it is getting lots of spikes, it might even process it much later than that).

 

I hope that helps to clear things up!

 

Andrew :)

Reply all
Reply to author
Forward
0 new messages