implement an incremental fsim
This commit is contained in:
1 parent
7ae0569e30
commit
a0763d6124
6 files changed
+97
-52
No files matched your search
@@ -40,7 +40,7 @@ Choose `uv-env` as kernel in Jupyter Lab.
|
|||||||
|
|
||||||
Numbers are given in `gfs/s` = `gates * faults * patterns / second`.
|
Numbers are given in `gfs/s` = `gates * faults * patterns / second`.
|
||||||
|
|
||||||
Stuck-at fault sim on 1024 patterns, baseline:
|
`SAFSimSimple` on 1024 patterns (baseline):
|
||||||
|
|
||||||
| OS, CPU, RAM | `tests/c6288.bench` | `polito-itc99-b15-sky130` |
|
| OS, CPU, RAM | `tests/c6288.bench` | `polito-itc99-b15-sky130` |
|
||||||
|--------------|---------------------|---------------------------|
|
|--------------|---------------------|---------------------------|
|
||||||
|
|||||||
+1
-1
Submodule kyupy updated: c90bc89522...53309f9e59.
@@ -10,7 +10,8 @@ from kyupy import verilog, bench, log, logic, batchrange, atalanta, stil
|
|||||||
from kyupy.techlib import techlib_by_name, KYUPY
|
from kyupy.techlib import techlib_by_name, KYUPY
|
||||||
|
|
||||||
from fsim.static import LineRoles, FaultSet
|
from fsim.static import LineRoles, FaultSet
|
||||||
from fsim.baseline import SAFSimSimple
|
from fsim.simple import SAFSimSimple
|
||||||
|
from fsim.incremental import SAFSimIncremental
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -80,8 +81,8 @@ def main():
|
|||||||
|
|
||||||
fclasses = safsim.classify_faults(saf_collapsed, patterns)
|
fclasses = safsim.classify_faults(saf_collapsed, patterns)
|
||||||
|
|
||||||
log.info(f'fsim time: {safsim.sim_time:.2f}s')
|
log.info(f'{safsim.timers=}')
|
||||||
sim_performance = stats['comb'] * len(saf_collapsed) * patterns.shape[1] / safsim.sim_time
|
sim_performance = stats['comb'] * len(saf_collapsed) * patterns.shape[1] / safsim.timers['sim'].s
|
||||||
log.info(f'fsim performance: {sim_performance:.2e} gfp/s')
|
log.info(f'fsim performance: {sim_performance:.2e} gfp/s')
|
||||||
log.info(f'detected by simulation (collapsed): {len(fclasses["DS"])}/{len(saf_collapsed)} - {len(fclasses["DS"])/len(saf_collapsed)*100:.2f}%')
|
log.info(f'detected by simulation (collapsed): {len(fclasses["DS"])}/{len(saf_collapsed)} - {len(fclasses["DS"])/len(saf_collapsed)*100:.2f}%')
|
||||||
|
|
||||||
|
|||||||
@@ -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}
|
|
||||||
@@ -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}
|
||||||
@@ -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}
|
||||||
Reference in new issue
Block a user