Skip to content

Commit e6143e6

Browse files
authored
Spiker with 32bit
1 parent a6ff427 commit e6143e6

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

src/lava/proc/spiker/process.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# See: https://spdx.org/licenses/
44

55
import typing as ty
6+
import numpy.typing as npty
67

78
import numpy as np
89
from lava.magma.core.process.ports.ports import OutPort
@@ -19,6 +20,7 @@ class Spiker(AbstractProcess):
1920
Shape of the population of process units.
2021
period : int
2122
Number of timesteps between subsequent emissions of payload.
23+
Note that the first spike is emitted at time step period + 1.
2224
payload : int
2325
A value to be send with every output message.
2426
name : str
@@ -39,3 +41,74 @@ def __init__(self, *,
3941
self.rate = Var(shape=shape, init=period)
4042
self.counter = Var(shape=shape, init=np.zeros(shape).astype(int))
4143
self.payload = Var(shape=shape, init=payload)
44+
45+
46+
class Spiker32bit(AbstractProcess):
47+
"""Process emitting a specified payload at a given rate.
48+
Provides 32bit payloads, and separate payloads for each neuron.
49+
Other than the default Spiker process, this process actually starts spiking
50+
at timestep = period.
51+
52+
Parameters
53+
----------
54+
shape : tuple(int)
55+
Shape of the population of process units.
56+
period : int
57+
Number of timesteps between subsequent emissions of payload.
58+
payload : int
59+
A value to be send with every output message.
60+
Can be in [0, 2**32 - 1] if signed==False,
61+
or in [-2**31, 2**31 - 1] if signed==True.
62+
signed : bool
63+
True if signed payload, False otherwise.
64+
name : str
65+
Name of the Process. Default is 'Process_ID', where ID is an
66+
integer value that is determined automatically.
67+
log_config : LogConfig
68+
Configuration options for logging.
69+
"""
70+
71+
def __init__(self, *,
72+
shape: ty.Tuple[int, ...] = (1,),
73+
period: ty.Union[int, npty.ArrayLike] = 1,
74+
payload: ty.Union[int, npty.ArrayLike] = 1,
75+
name: ty.Optional[str] = None,
76+
log_config: ty.Optional[LogConfig] = None) -> None:
77+
78+
signed = self._input_validation(payload)
79+
80+
if np.isscalar(period):
81+
period = np.array([period], dtype=int)
82+
else:
83+
period = period.astype(int)
84+
if np.isscalar(payload):
85+
payload = np.array([payload])
86+
else:
87+
payload = payload.astype(int)
88+
89+
super().__init__(shape=shape,
90+
period=period,
91+
payload=payload,
92+
signed=signed,
93+
name=name, log_config=log_config)
94+
self.s_out = OutPort(shape=shape)
95+
self.counter = Var(shape=shape, init=np.zeros(shape).astype(int) + 1)
96+
97+
def _input_validation(self, payload) -> bool:
98+
payload_min = np.min(payload)
99+
payload_max = np.max(payload)
100+
signed = payload_min < 0
101+
102+
if payload_min < -2 ** 31:
103+
raise ValueError(
104+
f"The payload must be >= -2**31, but the smallest value is "
105+
f"{payload_min}.")
106+
107+
payload_max_allowed = 2 ** 31 - 1 if signed else 2 ** 32 - 1
108+
109+
if payload_max > payload_max_allowed:
110+
raise ValueError(
111+
f"The payload must be <= {payload_max_allowed}, but the "
112+
f"largest value is {payload_max}.")
113+
114+
return signed

0 commit comments

Comments
 (0)