How To Leak The Neurons On The Devkit

How To Leak The Neurons On The Devkit#

To leak the neuron, all you need to do are:

  • Make sure you have a bias term for the torch.nn.Module.

  • Setting the external slow-clock frequency.

Then the bias term will be added to the neuron’s membrane potential at every clock cycle.

import torch
import time
import samna
from torch import nn
from sinabs.layers import IAFSqueeze
from sinabs.backend.dynapcnn import DynapcnnNetwork
from sinabs.backend.dynapcnn.io import calculate_neuron_address, neuron_address_to_cxy
# Define a SNN with bias term on the Convolution Layer

snn = nn.Sequential(
    nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(1, 1), bias=True),
    IAFSqueeze(min_v_mem=-1.0, spike_threshold=1.0, batch_size=1),
)

input_shape = (1, 2, 2)
# Set artificial values for vmem and bias

weight_value = 1.0
bias_value = -0.1
vmem_value = 1.0
snn[0].weight.data = torch.ones_like(snn[0].weight.data) * weight_value
snn[0].bias.data = torch.ones_like(snn[0].bias.data) * bias_value

# init the v_mem as 1.0(which means as same as the threshold)

_ = snn(torch.zeros(1, *input_shape))
snn[1].v_mem.data = torch.ones_like(snn[1].v_mem.data) * vmem_value
# Create samna ReadNeuronValue for inpecting the value of the Vmem

input_events = []

# create ReadNeuronValue event as input
for x in range(input_shape[2]):
    for y in range(input_shape[1]):
        ev = samna.speck2f.event.ReadNeuronValue()
        ev.layer = 0
        # output feature map size is the same as the input shape
        ev.address = calculate_neuron_address(x=x, y=y, c=0, feature_map_size=input_shape)
        input_events.append(ev)
        
input_events
[speck2f::event::ReadNeuronValue(layer=0, address=0),
 speck2f::event::ReadNeuronValue(layer=0, address=2),
 speck2f::event::ReadNeuronValue(layer=0, address=1),
 speck2f::event::ReadNeuronValue(layer=0, address=3)]
# Deploy the snn to speck devkit

dynapcnn = DynapcnnNetwork(snn=snn, discretize=True, dvs_input=False, input_shape=input_shape)
# don't forget to set the slow clock frequency!
# here we set the frequency to 1Hz, which mean the Vmem should decrease after every 1 second 
dynapcnn.to(device="speck2fmodule", slow_clk_frequency=1)

# Check if neuron states decrease along with time pass by

neuron_states = dict()

for iter_times in range(1, 21):
    # write input
    dynapcnn.samna_input_buffer.write(input_events)
    time.sleep(0.5)
    print(f'----After {0.5 * iter_times} seconds:----')
    # get outputs
    output_events = dynapcnn.samna_output_buffer.get_events()

    for out_ev in output_events:
        c, x, y = neuron_address_to_cxy(out_ev.address, feature_map_size=input_shape)
        pre_neuron_state = neuron_states.get((c, x, y), 127)
        neuron_states.update({(c, x, y): out_ev.neuron_state})
        print(f"c:{c}, x:{x}, y:{y}, vmem:{out_ev.neuron_state}")
    
Network is valid
----After 0.5 seconds:----
c:0, x:0, y:0, vmem:101
c:0, x:0, y:1, vmem:101
c:0, x:1, y:0, vmem:101
c:0, x:1, y:1, vmem:101
----After 1.0 seconds:----
c:0, x:0, y:0, vmem:101
c:0, x:0, y:1, vmem:101
c:0, x:1, y:0, vmem:101
c:0, x:1, y:1, vmem:101
----After 1.5 seconds:----
c:0, x:0, y:0, vmem:88
c:0, x:0, y:1, vmem:88
c:0, x:1, y:0, vmem:88
c:0, x:1, y:1, vmem:88
----After 2.0 seconds:----
c:0, x:0, y:0, vmem:88
c:0, x:0, y:1, vmem:88
c:0, x:1, y:0, vmem:88
c:0, x:1, y:1, vmem:88
----After 2.5 seconds:----
c:0, x:0, y:0, vmem:75
c:0, x:0, y:1, vmem:75
c:0, x:1, y:0, vmem:75
c:0, x:1, y:1, vmem:75
----After 3.0 seconds:----
c:0, x:0, y:0, vmem:75
c:0, x:0, y:1, vmem:75
c:0, x:1, y:0, vmem:75
c:0, x:1, y:1, vmem:75
----After 3.5 seconds:----
c:0, x:0, y:0, vmem:62
c:0, x:0, y:1, vmem:62
c:0, x:1, y:0, vmem:62
c:0, x:1, y:1, vmem:62
----After 4.0 seconds:----
c:0, x:0, y:0, vmem:62
c:0, x:0, y:1, vmem:62
c:0, x:1, y:0, vmem:62
c:0, x:1, y:1, vmem:62
----After 4.5 seconds:----
c:0, x:0, y:0, vmem:49
c:0, x:0, y:1, vmem:49
c:0, x:1, y:0, vmem:49
c:0, x:1, y:1, vmem:49
----After 5.0 seconds:----
c:0, x:0, y:0, vmem:49
c:0, x:0, y:1, vmem:49
c:0, x:1, y:0, vmem:49
c:0, x:1, y:1, vmem:49
----After 5.5 seconds:----
c:0, x:0, y:0, vmem:36
c:0, x:0, y:1, vmem:36
c:0, x:1, y:0, vmem:36
c:0, x:1, y:1, vmem:36
----After 6.0 seconds:----
c:0, x:0, y:0, vmem:36
c:0, x:0, y:1, vmem:36
c:0, x:1, y:0, vmem:36
c:0, x:1, y:1, vmem:36
----After 6.5 seconds:----
c:0, x:0, y:0, vmem:23
c:0, x:0, y:1, vmem:23
c:0, x:1, y:0, vmem:23
c:0, x:1, y:1, vmem:23
----After 7.0 seconds:----
c:0, x:0, y:0, vmem:23
c:0, x:0, y:1, vmem:23
c:0, x:1, y:0, vmem:23
c:0, x:1, y:1, vmem:23
----After 7.5 seconds:----
c:0, x:0, y:0, vmem:10
c:0, x:0, y:1, vmem:10
c:0, x:1, y:0, vmem:10
c:0, x:1, y:1, vmem:10
----After 8.0 seconds:----
c:0, x:0, y:0, vmem:10
c:0, x:0, y:1, vmem:10
c:0, x:1, y:0, vmem:10
c:0, x:1, y:1, vmem:10
----After 8.5 seconds:----
c:0, x:0, y:0, vmem:-3
c:0, x:0, y:1, vmem:-3
c:0, x:1, y:0, vmem:-3
c:0, x:1, y:1, vmem:-3
----After 9.0 seconds:----
c:0, x:0, y:0, vmem:-3
c:0, x:0, y:1, vmem:-3
c:0, x:1, y:0, vmem:-3
c:0, x:1, y:1, vmem:-3
----After 9.5 seconds:----
c:0, x:0, y:0, vmem:-16
c:0, x:0, y:1, vmem:-16
c:0, x:1, y:0, vmem:-16
c:0, x:1, y:1, vmem:-16
----After 10.0 seconds:----
c:0, x:0, y:0, vmem:-16
c:0, x:0, y:1, vmem:-16
c:0, x:1, y:0, vmem:-16
c:0, x:1, y:1, vmem:-16