--- license: mit tags: - pytorch - safetensors - threshold-logic - neuromorphic - multiplexer --- # threshold-mux2 2:1 multiplexer. The fundamental building block for data selection, routing one of two inputs to the output based on a select signal. ## Circuit ``` d0 d1 │ │ │ │ s (select) │ │ │ ├───────┼───────┤ │ │ │ ▼ │ │ ┌───────┐ │ │ │ sel0 │◄──┼───────┤ │d0∧¬s │ │ │ └───────┘ │ │ │ ▼ │ │ ┌───────┐ │ │ │ sel1 │◄──┘ │ │ d1∧s │ │ └───────┘ │ │ └───┬───┘ ▼ ┌───────┐ │ OR │ └───────┘ │ ▼ output ``` ## Truth Table | s | d0 | d1 | out | Description | |---|----|----|-----|-------------| | 0 | 0 | 0 | 0 | Select d0 (0) | | 0 | 0 | 1 | 0 | Select d0 (0) | | 0 | 1 | 0 | 1 | Select d0 (1) | | 0 | 1 | 1 | 1 | Select d0 (1) | | 1 | 0 | 0 | 0 | Select d1 (0) | | 1 | 0 | 1 | 1 | Select d1 (1) | | 1 | 1 | 0 | 0 | Select d1 (0) | | 1 | 1 | 1 | 1 | Select d1 (1) | Formula: `out = (d0 AND NOT s) OR (d1 AND s)` ## Mechanism **Layer 1 - Selection Gates:** The circuit uses two AND-with-complement gates that fire only when their respective data input is selected: | Gate | Weights [d0, d1, s] | Bias | Function | |------|---------------------|------|----------| | sel0 | [1, 0, -1] | -1 | d0 AND NOT(s) | | sel1 | [0, 1, 1] | -2 | d1 AND s | **sel0** fires when d0=1 AND s=0: - The negative weight on s means s=1 inhibits firing - Bias -1 requires d0=1 to reach threshold when s=0 **sel1** fires when d1=1 AND s=1: - Both d1 and s must be 1 to overcome bias -2 **Layer 2 - Output:** Simple OR gate combines the two selection paths. ## Architecture | Component | Weights | Bias | Function | |-----------|---------|------|----------| | sel0 | [1, 0, -1] | -1 | d0 AND NOT(s) | | sel1 | [0, 1, 1] | -2 | d1 AND s | | or | [1, 1] | -1 | OR(sel0, sel1) | ## Parameters | | | |---|---| | Inputs | 3 (d0, d1, s) | | Outputs | 1 | | Neurons | 3 | | Layers | 2 | | Parameters | 11 | | Magnitude | 10 | ## Building Larger Multiplexers The MUX2 is the primitive for constructing larger multiplexers: ``` MUX4 = MUX2(MUX2(d0,d1,s0), MUX2(d2,d3,s0), s1) MUX8 = MUX2(MUX4(d0-d3), MUX4(d4-d7), s2) MUX16 = MUX2(MUX8(d0-d7), MUX8(d8-d15), s3) ``` Each doubling adds one layer of MUX2 gates. ## Usage ```python from safetensors.torch import load_file import torch w = load_file('model.safetensors') def mux2(d0, d1, s): inp = torch.tensor([float(d0), float(d1), float(s)]) # Layer 1: Selection sel0 = int((inp @ w['sel0.weight'].T + w['sel0.bias'] >= 0).item()) sel1 = int((inp @ w['sel1.weight'].T + w['sel1.bias'] >= 0).item()) # Layer 2: Combine l1 = torch.tensor([float(sel0), float(sel1)]) return int((l1 @ w['or.weight'].T + w['or.bias'] >= 0).item()) # Examples print(mux2(1, 0, 0)) # 1 (selects d0) print(mux2(1, 0, 1)) # 0 (selects d1) print(mux2(0, 1, 1)) # 1 (selects d1) ``` ## Applications - Data routing in ALUs - Register file read ports - Conditional assignment in hardware - Building blocks for barrel shifters - Crossbar switches ## Files ``` threshold-mux2/ ├── model.safetensors ├── model.py ├── create_safetensors.py ├── config.json └── README.md ``` ## License MIT