sc_neurocore_engine/neurons/hardware/
loihi2.rs1#[derive(Clone, Debug)]
11pub struct Loihi2Neuron {
12 pub s1: i32,
13 pub s2: i32,
14 pub s3: i32,
15 pub tau1: i32,
16 pub tau2: i32,
17 pub tau3: i32,
18 pub w12: i32,
19 pub w13: i32,
20 pub w23: i32,
21 pub s1_threshold: i32,
22 pub s1_reset: i32,
23 pub s3_incr: i32,
24}
25
26impl Loihi2Neuron {
27 pub fn new() -> Self {
28 Self {
29 s1: 0,
30 s2: 0,
31 s3: 0,
32 tau1: 10,
33 tau2: 5,
34 tau3: 50,
35 w12: 1,
36 w13: 0,
37 w23: 0,
38 s1_threshold: 1000,
39 s1_reset: 0,
40 s3_incr: 10,
41 }
42 }
43 pub fn step(&mut self, weighted_input: i32) -> i32 {
44 self.s3 -= self.s3 / self.tau3;
45 self.s2 = self.s2 - self.s2 / self.tau2 + weighted_input + self.w23 * self.s3;
46 self.s1 = self.s1 - self.s1 / self.tau1 + self.w12 * self.s2 + self.w13 * self.s3;
47 if self.s1 >= self.s1_threshold {
48 self.s1 = self.s1_reset;
49 self.s3 += self.s3_incr;
50 1
51 } else {
52 0
53 }
54 }
55 pub fn reset(&mut self) {
56 self.s1 = 0;
57 self.s2 = 0;
58 self.s3 = 0;
59 }
60}
61impl Default for Loihi2Neuron {
62 fn default() -> Self {
63 Self::new()
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn loihi2_fires() {
73 let mut n = Loihi2Neuron {
74 tau3: 8,
75 ..Loihi2Neuron::new()
76 };
77 let t: i32 = (0..500).map(|_| n.step(200)).sum();
78 assert!(t > 0);
79 }
80 #[test]
81 fn loihi2_silent() {
82 let mut n = Loihi2Neuron::new();
83 let t: i32 = (0..200).map(|_| n.step(0)).sum();
84 assert_eq!(t, 0);
85 }
86 #[test]
87 fn loihi2_reset() {
88 let mut n = Loihi2Neuron::new();
89 for _ in 0..50 {
90 n.step(200);
91 }
92 n.reset();
93 assert_eq!(n.s1, 0);
94 }
95 #[test]
96 fn loihi2_bounded() {
97 let mut n = Loihi2Neuron {
98 tau3: 8,
99 ..Loihi2Neuron::new()
100 };
101 for _ in 0..1000 {
102 n.step(10000);
103 }
104 }
105}