From 89ac9abe7510e2f4440835160f6329c7371a4ec3 Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Mon, 24 Oct 2011 15:21:08 -0700 Subject: pyabc: updated Bob's scripts --- scripts/abc_common.py | 720 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 436 insertions(+), 284 deletions(-) (limited to 'scripts/abc_common.py') diff --git a/scripts/abc_common.py b/scripts/abc_common.py index 891a918b..df2b731b 100644 --- a/scripts/abc_common.py +++ b/scripts/abc_common.py @@ -1,9 +1,13 @@ from pyabc import * +import pyabc_split +import par import redirect import sys import os import time import math + + global G_C,G_T,latches_before_abs,latches_before_pba,n_pos_before,x_factor """ @@ -40,7 +44,7 @@ stackno_gabs = stackno_gore = stackno_greg= 0 STATUS_UNKNOWN = -1 STATUS_SAT = 0 STATUS_UNSAT = 1 -RESULT = ('SAT' , 'SAT', 'UNSAT', 'UNDECIDED but reduced', 'UNDECIDED, no reduction', 'UNDCIDED but reduced' ) +RESULT = ('SAT' , 'SAT', 'UNSAT', 'UNDECIDED', 'UNDECIDED,', 'UNDCIDED' ) Sat_reg = 0 Sat_true = 1 Unsat = 2 @@ -190,29 +194,6 @@ def read_file(): def rf(): read_file() -##def read_file(): -## """This is the main program used for reading in a new circuit. The global file name is stored (f_name) -## Sometimes we want to know the initial starting name. The file name can have the .aig extension left off -## and it will assume that the .aig extension is implied. This should not be used for .blif files. -## Any time we want to process a new circuit, we should use this since otherwise we would not have the -## correct f_name.""" -## global max_bmc, f_name, d_name, initial_f_name, x_factor -## x_factor = 1 -## max_bmc = -1 -## print 'Type in the name of the aig file to be read in' -## s = raw_input() -## if s[-4:] == '.aig': -## f_name = s[:-4] -## else: -## f_name = s -## s = s+'.aig' -## run_command(s) -## initial_f_name = f_name -## print_circuit_stats() -## -##def rf(): -## """just an alias for read_file""" -## read_file() def write_file(s): """this is the main method for writing the current circuit to an AIG file on disk. @@ -236,7 +217,7 @@ def wf(): def bmc_depth(): """ Finds the number of BMC frames that the latest operation has used. The operation could be BMC, reachability interpolation, abstract, speculate. max_bmc is continually increased. It reflects the maximum depth of any version of the circuit - including abstract ones, for which it is known that there is not cex out to that depth.""" + including g ones, for which it is known that there is not cex out to that depth.""" global max_bmc b = n_bmc_frames() max_bmc = max(b,max_bmc) @@ -301,43 +282,7 @@ def rc(file): """reads so that if constraints are explicit, it will preserve them""" abc('&r %s;&put'%file) -##def push(file): -## """ saves .aig in stack_x""" -## global stackno_gabs, stackno_gsrm, stackno_greg -## if 'gabs' in file: -## snm = 'gabs' -## elif 'gsrm' in file: -## snm = 'gsrm' -## elif 'x' in file: -## snm = 'greg' -## else: -## print 'wrong file name' -## return -## print snm -## sn = 'stackno_%s'%snm -## print sn -## exec 'sn += sn' -## print sn, eval(sn) -## run_command("r %s.aig"%file) -## run_command("w %s_%d.aig"%(file,eval(sn))) -## -##def pop(file): -## """ reads top .aig in stack_1 and saves it in .aig""" -## global stackno_gabs, stackno_gsrm, stackno_greg -## if 'gabs' in file: -## sn = 'gabs' -## if 'gsrm' in file: -## sn = 'gsrm' -## if 'x' in file: -## sn = 'greg' -## else: -## print 'wrong file name' -## return -## run_command("r %s_%d.aig"%(file,eval(sn))) -## run_command("w %s.aig"%file) -## os.remove("%s_%d.aig"%(file,eval(sn))) -## exec 'sn = sn-1' -## # need to protect against wrong stack count + def fast_int(n): """This is used to eliminate easy-to-prove outputs. Arg n is conflict limit to be used @@ -382,10 +327,10 @@ def simplify(): # set_globals() ## print 'simplify initial ', ## ps() - abc('w t.aig') + #abc('w t.aig') n=n_ands() abc('scl') - if n > 30000: + if n > 40000: abc('&get;&scl;&put') n = n_ands() if n < 100000: @@ -393,7 +338,7 @@ def simplify(): run_command('ps') print '.', n = n_ands() - if n<45000: + if n<60000: abc("&get;&scorr -F 2;&put;dc2rs") print '.', #ps() @@ -403,28 +348,34 @@ def simplify(): #ps() n = n_ands() n = n_ands() - if n <= 30000: + if n <= 40000: print '.', #ps() - if n > 15000: + if n > 30000: abc("dc2rs") print '.', - else: - abc("scorr -F 2;dc2rs") - print '.', - #ps() +## else: +## abc("scorr -F 2;dc2rs") +## print '.', +## ps() n = max(1,n_ands()) - ps() - if n < 20000: + #ps() + if n < 30000: + abc('scl;rw;dr;lcorr;rw;dr') m = int(min( 60000/n, 16)) #print 'm = %d'%m - if m >= 4: - j = 4 + if m >= 1: + j = 1 while j <= m: set_size() #print 'j - %d'%j - abc('scl;dr;dc2;scorr -C 5000 -F %d'%j) - if check_size() == 1: + #abc('scl;dr;dc2;scorr -C 5000 -F %d'%j) + if j<8: + abc('dc2') + else: + abc('dc2rs') + abc('scorr -C 5000 -F %d'%j) + if check_size(): break j = 2*j #ps() @@ -464,6 +415,25 @@ def iterate_simulation(latches_before): if not is_sat(): break +def simulate(): + """Simulation is controlled by the amount + of memory it might use. At first wide but shallow simulation is done, bollowed by + successively more narrow but deeper simulation""" + global x_factor, f_name +## print 'RUNNING simulation iteratively' + f = 5 + w = 255 + for k in range(9): + f = min(f *2, 3500) + w = max(((w+1)/2)-1,1) + print '.', + abc('sim -m -F %d -W %d'%(f,w)) + if is_sat(): + print 'cex found in frame %d'%cex_frame() + return 'SAT' + return 'UNDECIDED' + + def iterate_abstraction_refinement(latches_before,NBF): """Subroutine of 'abstract' which does the refinement of the abstracted model, using counterexamples found by BMC or BDD reachability""" @@ -472,8 +442,7 @@ def iterate_abstraction_refinement(latches_before,NBF): F = 2000 else: F = 2*NBF - print '\nIterating BMC or BDD reachability' - reach_sw = 0 + print '\nIterating BMC/PDR' always_reach = 0 cexf = 0 reach_failed = 0 @@ -490,36 +459,47 @@ def iterate_abstraction_refinement(latches_before,NBF): nlri = n_latches()+ri #reach_allowed = ((nlri<150) or (((cexf>250))&(nlri<300))) reach_allowed = ((nlri<75) or (((cexf>250))&(nlri<300))) + pdr_allowed = True + bmc = False t = max(1,G_T) if not F == -1: F = int(1.5*max_bmc) - if (((reach_allowed or (reach_sw ==1)) and not reach_failed)): + if (((reach_allowed or pdr_allowed ) and not reach_failed)): #cmd = 'reach -B 200000 -F 3500 -T %f'%t #cmd = 'reachx -e %d -t %d'%(int(long(t)),max(10,int(t))) - cmd = 'reachx -t %d'%max(10,int(t)) - reach_sw = 1 + #cmd = 'reachx -t %d'%max(10,int(t)) + cmd = '&get;,pdr -vt=%f'%t else: - reach_sw = 0 - cmd = 'bmc3 -C %d -T %f -F %d'%(G_C,t,F) - print 'RUNNING %s'%cmd + #cmd = 'bmc3 -C %d -T %f -F %d'%(G_C,t,F) + bmc = True + cmd = '&get;,bmc -vt=%f'%(t) + #cmd = '&get;,pdr -vt=%f'%(t) + print '\n***RUNNING %s'%cmd + #run_command(cmd) + last_bmc = max_bmc abc(cmd) if prob_status() == 1: - print 'Reachability went to %d frames, '%n_bmc_frames() + #print 'Depth reached %d frames, '%n_bmc_frames() print 'UNSAT' return Unsat cexf = cex_frame() - set_max_bmc(cexf -1) - if ((not is_sat()) and (reach_sw == 1)): + #print 'cex depth = %d'%cexf + #set_max_bmc(cexf -1) + if ((not is_sat()) ): reach_failed = 1 # if ever reach failed, then we should not try it again on more refined models if is_sat(): - set_max_bmc(cex_frame()-1) + #print 'CEX in frame %d for output %d'%(cex_frame(),cex_po()) + #set_max_bmc(cexf-1) refine_with_cex() # if cex can't refine, status is set to Sat_true if is_sat(): print 'cex did not refine. Implies true_sat' return Sat_true else: print "No CEX found in %d frames"%n_bmc_frames() - if reach_sw == 0: + set_max_bmc(n_bmc_frames()) + if bmc: + break + elif max_bmc> 1.2*last_bmc: # if pdr increased significantly over abs, the assume OK break else: continue @@ -543,29 +523,18 @@ def abstract(): print 'Start: ', print_circuit_stats() c = 1.5*G_C - #c = 20000 - t = max(1,1.25*G_T) - method = 3 - if n_ands() > 100000: - method = 0 + #t = max(1,1.25*G_T) + t = 2*max(1,1.25*G_T) s = min(max(3,c/30000),10) # stability between 3 and 10 - if max_bmc == -1: - time = max(1,.01*G_T) - abc('bmc3 -C %d -T %f -F 165'%(.01*G_C, time)) - set_max_bmc(bmc_depth()) - f = min(250,1.5*max_bmc) - f = max(20, f) - f = 10*f - if not method == 0: - b = 10 - b = max(b,max_bmc+2) - b = b*2**(x_factor-1) - b = 2*b - print 'Neen abstraction params: Bob = %d, Method #%d, %d conflicts, %d stable, %d sec., %d frames'%(b,method,c/3,s,t,f) - abc('&get; &abs_newstart -v -B %f -A %d -C %d -S %d -V %f -F %d'%(b,method,c/3,s,t,f)) - else: - abc('&get;&abs_start -v -C 500000 -R 1') - #abc('w abstemp.aig') + time = max(1,.01*G_T) + abc('&get;,bmc -vt=%f'%time) + print 'BMC went %d frames'%n_bmc_frames() + set_max_bmc(bmc_depth()) + f = max(2*max_bmc,20) + b = min(max(10,max_bmc),200) + cmd = '&get;,abs -bob=%d -stable=%d -timeout=%f -vt=%f -depth=%d'%(b,s,t,t,f) + print ' Running %s'%cmd + run_command(cmd) if is_sat(): print 'Found true counterexample in frame %d'%cex_frame() return Sat_true @@ -573,8 +542,8 @@ def abstract(): print 'Abstraction good to %d frames'%n_bmc_frames() set_max_bmc(NBF) abc('&w %s_greg.aig; &abs_derive; &put; w %s_gabs.aig'%(f_name,f_name)) - print 'First abstraction: ', - print_circuit_stats() +## print 'First abstraction: ', +## print_circuit_stats() latches_after = n_latches() #if latches_before_abs == latches_after: if latches_after >= .98*latches_before_abs: @@ -583,7 +552,7 @@ def abstract(): return Undecided_no_reduction # refinement loop if (n_ands() + n_latches() + n_pis()) < 15000: - print 'Running simulation iteratively' + print '\n***Running simulation iteratively' for i in range(5): result = iterate_simulation(latches_before_abs) if result == Restart: @@ -610,7 +579,8 @@ def absv(n,v): s = min(max(3,c/30000),10) # stability between 3 and 10 if max_bmc == -1: time = max(1,.01*G_T) - abc('bmc3 -C %d -T %f -F 165'%(.01*G_C, time)) + #abc('bmc3 -C %d -T %f -F 165'%(.01*G_C, time)) + abc('&get;,bmc -vt=%f'%time) set_max_bmc(bmc_depth()) f = min(250,1.5*max_bmc) f = max(20, f) @@ -648,7 +618,7 @@ def spec(): set_globals() t = max(1,.5*G_T) r = max(1,int(t)) - print 'Running &equiv2 with C = %d, T = %f sec., F = %d -S 1 -R %d'%(G_C,t,200,r) + print '\n***Running &equiv2 with C = %d, T = %f sec., F = %d -S 1 -R %d'%(G_C,t,200,r) abc("&get; &equiv2 -C %d -F 200 -T %f -S 1 -R %d; &semi -F 50; &speci -F 20 -C 1000;&srm; r gsrm.aig; w %s_gsrm.aig; &w %s_gore.aig"%((G_C),t,r,f_name,f_name)) print 'Initial speculation: ', print_circuit_stats() @@ -723,11 +693,13 @@ def speculate(): set_globals() t = max(1,.5*G_T) r = max(1,int(t)) - print 'Running &equiv2 with C = %d, T = %f sec., F = %d -S 1 -R %d'%(G_C,t,200,r) - abc("&get; &equiv2 -C %d -F 200 -T %f -S 1 -R %d; &semi -F 50; &speci -F 20 -C 1000;&srm; r gsrm.aig; w %s_gsrm.aig; &w %s_gore.aig"%((G_C),t,r,f_name,f_name)) + abc('write spec_temp.aig') + print '\n***Running &equiv2 with C = %d, T = %f sec., F = %d -S 1 -R %d'%(G_C,t,200,r) +## abc("&get; &equiv2 -C %d -F 200 -T %f -S 1 -R %d; &semi -F 50; &speci -F 20 -C 1000;&srm; r gsrm.aig; w %s_gsrm.aig; &w %s_gore.aig"%((G_C),t,r,f_name,f_name)) + abc("&get; &equiv2 -C %d -F 200 -T %f -S 1 -R %d; &semi -W 63 -S 5 -C 500 -F 500; &speci -F 200 -C 5000;&srm; r gsrm.aig; w %s_gsrm.aig; &w %s_gore.aig"%((G_C),t,r,f_name,f_name)) print 'Initial speculation: ', print_circuit_stats() - print 'Speculation good to %d frames'%n_bmc_frames() + #print 'Speculation good to %d frames'%n_bmc_frames() #simplify() if n_pos_before == n_pos(): print 'No new outputs. Quitting speculate' @@ -735,6 +707,12 @@ def speculate(): if is_sat(): #print '\nWARNING: if an abstraction was done, need to refine it further\n' return Sat_true + if n_latches() > .98*n_latches_before: + pre_simp() + if n_latches() > .98*n_latches_before: + print 'Quitting speculation - not enough gain' + abc('r spec_temp.aig') + return Undecided_no_reduction # not worth it k = n_ands() + n_latches() + n_pis() n = 0 if k < 15000: @@ -746,7 +724,7 @@ def speculate(): elif k < 120000: n = 8 if n > 0: # simulation can run out of memory for too large designs, so be careful - print 'RUNNING simulation iteratively' + print '\n***RUNNING simulation iteratively' for i in range(5): result = run_simulation(n) if result == Sat_true: @@ -757,6 +735,7 @@ def speculate(): cexf = 0 reach_failed = 0 init = 1 + run_command('write temptemp.aig') print '\nIterating BMC or BDD reachability' while True: # now try real hard to get the last cex. set_globals() @@ -788,7 +767,8 @@ def speculate(): print 'Int found true cex: Output = %d, Frame = %d'%(cex_po(),cex_frame()) return Sat_true refine_with_cex() - if n_pos_before == n_pos(): + if ((n_pos_before == n_pos()) or (n_latches_before == n_latches())): + abc('r temp_spec.aig') return Undecided_no_reduction if is_sat(): print '1. cex failed to refine abstraction' @@ -800,11 +780,13 @@ def speculate(): ri = n_real_inputs() #seeing how many inputs would trm get rid of nlri = n_latches() + ri reach_allowed = ((nlri<75) or (((cexf>250)) and (nlri<300))) - if (((reach_allowed or (reach_sw == 1)) and not reach_failed)): + pdr_allowed = True + bmc = False + if (((reach_allowed or pdr_allowed ) and not reach_failed)): t = max(1,1.2*G_T) f = max(3500, 2*max_bmc) - cmd = 'reachx -t %d'%max(10,int(t)) - reach_sw = 1 + #cmd = 'reachx -t %d'%max(10,int(t)) + cmd ='&get;,pdr -vt=%f'%t else: t = max(1,1.5*G_T) if max_bmc == -1: @@ -812,16 +794,19 @@ def speculate(): else: f = max_bmc f = int(1.5*f) - cmd = 'bmc3 -C %d -T %f -F %f'%(1.5*G_C,1.2*t,f) - reach_sw = 0 - print 'Running %s'%cmd + #cmd = 'bmc3 -C %d -T %f -F %f'%(1.5*G_C,1.2*t,f) + bmc = True + cmd = '&get;,bmc -vt=%f'%(1.2*t) + print '\n***Running %s'%cmd + last_bmc = max_bmc abc(cmd) + #run_command(cmd) if is_sat(): cexf = cex_frame() - set_max_bmc(cexf - 1) + #set_max_bmc(cexf - 1) #This is a temporary fix since reachx always reports cex_ps = 0 - if ((cex_po() < n_pos_before) and (cmd[:3] == 'bmc')): - print 'BMC found true cex: Output = %d, Frame = %d'%(cex_po(),cex_frame()) + if ((cex_po() < n_pos_before) and (cmd[:4] == '&get')): + print 'BMC/PDR found true cex: Output = %d, Frame = %d'%(cex_po(),cex_frame()) return Sat_true #End of temporary fix refine_with_cex()#change the number of equivalences @@ -829,14 +814,16 @@ def speculate(): return Undecided_no_reduction continue else: - set_max_bmc(bmc_depth()) + set_max_bmc(n_bmc_frames()) + if prob_status() == 1: + #print 'Convergence reached in %d frames'%n_bmc_frames() + return Unsat print 'No cex found in %d frames'%n_bmc_frames() - if reach_sw == 0: + if bmc: + break + elif max_bmc > 1.2*last_bmc: break else: - if prob_status() == 1: - print 'Reachability converged in %d frames'%n_bmc_frames() - return Unsat reach_failed = 1 init = 1 continue @@ -880,28 +867,39 @@ def quick_verify(n): if n_latches == 0: return check_sat() abc('trm') + if is_sat(): + return Sat_true print 'After trimming: ', print_circuit_stats() #try_rpm() set_globals() - if is_sat(): - return Sat_true + t = max(1,.4*G_T) + print ' Running PDR for %d sec '%(t) + abc('&get;,pdr -vt=%f'%(t*.8)) + status = get_status() + if not status == Unsat: + print 'PDR went to %d frames, '%n_bmc_frames(), + print RESULT[status] + return status #temporary + if status <= Unsat: + return status + N = bmc_depth() c = max(G_C/10, 1000) t = max(1,.4*G_T) - print 'RUNNING interpolation with %d conflicts, max %d sec and 100 frames'%(c,t) - abc('int -v -F 100 -C %d -T %f'%(c,t)) + print ' RUNNING interpolation with %d conflicts, max %d sec and 100 frames'%(c,t) + #abc('int -v -F 100 -C %d -T %f'%(c,t)) + abc(',imc -vt=%f '%t) status = get_status() if status <= Unsat: print 'Interpolation went to %d frames, '%n_bmc_frames(), print RESULT[status] return status - N = bmc_depth() L = n_latches() I = n_real_inputs() if ( ((I+L<200)&(N>100)) or (I+L<125) or L < 51 ): #heuristic that if bmc went deep, then reachability might also t = max(1,.4*G_T) cmd = 'reachx -t %d'%max(10,int(t)) - print 'Running %s'%cmd + print ' Running %s'%cmd abc(cmd) status = get_status() if status <= Unsat: @@ -944,7 +942,8 @@ def try_rpm(): bmc_before = bmc_depth() #print 'running quick bmc to see if rpm is OK' t = max(1,.1*G_T) - abc('bmc3 -C %d, -T %f'%(.1*G_C, t)) + #abc('bmc3 -C %d, -T %f'%(.1*G_C, t)) + abc('&get;,bmc -vt=%f'%t) if is_sat(): #rpm made it sat by bmc test, so undo rpm abc('r %s_savetemp.aig'%f_name) else: @@ -970,13 +969,22 @@ def final_verify(): L = n_latches() I = n_real_inputs() #try_induction(G_C) + c = max(G_C/5, 1000) + t = max(1,G_T) + print '\n***Running PDR for %d sec'%(t) + abc('&get;,pdr -vt=%f'%(t*.8)) + status = get_status() + if status <= Unsat: + print 'PDR went to %d frames, '%n_bmc_frames(), + print RESULT[status] + return status if ( ((I+L<250)&(N>100)) or (I+L<200) or (L<51) ): #heuristic that if bmc went deep, then reachability might also t = max(1,1.5*G_T) #cmd = 'reach -v -B 1000000 -F 10000 -T %f'%t #cmd = 'reachx -e %d'%int(long(t)) #cmd = 'reachx -e %d -t %d'%(int(long(t)),max(10,int(t))) cmd = 'reachx -t %d'%max(10,int(t)) - print 'Running %s'%cmd + print '\n***Running %s'%cmd abc(cmd) status = get_status() if status <= Unsat: @@ -984,16 +992,17 @@ def final_verify(): print RESULT[status] return status print 'BDD reachability aborted' - #f = max(100,bmc_depth()) - c = max(G_C/5, 1000) - t = max(1,G_T) - print '\nRUNNING interpolation with %d conflicts, %d sec, max 100 frames'%(c,t) - abc('int -v -F 100 -C %d -T %f'%(c,t)) + return status #temporary + #f = max(100, bmc_depth()) + print '\n***RUNNING interpolation with %d conflicts, %d sec, max 100 frames'%(c,t) + #abc('int -v -F 100 -C %d -T %f'%(c,t)) + abc(',imc -vt=%f '%t) status = get_status() if status <= Unsat: print 'Interpolation went to %d frames, '%n_bmc_frames(), print RESULT[status] return status + t = max(1,G_T) simplify() if n_latches() == 0: return check_sat() @@ -1005,7 +1014,7 @@ def check_sat(): the remaining logic may be UNSAT, which is usually the case, but this has to be proved. The ABC command 'dsat' is used fro combinational problems""" ## if n_ands() == 0: ## return Unsat - abc('dsat -C %d'%G_C) + abc('orpos;dsat -C %d'%G_C) if is_sat(): return Sat_true elif is_unsat(): @@ -1026,7 +1035,7 @@ def try_induction(C): """Sometimes proving the property directly using induction works but not very often. For 'ind' to work, it must have only 1 output, so all outputs are or'ed together temporarily""" return Undecided_reduction - print '\nTrying induction' + print '\n***Running induction' abc('w %s_temp.aig'%f_name) abc('orpos; ind -uv -C %d -F 10'%C) abc('r %s_savetemp.aig'%f_name) @@ -1055,11 +1064,11 @@ def final_verify_recur(K): if status >= Unsat: return status if i > 0: - print 'SAT returned, trying less abstract backup' + print 'SAT returned, Running less abstract backup' continue break if ((i == 0) and (status > Unsat) and (n_ands() > 0)): - print '\nTrying speculate on initial backup number %d:'%i, + print '\n***Running speculate on initial backup number %d:'%i, abc('r %s_backup_%d.aig'%(initial_f_name,i)) ps() if n_ands() < 20000: @@ -1073,29 +1082,42 @@ def final_verify_recur(K): return Undecided_reduction +def smp(): + pre_simp() + write_file('smp') + def pre_simp(): """This uses a set of simplification algorithms which preprocesses a design. Includes forward retiming, quick simp, signal correspondence with constraints, trimming away PIs, and strong simplify""" +## print "Trying BMC for 2 sec." +## abc("&get; ,bmc -vt=2") +## if is_sat(): +## return Sat_true set_globals() - #print 'trying forward' + if n_latches == 0: + return check_sat() + #print '\n*** Running forward' try_forward() - #print 'trying quick simp' + #print \n*** Running quick simp' quick_simp() - #print 'trying_scorr_constr' + #print 'Running_scorr_constr' status = try_scorr_constr() #status = 3 - #print 'trying trm' + #print 'Running trm' if ((n_ands() > 0) or (n_latches()>0)): abc('trm') print 'Forward, quick_simp, scorr_constr,: ', print_circuit_stats() + if n_latches() == 0: + return check_sat() status = process_status(status) if status <= Unsat: return status simplify() print 'Simplify: ', print_circuit_stats() + #abc('w temp_simp.aig') if n_latches() == 0: return check_sat() try_phase() @@ -1132,7 +1154,7 @@ def try_phase(): simplified (with retiming to see if there is a significant reduction. If not, then revert back to original""" n = n_phases() - if ((n == 1) or (n_ands() > 30000)): + if ((n == 1) or (n_ands() > 40000)): return print 'Number of possible phases = %d'%n abc('w %s_savetemp.aig'%f_name) @@ -1140,7 +1162,7 @@ def try_phase(): nl = n_latches() ni = n_pis() no = n_pos() - cost_init = (1*n_pis())+(2*n_latches())+.05*n_ands() + cost_init = (1*n_pis())+(2*n_latches())+1*n_ands() cost_min = cost_init cost = cost_init abc('w %s_best.aig'%f_name) @@ -1158,7 +1180,7 @@ def try_phase(): #print_circuit_stats() abc('rw;lcorr;trm') #print_circuit_stats() - cost = (1*n_pis())+(2*n_latches())+.05*n_ands() + cost = (1*n_pis())+(2*n_latches())+1*n_ands() if cost < cost_min: cost_min = cost abc('w %s_best.aig'%f_name) @@ -1207,7 +1229,6 @@ def quick_simp(): abc('&get;&scl;&put;rw') def scorr_constr(): - #return Undecided_no_reduction #temporarily disable the for the moment """Extracts implicit constraints and uses them in signal correspondence Constraints that are found are folded back when done""" na = max(1,n_ands()) @@ -1223,18 +1244,13 @@ def scorr_constr(): else: cmd = 'unfold' abc(cmd) - if ((n_ands() > na) or (n_pos() == 1)): + if ((n_ands() > na) or (n_pos() == n_pos_before)): abc('r %s_savetemp.aig'%f_name) return Undecided_no_reduction print_circuit_stats() print 'Number of constraints = %d'%(n_pos() - n_pos_before) - abc('scorr -c -F %dd'%f) - if n_pos_before == 1: - #abc('cone -s -O 0') #don't fold constraints back in - abc('fold') - else: - abc('fold') -## abc('fold') + abc('scorr -c -F %d'%f) + abc('fold') return Undecided_no_reduction def process_status(status): @@ -1253,7 +1269,7 @@ def input_x_factor(): def prove(a): """Proves all the outputs together. If ever an abstraction was done then if SAT is returned, we make RESULT return "undecided". - if a = 0 we skip the first quick_verify""" + If a == 1 do not run speculate""" global x_factor,xfi,f_name x = time.clock() max_bmc = -1 @@ -1262,14 +1278,18 @@ def prove(a): print_circuit_stats() x_factor = xfi print 'x_factor = %f'%x_factor - print '\nRunning pre_simp' + print '\n***Running pre_simp' set_globals() - status = pre_simp() - if status <= Unsat: + if n_latches() > 0: + status = pre_simp() + else: + status = check_sat() + if ((status <= Unsat) or (n_latches() == 0)): print 'Time for proof = %f sec.'%(time.clock() - x) return RESULT[status] if n_ands() == 0: - abc('bmc3 -T 2') + #abc('bmc3 -T 2') + abc('&get;,bmc -vt=2') if is_sat(): return 'SAT' abc('trm') @@ -1277,8 +1297,9 @@ def prove(a): abc('w %s_backup_%d.aig'%(initial_f_name,K)) K = K +1 set_globals() - if ((n_ands() < 30000) and (a == 1) and (n_latches() < 300)): - print '\nRunning quick_verify' +## if ((n_ands() < 30000) and (a == 1) and (n_latches() < 300)): + if ((n_ands() < 30000) and (n_latches() < 300)): + print '\n***Running quick_verify' status = quick_verify(0) if status <= Unsat: if not status == Unsat: @@ -1286,10 +1307,11 @@ def prove(a): print 'Time for proof = %f sec.'%(time.clock() - x) return RESULT[status] if n_ands() == 0: - abc('bmc3 -T 2') + #abc('bmc3 -T 2') + abc('&get;,bmc -vt=2') if is_sat(): return 'SAT' - print'\nRunning abstract' + print'\n***Running abstract' nl_b = n_latches() status = abstract() abc('trm') @@ -1306,27 +1328,14 @@ def prove(a): return RESULT[status] abc('w %s_backup_%d.aig'%(initial_f_name,K)) K = K +1 - if status == Undecided_reduction: - print '\nRunning quick_verify' - status = quick_verify(1) - status = process_status(status) - if status <= Unsat: - if status < Unsat: - print 'CEX in frame %d'%cex_frame() - #print 'Time for proof = %f sec.'%(time.clock() - x) - status = final_verify_recur(K-1) - abc('trm') - write_file('final') - print 'Time for proof = %f sec.'%(time.clock() - x) - return RESULT[status] - if n_ands() > 20000: - print 'Speculation skipped because too large' + if ((n_ands() > 20000) or (a == 1)): + print 'Speculation skipped because either too large or already done' K = 2 elif n_ands() == 0: - print 'Speculation skipped because no and nodes' + print 'Speculation skipped because no AND nodes' K = 2 else: - print '\nRunning speculate' + print '\n***Running speculate' status = speculate() abc('trm') write_file('spec') @@ -1359,11 +1368,11 @@ def prove_g_pos(a): init_f_name = f_name #fast_int(1) print 'Beginning prove_g_pos' - result = prove_all_ind() + prove_all_ind() print 'Number of outputs reduced to %d by induction and fast interpolation'%n_pos() - print '\n************Trying second level prove****************\n' + print '\n************Running second level prove****************\n' try_rpm() - result = prove(0) + result = prove(1) # 1 here means do not try speculate. #result = prove_0_ind() if result == 'UNSAT': print 'Second prove returned UNSAT' @@ -1372,7 +1381,7 @@ def prove_g_pos(a): print 'CEX found' return result print '\n********** Proving each output separately ************' - result = prove_all_ind() + prove_all_ind() print 'Number of outputs reduced to %d by induction and fast interpolation'%n_pos() f_name = init_f_name abc('w %s_osavetemp.aig'%f_name) @@ -1428,20 +1437,16 @@ def prove_g_pos(a): return result def prove_pos(): - """Proves the outputs clustered by a parameter a. - a is the disallowed increase in latch support Clusters must be contiguous - If a = 0 then outputs are proved individually. Clustering is done from last to first - Output 0 is attempted to be proved inductively using other outputs as constraints. + """ Proved outputs are removed if all the outputs have not been proved. If ever one of the proofs returns SAT, we stop and do not try any other outputs.""" global f_name, max_bmc,x_factor - a=0 x = time.clock() #input_x_factor() init_f_name = f_name #fast_int(1) - print 'Beginning prove_g_pos' - result = prove_all_ind() + print 'Beginning prove_pos' + prove_all_ind() print 'Number of outputs reduced to %d by induction and fast interpolation'%n_pos() print '\n********** Proving each output separately ************' f_name = init_f_name @@ -1450,6 +1455,7 @@ def prove_pos(): print 'Number of outputs = %d'%n #count = 0 pos_proved = [] + pos_disproved = [] J = 0 jnext = n-1 while jnext >= 0: @@ -1458,43 +1464,36 @@ def prove_pos(): abc('r %s_osavetemp.aig'%f_name) #Do in reverse order jnext_old = jnext - if a == 0: # do not group - extract(jnext,jnext) - jnext = jnext -1 - else: - jnext = group(a,jnext) - if jnext_old > jnext+1: - print '\nProving outputs [%d-%d]'%(jnext + 1,jnext_old) - else: - print '\nProving output %d'%(jnext_old) - #ps() - #fast_int(1) + extract(jnext,jnext) + jnext = jnext -1 + print '\nProving output %d'%(jnext_old) f_name = f_name + '_%d'%jnext_old result = prove_1() if result == 'UNSAT': - if jnext_old > jnext+1: - print '\n******** PROVED OUTPUTS [%d-%d] ******** \n\n'%(jnext+1,jnext_old) - else: - print '\n******** PROVED OUTPUT %d ******** \n\n'%(jnext_old) + print '\n******** PROVED OUTPUT %d ******** \n\n'%(jnext_old) pos_proved = pos_proved + range(jnext +1,jnext_old+1) continue if result == 'SAT': - print 'One of output in (%d to %d) is SAT'%(jnext + 1,jnext_old) - return result + print '\n******** DISPROVED OUTPUT %d ******** \n\n'%(jnext_old) + pos_disproved = pos_disproved + range(jnext +1,jnext_old+1) + continue else: - print '\n******** UNDECIDED on OUTPUTS %d thru %d ******** \n\n'%(jnext+1,jnext_old) + print '\n******** UNDECIDED on OUTPUT %d ******** \n\n'%(jnext_old) f_name = init_f_name abc('r %s_osavetemp.aig'%f_name) - if not len(pos_proved) == n: - print 'Eliminating %d proved outputs'%(len(pos_proved)) - remove(pos_proved) + list = pos_proved + pos_disproved + print 'Proved the following outputs: %s'%pos_proved + print 'Disproved the following outputs: %s'%pos_disproved + if not len(list) == n: + print 'Eliminating %d resolved outputs'%(len(list)) + remove(list) abc('trm') write_file('group') - result = 'UNDECIDED' + result = 'UNRESOLVED' else: - print 'Proved all outputs. The problem is proved UNSAT' - result = 'UNSAT' - print 'Total time for prove_g_pos = %f sec.'%(time.clock() - x) + print 'Proved or disproved all outputs. The problem is proved RESOLVED' + result = 'RESOLVED' + print 'Total time for prove_pos = %f sec.'%(time.clock() - x) return result @@ -1506,7 +1505,7 @@ def prove_g_pos_split(): init_f_name = f_name #fast_int(1) print 'Beginning prove_g_pos_split' - result = prove_all_ind() + prove_all_ind() print 'Number of outputs reduced to %d by induction and fast interpolation'%n_pos() try_rpm() print '\n********** Proving each output separately ************' @@ -1575,7 +1574,7 @@ def group(a,n): for J in range(1,n+1): abc('r %s_osavetemp.aig'%f_name) j = n-J - #print 'trying %d to %d'%(j,n) + #print 'Running %d to %d'%(j,n) extract(j,n) #print 'n_latches = %d'%n_latches() #if n_latches() >= nli + (nlt - nli)/2: @@ -1613,10 +1612,10 @@ def prove_0_ind(): return status def remove(list): - """Removes outputs in list as well as easy output proved by fast interpolation""" + """Removes outputs in list""" zero(list) - abc('scl') - fast_int(1) + abc('&get;&trim;&put') + #fast_int(1) def zero(list): """Zeros out POs in list""" @@ -1640,7 +1639,14 @@ def super_prove(): input_x_factor() max_bmc = -1 x = time.clock() + print "Trying BMC for 2 sec." + abc("&get; ,bmc -vt=2") + if is_sat(): + print 'Total time taken by super_prove = %f sec.'%(time.clock() - x) + return 'SAT' result = prove(0) + if ((result[:3] == 'UND') and (n_latches() == 0)): + return result k = 1 print result if not result[:3] == 'UND': @@ -1662,60 +1668,64 @@ def super_prove(): return result def reachm(t): + x = time.clock() run_command('&get;&reach -vcs -T %d;&put'%t) - + print 'Time = %f'%(time.clock() - x) + +def reachx(t): + x = time.clock() + run_command('reachx -t %d'%t) + print 'Time = %f'%(time.clock() - x) def BMC_VER_result(n): global init_initial_f_name #print init_initial_f_name - if n == 0: - print '\nTrying proof on initial simplified and abstracted circuit\n' - abc('r %s_smp.abs.aig'%init_initial_f_name) - ps() - x = time.clock() + xt = time.clock() result = 5 - N = 0 T = 150 - if (n_pis()+n_latches() < 250): - print ' Trying deep Reachability' - run_command('reachx -t 150') - #run_command('&get;&reach -vcs -T %d'%T) - result = get_status() - if result == Unsat: - return 'UNSAT' - if ((result < Unsat) and (n == 0)): - N = 1 - if ((result >= Unsat) and (N == 0)): - print 'Trying deep interpolation' - run_command('int -v -F 30000 -C 1000000 -T %d'%T) - result = get_status() - if result == Unsat: - return 'UNSAT' -## try_split() -## if n_pos() > 1: -## result = prove_g_pos_split() -## if result[:5] == 'UNSAT': -## return result - #ps() - abc('r %s_smp.aig'%init_initial_f_name) + if n == 0: + abc('r %s_smp.aig'%init_initial_f_name) + print '\n***Running proof on initial simplified circuit\n', + ps() + else: + print '\n***Running proof on final unproved circuit' + ps() + print ' Running PDR for %d sec'%T + abc('&get;,pdr -vt=%d'%(T*.8)) + result = get_status() + if result == Unsat: + return 'UNSAT' + if result > Unsat: #still undefined + if (n_pis()+n_latches() < 250): + print ' Running Reachability for 150 sec.' + abc('reachx -t 150') + #run_command('&get;&reach -vcs -T %d'%T) + result = get_status() + if result == Unsat: + return 'UNSAT' + if ((result > Unsat) and n ==1): + print ' Running interpolation for %f sec.'%T + abc(',imc -vt=%f'%T) + result = get_status() + if result == Unsat: + return 'UNSAT' + # if n=1 we are trying to prove result on abstracted circuit. If still undefined, then probably does + # not make sense to try pdr, reach, int on original simplified circuit, only BMC here. + if n == 1: + abc('r %s_smp.aig'%init_initial_f_name) #check if the initial circuit was SAT + #print 'Reading %s_smp'%init_initial_f_name, + #run_command('bmc3 -v -T %d -F 200000 -C 1000000'%T) + print '***Running BMC on initial simplified circuit' ps() - if N == 1: - print '\nTrying deep interpolation on initial simplified circuit\n' - run_command('int -v -F 30000 -C 1000000 -T %d'%T) - result = get_status() - if result == Unsat: - return 'UNSAT' - if result < Unsat: - return 'SAT' - print '\nTrying deep BMC on initial simplified circuit\n' - run_command('bmc3 -v -T %d -F 200000 -C 1000000'%T) + print '\n' + abc('&get;,bmc -vt=%f'%T) result = get_status() if result < Unsat: result = 'SAT' print ' CEX found in frame %d'%cex_frame() else: result = 'UNDECIDED' - print 'Additional time taken by BMC/ability = %f sec.'%(time.clock() - x) + print 'Additional time taken by BMC/PDR/Reach = %f sec.'%(time.clock() - xt) return result def try_split(): @@ -1733,12 +1743,74 @@ def time_diff(): last_time = new_time result = 'Lapsed time = %.2f sec.'%diff return result - + def prove_all_ind(): + """Tries to prove output k by induction, using other outputs as constraints. If ever an output is proved + it is set to 0 so it can't be used in proving another output to break circularity. + Finally all zero'ed ooutputs are removed. """ + N = n_pos() + remove_0_pos() + print '0 valued output removal changed POs from %d to %d'%(N,n_pos()) + abc('w %s_osavetemp.aig'%f_name) + list = range(n_pos()) + for j in list: + #abc('r %s_osavetemp.aig'%f_name) + abc('swappos -N %d'%j) + remove_0_pos() #may not have to do this if constr works well with 0'ed outputs + abc('constr -N %d'%(n_pos()-1)) + abc('fold') + n = max(1,n_ands()) + f = max(1,min(40000/n,16)) + f = int(f) + abc('ind -u -C 10000 -F %d'%f) + status = get_status() + abc('r %s_osavetemp.aig'%f_name) + if status == Unsat: + print '+', + abc('zeropo -N %d'%j) + abc('w %s_osavetemp.aig'%f_name) #if changed, store it permanently + print '%d'%j, + remove_0_pos() + print '\nThe number of POs reduced from %d to %d'%(N,n_pos()) + #return status + +def prove_all_pdr(t): + """Tries to prove output k by PDR. If ever an output is proved + it is set to 0. Finally all zero'ed ooutputs are removed. """ + N = n_pos() + remove_0_pos() + print '0 valued output removal changed POs from %d to %d'%(N,n_pos()) + abc('w %s_osavetemp.aig'%f_name) + list = range(n_pos()) + for j in list: + #abc('r %s_osavetemp.aig'%f_name) + abc('cone -O %d -s'%j) + abc('scl') + abc('&get;,pdr -vt=%d'%t) + status = get_status() + abc('r %s_osavetemp.aig'%f_name) + if status == Unsat: + print '+', + abc('zeropo -N %d'%j) + abc('w %s_osavetemp.aig'%f_name) #if changed, store it permanently + print '%d'%j, + remove_0_pos() + print '\nThe number of POs reduced from %d to %d'%(N,n_pos()) + #return status + + +def remove_0_pos(): + abc('&get; &trim; &put') + + +def prove_all_ind2(): """Tries to prove output k by induction, using outputs > k as constraints. Removes proved outputs from POs.""" abc('w %s_osavetemp.aig'%f_name) plist = [] - for j in range(n_pos()): + list = range(n_pos()) +## if r == 1: +## list.reverse() + for j in list: abc('r %s_osavetemp.aig'%f_name) extract(j,n_pos()) abc('constr -N %d'%(n_pos()-1)) @@ -1750,12 +1822,50 @@ def prove_all_ind(): status = get_status() if status == Unsat: plist = plist + [j] + print '-', +## else: +## status = pdr(1) +## if status == Unsat: +## print '+', +## plist = plist + [j] print '%d'%j, - print '\nOutputs proved inductively = ', + print '\nOutputs proved = ', print plist abc('r %s_osavetemp.aig'%f_name) remove(plist) #remove the outputs proved - return status +## #the following did not work because abc command constr, allows only last set of outputs to be constraints +## abc('w %s_osavetemp.aig'%f_name) +## plist = [] +## list = range(n_pos()) +## list.reverse() +## for j in list: +## abc('r %s_osavetemp.aig'%f_name) +## extract(j,n_pos()) +## abc('constr -N %d'%(n_pos()-1)) +## abc('fold') +## n = max(1,n_ands()) +## f = max(1,min(40000/n,16)) +## f = int(f) +## abc('ind -u -C 10000 -F %d'%f) +## status = get_status() +## if status == Unsat: +## plist = plist + [j] +## print '-', +#### else: +#### status = pdr(1) +#### if status == Unsat: +#### print '+', +#### plist = plist + [j] +## print '%d'%j, +## print '\nOutputs proved = ', +## print plist.reverse +## abc('r %s_osavetemp.aig'%f_name) +## remove(plist) #remove the outputs proved +## return status + +def pdr(t): + abc('&get; ,pdr -vt=%f'%t) + result = get_status() def split(n): abc('orpos;&get') @@ -1787,10 +1897,10 @@ def prove_1(): print_circuit_stats() x_factor = xfi print 'x_factor = %f'%x_factor - print '\nRunning pre_simp' + print '\n***Running pre_simp' set_globals() status = pre_simp() - if status <= Unsat: + if ((status <= Unsat) or (n_latches == 0)): print 'Time for proof = %f sec.'%(time.clock() - x) return RESULT[status] abc('trm') @@ -1799,14 +1909,14 @@ def prove_1(): K = K +1 set_globals() if ((n_ands() < 30000) and (a == 1) and (n_latches() < 300)): - print '\nRunning quick_verify' + print '\n***Running quick_verify' status = quick_verify(0) if status <= Unsat: if not status == Unsat: print 'CEX in frame %d'%cex_frame() print 'Time for proof = %f sec.'%(time.clock() - x) return RESULT[status] - print'\nRunning abstract' + print'\n***Running abstract' nl_b = n_latches() status = abstract() abc('trm') @@ -1851,5 +1961,47 @@ def qprove(): print 'Time for proof = %f sec.'%(time.clock() - x) return result +def pre_reduce(): + x = time.clock() + pre_simp() + write_file('smp') + abstract() + write_file('abs') + print 'Time = %f'%(time.clock() - x) + +#PARALLEL FUNCTIONS +""" funcs should look like +funcs = [defer(abc)('&get;,bmc -vt=50;&put'),defer(super_prove)()] +After this is executed funcs becomes a special list of lambda functions +which are given to abc_split_all to be executed as in fork below. +It has been set up so that each of the functions works on the current aig and +possibly transforms it. The new aig and status is always read into the master when done +""" + +def fork(funcs): + """ runs funcs in parallel""" + for i,res in pyabc_split.abc_split_all(funcs): + status = prob_status() + if not status == -1: + print i,status + ps() + break + else: + print i,status + ps() + continue + return status + +def handler_s(res): + """ This serial handler returns True if the problem is solved by the first returning function, + in which case, the problem is replaced by the new aig and status. + """ + if not res == -1: + #replace_prob() + print ('UNSAT','SAT')[res] + return True + else: + return False + -- cgit v1.2.3