implement an incremental fsim

This commit is contained in:
stefan committed 2026-06-25 14:30:19 +09:00
1 parent 7ae0569e30
commit a0763d6124
6 files changed
+97 -52

No files matched your search

-47
View File
@@ -1,47 +0,0 @@
import time
from collections.abc import Collection
import numpy as np
from kyupy import log, batchrange
from kyupy.circuit import Circuit
from kyupy.logic_sim import LogicSim2V
class SAFSimSimple:
def __init__(self, circuit_resolved: Circuit, batch_size: int):
self.sim = LogicSim2V(circuit_resolved, sims=batch_size)
self.sim_time = 0
pass
def classify_faults(self, faults: Collection[int], patterns: np.ndarray):
golden = np.zeros_like(patterns)
self.sim.simulate(patterns, golden)
log.info(f'golden sim finished.')
syndrome = np.zeros_like(patterns)
fclass_NO = set()
fclass_DS = set()
start_time = time.perf_counter()
with log.progress() as p:
for fidx, fault in enumerate(faults):
fault_site = fault//2
fault_polarity = fault&1
p.update((fidx+1) / len(faults), f'DS:{len(fclass_DS)} NO:{len(fclass_NO)}')
for bo, bs in batchrange(patterns.shape[1], self.sim.sims):
self.sim.s_assign[:, :bs] = patterns[:, bo:bo+bs]
self.sim.s_to_c()
self.sim.c_prop(fault_line=fault_site, fault_model=fault_polarity)
self.sim.c_to_s()
syndrome[:, bo:bo+bs] = self.sim.s_result[:,:bs]
if np.allclose(golden, syndrome):
fclass_NO.add(fault)
else:
fclass_DS.add(fault)
self.sim_time += time.perf_counter() - start_time
return {'DS': fclass_DS, 'NO': fclass_NO}
+47
View File
@@ -0,0 +1,47 @@
import time
from collections.abc import Collection
import numpy as np
from kyupy import log, batchrange, cdiv, Timers
from kyupy.circuit import Circuit
from kyupy.logic_sim import LogicSim2V
class SAFSimIncremental:
def __init__(self, circuit_resolved: Circuit, batch_size: int):
self.sim = LogicSim2V(circuit_resolved, sims=batch_size)
self.timers = Timers()
def classify_faults(self, faults: Collection[int], patterns: np.ndarray):
with self.timers['startup']:
self.sim.c_prop() # trigger jit
c_golden = np.zeros_like(self.sim.c)
fclass_DS = set()
nbatches = cdiv(patterns.shape[1], self.sim.sims)
nfaults = len(faults)
with self.timers['sim'], log.progress() as p:
for bidx, (bo, bs) in enumerate(batchrange(patterns.shape[1], self.sim.sims)):
self.sim.s_assign[:, :bs] = patterns[:, bo:bo+bs]
self.sim.s_to_c()
self.sim.c_dirty[...] = 1
with self.timers['sim_full_prop']:
self.sim.c_prop()
c_golden[...] = self.sim.c
c_golden_poppo = c_golden[self.sim.poppo_c_locs]
for fidx, fault in enumerate(faults):
fault_site = fault//2
fault_polarity = fault&1
self.sim.c_dirty[...] = 0
with self.timers['sim_incr_prop']:
self.sim.c_prop(fault_line=fault_site, fault_model=fault_polarity)
with self.timers['sim_incr_eval']:
if not np.all(c_golden_poppo == self.sim.c[self.sim.poppo_c_locs]):
fclass_DS.add(fault)
with self.timers['sim_incr_reset']:
self.sim.c[...] = c_golden # clear fault
p.update(((fidx+1) / nfaults) * ((bidx+1) / nbatches))
return {'DS': fclass_DS, 'NO': set(faults) - fclass_DS}
+44
View File
@@ -0,0 +1,44 @@
import time
from collections.abc import Collection
import numpy as np
from kyupy import log, batchrange, Timers
from kyupy.circuit import Circuit
from kyupy.logic_sim import LogicSim2V
class SAFSimSimple:
def __init__(self, circuit_resolved: Circuit, batch_size: int):
self.sim = LogicSim2V(circuit_resolved, sims=batch_size)
self.timers = Timers()
def classify_faults(self, faults: Collection[int], patterns: np.ndarray):
with self.timers['startup']:
golden = np.zeros_like(patterns)
self.sim.simulate(patterns, golden)
syndrome = np.zeros_like(patterns)
fclass_NO = set()
fclass_DS = set()
with self.timers['sim'], log.progress() as p:
for fidx, fault in enumerate(faults):
fault_site = fault//2
fault_polarity = fault&1
p.update((fidx+1) / len(faults), f'DS:{len(fclass_DS)} NO:{len(fclass_NO)}')
for bo, bs in batchrange(patterns.shape[1], self.sim.sims):
self.sim.s_assign[:, :bs] = patterns[:, bo:bo+bs]
self.sim.s_to_c()
with self.timers['sim_prop']:
self.sim.c_prop(fault_line=fault_site, fault_model=fault_polarity)
with self.timers['sim_eval']:
self.sim.c_to_s()
syndrome[:, bo:bo+bs] = self.sim.s_result[:,:bs]
with self.timers['sim_eval2']:
if np.allclose(golden, syndrome):
fclass_NO.add(fault)
else:
fclass_DS.add(fault)
return {'DS': fclass_DS, 'NO': fclass_NO}