Upload folder using huggingface_hub
Browse files- README.md +135 -0
- config.json +9 -0
- model.py +48 -0
- model.safetensors +3 -0
README.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
tags:
|
| 4 |
+
- pytorch
|
| 5 |
+
- safetensors
|
| 6 |
+
- threshold-logic
|
| 7 |
+
- neuromorphic
|
| 8 |
+
- encoder
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
# threshold-priorityencoder
|
| 12 |
+
|
| 13 |
+
8-to-3 priority encoder. Outputs the binary index of the highest-priority active input.
|
| 14 |
+
|
| 15 |
+
## Circuit
|
| 16 |
+
|
| 17 |
+
```
|
| 18 |
+
x₀ x₁ x₂ x₃ x₄ x₅ x₆ x₇
|
| 19 |
+
│ │ │ │ │ │ │ │
|
| 20 |
+
└──┴──┴──┴──┼──┴──┴──┴──┘
|
| 21 |
+
│
|
| 22 |
+
┌──────────┼──────────┐
|
| 23 |
+
│ │ │
|
| 24 |
+
▼ ▼ ▼
|
| 25 |
+
┌──────┐ ┌──────┐ ┌──────┐
|
| 26 |
+
│win₀ │...│win₃ │...│win₇ │ Layer 1: Winner detectors
|
| 27 |
+
│+1,0..│ │inhibit│ │just │ (8 neurons)
|
| 28 |
+
│b=-1 │ │higher │ │x₇ │
|
| 29 |
+
└──────┘ └──────┘ └──────┘
|
| 30 |
+
│ │ │
|
| 31 |
+
└────┬─────┴────┬─────┘
|
| 32 |
+
│ │
|
| 33 |
+
┌────┴────┐┌────┴────┐
|
| 34 |
+
│ y₀ OR ││ y₂ OR │ Layer 2: Output encoding
|
| 35 |
+
│ 1,3,5,7 ││ 4,5,6,7 │ (4 neurons)
|
| 36 |
+
└─────────┘└─────────┘
|
| 37 |
+
│ │
|
| 38 |
+
▼ ▼
|
| 39 |
+
y₀ y₁ y₂ valid
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
## Mechanism
|
| 43 |
+
|
| 44 |
+
**Winner Detection**: Each position has a neuron that fires only when:
|
| 45 |
+
1. That input is active (weight +1)
|
| 46 |
+
2. No higher-priority input is active (weight -1 on each higher input)
|
| 47 |
+
|
| 48 |
+
```
|
| 49 |
+
winner₅: fires when x₅=1 AND x₆=0 AND x₇=0
|
| 50 |
+
weights: [0, 0, 0, 0, 0, +1, -1, -1]
|
| 51 |
+
bias: -1
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
**Output Encoding**: The 3-bit output is assembled by OR-ing the appropriate winners:
|
| 55 |
+
- y₀ = OR(win₁, win₃, win₅, win₇) — odd indices
|
| 56 |
+
- y₁ = OR(win₂, win₃, win₆, win₇) — indices with bit 1 set
|
| 57 |
+
- y₂ = OR(win₄, win₅, win₆, win₇) — indices with bit 2 set
|
| 58 |
+
|
| 59 |
+
## Truth Table (samples)
|
| 60 |
+
|
| 61 |
+
| Active inputs | Winner | Output (y₂y₁y₀) | Index |
|
| 62 |
+
|---------------|--------|-----------------|-------|
|
| 63 |
+
| x₀ only | win₀ | 000 | 0 |
|
| 64 |
+
| x₃ only | win₃ | 011 | 3 |
|
| 65 |
+
| x₇ only | win₇ | 111 | 7 |
|
| 66 |
+
| x₀, x₃ | win₃ | 011 | 3 |
|
| 67 |
+
| x₂, x₅, x₆ | win₆ | 110 | 6 |
|
| 68 |
+
| all | win₇ | 111 | 7 |
|
| 69 |
+
| none | none | 000 | 0* |
|
| 70 |
+
|
| 71 |
+
*valid=0 when no inputs active
|
| 72 |
+
|
| 73 |
+
## Priority Convention
|
| 74 |
+
|
| 75 |
+
Highest index wins. x₇ has absolute priority over all others.
|
| 76 |
+
|
| 77 |
+
| Input | Priority |
|
| 78 |
+
|-------|----------|
|
| 79 |
+
| x₇ | Highest |
|
| 80 |
+
| x₆ | ... |
|
| 81 |
+
| ... | ... |
|
| 82 |
+
| x₀ | Lowest |
|
| 83 |
+
|
| 84 |
+
## Architecture
|
| 85 |
+
|
| 86 |
+
| Layer | Neurons | Function |
|
| 87 |
+
|-------|---------|----------|
|
| 88 |
+
| 1 | 8 | Winner detectors |
|
| 89 |
+
| 2 | 4 | Output OR gates (y₀, y₁, y₂, valid) |
|
| 90 |
+
|
| 91 |
+
**Total: 12 neurons, 96 parameters, 2 layers**
|
| 92 |
+
|
| 93 |
+
## The Inhibition Principle
|
| 94 |
+
|
| 95 |
+
The key insight: each winner neuron is *inhibited* by all higher-priority inputs.
|
| 96 |
+
|
| 97 |
+
```
|
| 98 |
+
winner₃ weights: [0, 0, 0, +1, -1, -1, -1, -1]
|
| 99 |
+
x₃ x₄ x₅ x₆ x₇
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
If any of x₄-x₇ is active, the negative weight cancels x₃'s contribution.
|
| 103 |
+
|
| 104 |
+
## Usage
|
| 105 |
+
|
| 106 |
+
```python
|
| 107 |
+
from safetensors.torch import load_file
|
| 108 |
+
import torch
|
| 109 |
+
|
| 110 |
+
w = load_file('model.safetensors')
|
| 111 |
+
|
| 112 |
+
def priority_encode(bits):
|
| 113 |
+
"""Returns (y2, y1, y0, valid)"""
|
| 114 |
+
# See model.py for full implementation
|
| 115 |
+
pass
|
| 116 |
+
|
| 117 |
+
# Multiple active: highest wins
|
| 118 |
+
bits = [1, 0, 1, 0, 0, 1, 0, 0] # x0, x2, x5 active
|
| 119 |
+
y2, y1, y0, valid = priority_encode(bits)
|
| 120 |
+
# Result: (1, 0, 1, 1) = index 5
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
## Files
|
| 124 |
+
|
| 125 |
+
```
|
| 126 |
+
threshold-priorityencoder/
|
| 127 |
+
├── model.safetensors
|
| 128 |
+
├── model.py
|
| 129 |
+
├── config.json
|
| 130 |
+
└── README.md
|
| 131 |
+
```
|
| 132 |
+
|
| 133 |
+
## License
|
| 134 |
+
|
| 135 |
+
MIT
|
config.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "threshold-priorityencoder",
|
| 3 |
+
"description": "8-to-3 priority encoder as threshold circuit",
|
| 4 |
+
"inputs": 8,
|
| 5 |
+
"outputs": 4,
|
| 6 |
+
"neurons": 12,
|
| 7 |
+
"layers": 2,
|
| 8 |
+
"parameters": 96
|
| 9 |
+
}
|
model.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 priority_encode(bits, weights):
|
| 8 |
+
"""8-to-3 priority encoder with valid bit.
|
| 9 |
+
Returns (y2, y1, y0, valid) where y2y1y0 is the index of highest active input.
|
| 10 |
+
Highest index (x7) has highest priority.
|
| 11 |
+
"""
|
| 12 |
+
inp = torch.tensor([float(b) for b in bits])
|
| 13 |
+
|
| 14 |
+
# Compute winner for each input position
|
| 15 |
+
winners = []
|
| 16 |
+
for i in range(8):
|
| 17 |
+
win = int((inp * weights[f'winner{i}.weight']).sum() + weights[f'winner{i}.bias'] >= 0)
|
| 18 |
+
winners.append(win)
|
| 19 |
+
|
| 20 |
+
# Compute output bits from winners
|
| 21 |
+
win_137 = torch.tensor([float(winners[i]) for i in [1,3,5,7]])
|
| 22 |
+
y0 = int((win_137 * weights['y0.weight']).sum() + weights['y0.bias'] >= 0)
|
| 23 |
+
|
| 24 |
+
win_2367 = torch.tensor([float(winners[i]) for i in [2,3,6,7]])
|
| 25 |
+
y1 = int((win_2367 * weights['y1.weight']).sum() + weights['y1.bias'] >= 0)
|
| 26 |
+
|
| 27 |
+
win_4567 = torch.tensor([float(winners[i]) for i in [4,5,6,7]])
|
| 28 |
+
y2 = int((win_4567 * weights['y2.weight']).sum() + weights['y2.bias'] >= 0)
|
| 29 |
+
|
| 30 |
+
valid = int((inp * weights['valid.weight']).sum() + weights['valid.bias'] >= 0)
|
| 31 |
+
|
| 32 |
+
return y2, y1, y0, valid
|
| 33 |
+
|
| 34 |
+
if __name__ == '__main__':
|
| 35 |
+
w = load_model()
|
| 36 |
+
print('8-to-3 Priority Encoder (highest index wins)')
|
| 37 |
+
print('Input -> Index, Valid')
|
| 38 |
+
|
| 39 |
+
# Single-bit tests
|
| 40 |
+
for i in range(8):
|
| 41 |
+
bits = [0]*8
|
| 42 |
+
bits[i] = 1
|
| 43 |
+
y2, y1, y0, valid = priority_encode(bits, w)
|
| 44 |
+
print(f'x{i} only: {y2*4 + y1*2 + y0}, {valid}')
|
| 45 |
+
|
| 46 |
+
# No input
|
| 47 |
+
y2, y1, y0, valid = priority_encode([0]*8, w)
|
| 48 |
+
print(f'None: {y2*4 + y1*2 + y0}, valid={valid}')
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:200b8aacf0d8c6f9f14ce1d0052554b967077dbc3db38c8476b5cda27b13c35c
|
| 3 |
+
size 2008
|