Skip to content

Commit fac803f

Browse files
committed
[WIP] Update about and tests
Still need to verify a way to validate this test properly
1 parent 70cee7a commit fac803f

2 files changed

Lines changed: 119 additions & 38 deletions

File tree

docs/speck/the_basics.md

Lines changed: 82 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
The Basics
22
==========
33

4-
Deploying a SNN on devices based on DYNAP-CNN technology involves several steps such as model architecture conversion, placement and parameter quantization.
5-
This package automates this process for the end-user and enables quick deployment and testing of your models on to the dev-kits.
4+
Deploying an SNN on DYNAPCNN-based devices involves several steps, such as model architecture conversion, placement, and parameter quantization.
5+
Sinabs automates this process for the end user and enables quick deployment and testing of your models on the devkits.
66

77
TLDR;
88
-----
@@ -59,7 +59,7 @@ events_out = hw_model(events_in)
5959
Model conversion to DYNAP-CNN core structure
6060
--------------------------------------------
6161

62-
Speck family chips, based on DYNAP-CNN, comprise several `cores` or `layers`.
62+
Speck family chips, based on DYNAPCNN, comprise several `cores` or `layers`.
6363
Each of these `layers` comprises three functionalities:
6464

6565
1. 2D Convolution
@@ -72,33 +72,33 @@ Accordingly, the `DynapcnnLayer` class is a `sequential` model with three layers
7272
2. spk_layer
7373
3. pool_layer
7474

75-
In order to deploy a model onto these chips, the network structure needs to be converted into a sequence of *DynapcnnLayer*s.
75+
To deploy a model on these chips, the network architecture must be converted into a sequence of *DynapcnnLayer*s.
7676
The `DynapcnnNetwork` class automates this model conversion from a sequential `sinabs` spiking neural network into a sequence of *DynapcnnLayer*s.
77-
In addition, it also descretizes/quantizes the parameters to 8 bits (according to the chip specifications).
77+
In addition, it discretizes/quantizes the parameters to 8 bits (per chip specifications).
7878

7979

8080
Layer conversion
8181
----------------
8282

83-
Often, the network architectures comprise of layers such as `AvgPool2d`, `Flatten` or `Linear`.
83+
Often, the network architecture is comprised of layers such as `AvgPool2d`, `Flatten`, or `Linear`.
8484
The chips do not support these layers in their original form and require some transformation.
85-
For instance, while `AvgPool2d` works in simulations, spikes cannot really be averaged. Instead `SumPool2d` is a better fit for spiking networks.
86-
Similarly, a `Linear` layer can be replaced with `Conv2d` with a kernel size 1x1 such that it is compatible with `DynapcnnLayer`.
87-
Instantiating `DynapcnnNetwork` takes care of all such conversions.
85+
For instance, while `AvgPool2d` works in simulations, spikes cannot really be averaged. Instead, `SumPool2d` is a better fit for spiking networks.
86+
Similarly, a `Linear` layer can be replaced with `Conv2d` with a kernel size 1x1, such that it is compatible with `DynapcnnLayer`.
87+
Instantiating `DynapcnnNetwork` handles all such conversions.
8888

8989
Parameter quantization
9090
----------------------
9191

92-
The hardware suppports fixed point weights (8 bits for weights and 16 bits for membrane potentials for instance).
93-
The models trained in pytorch typically use floating point representation of weights.
94-
Setting `discretize=True` converts the model parameters from floating point to fixed point representation while preserving the highest possible precision.
92+
The hardware supports fixed-point weights (8-bit for weights and 16-bit for membrane potentials, for instance).
93+
The models trained in PyTorch typically use a floating-point representation of weights.
94+
Setting `discretize=True` converts the model parameters from floating-point to fixed-point representation while preserving the highest possible precision.
9595

9696
Device selection
9797
----------------
9898

99-
The device naming is inspired by `pytorch` device naming convention ie `DEVICE_TYPE:INDEX`.
99+
The device naming is inspired by `pytorch` device naming convention, i.e., `DEVICE_TYPE:INDEX`.
100100
`speck2fdevkit:0` refers to the _first_ `Speck 2F DevKit` available.
101-
If there are multiple devices of the same kind connected to the PC, then they are referred by higher incremental indices.
101+
If there are multiple devices of the same kind connected to the PC, then they are referred to by higher incremental indices.
102102

103103
To see all the recognized devices, please have a look at the `sinabs.backend.dynapcnn.io.device_types`
104104

@@ -111,7 +111,7 @@ List of devices currently recognized by *samna*
111111
-----------------------------------------------
112112

113113
.. note::
114-
Not all of these are supported by this plugin and not all of these are compatible with DYNAP-CNN
114+
Not all of these are supported by this plugin, and not all of these are compatible with DYNAP-CNN
115115

116116
```
117117
# A map of all device types and their corresponding samna `device_name`
@@ -135,8 +135,7 @@ from sinabs.backend.dynapcnn import io
135135
io.get_all_samna_devices()
136136
```
137137

138-
Finally to get a list of all the supported devices that this plugin supports and allows you to port your models,
139-
you can inspect `ChipFactory.supported_devices`
138+
Finally, to get a list of all supported devices that Sinabs supports and can port your models to, inspect `ChipFactory.supported_devices`.
140139

141140
```python
142141
from sinabs.backend.dynapcnn.chip_factory import ChipFactory
@@ -146,15 +145,15 @@ ChipFactory.supported_devices
146145
Placement of layers on device cores
147146
-----------------------------------
148147

149-
A sequence of *DynapcnnLayer*s (i.e. a model that has been converted to `DynapcnnNetwork`) is ready to be mapped onto the chip cores/layers.
150-
This is done by placing each layer of the model onto a layer on the chip. The exact placement is specified by the parameter `chip_layers_ordering`.
148+
A sequence of *DynapcnnLayer*s (i.e., a model converted to `DynapcnnNetwork`) is ready to be mapped onto chip cores/layers.
149+
This is done by placing each model layer onto a chip layer. The exact placement is specified by the parameter `chip_layers_ordering`.
151150

152-
This is an important parameter because each layer of the model has a certain memory requirement for kernel parameters and neurons.
153-
The chip layers are not homogenous and have a limited amount of memory allocated to each.
154-
Consequently, not all layers on the chip will be compatible with each layer in the model.
151+
This is an essential parameter because each model layer has a specific memory requirement for kernel parameters and neurons.
152+
The chip layers are not homogeneous and have a limited amount of memory allocated to each.
153+
Consequently, not all chip layers will be compatible with every layer in the model.
155154

156-
If the `chip_layers_ordering` is set to `"auto"`, the network is going to be mapped onto the chip based on a placement algorithm.
157-
If the algorithm is unable to place the model onto the chip, it will throw an error message.
155+
If `chip_layers_ordering` is set to `"auto"`, the network is mapped onto the chip using a placement algorithm.
156+
If the algorithm cannot place the model on the chip, it will throw an error.
158157

159158
Some methods helpful for debugging if you run into problems are `ConfigBuilder.get_valid_mapping()` and the object `ConfigBuilder.get_constraints()`.
160159

@@ -165,9 +164,9 @@ Porting model to device
165164
-----------------------
166165

167166
`DynapcnnNetwork` class has an API similar to that of native `pytorch` and its `.to` method.
168-
Similar to porting a model to cpu with `model.to("cpu")` and GPU with `model.to("cuda:0")` you can also port your `DynapcnnCompatibleModel` to a chip with `model.to("speck2fdevkit:0")`.
167+
Similar to porting a model to CPU with `model.to("cpu")` and GPU with `model.to("cuda:0")`, you can also port your `DynapcnnCompatibleModel` to a chip with `model.to("speck2fdevkit:0")`.
169168

170-
You can also specify a few additional parameters as shown below.
169+
You can also specify a few additional parameters, as shown below:
171170

172171
```python
173172
hw_model.to(
@@ -178,33 +177,78 @@ hw_model.to(
178177
)
179178
```
180179

181-
As shown in the above example, you can specify which layers are to be monitored.
182-
Note here that the layer indices are that of the model. For instance -1 refers to the last layer of the model.
183-
In addition, for advanced users, a `config_modifier` can be passed.
184-
This is a `callable` or a function that takes a config object and does any custom setting changes before writing this on the chip.
180+
As shown in the example above, you can specify which layers to monitor.
181+
Note here that the layer indices are those of the model. For instance, -1 refers to the model's last layer.
182+
In addition, advanced users can pass a `config_modifier`.
183+
This is a `callable`, or a function that takes a config object and applies any custom configuration changes before writing it to the chip.
185184

186185
See the `__doc__` string for further details on each of these parameters.
187186

188187
Sending and receiving spikes
189188
----------------------------
190189

191-
You can send a pre-defined sequence of events to the chip using the model's forward method as you do with standard `pytorch` models.
190+
You can send a pre-defined sequence of events to the chip using the model's forward method, as you do with standard `pytorch` models.
192191

193192
```python
194193
events_out = hw_model(events_in)
195194
```
196195

197196
The `events_in` has to be a list of `Spike` objects corresponding to the chip in use.
198-
Similarly `events_out` will also be a list of `Spike` objects corresponding to the events generated from the monitored layers.
199-
Each `Spike` event has attributes `layer`, `x`, `y`, `feature` and `timestamp`.
197+
Similarly, `events_out` will also be a list of `Spike` objects corresponding to the events generated from the monitored layers.
198+
Each `Spike` event has attributes `layer`, `x`, `y`, `feature`, and `timestamp`.
200199

201200

202201
Monitoring layer activity
203202
-------------------------
204203

205-
In order to monitor the spiking activity of a given layer, the corresponding layer has to be specified in the `monitor_layers` parameter.
206-
In most use cases, you will want to monitor the activity of the last layer of the model and so this parameter will be set to [-1].
204+
To monitor the spiking activity of a given layer, the corresponding layer has to be specified in the `monitor_layers` parameter.
205+
In most use cases, you will want to monitor the activity of the last layer of the model, and so this parameter will be set to [-1].
206+
207+
Once enabled, all corresponding spikes will appear in the sequence of returned events from the chip.
208+
The `samna_output_buffer` accumulates all events emitted by the chip, including those from the monitored layers.
209+
The events from this buffer are read and returned to the user when the forward method is called.
210+
211+
Recording data from hardware
212+
----------------------------
213+
214+
If you want to record data from the speck sensor for a given duration, a simple way to do so is by:
215+
216+
Instantiate a DynapcnnNetwork with a sequential model that only contains a DVSLayer.
217+
218+
```python
219+
shape = (128, 128)
220+
layers = [
221+
DVSLayer(
222+
input_shape=shape,
223+
),
224+
]
225+
snn = nn.Sequential(*layers)
226+
227+
dynapcnn = DynapcnnNetwork(
228+
snn=snn, dvs_input=True, discretize=True
229+
)
230+
```
231+
232+
Deploy that network onto the chip with the `to` method, passing monitor_layers = ["dvs"]
233+
234+
235+
```python
236+
dynapcnn.to(device="speck2fdevkit:0", monitor_layers=["dvs"])
237+
238+
```
239+
240+
To record, call the forward method of the DynapcnnNetwork instance with a list containing a single dummy event whose timestamp equals the desired recording duration (in microseconds).
241+
242+
243+
```python
244+
factory = ChipFactory("speck2fdevkit")
245+
Spike = factory.get_config_builder().get_samna_module().event.Spike
246+
247+
input_data = [Spike(timestamp=10),]
248+
events_out = dynapcnn(input_data)
249+
250+
```
251+
252+
The return value will be a list of all events recorded from the DVS within the specified duration.
253+
207254

208-
Once enabled, all the corresponding spikes will be found in the sequence of returned events from the chip.
209-
The `samna_output_buffer` accumulates all the events sent out by the chip, including those from the monitored layers.
210-
The events from this buffer are then read out and returned to the user on calling the forward method.

tests/test_dynapcnn/test_dvs_input.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,40 @@ def test_whether_dvs_mirror_cfg_is_all_switched_off(dvs_input, pool):
325325
assert samna_cfg.dvs_layer.mirror.x is False
326326
assert samna_cfg.dvs_layer.mirror.y is False
327327
assert samna_cfg.dvs_layer.mirror_diagonal is False
328+
329+
330+
def test_record_dvs_input():
331+
from torch import nn
332+
333+
from sinabs.backend.dynapcnn import DynapcnnNetwork
334+
from sinabs.backend.dynapcnn.chip_factory import ChipFactory
335+
336+
shape = (128, 128)
337+
layers = [
338+
DVSLayer(
339+
input_shape=shape,
340+
),
341+
]
342+
snn = nn.Sequential(*layers)
343+
344+
dynapcnn = DynapcnnNetwork(snn=snn, dvs_input=True, discretize=True)
345+
346+
# Deploy model to a dev-kit
347+
dynapcnn.to(device="speck2fdevkit:0", monitor_layers=["dvs"])
348+
349+
factory = ChipFactory("speck2fdevkit")
350+
351+
Spike = factory.get_config_builder().get_samna_module().event.Spike
352+
353+
input_data = [
354+
Spike(timestamp=10),
355+
]
356+
357+
print(input_data)
358+
events_out = dynapcnn(input_data)
359+
360+
# print(events_out)
361+
362+
print(len(events_out))
363+
364+
assert False

0 commit comments

Comments
 (0)