Fix signal registry to use actual gate names instead of canonical aliases
Browse filesProblem: The signal registry used canonical names (e.g., 'ha1.sum', 'cout')
but the actual gates have different names (e.g., 'ha1.sum.layer2', 'carry_or').
This caused eval to fail when storing gate outputs because name_to_id lookups
returned None for the actual gate names.
Changes to build.py:
1. infer_fulladder_inputs():
- Changed ha1.sum -> ha1.sum.layer2
- The XOR gate's final output is layer2, not a bare 'sum'
2. infer_ripplecarry_inputs():
- Changed fa{idx-1}.cout -> fa{idx-1}.carry_or
- The carry output gate is named carry_or, not cout
- Changed ha1.sum -> ha1.sum.layer2
- Added .or_carry to carry gate detection (some circuits use this variant)
3. infer_multiplier_inputs():
- Changed bit{bit-1}.cout -> bit{bit-1}.carry_or
- Changed ha1.sum -> ha1.sum.layer2
- Added .or_carry to carry gate detection
4. main():
- Added registry.register(gate) after inferring inputs
- This ensures every gate with inferred inputs is registered
- Allows eval to store outputs under the gate's own name
The underlying issue: Multi-layer gates (XOR implemented as OR+NAND->AND)
have their output at 'layer2', but downstream gates were looking for the
parent name. Similarly, full adder carry outputs are 'carry_or' gates but
were referenced as 'cout'.
This is a step toward fixing the 33% tensor coverage issue where eval
could not trace through internal gates due to signal ID mismatches.
- .gitignore +1 -0
- __pycache__/eval.cpython-311.pyc +0 -0
- arithmetic.safetensors +2 -2
- build.py +11 -7
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
|
Binary file (53 kB)
|
|
|
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:213723982da54ff6c68e0db8976cd41c88eabf2a112e7cbb56fa7aab60684ae5
|
| 3 |
+
size 3026232
|
|
@@ -130,7 +130,8 @@ def infer_fulladder_inputs(gate: str, prefix: str, registry: SignalRegistry) ->
|
|
| 130 |
return [or_out, nand_out]
|
| 131 |
|
| 132 |
# HA2 inputs (ha1.sum output + cin)
|
| 133 |
-
|
|
|
|
| 134 |
|
| 135 |
if '.ha2.sum.layer1' in gate or '.ha2.carry' in gate:
|
| 136 |
return [ha1_sum, registry.get_id(f"{prefix}.$cin")]
|
|
@@ -169,7 +170,8 @@ def infer_ripplecarry_inputs(gate: str, prefix: str, bits: int, registry: Signal
|
|
| 169 |
if fa_idx == 0:
|
| 170 |
cin = registry.register("#0")
|
| 171 |
else:
|
| 172 |
-
|
|
|
|
| 173 |
|
| 174 |
# Register this FA's external inputs
|
| 175 |
a_bit = registry.get_id(f"{prefix}.$a[{fa_idx}]")
|
|
@@ -185,7 +187,7 @@ def infer_ripplecarry_inputs(gate: str, prefix: str, bits: int, registry: Signal
|
|
| 185 |
nand_out = registry.register(f"{parent}.layer1.nand")
|
| 186 |
return [or_out, nand_out]
|
| 187 |
|
| 188 |
-
ha1_sum = registry.register(f"{fa_prefix}.ha1.sum")
|
| 189 |
|
| 190 |
if '.ha2.sum.layer1' in gate or '.ha2.carry' in gate:
|
| 191 |
return [ha1_sum, cin]
|
|
@@ -196,7 +198,7 @@ def infer_ripplecarry_inputs(gate: str, prefix: str, bits: int, registry: Signal
|
|
| 196 |
nand_out = registry.register(f"{parent}.layer1.nand")
|
| 197 |
return [or_out, nand_out]
|
| 198 |
|
| 199 |
-
if '.carry_or' in gate:
|
| 200 |
ha1_carry = registry.register(f"{fa_prefix}.ha1.carry")
|
| 201 |
ha2_carry = registry.register(f"{fa_prefix}.ha2.carry")
|
| 202 |
return [ha1_carry, ha2_carry]
|
|
@@ -625,7 +627,7 @@ def infer_multiplier_inputs(gate: str, registry: SignalRegistry) -> List[int]:
|
|
| 625 |
if bit == 0:
|
| 626 |
carry_in = registry.get_id("#0")
|
| 627 |
else:
|
| 628 |
-
carry_in = registry.register(f"{prefix}.stage{stage}.bit{bit-1}.
|
| 629 |
|
| 630 |
if '.ha1.sum.layer1' in gate or '.ha1.carry' in gate:
|
| 631 |
return [prev_bit, pp_bit]
|
|
@@ -633,7 +635,7 @@ def infer_multiplier_inputs(gate: str, registry: SignalRegistry) -> List[int]:
|
|
| 633 |
return [registry.register(f"{stage_prefix}.ha1.sum.layer1.or"),
|
| 634 |
registry.register(f"{stage_prefix}.ha1.sum.layer1.nand")]
|
| 635 |
|
| 636 |
-
ha1_sum = registry.register(f"{stage_prefix}.ha1.sum")
|
| 637 |
|
| 638 |
if '.ha2.sum.layer1' in gate or '.ha2.carry' in gate:
|
| 639 |
return [ha1_sum, carry_in]
|
|
@@ -641,7 +643,7 @@ def infer_multiplier_inputs(gate: str, registry: SignalRegistry) -> List[int]:
|
|
| 641 |
return [registry.register(f"{stage_prefix}.ha2.sum.layer1.or"),
|
| 642 |
registry.register(f"{stage_prefix}.ha2.sum.layer1.nand")]
|
| 643 |
|
| 644 |
-
if '.carry_or' in gate:
|
| 645 |
return [registry.register(f"{stage_prefix}.ha1.carry"),
|
| 646 |
registry.register(f"{stage_prefix}.ha2.carry")]
|
| 647 |
|
|
@@ -6952,6 +6954,8 @@ def main():
|
|
| 6952 |
inputs = infer_inputs_for_gate(gate, registry, routing)
|
| 6953 |
if inputs:
|
| 6954 |
gate_inputs[gate] = inputs
|
|
|
|
|
|
|
| 6955 |
else:
|
| 6956 |
missing_inputs.append(gate)
|
| 6957 |
|
|
|
|
| 130 |
return [or_out, nand_out]
|
| 131 |
|
| 132 |
# HA2 inputs (ha1.sum output + cin)
|
| 133 |
+
# Use full gate name for ha1.sum output (which is ha1.sum.layer2)
|
| 134 |
+
ha1_sum = registry.register(f"{prefix}.ha1.sum.layer2")
|
| 135 |
|
| 136 |
if '.ha2.sum.layer1' in gate or '.ha2.carry' in gate:
|
| 137 |
return [ha1_sum, registry.get_id(f"{prefix}.$cin")]
|
|
|
|
| 170 |
if fa_idx == 0:
|
| 171 |
cin = registry.register("#0")
|
| 172 |
else:
|
| 173 |
+
# Carry output is from carry_or gate
|
| 174 |
+
cin = registry.register(f"{prefix}.fa{fa_idx-1}.carry_or")
|
| 175 |
|
| 176 |
# Register this FA's external inputs
|
| 177 |
a_bit = registry.get_id(f"{prefix}.$a[{fa_idx}]")
|
|
|
|
| 187 |
nand_out = registry.register(f"{parent}.layer1.nand")
|
| 188 |
return [or_out, nand_out]
|
| 189 |
|
| 190 |
+
ha1_sum = registry.register(f"{fa_prefix}.ha1.sum.layer2")
|
| 191 |
|
| 192 |
if '.ha2.sum.layer1' in gate or '.ha2.carry' in gate:
|
| 193 |
return [ha1_sum, cin]
|
|
|
|
| 198 |
nand_out = registry.register(f"{parent}.layer1.nand")
|
| 199 |
return [or_out, nand_out]
|
| 200 |
|
| 201 |
+
if '.carry_or' in gate or '.or_carry' in gate:
|
| 202 |
ha1_carry = registry.register(f"{fa_prefix}.ha1.carry")
|
| 203 |
ha2_carry = registry.register(f"{fa_prefix}.ha2.carry")
|
| 204 |
return [ha1_carry, ha2_carry]
|
|
|
|
| 627 |
if bit == 0:
|
| 628 |
carry_in = registry.get_id("#0")
|
| 629 |
else:
|
| 630 |
+
carry_in = registry.register(f"{prefix}.stage{stage}.bit{bit-1}.carry_or")
|
| 631 |
|
| 632 |
if '.ha1.sum.layer1' in gate or '.ha1.carry' in gate:
|
| 633 |
return [prev_bit, pp_bit]
|
|
|
|
| 635 |
return [registry.register(f"{stage_prefix}.ha1.sum.layer1.or"),
|
| 636 |
registry.register(f"{stage_prefix}.ha1.sum.layer1.nand")]
|
| 637 |
|
| 638 |
+
ha1_sum = registry.register(f"{stage_prefix}.ha1.sum.layer2")
|
| 639 |
|
| 640 |
if '.ha2.sum.layer1' in gate or '.ha2.carry' in gate:
|
| 641 |
return [ha1_sum, carry_in]
|
|
|
|
| 643 |
return [registry.register(f"{stage_prefix}.ha2.sum.layer1.or"),
|
| 644 |
registry.register(f"{stage_prefix}.ha2.sum.layer1.nand")]
|
| 645 |
|
| 646 |
+
if '.carry_or' in gate or '.or_carry' in gate:
|
| 647 |
return [registry.register(f"{stage_prefix}.ha1.carry"),
|
| 648 |
registry.register(f"{stage_prefix}.ha2.carry")]
|
| 649 |
|
|
|
|
| 6954 |
inputs = infer_inputs_for_gate(gate, registry, routing)
|
| 6955 |
if inputs:
|
| 6956 |
gate_inputs[gate] = inputs
|
| 6957 |
+
# Register the gate itself so eval can store its output
|
| 6958 |
+
registry.register(gate)
|
| 6959 |
else:
|
| 6960 |
missing_inputs.append(gate)
|
| 6961 |
|