CharlesCNorton commited on
Commit
86302ab
·
1 Parent(s): 947fcab

Fix signal registry to use actual gate names instead of canonical aliases

Browse files

Problem: 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 ADDED
@@ -0,0 +1 @@
 
 
1
+ __pycache__/
__pycache__/eval.cpython-311.pyc DELETED
Binary file (53 kB)
 
arithmetic.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:cd147a9a27df47020615265d1c0a62b10cd4839d2a6252b1f19c8c2dbf83790d
3
- size 3062104
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:213723982da54ff6c68e0db8976cd41c88eabf2a112e7cbb56fa7aab60684ae5
3
+ size 3026232
build.py CHANGED
@@ -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
- ha1_sum = registry.register(f"{prefix}.ha1.sum")
 
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
- cin = registry.register(f"{prefix}.fa{fa_idx-1}.cout")
 
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}.cout")
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