CharlesCNorton commited on
Commit
5334ac8
·
0 Parent(s):

Add 4-bit buffer threshold circuit

Browse files

4 neurons, 1 layer, 20 parameters, magnitude 8.

Files changed (6) hide show
  1. .gitattributes +1 -0
  2. README.md +83 -0
  3. config.json +9 -0
  4. create_safetensors.py +66 -0
  5. model.py +24 -0
  6. model.safetensors +3 -0
.gitattributes ADDED
@@ -0,0 +1 @@
 
 
1
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ ---
9
+
10
+ # threshold-buffer
11
+
12
+ 4-bit buffer (identity function). Passes input through unchanged.
13
+
14
+ ## Function
15
+
16
+ buffer4(x3, x2, x1, x0) -> (y3, y2, y1, y0)
17
+
18
+ Output equals input: y_i = x_i for all i.
19
+
20
+ ## Truth Table
21
+
22
+ | Input | Output |
23
+ |-------|--------|
24
+ | 0000 | 0000 |
25
+ | 0001 | 0001 |
26
+ | ... | ... |
27
+ | 1111 | 1111 |
28
+
29
+ ## Architecture
30
+
31
+ Single-layer, each output independently buffers one input:
32
+
33
+ ```
34
+ x3 x2 x1 x0
35
+ │ │ │ │
36
+ ▼ ▼ ▼ ▼
37
+ ○ ○ ○ ○ Layer 1
38
+ │ │ │ │
39
+ ▼ ▼ ▼ ▼
40
+ y3 y2 y1 y0
41
+ ```
42
+
43
+ Each neuron: w=[...,1,...], b=-1 (single input with weight 1).
44
+
45
+ ## Parameters
46
+
47
+ | | |
48
+ |---|---|
49
+ | Inputs | 4 |
50
+ | Outputs | 4 |
51
+ | Neurons | 4 |
52
+ | Layers | 1 |
53
+ | Parameters | 20 |
54
+ | Magnitude | 8 |
55
+
56
+ ## Purpose
57
+
58
+ While trivial, buffers serve several purposes:
59
+ - Signal regeneration in long chains
60
+ - Fan-out amplification
61
+ - Timing alignment
62
+ - Isolation between circuit stages
63
+
64
+ ## Usage
65
+
66
+ ```python
67
+ from safetensors.torch import load_file
68
+ import torch
69
+
70
+ w = load_file('model.safetensors')
71
+
72
+ def buffer(x3, x2, x1, x0):
73
+ inp = torch.tensor([float(x3), float(x2), float(x1), float(x0)])
74
+ y0 = int((inp @ w['y0.weight'].T + w['y0.bias'] >= 0).item())
75
+ y1 = int((inp @ w['y1.weight'].T + w['y1.bias'] >= 0).item())
76
+ y2 = int((inp @ w['y2.weight'].T + w['y2.bias'] >= 0).item())
77
+ y3 = int((inp @ w['y3.weight'].T + w['y3.bias'] >= 0).item())
78
+ return y3, y2, y1, y0
79
+ ```
80
+
81
+ ## License
82
+
83
+ MIT
config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "threshold-buffer",
3
+ "description": "4-bit buffer (identity)",
4
+ "inputs": 4,
5
+ "outputs": 4,
6
+ "neurons": 4,
7
+ "layers": 1,
8
+ "parameters": 20
9
+ }
create_safetensors.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import save_file
3
+
4
+ weights = {}
5
+
6
+ # 4-bit Buffer (identity function)
7
+ # Inputs: x3, x2, x1, x0
8
+ # Outputs: y3, y2, y1, y0 (same as inputs)
9
+ #
10
+ # Each output is a threshold neuron that fires when input >= 1
11
+ # y_i = 1 iff x_i = 1
12
+
13
+ # y0 = x0
14
+ weights['y0.weight'] = torch.tensor([[0.0, 0.0, 0.0, 1.0]], dtype=torch.float32)
15
+ weights['y0.bias'] = torch.tensor([-1.0], dtype=torch.float32)
16
+
17
+ # y1 = x1
18
+ weights['y1.weight'] = torch.tensor([[0.0, 0.0, 1.0, 0.0]], dtype=torch.float32)
19
+ weights['y1.bias'] = torch.tensor([-1.0], dtype=torch.float32)
20
+
21
+ # y2 = x2
22
+ weights['y2.weight'] = torch.tensor([[0.0, 1.0, 0.0, 0.0]], dtype=torch.float32)
23
+ weights['y2.bias'] = torch.tensor([-1.0], dtype=torch.float32)
24
+
25
+ # y3 = x3
26
+ weights['y3.weight'] = torch.tensor([[1.0, 0.0, 0.0, 0.0]], dtype=torch.float32)
27
+ weights['y3.bias'] = torch.tensor([-1.0], dtype=torch.float32)
28
+
29
+ save_file(weights, 'model.safetensors')
30
+
31
+ def buffer4(x3, x2, x1, x0):
32
+ inp = torch.tensor([float(x3), float(x2), float(x1), float(x0)])
33
+
34
+ y0 = int((inp @ weights['y0.weight'].T + weights['y0.bias'] >= 0).item())
35
+ y1 = int((inp @ weights['y1.weight'].T + weights['y1.bias'] >= 0).item())
36
+ y2 = int((inp @ weights['y2.weight'].T + weights['y2.bias'] >= 0).item())
37
+ y3 = int((inp @ weights['y3.weight'].T + weights['y3.bias'] >= 0).item())
38
+
39
+ return y3, y2, y1, y0
40
+
41
+ print("Verifying 4-bit Buffer...")
42
+ errors = 0
43
+ for i in range(16):
44
+ x3, x2, x1, x0 = (i >> 3) & 1, (i >> 2) & 1, (i >> 1) & 1, i & 1
45
+ y3, y2, y1, y0 = buffer4(x3, x2, x1, x0)
46
+ if (y3, y2, y1, y0) != (x3, x2, x1, x0):
47
+ errors += 1
48
+ print(f"ERROR: ({x3},{x2},{x1},{x0}) -> ({y3},{y2},{y1},{y0})")
49
+
50
+ if errors == 0:
51
+ print("All 16 test cases passed!")
52
+ else:
53
+ print(f"FAILED: {errors} errors")
54
+
55
+ print("\nTruth Table:")
56
+ print("x3 x2 x1 x0 | y3 y2 y1 y0")
57
+ print("-" * 26)
58
+ for i in range(16):
59
+ x3, x2, x1, x0 = (i >> 3) & 1, (i >> 2) & 1, (i >> 1) & 1, i & 1
60
+ y3, y2, y1, y0 = buffer4(x3, x2, x1, x0)
61
+ print(f" {x3} {x2} {x1} {x0} | {y3} {y2} {y1} {y0}")
62
+
63
+ mag = sum(t.abs().sum().item() for t in weights.values())
64
+ print(f"\nMagnitude: {mag:.0f}")
65
+ print(f"Parameters: {sum(t.numel() for t in weights.values())}")
66
+ print(f"Neurons: {len([k for k in weights.keys() if 'weight' in k])}")
model.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import load_file
3
+
4
+ def load_model(path='model.safetensors'):
5
+ return load_file(path)
6
+
7
+ def buffer4(x3, x2, x1, x0, weights):
8
+ """4-bit buffer (identity function)."""
9
+ inp = torch.tensor([float(x3), float(x2), float(x1), float(x0)])
10
+
11
+ y0 = int((inp @ weights['y0.weight'].T + weights['y0.bias'] >= 0).item())
12
+ y1 = int((inp @ weights['y1.weight'].T + weights['y1.bias'] >= 0).item())
13
+ y2 = int((inp @ weights['y2.weight'].T + weights['y2.bias'] >= 0).item())
14
+ y3 = int((inp @ weights['y3.weight'].T + weights['y3.bias'] >= 0).item())
15
+
16
+ return y3, y2, y1, y0
17
+
18
+ if __name__ == '__main__':
19
+ w = load_model()
20
+ print('4-bit Buffer:')
21
+ for i in [0, 5, 10, 15]:
22
+ x3, x2, x1, x0 = (i >> 3) & 1, (i >> 2) & 1, (i >> 1) & 1, i & 1
23
+ y3, y2, y1, y0 = buffer4(x3, x2, x1, x0, w)
24
+ print(f' {x3}{x2}{x1}{x0} -> {y3}{y2}{y1}{y0}')
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:89cccbe884732d059b828b98ca85631a621ac89e7274315d03f33f671a236221
3
+ size 592