From 211db8bf28002dcfefca32bb83c488265347c3cf Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 8 Dec 2016 10:37:36 -0800 Subject: Improvements to GIA visualization. --- src/aig/gia/giaShow.c | 770 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 505 insertions(+), 265 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 872ba6ec..bc372746 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -33,151 +33,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -/* -Vec_Int_t * Gia_WriteDotAigMarks( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds ) -{ - int i; - Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) ); - for ( i = 0; i < Vec_IntSize(vHadds)/2; i++ ) - { - Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+0), Abc_Var2Lit(i+1, 0) ); - Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+1), Abc_Var2Lit(i+1, 0) ); - } - for ( i = 0; i < Vec_IntSize(vFadds)/5; i++ ) - { - Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+3), Abc_Var2Lit(i+1, 1) ); - Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+4), Abc_Var2Lit(i+1, 1) ); - } - return vMarks; -} -int Gia_WriteDotAigLevel_rec( Gia_Man_t * p, Vec_Int_t * vMarks, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int Id, Vec_Int_t * vLevel ) -{ - int Level = Vec_IntEntry(vLevel, Id), Mark = Vec_IntEntry(vMarks, Id); - if ( Level || Mark == -1 ) - return Level; - if ( Mark == 0 ) - { - Gia_Obj_t * pObj = Gia_ManObj( p, Id ); - int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel ); - int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel ); - Level = Abc_MaxInt(Level0, Level1) + 1; - Vec_IntWriteEntry( vLevel, Id, Level ); - Vec_IntWriteEntry( vMarks, Id, -1 ); - } - else if ( Abc_LitIsCompl(Mark) ) // FA - { - int i, * pFanins = Vec_IntEntryP( vFadds, 5*(Abc_Lit2Var(Mark)-1) ); - assert( pFanins[3] == Id || pFanins[4] == Id ); - for ( i = 0; i < 3; i++ ) - Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, pFanins[i], vLevel ) ); - Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 ); - Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 ); - } - else // HA - { - int * pFanins = Vec_IntEntryP( vHadds, 2*(Abc_Lit2Var(Mark)-1) ); - Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] ); - int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel ); - int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel ); - assert( pFanins[0] == Id || pFanins[1] == Id ); - Level = Abc_MaxInt(Level0, Level1) + 1; - Vec_IntWriteEntry( vLevel, pFanins[0], Level ); - Vec_IntWriteEntry( vLevel, pFanins[1], Level ); - } - return Level; -} -int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t ** pvMarks, Vec_Int_t ** pvLevel ) -{ - Vec_Int_t * vMarks = Gia_WriteDotAigMarks( p, vFadds, vHadds ); - Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) ); - int i, Id, Level = 0; - Vec_IntWriteEntry( vMarks, 0, -1 ); - Gia_ManForEachCiId( p, Id, i ) - Vec_IntWriteEntry( vMarks, Id, -1 ); - Gia_ManForEachCoDriverId( p, Id, i ) - Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec(p, vMarks, vFadds, vHadds, Id, vLevel) ); - Gia_ManForEachCoId( p, Id, i ) - Vec_IntWriteEntry( vMarks, Id, -1 ); - *pvMarks = vMarks; - *pvLevel = vLevel; - return Level; -} -*/ -int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t * vRecord, Vec_Int_t ** pvLevel, Vec_Int_t ** pvMarks, Vec_Int_t ** pvRemap, Vec_Int_t ** pvRemap2 ) -{ - Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) ); - Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) ); - Vec_Int_t * vRemap = Vec_IntStartNatural( Gia_ManObjNum(p) ); - Vec_Int_t * vRemap2 = Vec_IntStartNatural( Gia_ManObjNum(p) ); - int i, k, Id, Entry, LevelMax = 0; - - Vec_IntWriteEntry( vMarks, 0, -1 ); - Gia_ManForEachCiId( p, Id, i ) - Vec_IntWriteEntry( vMarks, Id, -1 ); - Gia_ManForEachCoId( p, Id, i ) - Vec_IntWriteEntry( vMarks, Id, -1 ); - - Vec_IntForEachEntry( vRecord, Entry, i ) - { - int Level = 0; - int Node = Abc_Lit2Var2(Entry); - int Attr = Abc_Lit2Att2(Entry); - if ( Attr == 2 ) - { - int * pFanins = Vec_IntEntryP( vFadds, 5*Node ); - for ( k = 0; k < 3; k++ ) - Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFanins[k]) ); - Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 ); - Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 ); - Vec_IntWriteEntry( vMarks, pFanins[4], Entry ); - Vec_IntWriteEntry( vRemap, pFanins[3], pFanins[4] ); - Vec_IntWriteEntry( vRemap2, pFanins[4], pFanins[3] ); - //printf( "Making FA output %d.\n", pFanins[4] ); - } - else if ( Attr == 1 ) - { - int * pFanins = Vec_IntEntryP( vHadds, 2*Node ); - Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] ); - int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, pFanins[1]), Gia_ObjFaninId1(pObj, pFanins[1]) }; - for ( k = 0; k < 2; k++ ) - Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) ); - Vec_IntWriteEntry( vLevel, pFanins[0], Level+1 ); - Vec_IntWriteEntry( vLevel, pFanins[1], Level+1 ); - Vec_IntWriteEntry( vMarks, pFanins[1], Entry ); - Vec_IntWriteEntry( vRemap, pFanins[0], pFanins[1] ); - Vec_IntWriteEntry( vRemap2, pFanins[1], pFanins[0] ); - //printf( "Making HA output %d %d.\n", pFanins[0], pFanins[1] ); - } - else // if ( Attr == 3 || Attr == 0 ) - { - Gia_Obj_t * pObj = Gia_ManObj( p, Node ); - int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, Node), Gia_ObjFaninId1(pObj, Node) }; - for ( k = 0; k < 2; k++ ) - Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) ); - Vec_IntWriteEntry( vLevel, Node, Level+1 ); - Vec_IntWriteEntry( vMarks, Node, -1 ); - //printf( "Making node %d.\n", Node ); - } - LevelMax = Abc_MaxInt( LevelMax, Level+1 ); - } - *pvLevel = vLevel; - *pvMarks = vMarks; - *pvRemap = vRemap; - *pvRemap2 = vRemap2; - return LevelMax; -} - /**Function************************************************************* Synopsis [Writes the graph structure of AIG for DOT.] @@ -190,17 +45,16 @@ int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, SeeAlso [] ***********************************************************************/ -void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fAdders ) +void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) { - Vec_Int_t * vFadds = NULL, * vHadds = NULL, * vRecord = NULL, * vMarks = NULL, * vRemap = NULL, * vRemap2 = NULL; FILE * pFile; Gia_Obj_t * pNode;//, * pTemp, * pPrev; int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(pMan) > 1000 ) + if ( Gia_ManAndNum(p) > 200 ) { - fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -211,28 +65,17 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // mark the nodes if ( vBold ) - Gia_ManForEachObjVec( vBold, pMan, pNode, i ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) pNode->fMark0 = 1; - else if ( pMan->nXors || pMan->nMuxes ) - Gia_ManForEachObj( pMan, pNode, i ) - if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(pMan, pNode) ) + else if ( p->nXors || p->nMuxes ) + Gia_ManForEachObj( p, pNode, i ) + if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) ) pNode->fMark0 = 1; // compute levels - if ( fAdders ) - { - Vec_IntFreeP( &pMan->vLevels ); - vFadds = Gia_ManDetectFullAdders( pMan, 0, NULL ); - vHadds = Gia_ManDetectHalfAdders( pMan, 0 ); - vRecord = Gia_PolynFindOrder( pMan, vFadds, vHadds, 0, 0 ); - LevelMax = 1 + Gia_WriteDotAigLevel( pMan, vFadds, vHadds, vRecord, &pMan->vLevels, &vMarks, &vRemap, &vRemap2 ); - } - else - LevelMax = 1 + Gia_ManLevelNum( pMan ); - - // set output levels - Gia_ManForEachCo( pMan, pNode, i ) - Vec_IntWriteEntry( pMan->vLevels, Gia_ObjId(pMan, pNode), LevelMax ); + LevelMax = 1 + Gia_ManLevelNum( p ); + Gia_ManForEachCo( p, pNode, i ) + Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); // write the DOT header fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); @@ -309,7 +152,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(pMan), LevelMax ); + fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -323,9 +166,9 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // the labeling node of this level fprintf( pFile, " Level%d;\n", LevelMax ); // generate the CO nodes - Gia_ManForEachCo( pMan, pNode, i ) + Gia_ManForEachCo( p, pNode, i ) { - if ( Gia_ObjFaninId0p(pMan, pNode) == 0 ) + if ( Gia_ObjFaninId0p(p, pNode) == 0 ) fConstIsUsed = 1; /* if ( fHaig || pNode->pEquiv == NULL ) @@ -336,7 +179,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int (Gia_ObjIsLatch(pNode)? "_in":""), pNode->Id, (Gia_ObjIsLatch(pNode)? "_in":""), Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" ); */ - fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(pMan, pNode), Gia_ObjId(pMan, pNode) ); + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); fprintf( pFile, ", shape = %s", "invtriangle" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); @@ -353,11 +196,9 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fprintf( pFile, " rank = same;\n" ); // the labeling node of this level fprintf( pFile, " Level%d;\n", Level ); - Gia_ManForEachObj( pMan, pNode, i ) + Gia_ManForEachObj( p, pNode, i ) { - if ( vMarks && Vec_IntEntry(vMarks, i) == 0 ) - continue; - if ( (int)Gia_ObjLevel(pMan, pNode) != Level ) + if ( (int)Gia_ObjLevel(p, pNode) != Level ) continue; /* if ( fHaig || pNode->pEquiv == NULL ) @@ -366,29 +207,14 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fprintf( pFile, " Node%d [label = \"%d(%d%s)\"", pNode->Id, pNode->Id, Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" ); */ - if ( vMarks && Vec_IntEntry(vMarks, i) > 0 ) - { - fprintf( pFile, " Node%d [label = \"%d_%d\"", i, Vec_IntEntry(vRemap2, i), i ); - if ( Abc_Lit2Att2(Vec_IntEntry(vMarks, i)) == 2 ) - fprintf( pFile, ", shape = doubleoctagon" ); - else - fprintf( pFile, ", shape = octagon" ); - } - else if ( Gia_ObjIsXor(pNode) ) - { - fprintf( pFile, " Node%d [label = \"%d\"", i, i ); + fprintf( pFile, " Node%d [label = \"%d\"", i, i ); + + if ( Gia_ObjIsXor(pNode) ) fprintf( pFile, ", shape = doublecircle" ); - } - else if ( Gia_ObjIsMux(pMan, pNode) ) - { - fprintf( pFile, " Node%d [label = \"%d\"", i, i ); + else if ( Gia_ObjIsMux(p, pNode) ) fprintf( pFile, ", shape = trapezium" ); - } else - { - fprintf( pFile, " Node%d [label = \"%d\"", i, i ); fprintf( pFile, ", shape = ellipse" ); - } if ( pNode->fMark0 ) fprintf( pFile, ", style = filled" ); @@ -405,7 +231,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // the labeling node of this level fprintf( pFile, " Level%d;\n", 0 ); // generate constant node - if ( fConstIsUsed || pMan->fGiaSimple ) + if ( fConstIsUsed ) { // check if the costant node is present fprintf( pFile, " Node%d [label = \"Const0\"", 0 ); @@ -414,7 +240,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int fprintf( pFile, "];\n" ); } // generate the CI nodes - Gia_ManForEachCi( pMan, pNode, i ) + Gia_ManForEachCi( p, pNode, i ) { /* if ( fHaig || pNode->pEquiv == NULL ) @@ -425,7 +251,7 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int (Gia_ObjIsLatch(pNode)? "_out":""), pNode->Id, (Gia_ObjIsLatch(pNode)? "_out":""), Gia_Regular(pNode->pEquiv)->Id, Gia_IsComplement(pNode->pEquiv)? "\'":"" ); */ - fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(pMan, pNode), Gia_ObjId(pMan, pNode) ); + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); fprintf( pFile, ", shape = %s", "triangle" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); @@ -437,73 +263,37 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // generate invisible edges from the square down fprintf( pFile, "title1 -> title2 [style = invis];\n" ); - Gia_ManForEachCo( pMan, pNode, i ) - fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(pMan, pNode) ); + Gia_ManForEachCo( p, pNode, i ) + fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) ); // generate invisible edges among the COs Prev = -1; - Gia_ManForEachCo( pMan, pNode, i ) + Gia_ManForEachCo( p, pNode, i ) { if ( i > 0 ) - fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(pMan, pNode) ); - Prev = Gia_ObjId(pMan, pNode); + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Gia_ManForEachCi( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); } // generate edges - Gia_ManForEachObj( pMan, pNode, i ) + Gia_ManForEachObj( p, pNode, i ) { if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) ) continue; - if ( vMarks && Vec_IntEntry(vMarks, i) == 0 ) - continue; - // consider half/full-adder - if ( vMarks && Vec_IntEntry(vMarks, i) > 0 ) - { - int k, Mark = Vec_IntEntry(vMarks, i); - if ( Abc_Lit2Att2(Mark) == 2 ) // FA - { - int * pFanins = Vec_IntEntryP( vFadds, 5*Abc_Lit2Var2(Mark) ); - if ( pFanins[3] == i ) - continue; - assert( pFanins[4] == i ); - // generate the edge from this node to the next - for ( k = 0; k < 3; k++ ) - { - fprintf( pFile, "Node%d", i ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", Vec_IntEntry(vRemap, pFanins[k]) ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", "bold" ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - } - } - else // HA - { - int * pFanins = Vec_IntEntryP( vHadds, 2*Abc_Lit2Var2(Mark) ); - int pFaninsIn[2] = { Vec_IntEntry(vRemap, Gia_ObjFaninId0(pNode, i)), Vec_IntEntry(vRemap, Gia_ObjFaninId1(pNode, i)) }; - if ( pFanins[0] == i ) - continue; - assert( pFanins[1] == i ); - for ( k = 0; k < 2; k++ ) - { - fprintf( pFile, "Node%d", i ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", Vec_IntEntry(vRemap, pFaninsIn[k]) ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", "bold" ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - } - } - continue; - } // generate the edge from this node to the next fprintf( pFile, "Node%d", i ); fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId0(pNode, i)) : Gia_ObjFaninId0(pNode, i) ); + fprintf( pFile, "Node%d", Gia_ObjFaninId0(pNode, i) ); fprintf( pFile, " [" ); fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); -// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL0(pNode) > 0 ) +// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL0(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -512,23 +302,23 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // generate the edge from this node to the next fprintf( pFile, "Node%d", i ); fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId1(pNode, i)) : Gia_ObjFaninId1(pNode, i) ); + fprintf( pFile, "Node%d", Gia_ObjFaninId1(pNode, i) ); fprintf( pFile, " [" ); fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" ); -// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL1(pNode) > 0 ) +// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL1(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); - if ( !Gia_ObjIsMux(pMan, pNode) ) + if ( !Gia_ObjIsMux(p, pNode) ) continue; // generate the edge from this node to the next fprintf( pFile, "Node%d", i ); fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", vRemap ? Vec_IntEntry(vRemap, Gia_ObjFaninId2(pMan, i)) : Gia_ObjFaninId2(pMan, i) ); + fprintf( pFile, "Node%d", Gia_ObjFaninId2(p, i) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC2(pMan, pNode)? "dotted" : "bold" ); -// if ( Gia_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL1(pNode) > 0 ) + fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "bold" ); +// if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL1(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -564,18 +354,440 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int // unmark nodes if ( vBold ) - Gia_ManForEachObjVec( vBold, pMan, pNode, i ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) pNode->fMark0 = 0; - else if ( pMan->nXors || pMan->nMuxes ) - Gia_ManCleanMark0( pMan ); + else if ( p->nXors || p->nMuxes ) + Gia_ManCleanMark0( p ); + + Vec_IntFreeP( &p->vLevels ); +} + +/**Function************************************************************* + + Synopsis [Writes the graph structure of AIG for DOT.] + + Description [Useful for graph visualization using tools such as GraphViz: + http://www.graphviz.org/] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node ) +{ + int iBox = Vec_IntEntry( vMapAdds, Node ); + if ( iBox >= 0 ) + return Vec_IntEntry( vAdds, 6*iBox+3 ); + return Node; +} +void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) +{ + FILE * pFile; + Gia_Obj_t * pNode;//, * pTemp, * pPrev; + int LevelMax, Prev, Level, i; + int fConstIsUsed = 0; + + if ( Gia_ManAndNum(p) > 500 ) + { + fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); + return; + } + if ( (pFile = fopen( pFileName, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); + return; + } + + // compute levels + LevelMax = 1 + p->nLevels; + Gia_ManForEachCo( p, pNode, i ) + Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); + + // write the DOT header + fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "digraph AIG {\n" ); + fprintf( pFile, "size = \"7.5,10\";\n" ); +// fprintf( pFile, "ranksep = 0.5;\n" ); +// fprintf( pFile, "nodesep = 0.5;\n" ); + fprintf( pFile, "center = true;\n" ); +// fprintf( pFile, "orientation = landscape;\n" ); +// fprintf( pFile, "edge [fontsize = 10];\n" ); +// fprintf( pFile, "edge [dir = none];\n" ); + fprintf( pFile, "edge [dir = back];\n" ); + fprintf( pFile, "\n" ); + + // labels on the left of the picture + fprintf( pFile, "{\n" ); + fprintf( pFile, " node [shape = plaintext];\n" ); + fprintf( pFile, " edge [style = invis];\n" ); + fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); + fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); + // generate node names with labels + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + fprintf( pFile, " [label = " ); + // label name + fprintf( pFile, "\"" ); + fprintf( pFile, "\"" ); + fprintf( pFile, "];\n" ); + } + + // genetate the sequence of visible/invisible nodes to mark levels + fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + // the connector + if ( Level != 0 ) + fprintf( pFile, " ->" ); + else + fprintf( pFile, ";" ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate title box on top + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle1;\n" ); + fprintf( pFile, " title1 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=20,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "%s", "AIG structure visualized by ABC" ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" ); +// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate statistics box + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle2;\n" ); + fprintf( pFile, " title2 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=18,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate the COs + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", LevelMax ); + // generate the CO nodes + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjFaninId0p(p, pNode) == 0 ) + fConstIsUsed = 1; + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + + fprintf( pFile, ", shape = %s", "invtriangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate nodes of each rank + for ( Level = LevelMax - 1; Level > 0; Level-- ) + { + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", Level ); + Gia_ManForEachObjVec( vOrder, p, pNode, i ) + { + int iNode = Gia_ObjId( p, pNode ); + if ( (int)Gia_ObjLevel(p, pNode) != Level ) + continue; +/* + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + if ( Gia_ObjIsXor(pNode) ) + fprintf( pFile, ", shape = doublecircle" ); + else if ( Gia_ObjIsMux(p, pNode) ) + fprintf( pFile, ", shape = trapezium" ); + else + fprintf( pFile, ", shape = ellipse" ); +*/ + if ( Vec_IntEntry(vMapAdds, iNode) >= 0 ) + { + int iBox = Vec_IntEntry(vMapAdds, iNode); + fprintf( pFile, " Node%d [label = \"%d_%d\"", Gia_ShowAddOut(vAdds, vMapAdds, iNode), Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); + if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) + fprintf( pFile, ", shape = octagon" ); + else + fprintf( pFile, ", shape = doubleoctagon" ); + } + else if ( Vec_IntEntry(vMapXors, iNode) >= 0 ) + { + int iXor = Vec_IntEntry(vMapXors, iNode); + fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); + fprintf( pFile, ", shape = doublecircle" ); + } + else if ( Gia_ObjIsXor(pNode) ) + { + fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); + fprintf( pFile, ", shape = doublecircle" ); + } + else if ( Gia_ObjIsMux(p, pNode) ) + { + fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); + fprintf( pFile, ", shape = trapezium" ); + } + else + { + fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); + fprintf( pFile, ", shape = ellipse" ); + } +// if ( pNode->fMark0 ) +// fprintf( pFile, ", style = filled" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + } - Vec_IntFreeP( &vFadds ); - Vec_IntFreeP( &vHadds ); - Vec_IntFreeP( &vRecord ); + // generate the CI nodes + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", 0 ); + // generate constant node + if ( fConstIsUsed ) + { + // check if the costant node is present + fprintf( pFile, " Node%d [label = \"Const0\"", 0 ); + fprintf( pFile, ", shape = ellipse" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + // generate the CI nodes + Gia_ManForEachCi( p, pNode, i ) + { + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + + fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); - Vec_IntFreeP( &pMan->vLevels ); - Vec_IntFreeP( &vMarks ); - Vec_IntFreeP( &vRemap ); + // generate invisible edges from the square down + fprintf( pFile, "title1 -> title2 [style = invis];\n" ); + Gia_ManForEachCo( p, pNode, i ) + fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) ); + // generate invisible edges among the COs + Prev = -1; + Gia_ManForEachCo( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Gia_ManForEachCi( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + + // generate edges + Gia_ManForEachCo( p, pNode, i ) + { + int iNode = Gia_ObjId( p, pNode ); + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + Gia_ManForEachObjVec( vOrder, p, pNode, i ) + { + int iNode = Gia_ObjId( p, pNode ); +// if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) ) +// continue; + if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pNode)) >= 0 ) + { + int k, iBox = Vec_IntEntry(vMapAdds, iNode); + for ( k = 0; k < 3; k++ ) + if ( Vec_IntEntry(vAdds, 6*iBox+k) ) + { + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, iNode) ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vAdds, 6*iBox+k)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", 0? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + continue; + } + if ( Vec_IntEntry(vMapXors, Gia_ObjId(p, pNode)) >= 0 ) + { + int k, iXor = Vec_IntEntry(vMapXors, iNode); + for ( k = 1; k < 4; k++ ) + if ( Vec_IntEntry(vXors, 4*iXor+k) ) + { + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vXors, 4*iXor+k)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", 0? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + continue; + } + // generate the edge from this node to the next + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + if ( !Gia_ObjIsAnd(pNode) ) + continue; + // generate the edge from this node to the next + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId1(pNode, iNode)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + + if ( !Gia_ObjIsMux(p, pNode) ) + continue; + // generate the edge from this node to the next + fprintf( pFile, "Node%d", iNode ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId2(p, iNode)) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + + Vec_IntFreeP( &p->vLevels ); +} + +/**Function************************************************************* + + Synopsis [Returns DFS ordered array of objects and their levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i ); + Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i ); + } + return vMapAdds; +} +Vec_Int_t * Gia_ShowMapXors( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Int_t * vMapXors = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + Vec_IntWriteEntry( vMapXors, Vec_IntEntry(vXors, 4*i), i ); + return vMapXors; +} +int Gia_ShowCollectObjs_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) +{ + int Level0, Level1, Level2 = 0, Level = 0; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return Gia_ObjLevel(p, pObj); + Gia_ObjSetTravIdCurrent(p, pObj); + if ( Gia_ObjIsCi(pObj) ) + return 0; + if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pObj)) >= 0 ) + { + int iBox = Vec_IntEntry(vMapAdds, Gia_ObjId(p, pObj)); + Gia_ObjSetTravIdCurrentId(p, Vec_IntEntry(vAdds, 6*iBox+3) ); + Gia_ObjSetTravIdCurrentId(p, Vec_IntEntry(vAdds, 6*iBox+4) ); + Level0 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+0) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level1 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+1) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + if ( Vec_IntEntry(vAdds, 6*iBox+2) ) + Level2 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+2) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level = 1 + Abc_MaxInt( Abc_MaxInt(Level0, Level1), Level2 ); + Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+3), Level ); + Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+4), Level ); + pObj = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+3) ); + } + else if ( Vec_IntEntry(vMapXors, Gia_ObjId(p, pObj)) >= 0 ) + { + int iXor = Vec_IntEntry(vMapXors, Gia_ObjId(p, pObj)); + Level0 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+1) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level1 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+2) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + if ( Vec_IntEntry(vXors, 4*iXor+3) ) + Level2 = Gia_ShowCollectObjs_rec( p, Gia_ManObj( p, Vec_IntEntry(vXors, 4*iXor+3) ), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level = 1 + Abc_MaxInt( Abc_MaxInt(Level0, Level1), Level2 ); + Gia_ObjSetLevel( p, pObj, Level ); + } + else + { + assert( !Gia_ObjIsMux(p, pObj) ); + Level0 = Gia_ShowCollectObjs_rec( p, Gia_ObjFanin0(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level1 = Gia_ShowCollectObjs_rec( p, Gia_ObjFanin1(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Level = 1 + Abc_MaxInt(Level0, Level1); + Gia_ObjSetLevel( p, pObj, Level ); + } + Vec_IntPush( vOrder, Gia_ObjId(p, pObj) ); + p->nLevels = Abc_MaxInt( p->nLevels, Level ); + return Level; +} +Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors ) +{ + Gia_Obj_t * pObj; int i; + Vec_Int_t * vOrder = Vec_IntAlloc( 100 ); + Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); + p->nLevels = 0; + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrent(p, Gia_ManConst0(p)); + Gia_ManForEachCi( p, pObj, i ) + Gia_ObjSetTravIdCurrent(p, pObj); + Gia_ManForEachCo( p, pObj, i ) + Gia_ShowCollectObjs_rec( p, Gia_ObjFanin0(pObj), vAdds, vXors, vMapAdds, vMapXors, vOrder ); + return vOrder; } /**Function************************************************************* @@ -589,12 +801,31 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold, int SeeAlso [] ***********************************************************************/ +void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors ) +{ + Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds ); + Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); + Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); + Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Vec_IntFree( vMapAdds ); + Vec_IntFree( vMapXors ); + Vec_IntFree( vOrder ); +} void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) { + extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); + extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Abc_ShowFile( char * FileNameDot ); static int Counter = 0; char FileNameDot[200]; FILE * pFile; + + Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); + Ree_ManRemoveTrivial( pMan, vAdds ); + Ree_ManRemoveContained( pMan, vAdds ); + // create the file name // Gia_ShowGetFileName( pMan->pName, FileNameDot ); sprintf( FileNameDot, "temp%02d.dot", Counter++ ); @@ -606,12 +837,21 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) } fclose( pFile ); // generate the file - Gia_WriteDotAig( pMan, FileNameDot, vBold, fAdders ); + if ( fAdders ) + Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors ); + else + Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file Abc_ShowFile( FileNameDot ); + + Vec_IntFree( vAdds ); + Vec_IntFree( vXors ); } + + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From cd92b1fea386707bd1dd3003d3fa630385528373 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 8 Dec 2016 10:39:11 -0800 Subject: Improvements to GIA visualization. --- src/aig/gia/giaShow.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index bc372746..c68ba26c 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -539,7 +539,6 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In } else if ( Vec_IntEntry(vMapXors, iNode) >= 0 ) { - int iXor = Vec_IntEntry(vMapXors, iNode); fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); fprintf( pFile, ", shape = doublecircle" ); } -- cgit v1.2.3 From 5351ab4b13aa46db5710ca3ffe659e8e691ba126 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 12 Dec 2016 16:20:38 -0200 Subject: =?UTF-8?q?xSAT=20is=20an=20experimental=20SAT=20Solver=20based=20?= =?UTF-8?q?on=20Glucose=20v3(see=20Glucose=20copyrights=20below)=20and=20A?= =?UTF-8?q?BC=20C=20version=20of=20MiniSat=20(bsat)=20developed=20by=20Nik?= =?UTF-8?q?las=20Sorensson=20and=20modified=20by=20Alan=20Mishchenko.=20It?= =?UTF-8?q?=E2=80=99s=20development=20has=20reached=20sufficient=20maturit?= =?UTF-8?q?y=20to=20be=20committed=20in=20ABC,=20but=20still=20in=20a=20be?= =?UTF-8?q?ta=20state.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TODO: * Read compressed CNF files. * Study the use of floating point for variables and clauses activity. * Better documentation. * Improve verbose messages. * Expose parameters for tuning. --- src/base/abci/abc.c | 339 ++++++++++----- src/sat/xsat/license | 39 ++ src/sat/xsat/module.make | 3 + src/sat/xsat/xsat.h | 59 +++ src/sat/xsat/xsatBQueue.h | 189 ++++++++ src/sat/xsat/xsatClause.h | 109 +++++ src/sat/xsat/xsatCnfReader.c | 236 ++++++++++ src/sat/xsat/xsatHeap.h | 330 ++++++++++++++ src/sat/xsat/xsatMemory.h | 225 ++++++++++ src/sat/xsat/xsatSolver.c | 995 +++++++++++++++++++++++++++++++++++++++++++ src/sat/xsat/xsatSolver.h | 247 +++++++++++ src/sat/xsat/xsatSolverAPI.c | 345 +++++++++++++++ src/sat/xsat/xsatUtils.h | 106 +++++ src/sat/xsat/xsatWatchList.h | 268 ++++++++++++ 14 files changed, 3391 insertions(+), 99 deletions(-) create mode 100644 src/sat/xsat/license create mode 100644 src/sat/xsat/module.make create mode 100644 src/sat/xsat/xsat.h create mode 100644 src/sat/xsat/xsatBQueue.h create mode 100644 src/sat/xsat/xsatClause.h create mode 100644 src/sat/xsat/xsatCnfReader.c create mode 100644 src/sat/xsat/xsatHeap.h create mode 100644 src/sat/xsat/xsatMemory.h create mode 100644 src/sat/xsat/xsatSolver.c create mode 100644 src/sat/xsat/xsatSolver.h create mode 100644 src/sat/xsat/xsatSolverAPI.c create mode 100644 src/sat/xsat/xsatUtils.h create mode 100644 src/sat/xsat/xsatWatchList.h (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7da88d3c..dabeb982 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -1,15 +1,15 @@ /**CFile**************************************************************** - - FileName [abc.c] + + FileName [abc.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Network and node package.] - + Synopsis [Command file.] Author [Alan Mishchenko] - + Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] @@ -42,6 +42,7 @@ #include "bool/kit/kit.h" #include "map/amap/amap.h" #include "opt/ret/retInt.h" +#include "sat/xsat/xsat.h" #include "sat/cnf/cnf.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" @@ -306,6 +307,7 @@ static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -520,7 +522,7 @@ extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -545,7 +547,7 @@ void Abc_FrameReplaceCex( Abc_Frame_t * pAbc, Abc_Cex_t ** ppCex ) Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -623,7 +625,7 @@ Vec_Int_t * Abc_FrameDeriveStatusArray( Vec_Ptr_t * vCexes ) Vec_PtrForEachEntry( Abc_Cex_t *, vCexes, pCex, i ) if ( pCex != NULL ) Vec_IntWriteEntry( vStatuses, i, 0 ); // set this output as SAT - return vStatuses; + return vStatuses; } /**Function************************************************************* @@ -951,6 +953,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "match", Abc_CommandMatch, 0 ); Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -966,8 +969,8 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "constr", Abc_CommandConstr, 0 ); Cmd_CommandAdd( pAbc, "Verification", "unfold", Abc_CommandUnfold, 1 ); Cmd_CommandAdd( pAbc, "Verification", "fold", Abc_CommandFold, 1 ); - Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong - Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong + Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong + Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong Cmd_CommandAdd( pAbc, "Verification", "bm", Abc_CommandBm, 1 ); Cmd_CommandAdd( pAbc, "Verification", "bm2", Abc_CommandBm2, 1 ); Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); @@ -2717,8 +2720,8 @@ int Abc_CommandPrintStatus( Abc_Frame_t * pAbc, int argc, char ** argv ) { if ( fShort ) { - printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).", - Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1), + printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).", + Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1), Vec_IntCountEntry(pAbc->vStatuses, -1), Vec_IntSize(pAbc->vStatuses) ); } else @@ -5296,7 +5299,7 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( Vec_IntSize(pAbc->vIndFlops) != Abc_NtkLatchNum(pNtk) ) { - Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n", + Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n", Vec_IntSize(pAbc->vIndFlops), Abc_NtkLatchNum(pNtk) ); return 0; } @@ -6380,7 +6383,7 @@ int Abc_CommandTestRPO(Abc_Frame_t * pAbc, int argc, char ** argv) { goto usage; } } - if (argc != globalUtilOptind + 1) + if (argc != globalUtilOptind + 1) { Abc_Print(1, "Input file is not given.\n"); goto usage; @@ -12007,7 +12010,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) } */ // if ( pNtk ) -// Abc_NtkMakeLegit( pNtk ); +// Abc_NtkMakeLegit( pNtk ); { // extern void Ifd_ManDsdTest(); // Ifd_ManDsdTest(); @@ -14270,7 +14273,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -14311,7 +14314,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -14390,7 +14393,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -15765,7 +15768,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv ) } nGatesMin = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nGatesMin < 0 ) + if ( nGatesMin < 0 ) goto usage; break; case 'a': @@ -16468,7 +16471,7 @@ usage: SeeAlso [] ***********************************************************************/ -#if 0 +#if 0 int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) { char Buffer[100]; @@ -16839,7 +16842,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'N': @@ -17213,7 +17216,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } } - + // complain if truth tables are requested but the cut size is too large if ( pPars->fTruth && pPars->nLutSize > IF_MAX_FUNC_LUTSIZE ) { @@ -18120,7 +18123,7 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_LatchSetInit0( pObj ); else if ( pInitStr[i] == '1' ) Abc_LatchSetInit1( pObj ); - else + else Abc_LatchSetInitDc( pObj ); return 0; } @@ -18302,7 +18305,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fUseCex ) { - char * pInit; + char * pInit; Abc_Cex_t * pTemp; int k, nFlopsX = 0; if ( pAbc->pCex == NULL ) @@ -18317,7 +18320,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv ) // compare this value if ( Abc_NtkPiNum(pNtk) + nFlopsX != pAbc->pCex->nPis ) { - Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n", + Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n", Abc_NtkPiNum(pNtk), Abc_NtkLatchNum(pNtk), pAbc->pCex->nPis ); return 1; } @@ -20701,7 +20704,7 @@ int Abc_CommandSim3( Abc_Frame_t * pAbc, int argc, char ** argv ) extern int Abc_NtkDarSeqSim3( Abc_Ntk_t * pNtk, Ssw_RarPars_t * pPars ); Ssw_RarPars_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc); - Vec_Ptr_t * vSeqModelVec; + Vec_Ptr_t * vSeqModelVec; int c; Ssw_RarSetDefaultParams( pPars ); Extra_UtilGetoptReset(); @@ -23157,6 +23160,144 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandXSat( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + abctime clk; + int c; + int fVerbose = 0; + int nConfLimit = 0; + int nInsLimit = 0; + int nLearnedStart = 0; + int nLearnedDelta = 0; + int nLearnedPerce = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CILDEhv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + nConfLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nConfLimit < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + nInsLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nInsLimit < 0 ) + goto usage; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedStart = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedStart < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedDelta = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedDelta < 0 ) + goto usage; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedPerce = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedPerce < 0 ) + goto usage; + break; + case 'h': + goto usage; + case 'v': + fVerbose ^= 1; + break; + + default: + goto usage; + } + } + + if ( argc == globalUtilOptind + 1 ) + { + char * pFileName = argv[globalUtilOptind]; + xSAT_Solver_t * p; + int status; + + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + return 0; + } + xSAT_SolverParseDimacs( pFile, &p ); + + clk = Abc_Clock(); + status = xSAT_SolverSolve( p ); + fclose( pFile ); + + xSAT_SolverPrintStats( p ); + if ( status == 0 ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == 1 ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + xSAT_SolverDestroy( p ); + return 0; + } + +usage: + Abc_Print( -2, "usage: xsat [-CILDE num] [-hv].cnf\n" ); + Abc_Print( -2, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" ); + Abc_Print( -2, "\t derives CNF from the current network and leaves it unchanged\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit ); + Abc_Print( -2, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit ); + Abc_Print( -2, "\t-L num : starting value for learned clause removal [default = %d]\n", nLearnedStart ); + Abc_Print( -2, "\t-D num : delta value for learned clause removal [default = %d]\n", nLearnedDelta ); + Abc_Print( -2, "\t-E num : ratio percentage for learned clause removal [default = %d]\n", nLearnedPerce ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] @@ -24155,7 +24296,7 @@ int Abc_CommandBmc3( Abc_Frame_t * pAbc, int argc, char ** argv ) } } vStatuses = Abc_FrameDeriveStatusArray( vSeqModelVec ); - Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); + Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); if ( vSeqModelVec ) Abc_FrameReplaceCexVec( pAbc, &vSeqModelVec ); else @@ -25483,47 +25624,47 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ +{ FILE * pOut, * pErr; Abc_Ntk_t *pNtk, *pNtk1, *pNtk2; - int fDelete1, fDelete2; + int fDelete1, fDelete2; Abc_Obj_t * pObj; char ** pArgvNew; - int c, nArgcNew, i; + int c, nArgcNew, i; extern void saucyGateWay( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodePo, FILE * gFile, int fBooleanMatching, int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - + pErr = Abc_FrameReadErr(pAbc); + Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) { switch ( c ) { case 'h': - goto usage; + goto usage; default: Abc_Print( -2, "Unknown switch.\n"); goto usage; } } - + pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew , &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) return 1; - - if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) || + + if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) || (unsigned)Abc_NtkPoNum(pNtk1) != (unsigned)Abc_NtkPoNum(pNtk2) ) { Abc_Print( -2, "Mismatch in the number of inputs or outputs\n"); @@ -25532,7 +25673,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); return 1; } - + Abc_NtkPermute(pNtk2, 1, 1, 0, NULL ); Abc_NtkShortNames(pNtk2); @@ -25562,7 +25703,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) saucyGateWay( pNtk1, NULL, NULL, 1, 0, 0, 0, 0, 0); if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); - if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); + if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); return 0; usage: @@ -25570,8 +25711,8 @@ usage: Abc_Print( -2, "\t performs Boolean matching (PP-equivalence)\n" ); Abc_Print( -2, "\t for equivalent circuits, permutation that maps one circuit\n" ); Abc_Print( -2, "\t to another is printed to standard output (PIs and POs of the\n" ); - Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" ); - Abc_Print( -2, "\t second network have prefix \"N2:\")\n" ); + Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" ); + Abc_Print( -2, "\t second network have prefix \"N2:\")\n" ); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\tfile1 : the file with the first network\n"); Abc_Print( -2, "\tfile2 : the file with the second network\n"); @@ -25593,14 +25734,14 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ +{ Abc_Ntk_t *pNtk; char * outputName = NULL; FILE * gFile = NULL; @@ -25629,20 +25770,20 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) outputName = argv[globalUtilOptind]; if ( !strcmp(argv[globalUtilOptind], "all") ) fOutputsOneAtTime ^= 1; - globalUtilOptind++; + globalUtilOptind++; break; case 'F': if ( globalUtilOptind >= argc ) { Abc_Print( -1, "Command line switch \"-F\" should be followed by a file name.\n" ); goto usage; - } + } if ( (gFile = fopen( argv[globalUtilOptind], "w" )) == NULL ) { - Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] ); + Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] ); return 1; } - globalUtilOptind++; + globalUtilOptind++; break; case 'i': fFixOutputs ^= 1; @@ -25665,9 +25806,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -2, "Unknown switch.\n"); goto usage; } - } - - pNtk = Abc_FrameReadNtk(pAbc); + } + + pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk == NULL ) { @@ -25690,21 +25831,21 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_NtkForEachPo( pNtk, pNodePo, i ) { printf("Ouput %s\n\n", Abc_ObjName(pNodePo)); saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); - printf("----------------------------------------\n"); + printf("----------------------------------------\n"); } fclose(hadi); } else if (outputName != NULL) { int i; - Abc_Obj_t * pNodePo; + Abc_Obj_t * pNodePo; Abc_NtkForEachPo( pNtk, pNodePo, i ) { if (!strcmp(Abc_ObjName(pNodePo), outputName)) { saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); Abc_NtkDelete( pNtk ); return 0; - } + } } Abc_Print( -1, "Output not found\n" ); - return 1; + return 1; } else saucyGateWay( pNtk, NULL, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); @@ -25715,9 +25856,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: saucy3 [-O ] [-F ] [-iosqvh]\n\n" ); Abc_Print( -2, "\t computes functional symmetries of the netowrk\n" ); - Abc_Print( -2, "\t prints symmetry generators to the standard output\n" ); + Abc_Print( -2, "\t prints symmetry generators to the standard output\n" ); Abc_Print( -2, "\t-O : (optional) compute symmetries only for output given by name\n"); - Abc_Print( -2, "\t only inputs in the output cone are permuted\n"); + Abc_Print( -2, "\t only inputs in the output cone are permuted\n"); Abc_Print( -2, "\t (special case) name=all, compute symmetries for each\n" ); Abc_Print( -2, "\t output, but only one output at a time\n" ); Abc_Print( -2, "\t [default = compute symmetries by permuting all I/Os]\n" ); @@ -25726,8 +25867,8 @@ usage: Abc_Print( -2, "\t-o : permute just the outputs (fix the inputs) [default = no]\n"); Abc_Print( -2, "\t-s : only look for swaps of inputs [default = no]\n"); Abc_Print( -2, "\t-q : quiet (do not print symmetry generators) [default = no]\n"); - Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n"); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n"); + Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t \n" ); Abc_Print( -2, "\t This command was contributed by Hadi Katebi from U Michigan.\n" ); @@ -27055,7 +27196,7 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) pAig = Gia_ManReadMiniLut( FileName ); // else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) ) // Abc3_ReadShowHie( FileName, fSkipStrash ); - else + else pAig = Gia_AigerRead( FileName, fGiaSimple, fSkipStrash, 0 ); if ( pAig ) Abc_FrameUpdateGia( pAbc, pAig ); @@ -27466,8 +27607,8 @@ int Abc_CommandAbc9Get( Abc_Frame_t * pAbc, int argc, char ** argv ) Vec_FltFreeP( &pGia->vOutReqs ); pGia->DefInArrs = Abc_NtkReadDefaultArrivalWorst(pNtk); pGia->DefOutReqs = Abc_NtkReadDefaultRequiredWorst(pNtk); - pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) ); - pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) ); + pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) ); + pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) ); } Abc_FrameUpdateGia( pAbc, pGia ); return 0; @@ -27626,7 +27767,7 @@ usage: Synopsis [Compares to versions of the design and finds the best.] Description [] - + SideEffects [] SeeAlso [] @@ -27637,11 +27778,11 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int int nCurLuts, nCurEdges, nCurLevels; Gia_ManLutParams( p, &nCurLuts, &nCurEdges, &nCurLevels ); if ( pBest == NULL || - Gia_ManPiNum(pBest) != Gia_ManPiNum(p) || - Gia_ManPoNum(pBest) != Gia_ManPoNum(p) || + Gia_ManPiNum(pBest) != Gia_ManPiNum(p) || + Gia_ManPoNum(pBest) != Gia_ManPoNum(p) || Gia_ManRegNum(pBest) != Gia_ManRegNum(p) || strcmp(Gia_ManName(pBest), Gia_ManName(p)) || - (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) || + (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) || ( fArea && (*pnBestLuts > nCurLuts || (*pnBestLuts == nCurLuts && *pnBestLevels > nCurLevels))) ) { @@ -27659,7 +27800,7 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -27697,7 +27838,7 @@ int Abc_CommandAbc9Save( Abc_Frame_t * pAbc, int argc, char ** argv ) // save the design as best Gia_ManStopP( &pAbc->pGiaBest ); pAbc->pGiaBest = Gia_ManDupWithAttributes( pAbc->pGia ); - return 0; + return 0; usage: Abc_Print( -2, "usage: &save [-ah]\n" ); @@ -27712,7 +27853,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -30868,7 +31009,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv ) } nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nRelaxRatio < 0 ) + if ( nRelaxRatio < 0 ) goto usage; break; case 'a': @@ -30908,7 +31049,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "DSD manager has incompatible number of variables. Delay minimization is not performed.\n" ); fDelayMin = 0; } - } + } pTemp = Gia_ManAigSyn2( pAbc->pGia, fOldAlgo, fCoarsen, fCutMin, nRelaxRatio, fDelayMin, fVerbose, fVeryVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; @@ -31005,7 +31146,7 @@ int Abc_CommandAbc9Synch2( Abc_Frame_t * pAbc, int argc, char ** argv ) } nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nRelaxRatio < 0 ) + if ( nRelaxRatio < 0 ) goto usage; break; case 'f': @@ -32857,7 +32998,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) pAbc->Status = Cec_ManVerify( pTemp, pPars ); ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb ); Gia_ManStop( pTemp ); - } + } Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); return 0; } @@ -33749,7 +33890,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'T': @@ -34867,7 +35008,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -34878,7 +35019,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -34889,7 +35030,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35099,7 +35240,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35110,7 +35251,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35121,7 +35262,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35303,7 +35444,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35314,7 +35455,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35325,7 +35466,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35518,7 +35659,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35529,7 +35670,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35540,7 +35681,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35886,7 +36027,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) { //Edg_ManAssignEdgeNew( pAbc->pGia, nEdges, fVerbose ); Seg_ManComputeDelay( pAbc->pGia, DelayMax, nFanouts, nEdges==2, fVerbose ); - return 0; + return 0; } if ( pAbc->pGia->pManTime && fReverse ) { @@ -35895,7 +36036,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( fReverse ) DelayMax = Gia_ManComputeEdgeDelay2( pAbc->pGia ); - else + else DelayMax = Gia_ManComputeEdgeDelay( pAbc->pGia, nEdges == 2 ); //printf( "The number of edges = %d. Delay = %d.\n", Gia_ManEvalEdgeCount(pAbc->pGia), DelayMax ); return 0; @@ -38307,7 +38448,7 @@ int Abc_CommandAbc9MultiProve( Abc_Frame_t * pAbc, int argc, char ** argv ) } pAbc->Status = Gia_ManMultiProve( pAbc->pGia, pPars ); vStatuses = Abc_FrameDeriveStatusArray( pAbc->pGia->vSeqModelVec ); - Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); + Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); Abc_FrameReplaceCexVec( pAbc, &pAbc->pGia->vSeqModelVec ); return 0; @@ -38454,7 +38595,7 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv ) Bmc_AndPar_t Pars, * pPars = &Pars; memset( pPars, 0, sizeof(Bmc_AndPar_t) ); pPars->nStart = 0; // starting timeframe - pPars->nFramesMax = 0; // maximum number of timeframes + pPars->nFramesMax = 0; // maximum number of timeframes pPars->nFramesAdd = 50; // the number of additional frames pPars->nConfLimit = 0; // maximum number of conflicts at a node pPars->nTimeOut = 0; // timeout in seconds @@ -38463,9 +38604,9 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->fDumpFrames = 0; // dump unrolled timeframes pPars->fUseSynth = 0; // use synthesis pPars->fUseOldCnf = 0; // use old CNF construction - pPars->fVerbose = 0; // verbose - pPars->fVeryVerbose = 0; // very verbose - pPars->fNotVerbose = 0; // skip line-by-line print-out + pPars->fVerbose = 0; // verbose + pPars->fVeryVerbose = 0; // very verbose + pPars->fNotVerbose = 0; // skip line-by-line print-out pPars->iFrame = 0; // explored up to this frame pPars->nFailOuts = 0; // the number of failed outputs pPars->nDropOuts = 0; // the number of dropped outputs @@ -39166,7 +39307,7 @@ usage: Abc_Print( -2, "\t ((a&b)^p) complement at the output\n"); Abc_Print( -2, "\t (((a^p)&(b^q))^r) complement at the inputs and at the output\n"); Abc_Print( -2, "\t (a?(b?~s:r):(b?q:p)) functionally observable fault at the output\n"); - Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n"); + Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n"); return 1; } @@ -40039,7 +40180,7 @@ int Abc_CommandAbc9Demiter( Abc_Frame_t * pAbc, int argc, char ** argv ) { char pName0[1000] = "miter_part0.aig"; char pName1[1000] = "miter_part1.aig"; - Gia_Man_t * pPart1, * pPart2; + Gia_Man_t * pPart1, * pPart2; if ( Gia_ManPoNum(pAbc->pGia) % 2 != 0 ) { Abc_Print( -1, "Abc_CommandAbc9Demiter(): Does not look like a dual-output miter.\n" ); @@ -40481,7 +40622,7 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManDemiterDual( pDual, &pGia0, &pGia1 ); Gia_ManStop( pDual ); pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); - } + } Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb ); Gia_ManStop( pGia0 ); Gia_ManStop( pGia1 ); @@ -40687,7 +40828,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -40701,7 +40842,7 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv ) Sfm_ParSetDefault( pPars ); pPars->nTfoLevMax = 5; pPars->nDepthMax = 100; - pPars->nWinSizeMax = 2000; + pPars->nWinSizeMax = 2000; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCNdaebvwh" ) ) != EOF ) { @@ -40852,7 +40993,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -41324,7 +41465,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -41385,7 +41526,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] diff --git a/src/sat/xsat/license b/src/sat/xsat/license new file mode 100644 index 00000000..a6389ab1 --- /dev/null +++ b/src/sat/xsat/license @@ -0,0 +1,39 @@ +xSAT - Copyright (c) 2016, Bruno Schmitt - UC Berkeley / UFRGS (boschmitt@inf.ufrgs.br) + +xSAT is based on Glucose v3(see Glucose copyrights below) and ABC C version of +MiniSat (bsat) developed by Niklas Sorensson and modified by Alan Mishchenko. +Permissions and copyrights of xSAT are exactly the same as Glucose v3/Minisat. +(see below). + +--------------- + +Glucose -- Copyright (c) 2013, Gilles Audemard, Laurent Simon + CRIL - Univ. Artois, France + LRI - Univ. Paris Sud, France + +Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions +and copyrights of Glucose are exactly the same as Minisat on which it is based +on. (see below). + +--------------- + +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*******************************************************************************/ diff --git a/src/sat/xsat/module.make b/src/sat/xsat/module.make new file mode 100644 index 00000000..1d7352e2 --- /dev/null +++ b/src/sat/xsat/module.make @@ -0,0 +1,3 @@ +SRC += src/sat/xsat/xsatSolver.c \ + src/sat/xsat/xsatSolverAPI.c \ + src/sat/xsat/xsatCnfReader.c diff --git a/src/sat/xsat/xsat.h b/src/sat/xsat/xsat.h new file mode 100644 index 00000000..b2962d91 --- /dev/null +++ b/src/sat/xsat/xsat.h @@ -0,0 +1,59 @@ +/**CFile**************************************************************** + + FileName [xsat.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [External definitions of the solver.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xSAT_h +#define ABC__sat__xSAT__xSAT_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" +#include "misc/vec/vecInt.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +struct xSAT_Solver_t_; +typedef struct xSAT_Solver_t_ xSAT_Solver_t; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/*=== xsatCnfReader.c ================================================*/ +extern int xSAT_SolverParseDimacs( FILE *, xSAT_Solver_t ** ); + +/*=== xsatSolverAPI.c ================================================*/ +extern xSAT_Solver_t * xSAT_SolverCreate(); +extern void xSAT_SolverDestroy( xSAT_Solver_t * ); + +extern int xSAT_SolverAddClause( xSAT_Solver_t *, Vec_Int_t * ); +extern int xSAT_SolverSimplify( xSAT_Solver_t * ); +extern int xSAT_SolverSolve( xSAT_Solver_t * ); + +extern void xSAT_SolverPrintStats( xSAT_Solver_t * ); + +ABC_NAMESPACE_HEADER_END + +#endif +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h new file mode 100644 index 00000000..37951684 --- /dev/null +++ b/src/sat/xsat/xsatBQueue.h @@ -0,0 +1,189 @@ +/**CFile**************************************************************** + + FileName [xsatBQueue.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Bounded queue implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatBQueue_h +#define ABC__sat__xSAT__xsatBQueue_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_BQueue_t_ xSAT_BQueue_t; +struct xSAT_BQueue_t_ +{ + int nSize; + int nCap; + int iFirst; + int iEmpty; + uint64_t nSum; + uint32_t * pData; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_BQueue_t * xSAT_BQueueNew( int nCap ) +{ + xSAT_BQueue_t * p = ABC_CALLOC( xSAT_BQueue_t, 1 ); + p->nCap = nCap; + p->pData = ABC_CALLOC( uint32_t, nCap ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_BQueueFree( xSAT_BQueue_t * p ) +{ + ABC_FREE( p->pData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, uint32_t Value ) +{ + if ( p->nSize == p->nCap ) + { + assert(p->iFirst == p->iEmpty); + p->nSum -= p->pData[p->iFirst]; + p->iFirst = ( p->iFirst + 1 ) % p->nCap; + } + else + p->nSize++; + + p->nSum += Value; + p->pData[p->iEmpty] = Value; + if ( ( ++p->iEmpty ) == p->nCap ) + { + p->iEmpty = 0; + p->iFirst = 0; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) +{ + assert( p->nSize >= 1 ); + int RetValue = p->pData[p->iFirst]; + p->nSum -= RetValue; + p->iFirst = ( p->iFirst + 1 ) % p->nCap; + p->nSize--; + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_BQueueAvg( xSAT_BQueue_t * p ) +{ + return ( uint32_t )( p->nSum / ( ( uint64_t ) p->nSize ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_BQueueIsValid( xSAT_BQueue_t * p ) +{ + return ( p->nCap == p->nSize ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_BQueueClean( xSAT_BQueue_t * p ) +{ + p->iFirst = 0; + p->iEmpty = 0; + p->nSize = 0; + p->nSum = 0; +} + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/xsat/xsatClause.h b/src/sat/xsat/xsatClause.h new file mode 100644 index 00000000..39f0a0c8 --- /dev/null +++ b/src/sat/xsat/xsatClause.h @@ -0,0 +1,109 @@ +/**CFile**************************************************************** + + FileName [xsatClause.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Clause data type definition.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatClause_h +#define ABC__sat__xSAT__xsatClause_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_Clause_t_ xSAT_Clause_t; +struct xSAT_Clause_t_ +{ + unsigned fLearnt : 1; + unsigned fMark : 1; + unsigned fReallocd : 1; + unsigned fCanBeDel : 1; + unsigned nLBD : 28; + unsigned nSize; + union { + int Lit; + unsigned Act; + } pData[0]; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int xSAT_ClauseCompare( const void * p1, const void * p2 ) +{ + xSAT_Clause_t * pC1 = ( xSAT_Clause_t * ) p1; + xSAT_Clause_t * pC2 = ( xSAT_Clause_t * ) p2; + + if ( pC1->nSize > 2 && pC2->nSize == 2 ) + return 1; + if ( pC1->nSize == 2 && pC2->nSize > 2 ) + return 0; + if ( pC1->nSize == 2 && pC2->nSize == 2 ) + return 0; + + if ( pC1->nLBD > pC2->nLBD ) + return 1; + if ( pC1->nLBD < pC2->nLBD ) + return 0; + + return pC1->pData[pC1->nSize].Act < pC2->pData[pC2->nSize].Act; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_ClausePrint( xSAT_Clause_t * pCla ) +{ + int i; + + printf("{ "); + for ( i = 0; i < pCla->nSize; i++ ) + printf("%d ", pCla->pData[i].Lit ); + printf("}\n"); +} + +ABC_NAMESPACE_HEADER_END + +#endif +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatCnfReader.c b/src/sat/xsat/xsatCnfReader.c new file mode 100644 index 00000000..d23e8a0a --- /dev/null +++ b/src/sat/xsat/xsatCnfReader.c @@ -0,0 +1,236 @@ +/**CFile**************************************************************** + + FileName [xsatCnfReader.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [CNF DIMACS file format parser.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include + +#include "misc/util/abc_global.h" +#include "misc/vec/vecInt.h" + +#include "xsatSolver.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Read the file into the internal buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * xSAT_FileRead( FILE * pFile ) +{ + int nFileSize; + char * pBuffer; + int RetValue; + // get the file size, in bytes + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + // move the file current reading position to the beginning + rewind( pFile ); + // load the contents of the file into memory + pBuffer = ABC_ALLOC( char, nFileSize + 3 ); + RetValue = fread( pBuffer, nFileSize, 1, pFile ); + // terminate the string with '\0' + pBuffer[ nFileSize + 0] = '\n'; + pBuffer[ nFileSize + 1] = '\0'; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void skipLine( char ** pIn ) +{ + while ( 1 ) + { + if (**pIn == 0) + return; + if (**pIn == '\n') + { + (*pIn)++; + return; + } + (*pIn)++; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int xSAT_ReadInt( char ** pIn ) +{ + int val = 0; + int neg = 0; + + for(; isspace(**pIn); (*pIn)++); + if ( **pIn == '-' ) + neg = 1, + (*pIn)++; + else if ( **pIn == '+' ) + (*pIn)++; + if ( !isdigit(**pIn) ) + fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", **pIn), + exit(1); + while ( isdigit(**pIn) ) + val = val*10 + (**pIn - '0'), + (*pIn)++; + return neg ? -val : val; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_ReadClause( char ** pIn, xSAT_Solver_t * p, Vec_Int_t * vLits ) +{ + int token, var, sign; + + Vec_IntClear( vLits ); + while ( 1 ) + { + token = xSAT_ReadInt( pIn ); + if ( token == 0 ) + break; + var = abs(token) - 1; + sign = (token > 0); + Vec_IntPush( vLits, xSAT_Var2Lit( var, !sign ) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int xSAT_ParseDimacs( char * pText, xSAT_Solver_t ** pS ) +{ + xSAT_Solver_t * p = NULL; + Vec_Int_t * vLits = NULL; + char * pIn = pText; + int nVars, nClas; + while ( 1 ) + { + for(; isspace(*pIn); pIn++); + if ( *pIn == 0 ) + break; + else if ( *pIn == 'c' ) + skipLine( &pIn ); + else if ( *pIn == 'p' ) + { + pIn++; + for(; isspace(*pIn); pIn++); + for(; !isspace(*pIn); pIn++); + + nVars = xSAT_ReadInt( &pIn ); + nClas = xSAT_ReadInt( &pIn ); + skipLine( &pIn ); + + /* start the solver */ + p = xSAT_SolverCreate(); + /* allocate the vector */ + vLits = Vec_IntAlloc( nVars ); + } + else + { + if ( p == NULL ) + { + printf( "There is no parameter line.\n" ); + exit(1); + } + xSAT_ReadClause( &pIn, p, vLits ); + if ( !xSAT_SolverAddClause( p, vLits ) ) + { + Vec_IntPrint(vLits); + return 0; + } + } + } + Vec_IntFree( vLits ); + *pS = p; + return xSAT_SolverSimplify( p ); +} + +/**Function************************************************************* + + Synopsis [Starts the solver and reads the DIMAC file.] + + Description [Returns FALSE upon immediate conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverParseDimacs( FILE * pFile, xSAT_Solver_t ** p ) +{ + char * pText; + int Value; + pText = xSAT_FileRead( pFile ); + Value = xSAT_ParseDimacs( pText, p ); + ABC_FREE( pText ); + return Value; +} + +ABC_NAMESPACE_IMPL_END + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h new file mode 100644 index 00000000..2e873e59 --- /dev/null +++ b/src/sat/xsat/xsatHeap.h @@ -0,0 +1,330 @@ +/**CFile**************************************************************** + + FileName [xsatHeap.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Heap implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatHeap_h +#define ABC__sat__xSAT__xsatHeap_h + +#include "misc/util/abc_global.h" +#include "misc/vec/vecInt.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_Heap_t_ xSAT_Heap_t; +struct xSAT_Heap_t_ +{ + Vec_Int_t * vActivity; + Vec_Int_t * vIndices; + Vec_Int_t * vHeap; +}; + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +inline int xSAT_HeapSize( xSAT_Heap_t * h ) +{ + return Vec_IntSize( h->vHeap ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) +{ + return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 ); +} + +static inline int Left ( int i ) { return 2 * i + 1; } +static inline int Right ( int i ) { return ( i + 1 ) * 2; } +static inline int Parent( int i ) { return ( i - 1 ) >> 1; } +static inline int Compare( xSAT_Heap_t * p, int x, int y ) +{ + return ( unsigned )Vec_IntEntry( p->vActivity, x ) > ( unsigned )Vec_IntEntry( p->vActivity, y ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapPercolateUp( xSAT_Heap_t * h, int i ) +{ + int x = Vec_IntEntry( h->vHeap, i ); + int p = Parent( i ); + + while ( i != 0 && Compare( h, x, Vec_IntEntry( h->vHeap, p ) ) ) + { + Vec_IntWriteEntry( h->vHeap, i, Vec_IntEntry( h->vHeap, p ) ); + Vec_IntWriteEntry( h->vIndices, Vec_IntEntry( h->vHeap, p ), i ); + i = p; + p = Parent(p); + } + Vec_IntWriteEntry( h->vHeap, i, x ); + Vec_IntWriteEntry( h->vIndices, x, i ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapPercolateDown( xSAT_Heap_t * h, int i ) +{ + int x = Vec_IntEntry( h->vHeap, i ); + + while ( Left( i ) < Vec_IntSize( h->vHeap ) ) + { + int child = Right( i ) < Vec_IntSize( h->vHeap ) && + Compare( h, Vec_IntEntry( h->vHeap, Right( i ) ), Vec_IntEntry( h->vHeap, Left( i ) ) ) ? + Right( i ) : Left( i ); + + if ( !Compare( h, Vec_IntEntry( h->vHeap, child ), x ) ) + break; + + Vec_IntWriteEntry( h->vHeap, i, Vec_IntEntry( h->vHeap, child ) ); + Vec_IntWriteEntry( h->vIndices, Vec_IntEntry( h->vHeap, i ), i ); + i = child; + } + Vec_IntWriteEntry( h->vHeap, i, x ); + Vec_IntWriteEntry( h->vIndices, x, i ); +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_Heap_t * xSAT_HeapAlloc( Vec_Int_t * vActivity ) +{ + xSAT_Heap_t * p = ABC_ALLOC( xSAT_Heap_t, 1 ); + p->vActivity = vActivity; + p->vIndices = Vec_IntAlloc( 0 ); + p->vHeap = Vec_IntAlloc( 0 ); + + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapFree( xSAT_Heap_t * p ) +{ + Vec_IntFree( p->vIndices ); + Vec_IntFree( p->vHeap ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapIncrease( xSAT_Heap_t * h, int e ) +{ + assert( xSAT_HeapInHeap( h, e ) ); + xSAT_HeapPercolateDown( h, Vec_IntEntry( h->vIndices, e ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapDecrease( xSAT_Heap_t * p, int e ) +{ + assert( xSAT_HeapInHeap( p, e ) ); + xSAT_HeapPercolateUp( p , Vec_IntEntry( p->vIndices, e ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapInsert( xSAT_Heap_t * p, int n ) +{ + Vec_IntFillExtra( p->vIndices, n + 1, -1); + assert( !xSAT_HeapInHeap( p, n ) ); + + Vec_IntWriteEntry( p->vIndices, n, Vec_IntSize( p->vHeap ) ); + Vec_IntPush( p->vHeap, n ); + xSAT_HeapPercolateUp( p, Vec_IntEntry( p->vIndices, n ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapUpdate( xSAT_Heap_t * p, int i ) +{ + if ( !xSAT_HeapInHeap( p, i ) ) + xSAT_HeapInsert( p, i ); + else + { + xSAT_HeapPercolateUp( p, Vec_IntEntry( p->vIndices, i ) ); + xSAT_HeapPercolateDown( p, Vec_IntEntry( p->vIndices, i ) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapBuild( xSAT_Heap_t * p, Vec_Int_t * Vars ) +{ + int i, Var; + + Vec_IntForEachEntry( p->vHeap, Var, i ) + Vec_IntWriteEntry( p->vIndices, Var, -1 ); + Vec_IntClear( p->vHeap ); + + Vec_IntForEachEntry( Vars, Var, i ) + { + Vec_IntWriteEntry( p->vIndices, Var, i ); + Vec_IntPush( p->vHeap, Var ); + } + + for ( ( i = Vec_IntSize( p->vHeap ) / 2 - 1 ); i >= 0; i-- ) + xSAT_HeapPercolateDown( p, i ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_HeapClear( xSAT_Heap_t * p ) +{ + Vec_IntFill( p->vIndices, Vec_IntSize( p->vIndices ), -1 ); + Vec_IntClear( p->vHeap ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_HeapRemoveMin( xSAT_Heap_t * p ) +{ + int x = Vec_IntEntry( p->vHeap, 0 ); + Vec_IntWriteEntry( p->vHeap, 0, Vec_IntEntryLast( p->vHeap ) ); + Vec_IntWriteEntry( p->vIndices, Vec_IntEntry( p->vHeap, 0), 0 ); + Vec_IntWriteEntry( p->vIndices, x, -1 ); + Vec_IntPop( p->vHeap ); + if ( Vec_IntSize( p->vHeap ) > 1 ) + xSAT_HeapPercolateDown( p, 0 ); + return x; +} + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/xsat/xsatMemory.h b/src/sat/xsat/xsatMemory.h new file mode 100644 index 00000000..3a961b97 --- /dev/null +++ b/src/sat/xsat/xsatMemory.h @@ -0,0 +1,225 @@ +/**CFile**************************************************************** + + FileName [xsatMemory.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Memory management implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatMemory_h +#define ABC__sat__xSAT__xsatMemory_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +#include "xsatClause.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_Mem_t_ xSAT_Mem_t; +struct xSAT_Mem_t_ +{ + uint32_t nSize; + uint32_t nCap; + uint32_t nWasted; + uint32_t * pData; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_Clause_t * xSAT_MemClauseHand( xSAT_Mem_t * p, int h ) +{ + return h != UINT32_MAX ? ( xSAT_Clause_t * )( p->pData + h ) : NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_MemGrow( xSAT_Mem_t * p, uint32_t nCap ) +{ + if ( p->nCap >= nCap ) + return; + + uint32_t nPrevCap = p->nCap; + while (p->nCap < nCap) + { + uint32_t delta = ((p->nCap >> 1) + (p->nCap >> 3) + 2) & ~1; + p->nCap += delta; + assert(p->nCap >= nPrevCap); + } + + assert(p->nCap > 0); + p->pData = ABC_REALLOC(uint32_t, p->pData, p->nCap); +} + +/**Function************************************************************* + + Synopsis [Allocating vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_Mem_t * xSAT_MemAlloc( int nCap ) +{ + xSAT_Mem_t * p; + p = ABC_CALLOC( xSAT_Mem_t, 1 ); + if (nCap <= 0) + nCap = 1024*1024; + + xSAT_MemGrow(p, nCap); + return p; +} + +/**Function************************************************************* + + Synopsis [Resetting vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_MemRestart( xSAT_Mem_t * p ) +{ + p->nSize = 0; + p->nWasted = 0; +} + +/**Function************************************************************* + + Synopsis [Freeing vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_MemFree( xSAT_Mem_t * p ) +{ + ABC_FREE( p->pData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Creates new clause.] + + Description [The resulting clause is fully initialized.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) +{ + assert(nSize > 0); + xSAT_MemGrow(p, p->nSize + nSize); + + uint32_t nPrevSize = p->nSize; + p->nSize += nSize; + assert(p->nSize > nPrevSize); + + return nPrevSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_MemCRef( xSAT_Mem_t * p, uint32_t * pC ) +{ + return ( uint32_t )( pC - &(p->pData[0]) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_MemCap( xSAT_Mem_t * p ) +{ + return p->nCap; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline uint32_t xSAT_MemWastedCap( xSAT_Mem_t * p ) +{ + return p->nWasted; +} + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c new file mode 100644 index 00000000..d6968a2d --- /dev/null +++ b/src/sat/xsat/xsatSolver.c @@ -0,0 +1,995 @@ +/**CFile**************************************************************** + + FileName [xsatSolver.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Solver internal functions implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include + +#include "xsatHeap.h" +#include "xsatSolver.h" +#include "xsatUtils.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_SolverDecide( xSAT_Solver_t* s ) +{ + int NextVar = VarUndef; + + while ( NextVar == VarUndef || Vec_StrEntry( s->vAssigns, NextVar ) != VarX ) + { + if ( xSAT_HeapSize( s->hOrder ) == 0 ) + { + NextVar = VarUndef; + break; + } + else + NextVar = xSAT_HeapRemoveMin( s->hOrder ); + } + return NextVar; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ) +{ + Vec_Int_t * vTemp = Vec_IntAlloc( Vec_StrSize( s->vAssigns ) ); + int Var; + + for ( Var = 0; Var < Vec_StrSize( s->vAssigns ); Var++ ) + if ( Vec_StrEntry( s->vAssigns, Var ) == VarX ) + Vec_IntPush( vTemp, Var ); + + xSAT_HeapBuild( s->hOrder, vTemp ); + Vec_IntFree( vTemp ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s ) +{ + unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); + + for ( int i = 0; i < Vec_IntSize( s->vActivity ); i++ ) + pActivity[i] >>= 19; + + s->nVarActInc >>= 19; + s->nVarActInc = Abc_MaxInt( s->nVarActInc, (1 << 5) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverVarActBump( xSAT_Solver_t* s, int Var ) +{ + unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); + + pActivity[Var] += s->nVarActInc; + if ( pActivity[Var] & 0x80000000 ) + xSAT_SolverVarActRescale( s ); + + if ( xSAT_HeapInHeap( s->hOrder, Var ) ) + xSAT_HeapDecrease( s->hOrder, Var ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverVarActDecay( xSAT_Solver_t * s ) +{ + s->nVarActInc += ( s->nVarActInc >> 4 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverClaActRescale( xSAT_Solver_t * s ) +{ + xSAT_Clause_t * pC; + int i, CRef; + + Vec_IntForEachEntry( s->vLearnts, CRef, i ) + { + pC = xSAT_SolverReadClause( s, (uint32_t) CRef ); + pC->pData[pC->nSize].Act >>= 14; + } + s->nClaActInc >>= 14; + s->nClaActInc = Abc_MaxInt( s->nClaActInc, ( 1 << 10 ) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverClaActBump( xSAT_Solver_t* s, xSAT_Clause_t * pCla ) +{ + pCla->pData[pCla->nSize].Act += s->nClaActInc; + if ( pCla->pData[pCla->nSize].Act & 0x80000000 ) + xSAT_SolverClaActRescale( s ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverClaActDecay( xSAT_Solver_t * s ) +{ + s->nClaActInc += ( s->nClaActInc >> 10 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) +{ + int nLBD = 0; + + s->nStamp++; + for ( int i = 0; i < pCla->nSize; i++ ) + { + int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pCla->pData[i].Lit ) ); + if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) + { + Vec_IntWriteEntry( s->vStamp, Level, (int) s->nStamp ); + nLBD++; + } + } + return nLBD; +} + +static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits ) +{ + int nLBD = 0; + + s->nStamp++; + for ( int i = 0; i < Vec_IntSize( vLits ); i++ ) + { + int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Vec_IntEntry( vLits, i ) ) ); + if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) + { + Vec_IntWriteEntry( s->vStamp, Level, (int) s->nStamp ); + nLBD++; + } + } + return nLBD; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +uint32_t xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) +{ + assert( Vec_IntSize( vLits ) > 1); + assert( fLearnt == 0 || fLearnt == 1 ); + + uint32_t CRef; + xSAT_Clause_t * pCla; + xSAT_Watcher_t w1; + xSAT_Watcher_t w2; + + uint32_t nWords = 3 + fLearnt + Vec_IntSize( vLits ); + CRef = xSAT_MemAppend( s->pMemory, nWords ); + pCla = xSAT_SolverReadClause( s, CRef ); + pCla->fLearnt = fLearnt; + pCla->fMark = 0; + pCla->fReallocd = 0; + pCla->fCanBeDel = fLearnt; + pCla->nSize = Vec_IntSize( vLits ); + memcpy( &( pCla->pData[0].Lit ), Vec_IntArray( vLits ), sizeof( int ) * Vec_IntSize( vLits ) ); + + if ( fLearnt ) + { + Vec_IntPush( s->vLearnts, CRef ); + pCla->nLBD = xSAT_SolverClaCalcLBD2( s, vLits ); + pCla->pData[pCla->nSize].Act = 0; + s->Stats.nLearntLits += Vec_IntSize( vLits ); + xSAT_SolverClaActBump(s, pCla); + } + else + { + Vec_IntPush( s->vClauses, CRef ); + s->Stats.nClauseLits += Vec_IntSize( vLits ); + } + + w1.CRef = CRef; + w2.CRef = CRef; + w1.Blocker = pCla->pData[1].Lit; + w2.Blocker = pCla->pData[0].Lit; + + if ( Vec_IntSize( vLits ) == 2 ) + { + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), w1 ); + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), w2 ); + } + else + { + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), w1 ); + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), w2 ); + } + return CRef; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, uint32_t Reason ) +{ + int Var = xSAT_Lit2Var( Lit ); + + Vec_StrWriteEntry( s->vAssigns, Var, xSAT_LitSign( Lit ) ); + Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) ); + Vec_IntWriteEntry( s->vReasons, Var, (int) Reason ); + Vec_IntPush( s->vTrail, Lit ); + + return true; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_SolverNewDecision( xSAT_Solver_t* s, int Lit ) +{ + assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX ); + s->Stats.nDecisions++; + Vec_IntPush( s->vTrailLim, Vec_IntSize( s->vTrail ) ); + xSAT_SolverEnqueue( s, Lit, CRefUndef ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverCancelUntil( xSAT_Solver_t * s, int Level ) +{ + if ( xSAT_SolverDecisionLevel( s ) <= Level ) + return; + + for ( int c = Vec_IntSize( s->vTrail ) - 1; c >= Vec_IntEntry( s->vTrailLim, Level ); c-- ) + { + int Var = xSAT_Lit2Var( Vec_IntEntry( s->vTrail, c ) ); + + Vec_StrWriteEntry( s->vAssigns, Var, VarX ); + Vec_IntWriteEntry( s->vReasons, Var, ( int ) CRefUndef ); + Vec_StrWriteEntry( s->vPolarity, Var, xSAT_LitSign( Vec_IntEntry( s->vTrail, c ) ) ); + + if ( !xSAT_HeapInHeap( s->hOrder, Var ) ) + xSAT_HeapInsert( s->hOrder, Var ); + } + + s->iQhead = Vec_IntEntry( s->vTrailLim, Level ); + Vec_IntShrink( s->vTrail, Vec_IntEntry( s->vTrailLim, Level ) ); + Vec_IntShrink( s->vTrailLim, Level ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) +{ + int top = Vec_IntSize( s->vTagged ); + + assert( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); + Vec_IntClear( s->vStack ); + Vec_IntPush( s->vStack, xSAT_Lit2Var( Lit ) ); + + while ( Vec_IntSize( s->vStack ) ) + { + int v = Vec_IntPop( s->vStack ); + assert( (uint32_t) Vec_IntEntry( s->vReasons, v ) != CRefUndef); + xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( uint32_t ) Vec_IntEntry( s->vReasons, v ) ); + int* Lits = &( c->pData[0].Lit ); + int i; + + if( c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) + { + assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) ); + ABC_SWAP( int, Lits[0], Lits[1] ); + } + + for (i = 1; i < c->nSize; i++) + { + int v = xSAT_Lit2Var( Lits[i] ); + if ( !Vec_StrEntry( s->vSeen, v ) && Vec_IntEntry( s->vLevels, v ) ) + { + if ( (uint32_t) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ((1 << (Vec_IntEntry( s->vLevels, v ) & 31)) & MinLevel)) + { + Vec_IntPush( s->vStack, v ); + Vec_IntPush( s->vTagged, Lits[i] ); + Vec_StrWriteEntry( s->vSeen, v, 1 ); + } + else + { + int Lit; + Vec_IntForEachEntryStart( s->vTagged, Lit, i, top ) + Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var(Lit), 0 ); + Vec_IntShrink( s->vTagged, top ); + return 0; + } + } + } + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) +{ + int * pLits = Vec_IntArray( vLits ); + int MinLevel = 0; + int i, j; + + for ( i = 1; i < Vec_IntSize( vLits ); i++ ) + { + int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pLits[i] ) ); + MinLevel |= 1 << ( Level & 31 ); + } + + /* Remove reduntant literals */ + Vec_IntAppend( s->vTagged, vLits ); + for ( i = j = 1; i < Vec_IntSize( vLits ); i++ ) + if ( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) + pLits[j++] = pLits[i]; + Vec_IntShrink( vLits, j ); + + /* Binary Resolution */ + if( Vec_IntSize( vLits ) <= 30 && xSAT_SolverClaCalcLBD2( s, vLits ) <= 6 ) + { + int Lit; + int FlaseLit = xSAT_NegLit( pLits[0] ); + + s->nStamp++; + Vec_IntForEachEntry( vLits, Lit, i ) + Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), s->nStamp ); + + xSAT_WatchList_t * ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); + xSAT_Watcher_t * begin = xSAT_WatchListArray( ws ); + xSAT_Watcher_t * end = begin + xSAT_WatchListSize( ws ); + xSAT_Watcher_t * pWatcher; + + int nb = 0; + for ( pWatcher = begin; pWatcher < end; pWatcher++ ) + { + int ImpLit = pWatcher->Blocker; + + if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) + { + nb++; + Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), s->nStamp - 1 ); + } + } + + int l = Vec_IntSize( vLits ) - 1; + if ( nb > 0 ) + { + for ( i = 1; i < Vec_IntSize( vLits ) - nb; i++ ) + if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != s->nStamp ) + { + int TempLit = pLits[l]; + pLits[l] = pLits[i]; + pLits[i] = TempLit; + i--; l--; + } + + Vec_IntShrink( vLits, Vec_IntSize( vLits ) - nb ); + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD ) +{ + int* trail = Vec_IntArray( s->vTrail ); + int Count = 0; + int p = LitUndef; + int Idx = Vec_IntSize( s->vTrail ) - 1; + int* Lits; + int i, j; + + Vec_IntPush( vLearnt, LitUndef ); + do + { + assert( ConfCRef != CRefUndef ); + xSAT_Clause_t * c = xSAT_SolverReadClause(s, ConfCRef); + Lits = &( c->pData[0].Lit ); + + if( p != LitUndef && c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(Lits[0])) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) + { + assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) ); + ABC_SWAP( int, Lits[0], Lits[1] ); + } + + if ( c->fLearnt ) + xSAT_SolverClaActBump( s, c ); + + if ( c->fLearnt && c->nLBD > 2 ) + { + unsigned int nblevels = xSAT_SolverClaCalcLBD(s, c); + if ( nblevels + 1 < c->nLBD ) + { + if (c->nLBD <= s->Config.nLBDFrozenClause) + c->fCanBeDel = 0; + c->nLBD = nblevels; + } + } + + for ( j = ( p == LitUndef ? 0 : 1 ); j < c->nSize; j++ ) + { + int Var = xSAT_Lit2Var( Lits[j] ); + + if ( Vec_StrEntry( s->vSeen, Var ) == 0 && Vec_IntEntry( s->vLevels, Var ) > 0 ) + { + Vec_StrWriteEntry( s->vSeen, Var, 1 ); + xSAT_SolverVarActBump( s, Var ); + if ( Vec_IntEntry( s->vLevels, Var ) >= xSAT_SolverDecisionLevel( s ) ) + { + Count++; + if ( Vec_IntEntry( s->vReasons, Var ) != CRefUndef && xSAT_SolverReadClause( s, Vec_IntEntry( s->vReasons, Var ) )->fLearnt ) + Vec_IntPush( s->vLastDLevel, Var ); + } + else + Vec_IntPush( vLearnt, Lits[j] ); + } + } + + while ( !Vec_StrEntry( s->vSeen, xSAT_Lit2Var( trail[Idx--] ) ) ); + + // Next clause to look at + p = trail[Idx+1]; + ConfCRef = (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); + Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( p ), 0 ); + Count--; + + } while ( Count > 0 ); + + Vec_IntArray( vLearnt )[0] = xSAT_NegLit( p ); + + xSAT_SolverClaMinimisation( s, vLearnt ); + + // Find the backtrack level + Lits = Vec_IntArray( vLearnt ); + if ( Vec_IntSize( vLearnt ) == 1 ) + *OutBtLevel = 0; + else + { + int iMax = 1; + int Max = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[1] ) ); + int Tmp; + + for (i = 2; i < Vec_IntSize( vLearnt ); i++) + if ( Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[i]) ) > Max) + { + Max = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[i]) ); + iMax = i; + } + + Tmp = Lits[1]; + Lits[1] = Lits[iMax]; + Lits[iMax] = Tmp; + *OutBtLevel = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[1] ) ); + } + + *nLBD = xSAT_SolverClaCalcLBD2( s, vLearnt ); + if ( Vec_IntSize( s->vLastDLevel ) > 0 ) + { + int Var; + Vec_IntForEachEntry( s->vLastDLevel, Var, i ) + { + if ( xSAT_SolverReadClause( s, Vec_IntEntry( s->vReasons, Var ) )->nLBD < *nLBD ) + xSAT_SolverVarActBump( s, Var ); + } + + Vec_IntClear( s->vLastDLevel ); + } + + int Lit; + Vec_IntForEachEntry( s->vTagged, Lit, i ) + Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 ); + Vec_IntClear( s->vTagged ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ) +{ + uint32_t hConfl = CRefUndef; + int * Lits; + int NegLit; + int nProp = 0; + + while ( s->iQhead < Vec_IntSize( s->vTrail ) ) + { + int p = Vec_IntEntry( s->vTrail, s->iQhead++ ); + + xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vBinWatches, p ); + xSAT_Watcher_t* begin = xSAT_WatchListArray( ws ); + xSAT_Watcher_t* end = begin + xSAT_WatchListSize( ws ); + xSAT_Watcher_t *i, *j; + + nProp++; + for (i = begin; i < end; i++) + { + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(i->Blocker)) == xSAT_LitSign(xSAT_NegLit(i->Blocker))) + { + return i->CRef; + } + else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(i->Blocker)) == VarX) + xSAT_SolverEnqueue(s, i->Blocker, i->CRef); + } + + + ws = xSAT_VecWatchListEntry( s->vWatches, p); + begin = xSAT_WatchListArray( ws ); + end = begin + xSAT_WatchListSize( ws ); + + for ( i = j = begin; i < end; ) + { + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( i->Blocker ) ) + { + *j++ = *i++; + continue; + } + + xSAT_Clause_t* c = xSAT_SolverReadClause( s, i->CRef ); + Lits = &( c->pData[0].Lit ); + + // Make sure the false literal is data[1]: + NegLit = xSAT_NegLit( p ); + if ( Lits[0] == NegLit ) + { + Lits[0] = Lits[1]; + Lits[1] = NegLit; + } + assert( Lits[1] == NegLit ); + + xSAT_Watcher_t w = { .CRef = i->CRef, + .Blocker = Lits[0] }; + // If 0th watch is true, then clause is already satisfied. + if ( Lits[0] != i->Blocker && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( Lits[0] ) ) + *j++ = w; + else + { + // Look for new watch: + int* stop = Lits + c->nSize; + int* k; + for ( k = Lits + 2; k < stop; k++ ) + { + if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( *k ) ) != !xSAT_LitSign( *k ) ) + { + Lits[1] = *k; + *k = NegLit; + xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( Lits[1] ) ), w ); + goto next; + } + } + + *j++ = w; + + // Clause is unit under assignment: + if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) + { + hConfl = i->CRef; + i++; + s->iQhead = Vec_IntSize( s->vTrail ); + // Copy the remaining watches: + while (i < end) + *j++ = *i++; + } + else + xSAT_SolverEnqueue( s, Lits[0], i->CRef ); + } + next: + i++; + } + + s->Stats.nInspects += j - xSAT_WatchListArray( ws ); + xSAT_WatchListShrink( ws, j - xSAT_WatchListArray( ws ) ); + } + + s->Stats.nPropagations += nProp; + s->nPropSimplify -= nProp; + + return hConfl; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverReduceDB( xSAT_Solver_t * s ) +{ + static abctime TimeTotal = 0; + abctime clk = Abc_Clock(); + int nLearnedOld = Vec_IntSize( s->vLearnts ); + int i, limit; + uint32_t CRef; + xSAT_Clause_t * c; + xSAT_Clause_t ** learnts_cls; + + learnts_cls = ABC_ALLOC( xSAT_Clause_t *, nLearnedOld ); + Vec_IntForEachEntry( s->vLearnts, CRef, i ) + learnts_cls[i] = xSAT_SolverReadClause(s, CRef); + + limit = nLearnedOld / 2; + + xSAT_UtilSort((void *) learnts_cls, nLearnedOld, + (int (*)( const void *, const void * )) xSAT_ClauseCompare); + + if ( learnts_cls[nLearnedOld / 2]->nLBD <= 3 ) + s->nRC2 += s->Config.nSpecialIncReduce; + if ( learnts_cls[nLearnedOld - 1]->nLBD <= 5 ) + s->nRC2 += s->Config.nSpecialIncReduce; + + Vec_IntClear( s->vLearnts ); + for ( i = 0; i < nLearnedOld; i++ ) + { + c = learnts_cls[i]; + uint32_t CRef = xSAT_MemCRef( s->pMemory, (uint32_t * ) c ); + assert(c->fMark == 0); + if ( c->fCanBeDel && c->nLBD > 2 && c->nSize > 2 && (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( c->pData[0].Lit ) ) != CRef && ( i < limit ) ) + { + c->fMark = 1; + s->Stats.nLearntLits -= c->nSize; + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( c->pData[0].Lit ) ), CRef ); + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( c->pData[1].Lit ) ), CRef ); + } + else + { + if (!c->fCanBeDel) + limit++; + c->fCanBeDel = 1; + Vec_IntPush( s->vLearnts, CRef ); + } + } + ABC_FREE( learnts_cls ); + + TimeTotal += Abc_Clock() - clk; + if ( s->Config.fVerbose ) + { + Abc_Print(1, "reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) ", + Vec_IntSize( s->vLearnts ), nLearnedOld, 100.0 * Vec_IntSize( s->vLearnts ) / nLearnedOld ); + Abc_PrintTime( 1, "Time", TimeTotal ); + } + xSAT_SolverGarbageCollect(s); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char xSAT_SolverSearch( xSAT_Solver_t * s ) +{ + ABC_INT64_T conflictC = 0; + + s->Stats.nStarts++; + for (;;) + { + uint32_t hConfl = xSAT_SolverPropagate( s ); + + if ( hConfl != CRefUndef ) + { + /* Conflict */ + int BacktrackLevel; + unsigned nLBD; + uint32_t CRef; + + s->Stats.nConflicts++; + conflictC++; + + if ( xSAT_SolverDecisionLevel( s ) == 0 ) + return LBoolFalse; + + xSAT_BQueuePush( s->bqTrail, Vec_IntSize( s->vTrail ) ); + if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * xSAT_BQueueAvg( s->bqTrail ) ) ) ) + xSAT_BQueueClean(s->bqLBD); + + Vec_IntClear( s->vLearntClause ); + xSAT_SolverAnalyze( s, hConfl, s->vLearntClause, &BacktrackLevel, &nLBD ); + + s->nSumLBD += nLBD; + xSAT_BQueuePush( s->bqLBD, nLBD ); + xSAT_SolverCancelUntil( s, BacktrackLevel ); + + CRef = Vec_IntSize( s->vLearntClause ) == 1 ? CRefUndef : xSAT_SolverClaNew( s, s->vLearntClause , 1 ); + xSAT_SolverEnqueue( s, Vec_IntEntry( s->vLearntClause , 0 ), CRef ); + + xSAT_SolverVarActDecay( s ); + xSAT_SolverClaActDecay( s ); + } + else + { + /* No conflict */ + int NextVar; + if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / s->Stats.nConflicts ) ) ) + { + xSAT_BQueueClean( s->bqLBD ); + xSAT_SolverCancelUntil( s, 0 ); + return LBoolUndef; + } + + // Simplify the set of problem clauses: + if ( xSAT_SolverDecisionLevel( s ) == 0 ) + xSAT_SolverSimplify( s ); + + // Reduce the set of learnt clauses: + if ( s->Stats.nConflicts >= s->nConfBeforeReduce ) + { + s->nRC1 = ( s->Stats.nConflicts / s->nRC2 ) + 1; + xSAT_SolverReduceDB(s); + s->nRC2 += s->Config.nIncReduce; + s->nConfBeforeReduce = s->nRC1 * s->nRC2; + } + + // New variable decision: + NextVar = xSAT_SolverDecide( s ); + + if ( NextVar == VarUndef ) + return LBoolTrue; + + xSAT_SolverNewDecision( s, xSAT_Var2Lit( NextVar, ( int ) Vec_StrEntry( s->vPolarity, NextVar ) ) ); + } + } + + return LBoolUndef; // cannot happen +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, uint32_t * pCRef ) +{ + xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef ); + if ( pOldCla->fReallocd ) + { + *pCRef = (uint32_t) pOldCla->nSize; + return; + } + + uint32_t nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize ); + xSAT_Clause_t * pNewCla = xSAT_MemClauseHand( pDest, nNewCRef ); + + memcpy( pNewCla, pOldCla, ( 3 + pOldCla->fLearnt + pOldCla->nSize ) * 4 ); + + pOldCla->fReallocd = 1; + pOldCla->nSize = (unsigned) nNewCRef; + *pCRef = nNewCRef; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) +{ + int i; + uint32_t * pArray; + xSAT_Mem_t * pNewMemMngr = xSAT_MemAlloc( xSAT_MemCap( s->pMemory ) - xSAT_MemWastedCap( s->pMemory ) ); + + for ( i = 0; i < 2 * Vec_StrSize( s->vAssigns ); i++ ) + { + xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vWatches, i); + xSAT_Watcher_t* begin = xSAT_WatchListArray(ws); + xSAT_Watcher_t* end = begin + xSAT_WatchListSize(ws); + xSAT_Watcher_t *w; + + for ( w = begin; w != end; w++ ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(w->CRef) ); + + ws = xSAT_VecWatchListEntry( s->vBinWatches, i); + begin = xSAT_WatchListArray(ws); + end = begin + xSAT_WatchListSize(ws); + for ( w = begin; w != end; w++ ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(w->CRef) ); + } + + for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ ) + if ( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); + + pArray = ( uint32_t * ) Vec_IntArray( s->vLearnts ); + for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); + + pArray = (uint32_t *) Vec_IntArray( s->vClauses ); + for ( i = 0; i < Vec_IntSize( s->vClauses ); i++ ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); + + xSAT_MemFree( s->pMemory ); + s->pMemory = pNewMemMngr; +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h new file mode 100644 index 00000000..a6d646c6 --- /dev/null +++ b/src/sat/xsat/xsatSolver.h @@ -0,0 +1,247 @@ +/**CFile**************************************************************** + + FileName [xsatSolver.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Internal definitions of the solver.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatSolver_h +#define ABC__sat__xSAT__xsatSolver_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include + +#include "misc/util/abc_global.h" +#include "misc/vec/vecStr.h" + +#include "xsat.h" +#include "xsatBQueue.h" +#include "xsatClause.h" +#include "xsatHeap.h" +#include "xsatMemory.h" +#include "xsatWatchList.h" + +ABC_NAMESPACE_HEADER_START + +#ifndef __cplusplus +#ifndef false +# define false 0 +#endif +#ifndef true +# define true 1 +#endif +#endif + +enum +{ + Var0 = 1, + Var1 = 0, + VarX = 3 +}; + +enum +{ + LBoolUndef = 0, + LBoolTrue = 1, + LBoolFalse = -1 +}; + +enum +{ + VarUndef = -1, + LitUndef = -2 +}; + +#define CRefUndef UINT32_MAX + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_SolverOptions_t_ xSAT_SolverOptions_t; +struct xSAT_SolverOptions_t_ +{ + char fVerbose; + + // Limits + ABC_INT64_T nConfLimit; // external limit on the number of conflicts + ABC_INT64_T nInsLimit; // external limit on the number of implications + abctime nRuntimeLimit; // external limit on runtime + + // Constants used for restart heuristic + double K; // Forces a restart + double R; // Block a restart + int nFirstBlockRestart; // Lower bound number of conflicts for start blocking restarts + int nSizeLBDQueue; // Size of the moving avarege queue for LBD (force restart) + int nSizeTrailQueue; // Size of the moving avarege queue for Trail size (block restart) + + // Constants used for clause database reduction heuristic + int nConfFirstReduce; // Number of conflicts before first reduction + int nIncReduce; // Increment to reduce + int nSpecialIncReduce; // Special increment to reduce + unsigned nLBDFrozenClause; +}; + +typedef struct xSAT_Stats_t_ xSAT_Stats_t; +struct xSAT_Stats_t_ +{ + unsigned nStarts; + unsigned nReduceDB; + + ABC_INT64_T nDecisions; + ABC_INT64_T nPropagations; + ABC_INT64_T nInspects; + ABC_INT64_T nConflicts; + + ABC_INT64_T nClauseLits; + ABC_INT64_T nLearntLits; +}; + +struct xSAT_Solver_t_ +{ + /* Clauses Database */ + xSAT_Mem_t * pMemory; + Vec_Int_t * vLearnts; + Vec_Int_t * vClauses; + xSAT_VecWatchList_t * vWatches; + xSAT_VecWatchList_t * vBinWatches; + + /* Activity heuristic */ + int nVarActInc; /* Amount to bump next variable with. */ + int nClaActInc; /* Amount to bump next clause with. */ + + /* Variable Information */ + Vec_Int_t * vActivity; /* A heuristic measurement of the activity of a variable. */ + xSAT_Heap_t * hOrder; + Vec_Int_t * vLevels; /* Decision level of the current assignment */ + Vec_Int_t * vReasons; /* Reason (clause) of the current assignment */ + Vec_Str_t * vAssigns; /* Current assignment. */ + Vec_Str_t * vPolarity; + Vec_Str_t * vTags; + + /* Assignments */ + Vec_Int_t * vTrail; + Vec_Int_t * vTrailLim; // Separator indices for different decision levels in 'trail'. + int iQhead; // Head of propagation queue (as index into the trail). + + int nAssignSimplify; /* Number of top-level assignments since last + * execution of 'simplify()'. */ + int64_t nPropSimplify; /* Remaining number of propagations that must be + * made before next execution of 'simplify()'. */ + + /* Temporary data used by Search method */ + xSAT_BQueue_t * bqTrail; + xSAT_BQueue_t * bqLBD; + float nSumLBD; + int nConfBeforeReduce; + long nRC1; + int nRC2; + + /* Temporary data used by Analyze */ + Vec_Int_t * vLearntClause; + Vec_Str_t * vSeen; + Vec_Int_t * vTagged; + Vec_Int_t * vStack; + Vec_Int_t * vLastDLevel; + + /* Misc temporary */ + unsigned nStamp; + Vec_Int_t * vStamp; /* Multipurpose stamp used to calculate LBD and + * clauses minimization with binary resolution */ + + xSAT_SolverOptions_t Config; + xSAT_Stats_t Stats; +}; + +static inline int xSAT_Var2Lit( int Var, int c ) +{ + return Var + Var + ( c != 0 ); +} + +static inline int xSAT_NegLit( int Lit ) +{ + return Lit ^ 1; +} + +static inline int xSAT_Lit2Var( int Lit ) +{ + return Lit >> 1; +} + +static inline int xSAT_LitSign( int Lit ) +{ + return Lit & 1; +} + +static inline int xSAT_SolverDecisionLevel( xSAT_Solver_t * s ) +{ + return Vec_IntSize( s->vTrailLim ); +} + +static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, uint32_t h ) +{ + return xSAT_MemClauseHand( s->pMemory, h ); +} + +static inline int xSAT_SolverIsClauseSatisfied( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) +{ + int * lits = &( pCla->pData[0].Lit ); + + for ( int i = 0; i < pCla->nSize; i++ ) + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( lits[i] ) ) == xSAT_LitSign( ( lits[i] ) ) ) + return true; + + return false; +} + +static inline void xSAT_SolverPrintClauses( xSAT_Solver_t * s ) +{ + int i; + unsigned CRef; + + Vec_IntForEachEntry( s->vClauses, CRef, i ) + xSAT_ClausePrint( xSAT_SolverReadClause( s, CRef ) ); +} + +static inline void xSAT_SolverPrintState( xSAT_Solver_t * s ) +{ + printf( "starts : %10d\n", s->Stats.nStarts ); + printf( "conflicts : %10ld\n", s->Stats.nConflicts ); + printf( "decisions : %10ld\n", s->Stats.nDecisions ); + printf( "propagations : %10ld\n", s->Stats.nPropagations ); +} + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// +extern uint32_t xSAT_SolverClaNew( xSAT_Solver_t* s, Vec_Int_t * vLits, int fLearnt ); +extern char xSAT_SolverSearch( xSAT_Solver_t * s ); + +extern void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ); + +extern int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, uint32_t From ); +extern void xSAT_SolverCancelUntil( xSAT_Solver_t* s, int Level); +extern uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ); +extern void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ); + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/xsat/xsatSolverAPI.c b/src/sat/xsat/xsatSolverAPI.c new file mode 100644 index 00000000..7ee817ee --- /dev/null +++ b/src/sat/xsat/xsatSolverAPI.c @@ -0,0 +1,345 @@ +/**CFile**************************************************************** + + FileName [xsatSolverAPI.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Solver external API functions implementation.] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include + +#include "xsatSolver.h" + +ABC_NAMESPACE_IMPL_START + +xSAT_SolverOptions_t DefaultConfig = +{ + .fVerbose = 1, + + .nConfLimit = 0, + .nInsLimit = 0, + .nRuntimeLimit = 0, + + .K = 0.8, + .R = 1.4, + .nFirstBlockRestart = 10000, + .nSizeLBDQueue = 50, + .nSizeTrailQueue = 5000, + + .nConfFirstReduce = 2000, + .nIncReduce = 300, + .nSpecialIncReduce = 1000, + + .nLBDFrozenClause = 30 +}; + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +xSAT_Solver_t* xSAT_SolverCreate() +{ + xSAT_Solver_t * s = (xSAT_Solver_t *) ABC_CALLOC( char, sizeof( xSAT_Solver_t ) ); + s->Config = DefaultConfig; + + s->pMemory = xSAT_MemAlloc(0); + s->vClauses = Vec_IntAlloc(0); + s->vLearnts = Vec_IntAlloc(0); + s->vWatches = xSAT_VecWatchListAlloc( 0 ); + s->vBinWatches = xSAT_VecWatchListAlloc( 0 ); + + s->vTrailLim = Vec_IntAlloc(0); + s->vTrail = Vec_IntAlloc( 0 ); + + s->vActivity = Vec_IntAlloc( 0 ); + s->hOrder = xSAT_HeapAlloc( s->vActivity ); + + s->vPolarity = Vec_StrAlloc( 0 ); + s->vTags = Vec_StrAlloc( 0 ); + s->vAssigns = Vec_StrAlloc( 0 ); + s->vLevels = Vec_IntAlloc( 0 ); + s->vReasons = Vec_IntAlloc( 0 ); + s->vStamp = Vec_IntAlloc( 0 ); + + s->vTagged = Vec_IntAlloc(0); + s->vStack = Vec_IntAlloc(0); + + s->vSeen = Vec_StrAlloc( 0 ); + s->vLearntClause = Vec_IntAlloc(0); + s->vLastDLevel = Vec_IntAlloc(0); + + + s->bqTrail = xSAT_BQueueNew( s->Config.nSizeTrailQueue ); + s->bqLBD = xSAT_BQueueNew( s->Config.nSizeLBDQueue ); + + s->nVarActInc = (1 << 5); + s->nClaActInc = (1 << 11); + + s->nConfBeforeReduce = s->Config.nConfFirstReduce; + s->nRC1 = 1; + s->nRC2 = s->Config.nConfFirstReduce; + return s; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverDestroy( xSAT_Solver_t * s ) +{ + xSAT_MemFree( s->pMemory ); + Vec_IntFree( s->vClauses ); + Vec_IntFree( s->vLearnts ); + xSAT_VecWatchListFree( s->vWatches ); + xSAT_VecWatchListFree( s->vBinWatches ); + + // delete vectors + xSAT_HeapFree(s->hOrder); + Vec_IntFree( s->vTrailLim ); + Vec_IntFree( s->vTrail ); + Vec_IntFree( s->vTagged ); + Vec_IntFree( s->vStack ); + + Vec_StrFree( s->vSeen ); + Vec_IntFree( s->vLearntClause ); + Vec_IntFree( s->vLastDLevel ); + + Vec_IntFree( s->vActivity ); + Vec_StrFree( s->vPolarity ); + Vec_StrFree( s->vTags ); + Vec_StrFree( s->vAssigns ); + Vec_IntFree( s->vLevels ); + Vec_IntFree( s->vReasons ); + + xSAT_BQueueFree(s->bqLBD); + xSAT_BQueueFree(s->bqTrail); + + ABC_FREE(s); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverSimplify( xSAT_Solver_t * s ) +{ + int i, j; + uint32_t CRef; + assert( xSAT_SolverDecisionLevel(s) == 0 ); + + if ( xSAT_SolverPropagate(s) != CRefUndef ) + return false; + + if ( s->nAssignSimplify == Vec_IntSize( s->vTrail ) || s->nPropSimplify > 0 ) + return true; + + j = 0; + Vec_IntForEachEntry( s->vClauses, CRef, i ) + { + xSAT_Clause_t * pCla = xSAT_SolverReadClause( s, CRef ); + if ( xSAT_SolverIsClauseSatisfied( s, pCla ) ) + { + pCla->fMark = 1; + s->Stats.nClauseLits -= pCla->nSize; + + if ( pCla->nSize == 2 ) + { + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit(pCla->pData[0].Lit) ), CRef ); + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit(pCla->pData[1].Lit) ), CRef ); + } + else + { + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit(pCla->pData[0].Lit) ), CRef ); + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit(pCla->pData[1].Lit) ), CRef ); + } + } + else + Vec_IntWriteEntry( s->vClauses, j++, CRef ); + } + Vec_IntShrink( s->vClauses, j ); + xSAT_SolverRebuildOrderHeap( s ); + + s->nAssignSimplify = Vec_IntSize( s->vTrail ); + s->nPropSimplify = s->Stats.nClauseLits + s->Stats.nLearntLits; + + return true; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverAddVariable( xSAT_Solver_t* s, int Sign ) +{ + int Var = Vec_IntSize( s->vActivity ); + + xSAT_VecWatchListPush( s->vWatches ); + xSAT_VecWatchListPush( s->vWatches ); + xSAT_VecWatchListPush( s->vBinWatches ); + xSAT_VecWatchListPush( s->vBinWatches ); + + Vec_IntPush( s->vActivity, 0 ); + Vec_IntPush( s->vLevels, 0 ); + Vec_StrPush( s->vAssigns, VarX ); + Vec_StrPush( s->vPolarity, 1 ); + Vec_StrPush( s->vTags, 0 ); + Vec_IntPush( s->vReasons, ( int ) CRefUndef ); + Vec_IntPush( s->vStamp, 0 ); + Vec_StrPush( s->vSeen, 0 ); + + xSAT_HeapInsert( s->hOrder, Var ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverAddClause( xSAT_Solver_t * s, Vec_Int_t * vLits ) +{ + int i, j; + int Lit, PrevLit; + int MaxVar; + + Vec_IntSort( vLits, 0 ); + MaxVar = xSAT_Lit2Var( Vec_IntEntryLast( vLits ) ); + while ( MaxVar >= Vec_IntSize( s->vActivity ) ) + xSAT_SolverAddVariable( s, 1 ); + + j = 0; + PrevLit = LitUndef; + Vec_IntForEachEntry( vLits, Lit, i ) + { + if ( Lit == xSAT_NegLit( PrevLit ) || Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == xSAT_LitSign( Lit ) ) + return true; + else if ( Lit != PrevLit && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX ) + { + PrevLit = Lit; + Vec_IntWriteEntry( vLits, j++, Lit ); + } + } + Vec_IntShrink( vLits, j ); + + if ( Vec_IntSize( vLits ) == 0 ) + return false; + if ( Vec_IntSize( vLits ) == 1 ) + { + xSAT_SolverEnqueue( s, Vec_IntEntry( vLits, 0 ), CRefUndef ); + return ( xSAT_SolverPropagate( s ) == CRefUndef ); + } + + xSAT_SolverClaNew( s, vLits, 0 ); + return true; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int xSAT_SolverSolve( xSAT_Solver_t* s ) +{ + char status = LBoolUndef; + + assert(s); + if ( s->Config.fVerbose ) + { + printf( "==========================================[ BLACK MAGIC ]================================================\n" ); + printf( "| | | |\n" ); + printf( "| - Restarts: | - Reduce Clause DB: | - Minimize Asserting: |\n" ); + printf( "| * LBD Queue : %6d | * First : %6d | * size < %3d |\n", s->Config.nSizeLBDQueue, s->Config.nConfFirstReduce, 0 ); + printf( "| * Trail Queue : %6d | * Inc : %6d | * lbd < %3d |\n", s->Config.nSizeTrailQueue, s->Config.nIncReduce, 0 ); + printf( "| * K : %6.2f | * Special : %6d | |\n", s->Config.K, s->Config.nSpecialIncReduce ); + printf( "| * R : %6.2f | * Protected : (lbd)< %2d | |\n", s->Config.R, s->Config.nLBDFrozenClause ); + printf( "| | | |\n" ); + printf( "=========================================================================================================\n" ); + } + + while ( status == LBoolUndef ) + status = xSAT_SolverSearch( s ); + + if ( s->Config.fVerbose ) + printf( "=========================================================================================================\n" ); + + xSAT_SolverCancelUntil( s, 0 ); + return status; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void xSAT_SolverPrintStats( xSAT_Solver_t * s ) +{ + printf( "starts : %10d\n", s->Stats.nStarts ); + printf( "conflicts : %10ld\n", s->Stats.nConflicts ); + printf( "decisions : %10ld\n", s->Stats.nDecisions ); + printf( "propagations : %10ld\n", s->Stats.nPropagations ); +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/xsat/xsatUtils.h b/src/sat/xsat/xsatUtils.h new file mode 100644 index 00000000..7f774d85 --- /dev/null +++ b/src/sat/xsat/xsatUtils.h @@ -0,0 +1,106 @@ +/**CFile**************************************************************** + + FileName [xsatUtils.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Utility functions used in xSAT] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatUtils_h +#define ABC__sat__xSAT__xsatUtils_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_UtilSelectSort( void** pArray, int nSize, int(* CompFnct )( const void *, const void * ) ) +{ + int i, j, iBest; + void* pTmp; + + for ( i = 0; i < ( nSize - 1 ); i++ ) + { + iBest = i; + for ( j = i + 1; j < nSize; j++ ) + { + if ( CompFnct( pArray[j], pArray[iBest] ) ) + iBest = j; + } + pTmp = pArray[i]; + pArray[i] = pArray[iBest]; + pArray[iBest] = pTmp; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static void xSAT_UtilSort( void** pArray, int nSize, int(* CompFnct )( const void *, const void *) ) +{ + if ( nSize <= 15 ) + xSAT_UtilSelectSort( pArray, nSize, CompFnct ); + else + { + void* pPivot = pArray[nSize / 2]; + void* pTmp; + int i = -1; + int j = nSize; + + for(;;) + { + do i++; while( CompFnct( pArray[i], pPivot ) ); + do j--; while( CompFnct( pPivot, pArray[j] ) ); + + if ( i >= j ) + break; + + pTmp = pArray[i]; + pArray[i] = pArray[j]; + pArray[j] = pTmp; + } + + xSAT_UtilSort( pArray, i, CompFnct ); + xSAT_UtilSort( pArray + i, ( nSize - i ), CompFnct ); + } +} + +ABC_NAMESPACE_HEADER_END + +#endif +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/sat/xsat/xsatWatchList.h b/src/sat/xsat/xsatWatchList.h new file mode 100644 index 00000000..454cfe44 --- /dev/null +++ b/src/sat/xsat/xsatWatchList.h @@ -0,0 +1,268 @@ +/**CFile**************************************************************** + + FileName [xsatWatchList.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Watch list and its related structures implementation] + + Author [Bruno Schmitt ] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - November 10, 2016.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatWatchList_h +#define ABC__sat__xSAT__xsatWatchList_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +typedef struct xSAT_Watcher_t_ xSAT_Watcher_t; +struct xSAT_Watcher_t_ +{ + uint32_t CRef; + int Blocker; +}; + +typedef struct xSAT_WatchList_t_ xSAT_WatchList_t; +struct xSAT_WatchList_t_ +{ + int nCap; + int nSize; + xSAT_Watcher_t * pArray; +}; + +typedef struct xSAT_VecWatchList_t_ xSAT_VecWatchList_t; +struct xSAT_VecWatchList_t_ +{ + int nCap; + int nSize; + xSAT_WatchList_t * pArray; +}; + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_WatchListFree( xSAT_WatchList_t * v ) +{ + if ( v->pArray ) + ABC_FREE( v->pArray ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int xSAT_WatchListSize( xSAT_WatchList_t * v ) +{ + return v->nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_WatchListShrink( xSAT_WatchList_t * v, int k ) +{ + assert(k <= v->nSize); + v->nSize = k; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_WatchListPush( xSAT_WatchList_t * v, xSAT_Watcher_t e ) +{ + assert( v ); + if (v->nSize == v->nCap) + { + int newsize = (v->nCap < 4) ? 4 : (v->nCap / 2) * 3; + + v->pArray = ABC_REALLOC( xSAT_Watcher_t, v->pArray, newsize ); + if ( v->pArray == NULL ) + { + printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n", + 1.0 * v->nCap / (1<<20), 1.0 * newsize / (1<<20) ); + fflush( stdout ); + } + v->nCap = newsize; + } + + v->pArray[v->nSize++] = e; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_Watcher_t* xSAT_WatchListArray( xSAT_WatchList_t * v ) +{ + return v->pArray; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, uint32_t CRef ) +{ + xSAT_Watcher_t* ws = xSAT_WatchListArray(v); + int j = 0; + + for (; ws[j].CRef != CRef; j++); + assert(j < xSAT_WatchListSize(v)); + memmove(v->pArray + j, v->pArray + j + 1, (v->nSize - j - 1) * sizeof(xSAT_Watcher_t)); + v->nSize -= 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_VecWatchList_t * xSAT_VecWatchListAlloc( int nCap ) +{ + xSAT_VecWatchList_t * v = ABC_ALLOC( xSAT_VecWatchList_t, 1 ); + + v->nCap = 4; + v->nSize = 0; + v->pArray = (xSAT_WatchList_t *) ABC_CALLOC(xSAT_WatchList_t, sizeof( xSAT_WatchList_t ) * v->nCap); + return v; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_VecWatchListFree( xSAT_VecWatchList_t* v ) +{ + for( int i = 0; i < v->nSize; i++ ) + xSAT_WatchListFree( v->pArray + i ); + + ABC_FREE( v->pArray ); + ABC_FREE( v ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSAT_VecWatchListPush( xSAT_VecWatchList_t* v ) +{ + if ( v->nSize == v->nCap ) + { + int newsize = (v->nCap < 4) ? v->nCap * 2 : (v->nCap / 2) * 3; + + v->pArray = ABC_REALLOC( xSAT_WatchList_t, v->pArray, newsize ); + memset( v->pArray + v->nCap, 0, sizeof(xSAT_WatchList_t) * (newsize - v->nCap) ); + if ( v->pArray == NULL ) + { + printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n", + 1.0 * v->nCap / (1<<20), 1.0 * newsize / (1<<20) ); + fflush( stdout ); + } + v->nCap = newsize; + } + + v->nSize++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xSAT_WatchList_t * xSAT_VecWatchListEntry( xSAT_VecWatchList_t* v, int iEntry ) +{ + assert( iEntry < v->nCap ); + assert( iEntry < v->nSize ); + return v->pArray + iEntry; +} + +ABC_NAMESPACE_HEADER_END + +#endif -- cgit v1.2.3 From 81af996fee2626daf45936e892ab34f26bea2ada Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 13 Dec 2016 10:02:28 +0800 Subject: Bug fix in 'dsat ' when the number of classes in listed incorrectly. --- src/aig/gia/giaShow.c | 12 +-- src/proof/acec/acecCl.c | 204 +++++++++++++++++++++++++++++++++++++++++++ src/sat/cnf/cnfUtil.c | 2 +- src/sat/xsat/xsatBQueue.h | 17 ++-- src/sat/xsat/xsatClause.h | 2 +- src/sat/xsat/xsatMemory.h | 31 +++---- src/sat/xsat/xsatSolver.c | 129 +++++++++++++++------------ src/sat/xsat/xsatSolver.h | 31 +++---- src/sat/xsat/xsatSolverAPI.c | 29 +++--- src/sat/xsat/xsatWatchList.h | 7 +- 10 files changed, 348 insertions(+), 116 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index c68ba26c..afc58bf8 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -52,9 +52,9 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(p) > 200 ) + if ( Gia_ManAndNum(p) > 500 ) { - fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -378,7 +378,7 @@ int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node ) { int iBox = Vec_IntEntry( vMapAdds, Node ); if ( iBox >= 0 ) - return Vec_IntEntry( vAdds, 6*iBox+3 ); + return Vec_IntEntry( vAdds, 6*iBox+4 ); return Node; } void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) @@ -388,9 +388,9 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(p) > 500 ) + if ( Gia_ManAndNum(p) > 1000 ) { - fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -750,7 +750,7 @@ int Gia_ShowCollectObjs_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vAdds, Level = 1 + Abc_MaxInt( Abc_MaxInt(Level0, Level1), Level2 ); Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+3), Level ); Gia_ObjSetLevelId( p, Vec_IntEntry(vAdds, 6*iBox+4), Level ); - pObj = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+3) ); + pObj = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*iBox+4) ); } else if ( Vec_IntEntry(vMapXors, Gia_ObjId(p, pObj)) >= 0 ) { diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 32be3b30..b60c2bf9 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -45,6 +45,210 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ +void Acec_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors ) +{ + Gia_Obj_t * pObj; + int Obj = Node; + if ( Vec_IntEntry(vMirrors, Node) >= 0 ) + Obj = Abc_Lit2Var( Vec_IntEntry(vMirrors, Node) ); + pObj = Gia_ManObj( p, Obj ); + if ( !~pObj->Value ) + { + assert( Gia_ObjIsAnd(pObj) ); + Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0(pObj, Obj), vMirrors ); + Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId1(pObj, Obj), vMirrors ); + if ( Gia_ObjIsXor(pObj) ) + pObj->Value = Gia_ManAppendXorReal( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } + // set the original node as well + if ( Obj != Node ) + Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) ); +} +Gia_Man_t * Acec_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + assert( p->pMuxes == NULL ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachCo( p, pObj, i ) + Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0p(p, pObj), vMirrors ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p ) +{ + Vec_Int_t * vRootXorSet = Vec_IntAlloc( Gia_ManCoNum(p) ); + Gia_Obj_t * pObj, * pFan0, * pFan1, * pFan00, * pFan01, * pFan10, * pFan11; + int i, fXor0, fXor1, fFirstXor = 0; + Gia_ManForEachCoDriver( p, pObj, i ) + { + if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + { + if ( fFirstXor ) + { + printf( "XORs do not form a continuous sequence\n" ); + Vec_IntFreeP( &vRootXorSet ); + break; + } + continue; + } + fFirstXor = 1; + fXor0 = Gia_ObjRecognizeExor(Gia_Regular(pFan0), &pFan00, &pFan01); + fXor1 = Gia_ObjRecognizeExor(Gia_Regular(pFan1), &pFan10, &pFan11); + if ( fXor0 == fXor1 ) + { + printf( "Both inputs of top level XOR have XOR/non-XOR\n" ); + Vec_IntFreeP( &vRootXorSet ); + break; + } + Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan1)) : Gia_ObjId(p, Gia_Regular(pFan0)) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan10)) : Gia_ObjId(p, Gia_Regular(pFan00)) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan11)) : Gia_ObjId(p, Gia_Regular(pFan01)) ); + } + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + printf( "%2d : ", i ); + printf( "%4d <- ", Vec_IntEntry(vRootXorSet, 4*i) ); + printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+1) ); + printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+2) ); + printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+3) ); + printf( "\n" ); + } + return vRootXorSet; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf ) +{ + Gia_Obj_t * pNode; + int Lit0, Lit1; + if ( Node < Leaf ) + return -1; + if ( Node == Leaf ) + return Abc_Var2Lit(Node, 0); + pNode = Gia_ManObj( p, Node ); + Lit0 = Acec_DetectLitPolarity( p, Gia_ObjFaninId0(pNode, Node), Leaf ); + Lit1 = Acec_DetectLitPolarity( p, Gia_ObjFaninId1(pNode, Node), Leaf ); + Lit0 = Lit0 == -1 ? Lit0 : Abc_LitNotCond( Lit0, Gia_ObjFaninC0(pNode) ); + Lit1 = Lit1 == -1 ? Lit1 : Abc_LitNotCond( Lit1, Gia_ObjFaninC1(pNode) ); + if ( Lit0 == -1 && Lit1 == -1 ) + return -1; + assert( Lit0 != -1 || Lit1 != -1 ); + if ( Lit0 != -1 && Lit1 != -1 ) + { + assert( Lit0 == Lit1 ); + return Lit0; + } + return Lit0 != -1 ? Lit0 : Lit1; +} +Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) +{ + Gia_Man_t * pNew; + int i, k, iOr1, iAnd1, iAnd2, pLits[3]; // carry, in1, in2 + Vec_Int_t * vMirrors = Vec_IntStart( Gia_ManObjNum(p) ); + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + pLits[0] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+1) ); + // get polarity of two new ones + for ( k = 1; k < 3; k++ ) + pLits[k] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+k+1) ); + // create the gate + iOr1 = Gia_ManAppendOr( p, pLits[1], pLits[2] ); + iAnd1 = Gia_ManAppendAnd( p, pLits[0], iOr1 ); + iAnd2 = Gia_ManAppendAnd( p, pLits[1], pLits[2] ); + pLits[0] = Gia_ManAppendOr( p, iAnd1, iAnd2 ); + Vec_IntWriteEntry( vMirrors, Vec_IntEntry(vRootXorSet, 4*i+1), pLits[0] ); + } + // remap the AIG using map + pNew = Acec_ManDerive( p, vMirrors ); + Vec_IntFree( vMirrors ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) +{ + extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); + extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); + extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); + + abctime clk = Abc_Clock(); + Gia_Man_t * pNew; + Vec_Int_t * vRootXorSet; +// Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); +// Ree_ManRemoveTrivial( p, vAdds ); +// Ree_ManRemoveContained( p, vAdds ); + + //Ree_ManPrintAdders( vAdds, 1 ); +// printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); +// Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + clk = Abc_Clock(); + vRootXorSet = Acec_CollectXorTops( p ); + if ( vRootXorSet ) + { + pNew = Acec_DetectXorBuildNew( p, vRootXorSet ); + Vec_IntFree( vRootXorSet ); + } + else + pNew = Gia_ManDup( p ); + + printf( "Detected %d top XORs. ", Vec_IntSize(vRootXorSet)/4 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + +// Vec_IntFree( vXors ); +// Vec_IntFree( vAdds ); + return pNew; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/sat/cnf/cnfUtil.c b/src/sat/cnf/cnfUtil.c index 96002df8..5ccbeb0d 100644 --- a/src/sat/cnf/cnfUtil.c +++ b/src/sat/cnf/cnfUtil.c @@ -374,7 +374,7 @@ Cnf_Dat_t * Cnf_DataReadFromFile( char * pFileName ) // create pCnf = ABC_CALLOC( Cnf_Dat_t, 1 ); pCnf->nVars = nVars; - pCnf->nClauses = nClas; + pCnf->nClauses = Vec_IntSize(vClas)-1; pCnf->nLiterals = Vec_IntSize(vLits); pCnf->pClauses = ABC_ALLOC( int *, Vec_IntSize(vClas) ); pCnf->pClauses[0] = Vec_IntReleaseArray(vLits); diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h index 37951684..6c170c93 100644 --- a/src/sat/xsat/xsatBQueue.h +++ b/src/sat/xsat/xsatBQueue.h @@ -24,6 +24,7 @@ //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// + #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START @@ -31,6 +32,7 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// //////////////////////////////////////////////////////////////////////// + typedef struct xSAT_BQueue_t_ xSAT_BQueue_t; struct xSAT_BQueue_t_ { @@ -38,13 +40,14 @@ struct xSAT_BQueue_t_ int nCap; int iFirst; int iEmpty; - uint64_t nSum; - uint32_t * pData; + word nSum; + word * pData; }; //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// + /**Function************************************************************* Synopsis [] @@ -60,7 +63,7 @@ static inline xSAT_BQueue_t * xSAT_BQueueNew( int nCap ) { xSAT_BQueue_t * p = ABC_CALLOC( xSAT_BQueue_t, 1 ); p->nCap = nCap; - p->pData = ABC_CALLOC( uint32_t, nCap ); + p->pData = ABC_CALLOC( word, nCap ); return p; } @@ -92,7 +95,7 @@ static inline void xSAT_BQueueFree( xSAT_BQueue_t * p ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, uint32_t Value ) +static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, word Value ) { if ( p->nSize == p->nCap ) { @@ -125,8 +128,8 @@ static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, uint32_t Value ) ***********************************************************************/ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) { - assert( p->nSize >= 1 ); int RetValue = p->pData[p->iFirst]; + assert( p->nSize >= 1 ); p->nSum -= RetValue; p->iFirst = ( p->iFirst + 1 ) % p->nCap; p->nSize--; @@ -144,9 +147,9 @@ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_BQueueAvg( xSAT_BQueue_t * p ) +static inline word xSAT_BQueueAvg( xSAT_BQueue_t * p ) { - return ( uint32_t )( p->nSum / ( ( uint64_t ) p->nSize ) ); + return ( word )( p->nSum / ( ( word ) p->nSize ) ); } /**Function************************************************************* diff --git a/src/sat/xsat/xsatClause.h b/src/sat/xsat/xsatClause.h index 39f0a0c8..d05eb6de 100644 --- a/src/sat/xsat/xsatClause.h +++ b/src/sat/xsat/xsatClause.h @@ -96,7 +96,7 @@ static void xSAT_ClausePrint( xSAT_Clause_t * pCla ) int i; printf("{ "); - for ( i = 0; i < pCla->nSize; i++ ) + for ( i = 0; i < (int)pCla->nSize; i++ ) printf("%d ", pCla->pData[i].Lit ); printf("}\n"); } diff --git a/src/sat/xsat/xsatMemory.h b/src/sat/xsat/xsatMemory.h index 3a961b97..3324a563 100644 --- a/src/sat/xsat/xsatMemory.h +++ b/src/sat/xsat/xsatMemory.h @@ -36,10 +36,10 @@ ABC_NAMESPACE_HEADER_START typedef struct xSAT_Mem_t_ xSAT_Mem_t; struct xSAT_Mem_t_ { - uint32_t nSize; - uint32_t nCap; - uint32_t nWasted; - uint32_t * pData; + unsigned nSize; + unsigned nCap; + unsigned nWasted; + unsigned * pData; }; //////////////////////////////////////////////////////////////////////// @@ -58,7 +58,7 @@ struct xSAT_Mem_t_ ***********************************************************************/ static inline xSAT_Clause_t * xSAT_MemClauseHand( xSAT_Mem_t * p, int h ) { - return h != UINT32_MAX ? ( xSAT_Clause_t * )( p->pData + h ) : NULL; + return h != 0xFFFFFFFF ? ( xSAT_Clause_t * )( p->pData + h ) : NULL; } /**Function************************************************************* @@ -72,21 +72,21 @@ static inline xSAT_Clause_t * xSAT_MemClauseHand( xSAT_Mem_t * p, int h ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_MemGrow( xSAT_Mem_t * p, uint32_t nCap ) +static inline void xSAT_MemGrow( xSAT_Mem_t * p, unsigned nCap ) { + unsigned nPrevCap = p->nCap; if ( p->nCap >= nCap ) return; - uint32_t nPrevCap = p->nCap; while (p->nCap < nCap) { - uint32_t delta = ((p->nCap >> 1) + (p->nCap >> 3) + 2) & ~1; + unsigned delta = ((p->nCap >> 1) + (p->nCap >> 3) + 2) & ~1; p->nCap += delta; assert(p->nCap >= nPrevCap); } assert(p->nCap > 0); - p->pData = ABC_REALLOC(uint32_t, p->pData, p->nCap); + p->pData = ABC_REALLOC(unsigned, p->pData, p->nCap); } /**Function************************************************************* @@ -156,12 +156,13 @@ static inline void xSAT_MemFree( xSAT_Mem_t * p ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) +static inline unsigned xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) { + unsigned nPrevSize; assert(nSize > 0); xSAT_MemGrow(p, p->nSize + nSize); - uint32_t nPrevSize = p->nSize; + nPrevSize = p->nSize; p->nSize += nSize; assert(p->nSize > nPrevSize); @@ -179,9 +180,9 @@ static inline uint32_t xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_MemCRef( xSAT_Mem_t * p, uint32_t * pC ) +static inline unsigned xSAT_MemCRef( xSAT_Mem_t * p, unsigned * pC ) { - return ( uint32_t )( pC - &(p->pData[0]) ); + return ( unsigned )( pC - &(p->pData[0]) ); } /**Function************************************************************* @@ -195,7 +196,7 @@ static inline uint32_t xSAT_MemCRef( xSAT_Mem_t * p, uint32_t * pC ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_MemCap( xSAT_Mem_t * p ) +static inline unsigned xSAT_MemCap( xSAT_Mem_t * p ) { return p->nCap; } @@ -211,7 +212,7 @@ static inline uint32_t xSAT_MemCap( xSAT_Mem_t * p ) SeeAlso [] ***********************************************************************/ -static inline uint32_t xSAT_MemWastedCap( xSAT_Mem_t * p ) +static inline unsigned xSAT_MemWastedCap( xSAT_Mem_t * p ) { return p->nWasted; } diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index d6968a2d..91b0c595 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -101,8 +101,9 @@ void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ) static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s ) { unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); + int i; - for ( int i = 0; i < Vec_IntSize( s->vActivity ); i++ ) + for ( i = 0; i < Vec_IntSize( s->vActivity ); i++ ) pActivity[i] >>= 19; s->nVarActInc >>= 19; @@ -166,7 +167,7 @@ static inline void xSAT_SolverClaActRescale( xSAT_Solver_t * s ) Vec_IntForEachEntry( s->vLearnts, CRef, i ) { - pC = xSAT_SolverReadClause( s, (uint32_t) CRef ); + pC = xSAT_SolverReadClause( s, (unsigned) CRef ); pC->pData[pC->nSize].Act >>= 14; } s->nClaActInc >>= 14; @@ -221,9 +222,10 @@ static inline void xSAT_SolverClaActDecay( xSAT_Solver_t * s ) static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) { int nLBD = 0; + int i; s->nStamp++; - for ( int i = 0; i < pCla->nSize; i++ ) + for ( i = 0; i < (int)pCla->nSize; i++ ) { int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pCla->pData[i].Lit ) ); if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) @@ -238,9 +240,10 @@ static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits ) { int nLBD = 0; + int i; s->nStamp++; - for ( int i = 0; i < Vec_IntSize( vLits ); i++ ) + for ( i = 0; i < Vec_IntSize( vLits ); i++ ) { int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Vec_IntEntry( vLits, i ) ) ); if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) @@ -263,17 +266,18 @@ static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits ) SeeAlso [] ***********************************************************************/ -uint32_t xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) +unsigned xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) { - assert( Vec_IntSize( vLits ) > 1); - assert( fLearnt == 0 || fLearnt == 1 ); - - uint32_t CRef; + unsigned CRef; xSAT_Clause_t * pCla; xSAT_Watcher_t w1; xSAT_Watcher_t w2; + unsigned nWords; - uint32_t nWords = 3 + fLearnt + Vec_IntSize( vLits ); + assert( Vec_IntSize( vLits ) > 1); + assert( fLearnt == 0 || fLearnt == 1 ); + + nWords = 3 + fLearnt + Vec_IntSize( vLits ); CRef = xSAT_MemAppend( s->pMemory, nWords ); pCla = xSAT_SolverReadClause( s, CRef ); pCla->fLearnt = fLearnt; @@ -326,11 +330,11 @@ uint32_t xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) SeeAlso [] ***********************************************************************/ -int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, uint32_t Reason ) +int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned Reason ) { int Var = xSAT_Lit2Var( Lit ); - Vec_StrWriteEntry( s->vAssigns, Var, xSAT_LitSign( Lit ) ); + Vec_StrWriteEntry( s->vAssigns, Var, (char)xSAT_LitSign( Lit ) ); Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) ); Vec_IntWriteEntry( s->vReasons, Var, (int) Reason ); Vec_IntPush( s->vTrail, Lit ); @@ -370,16 +374,17 @@ static inline void xSAT_SolverNewDecision( xSAT_Solver_t* s, int Lit ) ***********************************************************************/ void xSAT_SolverCancelUntil( xSAT_Solver_t * s, int Level ) { + int c; if ( xSAT_SolverDecisionLevel( s ) <= Level ) return; - for ( int c = Vec_IntSize( s->vTrail ) - 1; c >= Vec_IntEntry( s->vTrailLim, Level ); c-- ) + for ( c = Vec_IntSize( s->vTrail ) - 1; c >= Vec_IntEntry( s->vTrailLim, Level ); c-- ) { int Var = xSAT_Lit2Var( Vec_IntEntry( s->vTrail, c ) ); Vec_StrWriteEntry( s->vAssigns, Var, VarX ); Vec_IntWriteEntry( s->vReasons, Var, ( int ) CRefUndef ); - Vec_StrWriteEntry( s->vPolarity, Var, xSAT_LitSign( Vec_IntEntry( s->vTrail, c ) ) ); + Vec_StrWriteEntry( s->vPolarity, Var, ( char )xSAT_LitSign( Vec_IntEntry( s->vTrail, c ) ) ); if ( !xSAT_HeapInHeap( s->hOrder, Var ) ) xSAT_HeapInsert( s->hOrder, Var ); @@ -405,17 +410,17 @@ static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) { int top = Vec_IntSize( s->vTagged ); - assert( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); + assert( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); Vec_IntClear( s->vStack ); Vec_IntPush( s->vStack, xSAT_Lit2Var( Lit ) ); while ( Vec_IntSize( s->vStack ) ) { int v = Vec_IntPop( s->vStack ); - assert( (uint32_t) Vec_IntEntry( s->vReasons, v ) != CRefUndef); - xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( uint32_t ) Vec_IntEntry( s->vReasons, v ) ); + xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( unsigned ) Vec_IntEntry( s->vReasons, v ) ); int* Lits = &( c->pData[0].Lit ); int i; + assert( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef); if( c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) { @@ -423,12 +428,12 @@ static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) ABC_SWAP( int, Lits[0], Lits[1] ); } - for (i = 1; i < c->nSize; i++) + for (i = 1; i < (int)c->nSize; i++) { int v = xSAT_Lit2Var( Lits[i] ); if ( !Vec_StrEntry( s->vSeen, v ) && Vec_IntEntry( s->vLevels, v ) ) { - if ( (uint32_t) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ((1 << (Vec_IntEntry( s->vLevels, v ) & 31)) & MinLevel)) + if ( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ((1 << (Vec_IntEntry( s->vLevels, v ) & 31)) & MinLevel)) { Vec_IntPush( s->vStack, v ); Vec_IntPush( s->vTagged, Lits[i] ); @@ -474,7 +479,7 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) /* Remove reduntant literals */ Vec_IntAppend( s->vTagged, vLits ); for ( i = j = 1; i < Vec_IntSize( vLits ); i++ ) - if ( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) + if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) pLits[j++] = pLits[i]; Vec_IntShrink( vLits, j ); @@ -483,33 +488,40 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) { int Lit; int FlaseLit = xSAT_NegLit( pLits[0] ); + int nb; + int l; + + xSAT_WatchList_t * ws; + xSAT_Watcher_t * begin; + xSAT_Watcher_t * end; + xSAT_Watcher_t * pWatcher; s->nStamp++; Vec_IntForEachEntry( vLits, Lit, i ) Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), s->nStamp ); - xSAT_WatchList_t * ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); - xSAT_Watcher_t * begin = xSAT_WatchListArray( ws ); - xSAT_Watcher_t * end = begin + xSAT_WatchListSize( ws ); - xSAT_Watcher_t * pWatcher; + ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); + begin = xSAT_WatchListArray( ws ); + end = begin + xSAT_WatchListSize( ws ); + pWatcher; - int nb = 0; + nb = 0; for ( pWatcher = begin; pWatcher < end; pWatcher++ ) { int ImpLit = pWatcher->Blocker; - if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) + if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == (int)s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) { nb++; Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), s->nStamp - 1 ); } } - int l = Vec_IntSize( vLits ) - 1; + l = Vec_IntSize( vLits ) - 1; if ( nb > 0 ) { for ( i = 1; i < Vec_IntSize( vLits ) - nb; i++ ) - if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != s->nStamp ) + if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != (int)s->nStamp ) { int TempLit = pLits[l]; pLits[l] = pLits[i]; @@ -533,20 +545,22 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) SeeAlso [] ***********************************************************************/ -static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD ) +static void xSAT_SolverAnalyze( xSAT_Solver_t* s, unsigned ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD ) { int* trail = Vec_IntArray( s->vTrail ); int Count = 0; int p = LitUndef; int Idx = Vec_IntSize( s->vTrail ) - 1; int* Lits; + int Lit; int i, j; Vec_IntPush( vLearnt, LitUndef ); do { + xSAT_Clause_t * c; assert( ConfCRef != CRefUndef ); - xSAT_Clause_t * c = xSAT_SolverReadClause(s, ConfCRef); + c = xSAT_SolverReadClause(s, ConfCRef); Lits = &( c->pData[0].Lit ); if( p != LitUndef && c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(Lits[0])) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) @@ -569,7 +583,7 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * } } - for ( j = ( p == LitUndef ? 0 : 1 ); j < c->nSize; j++ ) + for ( j = ( p == LitUndef ? 0 : 1 ); j < (int)c->nSize; j++ ) { int Var = xSAT_Lit2Var( Lits[j] ); @@ -592,7 +606,7 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * // Next clause to look at p = trail[Idx+1]; - ConfCRef = (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); + ConfCRef = (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( p ), 0 ); Count--; @@ -638,7 +652,6 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * Vec_IntClear( s->vLastDLevel ); } - int Lit; Vec_IntForEachEntry( s->vTagged, Lit, i ) Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 ); Vec_IntClear( s->vTagged ); @@ -655,9 +668,9 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, uint32_t ConfCRef, Vec_Int_t * SeeAlso [] ***********************************************************************/ -uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ) +unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ) { - uint32_t hConfl = CRefUndef; + unsigned hConfl = CRefUndef; int * Lits; int NegLit; int nProp = 0; @@ -689,13 +702,16 @@ uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ) for ( i = j = begin; i < end; ) { + xSAT_Clause_t* c; + xSAT_Watcher_t w; + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( i->Blocker ) ) { *j++ = *i++; continue; } - xSAT_Clause_t* c = xSAT_SolverReadClause( s, i->CRef ); + c = xSAT_SolverReadClause( s, i->CRef ); Lits = &( c->pData[0].Lit ); // Make sure the false literal is data[1]: @@ -707,8 +723,9 @@ uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ) } assert( Lits[1] == NegLit ); - xSAT_Watcher_t w = { .CRef = i->CRef, - .Blocker = Lits[0] }; + w.CRef = i->CRef; + w.Blocker = Lits[0]; + // If 0th watch is true, then clause is already satisfied. if ( Lits[0] != i->Blocker && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( Lits[0] ) ) *j++ = w; @@ -774,7 +791,7 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) abctime clk = Abc_Clock(); int nLearnedOld = Vec_IntSize( s->vLearnts ); int i, limit; - uint32_t CRef; + unsigned CRef; xSAT_Clause_t * c; xSAT_Clause_t ** learnts_cls; @@ -795,10 +812,11 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) Vec_IntClear( s->vLearnts ); for ( i = 0; i < nLearnedOld; i++ ) { + unsigned CRef; c = learnts_cls[i]; - uint32_t CRef = xSAT_MemCRef( s->pMemory, (uint32_t * ) c ); + CRef = xSAT_MemCRef( s->pMemory, (unsigned * ) c ); assert(c->fMark == 0); - if ( c->fCanBeDel && c->nLBD > 2 && c->nSize > 2 && (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( c->pData[0].Lit ) ) != CRef && ( i < limit ) ) + if ( c->fCanBeDel && c->nLBD > 2 && c->nSize > 2 && (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( c->pData[0].Lit ) ) != CRef && ( i < limit ) ) { c->fMark = 1; s->Stats.nLearntLits -= c->nSize; @@ -838,19 +856,19 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) ***********************************************************************/ char xSAT_SolverSearch( xSAT_Solver_t * s ) { - ABC_INT64_T conflictC = 0; + iword conflictC = 0; s->Stats.nStarts++; for (;;) { - uint32_t hConfl = xSAT_SolverPropagate( s ); + unsigned hConfl = xSAT_SolverPropagate( s ); if ( hConfl != CRefUndef ) { /* Conflict */ int BacktrackLevel; unsigned nLBD; - uint32_t CRef; + unsigned CRef; s->Stats.nConflicts++; conflictC++; @@ -859,7 +877,7 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) return LBoolFalse; xSAT_BQueuePush( s->bqTrail, Vec_IntSize( s->vTrail ) ); - if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * xSAT_BQueueAvg( s->bqTrail ) ) ) ) + if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * (iword)xSAT_BQueueAvg( s->bqTrail ) ) ) ) xSAT_BQueueClean(s->bqLBD); Vec_IntClear( s->vLearntClause ); @@ -879,7 +897,7 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) { /* No conflict */ int NextVar; - if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / s->Stats.nConflicts ) ) ) + if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( (iword)xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / (iword)s->Stats.nConflicts ) ) ) { xSAT_BQueueClean( s->bqLBD ); xSAT_SolverCancelUntil( s, 0 ); @@ -923,17 +941,20 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) SeeAlso [] ***********************************************************************/ -void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, uint32_t * pCRef ) +void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, unsigned * pCRef ) { xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef ); + unsigned nNewCRef; + xSAT_Clause_t * pNewCla; + if ( pOldCla->fReallocd ) { - *pCRef = (uint32_t) pOldCla->nSize; + *pCRef = (unsigned) pOldCla->nSize; return; } - uint32_t nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize ); - xSAT_Clause_t * pNewCla = xSAT_MemClauseHand( pDest, nNewCRef ); + nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize ); + pNewCla = xSAT_MemClauseHand( pDest, nNewCRef ); memcpy( pNewCla, pOldCla, ( 3 + pOldCla->fLearnt + pOldCla->nSize ) * 4 ); @@ -956,7 +977,7 @@ void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, uint32_t * pC void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) { int i; - uint32_t * pArray; + unsigned * pArray; xSAT_Mem_t * pNewMemMngr = xSAT_MemAlloc( xSAT_MemCap( s->pMemory ) - xSAT_MemWastedCap( s->pMemory ) ); for ( i = 0; i < 2 * Vec_StrSize( s->vAssigns ); i++ ) @@ -977,14 +998,14 @@ void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) } for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ ) - if ( (uint32_t) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) + if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); - pArray = ( uint32_t * ) Vec_IntArray( s->vLearnts ); + pArray = ( unsigned * ) Vec_IntArray( s->vLearnts ); for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); - pArray = (uint32_t *) Vec_IntArray( s->vClauses ); + pArray = (unsigned *) Vec_IntArray( s->vClauses ); for ( i = 0; i < Vec_IntSize( s->vClauses ); i++ ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h index a6d646c6..2bcd93b7 100644 --- a/src/sat/xsat/xsatSolver.h +++ b/src/sat/xsat/xsatSolver.h @@ -70,7 +70,7 @@ enum LitUndef = -2 }; -#define CRefUndef UINT32_MAX +#define CRefUndef 0xFFFFFFFF //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// @@ -81,8 +81,8 @@ struct xSAT_SolverOptions_t_ char fVerbose; // Limits - ABC_INT64_T nConfLimit; // external limit on the number of conflicts - ABC_INT64_T nInsLimit; // external limit on the number of implications + word nConfLimit; // external limit on the number of conflicts + word nInsLimit; // external limit on the number of implications abctime nRuntimeLimit; // external limit on runtime // Constants used for restart heuristic @@ -105,13 +105,13 @@ struct xSAT_Stats_t_ unsigned nStarts; unsigned nReduceDB; - ABC_INT64_T nDecisions; - ABC_INT64_T nPropagations; - ABC_INT64_T nInspects; - ABC_INT64_T nConflicts; + word nDecisions; + word nPropagations; + word nInspects; + word nConflicts; - ABC_INT64_T nClauseLits; - ABC_INT64_T nLearntLits; + word nClauseLits; + word nLearntLits; }; struct xSAT_Solver_t_ @@ -143,7 +143,7 @@ struct xSAT_Solver_t_ int nAssignSimplify; /* Number of top-level assignments since last * execution of 'simplify()'. */ - int64_t nPropSimplify; /* Remaining number of propagations that must be + word nPropSimplify; /* Remaining number of propagations that must be * made before next execution of 'simplify()'. */ /* Temporary data used by Search method */ @@ -195,16 +195,17 @@ static inline int xSAT_SolverDecisionLevel( xSAT_Solver_t * s ) return Vec_IntSize( s->vTrailLim ); } -static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, uint32_t h ) +static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, unsigned h ) { return xSAT_MemClauseHand( s->pMemory, h ); } static inline int xSAT_SolverIsClauseSatisfied( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) { + int i; int * lits = &( pCla->pData[0].Lit ); - for ( int i = 0; i < pCla->nSize; i++ ) + for ( i = 0; i < (int)pCla->nSize; i++ ) if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( lits[i] ) ) == xSAT_LitSign( ( lits[i] ) ) ) return true; @@ -232,14 +233,14 @@ static inline void xSAT_SolverPrintState( xSAT_Solver_t * s ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern uint32_t xSAT_SolverClaNew( xSAT_Solver_t* s, Vec_Int_t * vLits, int fLearnt ); +extern unsigned xSAT_SolverClaNew( xSAT_Solver_t* s, Vec_Int_t * vLits, int fLearnt ); extern char xSAT_SolverSearch( xSAT_Solver_t * s ); extern void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ); -extern int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, uint32_t From ); +extern int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned From ); extern void xSAT_SolverCancelUntil( xSAT_Solver_t* s, int Level); -extern uint32_t xSAT_SolverPropagate( xSAT_Solver_t* s ); +extern unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ); extern void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ); ABC_NAMESPACE_HEADER_END diff --git a/src/sat/xsat/xsatSolverAPI.c b/src/sat/xsat/xsatSolverAPI.c index 7ee817ee..43c2d06e 100644 --- a/src/sat/xsat/xsatSolverAPI.c +++ b/src/sat/xsat/xsatSolverAPI.c @@ -32,23 +32,23 @@ ABC_NAMESPACE_IMPL_START xSAT_SolverOptions_t DefaultConfig = { - .fVerbose = 1, + 1, //.fVerbose = 1, - .nConfLimit = 0, - .nInsLimit = 0, - .nRuntimeLimit = 0, + 0, //.nConfLimit = 0, + 0, //.nInsLimit = 0, + 0, //.nRuntimeLimit = 0, - .K = 0.8, - .R = 1.4, - .nFirstBlockRestart = 10000, - .nSizeLBDQueue = 50, - .nSizeTrailQueue = 5000, + 0.8, //.K = 0.8, + 1.4, //.R = 1.4, + 10000, //.nFirstBlockRestart = 10000, + 50, //.nSizeLBDQueue = 50, + 5000, //.nSizeTrailQueue = 5000, - .nConfFirstReduce = 2000, - .nIncReduce = 300, - .nSpecialIncReduce = 1000, + 2000, //.nConfFirstReduce = 2000, + 300, //.nIncReduce = 300, + 1000, //.nSpecialIncReduce = 1000, - .nLBDFrozenClause = 30 + 30 //.nLBDFrozenClause = 30 }; /**Function************************************************************* @@ -142,6 +142,7 @@ void xSAT_SolverDestroy( xSAT_Solver_t * s ) Vec_StrFree( s->vAssigns ); Vec_IntFree( s->vLevels ); Vec_IntFree( s->vReasons ); + Vec_IntFree( s->vStamp ); xSAT_BQueueFree(s->bqLBD); xSAT_BQueueFree(s->bqTrail); @@ -163,7 +164,7 @@ void xSAT_SolverDestroy( xSAT_Solver_t * s ) int xSAT_SolverSimplify( xSAT_Solver_t * s ) { int i, j; - uint32_t CRef; + unsigned CRef; assert( xSAT_SolverDecisionLevel(s) == 0 ); if ( xSAT_SolverPropagate(s) != CRefUndef ) diff --git a/src/sat/xsat/xsatWatchList.h b/src/sat/xsat/xsatWatchList.h index 454cfe44..2ba13c24 100644 --- a/src/sat/xsat/xsatWatchList.h +++ b/src/sat/xsat/xsatWatchList.h @@ -34,7 +34,7 @@ ABC_NAMESPACE_HEADER_START typedef struct xSAT_Watcher_t_ xSAT_Watcher_t; struct xSAT_Watcher_t_ { - uint32_t CRef; + unsigned CRef; int Blocker; }; @@ -162,7 +162,7 @@ static inline xSAT_Watcher_t* xSAT_WatchListArray( xSAT_WatchList_t * v ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, uint32_t CRef ) +static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, unsigned CRef ) { xSAT_Watcher_t* ws = xSAT_WatchListArray(v); int j = 0; @@ -207,7 +207,8 @@ static inline xSAT_VecWatchList_t * xSAT_VecWatchListAlloc( int nCap ) ***********************************************************************/ static inline void xSAT_VecWatchListFree( xSAT_VecWatchList_t* v ) { - for( int i = 0; i < v->nSize; i++ ) + int i; + for( i = 0; i < v->nSize; i++ ) xSAT_WatchListFree( v->pArray + i ); ABC_FREE( v->pArray ); -- cgit v1.2.3 From cb49c5d0067bc2630c86d258bba5bfbbc5a5d916 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 13 Dec 2016 10:34:17 +0800 Subject: Bug fix in 'dsat ' when the number of classes in listed incorrectly. --- src/sat/xsat/xsatHeap.h | 4 ++-- src/sat/xsat/xsatSolver.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h index 2e873e59..409ce460 100644 --- a/src/sat/xsat/xsatHeap.h +++ b/src/sat/xsat/xsatHeap.h @@ -48,7 +48,7 @@ struct xSAT_Heap_t_ SeeAlso [] ***********************************************************************/ -inline int xSAT_HeapSize( xSAT_Heap_t * h ) +static inline int xSAT_HeapSize( xSAT_Heap_t * h ) { return Vec_IntSize( h->vHeap ); } @@ -64,7 +64,7 @@ inline int xSAT_HeapSize( xSAT_Heap_t * h ) SeeAlso [] ***********************************************************************/ -inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) +static inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) { return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 ); } diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index 91b0c595..5806409e 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -503,7 +503,6 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); begin = xSAT_WatchListArray( ws ); end = begin + xSAT_WatchListSize( ws ); - pWatcher; nb = 0; for ( pWatcher = begin; pWatcher < end; pWatcher++ ) @@ -999,7 +998,7 @@ void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ ) if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) - xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, (unsigned *)&( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); pArray = ( unsigned * ) Vec_IntArray( s->vLearnts ); for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ ) -- cgit v1.2.3 From 123b425052636beceaa52e47ea695d35b75fb40a Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Tue, 13 Dec 2016 11:29:38 -0200 Subject: Fixes to make xSAT compile with old compilers. Small typos and variables renaming. --- src/sat/xsat/xsatBQueue.h | 15 ++-- src/sat/xsat/xsatClause.h | 8 +- src/sat/xsat/xsatHeap.h | 4 +- src/sat/xsat/xsatMemory.h | 10 +-- src/sat/xsat/xsatSolver.c | 176 ++++++++++++++++++++----------------------- src/sat/xsat/xsatSolver.h | 26 +++---- src/sat/xsat/xsatSolverAPI.c | 2 +- src/sat/xsat/xsatWatchList.h | 14 ++-- 8 files changed, 119 insertions(+), 136 deletions(-) (limited to 'src') diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h index 6c170c93..560f75c0 100644 --- a/src/sat/xsat/xsatBQueue.h +++ b/src/sat/xsat/xsatBQueue.h @@ -24,7 +24,6 @@ //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// - #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START @@ -32,7 +31,6 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// //////////////////////////////////////////////////////////////////////// - typedef struct xSAT_BQueue_t_ xSAT_BQueue_t; struct xSAT_BQueue_t_ { @@ -41,13 +39,12 @@ struct xSAT_BQueue_t_ int iFirst; int iEmpty; word nSum; - word * pData; + unsigned * pData; }; //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// - /**Function************************************************************* Synopsis [] @@ -63,7 +60,7 @@ static inline xSAT_BQueue_t * xSAT_BQueueNew( int nCap ) { xSAT_BQueue_t * p = ABC_CALLOC( xSAT_BQueue_t, 1 ); p->nCap = nCap; - p->pData = ABC_CALLOC( word, nCap ); + p->pData = ABC_CALLOC( unsigned, nCap ); return p; } @@ -95,7 +92,7 @@ static inline void xSAT_BQueueFree( xSAT_BQueue_t * p ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, word Value ) +static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, unsigned Value ) { if ( p->nSize == p->nCap ) { @@ -128,8 +125,8 @@ static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, word Value ) ***********************************************************************/ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) { - int RetValue = p->pData[p->iFirst]; assert( p->nSize >= 1 ); + int RetValue = p->pData[p->iFirst]; p->nSum -= RetValue; p->iFirst = ( p->iFirst + 1 ) % p->nCap; p->nSize--; @@ -147,9 +144,9 @@ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) SeeAlso [] ***********************************************************************/ -static inline word xSAT_BQueueAvg( xSAT_BQueue_t * p ) +static inline unsigned xSAT_BQueueAvg( xSAT_BQueue_t * p ) { - return ( word )( p->nSum / ( ( word ) p->nSize ) ); + return ( unsigned )( p->nSum / ( ( word ) p->nSize ) ); } /**Function************************************************************* diff --git a/src/sat/xsat/xsatClause.h b/src/sat/xsat/xsatClause.h index d05eb6de..ef353198 100644 --- a/src/sat/xsat/xsatClause.h +++ b/src/sat/xsat/xsatClause.h @@ -39,7 +39,7 @@ struct xSAT_Clause_t_ unsigned fReallocd : 1; unsigned fCanBeDel : 1; unsigned nLBD : 28; - unsigned nSize; + int nSize; union { int Lit; unsigned Act; @@ -60,7 +60,7 @@ struct xSAT_Clause_t_ SeeAlso [] ***********************************************************************/ -static int xSAT_ClauseCompare( const void * p1, const void * p2 ) +static inline int xSAT_ClauseCompare( const void * p1, const void * p2 ) { xSAT_Clause_t * pC1 = ( xSAT_Clause_t * ) p1; xSAT_Clause_t * pC2 = ( xSAT_Clause_t * ) p2; @@ -91,12 +91,12 @@ static int xSAT_ClauseCompare( const void * p1, const void * p2 ) SeeAlso [] ***********************************************************************/ -static void xSAT_ClausePrint( xSAT_Clause_t * pCla ) +static inline void xSAT_ClausePrint( xSAT_Clause_t * pCla ) { int i; printf("{ "); - for ( i = 0; i < (int)pCla->nSize; i++ ) + for ( i = 0; i < pCla->nSize; i++ ) printf("%d ", pCla->pData[i].Lit ); printf("}\n"); } diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h index 409ce460..2e873e59 100644 --- a/src/sat/xsat/xsatHeap.h +++ b/src/sat/xsat/xsatHeap.h @@ -48,7 +48,7 @@ struct xSAT_Heap_t_ SeeAlso [] ***********************************************************************/ -static inline int xSAT_HeapSize( xSAT_Heap_t * h ) +inline int xSAT_HeapSize( xSAT_Heap_t * h ) { return Vec_IntSize( h->vHeap ); } @@ -64,7 +64,7 @@ static inline int xSAT_HeapSize( xSAT_Heap_t * h ) SeeAlso [] ***********************************************************************/ -static inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) +inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) { return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 ); } diff --git a/src/sat/xsat/xsatMemory.h b/src/sat/xsat/xsatMemory.h index 3324a563..129c2f50 100644 --- a/src/sat/xsat/xsatMemory.h +++ b/src/sat/xsat/xsatMemory.h @@ -77,16 +77,14 @@ static inline void xSAT_MemGrow( xSAT_Mem_t * p, unsigned nCap ) unsigned nPrevCap = p->nCap; if ( p->nCap >= nCap ) return; - while (p->nCap < nCap) { - unsigned delta = ((p->nCap >> 1) + (p->nCap >> 3) + 2) & ~1; + unsigned delta = ( ( p->nCap >> 1 ) + ( p->nCap >> 3 ) + 2 ) & ~1; p->nCap += delta; assert(p->nCap >= nPrevCap); } - assert(p->nCap > 0); - p->pData = ABC_REALLOC(unsigned, p->pData, p->nCap); + p->pData = ABC_REALLOC( unsigned, p->pData, p->nCap ); } /**Function************************************************************* @@ -160,12 +158,10 @@ static inline unsigned xSAT_MemAppend( xSAT_Mem_t * p, int nSize ) { unsigned nPrevSize; assert(nSize > 0); - xSAT_MemGrow(p, p->nSize + nSize); - + xSAT_MemGrow( p, p->nSize + nSize ); nPrevSize = p->nSize; p->nSize += nSize; assert(p->nSize > nPrevSize); - return nPrevSize; } diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index 5806409e..467f5f8d 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -46,7 +46,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -static inline int xSAT_SolverDecide( xSAT_Solver_t* s ) +static inline int xSAT_SolverDecide( xSAT_Solver_t * s ) { int NextVar = VarUndef; @@ -74,7 +74,7 @@ static inline int xSAT_SolverDecide( xSAT_Solver_t* s ) SeeAlso [] ***********************************************************************/ -void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ) +void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t * s ) { Vec_Int_t * vTemp = Vec_IntAlloc( Vec_StrSize( s->vAssigns ) ); int Var; @@ -100,14 +100,14 @@ void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s ) ***********************************************************************/ static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s ) { - unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); int i; + unsigned * pActivity = ( unsigned * ) Vec_IntArray( s->vActivity ); for ( i = 0; i < Vec_IntSize( s->vActivity ); i++ ) pActivity[i] >>= 19; s->nVarActInc >>= 19; - s->nVarActInc = Abc_MaxInt( s->nVarActInc, (1 << 5) ); + s->nVarActInc = Abc_MaxInt( s->nVarActInc, ( 1 << 5 ) ); } /**Function************************************************************* @@ -121,9 +121,9 @@ static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_SolverVarActBump( xSAT_Solver_t* s, int Var ) +static inline void xSAT_SolverVarActBump( xSAT_Solver_t * s, int Var ) { - unsigned * pActivity = (unsigned *) Vec_IntArray( s->vActivity ); + unsigned * pActivity = ( unsigned * ) Vec_IntArray( s->vActivity ); pActivity[Var] += s->nVarActInc; if ( pActivity[Var] & 0x80000000 ) @@ -167,7 +167,7 @@ static inline void xSAT_SolverClaActRescale( xSAT_Solver_t * s ) Vec_IntForEachEntry( s->vLearnts, CRef, i ) { - pC = xSAT_SolverReadClause( s, (unsigned) CRef ); + pC = xSAT_SolverReadClause( s, ( unsigned ) CRef ); pC->pData[pC->nSize].Act >>= 14; } s->nClaActInc >>= 14; @@ -221,16 +221,16 @@ static inline void xSAT_SolverClaActDecay( xSAT_Solver_t * s ) ***********************************************************************/ static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) { - int nLBD = 0; int i; + int nLBD = 0; s->nStamp++; - for ( i = 0; i < (int)pCla->nSize; i++ ) + for ( i = 0; i < pCla->nSize; i++ ) { int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pCla->pData[i].Lit ) ); - if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) + if ( ( unsigned ) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) { - Vec_IntWriteEntry( s->vStamp, Level, (int) s->nStamp ); + Vec_IntWriteEntry( s->vStamp, Level, ( int ) s->nStamp ); nLBD++; } } @@ -239,16 +239,16 @@ static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits ) { - int nLBD = 0; int i; + int nLBD = 0; s->nStamp++; for ( i = 0; i < Vec_IntSize( vLits ); i++ ) { int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Vec_IntEntry( vLits, i ) ) ); - if ( (unsigned) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) + if ( ( unsigned ) Vec_IntEntry( s->vStamp, Level ) != s->nStamp ) { - Vec_IntWriteEntry( s->vStamp, Level, (int) s->nStamp ); + Vec_IntWriteEntry( s->vStamp, Level, ( int ) s->nStamp ); nLBD++; } } @@ -330,13 +330,13 @@ unsigned xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt ) SeeAlso [] ***********************************************************************/ -int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned Reason ) +int xSAT_SolverEnqueue( xSAT_Solver_t * s, int Lit, unsigned Reason ) { int Var = xSAT_Lit2Var( Lit ); - Vec_StrWriteEntry( s->vAssigns, Var, (char)xSAT_LitSign( Lit ) ); + Vec_StrWriteEntry( s->vAssigns, Var, xSAT_LitSign( Lit ) ); Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) ); - Vec_IntWriteEntry( s->vReasons, Var, (int) Reason ); + Vec_IntWriteEntry( s->vReasons, Var, ( int ) Reason ); Vec_IntPush( s->vTrail, Lit ); return true; @@ -353,7 +353,7 @@ int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned Reason ) SeeAlso [] ***********************************************************************/ -static inline void xSAT_SolverNewDecision( xSAT_Solver_t* s, int Lit ) +static inline void xSAT_SolverNewDecision( xSAT_Solver_t * s, int Lit ) { assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX ); s->Stats.nDecisions++; @@ -375,6 +375,7 @@ static inline void xSAT_SolverNewDecision( xSAT_Solver_t* s, int Lit ) void xSAT_SolverCancelUntil( xSAT_Solver_t * s, int Level ) { int c; + if ( xSAT_SolverDecisionLevel( s ) <= Level ) return; @@ -410,30 +411,30 @@ static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) { int top = Vec_IntSize( s->vTagged ); - assert( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); + assert( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef ); Vec_IntClear( s->vStack ); Vec_IntPush( s->vStack, xSAT_Lit2Var( Lit ) ); while ( Vec_IntSize( s->vStack ) ) { + int i; int v = Vec_IntPop( s->vStack ); xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( unsigned ) Vec_IntEntry( s->vReasons, v ) ); - int* Lits = &( c->pData[0].Lit ); - int i; - assert( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef); + int * Lits = &( c->pData[0].Lit ); + assert( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef); if( c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) { assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) ); ABC_SWAP( int, Lits[0], Lits[1] ); } - for (i = 1; i < (int)c->nSize; i++) + for ( i = 1; i < c->nSize; i++ ) { int v = xSAT_Lit2Var( Lits[i] ); if ( !Vec_StrEntry( s->vSeen, v ) && Vec_IntEntry( s->vLevels, v ) ) { - if ( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ((1 << (Vec_IntEntry( s->vLevels, v ) & 31)) & MinLevel)) + if ( ( unsigned ) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ( ( 1 << (Vec_IntEntry( s->vLevels, v ) & 31 ) ) & MinLevel ) ) { Vec_IntPush( s->vStack, v ); Vec_IntPush( s->vTagged, Lits[i] ); @@ -443,7 +444,7 @@ static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel ) { int Lit; Vec_IntForEachEntryStart( s->vTagged, Lit, i, top ) - Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var(Lit), 0 ); + Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 ); Vec_IntShrink( s->vTagged, top ); return 0; } @@ -479,40 +480,34 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) /* Remove reduntant literals */ Vec_IntAppend( s->vTagged, vLits ); for ( i = j = 1; i < Vec_IntSize( vLits ); i++ ) - if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) + if ( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) ) pLits[j++] = pLits[i]; Vec_IntShrink( vLits, j ); /* Binary Resolution */ if( Vec_IntSize( vLits ) <= 30 && xSAT_SolverClaCalcLBD2( s, vLits ) <= 6 ) { + int nb, l; int Lit; int FlaseLit = xSAT_NegLit( pLits[0] ); - int nb; - int l; - - xSAT_WatchList_t * ws; - xSAT_Watcher_t * begin; - xSAT_Watcher_t * end; + xSAT_WatchList_t * ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); + xSAT_Watcher_t * begin = xSAT_WatchListArray( ws ); + xSAT_Watcher_t * end = begin + xSAT_WatchListSize( ws ); xSAT_Watcher_t * pWatcher; s->nStamp++; Vec_IntForEachEntry( vLits, Lit, i ) - Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), s->nStamp ); - - ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit ); - begin = xSAT_WatchListArray( ws ); - end = begin + xSAT_WatchListSize( ws ); + Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), ( int ) s->nStamp ); nb = 0; for ( pWatcher = begin; pWatcher < end; pWatcher++ ) { int ImpLit = pWatcher->Blocker; - if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == (int)s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) + if ( ( unsigned ) Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) ) { nb++; - Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), s->nStamp - 1 ); + Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), ( int )( s->nStamp - 1 ) ); } } @@ -520,7 +515,7 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) if ( nb > 0 ) { for ( i = 1; i < Vec_IntSize( vLits ) - nb; i++ ) - if ( Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != (int)s->nStamp ) + if ( ( unsigned ) Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != s->nStamp ) { int TempLit = pLits[l]; pLits[l] = pLits[i]; @@ -546,43 +541,44 @@ static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits ) ***********************************************************************/ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, unsigned ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD ) { - int* trail = Vec_IntArray( s->vTrail ); - int Count = 0; + int * trail = Vec_IntArray( s->vTrail ); + int Count = 0; int p = LitUndef; int Idx = Vec_IntSize( s->vTrail ) - 1; - int* Lits; + int * Lits; int Lit; int i, j; Vec_IntPush( vLearnt, LitUndef ); do { - xSAT_Clause_t * c; + xSAT_Clause_t * pCla; + assert( ConfCRef != CRefUndef ); - c = xSAT_SolverReadClause(s, ConfCRef); - Lits = &( c->pData[0].Lit ); + pCla = xSAT_SolverReadClause(s, ConfCRef); + Lits = &( pCla->pData[0].Lit ); - if( p != LitUndef && c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(Lits[0])) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) + if( p != LitUndef && pCla->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) ) { assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) ); ABC_SWAP( int, Lits[0], Lits[1] ); } - if ( c->fLearnt ) - xSAT_SolverClaActBump( s, c ); + if ( pCla->fLearnt ) + xSAT_SolverClaActBump( s, pCla ); - if ( c->fLearnt && c->nLBD > 2 ) + if ( pCla->fLearnt && pCla->nLBD > 2 ) { - unsigned int nblevels = xSAT_SolverClaCalcLBD(s, c); - if ( nblevels + 1 < c->nLBD ) + unsigned int nLevels = xSAT_SolverClaCalcLBD( s, pCla ); + if ( nLevels + 1 < pCla->nLBD ) { - if (c->nLBD <= s->Config.nLBDFrozenClause) - c->fCanBeDel = 0; - c->nLBD = nblevels; + if ( pCla->nLBD <= s->Config.nLBDFrozenClause ) + pCla->fCanBeDel = 0; + pCla->nLBD = nLevels; } } - for ( j = ( p == LitUndef ? 0 : 1 ); j < (int)c->nSize; j++ ) + for ( j = ( p == LitUndef ? 0 : 1 ); j < pCla->nSize; j++ ) { int Var = xSAT_Lit2Var( Lits[j] ); @@ -605,14 +601,13 @@ static void xSAT_SolverAnalyze( xSAT_Solver_t* s, unsigned ConfCRef, Vec_Int_t * // Next clause to look at p = trail[Idx+1]; - ConfCRef = (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); + ConfCRef = ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) ); Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( p ), 0 ); Count--; } while ( Count > 0 ); Vec_IntArray( vLearnt )[0] = xSAT_NegLit( p ); - xSAT_SolverClaMinimisation( s, vLearnt ); // Find the backtrack level @@ -677,41 +672,38 @@ unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ) while ( s->iQhead < Vec_IntSize( s->vTrail ) ) { int p = Vec_IntEntry( s->vTrail, s->iQhead++ ); - xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vBinWatches, p ); xSAT_Watcher_t* begin = xSAT_WatchListArray( ws ); xSAT_Watcher_t* end = begin + xSAT_WatchListSize( ws ); xSAT_Watcher_t *i, *j; nProp++; - for (i = begin; i < end; i++) + for ( i = begin; i < end; i++ ) { - if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(i->Blocker)) == xSAT_LitSign(xSAT_NegLit(i->Blocker))) + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( xSAT_NegLit( i->Blocker ) ) ) { return i->CRef; } - else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var(i->Blocker)) == VarX) - xSAT_SolverEnqueue(s, i->Blocker, i->CRef); + else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == VarX ) + xSAT_SolverEnqueue( s, i->Blocker, i->CRef ); } - - ws = xSAT_VecWatchListEntry( s->vWatches, p); + ws = xSAT_VecWatchListEntry( s->vWatches, p ); begin = xSAT_WatchListArray( ws ); end = begin + xSAT_WatchListSize( ws ); for ( i = j = begin; i < end; ) { - xSAT_Clause_t* c; + xSAT_Clause_t * pCla; xSAT_Watcher_t w; - if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( i->Blocker ) ) { *j++ = *i++; continue; } - c = xSAT_SolverReadClause( s, i->CRef ); - Lits = &( c->pData[0].Lit ); + pCla = xSAT_SolverReadClause( s, i->CRef ); + Lits = &( pCla->pData[0].Lit ); // Make sure the false literal is data[1]: NegLit = xSAT_NegLit( p ); @@ -731,8 +723,8 @@ unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ) else { // Look for new watch: - int* stop = Lits + c->nSize; - int* k; + int * stop = Lits + pCla->nSize; + int * k; for ( k = Lits + 2; k < stop; k++ ) { if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( *k ) ) != !xSAT_LitSign( *k ) ) @@ -791,7 +783,7 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) int nLearnedOld = Vec_IntSize( s->vLearnts ); int i, limit; unsigned CRef; - xSAT_Clause_t * c; + xSAT_Clause_t * pCla; xSAT_Clause_t ** learnts_cls; learnts_cls = ABC_ALLOC( xSAT_Clause_t *, nLearnedOld ); @@ -812,21 +804,22 @@ void xSAT_SolverReduceDB( xSAT_Solver_t * s ) for ( i = 0; i < nLearnedOld; i++ ) { unsigned CRef; - c = learnts_cls[i]; - CRef = xSAT_MemCRef( s->pMemory, (unsigned * ) c ); - assert(c->fMark == 0); - if ( c->fCanBeDel && c->nLBD > 2 && c->nSize > 2 && (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( c->pData[0].Lit ) ) != CRef && ( i < limit ) ) + + pCla = learnts_cls[i]; + CRef = xSAT_MemCRef( s->pMemory, ( unsigned * ) pCla ); + assert( pCla->fMark == 0 ); + if ( pCla->fCanBeDel && pCla->nLBD > 2 && pCla->nSize > 2 && (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pCla->pData[0].Lit ) ) != CRef && ( i < limit ) ) { - c->fMark = 1; - s->Stats.nLearntLits -= c->nSize; - xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( c->pData[0].Lit ) ), CRef ); - xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( c->pData[1].Lit ) ), CRef ); + pCla->fMark = 1; + s->Stats.nLearntLits -= pCla->nSize; + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), CRef ); + xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), CRef ); } else { - if (!c->fCanBeDel) + if ( !pCla->fCanBeDel ) limit++; - c->fCanBeDel = 1; + pCla->fCanBeDel = 1; Vec_IntPush( s->vLearnts, CRef ); } } @@ -876,7 +869,7 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) return LBoolFalse; xSAT_BQueuePush( s->bqTrail, Vec_IntSize( s->vTrail ) ); - if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * (iword)xSAT_BQueueAvg( s->bqTrail ) ) ) ) + if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * ( iword ) xSAT_BQueueAvg( s->bqTrail ) ) ) ) xSAT_BQueueClean(s->bqLBD); Vec_IntClear( s->vLearntClause ); @@ -896,7 +889,7 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) { /* No conflict */ int NextVar; - if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( (iword)xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / (iword)s->Stats.nConflicts ) ) ) + if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( ( iword )xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / s->Stats.nConflicts ) ) ) { xSAT_BQueueClean( s->bqLBD ); xSAT_SolverCancelUntil( s, 0 ); @@ -942,23 +935,20 @@ char xSAT_SolverSearch( xSAT_Solver_t * s ) ***********************************************************************/ void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, unsigned * pCRef ) { - xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef ); unsigned nNewCRef; xSAT_Clause_t * pNewCla; + xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef ); if ( pOldCla->fReallocd ) { - *pCRef = (unsigned) pOldCla->nSize; + *pCRef = ( unsigned ) pOldCla->nSize; return; } - nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize ); pNewCla = xSAT_MemClauseHand( pDest, nNewCRef ); - memcpy( pNewCla, pOldCla, ( 3 + pOldCla->fLearnt + pOldCla->nSize ) * 4 ); - pOldCla->fReallocd = 1; - pOldCla->nSize = (unsigned) nNewCRef; + pOldCla->nSize = ( unsigned ) nNewCRef; *pCRef = nNewCRef; } @@ -997,14 +987,14 @@ void xSAT_SolverGarbageCollect( xSAT_Solver_t * s ) } for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ ) - if ( (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) - xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, (unsigned *)&( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); + if ( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef ) + xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, ( unsigned * ) &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) ); pArray = ( unsigned * ) Vec_IntArray( s->vLearnts ); for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); - pArray = (unsigned *) Vec_IntArray( s->vClauses ); + pArray = ( unsigned * ) Vec_IntArray( s->vClauses ); for ( i = 0; i < Vec_IntSize( s->vClauses ); i++ ) xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) ); diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h index 2bcd93b7..bf8bf419 100644 --- a/src/sat/xsat/xsatSolver.h +++ b/src/sat/xsat/xsatSolver.h @@ -81,9 +81,9 @@ struct xSAT_SolverOptions_t_ char fVerbose; // Limits - word nConfLimit; // external limit on the number of conflicts - word nInsLimit; // external limit on the number of implications - abctime nRuntimeLimit; // external limit on runtime + iword nConfLimit; // external limit on the number of conflicts + iword nInsLimit; // external limit on the number of implications + abctime nRuntimeLimit; // external limit on runtime // Constants used for restart heuristic double K; // Forces a restart @@ -105,13 +105,13 @@ struct xSAT_Stats_t_ unsigned nStarts; unsigned nReduceDB; - word nDecisions; - word nPropagations; - word nInspects; - word nConflicts; + iword nDecisions; + iword nPropagations; + iword nInspects; + iword nConflicts; - word nClauseLits; - word nLearntLits; + iword nClauseLits; + iword nLearntLits; }; struct xSAT_Solver_t_ @@ -143,7 +143,7 @@ struct xSAT_Solver_t_ int nAssignSimplify; /* Number of top-level assignments since last * execution of 'simplify()'. */ - word nPropSimplify; /* Remaining number of propagations that must be + int64_t nPropSimplify; /* Remaining number of propagations that must be * made before next execution of 'simplify()'. */ /* Temporary data used by Search method */ @@ -203,10 +203,10 @@ static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, unsigned static inline int xSAT_SolverIsClauseSatisfied( xSAT_Solver_t * s, xSAT_Clause_t * pCla ) { int i; - int * lits = &( pCla->pData[0].Lit ); + int * Lits = &( pCla->pData[0].Lit ); - for ( i = 0; i < (int)pCla->nSize; i++ ) - if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( lits[i] ) ) == xSAT_LitSign( ( lits[i] ) ) ) + for ( i = 0; i < pCla->nSize; i++ ) + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[i] ) ) == xSAT_LitSign( ( Lits[i] ) ) ) return true; return false; diff --git a/src/sat/xsat/xsatSolverAPI.c b/src/sat/xsat/xsatSolverAPI.c index 43c2d06e..7746dc0b 100644 --- a/src/sat/xsat/xsatSolverAPI.c +++ b/src/sat/xsat/xsatSolverAPI.c @@ -51,6 +51,7 @@ xSAT_SolverOptions_t DefaultConfig = 30 //.nLBDFrozenClause = 30 }; + /**Function************************************************************* Synopsis [] @@ -125,7 +126,6 @@ void xSAT_SolverDestroy( xSAT_Solver_t * s ) xSAT_VecWatchListFree( s->vWatches ); xSAT_VecWatchListFree( s->vBinWatches ); - // delete vectors xSAT_HeapFree(s->hOrder); Vec_IntFree( s->vTrailLim ); Vec_IntFree( s->vTrail ); diff --git a/src/sat/xsat/xsatWatchList.h b/src/sat/xsat/xsatWatchList.h index 2ba13c24..284be100 100644 --- a/src/sat/xsat/xsatWatchList.h +++ b/src/sat/xsat/xsatWatchList.h @@ -118,9 +118,9 @@ static inline void xSAT_WatchListShrink( xSAT_WatchList_t * v, int k ) static inline void xSAT_WatchListPush( xSAT_WatchList_t * v, xSAT_Watcher_t e ) { assert( v ); - if (v->nSize == v->nCap) + if ( v->nSize == v->nCap ) { - int newsize = (v->nCap < 4) ? 4 : (v->nCap / 2) * 3; + int newsize = ( v->nCap < 4 ) ? 4 : ( v->nCap / 2 ) * 3; v->pArray = ABC_REALLOC( xSAT_Watcher_t, v->pArray, newsize ); if ( v->pArray == NULL ) @@ -167,9 +167,9 @@ static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, unsigned CRef ) xSAT_Watcher_t* ws = xSAT_WatchListArray(v); int j = 0; - for (; ws[j].CRef != CRef; j++); - assert(j < xSAT_WatchListSize(v)); - memmove(v->pArray + j, v->pArray + j + 1, (v->nSize - j - 1) * sizeof(xSAT_Watcher_t)); + for ( ; ws[j].CRef != CRef; j++ ); + assert( j < xSAT_WatchListSize( v ) ); + memmove( v->pArray + j, v->pArray + j + 1, ( v->nSize - j - 1 ) * sizeof( xSAT_Watcher_t ) ); v->nSize -= 1; } @@ -190,7 +190,7 @@ static inline xSAT_VecWatchList_t * xSAT_VecWatchListAlloc( int nCap ) v->nCap = 4; v->nSize = 0; - v->pArray = (xSAT_WatchList_t *) ABC_CALLOC(xSAT_WatchList_t, sizeof( xSAT_WatchList_t ) * v->nCap); + v->pArray = ( xSAT_WatchList_t * ) ABC_CALLOC(xSAT_WatchList_t, sizeof( xSAT_WatchList_t ) * v->nCap); return v; } @@ -233,7 +233,7 @@ static inline void xSAT_VecWatchListPush( xSAT_VecWatchList_t* v ) int newsize = (v->nCap < 4) ? v->nCap * 2 : (v->nCap / 2) * 3; v->pArray = ABC_REALLOC( xSAT_WatchList_t, v->pArray, newsize ); - memset( v->pArray + v->nCap, 0, sizeof(xSAT_WatchList_t) * (newsize - v->nCap) ); + memset( v->pArray + v->nCap, 0, sizeof( xSAT_WatchList_t ) * ( newsize - v->nCap ) ); if ( v->pArray == NULL ) { printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n", -- cgit v1.2.3 From cf5d4ad07f87e936a114afca483ed66ffb1a2120 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 21 Dec 2016 15:34:02 +0700 Subject: Converting some errors into warnings. --- src/base/abci/abc.c | 4 ++-- src/base/abci/abcMfs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dabeb982..fb301790 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -19532,7 +19532,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( Abc_NtkIsComb(pNtk) ) { - Abc_Print( -1, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" ); + Abc_Print( 0, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" ); return 0; } @@ -31954,7 +31954,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( Gia_ManRegNum(pAbc->pGia) == 0 ) { - Abc_Print( -1, "The network is combinational.\n" ); + Abc_Print( 0, "The network is combinational.\n" ); return 0; } pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars ); diff --git a/src/base/abci/abcMfs.c b/src/base/abci/abcMfs.c index e33d6c73..d44ca1a0 100644 --- a/src/base/abci/abcMfs.c +++ b/src/base/abci/abcMfs.c @@ -259,7 +259,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars ) if ( nFaninMax > 6 ) { Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" ); - return 0; + return 1; } if ( !Abc_NtkHasSop(pNtk) ) if ( !Abc_NtkToSop( pNtk, -1, ABC_INFINITY ) ) -- cgit v1.2.3 From b56a532682e34ae440bc6ffa939e82d06cf06e62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 22 Dec 2016 17:27:32 +0700 Subject: Several changes in arithmetic circuit manipulation. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaDup.c | 112 ++++++++++++++++++++--- src/aig/gia/giaShow.c | 12 +-- src/base/abci/abc.c | 12 ++- src/proof/acec/acecBo.c | 216 +++++++++++++++++++++++++++++++++++++++++++++ src/proof/acec/acecCl.c | 95 +++++++++++++++++++- src/proof/acec/module.make | 1 + 7 files changed, 426 insertions(+), 24 deletions(-) create mode 100644 src/proof/acec/acecBo.c (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index bf7bf349..ac40f975 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1403,7 +1403,7 @@ extern Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); /*=== giaShow.c ===========================================================*/ -extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ); +extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ); /*=== giaShrink.c ===========================================================*/ extern Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose ); extern Gia_Man_t * Gia_ManMapShrink6( Gia_Man_t * p, int nFanoutMax, int fKeepLevel, int fVerbose ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 7ced54a4..c58596b2 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3377,6 +3377,26 @@ Gia_Man_t * Gia_ManDupOuts( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ +Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gia_Obj_t * pObj; int i, Id; + Vec_Wec_t * vSuppsNo = Vec_WecStart( Vec_IntSize(vNodes) ); + Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) ); + Gia_ManForEachCiId( p, Id, i ) + Vec_IntPush( Vec_WecEntry(vSupps, Id), i ); + Gia_ManForEachAnd( p, pObj, Id ) + Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, Id)), + Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, Id)), + Vec_WecEntry(vSupps, Id) ); + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Vec_IntAppend( Vec_WecEntry(vSuppsNo, i), Vec_WecEntry(vSupps, Gia_ObjId(p, pObj)) ); + Vec_WecFree( vSupps ); + if ( fVerbose ) + Abc_PrintTime( 1, "Support computation", Abc_Clock() - clk ); + return vSuppsNo; +} + Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose ) { abctime clk = Abc_Clock(); @@ -3679,6 +3699,81 @@ Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupDemiterOrderXors2( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + int i, iObj, * pPerm; + Vec_Int_t * vSizes = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vXors, iObj, i ) + Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) ); + pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) ); + Vec_IntClear( vSizes ); + for ( i = 0; i < Vec_IntSize(vXors); i++ ) + Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) ); + ABC_FREE( pPerm ); + Vec_IntClear( vXors ); + Vec_IntAppend( vXors, vSizes ); + Vec_IntFree( vSizes ); +} +int Gia_ManDupDemiterFindMin( Vec_Wec_t * vSupps, Vec_Int_t * vTakenIns, Vec_Int_t * vTakenOuts ) +{ + Vec_Int_t * vLevel; + int i, k, iObj, iObjBest = -1; + int Count, CountBest = ABC_INFINITY; + Vec_WecForEachLevel( vSupps, vLevel, i ) + { + if ( Vec_IntEntry(vTakenOuts, i) ) + continue; + Count = 0; + Vec_IntForEachEntry( vLevel, iObj, k ) + Count += !Vec_IntEntry(vTakenIns, iObj); + if ( CountBest > Count ) + { + CountBest = Count; + iObjBest = i; + } + } + return iObjBest; +} +void Gia_ManDupDemiterOrderXors( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + extern Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose ); + Vec_Wec_t * vSupps = Gia_ManCreateNodeSupps( p, vXors, 0 ); + Vec_Int_t * vTakenIns = Vec_IntStart( Gia_ManCiNum(p) ); + Vec_Int_t * vTakenOuts = Vec_IntStart( Vec_IntSize(vXors) ); + Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXors) ); + int i, k, iObj; + // add outputs in the order of increasing supports + for ( i = 0; i < Vec_IntSize(vXors); i++ ) + { + int Index = Gia_ManDupDemiterFindMin( vSupps, vTakenIns, vTakenOuts ); + assert( Index >= 0 && Index < Vec_IntSize(vXors) ); + Vec_IntPush( vOrder, Vec_IntEntry(vXors, Index) ); + assert( !Vec_IntEntry( vTakenOuts, Index ) ); + Vec_IntWriteEntry( vTakenOuts, Index, 1 ); + Vec_IntForEachEntry( Vec_WecEntry(vSupps, Index), iObj, k ) + Vec_IntWriteEntry( vTakenIns, iObj, 1 ); + } + Vec_WecFree( vSupps ); + Vec_IntFree( vTakenIns ); + Vec_IntFree( vTakenOuts ); + // reload + Vec_IntClear( vXors ); + Vec_IntAppend( vXors, vOrder ); + Vec_IntFree( vOrder ); +} + + /**Function************************************************************* Synopsis [] @@ -3781,8 +3876,8 @@ void Gia_ManCollectTopXors_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXo } Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) { - int i, iObj, iObj2, fFlip, * pPerm, Count1 = 0; - Vec_Int_t * vXors, * vSizes, * vPart[2], * vOrder; + int i, iObj, iObj2, fFlip, Count1 = 0; + Vec_Int_t * vXors, * vPart[2], * vOrder; Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0); assert( Gia_ManCoNum(p) == 1 ); vXors = Vec_IntAlloc( 100 ); @@ -3791,17 +3886,8 @@ Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) else Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); // order by support size - vSizes = Vec_IntAlloc( 100 ); - Vec_IntForEachEntry( vXors, iObj, i ) - Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) ); - pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) ); - Vec_IntClear( vSizes ); - for ( i = 0; i < Vec_IntSize(vXors); i++ ) - Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) ); - ABC_FREE( pPerm ); - Vec_IntClear( vXors ); - Vec_IntAppend( vXors, vSizes ); - Vec_IntFree( vSizes ); + Gia_ManDupDemiterOrderXors( p, vXors ); + //Vec_IntPrint( vXors ); Vec_IntReverseOrder( vXors ); // from MSB to LSB // divide into groups Gia_ManCleanMark01(p); diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index afc58bf8..afd36fff 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -713,11 +713,13 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds ) { Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { + if ( fFadds && Vec_IntEntry(vAdds, 6*i+2) == 0 ) + continue; Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i ); Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i ); } @@ -800,9 +802,9 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v SeeAlso [] ***********************************************************************/ -void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors ) +void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { - Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds ); + Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder ); @@ -810,7 +812,7 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); } -void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) +void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); @@ -837,7 +839,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders ) fclose( pFile ); // generate the file if ( fAdders ) - Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors ); + Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fb301790..7866b22d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -28592,15 +28592,18 @@ usage: int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) { Vec_Int_t * vBold = NULL; - int c, fAdders = 0; + int c, fAdders = 0, fFadds = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "afh" ) ) != EOF ) { switch ( c ) { case 'a': fAdders ^= 1; break; + case 'f': + fFadds ^= 1; + break; case 'h': goto usage; default: @@ -28623,14 +28626,15 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManForEachLut( pAbc->pGia, c ) Vec_IntPush( vBold, c ); } - Gia_ManShow( pAbc->pGia, vBold, fAdders ); + Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds ); Vec_IntFreeP( &vBold ); return 0; usage: - Abc_Print( -2, "usage: &show [-ah]\n" ); + Abc_Print( -2, "usage: &show [-afh]\n" ); Abc_Print( -2, "\t shows the current GIA using GSView\n" ); Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle only showing full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } diff --git a/src/proof/acec/acecBo.c b/src/proof/acec/acecBo.c new file mode 100644 index 00000000..9cddcd13 --- /dev/null +++ b/src/proof/acec/acecBo.c @@ -0,0 +1,216 @@ +/**CFile**************************************************************** + + FileName [acecBo.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Core procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecBo.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/vec/vecWec.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_DetectBoothXorMux( Gia_Man_t * p, Gia_Obj_t * pMux, Gia_Obj_t * pXor, int pIns[3] ) +{ + Gia_Obj_t * pFan0, * pFan1; + Gia_Obj_t * pDat0, * pDat1, * pCtrl; + if ( !Gia_ObjIsMuxType(pMux) || !Gia_ObjIsMuxType(pXor) ) + return 0; + if ( !Gia_ObjRecognizeExor( pXor, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Gia_ObjId(p, pFan0) > Gia_ObjId(p, pFan1) ) + ABC_SWAP( Gia_Obj_t *, pFan0, pFan1 ); + if ( !(pCtrl = Gia_ObjRecognizeMux( pMux, &pDat0, &pDat1 )) ) + return 0; + pDat0 = Gia_Regular(pDat0); + pDat1 = Gia_Regular(pDat1); + pCtrl = Gia_Regular(pCtrl); + if ( !Gia_ObjIsAnd(pDat0) || !Gia_ObjIsAnd(pDat1) ) + return 0; + if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjFaninId0p(p, pDat1) || + Gia_ObjFaninId1p(p, pDat0) != Gia_ObjFaninId1p(p, pDat1) ) + return 0; + if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjId(p, pFan0) || + Gia_ObjFaninId1p(p, pDat0) != Gia_ObjId(p, pFan1) ) + return 0; + pIns[0] = Gia_ObjId(p, pFan0); + pIns[1] = Gia_ObjId(p, pFan1); + pIns[2] = Gia_ObjId(p, pCtrl); + return 1; +} +int Acec_DetectBoothXorFanin( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + //int Id = Gia_ObjId(p, pObj); + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( !Gia_ObjFaninC0(pObj) || !Gia_ObjFaninC1(pObj) ) + return 0; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( !Gia_ObjIsAnd(pFan0) || !Gia_ObjIsAnd(pFan1) ) + return 0; + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin0(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin1(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin0(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1)); + return 1; + } + if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin1(pFan1), pIns) ) + { + pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0)); + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1)); + return 1; + } + return 0; +} +int Acec_DetectBoothOne( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Acec_DetectBoothXorFanin( p, pFan0, pIns ) && pIns[2] == Gia_ObjId(p, pFan1) ) + return 1; + if ( Acec_DetectBoothXorFanin( p, pFan1, pIns ) && pIns[2] == Gia_ObjId(p, pFan0) ) + return 1; + return 0; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_DetectBoothTwoXor( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( Gia_ObjRecognizeExor( Gia_ObjFanin0(pObj), &pFan0, &pFan1 ) ) + { + pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + pIns[2] = -1; + pIns[3] = 0; + pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pObj)); + return 1; + } + if ( Gia_ObjRecognizeExor( Gia_ObjFanin1(pObj), &pFan0, &pFan1 ) ) + { + pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + pIns[2] = -1; + pIns[3] = 0; + pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pObj)); + return 1; + } + return 0; +} +int Acec_DetectBoothTwo( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) ) + return 0; + pFan0 = Gia_Regular(pFan0); + pFan1 = Gia_Regular(pFan1); + if ( Acec_DetectBoothTwoXor( p, pFan0, pIns ) ) + { + pIns[2] = Gia_ObjId(p, pFan1); + return 1; + } + if ( Acec_DetectBoothTwoXor( p, pFan1, pIns ) ) + { + pIns[2] = Gia_ObjId(p, pFan0); + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_DetectBoothTest( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, pIns[5]; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Acec_DetectBoothOne(p, pObj, pIns) && !Acec_DetectBoothTwo(p, pObj, pIns) ) + continue; + printf( "obj = %4d : b0 = %4d b1 = %4d b2 = %4d a0 = %4d a1 = %4d\n", + i, pIns[0], pIns[1], pIns[2], pIns[3], pIns[4] ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index b60c2bf9..63483d57 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -127,7 +127,7 @@ Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p ) break; } Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) ); - Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan1)) : Gia_ObjId(p, Gia_Regular(pFan0)) ); + Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan0)) : Gia_ObjId(p, Gia_Regular(pFan1)) ); Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan10)) : Gia_ObjId(p, Gia_Regular(pFan00)) ); Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan11)) : Gia_ObjId(p, Gia_Regular(pFan01)) ); } @@ -173,10 +173,101 @@ int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf ) if ( Lit0 != -1 && Lit1 != -1 ) { assert( Lit0 == Lit1 ); + printf( "Problem for leaf %d\n", Leaf ); return Lit0; } return Lit0 != -1 ? Lit0 : Lit1; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_DetectComputeSuppOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Int_t * vNods ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( pObj->fMark0 ) + { + Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin0(pObj), vSupp, vNods ); + Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin1(pObj), vSupp, vNods ); + Vec_IntPush( vNods, Gia_ObjId(p, pObj) ); +} +void Acec_DetectComputeSupports( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) +{ + Vec_Int_t * vNods = Vec_IntAlloc( 100 ); + Vec_Int_t * vPols = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); int i, k, Node, Pol; + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 1; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 1; + } + for ( i = 1; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Vec_IntClear( vSupp ); + Gia_ManIncrementTravId( p ); + + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0; + Acec_DetectComputeSuppOne_rec( p, Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) ), vSupp, vNods ); + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1; + + Vec_IntSort( vSupp, 0 ); + + printf( "Out %4d : %4d \n", i, Vec_IntEntry(vRootXorSet, 4*i+1) ); + Vec_IntPrint( vSupp ); + + printf( "Cone:\n" ); + Vec_IntForEachEntry( vNods, Node, k ) + Gia_ObjPrint( p, Gia_ManObj(p, Node) ); + + + Vec_IntClear( vPols ); + Vec_IntForEachEntry( vSupp, Node, k ) + Vec_IntPush( vPols, Acec_DetectLitPolarity(p, Vec_IntEntry(vRootXorSet, 4*i+1), Node) ); + + Vec_IntForEachEntryTwo( vSupp, vPols, Node, Pol, k ) + printf( "%d(%d) ", Node, Abc_LitIsCompl(Pol) ); + + printf( "\n" ); + + Vec_IntPrint( vSupp ); + } + for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ ) + { + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 0; + Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 0; + } + Vec_IntFree( vSupp ); + Vec_IntFree( vPols ); + Vec_IntFree( vNods ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) { Gia_Man_t * pNew; @@ -236,6 +327,8 @@ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) vRootXorSet = Acec_CollectXorTops( p ); if ( vRootXorSet ) { + Acec_DetectComputeSupports( p, vRootXorSet ); + pNew = Acec_DetectXorBuildNew( p, vRootXorSet ); Vec_IntFree( vRootXorSet ); } diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index df6db695..4003695e 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -1,6 +1,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecCore.c \ src/proof/acec/acecCo.c \ + src/proof/acec/acecBo.c \ src/proof/acec/acecRe.c \ src/proof/acec/acecPa.c \ src/proof/acec/acecPo.c \ -- cgit v1.2.3 From 7d0648e24098ed0e6a0a1471a52946303c351c87 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 23 Dec 2016 00:23:17 +0700 Subject: Correcting API names for inputing/outputing MiniLut. --- src/aig/miniaig/abcapis.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/aig/miniaig/abcapis.h b/src/aig/miniaig/abcapis.h index 38c0591d..f412f5ae 100644 --- a/src/aig/miniaig/abcapis.h +++ b/src/aig/miniaig/abcapis.h @@ -54,9 +54,9 @@ extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig ); extern void * Abc_NtkOutputMiniAig( void * pAbc ); extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops ); -// procedures to input/output 'mini AIG' -extern void Abc_NtkInputMiniLut( void * pAbc, void * pMiniLut ); -extern void * Abc_NtkOutputMiniLut( void * pAbc ); +// procedures to input/output 'mini LUT' +extern void Abc_FrameGiaInputMiniLut( void * pAbc, void * pMiniLut ); +extern void * Abc_FrameGiaOutputMiniLut( void * pAbc ); // procedures to set CI/CO arrival/required times extern void Abc_NtkSetCiArrivalTime( void * pAbc, int iCi, float Rise, float Fall ); -- cgit v1.2.3 From ac3216cf238dab066b12ddb1eac57c6682e34d2b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 25 Dec 2016 15:58:54 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCore.c | 166 +++++++++++++++++++++++-------- src/opt/sbd/sbdInt.h | 11 +++ src/opt/sbd/sbdLut.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++++ src/opt/sbd/sbdSat.c | 4 - src/opt/sbd/sbdWin.c | 177 ++++++++++++++++++++++++++++++--- 6 files changed, 551 insertions(+), 63 deletions(-) create mode 100644 src/opt/sbd/sbdLut.c (limited to 'src') diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index d966e577..0320d381 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -1,5 +1,6 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ + src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index b6ec70f9..563e6e98 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -54,10 +54,12 @@ struct Sbd_Man_t_ abctime timeTotal; // target node int Pivot; // target node + int DivCutoff; // the place where D-2 divisors begin Vec_Int_t * vTfo; // TFO (excludes node, includes roots) - precomputed Vec_Int_t * vRoots; // TFO root nodes Vec_Int_t * vWinObjs; // TFI + Pivot + sideTFI + TFO (including roots) Vec_Int_t * vObj2Var; // SAT variables for the window (indexes of objects in vWinObjs) + Vec_Int_t * vDivSet; // divisor variables Vec_Int_t * vDivVars; // divisor variables Vec_Int_t * vDivValues; // SAT variables values for the divisor variables Vec_Wec_t * vDivLevels; // divisors collected by levels @@ -200,6 +202,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) p->vRoots = Vec_IntAlloc( 100 ); p->vWinObjs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); p->vObj2Var = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vDivSet = Vec_IntAlloc( 100 ); p->vDivVars = Vec_IntAlloc( 100 ); p->vDivValues = Vec_IntAlloc( 100 ); p->vDivLevels = Vec_WecAlloc( 100 ); @@ -234,6 +237,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vRoots ); Vec_IntFree( p->vWinObjs ); Vec_IntFree( p->vObj2Var ); + Vec_IntFree( p->vDivSet ); Vec_IntFree( p->vDivVars ); Vec_IntFree( p->vDivValues ); Vec_WecFree( p->vDivLevels ); @@ -318,12 +322,11 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) Vec_WecInit( p->vDivLevels, LevelMax + 1 ); Vec_IntForEachEntry( p->vWinObjs, Node, i ) Vec_WecPush( p->vDivLevels, Vec_IntEntry(p->vLutLevs, Node), Node ); - // sort primary inputs - Vec_IntSort( Vec_WecEntry(p->vDivLevels, 0), 0 ); // reload divisors Vec_IntClear( p->vWinObjs ); Vec_WecForEachLevel( p->vDivLevels, vLevel, i ) { + Vec_IntSort( vLevel, 0 ); Vec_IntForEachEntry( vLevel, Node, k ) { Vec_IntWriteEntry( p->vObj2Var, Node, Vec_IntSize(p->vWinObjs) ); @@ -334,8 +337,26 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) nTimeValidDivs = Vec_IntSize(p->vWinObjs); } assert( nTimeValidDivs > 0 ); - Vec_IntFill( p->vDivValues, Abc_MinInt(63, nTimeValidDivs), 0 ); - //printf( "%d ", Abc_MinInt(63, nTimeValidDivs) ); + Vec_IntClear( p->vDivVars ); + p->DivCutoff = -1; + Vec_IntForEachEntryStartStop( p->vWinObjs, Node, i, Abc_MaxInt(0, nTimeValidDivs-63), nTimeValidDivs ) + { + if ( p->DivCutoff == -1 && Vec_IntEntry(p->vLutLevs, Node) == LevelMax - 2 ) + p->DivCutoff = Vec_IntSize(p->vDivVars); + Vec_IntPush( p->vDivVars, i ); + } + if ( p->DivCutoff == -1 ) + p->DivCutoff = 0; + // verify + assert( Vec_IntSize(p->vDivVars) < 64 ); + Vec_IntForEachEntryStart( p->vDivVars, Node, i, p->DivCutoff ) + assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); + Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) + assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); + Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); + //printf( "%d ", Vec_IntSize(p->vDivVars) ); +// printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", +// Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); } void Sbd_ManWindowSim_rec( Sbd_Man_t * p, int NodeInit ) { @@ -408,6 +429,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); Sbd_ManUpdateOrder( p, Pivot ); + assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); + assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); // simulate node Gia_ManObj(p->pGia, Pivot)->fMark0 = 1; Abc_TtCopy( Sbd_ObjSim1(p, Pivot), Sbd_ObjSim0(p, Pivot), p->pPars->nWords, 1 ); @@ -440,8 +463,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) p->timeWin += Abc_Clock() - clk; // propagate controlability to fanins for the TFI nodes starting from the pivot Sbd_ManPropagateControl( p, Pivot ); - assert( Vec_IntSize(p->vDivValues) < 64 ); - return (int)(Vec_IntSize(p->vDivValues) >= 64); + assert( Vec_IntSize(p->vDivValues) <= 64 ); + return (int)(Vec_IntSize(p->vDivValues) > 64); } /**Function************************************************************* @@ -466,8 +489,8 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) int RetValue, i, iObj, Ind, fFindOnset, nCares[2] = {0}; abctime clk = Abc_Clock(); extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); - p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; if ( p->pSat == NULL ) { @@ -836,11 +859,11 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi { int c0, c1, c2, c3; word Target = Cover[nDivs]; - Vec_IntClear( p->vDivVars ); + Vec_IntClear( p->vDivSet ); for ( c0 = 0; c0 < nDivs; c0++ ) if ( Cover[c0] == Target ) { - Vec_IntPush( p->vDivVars, c0 ); + Vec_IntPush( p->vDivSet, c0 ); return 1; } @@ -848,8 +871,8 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi for ( c1 = c0+1; c1 < nDivs; c1++ ) if ( (Cover[c0] | Cover[c1]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); return 1; } @@ -858,9 +881,9 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi for ( c2 = c1+1; c2 < nDivs; c2++ ) if ( (Cover[c0] | Cover[c1] | Cover[c2]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); - Vec_IntPush( p->vDivVars, c2 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); + Vec_IntPush( p->vDivSet, c2 ); return 1; } @@ -871,10 +894,10 @@ static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDi { if ( (Cover[c0] | Cover[c1] | Cover[c2] | Cover[c3]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); - Vec_IntPush( p->vDivVars, c2 ); - Vec_IntPush( p->vDivVars, c3 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); + Vec_IntPush( p->vDivSet, c2 ); + Vec_IntPush( p->vDivSet, c3 ); return 1; } } @@ -891,11 +914,11 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) if ( nDivs < 8 || p->pPars->fCover ) return Sbd_ManFindCandsSimple( p, Cover, nDivs ); - Vec_IntClear( p->vDivVars ); + Vec_IntClear( p->vDivSet ); for ( c0 = 0; c0 < nDivs; c0++ ) if ( Cover[c0] == Target ) { - Vec_IntPush( p->vDivVars, c0 ); + Vec_IntPush( p->vDivSet, c0 ); return 1; } @@ -903,8 +926,8 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) for ( c1 = c0+1; c1 < nDivs; c1++ ) if ( (Cover[c0] | Cover[c1]) == Target ) { - Vec_IntPush( p->vDivVars, c0 ); - Vec_IntPush( p->vDivVars, c1 ); + Vec_IntPush( p->vDivSet, c0 ); + Vec_IntPush( p->vDivSet, c1 ); return 1; } @@ -923,9 +946,9 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) for ( c2 = c1+1; c2 < Limits[2]; c2++ ) if ( (Cover[Order[c0]] | Cover[Order[c1]] | Cover[Order[c2]]) == Target ) { - Vec_IntPush( p->vDivVars, Order[c0] ); - Vec_IntPush( p->vDivVars, Order[c1] ); - Vec_IntPush( p->vDivVars, Order[c2] ); + Vec_IntPush( p->vDivSet, Order[c0] ); + Vec_IntPush( p->vDivSet, Order[c1] ); + Vec_IntPush( p->vDivSet, Order[c2] ); return 1; } @@ -936,10 +959,10 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) { if ( (Cover[Order[c0]] | Cover[Order[c1]] | Cover[Order[c2]] | Cover[Order[c3]]) == Target ) { - Vec_IntPush( p->vDivVars, Order[c0] ); - Vec_IntPush( p->vDivVars, Order[c1] ); - Vec_IntPush( p->vDivVars, Order[c2] ); - Vec_IntPush( p->vDivVars, Order[c3] ); + Vec_IntPush( p->vDivSet, Order[c0] ); + Vec_IntPush( p->vDivSet, Order[c1] ); + Vec_IntPush( p->vDivSet, Order[c2] ); + Vec_IntPush( p->vDivSet, Order[c3] ); return 1; } } @@ -952,10 +975,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) int fVerbose = 0; abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); int nIters, nItersMax = 32; - extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp ); + extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; - int i, k, n, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; + int i, k, n, Node, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; int nDivs = Vec_IntSize(p->vDivValues); int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); @@ -969,11 +992,11 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) Sbd_ManPrintObj( p, Pivot ); // collect bit-matrices - for ( i = 0; i < nDivs; i++ ) + Vec_IntForEachEntry( p->vDivVars, Node, i ) { - MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, i) ); - MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, i) ); - MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, i) ); + MatrS[63-i] = *Sbd_ObjSim0( p, Vec_IntEntry(p->vWinObjs, Node) ); + MatrC[0][63-i] = *Sbd_ObjSim2( p, Vec_IntEntry(p->vWinObjs, Node) ); + MatrC[1][63-i] = *Sbd_ObjSim3( p, Vec_IntEntry(p->vWinObjs, Node) ); } MatrS[63-i] = *Sbd_ObjSim0( p, Pivot ); MatrC[0][63-i] = *Sbd_ObjSim2( p, Pivot ); @@ -1067,10 +1090,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) if ( p->pPars->fVerbose ) printf( "Candidate support: " ), - Vec_IntPrint( p->vDivVars ); + Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); - *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivVars, p->vDivValues, p->vLits ); + *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); clkSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) @@ -1103,7 +1126,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) if ( p->pPars->fVerbose ) { printf( "Node %d: UNSAT.\n", Pivot ); - Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivVars) ), printf( "\n" ); + Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); } RetValue = 1; break; @@ -1118,6 +1141,13 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) return RetValue; } +int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, + int nLuts, int nSels, int nVarsDivs[SBD_LUTS_MAX], + int pVarsDivs[SBD_LUTS_MAX][SBD_SIZE_MAX], word Truths[SBD_LUTS_MAX] ) +{ + return 0; +} + /**Function************************************************************* Synopsis [Computes delay-oriented k-feasible cut at the node.] @@ -1233,7 +1263,7 @@ int Sbd_ManMergeCuts( Sbd_Man_t * p, int Node ) Vec_IntWriteEntry( p->vLutLevs, Node, LevCur ); assert( pCutRes[0] <= p->pPars->nLutSize ); memcpy( Sbd_ObjCut(p, Node), pCutRes, sizeof(int) * (pCutRes[0] + 1) ); - //printf( "Setting node %d with delay %d.\n", Node, LevCur ); +//printf( "Setting node %d with delay %d.\n", Node, LevCur ); return LevCur == 1; // LevCur == Abc_MaxInt(Level0, Level1); } int Sbd_ManDelay( Sbd_Man_t * p ) @@ -1306,7 +1336,7 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) int iNewLev; // collect leaf literals Vec_IntClear( p->vLits ); - Vec_IntForEachEntry( p->vDivVars, Node, i ) + Vec_IntForEachEntry( p->vDivSet, Node, i ) { Node = Vec_IntEntry( p->vWinObjs, Node ); if ( Vec_IntEntry(p->vMirrors, Node) >= 0 ) @@ -1429,20 +1459,68 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { +// extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); + int RetValue; word Truth = 0; if ( Sbd_ManMergeCuts( p, Pivot ) ) return; - //if ( Pivot != 344 ) - // continue; + +// if ( Pivot != 13 ) +// return; + if ( p->pPars->fVerbose ) printf( "\nLooking at node %d\n", Pivot ); if ( Sbd_ManWindow( p, Pivot ) ) return; + +// Sbd_ManSolveSelect( p->pGia, p->vMirrors, Pivot, p->vDivVars, p->vDivValues, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); + RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) + { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); + //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); + } else if ( Sbd_ManExplore( p, Pivot, &Truth ) ) + { Sbd_ManImplement( p, Pivot, Truth ); + //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + } +/* + else + { + extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] + ); + + Sbd_Str_t Strs[2] = { + {1, 4, {0, 1, 2, 7}}, + {1, 4, {3, 4, 5, 6}} + }; + + word Truths[SBD_LUTS_MAX]; + + Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); + + int i, RetValue; + + for ( i = 0; i < 7; i++ ) + Vec_IntPush( vDivSet, i+1 ); + + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + vDivSet, 2, Strs, Truths ); + if ( RetValue ) + { + printf( "Solving succeded.\n" ); + //Sbd_ManImplement2( p, Pivot, Truth, nLuts, nSels, nVarsDivs, pVarsDivs, Truths ); + } + Vec_IntFree( vDivSet ); + } +*/ } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { @@ -1488,8 +1566,10 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) else { Gia_ManForEachAndId( pGia, Pivot ) + { if ( Pivot < nNodesOld ) Sbd_NtkPerformOne( p, Pivot ); + } } printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 4c553fb4..3646c6b9 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -52,10 +52,21 @@ ABC_NAMESPACE_HEADER_START #define SBD_SAT_UNDEC 0x1234567812345678 #define SBD_SAT_SAT 0x8765432187654321 +#define SBD_LUTS_MAX 2 +#define SBD_SIZE_MAX 4 +#define SBD_DIV_MAX 7 + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Sbd_Str_t_ Sbd_Str_t; +struct Sbd_Str_t_ +{ + int fLut; // LUT or SEL + int nVarIns; // input count + int VarIns[SBD_DIV_MAX]; // input vars +}; //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c new file mode 100644 index 00000000..42bb0955 --- /dev/null +++ b/src/opt/sbd/sbdLut.c @@ -0,0 +1,255 @@ +/**CFile**************************************************************** + + FileName [sbdLut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [CNF computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// count the number of parameter variables in the structure +int Sbd_ProblemCountParams( int nStrs, Sbd_Str_t * pStr0 ) +{ + Sbd_Str_t * pStr; int nPars = 0; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + nPars += (pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns); + return nPars; +} +// add clauses for the structure +void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +{ + // variable order: inputs, structure outputs, parameters + Sbd_Str_t * pStr; + int VarOut = nVars; + int VarPar = nVars + nStrs; + int m, k, n, status, pLits[SBD_SIZE_MAX+2]; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarOut++ ) + { + if ( pStr->fLut ) + { + int nMints = 1 << pStr->nVarIns; + assert( pStr->nVarIns <= 6 ); + for ( m = 0; m < nMints; m++, VarPar++ ) + { + for ( k = 0; k < pStr->nVarIns; k++ ) + pLits[k] = Abc_Var2Lit( pVars[pStr->VarIns[k]], (m >> k) & 1 ); + for ( n = 0; n < 2; n++ ) + { + pLits[pStr->nVarIns] = Abc_Var2Lit( pVars[VarPar], n ); + pLits[pStr->nVarIns+1] = Abc_Var2Lit( pVars[VarOut], !n ); + status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns + 2 ); + assert( status ); + } + } + } + else + { + for ( k = 0; k < pStr->nVarIns; k++, VarPar++ ) + { + for ( n = 0; n < 2; n++ ) + { + pLits[0] = Abc_Var2Lit( pVars[VarPar], 1 ); + pLits[1] = Abc_Var2Lit( pVars[VarOut], n ); + pLits[2] = Abc_Var2Lit( pVars[pStr->VarIns[k]], !n ); + status = sat_solver_addclause( pSat, pLits, pLits + 3 ); + assert( status ); + } + } + } + } +} +void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +{ + Sbd_Str_t * pStr; + int VarPar = nVars + nStrs; + int m, m2, pLits[2], status; + // make sure selector parameters are mutually exclusive + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarPar = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns ) + { + if ( pStr->fLut ) + continue; + for ( m = 0; m < pStr->nVarIns; m++ ) + for ( m2 = m+1; m2 < pStr->nVarIns; m2++ ) + { + pLits[0] = Abc_Var2Lit( pVars[VarPar + m], 1 ); + pLits[1] = Abc_Var2Lit( pVars[VarPar + m2], 1 ); + status = sat_solver_addclause( pSat, pLits, pLits + 2 ); + assert( status ); + } + } +} +void Sbd_ProblemPrintSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) +{ + Sbd_Str_t * pStr; + int m, nIters, iLit = 0; + printf( "Solution found:\n" ); + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + { + nIters = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; + printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", pStr-pStr0 ); + for ( m = 0; m < nIters; m++ ) + printf( "%d", Abc_LitIsCompl(Vec_IntEntry(vLits, iLit++)) ); + printf( "\n" ); + } + assert( iLit == Vec_IntSize(vLits) ); +} +void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits, word Truths[SBD_LUTS_MAX] ) +{ +} + +/**Function************************************************************* + + Synopsis [Solves QBF problem for the given window.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] ) // divisors, structures +{ + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); + sat_solver * pSatQbf = sat_solver_new(); + + int nVars = Vec_IntSize( vDivSet ); + int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); + + int VarCecOut = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); + int VarCecPar = VarCecOut + 1; + int VarCecFree = VarCecPar + nPars; + + int VarQbfPar = 0; + int VarQbfFree = nPars; + + int pVarsCec[256]; + int pVarsQbf[256]; + int i, iVar, iLit; + int RetValue = 0; + + assert( Vec_IntSize(vDivSet) <= SBD_SIZE_MAX ); + assert( nVars + nStrs + nPars <= 256 ); + + // collect CEC variables + Vec_IntForEachEntry( vDivSet, iVar, i ) + pVarsCec[i] = iVar; + pVarsCec[nVars] = VarCecOut; + for ( i = 1; i < nStrs; i++ ) + pVarsCec[nVars + i] = VarCecFree++; + for ( i = 0; i < nPars; i++ ) + pVarsCec[nVars + nStrs + i] = VarCecPar + i; + + // collect QBF variables + for ( i = 0; i < nVars + nStrs; i++ ) + pVarsQbf[i] = -1; + for ( i = 0; i < nPars; i++ ) + pVarsQbf[nVars + nStrs + i] = VarQbfPar + i; + + // add clauses to the CEC problem + Sbd_ProblemAddClauses( pSatCec, nVars, nStrs, pVarsCec, pStr0 ); + + // create QBF solver + sat_solver_setnvars( pSatQbf, 1000 ); + Sbd_ProblemAddClausesInit( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + + // assume all parameter variables are 0 + Vec_IntClear( vLits ); + for ( i = 0; i < nPars; i++ ) + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, 1) ); + while ( 1 ) + { + // check if these parameters solve the problem + int status = sat_solver_solve( pSatCec, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 ); + if ( status == l_False ) // solution found + break; + assert( status == l_True ); + Vec_IntClear( vLits ); + // create new QBF variables + for ( i = 0; i < nVars + nStrs; i++ ) + pVarsQbf[i] = VarQbfFree++; + // set their values + Vec_IntForEachEntry( vDivSet, iVar, i ) + { + iLit = Abc_Var2Lit( pVarsQbf[i], sat_solver_var_value(pSatCec, iVar) ); + status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); + assert( status ); + } + iLit = Abc_Var2Lit( pVarsQbf[nVars], sat_solver_var_value(pSatCec, VarCecOut) ); + status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); + assert( status ); + // add clauses to the QBF problem + Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + // check if solution still exists + status = sat_solver_solve( pSatQbf, NULL, NULL, 0, 0, 0, 0 ); + if ( status == l_False ) // solution does not exist + break; + assert( status == l_True ); + // find the new values of parameters + assert( Vec_IntSize(vLits) == 0 ); + for ( i = 0; i < nPars; i++ ) + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); + } + if ( Vec_IntSize(vLits) > 0 ) + { + Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); + Sbd_ProblemCollectSolution( nStrs, pStr0, vLits, Truths ); + RetValue = 1; + } + else + printf( "Solution does not exist.\n" ); + + sat_solver_delete( pSatCec ); + sat_solver_delete( pSatQbf ); + Vec_IntFree( vLits ); + return RetValue; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/sbd/sbdSat.c b/src/opt/sbd/sbdSat.c index ae865627..f0de4dbf 100644 --- a/src/opt/sbd/sbdSat.c +++ b/src/opt/sbd/sbdSat.c @@ -37,10 +37,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -#define SBD_LUTS_MAX 2 -#define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 16 - // new AIG manager typedef struct Sbd_Pro_t_ Sbd_Pro_t; struct Sbd_Pro_t_ diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index d722f456..fc79caa7 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -39,19 +39,26 @@ ABC_NAMESPACE_IMPL_START a DFS ordered array of objects (vWinObjs) whose indexed in the array (which will be used as SAT variables) are given in array vObj2Var. The TFO nodes are listed as the last ones in vWinObjs. The root nodes - are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.] + are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots. + If fQbf is 1, returns the instance meant for QBF solving. It is using + the last variable (LastVar) as the placeholder for the second copy + of the pivot node.] SideEffects [] SeeAlso [] ***********************************************************************/ -sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) +sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ) { Gia_Obj_t * pObj; + int nAddVars = 64; int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue; int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo); int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int LastVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); //Vec_IntPrint( vWinObjs ); //Vec_IntPrint( vTfo ); //Vec_IntPrint( vRoots ); @@ -60,7 +67,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi pSat = sat_solver_new(); else sat_solver_restart( pSat ); - sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + 32 ); + sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + nAddVars ); // create constant 0 clause sat_solver_addclause( pSat, &iLit, &iLit + 1 ); // add clauses for all nodes @@ -100,8 +107,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Fan1 = Vec_IntEntry( vObj2Var, Fan1 ); Fan0 = Fan0 < TfoStart ? Fan0 : Fan0 + Vec_IntSize(vTfo); Fan1 = Fan1 < TfoStart ? Fan1 : Fan1 + Vec_IntSize(vTfo); - fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); - fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); + if ( fQbf ) + { + Fan0 = Fan0 == PivotVar ? LastVar : Fan0; + Fan1 = Fan1 == PivotVar ? LastVar : Fan1; + } + fCompl0 = Gia_ObjFaninC0(pObj) ^ (!fQbf && Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); + fCompl1 = Gia_ObjFaninC1(pObj) ^ (!fQbf && Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); if ( Gia_ObjIsXor(pObj) ) sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 ); else @@ -127,7 +139,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi sat_solver_delete( pSat ); return NULL; } - assert( sat_solver_nvars(pSat) == nVars + 32 ); + assert( sat_solver_nvars(pSat) == nVars + nAddVars ); } // finalize RetValue = sat_solver_simplify( pSat ); @@ -143,7 +155,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Synopsis [Solves one SAT problem.] - Description [Computes node function for PivotVar with fanins in vDivVars + Description [Computes node function for PivotVar with fanins in vDivSet using don't-care represented in the SAT solver. Uses array vValues to return the values of the first Vec_IntSize(vValues) SAT variables in case the implementation of the node with the given fanins does not exist.] @@ -153,12 +165,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi SeeAlso [] ***********************************************************************/ -word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp ) +word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ) { int nBTLimit = 0; word uCube, uTruth = 0; int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0; assert( FreeVar < sat_solver_nvars(pSat) ); + assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) ); pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1 pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit while ( 1 ) @@ -171,12 +184,12 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi return uTruth; assert( status == l_True ); // remember variable values - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) ); + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntWriteEntry( vDivValues, i, 2*sat_solver_var_value(pSat, iVar) ); // collect divisor literals Vec_IntClear( vTemp ); Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0 - Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntForEachEntry( vDivSet, iVar, i ) Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) ); // check against offset status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 ); @@ -195,7 +208,7 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi if ( pFinal[i] == pLits[0] ) continue; Vec_IntPush( vTemp, pFinal[i] ); - iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); + iVar = Vec_IntFind( vDivSet, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar]; } uTruth |= uCube; @@ -205,11 +218,11 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi } assert( status == l_True ); // store the counter-example - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) ); + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntAddToEntry( vDivValues, i, sat_solver_var_value(pSat, iVar) ); - for ( i = 0; i < Vec_IntSize(vValues); i++ ) - Vec_IntAddToEntry( vValues, i, 0xC ); + for ( i = 0; i < Vec_IntSize(vDivValues); i++ ) + Vec_IntAddToEntry( vDivValues, i, 0xC ); /* // reduce the counter example for ( n = 0; n < 2; n++ ) @@ -230,6 +243,138 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi return SBD_SAT_SAT; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManSolve2( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp, Vec_Int_t * vSop ) +{ + int nBTLimit = 0; + int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0; + assert( FreeVar < sat_solver_nvars(pSat) ); + assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) ); + pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1 + pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit + Vec_IntClear( vSop ); + while ( 1 ) + { + // find onset minterm + status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return 0; + if ( status == l_False ) + return 1; + assert( status == l_True ); + // remember variable values + //for ( i = 0; i < Vec_IntSize(vValues); i++ ) + // Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) ); + // collect divisor literals + Vec_IntClear( vTemp ); + Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0 + //Vec_IntForEachEntry( vDivSet, iVar, i ) + Vec_IntForEachEntry( vDivVars, iVar, i ) + Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) ); + // check against offset + status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return 0; + if ( status == l_True ) + break; + assert( status == l_False ); + // compute cube and add clause + nFinal = sat_solver_final( pSat, &pFinal ); + Vec_IntClear( vTemp ); + Vec_IntPush( vTemp, Abc_LitNot(pLits[1]) ); // NOT(iNewLit) + for ( i = 0; i < nFinal; i++ ) + { + if ( pFinal[i] == pLits[0] ) + continue; + Vec_IntPush( vTemp, pFinal[i] ); + iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); + //uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar]; + Vec_IntPush( vSop, Abc_Var2Lit( iVar, !Abc_LitIsCompl(pFinal[i]) ) ); + } + //uTruth |= uCube; + Vec_IntPush( vSop, -1 ); + status = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp) ); + assert( status ); + nIter++; + } + assert( status == l_True ); + // store the counter-example + //for ( i = 0; i < Vec_IntSize(vValues); i++ ) + // Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) ); + return 0; +} + +word Sbd_ManSolverSupp( Vec_Int_t * vSop, int * pInds, int * pnVars ) +{ + word Supp = 0; + int i, Entry, nVars = 0; + Vec_IntForEachEntry( vSop, Entry, i ) + { + if ( Entry == -1 ) + continue; + assert( Abc_Lit2Var(Entry) < 64 ); + if ( (Supp >> Abc_Lit2Var(Entry)) & 1 ) + continue; + pInds[Abc_Lit2Var(Entry)] = nVars++; + Supp |= (word)1 << Abc_Lit2Var(Entry); + } + *pnVars = nVars; + return Supp; +} +void Sbd_ManSolverPrint( Vec_Int_t * vSop ) +{ + int v, i, Entry, nVars, pInds[64]; + word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); + char Cube[65] = {'\0'}; + assert( Cube[nVars] == '\0' ); + for ( v = 0; v < nVars; v++ ) + Cube[v] = '-'; + Vec_IntForEachEntry( vSop, Entry, i ) + { + if ( Entry == -1 ) + { + printf( "%s\n", Cube ); + for ( v = 0; v < nVars; v++ ) + Cube[v] = '-'; + continue; + } + Cube[pInds[Abc_Lit2Var(Entry)]] = '1' - (char)Abc_LitIsCompl(Entry); + } +} +void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) +{ + Vec_Int_t * vSop = Vec_IntAlloc( 100 ); + Vec_Int_t * vTemp = Vec_IntAlloc( 100 ); + sat_solver * pSat = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 0 ); + int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int FreeVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); + int Status = Sbd_ManSolve2( pSat, PivotVar, FreeVar, vDivVars, vDivValues, vTemp, vSop ); + printf( "Pivot = %4d. Divs = %4d. ", Pivot, Vec_IntSize(vDivVars) ); + if ( Status == 0 ) + printf( "UNSAT.\n" ); + else + { + int nVars, pInds[64]; + word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); + //Sbd_ManSolverPrint( vSop ); + printf( "SAT with %d vars and %d cubes.\n", nVars, Vec_IntCountEntry(vSop, -1) ); + } + Vec_IntFree( vTemp ); + Vec_IntFree( vSop ); + sat_solver_delete( pSat ); +} + + /**Function************************************************************* Synopsis [Returns a bunch of positive/negative random care minterms.] -- cgit v1.2.3 From 398c4ec92c4e25fa588a6b3bcbd016df91e57771 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 18:08:39 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 158 ++++++++++++++++++++++++++++++++++++++++++-------- src/opt/sbd/sbdInt.h | 1 + src/opt/sbd/sbdLut.c | 108 ++++++++++++++++++++++++++-------- src/opt/sbd/sbdWin.c | 35 +++++++++++ 4 files changed, 254 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 563e6e98..5c5fe35a 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -777,15 +777,15 @@ void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ) } } -void Sbd_ManMatrPrint( word Cover[64], int nCol, int nRows ) +void Sbd_ManMatrPrint( Sbd_Man_t * p, word Cover[], int nCol, int nRows ) { int i, k; for ( i = 0; i <= nCol; i++ ) { printf( "%2d : ", i ); + printf( "%d ", i == nCol ? Vec_IntEntry(p->vLutLevs, p->Pivot) : Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Vec_IntEntry(p->vDivVars, i))) ); for ( k = 0; k < nRows; k++ ) - for ( k = 0; k < nRows; k++ ) - printf( "%d", (int)((Cover[i] >> k) & 1) ); + printf( "%d", (int)((Cover[i] >> k) & 1) ); printf( "\n"); } printf( "\n"); @@ -801,18 +801,18 @@ static inline void Sbd_ManCoverReverseOrder( word Cover[64] ) } } -static inline int Sbd_ManAddCube1( word Cover[64], int nRows, word Cube ) +static inline int Sbd_ManAddCube1( int nRowLimit, word Cover[], int nRows, word Cube ) { int n, m; if ( 0 ) { printf( "Adding cube: " ); - for ( n = 0; n < 64; n++ ) + for ( n = 0; n < nRowLimit; n++ ) printf( "%d", (int)((Cube >> n) & 1) ); printf( "\n" ); } // do not add contained Cube - assert( nRows <= 64 ); + assert( nRows <= nRowLimit ); for ( n = 0; n < nRows; n++ ) if ( (Cover[n] & Cube) == Cover[n] ) // Cube is contained return nRows; @@ -820,7 +820,7 @@ static inline int Sbd_ManAddCube1( word Cover[64], int nRows, word Cube ) for ( n = m = 0; n < nRows; n++ ) if ( (Cover[n] & Cube) != Cube ) // Cover[n] is not contained Cover[m++] = Cover[n]; - if ( m < 64 ) + if ( m < nRowLimit ) Cover[m++] = Cube; for ( n = m; n < nRows; n++ ) Cover[n] = 0; @@ -855,7 +855,7 @@ static inline int Sbd_ManAddCube2( word Cover[2][64], int nRows, word Cube[2] ) return nRows; } -static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[64], int nDivs ) +static inline int Sbd_ManFindCandsSimple( Sbd_Man_t * p, word Cover[], int nDivs ) { int c0, c1, c2, c3; word Target = Cover[nDivs]; @@ -1052,7 +1052,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { Cube = (Cubes[0][1][i] & Cubes[1][0][k]) | (Cubes[0][0][i] & Cubes[1][1][k]); assert( Cube ); - nRows = Sbd_ManAddCube1( Cover, nRows, Cube ); + nRows = Sbd_ManAddCube1( 64, Cover, nRows, Cube ); } Sbd_ManCoverReverseOrder( Cover ); @@ -1072,7 +1072,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) { if ( p->pPars->fVerbose ) - Sbd_ManMatrPrint( Cover, nDivs, nRows ); + Sbd_ManMatrPrint( p, Cover, nDivs, nRows ); clk = Abc_Clock(); if ( !Sbd_ManFindCands( p, Cover, nDivs ) ) @@ -1141,10 +1141,123 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) return RetValue; } -int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, - int nLuts, int nSels, int nVarsDivs[SBD_LUTS_MAX], - int pVarsDivs[SBD_LUTS_MAX][SBD_SIZE_MAX], word Truths[SBD_LUTS_MAX] ) +int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); + abctime clk = Abc_Clock(); + word Onset[64] = {0}, Offset[64] = {0}, Cube; + word CoverRows[256] = {0}, CoverCols[64] = {{0}}; + int nIters, nItersMax = 32; + int i, k, nRows = 0; + + int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int nDivs = Vec_IntSize( p->vDivVars ); + int nConsts = 4; + int RetValue; + + if ( p->pSat ) + sat_solver_delete( p->pSat ); + p->pSat = NULL; + + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + + assert( nConsts <= 8 ); + RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); + if ( RetValue >= 0 ) + { + if ( p->pPars->fVerbose ) + printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); + p->nConsts++; + return RetValue; + } + + // create rows of the table + nRows = 0; + for ( i = 0; i < nConsts; i++ ) + for ( k = 0; k < nConsts; k++ ) + { + Cube = Onset[i] ^ Offset[k]; + assert( Cube ); + nRows = Sbd_ManAddCube1( 256, CoverRows, nRows, Cube ); + } + assert( nRows <= 64 ); + + // create columns of the table + for ( i = 0; i < nRows; i++ ) + for ( k = 0; k <= nDivs; k++ ) + if ( (CoverRows[i] >> k) & 1 ) + Abc_TtXorBit(&CoverCols[k], i); + + // solve the covering problem + for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) + { + if ( p->pPars->fVerbose ) + Sbd_ManMatrPrint( p, CoverCols, nDivs, nRows ); + + clk = Abc_Clock(); + if ( !Sbd_ManFindCands( p, CoverCols, nDivs ) ) + { + if ( p->pPars->fVerbose ) + printf( "Cannot find a feasible cover.\n" ); + //clkEnu += Abc_Clock() - clk; + //clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + //p->timeSat += clkSat; + //p->timeCov += clkAll; + //p->timeEnu += clkEnu; + return 0; + } + //clkEnu += Abc_Clock() - clk; + + if ( p->pPars->fVerbose ) + printf( "Candidate support: " ), + Vec_IntPrint( p->vDivSet ); + + clk = Abc_Clock(); + *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + //clkSat += Abc_Clock() - clk; + + if ( *pTruth == SBD_SAT_UNDEC ) + printf( "Node %d: Undecided.\n", Pivot ); + else if ( *pTruth == SBD_SAT_SAT ) + { + if ( p->pPars->fVerbose ) + { + int i; + printf( "Node %d: SAT.\n", Pivot ); + for ( i = 0; i < nDivs; i++ ) + printf( "%d", Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Vec_IntEntry(p->vDivVars, i))) ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%d", i % 10 ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%c", (Vec_IntEntry(p->vDivValues, i) & 0x4) ? '0' + (Vec_IntEntry(p->vDivValues, i) & 1) : 'x' ); + printf( "\n" ); + for ( i = 0; i < nDivs; i++ ) + printf( "%c", (Vec_IntEntry(p->vDivValues, i) & 0x8) ? '0' + ((Vec_IntEntry(p->vDivValues, i) >> 1) & 1) : 'x' ); + printf( "\n" ); + } + // add row to the covering table + for ( i = 0; i < nDivs; i++ ) + if ( Vec_IntEntry(p->vDivValues, i) == 0xE || Vec_IntEntry(p->vDivValues, i) == 0xD ) + CoverCols[i] |= ((word)1 << nRows); + CoverCols[nDivs] |= ((word)1 << nRows); + nRows++; + } + else + { + if ( p->pPars->fVerbose ) + { + printf( "Node %d: UNSAT. ", Pivot ); + Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); + } + return 1; + } + } return 0; } @@ -1465,7 +1578,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) if ( Sbd_ManMergeCuts( p, Pivot ) ) return; -// if ( Pivot != 13 ) +// if ( Pivot != 70 ) // return; if ( p->pPars->fVerbose ) @@ -1481,7 +1594,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); } - else if ( Sbd_ManExplore( p, Pivot, &Truth ) ) + else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) { Sbd_ManImplement( p, Pivot, Truth ); //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); @@ -1493,26 +1606,23 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 ); - Sbd_Str_t Strs[2] = { - {1, 4, {0, 1, 2, 7}}, - {1, 4, {3, 4, 5, 6}} - }; - - word Truths[SBD_LUTS_MAX]; +// Sbd_Str_t Strs[2] = { {1, 4, {0, 1, 2, 8}}, {1, 4, {3, 4, 5, 6}} }; +// Sbd_Str_t Strs[2] = { {1, 4, {1, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}} }; + Sbd_Str_t Strs[3] = { {1, 4, {8, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}}, {0, 4, {0, 1, 2, 3}} }; Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); int i, RetValue; - for ( i = 0; i < 7; i++ ) + for ( i = 0; i < 6; i++ ) Vec_IntPush( vDivSet, i+1 ); RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - vDivSet, 2, Strs, Truths ); + vDivSet, 3, Strs ); if ( RetValue ) { printf( "Solving succeded.\n" ); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 3646c6b9..5395e148 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -66,6 +66,7 @@ struct Sbd_Str_t_ int fLut; // LUT or SEL int nVarIns; // input count int VarIns[SBD_DIV_MAX]; // input vars + word Res; // result of solving }; //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index 42bb0955..b68ecc26 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "sbdInt.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -46,17 +47,18 @@ int Sbd_ProblemCountParams( int nStrs, Sbd_Str_t * pStr0 ) { Sbd_Str_t * pStr; int nPars = 0; for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) - nPars += (pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns); + nPars += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; return nPars; } // add clauses for the structure -void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) +int Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) { // variable order: inputs, structure outputs, parameters Sbd_Str_t * pStr; int VarOut = nVars; int VarPar = nVars + nStrs; int m, k, n, status, pLits[SBD_SIZE_MAX+2]; +//printf( "Start par = %d. ", VarPar ); for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarOut++ ) { if ( pStr->fLut ) @@ -72,12 +74,14 @@ void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars pLits[pStr->nVarIns] = Abc_Var2Lit( pVars[VarPar], n ); pLits[pStr->nVarIns+1] = Abc_Var2Lit( pVars[VarOut], !n ); status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns + 2 ); - assert( status ); + if ( !status ) + return 0; } } } else { + assert( pStr->nVarIns <= SBD_DIV_MAX ); for ( k = 0; k < pStr->nVarIns; k++, VarPar++ ) { for ( n = 0; n < 2; n++ ) @@ -86,22 +90,32 @@ void Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars pLits[1] = Abc_Var2Lit( pVars[VarOut], n ); pLits[2] = Abc_Var2Lit( pVars[pStr->VarIns[k]], !n ); status = sat_solver_addclause( pSat, pLits, pLits + 3 ); - assert( status ); + if ( !status ) + return 0; } } } } +//printf( "Stop par = %d.\n", VarPar ); + return 1; } void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) { Sbd_Str_t * pStr; int VarPar = nVars + nStrs; - int m, m2, pLits[2], status; + int m, m2, status, pLits[SBD_DIV_MAX]; // make sure selector parameters are mutually exclusive - for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarPar = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns ) + for ( pStr = pStr0; pStr < pStr0 + nStrs; VarPar += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns, pStr++ ) { if ( pStr->fLut ) continue; + // one variable should be selected + assert( pStr->nVarIns <= SBD_DIV_MAX ); + for ( m = 0; m < pStr->nVarIns; m++ ) + pLits[m] = Abc_Var2Lit( pVars[VarPar + m], 0 ); + status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns ); + assert( status ); + // two variables cannot be selected for ( m = 0; m < pStr->nVarIns; m++ ) for ( m2 = m+1; m2 < pStr->nVarIns; m2++ ) { @@ -120,15 +134,44 @@ void Sbd_ProblemPrintSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) { nIters = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns; - printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", pStr-pStr0 ); - for ( m = 0; m < nIters; m++ ) - printf( "%d", Abc_LitIsCompl(Vec_IntEntry(vLits, iLit++)) ); - printf( "\n" ); + printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", (int)(pStr-pStr0) ); + for ( m = 0; m < nIters; m++, iLit++ ) + printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ); + printf( " {" ); + for ( m = 0; m < pStr->nVarIns; m++ ) + printf( " %d", pStr->VarIns[m] ); + printf( " }\n" ); } assert( iLit == Vec_IntSize(vLits) ); } -void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits, word Truths[SBD_LUTS_MAX] ) +void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits ) { + Sbd_Str_t * pStr; + int m, nIters, iLit = 0; + for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ ) + { + pStr->Res = 0; + if ( pStr->fLut ) + { + nIters = 1 << pStr->nVarIns; + for ( m = 0; m < nIters; m++, iLit++ ) + if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) + Abc_TtSetBit( &pStr->Res, m ); + Abc_TtStretch6( &pStr->Res, pStr->nVarIns, 6 ); + } + else + { + nIters = 0; + for ( m = 0; m < pStr->nVarIns; m++, iLit++ ) + if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) + { + pStr->Res = pStr->VarIns[m]; + nIters++; + } + assert( nIters == 1 ); + } + } + assert( iLit == Vec_IntSize(vLits) ); } /**Function************************************************************* @@ -145,38 +188,39 @@ void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0, word Truths[SBD_LUTS_MAX] ) // divisors, structures + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 ) // divisors, structures { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + int fVerbose = 1; Vec_Int_t * vLits = Vec_IntAlloc( 100 ); sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); + int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); int VarCecOut = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots); - int VarCecPar = VarCecOut + 1; - int VarCecFree = VarCecPar + nPars; + int VarCecPar = VarCecOut + nStrs; int VarQbfPar = 0; int VarQbfFree = nPars; int pVarsCec[256]; int pVarsQbf[256]; - int i, iVar, iLit; + int i, iVar, iLit, nIters; int RetValue = 0; - assert( Vec_IntSize(vDivSet) <= SBD_SIZE_MAX ); + assert( Vec_IntSize(vDivSet) <= SBD_DIV_MAX ); assert( nVars + nStrs + nPars <= 256 ); // collect CEC variables Vec_IntForEachEntry( vDivSet, iVar, i ) pVarsCec[i] = iVar; - pVarsCec[nVars] = VarCecOut; - for ( i = 1; i < nStrs; i++ ) - pVarsCec[nVars + i] = VarCecFree++; + for ( i = 0; i < nStrs; i++ ) + pVarsCec[nVars + i] = VarCecOut + i; for ( i = 0; i < nPars; i++ ) pVarsCec[nVars + nStrs + i] = VarCecPar + i; @@ -197,13 +241,24 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_IntClear( vLits ); for ( i = 0; i < nPars; i++ ) Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, 1) ); - while ( 1 ) + for ( nIters = 0; nIters < (1 << nVars); nIters++ ) { // check if these parameters solve the problem int status = sat_solver_solve( pSatCec, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 ); if ( status == l_False ) // solution found break; assert( status == l_True ); +// Vec_IntForEachEntry( vWinObjs, iVar, i ) +// printf( "Node = %4d. SatVar = %4d. Value = %d.\n", iVar, i, sat_solver_var_value(pSatCec, i) ); + + if ( fVerbose ) + { + printf( "Iter %3d : ", nIters ); + for ( i = 0; i < nPars; i++ ) + printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, i)) ); + printf( " " ); + } + Vec_IntClear( vLits ); // create new QBF variables for ( i = 0; i < nVars + nStrs; i++ ) @@ -211,15 +266,20 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, // set their values Vec_IntForEachEntry( vDivSet, iVar, i ) { - iLit = Abc_Var2Lit( pVarsQbf[i], sat_solver_var_value(pSatCec, iVar) ); + iLit = Abc_Var2Lit( pVarsQbf[i], !sat_solver_var_value(pSatCec, iVar) ); status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); assert( status ); + if ( fVerbose ) + printf( "%d", sat_solver_var_value(pSatCec, iVar) ); } iLit = Abc_Var2Lit( pVarsQbf[nVars], sat_solver_var_value(pSatCec, VarCecOut) ); status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 ); assert( status ); + if ( fVerbose ) + printf( " %d\n", !sat_solver_var_value(pSatCec, VarCecOut) ); // add clauses to the QBF problem - Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ); + if ( !Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ) ) + break; // solution does not exist // check if solution still exists status = sat_solver_solve( pSatQbf, NULL, NULL, 0, 0, 0, 0 ); if ( status == l_False ) // solution does not exist @@ -228,12 +288,12 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, // find the new values of parameters assert( Vec_IntSize(vLits) == 0 ); for ( i = 0; i < nPars; i++ ) - Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); + Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, !sat_solver_var_value(pSatQbf, VarQbfPar + i)) ); } if ( Vec_IntSize(vLits) > 0 ) { Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); - Sbd_ProblemCollectSolution( nStrs, pStr0, vLits, Truths ); + Sbd_ProblemCollectSolution( nStrs, pStr0, vLits ); RetValue = 1; } else diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index fc79caa7..d5b7dd9d 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -141,6 +141,17 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi } assert( sat_solver_nvars(pSat) == nVars + nAddVars ); } + else if ( fQbf ) + { + int n, pLits[2]; + for ( n = 0; n < 2; n++ ) + { + pLits[0] = Abc_Var2Lit( PivotVar, n ); + pLits[1] = Abc_Var2Lit( LastVar, n ); + RetValue = sat_solver_addclause( pSat, pLits, pLits + 2 ); + assert( RetValue ); + } + } // finalize RetValue = sat_solver_simplify( pSat ); if ( RetValue == 0 ) @@ -418,6 +429,30 @@ int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, return -1; } +int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ) +{ + int nBTLimit = 0; + int n, i, k, status, iLit, iVar; + word * pPats[2] = {pOnset, pOffset}; + assert( Vec_IntSize(vDivVars) < 64 ); + for ( n = 0; n < 2; n++ ) + for ( i = 0; i < nConsts; i++ ) + { + sat_solver_random_polarity( pSat ); + iLit = Abc_Var2Lit( PivotVar, n ); + status = sat_solver_solve( pSat, &iLit, &iLit + 1, nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) + return -2; + if ( status == l_False ) + return n; + pPats[n][i] = ((word)!n) << Vec_IntSize(vDivVars); + Vec_IntForEachEntry( vDivVars, iVar, k ) + if ( sat_solver_var_value(pSat, iVar) ) + Abc_TtXorBit(&pPats[n][i], k); + } + return -1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// -- cgit v1.2.3 From fcd3133a9f2817893aa60d1ec2d1b94a1f5a7b5a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 18:15:05 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 5 +++-- src/opt/sbd/sbdLut.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 5c5fe35a..15874dc6 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -75,6 +75,8 @@ static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( static inline word * Sbd_ObjSim2( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[2], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim3( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[3], p->pPars->nWords * i ); } +extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -975,7 +977,6 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) int fVerbose = 0; abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); int nIters, nItersMax = 32; - extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; int i, k, n, Node, Index, nCubes[2] = {0}, nRows = 0, nRowsOld; @@ -1147,7 +1148,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); word Onset[64] = {0}, Offset[64] = {0}, Cube; - word CoverRows[256] = {0}, CoverCols[64] = {{0}}; + word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; int i, k, nRows = 0; diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index b68ecc26..b924a33b 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -197,7 +197,7 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); - int PivotVar = Vec_IntEntry(vObj2Var, Pivot); + //int PivotVar = Vec_IntEntry(vObj2Var, Pivot); int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); -- cgit v1.2.3 From 3581c94fec6e3fabe36591cd57a732d3f58a29ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 27 Dec 2016 21:08:52 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCut.c | 617 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 618 insertions(+) create mode 100644 src/opt/sbd/sbdCut.c (limited to 'src') diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index 0320d381..3bdc20b3 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -1,6 +1,7 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ + src/opt/sbd/sbdCut.c \ src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c new file mode 100644 index 00000000..cabc301c --- /dev/null +++ b/src/opt/sbd/sbdCut.c @@ -0,0 +1,617 @@ +/**CFile**************************************************************** + + FileName [sbdCut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SBD_MAX_CUTSIZE 8 +#define SBD_MAX_CUTNUM 64 +#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) + +#define SBD_CUT_NO_LEAF 255 + +typedef struct Sbd_Cut_t_ Sbd_Cut_t; +struct Sbd_Cut_t_ +{ + word Sign; // signature + int iFunc; // functionality + unsigned Cost : 24; // misc cut cost + unsigned nLeaves : 8; // the number of leaves + int pLeaves[SBD_MAX_CUTSIZE]; // leaves +}; + +typedef struct Sbd_Sto_t_ Sbd_Sto_t; +struct Sbd_Sto_t_ +{ + int nLutSize; + int nCutNum; + int fCutMin; + int fVerbose; + Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vDelays; // delays for each node + Vec_Wec_t * vCuts; // cuts for each node + Vec_Mem_t * vTtMem; // truth tables + Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts + Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers + abctime clkStart; // starting time + double CutCount[4]; // cut counters +}; + +static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } + +#define Sbd_ForEachCut( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 2 ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, int nLutSize, int nCutNum, int fCutMin, int fVerbose ) +{ + Sbd_Sto_t * p; + assert( nLutSize > 1 && nLutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Sto_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutNum = nCutNum; + p->fCutMin = fCutMin; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); + p->vTtMem = fCutMin ? Vec_MemAllocForTT( nLutSize, 0 ) : NULL; + return p; +} +void Sbd_StoFree( Sbd_Sto_t * p ) +{ + Vec_IntFree( p->vDelays ); + Vec_WecFree( p->vCuts ); + if ( p->fCutMin ) + Vec_MemHashFree( p->vTtMem ); + if ( p->fCutMin ) + Vec_MemFree( p->vTtMem ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Check correctness of cuts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Sbd_CutGetSign( Sbd_Cut_t * pCut ) +{ + word Sign = 0; int i; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Sign |= ((word)1) << (pCut->pLeaves[i] & 0x3F); + return Sign; +} +static inline int Sbd_CutCheck( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase +{ + int nSizeB = pBase->nLeaves; + int nSizeC = pCut->nLeaves; + int i, * pB = pBase->pLeaves; + int k, * pC = pCut->pLeaves; + for ( i = 0; i < nSizeC; i++ ) + { + for ( k = 0; k < nSizeB; k++ ) + if ( pC[i] == pB[k] ) + break; + if ( k == nSizeB ) + return 0; + } + return 1; +} +static inline int Sbd_CutSetCheckArray( Sbd_Cut_t ** ppCuts, int nCuts ) +{ + Sbd_Cut_t * pCut0, * pCut1; + int i, k, m, n, Value; + assert( nCuts > 0 ); + for ( i = 0; i < nCuts; i++ ) + { + pCut0 = ppCuts[i]; + assert( pCut0->nLeaves <= SBD_MAX_CUTSIZE ); + assert( pCut0->Sign == Sbd_CutGetSign(pCut0) ); + // check duplicates + for ( m = 0; m < (int)pCut0->nLeaves; m++ ) + for ( n = m + 1; n < (int)pCut0->nLeaves; n++ ) + assert( pCut0->pLeaves[m] < pCut0->pLeaves[n] ); + // check pairs + for ( k = 0; k < nCuts; k++ ) + { + pCut1 = ppCuts[k]; + if ( pCut0 == pCut1 ) + continue; + // check containments + Value = Sbd_CutCheck( pCut0, pCut1 ); + assert( Value == 0 ); + } + } + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +{ + int nSize0 = pCut0->nLeaves; + int nSize1 = pCut1->nLeaves; + int i, * pC0 = pCut0->pLeaves; + int k, * pC1 = pCut1->pLeaves; + int c, * pC = pCut->pLeaves; + // the case of the largest cut sizes + if ( nSize0 == nLutSize && nSize1 == nLutSize ) + { + for ( i = 0; i < nSize0; i++ ) + { + if ( pC0[i] != pC1[i] ) return 0; + pC[i] = pC0[i]; + } + pCut->nLeaves = nLutSize; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; + } + // compare two cuts with different numbers + i = k = c = 0; + if ( nSize0 == 0 ) goto FlushCut1; + if ( nSize1 == 0 ) goto FlushCut0; + while ( 1 ) + { + if ( c == nLutSize ) return 0; + if ( pC0[i] < pC1[k] ) + { + pC[c++] = pC0[i++]; + if ( i >= nSize0 ) goto FlushCut1; + } + else if ( pC0[i] > pC1[k] ) + { + pC[c++] = pC1[k++]; + if ( k >= nSize1 ) goto FlushCut0; + } + else + { + pC[c++] = pC0[i++]; k++; + if ( i >= nSize0 ) goto FlushCut1; + if ( k >= nSize1 ) goto FlushCut0; + } + } + +FlushCut0: + if ( c + nSize0 > nLutSize + i ) return 0; + while ( i < nSize0 ) + pC[c++] = pC0[i++]; + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; + +FlushCut1: + if ( c + nSize1 > nLutSize + k ) return 0; + while ( k < nSize1 ) + pC[c++] = pC1[k++]; + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; +} +static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +{ + int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves; + int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves; + int xMin, c = 0, * pC = pCut->pLeaves; + while ( 1 ) + { + x0 = (i0 == nSize0) ? ABC_INFINITY : pC0[i0]; + x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1]; + xMin = Abc_MinInt(x0, x1); + if ( xMin == ABC_INFINITY ) break; + if ( c == nLutSize ) return 0; + pC[c++] = xMin; + if (x0 == xMin) i0++; + if (x1 == xMin) i1++; + } + pCut->nLeaves = c; + pCut->iFunc = -1; + pCut->Sign = pCut0->Sign | pCut1->Sign; + return 1; +} +static inline int Sbd_CutSetCutIsContainedOrder( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase +{ + int i, nSizeB = pBase->nLeaves; + int k, nSizeC = pCut->nLeaves; + if ( nSizeB == nSizeC ) + { + for ( i = 0; i < nSizeB; i++ ) + if ( pBase->pLeaves[i] != pCut->pLeaves[i] ) + return 0; + return 1; + } + assert( nSizeB > nSizeC ); + if ( nSizeC == 0 ) + return 1; + for ( i = k = 0; i < nSizeB; i++ ) + { + if ( pBase->pLeaves[i] > pCut->pLeaves[k] ) + return 0; + if ( pBase->pLeaves[i] == pCut->pLeaves[k] ) + { + if ( ++k == nSizeC ) + return 1; + } + } + return 0; +} +static inline int Sbd_CutSetLastCutIsContained( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = 0; i < nCuts; i++ ) + if ( pCuts[i]->nLeaves <= pCuts[nCuts]->nLeaves && (pCuts[i]->Sign & pCuts[nCuts]->Sign) == pCuts[i]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[nCuts], pCuts[i]) ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) +{ + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + return 0; +} +static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, k, fChanges = 0; + for ( i = 0; i < nCuts; i++ ) + if ( pCuts[nCuts]->nLeaves < pCuts[i]->nLeaves && (pCuts[nCuts]->Sign & pCuts[i]->Sign) == pCuts[nCuts]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[i], pCuts[nCuts]) ) + pCuts[i]->nLeaves = SBD_CUT_NO_LEAF, fChanges = 1; + if ( !fChanges ) + return nCuts; + for ( i = k = 0; i <= nCuts; i++ ) + { + if ( pCuts[i]->nLeaves == SBD_CUT_NO_LEAF ) + continue; + if ( k < i ) + ABC_SWAP( Sbd_Cut_t *, pCuts[k], pCuts[i] ); + k++; + } + return k - 1; +} +static inline void Sbd_CutSetSortByCost( Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = nCuts; i > 0; i-- ) + { + if ( Sbd_CutCompare(pCuts[i - 1], pCuts[i]) < 0 )//!= 1 ) + return; + ABC_SWAP( Sbd_Cut_t *, pCuts[i - 1], pCuts[i] ); + } +} +static inline int Sbd_CutSetAddCut( Sbd_Cut_t ** pCuts, int nCuts, int nCutNum ) +{ + if ( nCuts == 0 ) + return 1; + nCuts = Sbd_CutSetLastCutContains(pCuts, nCuts); + assert( nCuts >= 0 ); + Sbd_CutSetSortByCost( pCuts, nCuts ); + // add new cut if there is room + return Abc_MinInt( nCuts + 1, nCutNum - 1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutComputeTruth6( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) +{ + int nOldSupp = pCutR->nLeaves, truthId, fCompl; word t; + word t0 = *Sbd_CutTruth(p, pCut0); + word t1 = *Sbd_CutTruth(p, pCut1); + if ( Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ) t0 = ~t0; + if ( Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ) t1 = ~t1; + t0 = Abc_Tt6Expand( t0, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + t1 = Abc_Tt6Expand( t1, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + t = fIsXor ? t0 ^ t1 : t0 & t1; + if ( (fCompl = (int)(t & 1)) ) t = ~t; + pCutR->nLeaves = Abc_Tt6MinBase( &t, pCutR->pLeaves, pCutR->nLeaves ); + assert( (int)(t & 1) == 0 ); + truthId = Vec_MemHashInsert(p->vTtMem, &t); + pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); + assert( (int)pCutR->nLeaves <= nOldSupp ); + return (int)pCutR->nLeaves < nOldSupp; +} +static inline int Sbd_CutComputeTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) +{ + if ( p->nLutSize <= 6 ) + return Sbd_CutComputeTruth6( p, pCut0, pCut1, fCompl0, fCompl1, pCutR, fIsXor ); + { + word uTruth[SBD_MAX_TT_WORDS], uTruth0[SBD_MAX_TT_WORDS], uTruth1[SBD_MAX_TT_WORDS]; + int nOldSupp = pCutR->nLeaves, truthId; + int nLutSize = p->nLutSize, fCompl; + int nWords = Abc_Truth6WordNum(nLutSize); + word * pTruth0 = Sbd_CutTruth(p, pCut0); + word * pTruth1 = Sbd_CutTruth(p, pCut1); + Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ); + Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ); + Abc_TtExpand( uTruth0, nLutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth1, nLutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + if ( fIsXor ) + Abc_TtXor( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] ^ uTruth1[0]) & 1)) ); + else + Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] & uTruth1[0]) & 1)) ); + pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nLutSize ); + assert( (uTruth[0] & 1) == 0 ); +//Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" ); + truthId = Vec_MemHashInsert(p->vTtMem, uTruth); + pCutR->iFunc = Abc_Var2Lit( truthId, fCompl ); + assert( (int)pCutR->nLeaves <= nOldSupp ); + return (int)pCutR->nLeaves < nOldSupp; + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_CutCountBits( word i ) +{ + i = i - ((i >> 1) & 0x5555555555555555); + i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333); + i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); + return (i*(0x0101010101010101))>>56; +} +static inline void Sbd_CutPrint( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); + printf( "%d {", pCut->nLeaves ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( " %*d", nDigits, pCut->pLeaves[i] ); + for ( ; i < (int)p->nLutSize; i++ ) + printf( " %*s", nDigits, " " ); + printf( " } Cost = %4d\n", pCut->Cost ); +} +static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vDelays, pCut->pLeaves[i] ); + return Cost; +} +static inline void Sbd_CutAddUnitCut( Sbd_Sto_t * p, int iObj ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + if ( Vec_IntSize(vThis) == 0 ) + Vec_IntPush( vThis, 1 ); + else + Vec_IntAddToEntry( vThis, 0, 1 ); + Vec_IntPush( vThis, 1 ); + Vec_IntPush( vThis, iObj ); + Vec_IntPush( vThis, 2 ); +} +static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + int i, v, * pCut, * pList = Vec_IntArray( vThis ); + Sbd_ForEachCut( pList, pCut, i ) + { + Sbd_Cut_t * pCutTemp = &p->pCuts[Index][i]; + pCutTemp->nLeaves = pCut[0]; + for ( v = 1; v <= pCut[0]; v++ ) + pCutTemp->pLeaves[v-1] = pCut[v]; + pCutTemp->iFunc = pCut[pCut[0]+1]; + pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); + pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); + } + return pList[0]; +} +static inline void Sbd_StoInitResult( Sbd_Sto_t * p ) +{ + int i; + for ( i = 0; i < SBD_MAX_CUTNUM; i++ ) + p->ppCuts[i] = &p->pCuts[2][i]; +} +static inline void Sbd_StoStoreResult( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, v; + Vec_Int_t * vList = Vec_WecEntry( p->vCuts, iObj ); + Vec_IntPush( vList, nCuts ); + for ( i = 0; i < nCuts; i++ ) + { + Vec_IntPush( vList, pCuts[i]->nLeaves ); + for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) + Vec_IntPush( vList, pCuts[i]->pLeaves[v] ); + Vec_IntPush( vList, pCuts[i]->iFunc ); + } +} +static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i, v, Delay, DelayMin = ABC_INFINITY; + assert( nCuts > 0 ); + for ( i = 0; i < nCuts; i++ ) + { + if ( (int)pCuts[i]->nLeaves > p->nLutSize ) + continue; + Delay = 0; + for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) + Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vDelays, pCuts[i]->pLeaves[v]) ); + DelayMin = Abc_MinInt( DelayMin, Delay ); + } + assert( DelayMin < ABC_INFINITY ); + Vec_IntWriteEntry( p->vDelays, iObj, (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin ); +} +void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + int fIsXor = Gia_ObjIsXor(pObj); + int nLutSize = p->nLutSize; + int nCutNum = p->nCutNum; + int fComp0 = Gia_ObjFaninC0(pObj); + int fComp1 = Gia_ObjFaninC1(pObj); + int nCuts0 = Sbd_StoPrepareSet( p, Gia_ObjFaninId0(pObj, iObj), 0 ); + int nCuts1 = Sbd_StoPrepareSet( p, Gia_ObjFaninId1(pObj, iObj), 1 ); + int i, k, nCutsR = 0; + Sbd_Cut_t * pCut0, * pCut1, ** pCutsR = p->ppCuts; + assert( !Gia_ObjIsBuf(pObj) ); + assert( !Gia_ObjIsMux(p->pGia, pObj) ); + Sbd_StoInitResult( p ); + p->CutCount[0] += nCuts0 * nCuts1; + for ( i = 0, pCut0 = p->pCuts[0]; i < nCuts0; i++, pCut0++ ) + for ( k = 0, pCut1 = p->pCuts[1]; k < nCuts1; k++, pCut1++ ) + { + if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nLutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nLutSize ) + continue; + p->CutCount[1]++; + if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nLutSize) ) + continue; + if ( Sbd_CutSetLastCutIsContained(pCutsR, nCutsR) ) + continue; + p->CutCount[2]++; + if ( p->fCutMin && Sbd_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) ) + pCutsR[nCutsR]->Sign = Sbd_CutGetSign(pCutsR[nCutsR]); + pCutsR[nCutsR]->Cost = Sbd_CutCost( p, pCutsR[nCutsR] ); + nCutsR = Sbd_CutSetAddCut( pCutsR, nCutsR, nCutNum ); + } + Sbd_StoComputeDelay( p, iObj, pCutsR, nCutsR ); + p->CutCount[3] += nCutsR; + // debug printout + if ( 0 ) + { + printf( "*** Obj = %d Delay = %d\n", iObj, Vec_IntEntry(p->vDelays, iObj) ); + for ( i = 0; i < nCutsR; i++ ) + Sbd_CutPrint( p, pCutsR[i] ); + printf( "\n" ); + } + // verify + assert( nCutsR > 0 && nCutsR < nCutNum ); + assert( Sbd_CutSetCheckArray(pCutsR, nCutsR) ); + // store the cutset + Sbd_StoStoreResult( p, iObj, pCutsR, nCutsR ); + if ( nCutsR > 1 || pCutsR[0]->nLeaves > 1 ) + Sbd_CutAddUnitCut( p, iObj ); +} +int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) +{ + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, 0 ); + Vec_WecPushLevel( p->vCuts ); + Sbd_StoMergeCuts( p, iObj ); + return Vec_IntEntry( p->vDelays, iObj ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbd_StoComputeCuts( Sbd_Sto_t * p ) +{ + Gia_Obj_t * pObj; + int i, iObj; + Gia_ManForEachCiId( p->pGia, iObj, i ) + Sbd_CutAddUnitCut( p, iObj ); + Gia_ManForEachAnd( p->pGia, pObj, iObj ) + Sbd_StoMergeCuts( p, iObj ); + if ( !p->fVerbose ) + return; + printf( "CutPair = %.0f ", p->CutCount[0] ); + printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); + printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); + printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); + printf( "\n" ); +} +void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) +{ + Sbd_Sto_t * p = Sbd_StoAlloc( pGia, 8, 32, 1, 1 ); + Sbd_StoComputeCuts( p ); + Sbd_StoFree( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3 From 1f45cca621ef5b76c5a7e8b3415530dc8182cdca Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 28 Dec 2016 09:43:28 +0700 Subject: C++ compatibility fix. --- src/proof/acec/acecSt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/proof/acec/acecSt.c b/src/proof/acec/acecSt.c index 63aa8131..d97dadc9 100644 --- a/src/proof/acec/acecSt.c +++ b/src/proof/acec/acecSt.c @@ -21,6 +21,8 @@ #include "acecInt.h" #include "misc/vec/vecWec.h" #include "misc/extra/extra.h" +#include "aig/aig/aig.h" +#include "opt/dar/dar.h" ABC_NAMESPACE_IMPL_START -- cgit v1.2.3 From fdd8404bfc47ae385b7a3684113e8a76806eba79 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 28 Dec 2016 12:34:53 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCut.c | 335 +++++++++++++++++++++++++++++++++++---------------- src/opt/sbd/sbdInt.h | 11 +- 2 files changed, 239 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index cabc301c..154df914 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -28,36 +28,45 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// #define SBD_MAX_CUTSIZE 8 -#define SBD_MAX_CUTNUM 64 +#define SBD_MAX_CUTNUM 1001 #define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) -#define SBD_CUT_NO_LEAF 255 +#define SBD_CUT_NO_LEAF 0xF typedef struct Sbd_Cut_t_ Sbd_Cut_t; struct Sbd_Cut_t_ { word Sign; // signature int iFunc; // functionality - unsigned Cost : 24; // misc cut cost - unsigned nLeaves : 8; // the number of leaves + int Cost; // cut cost + int CostLev; // cut cost + unsigned fSpec : 1; // special cut + unsigned nTreeLeaves : 27; // cut cost + unsigned nLeaves : 4; // the number of leaves int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; -typedef struct Sbd_Sto_t_ Sbd_Sto_t; struct Sbd_Sto_t_ { int nLutSize; + int nCutSize; int nCutNum; int fCutMin; int fVerbose; Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vMirrors; // mirrors for each node Vec_Int_t * vDelays; // delays for each node + Vec_Int_t * vLevels; // levels for each node + Vec_Int_t * vRefs; // refs for each node Vec_Wec_t * vCuts; // cuts for each node Vec_Mem_t * vTtMem; // truth tables Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers abctime clkStart; // starting time double CutCount[4]; // cut counters + int nCutsSpec; // special cuts + int nCutsOver; // overflow cuts + int DelayMin; // minimum delay }; static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } @@ -68,45 +77,6 @@ static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Ve /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, int nLutSize, int nCutNum, int fCutMin, int fVerbose ) -{ - Sbd_Sto_t * p; - assert( nLutSize > 1 && nLutSize <= SBD_MAX_CUTSIZE ); - assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); - p = ABC_CALLOC( Sbd_Sto_t, 1 ); - p->clkStart = Abc_Clock(); - p->nLutSize = nLutSize; - p->nCutNum = nCutNum; - p->fCutMin = fCutMin; - p->fVerbose = fVerbose; - p->pGia = pGia; - p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); - p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); - p->vTtMem = fCutMin ? Vec_MemAllocForTT( nLutSize, 0 ) : NULL; - return p; -} -void Sbd_StoFree( Sbd_Sto_t * p ) -{ - Vec_IntFree( p->vDelays ); - Vec_WecFree( p->vCuts ); - if ( p->fCutMin ) - Vec_MemHashFree( p->vTtMem ); - if ( p->fCutMin ) - Vec_MemFree( p->vTtMem ); - ABC_FREE( p ); -} - /**Function************************************************************* Synopsis [Check correctness of cuts.] @@ -181,7 +151,7 @@ static inline int Sbd_CutSetCheckArray( Sbd_Cut_t ** ppCuts, int nCuts ) SeeAlso [] ***********************************************************************/ -static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize ) { int nSize0 = pCut0->nLeaves; int nSize1 = pCut1->nLeaves; @@ -189,14 +159,14 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C int k, * pC1 = pCut1->pLeaves; int c, * pC = pCut->pLeaves; // the case of the largest cut sizes - if ( nSize0 == nLutSize && nSize1 == nLutSize ) + if ( nSize0 == nCutSize && nSize1 == nCutSize ) { for ( i = 0; i < nSize0; i++ ) { if ( pC0[i] != pC1[i] ) return 0; pC[i] = pC0[i]; } - pCut->nLeaves = nLutSize; + pCut->nLeaves = nCutSize; pCut->iFunc = -1; pCut->Sign = pCut0->Sign | pCut1->Sign; return 1; @@ -207,7 +177,7 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C if ( nSize1 == 0 ) goto FlushCut0; while ( 1 ) { - if ( c == nLutSize ) return 0; + if ( c == nCutSize ) return 0; if ( pC0[i] < pC1[k] ) { pC[c++] = pC0[i++]; @@ -227,7 +197,7 @@ static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_C } FlushCut0: - if ( c + nSize0 > nLutSize + i ) return 0; + if ( c + nSize0 > nCutSize + i ) return 0; while ( i < nSize0 ) pC[c++] = pC0[i++]; pCut->nLeaves = c; @@ -236,7 +206,7 @@ FlushCut0: return 1; FlushCut1: - if ( c + nSize1 > nLutSize + k ) return 0; + if ( c + nSize1 > nCutSize + k ) return 0; while ( k < nSize1 ) pC[c++] = pC1[k++]; pCut->nLeaves = c; @@ -244,7 +214,7 @@ FlushCut1: pCut->Sign = pCut0->Sign | pCut1->Sign; return 1; } -static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nLutSize ) +static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize ) { int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves; int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves; @@ -255,7 +225,7 @@ static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_ x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1]; xMin = Abc_MinInt(x0, x1); if ( xMin == ABC_INFINITY ) break; - if ( c == nLutSize ) return 0; + if ( c == nCutSize ) return 0; pC[c++] = xMin; if (x0 == xMin) i0++; if (x1 == xMin) i1++; @@ -313,10 +283,30 @@ static inline int Sbd_CutSetLastCutIsContained( Sbd_Cut_t ** pCuts, int nCuts ) ***********************************************************************/ static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) { - if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; - if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; - if ( pCut0->Cost < pCut1->Cost ) return -1; - if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->nLeaves <= 4 && pCut1->nLeaves <= 4 ) + { + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + } + else if ( pCut0->nLeaves <= 4 ) + return -1; + else if ( pCut1->nLeaves <= 4 ) + return 1; + else + { + if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1; + if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + } return 0; } static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) @@ -389,24 +379,24 @@ static inline int Sbd_CutComputeTruth6( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cu } static inline int Sbd_CutComputeTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor ) { - if ( p->nLutSize <= 6 ) + if ( p->nCutSize <= 6 ) return Sbd_CutComputeTruth6( p, pCut0, pCut1, fCompl0, fCompl1, pCutR, fIsXor ); { word uTruth[SBD_MAX_TT_WORDS], uTruth0[SBD_MAX_TT_WORDS], uTruth1[SBD_MAX_TT_WORDS]; int nOldSupp = pCutR->nLeaves, truthId; - int nLutSize = p->nLutSize, fCompl; - int nWords = Abc_Truth6WordNum(nLutSize); + int nCutSize = p->nCutSize, fCompl; + int nWords = Abc_Truth6WordNum(nCutSize); word * pTruth0 = Sbd_CutTruth(p, pCut0); word * pTruth1 = Sbd_CutTruth(p, pCut1); Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ); Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ); - Abc_TtExpand( uTruth0, nLutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); - Abc_TtExpand( uTruth1, nLutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth0, nCutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); + Abc_TtExpand( uTruth1, nCutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); if ( fIsXor ) Abc_TtXor( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] ^ uTruth1[0]) & 1)) ); else Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] & uTruth1[0]) & 1)) ); - pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nLutSize ); + pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nCutSize ); assert( (uTruth[0] & 1) == 0 ); //Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" ); truthId = Vec_MemHashInsert(p->vTtMem, uTruth); @@ -434,15 +424,12 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline void Sbd_CutPrint( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +static inline int Sbd_CutIsSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { - int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); - printf( "%d {", pCut->nLeaves ); + int i, Delay = Vec_IntEntry(p->vDelays, iObj), DelayMax = -ABC_INFINITY; for ( i = 0; i < (int)pCut->nLeaves; i++ ) - printf( " %*d", nDigits, pCut->pLeaves[i] ); - for ( ; i < (int)p->nLutSize; i++ ) - printf( " %*s", nDigits, " " ); - printf( " } Cost = %4d\n", pCut->Cost ); + DelayMax = Abc_MaxInt( DelayMax, Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); + return DelayMax < -1; } static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { @@ -451,7 +438,21 @@ static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) Cost += Vec_IntEntry( p->vDelays, pCut->pLeaves[i] ); return Cost; } -static inline void Sbd_CutAddUnitCut( Sbd_Sto_t * p, int iObj ) +static inline int Sbd_CutCostLev( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vLevels, pCut->pLeaves[i] ); + return Cost; +} +static inline int Sbd_CutTreeLeaves( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) +{ + int i, Cost = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1; + return Cost; +} +static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); if ( Vec_IntSize(vThis) == 0 ) @@ -474,7 +475,10 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->pLeaves[v-1] = pCut[v]; pCutTemp->iFunc = pCut[pCut[0]+1]; pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); + pCutTemp->fSpec = Sbd_CutIsSpec( p, iObj, pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); + pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); + pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); } return pList[0]; } @@ -511,18 +515,48 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC DelayMin = Abc_MinInt( DelayMin, Delay ); } assert( DelayMin < ABC_INFINITY ); - Vec_IntWriteEntry( p->vDelays, iObj, (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin ); + DelayMin = (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin; + Vec_IntWriteEntry( p->vDelays, iObj, DelayMin ); + p->DelayMin = Abc_MaxInt( p->DelayMin, DelayMin ); +} +static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts ) +{ + int i; + for ( i = 0; i < nCuts; i++ ) + { + pCuts[i]->fSpec = Sbd_CutIsSpec( p, iObj, pCuts[i] ); + p->nCutsSpec += pCuts[i]->fSpec; + } +} +static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); + int Delay = Vec_IntEntry(p->vDelays, iObj); + printf( "%d {", pCut->nLeaves ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( " %*d", nDigits, pCut->pLeaves[i] ); + for ( ; i < (int)p->nCutSize; i++ ) + printf( " %*s", nDigits, " " ); + printf( " } Cost = %4d CostLev = %4d Tree = %2d ", pCut->Cost, pCut->CostLev, pCut->nTreeLeaves ); + printf( "%c ", pCut->fSpec ? '*' : ' ' ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); + printf( "\n" ); } void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) { Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); int fIsXor = Gia_ObjIsXor(pObj); - int nLutSize = p->nLutSize; + int nCutSize = p->nCutSize; int nCutNum = p->nCutNum; - int fComp0 = Gia_ObjFaninC0(pObj); - int fComp1 = Gia_ObjFaninC1(pObj); - int nCuts0 = Sbd_StoPrepareSet( p, Gia_ObjFaninId0(pObj, iObj), 0 ); - int nCuts1 = Sbd_StoPrepareSet( p, Gia_ObjFaninId1(pObj, iObj), 1 ); + int Lit0m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ) : -1; + int Lit1m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ) : -1; + int fComp0 = Gia_ObjFaninC0(pObj) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m)); + int fComp1 = Gia_ObjFaninC1(pObj) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m)); + int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + int nCuts0 = Sbd_StoPrepareSet( p, Fan0, 0 ); + int nCuts1 = Sbd_StoPrepareSet( p, Fan1, 1 ); int i, k, nCutsR = 0; Sbd_Cut_t * pCut0, * pCut1, ** pCutsR = p->ppCuts; assert( !Gia_ObjIsBuf(pObj) ); @@ -532,10 +566,10 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) for ( i = 0, pCut0 = p->pCuts[0]; i < nCuts0; i++, pCut0++ ) for ( k = 0, pCut1 = p->pCuts[1]; k < nCuts1; k++, pCut1++ ) { - if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nLutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nLutSize ) + if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nCutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nCutSize ) continue; p->CutCount[1]++; - if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nLutSize) ) + if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nCutSize) ) continue; if ( Sbd_CutSetLastCutIsContained(pCutsR, nCutsR) ) continue; @@ -543,16 +577,21 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) if ( p->fCutMin && Sbd_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) ) pCutsR[nCutsR]->Sign = Sbd_CutGetSign(pCutsR[nCutsR]); pCutsR[nCutsR]->Cost = Sbd_CutCost( p, pCutsR[nCutsR] ); + pCutsR[nCutsR]->CostLev = Sbd_CutCostLev( p, pCutsR[nCutsR] ); + pCutsR[nCutsR]->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutsR[nCutsR] ); nCutsR = Sbd_CutSetAddCut( pCutsR, nCutsR, nCutNum ); } Sbd_StoComputeDelay( p, iObj, pCutsR, nCutsR ); + Sbd_StoComputeSpec( p, iObj, pCutsR, nCutsR ); p->CutCount[3] += nCutsR; + p->nCutsOver += nCutsR == nCutNum-1; // debug printout if ( 0 ) { - printf( "*** Obj = %d Delay = %d\n", iObj, Vec_IntEntry(p->vDelays, iObj) ); + printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) - Sbd_CutPrint( p, pCutsR[i] ); + if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->fSpec ) + Sbd_CutPrint( p, iObj, pCutsR[i] ); printf( "\n" ); } // verify @@ -561,21 +600,12 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) // store the cutset Sbd_StoStoreResult( p, iObj, pCutsR, nCutsR ); if ( nCutsR > 1 || pCutsR[0]->nLeaves > 1 ) - Sbd_CutAddUnitCut( p, iObj ); -} -int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) -{ - assert( iObj == Vec_IntSize(p->vDelays) ); - assert( iObj == Vec_WecSize(p->vCuts) ); - Vec_IntPush( p->vDelays, 0 ); - Vec_WecPushLevel( p->vCuts ); - Sbd_StoMergeCuts( p, iObj ); - return Vec_IntEntry( p->vDelays, iObj ); + Sbd_CutAddUnit( p, iObj ); } /**Function************************************************************* - Synopsis [] + Synopsis [Incremental cut computation.] Description [] @@ -584,30 +614,123 @@ int Sbd_StoMergeCutsPlus( Sbd_Sto_t * p, int iObj ) SeeAlso [] ***********************************************************************/ -void Sbd_StoComputeCuts( Sbd_Sto_t * p ) +Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ) { - Gia_Obj_t * pObj; - int i, iObj; - Gia_ManForEachCiId( p->pGia, iObj, i ) - Sbd_CutAddUnitCut( p, iObj ); - Gia_ManForEachAnd( p->pGia, pObj, iObj ) - Sbd_StoMergeCuts( p, iObj ); - if ( !p->fVerbose ) + Sbd_Sto_t * p; + assert( nLutSize <= nCutSize ); + assert( nCutSize < SBD_CUT_NO_LEAF ); + assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Sto_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutSize = nCutSize; + p->nCutNum = nCutNum; + p->fCutMin = fCutMin; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vMirrors = vMirrors; + p->vDelays = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vLevels = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vRefs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecAlloc( Gia_ManObjNum(pGia) ); + p->vTtMem = fCutMin ? Vec_MemAllocForTT( nCutSize, 0 ) : NULL; + return p; +} +void Sbd_StoFree( Sbd_Sto_t * p ) +{ + Vec_IntFree( p->vDelays ); + Vec_IntFree( p->vLevels ); + Vec_IntFree( p->vRefs ); + Vec_WecFree( p->vCuts ); + if ( p->fCutMin ) + Vec_MemHashFree( p->vTtMem ); + if ( p->fCutMin ) + Vec_MemFree( p->vTtMem ); + ABC_FREE( p ); +} +void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) +{ + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_IntSize(p->vLevels) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, Delay ); + Vec_IntPush( p->vLevels, Level ); + Vec_WecPushLevel( p->vCuts ); +} +void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) +{ + Sbd_StoComputeCutsObj( p, iObj, Delay, Level ); + Sbd_CutAddUnit( p, iObj ); +} +int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + int Lev0 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId0(pObj, iObj) ); + int Lev1 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId1(pObj, iObj) ); + Sbd_StoComputeCutsObj( p, iObj, -1, 1 + Abc_MaxInt(Lev0, Lev1) ); + Sbd_StoMergeCuts( p, iObj ); + return Vec_IntEntry( p->vDelays, iObj ); +} +void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + assert( iObj == Vec_IntSize(p->vRefs) ); + assert( iMirror < iObj ); + Vec_IntPush( p->vRefs, iMirror > 0 ? Vec_IntEntry(p->vRefs, iMirror) : 0 ); + if ( Gia_ObjIsAnd(pObj) ) + { + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId1(pObj, iObj), 1 ); + } + else if ( Gia_ObjIsCo(pObj) ) + Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); +} +void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + Vec_IntAddToEntry( p->vRefs, iObj, -1 ); + if ( Vec_IntEntry( p->vRefs, iObj ) > 0 ) return; - printf( "CutPair = %.0f ", p->CutCount[0] ); - printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); - printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); - printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); - printf( "\n" ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); + Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); } void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) { - Sbd_Sto_t * p = Sbd_StoAlloc( pGia, 8, 32, 1, 1 ); - Sbd_StoComputeCuts( p ); + Sbd_Sto_t * p = Sbd_StoAlloc( pGia, NULL, 4, 8, 100, 1, 1 ); + Gia_Obj_t * pObj; + int i, iObj; + // prepare references + Gia_ManForEachObj( p->pGia, pObj, iObj ) + Sbd_StoRefObj( p, iObj, -1 ); + // compute cuts + Sbd_StoComputeCutsObj( p, 0, 0, 0 ); + Gia_ManForEachCiId( p->pGia, iObj, i ) + Sbd_StoComputeCutsCi( p, iObj, 0, 0 ); + Gia_ManForEachAnd( p->pGia, pObj, iObj ) + Sbd_StoComputeCutsNode( p, iObj ); + if ( p->fVerbose ) + { + printf( "Running cut computation with LutSize = %d CutSize = %d CutNum = %d:\n", p->nLutSize, p->nCutSize, p->nCutNum ); + printf( "CutPair = %.0f ", p->CutCount[0] ); + printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); + printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); + printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] ); + printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) ); + printf( "\n" ); + printf( "Spec = %4d ", p->nCutsSpec ); + printf( "Over = %4d ", p->nCutsOver ); + printf( "Lev = %4d ", p->DelayMin ); + Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart ); + } Sbd_StoFree( p ); } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 5395e148..54174f76 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -60,6 +60,8 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Sbd_Sto_t_ Sbd_Sto_t; + typedef struct Sbd_Str_t_ Sbd_Str_t; struct Sbd_Str_t_ { @@ -78,7 +80,14 @@ struct Sbd_Str_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== sbdCnf.c ==========================================================*/ +/*=== sbdCut.c ==========================================================*/ +extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); +extern void Sbd_StoFree( Sbd_Sto_t * p ); +extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); +extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); ABC_NAMESPACE_HEADER_END -- cgit v1.2.3 From 4488ab83d0c36f65a349122f58c44b55025ff856 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 29 Dec 2016 14:45:16 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 268 ++++++++++++++++++++++++++++++++++++++++++++--- src/opt/sbd/sbdCut.c | 92 +++++++++++----- src/opt/sbd/sbdInt.h | 4 +- src/sat/bsat/satSolver.h | 7 +- 4 files changed, 332 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 15874dc6..daefb9af 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -43,6 +43,7 @@ struct Sbd_Man_t_ Vec_Wrd_t * vSims[4]; // simulation information (main, backup, controlability) Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary + Vec_Int_t * vLits2; // temporary int nConsts; // constants int nChanges; // changes abctime timeWin; @@ -52,6 +53,7 @@ struct Sbd_Man_t_ abctime timeEnu; abctime timeOther; abctime timeTotal; + Sbd_Sto_t * pSto; // target node int Pivot; // target node int DivCutoff; // the place where D-2 divisors begin @@ -201,6 +203,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) // target node p->vCover = Vec_IntAlloc( 100 ); p->vLits = Vec_IntAlloc( 100 ); + p->vLits2 = Vec_IntAlloc( 100 ); p->vRoots = Vec_IntAlloc( 100 ); p->vWinObjs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); p->vObj2Var = Vec_IntStart( Gia_ManObjNum(pGia) ); @@ -223,6 +226,8 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Gia_ManForEachCiId( pGia, Id, i ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); + // cut enumeration + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, 2*pPars->nLutSize-1, 64, 1, 1 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -236,6 +241,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_WrdFree( p->vSims[i] ); Vec_IntFree( p->vCover ); Vec_IntFree( p->vLits ); + Vec_IntFree( p->vLits2 ); Vec_IntFree( p->vRoots ); Vec_IntFree( p->vWinObjs ); Vec_IntFree( p->vObj2Var ); @@ -246,7 +252,8 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vCounts[0] ); Vec_IntFree( p->vCounts[1] ); Vec_WrdFree( p->vMatrix ); - if ( p->pSat ) sat_solver_delete( p->pSat ); + sat_solver_delete_p( &p->pSat ); + Sbd_StoFree( p->pSto ); ABC_FREE( p ); } @@ -1158,10 +1165,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) int nConsts = 4; int RetValue; - if ( p->pSat ) - sat_solver_delete( p->pSat ); - p->pSat = NULL; - + sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; @@ -1262,6 +1266,125 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) return 0; } +int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +{ + extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 + ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); + extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); + abctime clk = Abc_Clock(); + + int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int nDivs = Vec_IntSize( p->vDivVars ); + int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); + int i, k, iObj, nIters; + + int nLeaves, pLeaves[SBD_DIV_MAX]; + + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodeRefs[SBD_DIV_MAX]; + int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; + + sat_solver_delete_p( &p->pSat ); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + + // extract one cut + nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); + + // solve the covering problem + for ( nIters = 0; nIters < nLeaves; nIters++ ) + { + word Truth; + // try to remove one variable from divisors + Vec_IntClear( p->vDivSet ); + for ( i = 0; i < nLeaves; i++ ) + if ( i != nIters && pLeaves[i] != -1 ) + Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); + assert( Vec_IntSize(p->vDivSet) < nLeaves ); + + Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + if ( Truth == SBD_SAT_UNDEC ) + printf( "Node %d: Undecided.\n", Pivot ); + else if ( Truth == SBD_SAT_SAT ) + continue; + else + pLeaves[nIters] = -1; + } + + Vec_IntClear( p->vDivSet ); + for ( i = 0; i < nLeaves; i++ ) + if ( pLeaves[i] != -1 ) + Vec_IntPush( p->vDivSet, pLeaves[i] ); + printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); + + //Delay++; + + // count number of nodes on each level + nNodesTop = 0, nNodesBot = 0; + Vec_IntForEachEntry( p->vDivSet, iObj, i ) + { + int DelayDiff = Vec_IntEntry(p->vLutLevs, iObj) - Delay; + if ( DelayDiff > -2 ) + break; + if ( DelayDiff == -2 ) + pNodesTop[nNodesTop++] = i; + else // if ( DelayDiff < -2 ) + pNodesBot[nNodesBot++] = i; + Vec_IntWriteEntry( p->vDivSet, iObj, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); + pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); + } + if ( i < Vec_IntSize(p->vDivSet) ) + return 0; + if ( nNodesTop > p->pPars->nLutSize-1 ) + return 0; + if ( nNodesBot > p->pPars->nLutSize ) + { + // move left-over to the top + while ( nNodesBot > p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot]; + assert( nNodesBot == p->pPars->nLutSize ); + assert( nNodesTop <= p->pPars->nLutSize-1 ); + } + nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; + + // number of structures + *pnStrs = 2 + nNodesDiff; + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; + + Strs[1].fLut = 1; + Strs[1].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[2+k].fLut = 0; + Strs[2+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[2+k].VarIns[i] = pNodesBot[i]; + Strs[2+k].Res = 0; + } + + return Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + p->vDivSet, *pnStrs, Strs ); +} + + /**Function************************************************************* Synopsis [Computes delay-oriented k-feasible cut at the node.] @@ -1503,6 +1626,87 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) return 0; } +int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) +{ + int i, k, w, iLit, Node; + int iObjLast = Gia_ManObjNum(p->pGia); + int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); + int iNewLev; + // collect leaf literals + Vec_IntClear( p->vLits ); + Vec_IntForEachEntry( p->vDivSet, Node, i ) + { + Node = Vec_IntEntry( p->vWinObjs, Node ); + if ( Vec_IntEntry(p->vMirrors, Node) >= 0 ) + Vec_IntPush( p->vLits, Vec_IntEntry(p->vMirrors, Node) ); + else + Vec_IntPush( p->vLits, Abc_Var2Lit(Node, 0) ); + } + // collect structure nodes + for ( i = 0; i < nStrs; i++ ) + Vec_IntPush( p->vLits, -1 ); + // implement structures + for ( i = nStrs-1; i >= 0; i-- ) + { + if ( pStrs[i].fLut ) + { + // collect local literals + Vec_IntClear( p->vLits2 ); + for ( k = 0; k < (int)pStrs[i].nVarIns; k++ ) + Vec_IntPush( p->vLits2, Vec_IntEntry(p->vLits, pStrs[i].VarIns[k]) ); + // pretend to have MUXes + // assert( p->pGia->pMuxes == NULL ); + if ( p->pGia->nXors && p->pGia->pMuxes == NULL ) + p->pGia->pMuxes = (unsigned *)p; + // derive new function of the node + iLit = Dsm_ManTruthToGia( p->pGia, &pStrs[i].Res, p->vLits2, p->vCover ); + if ( p->pGia->pMuxes == (unsigned *)p ) + p->pGia->pMuxes = NULL; + } + else + { + iLit = Vec_IntEntry( p->vLits, (int)pStrs[i].Res ); + assert( iLit > 0 ); + } + // update literal + assert( Vec_IntEntry(p->vLits, Vec_IntSize(p->vLits)-nStrs+i) == -1 ); + Vec_IntWriteEntry( p->vLits, Vec_IntSize(p->vLits)-nStrs+i, iLit ); + } + iLit = Vec_IntEntry( p->vLits, Vec_IntSize(p->vDivSet) ); + assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); + // remember this function + assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); + Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); + if ( p->pPars->fVerbose ) + printf( "Replacing node %d by literal %d.\n", Pivot, iLit ); + + // extend data-structure to accommodate new nodes + assert( Vec_IntSize(p->vLutLevs) == iObjLast ); + for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); + assert( i == Vec_IntSize(p->vLutLevs) ); + Vec_IntPush( p->vLutLevs, Delay ); + Vec_IntPush( p->vObj2Var, 0 ); + Vec_IntPush( p->vMirrors, -1 ); + Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); + //Sbd_ManFindCut( p, i, p->vLits ); + for ( k = 0; k < 4; k++ ) + for ( w = 0; w < p->pPars->nWords; w++ ) + Vec_WrdPush( p->vSims[k], 0 ); + } + // make sure delay reduction is achieved + iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); + assert( iNewLev < iCurLev ); + // update delay of the initial node + assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + p->nChanges++; + return 0; +} + /**Function************************************************************* Synopsis [Derives new AIG after resynthesis.] @@ -1537,7 +1741,7 @@ void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * v } Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) { - Gia_Man_t * pNew; + Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i; Gia_ManFillValue( p ); @@ -1557,6 +1761,10 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Gia_ManTransferTiming( pNew, p ); + // remove dangling nodes + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManTransferTiming( pNew, pTemp ); + Gia_ManStop( pTemp ); return pNew; } @@ -1574,12 +1782,17 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { // extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); + Sbd_Str_t Strs[4]; + int nStrs = 0; int RetValue; word Truth = 0; - if ( Sbd_ManMergeCuts( p, Pivot ) ) - return; + if ( !p->pSto ) + { + if ( Sbd_ManMergeCuts( p, Pivot ) ) + return; + } -// if ( Pivot != 70 ) +// if ( Pivot != 15 ) // return; if ( p->pPars->fVerbose ) @@ -1595,11 +1808,28 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); } + else if ( Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) + { + //Sbd_ManImplement( p, Pivot, Truth ); + Sbd_ManImplement2( p, Pivot, nStrs, Strs ); + //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + } +/* else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) { - Sbd_ManImplement( p, Pivot, Truth ); + int i; + Sbd_Str_t Strs; + Strs.fLut = 1; + Strs.nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs.nVarIns; i++ ) + Strs.VarIns[i] = i; + Strs.Res = Truth; + //Sbd_ManImplement( p, Pivot, Truth ); + Sbd_ManImplement2( p, Pivot, 1, &Strs ); //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); } +*/ + /* else { @@ -1642,6 +1872,9 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) int k, Pivot; assert( pPars->nLutSize <= 6 ); //Sbd_ManMergeTest( p ); + // prepare references + Gia_ManForEachObj( p->pGia, pObj, Pivot ) + Sbd_StoRefObj( p->pSto, Pivot, -1 ); //return NULL; if ( pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)pGia->pManTime) ) { @@ -1676,10 +1909,19 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) } else { - Gia_ManForEachAndId( pGia, Pivot ) + Gia_ManForEachObj( pGia, pObj, Pivot ) { - if ( Pivot < nNodesOld ) - Sbd_NtkPerformOne( p, Pivot ); + if ( Pivot == nNodesOld ) + break; + if ( Gia_ObjIsAnd(pObj) ) + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); + if ( Delay > 1 ) + Sbd_NtkPerformOne( p, Pivot ); + } + else if ( !Gia_ObjIsCo(pObj) ) + Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); } } printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 154df914..d4c085a1 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -40,9 +40,9 @@ struct Sbd_Cut_t_ int iFunc; // functionality int Cost; // cut cost int CostLev; // cut cost - unsigned fSpec : 1; // special cut - unsigned nTreeLeaves : 27; // cut cost - unsigned nLeaves : 4; // the number of leaves + unsigned nSlowLeaves : 14; // slow leaves + unsigned nTreeLeaves : 14; // tree leaves + unsigned nLeaves : 4; // leaf count int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; @@ -62,11 +62,13 @@ struct Sbd_Sto_t_ Vec_Mem_t * vTtMem; // truth tables Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers - abctime clkStart; // starting time + int nCutsR; // the number of cuts + int Pivot; // current object double CutCount[4]; // cut counters int nCutsSpec; // special cuts int nCutsOver; // overflow cuts int DelayMin; // minimum delay + abctime clkStart; // starting time }; static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); } @@ -309,6 +311,22 @@ static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) } return 0; } +static inline int Sbd_CutCompare2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 ) +{ + assert( pCut0->nLeaves > 4 && pCut1->nLeaves > 4 ); + if ( pCut0->nSlowLeaves < pCut1->nSlowLeaves ) return -1; + if ( pCut0->nSlowLeaves > pCut1->nSlowLeaves ) return 1; + if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1; + if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1; + if ( pCut0->Cost < pCut1->Cost ) return -1; + if ( pCut0->Cost > pCut1->Cost ) return 1; + if ( pCut0->CostLev < pCut1->CostLev ) return -1; + if ( pCut0->CostLev > pCut1->CostLev ) return 1; + if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; + if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; + return 0; +} + static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts ) { int i, k, fChanges = 0; @@ -424,12 +442,12 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline int Sbd_CutIsSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { - int i, Delay = Vec_IntEntry(p->vDelays, iObj), DelayMax = -ABC_INFINITY; + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); for ( i = 0; i < (int)pCut->nLeaves; i++ ) - DelayMax = Abc_MaxInt( DelayMax, Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); - return DelayMax < -1; + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); + return Count; } static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { @@ -475,9 +493,9 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->pLeaves[v-1] = pCut[v]; pCutTemp->iFunc = pCut[pCut[0]+1]; pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); - pCutTemp->fSpec = Sbd_CutIsSpec( p, iObj, pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); + pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); } return pList[0]; @@ -524,8 +542,8 @@ static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCu int i; for ( i = 0; i < nCuts; i++ ) { - pCuts[i]->fSpec = Sbd_CutIsSpec( p, iObj, pCuts[i] ); - p->nCutsSpec += pCuts[i]->fSpec; + pCuts[i]->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCuts[i] ); + p->nCutsSpec += (pCuts[i]->nSlowLeaves == 0); } } static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) @@ -537,8 +555,9 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) printf( " %*d", nDigits, pCut->pLeaves[i] ); for ( ; i < (int)p->nCutSize; i++ ) printf( " %*s", nDigits, " " ); - printf( " } Cost = %4d CostLev = %4d Tree = %2d ", pCut->Cost, pCut->CostLev, pCut->nTreeLeaves ); - printf( "%c ", pCut->fSpec ? '*' : ' ' ); + printf( " } Cost = %3d CostL = %3d Slow = %d Tree = %d ", + pCut->Cost, pCut->CostLev, pCut->nSlowLeaves, pCut->nTreeLeaves ); + printf( "%c ", pCut->nSlowLeaves == 0 ? '*' : ' ' ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); printf( "\n" ); @@ -585,12 +604,14 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) Sbd_StoComputeSpec( p, iObj, pCutsR, nCutsR ); p->CutCount[3] += nCutsR; p->nCutsOver += nCutsR == nCutNum-1; + p->nCutsR = nCutsR; + p->Pivot = iObj; // debug printout - if ( 0 ) + if ( 1 ) { printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) - if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->fSpec ) + if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->nSlowLeaves < 2 ) Sbd_CutPrint( p, iObj, pCutsR[i] ); printf( "\n" ); } @@ -630,10 +651,10 @@ Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, p->fVerbose = fVerbose; p->pGia = pGia; p->vMirrors = vMirrors; - p->vDelays = Vec_IntAlloc( Gia_ManObjNum(pGia) ); - p->vLevels = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) ); + p->vLevels = Vec_IntStart( Gia_ManObjNum(pGia) ); p->vRefs = Vec_IntAlloc( Gia_ManObjNum(pGia) ); - p->vCuts = Vec_WecAlloc( Gia_ManObjNum(pGia) ); + p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) ); p->vTtMem = fCutMin ? Vec_MemAllocForTT( nCutSize, 0 ) : NULL; return p; } @@ -651,12 +672,20 @@ void Sbd_StoFree( Sbd_Sto_t * p ) } void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { - assert( iObj == Vec_IntSize(p->vDelays) ); - assert( iObj == Vec_IntSize(p->vLevels) ); - assert( iObj == Vec_WecSize(p->vCuts) ); - Vec_IntPush( p->vDelays, Delay ); - Vec_IntPush( p->vLevels, Level ); - Vec_WecPushLevel( p->vCuts ); + if ( iObj < Vec_IntSize(p->vDelays) ) + { + Vec_IntWriteEntry( p->vDelays, iObj, Delay ); + Vec_IntWriteEntry( p->vLevels, iObj, Level ); + } + else + { + assert( iObj == Vec_IntSize(p->vDelays) ); + assert( iObj == Vec_IntSize(p->vLevels) ); + assert( iObj == Vec_WecSize(p->vCuts) ); + Vec_IntPush( p->vDelays, Delay ); + Vec_IntPush( p->vLevels, Level ); + Vec_WecPushLevel( p->vCuts ); + } } void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { @@ -698,6 +727,21 @@ void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); } +int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) +{ + Sbd_Cut_t * pCutBest = NULL; int i; + assert( p->Pivot == iObj ); + for ( i = 0; i < p->nCutsR; i++ ) + { + if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) + pCutBest = p->ppCuts[i]; + } +Sbd_CutPrint( p, iObj, pCutBest ); + assert( pCutBest->nLeaves <= SBD_DIV_MAX ); + for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) + pLeaves[i] = pCutBest->pLeaves[i]; + return pCutBest->nLeaves; +} void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) { Sbd_Sto_t * p = Sbd_StoAlloc( pGia, NULL, 4, 8, 100, 1, 1 ); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 54174f76..31d0ea06 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -54,7 +54,7 @@ ABC_NAMESPACE_HEADER_START #define SBD_LUTS_MAX 2 #define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 7 +#define SBD_DIV_MAX 8 //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -88,6 +88,8 @@ extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ); + ABC_NAMESPACE_HEADER_END diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 7ef2c9e8..162b91e5 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -229,7 +229,12 @@ static void sat_solver_compress(sat_solver* s) (void) RetValue; } } - +static void sat_solver_delete_p( sat_solver ** ps ) +{ + if ( *ps ) + sat_solver_delete( *ps ); + *ps = NULL; +} static void sat_solver_clean_polarity(sat_solver* s, int * pVars, int nVars ) { int i; -- cgit v1.2.3 From 54b4692d4bb2a6c5e59b5f54aaff95e2c4966e77 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 29 Dec 2016 21:26:02 +0700 Subject: Updates to delay optimization project. --- src/base/abci/abc.c | 16 +++- src/opt/dau/dauGia.c | 2 +- src/opt/sbd/sbd.h | 1 + src/opt/sbd/sbdCore.c | 248 ++++++++++++++++++++++++++------------------------ src/opt/sbd/sbdCut.c | 62 +++++++++---- src/opt/sbd/sbdInt.h | 3 +- src/opt/sbd/sbdLut.c | 17 ++-- 7 files changed, 196 insertions(+), 153 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7866b22d..f9717aa8 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSWFMCacvwh" ) ) != EOF ) { switch ( c ) { @@ -41025,6 +41025,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutSize < 0 ) goto usage; break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLutNum < 0 ) + goto usage; + break; case 'W': if ( globalUtilOptind >= argc ) { @@ -41107,9 +41118,10 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSWFMC ] [-acvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); + Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); Abc_Print( -2, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels ); Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 5e74ad21..68375039 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -241,7 +241,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd ) if ( pGia->pHTable == NULL ) { if ( fAnd ) - iFan = Gia_ManAppendAnd( pGia, iFan0, iFan1 ); + iFan = Gia_ManAppendAnd2( pGia, iFan0, iFan1 ); else if ( pGia->pMuxes ) { int fCompl = Abc_LitIsCompl(iFan0) ^ Abc_LitIsCompl(iFan1); diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 89d29958..6cdfafe4 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -39,6 +39,7 @@ typedef struct Sbd_Par_t_ Sbd_Par_t; struct Sbd_Par_t_ { int nLutSize; // target LUT size + int nLutNum; // target LUT count int nTfoLevels; // the number of TFO levels (windowing) int nTfoFanMax; // the max number of fanouts (windowing) int nWinSizeMax; // maximum window size (windowing) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index daefb9af..0b399b8a 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1,12 +1,12 @@ /**CFile**************************************************************** - FileName [sbd.c] + FileName [sbdCore.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [SAT-based optimization using internal don't-cares.] - Synopsis [] + Synopsis [Core procedures.] Author [Alan Mishchenko] @@ -14,7 +14,7 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: sbd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: sbdCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -30,7 +30,6 @@ ABC_NAMESPACE_IMPL_START #define SBD_MAX_LUTSIZE 6 - typedef struct Sbd_Man_t_ Sbd_Man_t; struct Sbd_Man_t_ { @@ -44,13 +43,13 @@ struct Sbd_Man_t_ Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary Vec_Int_t * vLits2; // temporary - int nConsts; // constants - int nChanges; // changes + int nLuts[3]; // 0=const, 1=1lut, 2=2lut abctime timeWin; abctime timeCnf; abctime timeSat; abctime timeCov; abctime timeEnu; + abctime timeQbf; abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; @@ -98,6 +97,7 @@ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) { memset( pPars, 0, sizeof(Sbd_Par_t) ); pPars->nLutSize = 4; // target LUT size + pPars->nLutNum = 2; // target LUT count pPars->nTfoLevels = 2; // the number of TFO levels (windowing) pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) pPars->nWinSizeMax = 0; // maximum window size (windowing) @@ -489,24 +489,26 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) ***********************************************************************/ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) { + extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); + extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ); + int nMintCount = 1; Vec_Ptr_t * vSims; word * pSims = Sbd_ObjSim0( p, Pivot ); word * pCtrl = Sbd_ObjSim2( p, Pivot ); int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); int RetValue, i, iObj, Ind, fFindOnset, nCares[2] = {0}; + abctime clk = Abc_Clock(); - extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; if ( p->pSat == NULL ) { - if ( p->pPars->fVerbose ) - printf( "Found stuck-at-%d node %d.\n", 0, Pivot ); + //if ( p->pPars->fVerbose ) + // printf( "Found stuck-at-%d node %d.\n", 0, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return 0; } //return -1; @@ -526,7 +528,7 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) nCares[0] = nCares[0] < nMintCount ? nMintCount - nCares[0] : 0; nCares[1] = nCares[1] < nMintCount ? nMintCount - nCares[1] : 0; - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Computing %d offset and %d onset minterms for node %d.\n", nCares[0], nCares[1], Pivot ); if ( Vec_IntSize(p->vLits) >= nCares[0] + nCares[1] ) @@ -565,10 +567,10 @@ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) Vec_PtrFree( vSims ); if ( RetValue >= 0 ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return RetValue; } // set controlability of these minterms @@ -1153,7 +1155,7 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); - abctime clk = Abc_Clock(); + abctime clk, clkSat = 0, clkEnu = 0, clkAll; word Onset[64] = {0}, Offset[64] = {0}, Cube; word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; @@ -1165,20 +1167,25 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) int nConsts = 4; int RetValue; - sat_solver_delete_p( &p->pSat ); + clk = Abc_Clock(); + //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; + clkAll = Abc_Clock(); assert( nConsts <= 8 ); + clk = Abc_Clock(); RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); + clkSat += Abc_Clock() - clk; if ( RetValue >= 0 ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Found stuck-at-%d node %d.\n", RetValue, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, 0 ); - p->nConsts++; + p->nLuts[0]++; return RetValue; } + RetValue = 0; // create rows of the table nRows = 0; @@ -1200,36 +1207,35 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) // solve the covering problem for ( nIters = 0; nIters < nItersMax && nRows < 64; nIters++ ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) Sbd_ManMatrPrint( p, CoverCols, nDivs, nRows ); clk = Abc_Clock(); if ( !Sbd_ManFindCands( p, CoverCols, nDivs ) ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Cannot find a feasible cover.\n" ); - //clkEnu += Abc_Clock() - clk; - //clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - //p->timeSat += clkSat; - //p->timeCov += clkAll; - //p->timeEnu += clkEnu; + clkEnu += Abc_Clock() - clk; + clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + p->timeSat += clkSat; + p->timeCov += clkAll; + p->timeEnu += clkEnu; return 0; } - //clkEnu += Abc_Clock() - clk; - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Candidate support: " ), Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - //clkSat += Abc_Clock() - clk; + clkSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( *pTruth == SBD_SAT_SAT ) { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) { int i; printf( "Node %d: SAT.\n", Pivot ); @@ -1255,15 +1261,21 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) } else { - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) { printf( "Node %d: UNSAT. ", Pivot ); Extra_PrintBinary( stdout, (unsigned *)pTruth, 1 << Vec_IntSize(p->vDivSet) ), printf( "\n" ); } - return 1; + p->nLuts[1]++; + RetValue = 1; + break; } } - return 0; + clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; + p->timeSat += clkSat; + p->timeCov += clkAll; + p->timeEnu += clkEnu; + return RetValue; } int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) @@ -1277,37 +1289,41 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); + word Truth; int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); - int nDivs = Vec_IntSize( p->vDivVars ); + //int nDivs = Vec_IntSize( p->vDivVars ); int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); - int i, k, iObj, nIters; + int i, k, iObj, nIters, RetValue; int nLeaves, pLeaves[SBD_DIV_MAX]; - int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodeRefs[SBD_DIV_MAX]; + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX];//, pNodeRefs[SBD_DIV_MAX]; int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; - sat_solver_delete_p( &p->pSat ); + //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; // extract one cut nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); + if ( nLeaves == -1 ) + return 0; // solve the covering problem for ( nIters = 0; nIters < nLeaves; nIters++ ) { - word Truth; // try to remove one variable from divisors Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) if ( i != nIters && pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); assert( Vec_IntSize(p->vDivSet) < nLeaves ); - + // compute truth table + clk = Abc_Clock(); Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + p->timeSat += Abc_Clock() - clk; if ( Truth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( Truth == SBD_SAT_SAT ) @@ -1315,16 +1331,34 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) else pLeaves[nIters] = -1; } - Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) if ( pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, pLeaves[i] ); - printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + //printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); + if ( Vec_IntSize(p->vDivSet) <= p->pPars->nLutSize ) + { + *pnStrs = 1; + // remap divisors + Vec_IntForEachEntry( p->vDivSet, iObj, i ) + Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); + // compute truth table + clk = Abc_Clock(); + Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + p->timeSat += Abc_Clock() - clk; + assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); + // create structure + Strs->fLut = 1; + Strs->nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs->nVarIns; i++ ) + Strs->VarIns[i] = i; + Strs->Res = Truth; + p->nLuts[1]++; + //Extra_PrintBinary( stdout, (unsigned *)&Truth, 1 << Strs->nVarIns ), printf( "\n" ); + return 1; + } assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); - //Delay++; - // count number of nodes on each level nNodesTop = 0, nNodesBot = 0; Vec_IntForEachEntry( p->vDivSet, iObj, i ) @@ -1336,8 +1370,8 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) pNodesTop[nNodesTop++] = i; else // if ( DelayDiff < -2 ) pNodesBot[nNodesBot++] = i; - Vec_IntWriteEntry( p->vDivSet, iObj, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); - pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); + Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); + //pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); } if ( i < Vec_IntSize(p->vDivSet) ) return 0; @@ -1379,9 +1413,15 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) Strs[2+k].Res = 0; } - return Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - p->vDivSet, *pnStrs, Strs ); + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, + Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, + p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + + if ( RetValue ) + p->nLuts[2]++; + return RetValue; } @@ -1622,7 +1662,6 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); - p->nChanges++; return 0; } @@ -1677,13 +1716,14 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // remember this function assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); - if ( p->pPars->fVerbose ) + if ( p->pPars->fVeryVerbose ) printf( "Replacing node %d by literal %d.\n", Pivot, iLit ); // extend data-structure to accommodate new nodes assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); @@ -1703,7 +1743,6 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); - p->nChanges++; return 0; } @@ -1781,11 +1820,10 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { -// extern void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ); Sbd_Str_t Strs[4]; - int nStrs = 0; + int i, RetValue, nStrs = 0; + word Truth = 0; - int RetValue; word Truth = 0; if ( !p->pSto ) { if ( Sbd_ManMergeCuts( p, Pivot ) ) @@ -1795,83 +1833,39 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) // if ( Pivot != 15 ) // return; - if ( p->pPars->fVerbose ) - printf( "\nLooking at node %d\n", Pivot ); if ( Sbd_ManWindow( p, Pivot ) ) return; -// Sbd_ManSolveSelect( p->pGia, p->vMirrors, Pivot, p->vDivVars, p->vDivValues, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots ); - RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); - //printf( " --> Pivot %4d. Constant %d.\n", Pivot, RetValue ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } - else if ( Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) + else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { - //Sbd_ManImplement( p, Pivot, Truth ); - Sbd_ManImplement2( p, Pivot, nStrs, Strs ); - //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); - } -/* - else if ( Sbd_ManExplore2( p, Pivot, &Truth ) ) - { - int i; - Sbd_Str_t Strs; - Strs.fLut = 1; - Strs.nVarIns = Vec_IntSize( p->vDivSet ); - for ( i = 0; i < Strs.nVarIns; i++ ) - Strs.VarIns[i] = i; - Strs.Res = Truth; - //Sbd_ManImplement( p, Pivot, Truth ); - Sbd_ManImplement2( p, Pivot, 1, &Strs ); - //printf( " --> Pivot %4d. Supp %d.\n", Pivot, Vec_IntSize(p->vDivSet) ); + Strs->fLut = 1; + Strs->nVarIns = Vec_IntSize( p->vDivSet ); + for ( i = 0; i < Strs->nVarIns; i++ ) + Strs->VarIns[i] = i; + Strs->Res = Truth; + Sbd_ManImplement2( p, Pivot, 1, Strs ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } -*/ - -/* - else + else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { - extern int Sbd_ProblemSolve( - Gia_Man_t * p, Vec_Int_t * vMirrors, - int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, - Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 - ); - -// Sbd_Str_t Strs[2] = { {1, 4, {0, 1, 2, 8}}, {1, 4, {3, 4, 5, 6}} }; -// Sbd_Str_t Strs[2] = { {1, 4, {1, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}} }; - Sbd_Str_t Strs[3] = { {1, 4, {8, 4, 5, 7}}, {1, 4, {0, 1, 2, 3}}, {0, 4, {0, 1, 2, 3}} }; - - Vec_Int_t * vDivSet = Vec_IntAlloc( 8 ); - - int i, RetValue; - - for ( i = 0; i < 6; i++ ) - Vec_IntPush( vDivSet, i+1 ); - - RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - vDivSet, 3, Strs ); - if ( RetValue ) - { - printf( "Solving succeded.\n" ); - //Sbd_ManImplement2( p, Pivot, Truth, nLuts, nSels, nVarsDivs, pVarsDivs, Truths ); - } - Vec_IntFree( vDivSet ); + Sbd_ManImplement2( p, Pivot, nStrs, Strs ); + if ( p->pPars->fVerbose ) printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); } -*/ } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; Sbd_Man_t * p = Sbd_ManStart( pGia, pPars ); - int nNodesOld = Gia_ManObjNum(pGia);//, Count = 0; + int nNodesOld = Gia_ManObjNum(pGia); int k, Pivot; assert( pPars->nLutSize <= 6 ); - //Sbd_ManMergeTest( p ); // prepare references Gia_ManForEachObj( p->pGia, pObj, Pivot ) Sbd_StoRefObj( p->pSto, Pivot, -1 ); @@ -1886,21 +1880,28 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Pivot = Gia_ObjId( pGia, pObj ); if ( Pivot >= nNodesOld ) - continue; + break; if ( Gia_ObjIsAnd(pObj) ) - Sbd_NtkPerformOne( p, Pivot ); + { + int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); + if ( Delay > 1 ) + Sbd_NtkPerformOne( p, Pivot ); + } else if ( Gia_ObjIsCi(pObj) ) { int arrTime = Tim_ManGetCiArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj) ); Vec_IntWriteEntry( p->vLutLevs, Pivot, arrTime ); + Sbd_StoComputeCutsCi( p->pSto, Pivot, arrTime, arrTime ); } else if ( Gia_ObjIsCo(pObj) ) { int arrTime = Vec_IntEntry( p->vLutLevs, Gia_ObjFaninId0(pObj, Pivot) ); Tim_ManSetCoArrival( (Tim_Man_t*)pGia->pManTime, Gia_ObjCioId(pObj), arrTime ); } - else if ( !Gia_ObjIsConst0(pObj) ) - assert( 0 ); + else if ( Gia_ObjIsConst0(pObj) ) + Sbd_StoComputeCutsConst0( p->pSto, 0 ); + else assert( 0 ); } //Tim_ManPrint( pGia->pManTime ); Tim_ManStop( (Tim_Man_t *)pGia->pManTime ); @@ -1909,34 +1910,39 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) } else { + Sbd_StoComputeCutsConst0( p->pSto, 0 ); Gia_ManForEachObj( pGia, pObj, Pivot ) { - if ( Pivot == nNodesOld ) + if ( Pivot >= nNodesOld ) break; - if ( Gia_ObjIsAnd(pObj) ) + if ( Gia_ObjIsCi(pObj) ) + Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); + else if ( Gia_ObjIsAnd(pObj) ) { int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); if ( Delay > 1 ) Sbd_NtkPerformOne( p, Pivot ); } - else if ( !Gia_ObjIsCo(pObj) ) - Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); + //if ( nNodesOld != Gia_ManObjNum(pGia) ) + // break; } } - printf( "Found %d constants and %d replacements with delay %d. ", p->nConsts, p->nChanges, Sbd_ManDelay(p) ); + printf( "Found %d constants, %d one-LUT and %d two-LUT replacements with delay %d. ", + p->nLuts[0], p->nLuts[1], p->nLuts[2], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); pNew = Sbd_ManDerive( pGia, p->vMirrors ); // print runtime statistics - p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu; - if ( 0 ) + p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu - p->timeQbf; + if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); ABC_PRTP( "Cnf", p->timeCnf , p->timeTotal ); ABC_PRTP( "Sat", p->timeSat , p->timeTotal ); ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); ABC_PRTP( "Enu", p->timeEnu , p->timeTotal ); + ABC_PRTP( "Qbf", p->timeQbf , p->timeTotal ); ABC_PRTP( "Oth", p->timeOther, p->timeTotal ); ABC_PRTP( "ALL", p->timeTotal, p->timeTotal ); } diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index d4c085a1..9c54c74a 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -40,8 +40,9 @@ struct Sbd_Cut_t_ int iFunc; // functionality int Cost; // cut cost int CostLev; // cut cost - unsigned nSlowLeaves : 14; // slow leaves - unsigned nTreeLeaves : 14; // tree leaves + unsigned nTreeLeaves : 9; // tree leaves + unsigned nSlowLeaves : 9; // slow leaves + unsigned nTopLeaves : 10; // top leaves unsigned nLeaves : 4; // leaf count int pLeaves[SBD_MAX_CUTSIZE]; // leaves }; @@ -442,13 +443,6 @@ static inline int Sbd_CutCountBits( word i ) i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F); return (i*(0x0101010101010101))>>56; } -static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) -{ - int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); - return Count; -} static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { int i, Cost = 0; @@ -470,6 +464,20 @@ static inline int Sbd_CutTreeLeaves( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1; return Cost; } +static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1); + return Count; +} +static inline int Sbd_CutTopLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) +{ + int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay == -2); + return Count; +} static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); @@ -481,6 +489,14 @@ static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj ) Vec_IntPush( vThis, iObj ); Vec_IntPush( vThis, 2 ); } +static inline void Sbd_CutAddZero( Sbd_Sto_t * p, int iObj ) +{ + Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); + assert( Vec_IntSize(vThis) == 0 ); + Vec_IntPush( vThis, 1 ); + Vec_IntPush( vThis, 0 ); + Vec_IntPush( vThis, 0 ); +} static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) { Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj ); @@ -495,8 +511,9 @@ static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index ) pCutTemp->Sign = Sbd_CutGetSign( pCutTemp ); pCutTemp->Cost = Sbd_CutCost( p, pCutTemp ); pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp ); - pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp ); + pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp ); + pCutTemp->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCutTemp ); } return pList[0]; } @@ -542,6 +559,7 @@ static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCu int i; for ( i = 0; i < nCuts; i++ ) { + pCuts[i]->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCuts[i] ); pCuts[i]->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCuts[i] ); p->nCutsSpec += (pCuts[i]->nSlowLeaves == 0); } @@ -555,8 +573,8 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) printf( " %*d", nDigits, pCut->pLeaves[i] ); for ( ; i < (int)p->nCutSize; i++ ) printf( " %*s", nDigits, " " ); - printf( " } Cost = %3d CostL = %3d Slow = %d Tree = %d ", - pCut->Cost, pCut->CostLev, pCut->nSlowLeaves, pCut->nTreeLeaves ); + printf( " } Cost = %3d CostL = %3d Tree = %d Slow = %d Top = %d ", + pCut->Cost, pCut->CostLev, pCut->nTreeLeaves, pCut->nSlowLeaves, pCut->nTopLeaves ); printf( "%c ", pCut->nSlowLeaves == 0 ? '*' : ' ' ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay ); @@ -607,7 +625,7 @@ void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj ) p->nCutsR = nCutsR; p->Pivot = iObj; // debug printout - if ( 1 ) + if ( 0 ) { printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR ); for ( i = 0; i < nCutsR; i++ ) @@ -687,6 +705,11 @@ void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ) Vec_WecPushLevel( p->vCuts ); } } +void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ) +{ + Sbd_StoComputeCutsObj( p, iObj, 0, 0 ); + Sbd_CutAddZero( p, iObj ); +} void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ) { Sbd_StoComputeCutsObj( p, iObj, Delay, Level ); @@ -732,11 +755,14 @@ int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) Sbd_Cut_t * pCutBest = NULL; int i; assert( p->Pivot == iObj ); for ( i = 0; i < p->nCutsR; i++ ) - { - if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) + if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && + (int)p->ppCuts[i]->nSlowLeaves == 0 && + (int)p->ppCuts[i]->nTopLeaves <= p->nLutSize-1 && + (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) pCutBest = p->ppCuts[i]; - } -Sbd_CutPrint( p, iObj, pCutBest ); + if ( pCutBest == NULL ) + return -1; +//Sbd_CutPrint( p, iObj, pCutBest ); assert( pCutBest->nLeaves <= SBD_DIV_MAX ); for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) pLeaves[i] = pCutBest->pLeaves[i]; @@ -751,7 +777,7 @@ void Sbd_StoComputeCutsTest( Gia_Man_t * pGia ) Gia_ManForEachObj( p->pGia, pObj, iObj ) Sbd_StoRefObj( p, iObj, -1 ); // compute cuts - Sbd_StoComputeCutsObj( p, 0, 0, 0 ); + Sbd_StoComputeCutsConst0( p, 0 ); Gia_ManForEachCiId( p->pGia, iObj, i ) Sbd_StoComputeCutsCi( p, iObj, 0, 0 ); Gia_ManForEachAnd( p->pGia, pObj, iObj ) diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 31d0ea06..d54285f8 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -84,7 +84,8 @@ struct Sbd_Str_t_ extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); extern void Sbd_StoFree( Sbd_Sto_t * p ); extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); -extern void Sbd_StoDefefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index b924a33b..e8aee790 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -157,7 +157,7 @@ void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits for ( m = 0; m < nIters; m++, iLit++ ) if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) ) Abc_TtSetBit( &pStr->Res, m ); - Abc_TtStretch6( &pStr->Res, pStr->nVarIns, 6 ); + pStr->Res = Abc_Tt6Stretch( pStr->Res, pStr->nVarIns ); } else { @@ -192,13 +192,12 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, { extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - int fVerbose = 1; + int fVerbose = 0; + abctime clk = Abc_Clock(); Vec_Int_t * vLits = Vec_IntAlloc( 100 ); sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 ); sat_solver * pSatQbf = sat_solver_new(); - //int PivotVar = Vec_IntEntry(vObj2Var, Pivot); - int nVars = Vec_IntSize( vDivSet ); int nPars = Sbd_ProblemCountParams( nStrs, pStr0 ); @@ -248,8 +247,6 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, if ( status == l_False ) // solution found break; assert( status == l_True ); -// Vec_IntForEachEntry( vWinObjs, iVar, i ) -// printf( "Node = %4d. SatVar = %4d. Value = %d.\n", iVar, i, sat_solver_var_value(pSatCec, i) ); if ( fVerbose ) { @@ -292,16 +289,16 @@ int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, } if ( Vec_IntSize(vLits) > 0 ) { - Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); + //Sbd_ProblemPrintSolution( nStrs, pStr0, vLits ); Sbd_ProblemCollectSolution( nStrs, pStr0, vLits ); RetValue = 1; } - else - printf( "Solution does not exist.\n" ); - sat_solver_delete( pSatCec ); sat_solver_delete( pSatQbf ); Vec_IntFree( vLits ); + + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return RetValue; } -- cgit v1.2.3 From 01924ca118cad9bc8bf84de0525e54f5c4a832ec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 20:21:46 +0700 Subject: Updates to delay optimization project. --- src/aig/gia/gia.h | 53 ++++-- src/base/abci/abc.c | 28 +++- src/opt/dau/dauGia.c | 2 +- src/opt/sbd/sbd.h | 2 + src/opt/sbd/sbdCore.c | 446 +++++++++++++++++++++++++++++++++----------------- src/opt/sbd/sbdCut.c | 68 ++++++-- src/opt/sbd/sbdInt.h | 39 +++-- src/opt/sbd/sbdLut.c | 1 - src/opt/sbd/sbdWin.c | 5 +- 9 files changed, 446 insertions(+), 198 deletions(-) (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index ac40f975..d9b1716a 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -665,21 +665,6 @@ static inline int Gia_ManAppendAnd( Gia_Man_t * p, int iLit0, int iLit1 ) } return Gia_ObjId( p, pObj ) << 1; } -static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 ) -{ - if ( !p->fGiaSimple ) - { - if ( iLit0 < 2 ) - return iLit0 ? iLit1 : 0; - if ( iLit1 < 2 ) - return iLit1 ? iLit0 : 0; - if ( iLit0 == iLit1 ) - return iLit1; - if ( iLit0 == Abc_LitNot(iLit1) ) - return 0; - } - return Gia_ManAppendAnd( p, iLit0, iLit1 ); -} static inline int Gia_ManAppendXorReal( Gia_Man_t * p, int iLit0, int iLit1 ) { Gia_Obj_t * pObj = Gia_ManAppendObj( p ); @@ -780,6 +765,44 @@ static inline int Gia_ManAppendXor( Gia_Man_t * p, int iLit0, int iLit1 ) { return Gia_ManAppendMux( p, iLit0, Abc_LitNot(iLit1), iLit1 ); } + +static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + if ( !p->fGiaSimple ) + { + if ( iLit0 < 2 ) + return iLit0 ? iLit1 : 0; + if ( iLit1 < 2 ) + return iLit1 ? iLit0 : 0; + if ( iLit0 == iLit1 ) + return iLit1; + if ( iLit0 == Abc_LitNot(iLit1) ) + return 0; + } + return Gia_ManAppendAnd( p, iLit0, iLit1 ); +} +static inline int Gia_ManAppendOr2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + return Abc_LitNot(Gia_ManAppendAnd2( p, Abc_LitNot(iLit0), Abc_LitNot(iLit1) )); +} +static inline int Gia_ManAppendMux2( Gia_Man_t * p, int iCtrl, int iData1, int iData0 ) +{ + int iTemp0 = Gia_ManAppendAnd2( p, Abc_LitNot(iCtrl), iData0 ); + int iTemp1 = Gia_ManAppendAnd2( p, iCtrl, iData1 ); + return Abc_LitNotCond( Gia_ManAppendAnd2( p, Abc_LitNot(iTemp0), Abc_LitNot(iTemp1) ), 1 ); +} +static inline int Gia_ManAppendMaj2( Gia_Man_t * p, int iData0, int iData1, int iData2 ) +{ + int iTemp0 = Gia_ManAppendOr2( p, iData1, iData2 ); + int iTemp1 = Gia_ManAppendAnd2( p, iData0, iTemp0 ); + int iTemp2 = Gia_ManAppendAnd2( p, iData1, iData2 ); + return Gia_ManAppendOr2( p, iTemp1, iTemp2 ); +} +static inline int Gia_ManAppendXor2( Gia_Man_t * p, int iLit0, int iLit1 ) +{ + return Gia_ManAppendMux2( p, iLit0, Abc_LitNot(iLit1), iLit1 ); +} + static inline void Gia_ManPatchCoDriver( Gia_Man_t * p, int iCoIndex, int iLit0 ) { Gia_Obj_t * pObjCo = Gia_ManCo( p, iCoIndex ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f9717aa8..fccd4f63 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KSWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCacvwh" ) ) != EOF ) { switch ( c ) { @@ -41036,6 +41036,28 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutNum < 0 ) goto usage; break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nCutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutSize < 0 ) + goto usage; + break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nCutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutNum < 0 ) + goto usage; + break; case 'W': if ( globalUtilOptind >= argc ) { @@ -41118,10 +41140,12 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KSWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-acvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); + Abc_Print( -2, "\t-N : the cut size considered for optimization (2 <= num <= 10) [default = %d]\n", pPars->nCutSize ); + Abc_Print( -2, "\t-P : the number of cuts computed at a node (1 <= num <= 500) [default = %d]\n", pPars->nCutNum ); Abc_Print( -2, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels ); Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 68375039..8b0a76c3 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -249,7 +249,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd ) iFan = Abc_LitNotCond( iFan, fCompl ); } else - iFan = Gia_ManAppendXor( pGia, iFan0, iFan1 ); + iFan = Gia_ManAppendXor2( pGia, iFan0, iFan1 ); } else { diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 6cdfafe4..6e0f6b3b 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -40,6 +40,8 @@ struct Sbd_Par_t_ { int nLutSize; // target LUT size int nLutNum; // target LUT count + int nCutSize; // target cut size + int nCutNum; // target cut count int nTfoLevels; // the number of TFO levels (windowing) int nTfoFanMax; // the max number of fanouts (windowing) int nWinSizeMax; // maximum window size (windowing) diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 0b399b8a..a48e6489 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -43,12 +43,14 @@ struct Sbd_Man_t_ Vec_Int_t * vCover; // temporary Vec_Int_t * vLits; // temporary Vec_Int_t * vLits2; // temporary - int nLuts[3]; // 0=const, 1=1lut, 2=2lut + int nLuts[6]; // 0=const, 1=1lut, 2=2lut, 3=3lut + int nTried; + int nUsed; abctime timeWin; + abctime timeCut; + abctime timeCov; abctime timeCnf; abctime timeSat; - abctime timeCov; - abctime timeEnu; abctime timeQbf; abctime timeOther; abctime timeTotal; @@ -76,8 +78,6 @@ static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( static inline word * Sbd_ObjSim2( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[2], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim3( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[3], p->pPars->nWords * i ); } -extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -96,17 +96,19 @@ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) { memset( pPars, 0, sizeof(Sbd_Par_t) ); - pPars->nLutSize = 4; // target LUT size - pPars->nLutNum = 2; // target LUT count - pPars->nTfoLevels = 2; // the number of TFO levels (windowing) - pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) - pPars->nWinSizeMax = 0; // maximum window size (windowing) - pPars->nBTLimit = 0; // maximum number of SAT conflicts - pPars->nWords = 1; // simulation word count - pPars->fArea = 0; // area-oriented optimization - pPars->fCover = 0; // use complete cover procedure - pPars->fVerbose = 0; // verbose flag - pPars->fVeryVerbose = 0; // verbose flag + pPars->nLutSize = 4; // target LUT size + pPars->nLutNum = 3; // target LUT count + pPars->nCutSize = (pPars->nLutSize - 1) * pPars->nLutNum + 1; // target cut size + pPars->nCutNum = 128; // target cut count + pPars->nTfoLevels = 5; // the number of TFO levels (windowing) + pPars->nTfoFanMax = 4; // the max number of fanouts (windowing) + pPars->nWinSizeMax = 2000; // maximum window size (windowing) + pPars->nBTLimit = 0; // maximum number of SAT conflicts + pPars->nWords = 1; // simulation word count + pPars->fArea = 0; // area-oriented optimization + pPars->fCover = 0; // use complete cover procedure + pPars->fVerbose = 0; // verbose flag + pPars->fVeryVerbose = 0; // verbose flag } /**Function************************************************************* @@ -227,7 +229,7 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, 2*pPars->nLutSize-1, 64, 1, 1 ); + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 1, 1 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -437,6 +439,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ManIncrementTravId( p->pGia ); Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); + if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + return 0; Sbd_ManUpdateOrder( p, Pivot ); assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); @@ -461,6 +465,8 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vObj2Var, Abc_Lit2Var(Node), Vec_IntSize(p->vWinObjs) ); Vec_IntPush( p->vWinObjs, Abc_Lit2Var(Node) ); } + if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + return 0; // compute controlability for node if ( Vec_IntSize(p->vTfo) == 0 ) Abc_TtFill( Sbd_ObjSim2(p, Pivot), p->pPars->nWords ); @@ -473,7 +479,7 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) // propagate controlability to fanins for the TFI nodes starting from the pivot Sbd_ManPropagateControl( p, Pivot ); assert( Vec_IntSize(p->vDivValues) <= 64 ); - return (int)(Vec_IntSize(p->vDivValues) > 64); + return (int)(Vec_IntSize(p->vDivValues) <= 64); } /**Function************************************************************* @@ -489,10 +495,6 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) ***********************************************************************/ int Sbd_ManCheckConst( Sbd_Man_t * p, int Pivot ) { - extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern void Sbd_ManPrintObj( Sbd_Man_t * p, int Pivot ); - int nMintCount = 1; Vec_Ptr_t * vSims; word * pSims = Sbd_ObjSim0( p, Pivot ); @@ -984,7 +986,7 @@ static inline int Sbd_ManFindCands( Sbd_Man_t * p, word Cover[64], int nDivs ) int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { int fVerbose = 0; - abctime clk, clkSat = 0, clkEnu = 0, clkAll = Abc_Clock(); + abctime clk; int nIters, nItersMax = 32; word MatrS[64] = {0}, MatrC[2][64] = {{0}}, Cubes[2][2][64] = {{{0}}}, Cover[64] = {0}, Cube, CubeNew[2]; @@ -1089,14 +1091,10 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) { if ( p->pPars->fVerbose ) printf( "Cannot find a feasible cover.\n" ); - clkEnu += Abc_Clock() - clk; - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; + p->timeCov += Abc_Clock() - clk; return RetValue; } - clkEnu += Abc_Clock() - clk; + p->timeCov += Abc_Clock() - clk; if ( p->pPars->fVerbose ) printf( "Candidate support: " ), @@ -1104,7 +1102,7 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); @@ -1143,19 +1141,12 @@ int Sbd_ManExplore( Sbd_Man_t * p, int Pivot, word * pTruth ) } //break; } - //printf( "Node %4d : Iter = %4d Start table = %4d Final table = %4d\n", Pivot, nIters, nRowsOld, nRows ); - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; return RetValue; } int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); - abctime clk, clkSat = 0, clkEnu = 0, clkAll; + abctime clk; word Onset[64] = {0}, Offset[64] = {0}, Cube; word CoverRows[64] = {0}, CoverCols[64] = {0}; int nIters, nItersMax = 32; @@ -1171,12 +1162,11 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) //sat_solver_delete_p( &p->pSat ); p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; - clkAll = Abc_Clock(); assert( nConsts <= 8 ); clk = Abc_Clock(); RetValue = Sbd_ManCollectConstantsNew( p->pSat, p->vDivVars, nConsts, PivotVar, Onset, Offset ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( RetValue >= 0 ) { if ( p->pPars->fVeryVerbose ) @@ -1215,21 +1205,18 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) { if ( p->pPars->fVeryVerbose ) printf( "Cannot find a feasible cover.\n" ); - clkEnu += Abc_Clock() - clk; - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; + p->timeCov += Abc_Clock() - clk; return 0; } - + p->timeCov += Abc_Clock() - clk; + if ( p->pPars->fVeryVerbose ) printf( "Candidate support: " ), Vec_IntPrint( p->vDivSet ); clk = Abc_Clock(); *pTruth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); - clkSat += Abc_Clock() - clk; + p->timeSat += Abc_Clock() - clk; if ( *pTruth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); @@ -1271,65 +1258,42 @@ int Sbd_ManExplore2( Sbd_Man_t * p, int Pivot, word * pTruth ) break; } } - clkAll = Abc_Clock() - clkAll - clkSat - clkEnu; - p->timeSat += clkSat; - p->timeCov += clkAll; - p->timeEnu += clkEnu; return RetValue; } -int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +int Sbd_ManExploreCut( Sbd_Man_t * p, int Pivot, int nLeaves, int * pLeaves, int * pnStrs, Sbd_Str_t * Strs, int * pFreeVar ) { - extern int Sbd_ProblemSolve( - Gia_Man_t * p, Vec_Int_t * vMirrors, - int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, - Vec_Int_t * vTfo, Vec_Int_t * vRoots, - Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 - ); - extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); - extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); abctime clk = Abc_Clock(); - word Truth; - int PivotVar = Vec_IntEntry(p->vObj2Var, Pivot); - int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); - //int nDivs = Vec_IntSize( p->vDivVars ); int Delay = Vec_IntEntry( p->vLutLevs, Pivot ); - int i, k, iObj, nIters, RetValue; + int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX], pNodesBot1[SBD_DIV_MAX], pNodesBot2[SBD_DIV_MAX]; + int nNodesTop = 0, nNodesBot = 0, nNodesBot1 = 0, nNodesBot2 = 0, nNodesDiff = 0, nNodesDiff1 = 0, nNodesDiff2 = 0; + int i, k, iObj, nIters, RetValue = 0; - int nLeaves, pLeaves[SBD_DIV_MAX]; - - int pNodesTop[SBD_DIV_MAX], pNodesBot[SBD_DIV_MAX];//, pNodeRefs[SBD_DIV_MAX]; - int nNodesTop = 0, nNodesBot = 0, nNodesDiff = 0; - - //sat_solver_delete_p( &p->pSat ); - p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); - p->timeCnf += Abc_Clock() - clk; - - // extract one cut - nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, pLeaves ); - if ( nLeaves == -1 ) - return 0; - - // solve the covering problem + // try to remove fanins for ( nIters = 0; nIters < nLeaves; nIters++ ) { + word Truth; // try to remove one variable from divisors Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) - if ( i != nIters && pLeaves[i] != -1 ) + if ( i != nLeaves-1-nIters && pLeaves[i] != -1 ) Vec_IntPush( p->vDivSet, Vec_IntEntry(p->vObj2Var, pLeaves[i]) ); assert( Vec_IntSize(p->vDivSet) < nLeaves ); // compute truth table clk = Abc_Clock(); - Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; if ( Truth == SBD_SAT_UNDEC ) printf( "Node %d: Undecided.\n", Pivot ); else if ( Truth == SBD_SAT_SAT ) - continue; + { + int DelayDiff = Vec_IntEntry(p->vLutLevs, pLeaves[nLeaves-1-nIters]) - Delay; + if ( DelayDiff > -2 ) + return 0; + } else - pLeaves[nIters] = -1; + pLeaves[nLeaves-1-nIters] = -1; } Vec_IntClear( p->vDivSet ); for ( i = 0; i < nLeaves; i++ ) @@ -1338,13 +1302,14 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) //printf( "Reduced %d -> %d\n", nLeaves, Vec_IntSize(p->vDivSet) ); if ( Vec_IntSize(p->vDivSet) <= p->pPars->nLutSize ) { + word Truth; *pnStrs = 1; // remap divisors Vec_IntForEachEntry( p->vDivSet, iObj, i ) Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); // compute truth table clk = Abc_Clock(); - Truth = Sbd_ManSolve( p->pSat, PivotVar, FreeVar+nIters, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); + Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); // create structure @@ -1360,7 +1325,7 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) assert( Vec_IntSize(p->vDivSet) > p->pPars->nLutSize ); // count number of nodes on each level - nNodesTop = 0, nNodesBot = 0; + nNodesTop = nNodesBot = nNodesBot1 = nNodesBot2 = 0; Vec_IntForEachEntry( p->vDivSet, iObj, i ) { int DelayDiff = Vec_IntEntry(p->vLutLevs, iObj) - Delay; @@ -1369,60 +1334,227 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) if ( DelayDiff == -2 ) pNodesTop[nNodesTop++] = i; else // if ( DelayDiff < -2 ) + { pNodesBot[nNodesBot++] = i; + if ( DelayDiff == -3 ) + pNodesBot1[nNodesBot1++] = i; + else // if ( DelayDiff < -3 ) + pNodesBot2[nNodesBot2++] = i; + } Vec_IntWriteEntry( p->vDivSet, i, Vec_IntEntry(p->vObj2Var, iObj) ); - //pNodeRefs[i] = Gia_ObjRefNumId( p->pGia, iObj ); } + assert( nNodesBot == nNodesBot1 + nNodesBot2 ); if ( i < Vec_IntSize(p->vDivSet) ) return 0; if ( nNodesTop > p->pPars->nLutSize-1 ) return 0; - if ( nNodesBot > p->pPars->nLutSize ) + + // try 44 + if ( Vec_IntSize(p->vDivSet) <= 2*p->pPars->nLutSize-1 ) { - // move left-over to the top - while ( nNodesBot > p->pPars->nLutSize ) - pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot]; - assert( nNodesBot == p->pPars->nLutSize ); + int nMoved = 0; + if ( nNodesBot > p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot > p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot], nMoved++; + assert( nNodesBot == p->pPars->nLutSize ); + } + assert( nNodesBot <= p->pPars->nLutSize ); assert( nNodesTop <= p->pPars->nLutSize-1 ); - } - nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; - - // number of structures - *pnStrs = 2 + nNodesDiff; - - Strs[0].fLut = 1; - Strs[0].nVarIns = p->pPars->nLutSize; - for ( i = 0; i < nNodesTop; i++ ) - Strs[0].VarIns[i] = pNodesTop[i]; - for ( ; i < p->pPars->nLutSize; i++ ) - Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; - Strs[0].Res = 0; - - Strs[1].fLut = 1; - Strs[1].nVarIns = nNodesBot; - for ( i = 0; i < nNodesBot; i++ ) - Strs[1].VarIns[i] = pNodesBot[i]; - Strs[1].Res = 0; - - for ( k = 0; k < nNodesDiff; k++ ) - { - Strs[2+k].fLut = 0; - Strs[2+k].nVarIns = nNodesBot; + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; + + Strs[1].fLut = 1; + Strs[1].nVarIns = nNodesBot; for ( i = 0; i < nNodesBot; i++ ) - Strs[2+k].VarIns[i] = pNodesBot[i]; - Strs[2+k].Res = 0; + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + nNodesDiff = p->pPars->nLutSize-1 - nNodesTop; + assert( nNodesDiff >= 0 && nNodesDiff <= 3 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[2+k].fLut = 0; + Strs[2+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[2+k].VarIns[i] = pNodesBot[i]; + Strs[2+k].Res = 0; + } + + *pnStrs = 2 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[2]++; + + while ( nMoved-- ) + pNodesBot[nNodesBot++] = pNodesTop[--nNodesTop]; } - clk = Abc_Clock(); - RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, - Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, - p->vDivSet, *pnStrs, Strs ); - p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + return RetValue; + if ( p->pPars->nLutNum < 3 ) + return 0; + if ( Vec_IntSize(p->vDivSet) < 2*p->pPars->nLutSize-1 ) + return 0; + + // try 444 -- LUT(LUT, LUT) + if ( nNodesTop <= p->pPars->nLutSize-2 ) + { + int nMoved = 0; + if ( nNodesBot > 2*p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot > 2*p->pPars->nLutSize ) + pNodesTop[nNodesTop++] = pNodesBot[--nNodesBot], nMoved++; + assert( nNodesBot == 2*p->pPars->nLutSize ); + } + assert( nNodesBot > p->pPars->nLutSize ); + assert( nNodesBot <= 2*p->pPars->nLutSize ); + assert( nNodesTop <= p->pPars->nLutSize-2 ); + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+1 + i-nNodesTop; + Strs[0].Res = 0; + + Strs[1].fLut = 1; + Strs[1].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < Strs[1].nVarIns; i++ ) + Strs[1].VarIns[i] = pNodesBot[i]; + Strs[1].Res = 0; + + Strs[2].fLut = 1; + Strs[2].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < Strs[2].nVarIns; i++ ) + Strs[2].VarIns[i] = pNodesBot[nNodesBot-p->pPars->nLutSize+i]; + Strs[2].Res = 0; + + nNodesDiff = p->pPars->nLutSize-2 - nNodesTop; + assert( nNodesDiff >= 0 && nNodesDiff <= 2 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[3+k].fLut = 0; + Strs[3+k].nVarIns = nNodesBot; + for ( i = 0; i < nNodesBot; i++ ) + Strs[3+k].VarIns[i] = pNodesBot[i]; + Strs[3+k].Res = 0; + } + + *pnStrs = 3 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[3]++; + + while ( nMoved-- ) + pNodesBot[nNodesBot++] = pNodesTop[--nNodesTop]; + } + if ( RetValue ) + return RetValue; + + // try 444 -- LUT(LUT(LUT)) + if ( nNodesBot1 + nNodesTop <= 2*p->pPars->nLutSize-2 ) + { + if ( nNodesBot2 > p->pPars->nLutSize ) // need to move bottom left-over to the top + { + while ( nNodesBot2 > p->pPars->nLutSize ) + pNodesBot1[nNodesBot1++] = pNodesBot2[--nNodesBot2]; + assert( nNodesBot2 == p->pPars->nLutSize ); + } + if ( nNodesBot1 > p->pPars->nLutSize-1 ) // need to move bottom left-over to the top + { + while ( nNodesBot1 > p->pPars->nLutSize-1 ) + pNodesTop[nNodesTop++] = pNodesBot1[--nNodesBot1]; + assert( nNodesBot1 == p->pPars->nLutSize-1 ); + } + assert( nNodesBot2 <= p->pPars->nLutSize ); + assert( nNodesBot1 <= p->pPars->nLutSize-1 ); + assert( nNodesTop <= p->pPars->nLutSize-1 ); + + Strs[0].fLut = 1; + Strs[0].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesTop; i++ ) + Strs[0].VarIns[i] = pNodesTop[i]; + Strs[0].VarIns[i++] = Vec_IntSize(p->vDivSet)+1; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[0].VarIns[i] = Vec_IntSize(p->vDivSet)+2 + i-nNodesTop; + Strs[0].Res = 0; + nNodesDiff1 = p->pPars->nLutSize-1 - nNodesTop; + + Strs[1].fLut = 1; + Strs[1].nVarIns = p->pPars->nLutSize; + for ( i = 0; i < nNodesBot1; i++ ) + Strs[1].VarIns[i] = pNodesBot1[i]; + Strs[1].VarIns[i++] = Vec_IntSize(p->vDivSet)+2; + for ( ; i < p->pPars->nLutSize; i++ ) + Strs[1].VarIns[i] = Vec_IntSize(p->vDivSet)+2+nNodesDiff1 + i-nNodesBot1; + Strs[1].Res = 0; + nNodesDiff2 = p->pPars->nLutSize-1 - nNodesBot1; + + Strs[2].fLut = 1; + Strs[2].nVarIns = nNodesBot2; + for ( i = 0; i < Strs[2].nVarIns; i++ ) + Strs[2].VarIns[i] = pNodesBot2[i]; + Strs[2].Res = 0; + + nNodesDiff = nNodesDiff1 + nNodesDiff2; + assert( nNodesDiff >= 0 && nNodesDiff <= 3 ); + for ( k = 0; k < nNodesDiff; k++ ) + { + Strs[3+k].fLut = 0; + Strs[3+k].nVarIns = nNodesBot2; + for ( i = 0; i < nNodesBot2; i++ ) + Strs[3+k].VarIns[i] = pNodesBot2[i]; + Strs[3+k].Res = 0; + if ( k >= nNodesDiff1 ) + continue; + Strs[3+k].nVarIns += nNodesBot1; + for ( i = 0; i < nNodesBot1; i++ ) + Strs[3+k].VarIns[nNodesBot2 + i] = pNodesBot1[i]; + } - if ( RetValue ) - p->nLuts[2]++; + *pnStrs = 3 + nNodesDiff; + clk = Abc_Clock(); + RetValue = Sbd_ProblemSolve( p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, p->vDivSet, *pnStrs, Strs ); + p->timeQbf += Abc_Clock() - clk; + if ( RetValue ) + p->nLuts[4]++; + } return RetValue; } +int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) +{ + int FreeVar = Vec_IntSize(p->vWinObjs) + Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots); + int FreeVarStart = FreeVar; + int nSize, nLeaves, pLeaves[SBD_DIV_MAX]; + //sat_solver_delete_p( &p->pSat ); + abctime clk = Abc_Clock(); + p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); + p->timeCnf += Abc_Clock() - clk; + // extract one cut + for ( nSize = p->pPars->nLutSize + 1; nSize <= p->pPars->nCutSize; nSize++ ) + { + nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, nSize, pLeaves ); + if ( nLeaves == -1 ) + continue; + assert( nLeaves == nSize ); + if ( Sbd_ManExploreCut( p, Pivot, nLeaves, pLeaves, pnStrs, Strs, &FreeVar ) ) + return 1; + } + assert( FreeVar - FreeVarStart <= SBD_FVAR_MAX ); + return 0; +} /**Function************************************************************* @@ -1722,7 +1854,10 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) // extend data-structure to accommodate new nodes assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) + { + Vec_IntPush( p->vMirrors, -1 ); Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); + } Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { @@ -1730,7 +1865,6 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); Vec_IntPush( p->vObj2Var, 0 ); - Vec_IntPush( p->vMirrors, -1 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); //Sbd_ManFindCut( p, i, p->vLits ); for ( k = 0; k < 4; k++ ) @@ -1820,22 +1954,16 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[4]; - int i, RetValue, nStrs = 0; - word Truth = 0; - - if ( !p->pSto ) - { - if ( Sbd_ManMergeCuts( p, Pivot ) ) - return; - } - -// if ( Pivot != 15 ) -// return; - - if ( Sbd_ManWindow( p, Pivot ) ) + Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; + int RetValue, nStrs = 0; + if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; - + if ( !Sbd_ManWindow( p, Pivot ) ) + return; + //if ( Vec_IntSize(p->vWinObjs) > 100 ) + // printf( "Obj %d : Win = %d TFO = %d. Roots = %d.\n", Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vTfo), Vec_IntSize(p->vRoots) ); + p->nTried++; + p->nUsed++; RetValue = Sbd_ManCheckConst( p, Pivot ); if ( RetValue >= 0 ) { @@ -1844,6 +1972,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) } else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { + int i; Strs->fLut = 1; Strs->nVarIns = Vec_IntSize( p->vDivSet ); for ( i = 0; i < Strs->nVarIns; i++ ) @@ -1855,8 +1984,17 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + if ( !p->pPars->fVerbose ) + return; + if ( Vec_IntSize(p->vDivSet) <= 4 ) + printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); + else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) + printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + else + printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); } + else + p->nUsed--; } Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { @@ -1875,6 +2013,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( pGia ); Tim_Man_t * pTimOld = (Tim_Man_t *)pGia->pManTime; pGia->pManTime = Tim_ManDup( pTimOld, 1 ); + //Tim_ManPrint( pGia->pManTime ); Tim_ManIncrementTravId( (Tim_Man_t *)pGia->pManTime ); Gia_ManForEachObjVec( vNodes, pGia, pObj, k ) { @@ -1883,9 +2022,11 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) break; if ( Gia_ObjIsAnd(pObj) ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 ) + if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) Sbd_NtkPerformOne( p, Pivot ); } else if ( Gia_ObjIsCi(pObj) ) @@ -1903,7 +2044,6 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Sbd_StoComputeCutsConst0( p->pSto, 0 ); else assert( 0 ); } - //Tim_ManPrint( pGia->pManTime ); Tim_ManStop( (Tim_Man_t *)pGia->pManTime ); pGia->pManTime = pTimOld; Vec_IntFree( vNodes ); @@ -1919,29 +2059,33 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Sbd_StoComputeCutsCi( p->pSto, Pivot, 0, 0 ); else if ( Gia_ObjIsAnd(pObj) ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 ) + if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) Sbd_NtkPerformOne( p, Pivot ); } //if ( nNodesOld != Gia_ManObjNum(pGia) ) // break; } } - printf( "Found %d constants, %d one-LUT and %d two-LUT replacements with delay %d. ", - p->nLuts[0], p->nLuts[1], p->nLuts[2], Sbd_ManDelay(p) ); + printf( "K = %d. S = %d. N = %d. P = %d. ", + p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); + printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", + p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); pNew = Sbd_ManDerive( pGia, p->vMirrors ); // print runtime statistics - p->timeOther = p->timeTotal - p->timeWin - p->timeCnf - p->timeSat - p->timeCov - p->timeEnu - p->timeQbf; - if ( p->pPars->fVerbose ) + p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; + //if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); + ABC_PRTP( "Cut", p->timeCut , p->timeTotal ); + ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); ABC_PRTP( "Cnf", p->timeCnf , p->timeTotal ); ABC_PRTP( "Sat", p->timeSat , p->timeTotal ); - ABC_PRTP( "Cov", p->timeCov , p->timeTotal ); - ABC_PRTP( "Enu", p->timeEnu , p->timeTotal ); ABC_PRTP( "Qbf", p->timeQbf , p->timeTotal ); ABC_PRTP( "Oth", p->timeOther, p->timeTotal ); ABC_PRTP( "ALL", p->timeTotal, p->timeTotal ); diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 9c54c74a..7bcf2189 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -27,9 +27,9 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define SBD_MAX_CUTSIZE 8 -#define SBD_MAX_CUTNUM 1001 -#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) +#define SBD_MAX_CUTSIZE 10 +#define SBD_MAX_CUTNUM 501 +#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1) #define SBD_CUT_NO_LEAF 0xF @@ -568,6 +568,7 @@ static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut ) { int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia)); int Delay = Vec_IntEntry(p->vDelays, iObj); + if ( pCut == NULL ) { printf( "No cut.\n" ); return; } printf( "%d {", pCut->nLeaves ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) printf( " %*d", nDigits, pCut->pLeaves[i] ); @@ -724,45 +725,88 @@ int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) Sbd_StoMergeCuts( p, iObj ); return Vec_IntEntry( p->vDelays, iObj ); } +int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ) +{ + return Vec_IntEntry(p->vRefs, iObj); +} void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ) { Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); assert( iObj == Vec_IntSize(p->vRefs) ); assert( iMirror < iObj ); - Vec_IntPush( p->vRefs, iMirror > 0 ? Vec_IntEntry(p->vRefs, iMirror) : 0 ); + Vec_IntPush( p->vRefs, 0 ); +//printf( "Ref %d\n", iObj ); + if ( iMirror > 0 ) + { + Vec_IntWriteEntry( p->vRefs, iObj, Vec_IntEntry(p->vRefs, iMirror) ); + Vec_IntWriteEntry( p->vRefs, iMirror, 1 ); + } if ( Gia_ObjIsAnd(pObj) ) { - Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); - Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId1(pObj, iObj), 1 ); + int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + int Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + Vec_IntAddToEntry( p->vRefs, Fan0, 1 ); + Vec_IntAddToEntry( p->vRefs, Fan1, 1 ); } else if ( Gia_ObjIsCo(pObj) ) + { + int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + assert( Lit0m == -1 ); Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 ); + } } void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ) { - Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj); + Gia_Obj_t * pObj; + int Lit0m, Lit1m, Fan0, Fan1; + return; + + pObj = Gia_ManObj(p->pGia, iObj); + if ( Vec_IntEntry(p->vRefs, iObj) == 0 ) + printf( "Ref count mismatch at node %d\n", iObj ); + assert( Vec_IntEntry(p->vRefs, iObj) > 0 ); Vec_IntAddToEntry( p->vRefs, iObj, -1 ); if ( Vec_IntEntry( p->vRefs, iObj ) > 0 ) return; if ( Gia_ObjIsCi(pObj) ) return; +//printf( "Deref %d\n", iObj ); assert( Gia_ObjIsAnd(pObj) ); - Sbd_StoDerefObj( p, Gia_ObjFaninId0(pObj, iObj) ); - Sbd_StoDerefObj( p, Gia_ObjFaninId1(pObj, iObj) ); + Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + if ( Fan0 ) Sbd_StoDerefObj( p, Fan0 ); + if ( Fan1 ) Sbd_StoDerefObj( p, Fan1 ); } -int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ) +int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ) { + int fVerbose = 0; Sbd_Cut_t * pCutBest = NULL; int i; assert( p->Pivot == iObj ); + if ( fVerbose && iObj % 1000 == 0 ) + printf( "Node %6d : \n", iObj ); for ( i = 0; i < p->nCutsR; i++ ) + { + if ( fVerbose && iObj % 1000 == 0 ) + Sbd_CutPrint( p, iObj, p->ppCuts[i] ); + if ( nSize && (int)p->ppCuts[i]->nLeaves != nSize ) + continue; if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize && - (int)p->ppCuts[i]->nSlowLeaves == 0 && + (int)p->ppCuts[i]->nSlowLeaves <= 1 && (int)p->ppCuts[i]->nTopLeaves <= p->nLutSize-1 && (pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) ) pCutBest = p->ppCuts[i]; + } + if ( fVerbose && iObj % 1000 == 0 ) + { + printf( "Best cut of size %d:\n", nSize ); + Sbd_CutPrint( p, iObj, pCutBest ); + } if ( pCutBest == NULL ) return -1; -//Sbd_CutPrint( p, iObj, pCutBest ); assert( pCutBest->nLeaves <= SBD_DIV_MAX ); for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) pLeaves[i] = pCutBest->pLeaves[i]; diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index d54285f8..668c1231 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -52,9 +52,10 @@ ABC_NAMESPACE_HEADER_START #define SBD_SAT_UNDEC 0x1234567812345678 #define SBD_SAT_SAT 0x8765432187654321 -#define SBD_LUTS_MAX 2 -#define SBD_SIZE_MAX 4 -#define SBD_DIV_MAX 8 +#define SBD_LUTS_MAX 2 +#define SBD_SIZE_MAX 4 +#define SBD_DIV_MAX 10 +#define SBD_FVAR_MAX 100 //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// @@ -81,16 +82,28 @@ struct Sbd_Str_t_ //////////////////////////////////////////////////////////////////////// /*=== sbdCut.c ==========================================================*/ -extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); -extern void Sbd_StoFree( Sbd_Sto_t * p ); -extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); -extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); -extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); -extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); -extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); -extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); -extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int * pLeaves ); - +extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose ); +extern void Sbd_StoFree( Sbd_Sto_t * p ); +extern int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror ); +extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); +extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); +/*=== sbdWin.c ==========================================================*/ +extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); +extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); +extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); +extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); +/*=== sbdQbf.c ==========================================================*/ +extern int Sbd_ProblemSolve( + Gia_Man_t * p, Vec_Int_t * vMirrors, + int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, + Vec_Int_t * vTfo, Vec_Int_t * vRoots, + Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 + ); ABC_NAMESPACE_HEADER_END diff --git a/src/opt/sbd/sbdLut.c b/src/opt/sbd/sbdLut.c index e8aee790..ffcb71f8 100644 --- a/src/opt/sbd/sbdLut.c +++ b/src/opt/sbd/sbdLut.c @@ -96,7 +96,6 @@ int Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, } } } -//printf( "Stop par = %d.\n", VarPar ); return 1; } void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 ) diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index d5b7dd9d..b62332d1 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -54,7 +54,6 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ) { Gia_Obj_t * pObj; - int nAddVars = 64; int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue; int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo); int PivotVar = Vec_IntEntry(vObj2Var, Pivot); @@ -67,7 +66,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi pSat = sat_solver_new(); else sat_solver_restart( pSat ); - sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + nAddVars ); + sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + SBD_FVAR_MAX ); // create constant 0 clause sat_solver_addclause( pSat, &iLit, &iLit + 1 ); // add clauses for all nodes @@ -139,7 +138,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi sat_solver_delete( pSat ); return NULL; } - assert( sat_solver_nvars(pSat) == nVars + nAddVars ); + assert( sat_solver_nvars(pSat) == nVars + SBD_FVAR_MAX ); } else if ( fQbf ) { -- cgit v1.2.3 From 8eb5d1896a82ef9d1d5e0f25bb6f23e29e9e2ada Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 21:46:25 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 10 ++++++++++ src/opt/sbd/sbdWin.c | 2 ++ 2 files changed, 12 insertions(+) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a48e6489..251a4deb 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -52,6 +52,7 @@ struct Sbd_Man_t_ abctime timeCnf; abctime timeSat; abctime timeQbf; + abctime timeNew; abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; @@ -440,7 +441,10 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Gia_ObjSetTravIdCurrentId(p->pGia, 0); Sbd_ManWindowSim_rec( p, Pivot ); if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + { + p->timeWin += Abc_Clock() - clk; return 0; + } Sbd_ManUpdateOrder( p, Pivot ); assert( Vec_IntSize(p->vDivVars) == Vec_IntSize(p->vDivValues) ); assert( Vec_IntSize(p->vDivVars) < Vec_IntSize(p->vWinObjs) ); @@ -466,7 +470,10 @@ int Sbd_ManWindow( Sbd_Man_t * p, int Pivot ) Vec_IntPush( p->vWinObjs, Abc_Lit2Var(Node) ); } if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vWinObjs) > p->pPars->nWinSizeMax ) + { + p->timeWin += Abc_Clock() - clk; return 0; + } // compute controlability for node if ( Vec_IntSize(p->vTfo) == 0 ) Abc_TtFill( Sbd_ObjSim2(p, Pivot), p->pPars->nWords ); @@ -1855,13 +1862,16 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) assert( Vec_IntSize(p->vLutLevs) == iObjLast ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + assert( i == Vec_IntSize(p->vMirrors) ); Vec_IntPush( p->vMirrors, -1 ); Sbd_StoRefObj( p->pSto, i, i == Gia_ManObjNum(p->pGia)-1 ? Pivot : -1 ); } Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); + p->timeCut += Abc_Clock() - clk; assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); Vec_IntPush( p->vObj2Var, 0 ); diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c index b62332d1..069a4125 100644 --- a/src/opt/sbd/sbdWin.c +++ b/src/opt/sbd/sbdWin.c @@ -360,6 +360,7 @@ void Sbd_ManSolverPrint( Vec_Int_t * vSop ) } Cube[pInds[Abc_Lit2Var(Entry)]] = '1' - (char)Abc_LitIsCompl(Entry); } + Supp = 0; } void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots ) { @@ -378,6 +379,7 @@ void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars ); //Sbd_ManSolverPrint( vSop ); printf( "SAT with %d vars and %d cubes.\n", nVars, Vec_IntCountEntry(vSop, -1) ); + Supp = 0; } Vec_IntFree( vTemp ); Vec_IntFree( vSop ); -- cgit v1.2.3 From 3f2899d6ea1a141f40d7fdfe4556bb349d53c250 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 22:00:26 +0700 Subject: Compiler warnings. --- src/base/main/mainReal.c | 4 ++-- src/map/scl/sclLiberty.c | 6 +++--- src/misc/util/utilTruth.h | 6 +++--- src/misc/vec/vecPtr.h | 2 +- src/opt/lpk/lpkCore.c | 6 +++--- src/opt/lpk/lpkCut.c | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/base/main/mainReal.c b/src/base/main/mainReal.c index ee43d38d..31bfef75 100644 --- a/src/base/main/mainReal.c +++ b/src/base/main/mainReal.c @@ -196,7 +196,7 @@ int Abc_RealMain( int argc, char * argv[] ) case 't': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { - if ( !strcmp(globalUtilOptarg, "none") == 0 ) + if ( (!strcmp(globalUtilOptarg, "none")) == 0 ) { fInitRead = 1; sprintf( sReadCmd, "read_%s", globalUtilOptarg ); @@ -211,7 +211,7 @@ int Abc_RealMain( int argc, char * argv[] ) case 'T': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { - if (!strcmp(globalUtilOptarg, "none") == 0) + if ( (!strcmp(globalUtilOptarg, "none")) == 0) { fFinalWrite = 1; sprintf( sWriteCmd, "write_%s", globalUtilOptarg); diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 50e69d08..5ecf76bb 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -509,7 +509,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents ) { FILE * pFile = fopen( pFileName, "rb" ); char * pContents = ABC_ALLOC( char, nContents+1 ); - int RetValue; + int RetValue = 0; RetValue = fread( pContents, nContents, 1, pFile ); fclose( pFile ); pContents[nContents] = 0; @@ -518,7 +518,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents ) void Scl_LibertyStringDump( char * pFileName, Vec_Str_t * vStr ) { FILE * pFile = fopen( pFileName, "wb" ); - int RetValue; + int RetValue = 0; if ( pFile == NULL ) { printf( "Scl_LibertyStringDump(): The output file is unavailable.\n" ); @@ -583,7 +583,7 @@ Scl_Tree_t * Scl_LibertyParse( char * pFileName, int fVerbose ) return NULL; pPos = p->pContents; Scl_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents ); - if ( !Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 ) + if ( (!Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents )) == 0 ) { if ( p->pError ) printf( "%s", p->pError ); printf( "Parsing failed. " ); diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index b8a34da7..d77ed64d 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -2612,7 +2612,7 @@ static inline int Abc_TtProcessBiDec( word * pTruth, int nVars, int nSuppLim ) static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLim ) { word This, That, pTemp[64]; - int Res, resThis, resThat, nThis, nThat; + int Res, resThis, resThat;//, nThis, nThat; int nWords = Abc_TtWordNum(nVars); Abc_TtCopy( pTemp, pTruth, nWords, 0 ); Res = Abc_TtProcessBiDec( pTemp, nVars, nSuppLim ); @@ -2634,8 +2634,8 @@ static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLi // Dau_DsdPrintFromTruth( pTemp, nVars ); - nThis = Abc_TtBitCount16(resThis); - nThat = Abc_TtBitCount16(resThat); + //nThis = Abc_TtBitCount16(resThis); + //nThat = Abc_TtBitCount16(resThat); printf( "Variable sets: " ); Abc_TtPrintVarSet( resThis, nVars ); diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h index 5b40665f..015aa1be 100644 --- a/src/misc/vec/vecPtr.h +++ b/src/misc/vec/vecPtr.h @@ -65,7 +65,7 @@ struct Vec_Ptr_t_ #define Vec_PtrForEachEntryTwo( Type1, vVec1, Type2, vVec2, pEntry1, pEntry2, i ) \ for ( i = 0; (i < Vec_PtrSize(vVec1)) && (((pEntry1) = (Type1)Vec_PtrEntry(vVec1, i)), 1) && (((pEntry2) = (Type2)Vec_PtrEntry(vVec2, i)), 1); i++ ) #define Vec_PtrForEachEntryDouble( Type1, Type2, vVec, Entry1, Entry2, i ) \ - for ( i = 0; (i+1 < Vec_IntSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 ) + for ( i = 0; (i+1 < Vec_PtrSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// diff --git a/src/opt/lpk/lpkCore.c b/src/opt/lpk/lpkCore.c index a9088d10..6595b365 100644 --- a/src/opt/lpk/lpkCore.c +++ b/src/opt/lpk/lpkCore.c @@ -96,12 +96,12 @@ void Lpk_IfManStart( Lpk_Man_t * p ) int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode ) { Vec_Ptr_t * vNodes; - Abc_Obj_t * pTemp; + Abc_Obj_t * pTemp, * pTemp2; int i; vNodes = Vec_VecEntry( p->vVisited, iNode ); if ( Vec_PtrSize(vNodes) == 0 ) return 1; - Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pTemp, i ) + Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pTemp, pTemp2, i ) { // check if the node has changed pTemp = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pTemp ); @@ -110,7 +110,7 @@ int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode ) // check if the number of fanouts has changed // if ( Abc_ObjFanoutNum(pTemp) != (int)Vec_PtrEntry(vNodes, i+1) ) // return 1; - i++; +// i++; } return 0; } diff --git a/src/opt/lpk/lpkCut.c b/src/opt/lpk/lpkCut.c index 73711f2b..208facf2 100644 --- a/src/opt/lpk/lpkCut.c +++ b/src/opt/lpk/lpkCut.c @@ -234,7 +234,7 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p ) { Lpk_Cut_t * pCut; Vec_Ptr_t * vNodes = Vec_VecEntry( p->vVisited, p->pObj->Id ); - Abc_Obj_t * pNode; + Abc_Obj_t * pNode, * pNode2; int i, k; // collect the nodes that impact the given node Vec_PtrClear( vNodes ); @@ -252,11 +252,11 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p ) } } // clear the marks - Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i ) + Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pNode, pNode2, i ) { pNode = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pNode ); pNode->fMarkC = 0; - i++; +// i++; } //printf( "%d ", Vec_PtrSize(vNodes) ); } -- cgit v1.2.3 From 290c70f73e023434bee208eb4d8161541096bebe Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 22:56:30 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 251a4deb..a36b4bd2 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1883,7 +1883,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) } // make sure delay reduction is achieved iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); - assert( iNewLev < iCurLev ); + assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); -- cgit v1.2.3 From ab8db51f37581f247991c16f3ec11ef2674f1934 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 23:10:16 +0700 Subject: Updates to delay optimization project. --- src/opt/dau/dauGia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 8b0a76c3..fa757e62 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -361,7 +361,7 @@ int Dau_DsdToGia_rec( Gia_Man_t * pGia, char * pStr, char ** p, int * pMatches, if ( pGia->pMuxes ) Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] ); else - Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] ); + Res = Gia_ManAppendMux2( pGia, Temp[0], Temp[1], Temp[2] ); } else { -- cgit v1.2.3 From 39f32259957884645450ba345426f7f030f14713 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 00:32:19 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a36b4bd2..a6ae8bbb 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1851,7 +1851,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Vec_IntWriteEntry( p->vLits, Vec_IntSize(p->vLits)-nStrs+i, iLit ); } iLit = Vec_IntEntry( p->vLits, Vec_IntSize(p->vDivSet) ); - assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); + //assert( iObjLast == Gia_ManObjNum(p->pGia) || Abc_Lit2Var(iLit) == Gia_ManObjNum(p->pGia)-1 ); // remember this function assert( Vec_IntEntry(p->vMirrors, Pivot) == -1 ); Vec_IntWriteEntry( p->vMirrors, Pivot, iLit ); -- cgit v1.2.3 From 278c00242f7c3ca46858ece6682749cca06a5deb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 00:33:06 +0700 Subject: Compiler warnings. --- src/misc/zlib/inflate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/misc/zlib/inflate.c b/src/misc/zlib/inflate.c index 449779a9..9fae7045 100644 --- a/src/misc/zlib/inflate.c +++ b/src/misc/zlib/inflate.c @@ -1445,7 +1445,7 @@ long ZEXPORT inflateMark(z_streamp strm) { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + if (strm == Z_NULL || strm->state == Z_NULL) return -(1L << 16); state = (struct inflate_state FAR *)strm->state; return ((long)(state->back) << 16) + (state->mode == COPY ? state->length : -- cgit v1.2.3 From 1fef441a0dfde7887c18d218749c0f8d2d75f5ee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 11:01:47 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index a6ae8bbb..fa4cbc82 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -360,12 +360,14 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) if ( p->DivCutoff == -1 ) p->DivCutoff = 0; // verify +/* assert( Vec_IntSize(p->vDivVars) < 64 ); Vec_IntForEachEntryStart( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); +*/ //printf( "%d ", Vec_IntSize(p->vDivVars) ); // printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", // Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); -- cgit v1.2.3 From 4b20003e0cdec5d4d88ecf360c806e786272ab39 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 11:04:28 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index fa4cbc82..f8af9a4a 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -366,8 +366,8 @@ void Sbd_ManUpdateOrder( Sbd_Man_t * p, int Pivot ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) == LevelMax - 2 ); Vec_IntForEachEntryStop( p->vDivVars, Node, i, p->DivCutoff ) assert( Vec_IntEntry(p->vLutLevs, Vec_IntEntry(p->vWinObjs, Node)) < LevelMax - 2 ); - Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); */ + Vec_IntFill( p->vDivValues, Vec_IntSize(p->vDivVars), 0 ); //printf( "%d ", Vec_IntSize(p->vDivVars) ); // printf( "Node %4d : Win = %5d. Divs = %5d. D1 = %5d. D2 = %5d.\n", // Pivot, Vec_IntSize(p->vWinObjs), Vec_IntSize(p->vDivVars), Vec_IntSize(p->vDivVars)-p->DivCutoff, p->DivCutoff ); -- cgit v1.2.3 From 385cb73d32de7e7d18da68fffe6fd089cb7930b2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 19:47:30 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/module.make | 1 + src/opt/sbd/sbdCore.c | 29 +++- src/opt/sbd/sbdCut2.c | 432 ++++++++++++++++++++++++++++++++++++++++++++++++ src/opt/sbd/sbdInt.h | 7 + 4 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 src/opt/sbd/sbdCut2.c (limited to 'src') diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index 3bdc20b3..a9a6c3be 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -2,6 +2,7 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCnf.c \ src/opt/sbd/sbdCore.c \ src/opt/sbd/sbdCut.c \ + src/opt/sbd/sbdCut2.c \ src/opt/sbd/sbdLut.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index f8af9a4a..c9e92d73 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -56,6 +56,7 @@ struct Sbd_Man_t_ abctime timeOther; abctime timeTotal; Sbd_Sto_t * pSto; + Sbd_Srv_t * pSrv; // target node int Pivot; // target node int DivCutoff; // the place where D-2 divisors begin @@ -230,7 +231,8 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 1, 1 ); + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, 1, 1 ); + p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -257,6 +259,7 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_WrdFree( p->vMatrix ); sat_solver_delete_p( &p->pSat ); Sbd_StoFree( p->pSto ); + Sbd_ManCutServerStop( p->pSrv ); ABC_FREE( p ); } @@ -1320,6 +1323,11 @@ int Sbd_ManExploreCut( Sbd_Man_t * p, int Pivot, int nLeaves, int * pLeaves, int clk = Abc_Clock(); Truth = Sbd_ManSolve( p->pSat, PivotVar, (*pFreeVar)++, p->vDivSet, p->vDivVars, p->vDivValues, p->vLits ); p->timeSat += Abc_Clock() - clk; + if ( Truth == SBD_SAT_SAT ) + { + printf( "The cut at node %d is not topological.\n", p->Pivot ); + return 0; + } assert( Truth != SBD_SAT_UNDEC && Truth != SBD_SAT_SAT ); // create structure Strs->fLut = 1; @@ -1552,6 +1560,17 @@ int Sbd_ManExplore3( Sbd_Man_t * p, int Pivot, int * pnStrs, Sbd_Str_t * Strs ) p->pSat = Sbd_ManSatSolver( p->pSat, p->pGia, p->vMirrors, Pivot, p->vWinObjs, p->vObj2Var, p->vTfo, p->vRoots, 0 ); p->timeCnf += Abc_Clock() - clk; // extract one cut + if ( p->pSrv ) + { + nLeaves = Sbd_ManCutServerFirst( p->pSrv, Pivot, pLeaves ); + if ( nLeaves == -1 ) + return 0; + assert( nLeaves <= p->pPars->nCutSize ); + if ( Sbd_ManExploreCut( p, Pivot, nLeaves, pLeaves, pnStrs, Strs, &FreeVar ) ) + return 1; + return 0; + } + // extract one cut for ( nSize = p->pPars->nLutSize + 1; nSize <= p->pPars->nCutSize; nSize++ ) { nLeaves = Sbd_StoObjBestCut( p->pSto, Pivot, nSize, pLeaves ); @@ -1679,6 +1698,7 @@ int Sbd_ManMergeCuts( Sbd_Man_t * p, int Node ) assert( iFan0 != iFan1 ); assert( Vec_IntEntry(p->vLutLevs, Node) == 0 ); Vec_IntWriteEntry( p->vLutLevs, Node, LevCur ); + //Vec_IntWriteEntry( p->vLevs, Node, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, iFan0), Vec_IntEntry(p->vLevs, iFan1)) ); assert( pCutRes[0] <= p->pPars->nLutSize ); memcpy( Sbd_ObjCut(p, Node), pCutRes, sizeof(int) * (pCutRes[0] + 1) ); //printf( "Setting node %d with delay %d.\n", Node, LevCur ); @@ -1742,6 +1762,7 @@ void Sbd_ManFindCut( Sbd_Man_t * p, int Node, Vec_Int_t * vCutLits ) // create cut assert( Vec_IntEntry(p->vLutLevs, Node) == 0 ); Vec_IntWriteEntry( p->vLutLevs, Node, LevelMax+1 ); + //Vec_IntWriteEntry( p->vLevs, Node, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Node)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Node))) ); memcpy( Sbd_ObjCut(p, Node), pCut, sizeof(int) * (pCut[0] + 1) ); } @@ -1803,11 +1824,13 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) // update delay of the initial node assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + //Vec_IntWriteEntry( p->vLevs, Pivot, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) ); return 0; } int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) { + Gia_Obj_t * pObj = NULL; int i, k, w, iLit, Node; int iObjLast = Gia_ManObjNum(p->pGia); int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); @@ -1871,11 +1894,13 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { + Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); p->timeCut += Abc_Clock() - clk; assert( i == Vec_IntSize(p->vLutLevs) ); Vec_IntPush( p->vLutLevs, Delay ); + //Vec_IntPush( p->vLevs, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObjI, i)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObjI, i))) ); Vec_IntPush( p->vObj2Var, 0 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); //Sbd_ManFindCut( p, i, p->vLits ); @@ -1887,8 +1912,10 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node + pObj = Gia_ManObj( p->pGia, Pivot ); assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); + //Vec_IntWriteEntry( p->vLevs, Pivot, Pivot ? 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) : 0 ); return 0; } diff --git a/src/opt/sbd/sbdCut2.c b/src/opt/sbd/sbdCut2.c new file mode 100644 index 00000000..9422e439 --- /dev/null +++ b/src/opt/sbd/sbdCut2.c @@ -0,0 +1,432 @@ +/**CFile**************************************************************** + + FileName [sbdCut2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdCut2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SBD_MAX_CUTSIZE 10 +#define SBD_MAX_CUTNUM 501 + +#define SBD_CUT_NO_LEAF 0xF + +typedef struct Sbd_Cut_t_ Sbd_Cut_t; +struct Sbd_Cut_t_ +{ + word Sign; // signature + int iFunc; // functionality + int Cost; // cut cost + int CostLev; // cut cost + unsigned nTreeLeaves : 9; // tree leaves + unsigned nSlowLeaves : 9; // slow leaves + unsigned nTopLeaves : 10; // top leaves + unsigned nLeaves : 4; // leaf count + int pLeaves[SBD_MAX_CUTSIZE]; // leaves +}; + +struct Sbd_Srv_t_ +{ + int nLutSize; + int nCutSize; + int nCutNum; + int fVerbose; + Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes) + Vec_Int_t * vMirrors; // mirrors for each node + Vec_Int_t * vLutLevs; // delays for each node + Vec_Int_t * vLevs; // levels for each node + Vec_Int_t * vRefs; // refs for each node + Sbd_Cut_t pCuts[SBD_MAX_CUTNUM]; // temporary cuts + Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers + abctime clkStart; // starting time + Vec_Int_t * vCut0; // current cut + Vec_Int_t * vCut; // current cut + Vec_Int_t * vCutTop; // current cut + Vec_Int_t * vCutBot; // current cut +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, + Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs, + int nLutSize, int nCutSize, int nCutNum, int fVerbose ) +{ + Sbd_Srv_t * p; + assert( nLutSize <= nCutSize ); + assert( nCutSize < SBD_CUT_NO_LEAF ); + assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE ); + assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM ); + p = ABC_CALLOC( Sbd_Srv_t, 1 ); + p->clkStart = Abc_Clock(); + p->nLutSize = nLutSize; + p->nCutSize = nCutSize; + p->nCutNum = nCutNum; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->vMirrors = vMirrors; + p->vLutLevs = vLutLevs; + p->vLevs = vLevs; + p->vRefs = vRefs; + p->vCut0 = Vec_IntAlloc( 100 ); + p->vCut = Vec_IntAlloc( 100 ); + p->vCutTop = Vec_IntAlloc( 100 ); + p->vCutBot = Vec_IntAlloc( 100 ); + return p; +} +void Sbd_ManCutServerStop( Sbd_Srv_t * p ) +{ + Vec_IntFree( p->vCut0 ); + Vec_IntFree( p->vCut ); + Vec_IntFree( p->vCutTop ); + Vec_IntFree( p->vCutBot ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutIsTopo_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj ) +{ + Gia_Obj_t * pObj; + int Ret0, Ret1; + if ( Vec_IntEntry(vMirrors, iObj) >= 0 ) + iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj)); + if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 1; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Ret0 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Ret1 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + return Ret0 && Ret1; +} +int Sbd_ManCutIsTopo( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vCut, int iObj ) +{ + int i, Entry, RetValue; + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vCut, Entry, i ) + Gia_ObjSetTravIdCurrentId( p, Entry ); + RetValue = Sbd_ManCutIsTopo_rec( p, vMirrors, iObj ); + if ( RetValue == 0 ) + printf( "Cut of node %d is not tological\n", iObj ); + assert( RetValue ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Sbd_ManCutExpandOne( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, int iThis, int iObj ) +{ + int Lit0m, Lit1m, Fan0, Fan1, iPlace0, iPlace1; + int LutLev = Vec_IntEntry( vLutLevs, iObj ); + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) ); + Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj); + iPlace0 = Vec_IntFind( vCut, Fan0 ); + iPlace1 = Vec_IntFind( vCut, Fan1 ); + if ( iPlace0 == -1 && iPlace1 == -1 ) + return 0; + if ( Vec_IntEntry(vLutLevs, Fan0) > LutLev || Vec_IntEntry(vLutLevs, Fan1) > LutLev ) + return 0; + Vec_IntDrop( vCut, iThis ); + if ( iPlace0 == -1 && Fan0 ) + Vec_IntPushOrder( vCut, Fan0 ); + if ( iPlace1 == -1 && Fan1 ) + Vec_IntPushOrder( vCut, Fan1 ); + return 1; +} +void Vec_IntIsOrdered( Vec_Int_t * vCut ) +{ + int i, Prev, Entry; + Prev = Vec_IntEntry( vCut, 0 ); + Vec_IntForEachEntryStart( vCut, Entry, i, 1 ) + { + assert( Prev < Entry ); + Prev = Entry; + } +} +void Sbd_ManCutExpand( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut ) +{ + int i, Entry; + do + { + Vec_IntForEachEntry( vCut, Entry, i ) + if ( Sbd_ManCutExpandOne( p, vMirrors, vLutLevs, vCut, i, Entry ) ) + break; + } + while ( i < Vec_IntSize(vCut) ); +} +void Sbd_ManCutReload( Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, int LevStop, Vec_Int_t * vCut, Vec_Int_t * vCutTop, Vec_Int_t * vCutBot ) +{ + int i, Entry; + Vec_IntClear( vCutTop ); + Vec_IntClear( vCutBot ); + Vec_IntForEachEntry( vCut, Entry, i ) + { + assert( Entry ); + assert( Vec_IntEntry(vMirrors, Entry) == -1 ); + assert( Vec_IntEntry(vLutLevs, Entry) <= LevStop ); + if ( Vec_IntEntry(vLutLevs, Entry) == LevStop ) + Vec_IntPush( vCutTop, Entry ); + else + Vec_IntPush( vCutBot, Entry ); + } + Vec_IntIsOrdered( vCut ); +} +int Sbd_ManCutCollect_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, int LevStop, Vec_Int_t * vLutLevs, Vec_Int_t * vCut ) +{ + Gia_Obj_t * pObj; + int Ret0, Ret1; + if ( Vec_IntEntry(vMirrors, iObj) >= 0 ) + iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj)); + if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) ) + return 1; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) || Vec_IntEntry(vLutLevs, iObj) <= LevStop ) + { + Vec_IntPush( vCut, iObj ); + return Vec_IntEntry(vLutLevs, iObj) <= LevStop; + } + assert( Gia_ObjIsAnd(pObj) ); + Ret0 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj), LevStop, vLutLevs, vCut ); + Ret1 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj), LevStop, vLutLevs, vCut ); + return Ret0 && Ret1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutReduceTop( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, Vec_Int_t * vCutTop, int nCutSize ) +{ + int i, Entry, Lit0m, Lit1m, Fan0, Fan1; + int LevStop = Vec_IntEntry(vLutLevs, iObj) - 2; + Vec_IntIsOrdered( vCut ); + Vec_IntForEachEntryReverse( vCutTop, Entry, i ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Entry ); + if ( Gia_ObjIsCi(pObj) ) + continue; + assert( Gia_ObjIsAnd(pObj) ); + assert( Vec_IntEntry(vLutLevs, Entry) == LevStop ); + Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, Entry) ); + Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, Entry) ); + Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, Entry); + Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, Entry); + if ( Vec_IntEntry(vLutLevs, Fan0) > LevStop || Vec_IntEntry(vLutLevs, Fan1) > LevStop ) + continue; + assert( Vec_IntEntry(vLutLevs, Fan0) <= LevStop ); + assert( Vec_IntEntry(vLutLevs, Fan1) <= LevStop ); + if ( Vec_IntEntry(vLutLevs, Fan0) == LevStop && Vec_IntEntry(vLutLevs, Fan1) == LevStop ) + continue; + Vec_IntRemove( vCut, Entry ); + if ( Fan0 ) Vec_IntPushUniqueOrder( vCut, Fan0 ); + if ( Fan1 ) Vec_IntPushUniqueOrder( vCut, Fan1 ); + //Sbd_ManCutIsTopo( p, vMirrors, vCut, iObj ); + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) +{ + int RetValue, LevStop = Vec_IntEntry(p->vLutLevs, iObj) - 2; + + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "1=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + +#if 0 + // recompute the cut + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +#endif + + // try to reduce the topmost + Vec_IntClear( p->vCut0 ); + Vec_IntAppend( p->vCut0, p->vCut ); + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "* %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + // try again + if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) ) + { + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + assert( Vec_IntSize(p->vCut) <= p->nCutSize ); + if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "*** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + } + } + } + } + return -1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 668c1231..9b489854 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -62,6 +62,7 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// typedef struct Sbd_Sto_t_ Sbd_Sto_t; +typedef struct Sbd_Srv_t_ Sbd_Srv_t; typedef struct Sbd_Str_t_ Sbd_Str_t; struct Sbd_Str_t_ @@ -92,6 +93,12 @@ extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, i extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); +/*=== sbdCut2.c ==========================================================*/ +extern Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, + Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs, + int nLutSize, int nCutSize, int nCutNum, int fVerbose ); +extern void Sbd_ManCutServerStop( Sbd_Srv_t * p ); +extern int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ); /*=== sbdWin.c ==========================================================*/ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp ); extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); -- cgit v1.2.3 From 26eb3f3684e4478d6839d7d0a92ac67003c06b20 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 19:48:46 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index c9e92d73..7df97d3b 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1894,7 +1894,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) Sbd_StoDerefObj( p->pSto, Pivot ); for ( i = iObjLast; i < Gia_ManObjNum(p->pGia); i++ ) { - Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); + //Gia_Obj_t * pObjI = Gia_ManObj( p->pGia, i ); abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, i ); p->timeCut += Abc_Clock() - clk; -- cgit v1.2.3 From d948f7259a61a8eec0fdc94882b530e2d7f0ba12 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 20:48:21 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 ++ src/opt/sbd/sbdCut2.c | 59 +++++++++++++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 7df97d3b..ed3b620e 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -2009,6 +2009,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } +/* else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { int i; @@ -2020,6 +2021,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Sbd_ManImplement2( p, Pivot, 1, Strs ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } +*/ else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); diff --git a/src/opt/sbd/sbdCut2.c b/src/opt/sbd/sbdCut2.c index 9422e439..b4a8be74 100644 --- a/src/opt/sbd/sbdCut2.c +++ b/src/opt/sbd/sbdCut2.c @@ -336,36 +336,6 @@ int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) return Vec_IntSize(p->vCut); } -#if 0 - // recompute the cut - Vec_IntClear( p->vCut ); - Gia_ManIncrementTravId( p->pGia ); - RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); - if ( RetValue == 0 ) // cannot build delay-improving cut - return -1; - // check if the current cut is good - Vec_IntSort( p->vCut, 0 ); -/* - Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); - if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) - { - //printf( "%d ", Vec_IntSize(p->vCut) ); - memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); - return Vec_IntSize(p->vCut); - } -*/ - // try to expand the cut - Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); - Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); - if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) - { - //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); - //printf( "%d ", Vec_IntSize(p->vCut) ); - memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); - return Vec_IntSize(p->vCut); - } -#endif - // try to reduce the topmost Vec_IntClear( p->vCut0 ); Vec_IntAppend( p->vCut0, p->vCut ); @@ -420,6 +390,35 @@ int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves ) } } } + + // recompute the cut + Vec_IntClear( p->vCut ); + Gia_ManIncrementTravId( p->pGia ); + RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut ); + if ( RetValue == 0 ) // cannot build delay-improving cut + return -1; + // check if the current cut is good + Vec_IntSort( p->vCut, 0 ); +/* + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } +*/ + // try to expand the cut + Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut ); + Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot ); + if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 ) + { + //printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) ); + //printf( "%d ", Vec_IntSize(p->vCut) ); + memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) ); + return Vec_IntSize(p->vCut); + } + return -1; } -- cgit v1.2.3 From 6e1df46cd346ace1ed118da70c5b301915fcf453 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 1 Jan 2017 20:49:36 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index ed3b620e..988ad3db 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1993,7 +1993,7 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; + Sbd_Str_t Strs[SBD_DIV_MAX]; //word Truth = 0; int RetValue, nStrs = 0; if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; -- cgit v1.2.3 From 74c8d35f330f80e6e489f6829288093e798fbfc2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 16:29:10 +0700 Subject: Updates to delay optimization project. --- src/base/abci/abc.c | 31 +++++++----- src/opt/sbd/module.make | 1 + src/opt/sbd/sbd.h | 4 ++ src/opt/sbd/sbdCore.c | 113 +++++++++++++++++++++++++++++++++++++------ src/opt/sbd/sbdCut.c | 22 ++++++++- src/opt/sbd/sbdInt.h | 3 ++ src/opt/sbd/sbdPath.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 268 insertions(+), 30 deletions(-) create mode 100644 src/opt/sbd/sbdPath.c (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fccd4f63..2be65ed0 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCmcdpvwh" ) ) != EOF ) { switch ( c ) { @@ -41102,11 +41102,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBTLimit < 0 ) goto usage; break; - case 'a': - pPars->fArea ^= 1; + case 'm': + pPars->fMapping ^= 1; break; case 'c': - pPars->fCover ^= 1; + pPars->fMoreCuts ^= 1; + break; + case 'd': + pPars->fFindDivs ^= 1; + break; + case 'p': + pPars->fUsePath ^= 1; break; case 'v': pPars->fVerbose ^= 1; @@ -41122,25 +41128,22 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pGia == NULL ) { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): There is no AIG.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Mfsd(): There is no AIG.\n" ); return 0; } if ( Gia_ManBufNum(pAbc->pGia) ) { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): This command does not work with barrier buffers.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Mfsd(): This command does not work with barrier buffers.\n" ); return 1; } if ( Gia_ManHasMapping(pAbc->pGia) ) - { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has mapping (run &st to unmap).\n" ); - return 0; - } + Abc_Print( 1, "The current AIG has mapping, which can be used to determine critical path if \"-p\" is selected.\n" ); pTemp = Sbd_NtkPerform( pAbc->pGia, pPars ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-mcdpvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); @@ -41150,8 +41153,10 @@ usage: Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); Abc_Print( -2, "\t-C : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit ); - Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" ); - Abc_Print( -2, "\t-c : toggle using complete slow covering procedure [default = %s]\n", pPars->fCover? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "area": "area+edges" ); + Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/opt/sbd/module.make b/src/opt/sbd/module.make index a9a6c3be..fc176715 100644 --- a/src/opt/sbd/module.make +++ b/src/opt/sbd/module.make @@ -4,5 +4,6 @@ SRC += src/opt/sbd/sbd.c \ src/opt/sbd/sbdCut.c \ src/opt/sbd/sbdCut2.c \ src/opt/sbd/sbdLut.c \ + src/opt/sbd/sbdPath.c \ src/opt/sbd/sbdSat.c \ src/opt/sbd/sbdWin.c diff --git a/src/opt/sbd/sbd.h b/src/opt/sbd/sbd.h index 6e0f6b3b..9c419b16 100644 --- a/src/opt/sbd/sbd.h +++ b/src/opt/sbd/sbd.h @@ -47,6 +47,10 @@ struct Sbd_Par_t_ int nWinSizeMax; // maximum window size (windowing) int nBTLimit; // maximum number of SAT conflicts int nWords; // simulation word count + int fMapping; // generate mapping + int fMoreCuts; // use several cuts + int fFindDivs; // perform divisor search + int fUsePath; // optimize only critical path int fArea; // area-oriented optimization int fCover; // use complete cover procedure int fVerbose; // verbose flag diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 988ad3db..275d866f 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -38,6 +38,7 @@ struct Sbd_Man_t_ Vec_Wec_t * vTfos; // TFO for each node (roots are marked) (windowing) Vec_Int_t * vLutLevs; // LUT level for each node after resynthesis Vec_Int_t * vLutCuts; // LUT cut for each nodes after resynthesis + Vec_Int_t * vLutCuts2; // LUT cut for each nodes after resynthesis Vec_Int_t * vMirrors; // alternative node Vec_Wrd_t * vSims[4]; // simulation information (main, backup, controlability) Vec_Int_t * vCover; // temporary @@ -73,7 +74,8 @@ struct Sbd_Man_t_ sat_solver * pSat; // SAT solver }; -static inline int * Sbd_ObjCut( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts, (p->pPars->nLutSize + 1) * i ); } +static inline int * Sbd_ObjCut( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts, (p->pPars->nLutSize + 1) * i ); } +static inline int * Sbd_ObjCut2( Sbd_Man_t * p, int i ) { return Vec_IntEntryP( p->vLutCuts2, (p->pPars->nLutSize + 1) * i ); } static inline word * Sbd_ObjSim0( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[0], p->pPars->nWords * i ); } static inline word * Sbd_ObjSim1( Sbd_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims[1], p->pPars->nWords * i ); } @@ -107,6 +109,10 @@ void Sbd_ParSetDefault( Sbd_Par_t * pPars ) pPars->nWinSizeMax = 2000; // maximum window size (windowing) pPars->nBTLimit = 0; // maximum number of SAT conflicts pPars->nWords = 1; // simulation word count + pPars->fMapping = 1; // generate mapping + pPars->fMoreCuts = 0; // use several cuts + pPars->fFindDivs = 0; // perform divisor search + pPars->fUsePath = 0; // optimize only critical path pPars->fArea = 0; // area-oriented optimization pPars->fCover = 0; // use complete cover procedure pPars->fVerbose = 0; // verbose flag @@ -231,8 +237,13 @@ Sbd_Man_t * Sbd_ManStart( Gia_Man_t * pGia, Sbd_Par_t * pPars ) for ( w = 0; w < p->pPars->nWords; w++ ) Sbd_ObjSim0(p, Id)[w] = Gia_ManRandomW( 0 ); // cut enumeration - p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, 1, 1 ); - p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); + if ( pPars->fMoreCuts ) + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, !pPars->fMapping, 1 ); + else + { + p->pSto = Sbd_StoAlloc( pGia, p->vMirrors, pPars->nLutSize, pPars->nLutSize, pPars->nCutNum, !pPars->fMapping, 1 ); + p->pSrv = Sbd_ManCutServerStart( pGia, p->vMirrors, p->vLutLevs, NULL, NULL, pPars->nLutSize, pPars->nCutSize, pPars->nCutNum, 0 ); + } return p; } void Sbd_ManStop( Sbd_Man_t * p ) @@ -258,8 +269,8 @@ void Sbd_ManStop( Sbd_Man_t * p ) Vec_IntFree( p->vCounts[1] ); Vec_WrdFree( p->vMatrix ); sat_solver_delete_p( &p->pSat ); - Sbd_StoFree( p->pSto ); - Sbd_ManCutServerStop( p->pSrv ); + if ( p->pSto ) Sbd_StoFree( p->pSto ); + if ( p->pSrv ) Sbd_ManCutServerStop( p->pSrv ); ABC_FREE( p ); } @@ -1830,7 +1841,7 @@ int Sbd_ManImplement( Sbd_Man_t * p, int Pivot, word Truth ) int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) { - Gia_Obj_t * pObj = NULL; + //Gia_Obj_t * pObj = NULL; int i, k, w, iLit, Node; int iObjLast = Gia_ManObjNum(p->pGia); int iCurLev = Vec_IntEntry(p->vLutLevs, Pivot); @@ -1903,6 +1914,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) //Vec_IntPush( p->vLevs, 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObjI, i)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObjI, i))) ); Vec_IntPush( p->vObj2Var, 0 ); Vec_IntFillExtra( p->vLutCuts, Vec_IntSize(p->vLutCuts) + p->pPars->nLutSize + 1, 0 ); + Sbd_StoSaveBestDelayCut( p->pSto, i, Sbd_ObjCut(p, i) ); //Sbd_ManFindCut( p, i, p->vLits ); for ( k = 0; k < 4; k++ ) for ( w = 0; w < p->pPars->nWords; w++ ) @@ -1912,7 +1924,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) iNewLev = Vec_IntEntry( p->vLutLevs, Abc_Lit2Var(iLit) ); assert( !iNewLev || iNewLev < iCurLev ); // update delay of the initial node - pObj = Gia_ManObj( p->pGia, Pivot ); + //pObj = Gia_ManObj( p->pGia, Pivot ); assert( Vec_IntEntry(p->vLutLevs, Pivot) == iCurLev ); Vec_IntWriteEntry( p->vLutLevs, Pivot, iNewLev ); //Vec_IntWriteEntry( p->vLevs, Pivot, Pivot ? 1+Abc_MaxInt(Vec_IntEntry(p->vLevs, Gia_ObjFaninId0(pObj, Pivot)), Vec_IntEntry(p->vLevs, Gia_ObjFaninId1(pObj, Pivot))) : 0 ); @@ -1930,6 +1942,70 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) SeeAlso [] ***********************************************************************/ +void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) +{ + Gia_Obj_t * pObj; int k, * pCut; + if ( Gia_ObjIsTravIdCurrentId(pNew, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(pNew, iObj); + pObj = Gia_ManObj( pNew, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + pCut = Sbd_ObjCut2( p, iObj ); + for ( k = 1; k <= pCut[0]; k++ ) + Sbd_ManDeriveMapping_rec( p, pNew, pCut[k] ); + // add mapping + Vec_IntWriteEntry( pNew->vMapping, iObj, Vec_IntSize(pNew->vMapping) ); + for ( k = 0; k <= pCut[0]; k++ ) + Vec_IntPush( pNew->vMapping, pCut[k] ); + Vec_IntPush( pNew->vMapping, iObj ); +} +void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) +{ + Gia_Obj_t * pObj, * pFan; + int i, k, iFan, iObjNew, * pCut, * pCutNew; + Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); + // derive cuts for the new manager + p->vLutCuts2 = Vec_IntStart( Gia_ManObjNum(pNew) * (p->pPars->nLutSize + 1) ); + Gia_ManForEachAnd( p->pGia, pObj, i ) + { + if ( Vec_IntEntry(p->vMirrors, i) >= 0 ) + continue; + if ( pObj->Value == ~0 ) + continue; + iObjNew = Abc_Lit2Var( pObj->Value ); + if ( !Gia_ObjIsAnd(Gia_ManObj(pNew, iObjNew)) ) + continue; + pCutNew = Sbd_ObjCut2( p, iObjNew ); + pCut = Sbd_ObjCut( p, i ); + Vec_IntClear( vLeaves ); + for ( k = 1; k <= pCut[0]; k++ ) + { + iFan = Vec_IntEntry(p->vMirrors, pCut[k]) >= 0 ? Abc_Lit2Var(Vec_IntEntry(p->vMirrors, pCut[k])) : pCut[k]; + pFan = Gia_ManObj( p->pGia, iFan ); + if ( pFan->Value == ~0 ) + continue; + iObjNew = Abc_Lit2Var( pFan->Value ); + if ( iObjNew == 0 ) + continue; + Vec_IntPushUniqueOrder( vLeaves, iObjNew ); + } + assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); + assert( Vec_IntSize(vLeaves) > 1 ); + pCutNew[0] = Vec_IntSize(vLeaves); + memcpy( pCutNew+1, Vec_IntArray(vLeaves), sizeof(int) * Vec_IntSize(vLeaves) ); + } + Vec_IntFree( vLeaves ); + // create new mapping + Vec_IntFreeP( &pNew->vMapping ); + pNew->vMapping = Vec_IntAlloc( (p->pPars->nLutSize + 2) * Gia_ManObjNum(pNew) ); + Vec_IntFill( pNew->vMapping, Gia_ManObjNum(pNew), 0 ); + Gia_ManIncrementTravId( pNew ); + Gia_ManForEachCo( pNew, pObj, i ) + Sbd_ManDeriveMapping_rec( p, pNew, Gia_ObjFaninId0p(pNew, pObj) ); + Vec_IntFreeP( &p->vLutCuts2 ); +} void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors ) { Gia_Obj_t * pObj; @@ -1951,7 +2027,7 @@ void Sbd_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * v if ( Obj != Node ) Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) ); } -Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) +Gia_Man_t * Sbd_ManDerive( Sbd_Man_t * pMan, Gia_Man_t * p, Vec_Int_t * vMirrors ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; @@ -1973,9 +2049,12 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Gia_ManTransferTiming( pNew, p ); + if ( pMan->pPars->fMapping ) + Sbd_ManDeriveMapping( pMan, pNew ); // remove dangling nodes pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManTransferTiming( pNew, pTemp ); + Gia_ManTransferMapping( pNew, pTemp ); Gia_ManStop( pTemp ); return pNew; } @@ -1993,7 +2072,7 @@ Gia_Man_t * Sbd_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors ) ***********************************************************************/ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) { - Sbd_Str_t Strs[SBD_DIV_MAX]; //word Truth = 0; + Sbd_Str_t Strs[SBD_DIV_MAX]; word Truth = 0; int RetValue, nStrs = 0; if ( !p->pSto && Sbd_ManMergeCuts( p, Pivot ) ) return; @@ -2009,8 +2088,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } -/* - else if ( p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) + else if ( p->pPars->fFindDivs && p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { int i; Strs->fLut = 1; @@ -2021,7 +2099,6 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Sbd_ManImplement2( p, Pivot, 1, Strs ); if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } -*/ else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); @@ -2041,6 +2118,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; + Vec_Bit_t * vPath; Sbd_Man_t * p = Sbd_ManStart( pGia, pPars ); int nNodesOld = Gia_ManObjNum(pGia); int k, Pivot; @@ -2049,6 +2127,7 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) Gia_ManForEachObj( p->pGia, pObj, Pivot ) Sbd_StoRefObj( p->pSto, Pivot, -1 ); //return NULL; + vPath = (pPars->fUsePath && Gia_ManHasMapping(pGia)) ? Sbc_ManCriticalPath(pGia) : NULL; if ( pGia->pManTime != NULL && Tim_ManBoxNum((Tim_Man_t*)pGia->pManTime) ) { Vec_Int_t * vNodes = Gia_ManOrderWithBoxes( pGia ); @@ -2065,9 +2144,10 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Sbd_StoSaveBestDelayCut( p->pSto, Pivot, Sbd_ObjCut(p, Pivot) ); p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) + if ( Delay > 1 && (!vPath || Vec_BitEntry(vPath, Pivot)) ) Sbd_NtkPerformOne( p, Pivot ); } else if ( Gia_ObjIsCi(pObj) ) @@ -2102,22 +2182,25 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) { abctime clk = Abc_Clock(); int Delay = Sbd_StoComputeCutsNode( p->pSto, Pivot ); + Sbd_StoSaveBestDelayCut( p->pSto, Pivot, Sbd_ObjCut(p, Pivot) ); p->timeCut += Abc_Clock() - clk; Vec_IntWriteEntry( p->vLutLevs, Pivot, Delay ); - if ( Delay > 1 )//&& Gia_ObjRefNumId(p->pGia, Pivot) > 1 ) + if ( Delay > 1 && (!vPath || Vec_BitEntry(vPath, Pivot)) ) Sbd_NtkPerformOne( p, Pivot ); } //if ( nNodesOld != Gia_ManObjNum(pGia) ) // break; } } + Vec_BitFreeP( &vPath ); printf( "K = %d. S = %d. N = %d. P = %d. ", p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; Abc_PrintTime( 1, "Time", p->timeTotal ); - pNew = Sbd_ManDerive( pGia, p->vMirrors ); + //Sbd_ManDeriveMapping2( p ); + pNew = Sbd_ManDerive( p, pGia, p->vMirrors ); // print runtime statistics p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; //if ( p->pPars->fVerbose ) diff --git a/src/opt/sbd/sbdCut.c b/src/opt/sbd/sbdCut.c index 7bcf2189..59505c98 100644 --- a/src/opt/sbd/sbdCut.c +++ b/src/opt/sbd/sbdCut.c @@ -65,10 +65,11 @@ struct Sbd_Sto_t_ Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers int nCutsR; // the number of cuts int Pivot; // current object - double CutCount[4]; // cut counters + int iCutBest; // best-delay cut int nCutsSpec; // special cuts int nCutsOver; // overflow cuts int DelayMin; // minimum delay + double CutCount[4]; // cut counters abctime clkStart; // starting time }; @@ -540,6 +541,7 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC { int i, v, Delay, DelayMin = ABC_INFINITY; assert( nCuts > 0 ); + p->iCutBest = -1; for ( i = 0; i < nCuts; i++ ) { if ( (int)pCuts[i]->nLeaves > p->nLutSize ) @@ -547,8 +549,16 @@ static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pC Delay = 0; for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ ) Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vDelays, pCuts[i]->pLeaves[v]) ); - DelayMin = Abc_MinInt( DelayMin, Delay ); + //DelayMin = Abc_MinInt( DelayMin, Delay ); + if ( DelayMin > Delay ) + { + DelayMin = Delay; + p->iCutBest = i; + } + else if ( DelayMin == Delay && p->iCutBest >= 0 && pCuts[p->iCutBest]->nLeaves > pCuts[i]->nLeaves ) + p->iCutBest = i; } + assert( p->iCutBest >= 0 ); assert( DelayMin < ABC_INFINITY ); DelayMin = (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin; Vec_IntWriteEntry( p->vDelays, iObj, DelayMin ); @@ -725,6 +735,14 @@ int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ) Sbd_StoMergeCuts( p, iObj ); return Vec_IntEntry( p->vDelays, iObj ); } +void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut ) +{ + Sbd_Cut_t * pCutBest = p->ppCuts[p->iCutBest]; int i; + assert( iObj == p->Pivot ); + pCut[0] = pCutBest->nLeaves; + for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) + pCut[i+1] = pCutBest->pLeaves[i]; +} int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj ) { return Vec_IntEntry(p->vRefs, iObj); diff --git a/src/opt/sbd/sbdInt.h b/src/opt/sbd/sbdInt.h index 9b489854..eabe5355 100644 --- a/src/opt/sbd/sbdInt.h +++ b/src/opt/sbd/sbdInt.h @@ -92,6 +92,7 @@ extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj ); extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level ); extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj ); +extern void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut ); extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves ); /*=== sbdCut2.c ==========================================================*/ extern Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors, @@ -104,6 +105,8 @@ extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf ); extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds ); extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset ); +/*=== sbdPath.c ==========================================================*/ +extern Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ); /*=== sbdQbf.c ==========================================================*/ extern int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors, diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c new file mode 100644 index 00000000..417cb407 --- /dev/null +++ b/src/opt/sbd/sbdPath.c @@ -0,0 +1,124 @@ +/**CFile**************************************************************** + + FileName [sbdPath.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based optimization using internal don't-cares.] + + Synopsis [Critical path.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sbdPath.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sbdInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) +{ + Gia_Obj_t * pObj; + int k, iFan, Value = 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return Vec_BitEntry(vPath, iObj); + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return 0; + assert( Gia_ObjIsAnd(pObj) ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + Value |= Sbc_ManAddInternalToPath_rec( p, iFan, vPath ); + if ( Value ) + Vec_BitWriteEntry( vPath, iObj, 1 ); + return Value; +} +void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) +{ + int iObj; + Gia_ManForEachLut( p, iObj ) + { + if ( !Vec_BitEntry(vPath, iObj) ) + continue; + Gia_ManIncrementTravId( p ); + Sbc_ManAddInternalToPath_rec( p, iObj, vPath ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath ) +{ + Gia_Obj_t * pObj; int k, iFan; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Vec_BitWriteEntry( vPath, iObj, 1 ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + if ( pLevels[iFan] == LevelFan ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, LevelFan-1, vPath ); +} +Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) +{ + int * pLevels = NULL, k, iDriver; + int nLevels = p->pManTime ? Gia_ManLutLevelWithBoxes(p) : Gia_ManLutLevel(p, &pLevels); + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + if ( p->pManTime ) + pLevels = Vec_IntArray( p->vLevels ); + Gia_ManIncrementTravId( p ); + Gia_ManForEachCoDriverId( p, iDriver, k ) + if ( pLevels[iDriver] == nLevels && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); + if ( !p->pManTime ) + ABC_FREE( pLevels ); + Sbc_ManAddInternalToPath( p, vPath ); + return vPath; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3 From daf310cd4a98a941df164fc1deca6803723389c8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 17:15:00 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdPath.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 417cb407..3a040e1e 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -61,12 +61,14 @@ int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) } void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) { - int iObj; + int k, iFan, iObj; Gia_ManForEachLut( p, iObj ) { if ( !Vec_BitEntry(vPath, iObj) ) continue; Gia_ManIncrementTravId( p ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + Gia_ObjSetTravIdCurrentId(p, iFan); Sbc_ManAddInternalToPath_rec( p, iObj, vPath ); } } @@ -106,7 +108,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) pLevels = Vec_IntArray( p->vLevels ); Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) - if ( pLevels[iDriver] == nLevels && iDriver ) + if ( (pLevels[iDriver] == nLevels) && iDriver ) Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); if ( !p->pManTime ) ABC_FREE( pLevels ); -- cgit v1.2.3 From 8b898f85e6daae51e1fa4fdedeab84a23f6655bb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 17:18:08 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 275d866f..63dc51ab 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1945,7 +1945,7 @@ int Sbd_ManImplement2( Sbd_Man_t * p, int Pivot, int nStrs, Sbd_Str_t * pStrs ) void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) { Gia_Obj_t * pObj; int k, * pCut; - if ( Gia_ObjIsTravIdCurrentId(pNew, iObj) ) + if ( !iObj || Gia_ObjIsTravIdCurrentId(pNew, iObj) ) return; Gia_ObjSetTravIdCurrentId(pNew, iObj); pObj = Gia_ManObj( pNew, iObj ); -- cgit v1.2.3 From 9be69dca362453a9e2f631b81e3130180eb57a97 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 18:03:33 +0700 Subject: Updates to delay optimization project. --- src/aig/gia/giaIf.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 26f549d0..ac748f8c 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -539,22 +539,14 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) { sprintf( FileNameOld, "%s", p->pName ); fprintf( pTable, "\n" ); - fprintf( pTable, "%s ", p->pName ); -// fprintf( pTable, "%d ", Gia_ManCiNum(p) ); -// fprintf( pTable, "%d ", Gia_ManCoNum(p) ); -// fprintf( pTable, "%d ", Gia_ManAndNum(p) ); -// fprintf( pTable, "%d ", Gia_ManPiNum(p) - Gia_ManBoxCiNum(p) - Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManPoNum(p) - Gia_ManBoxCoNum(p) - Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManClockDomainNum(p) ); - + fprintf( pTable, "%s ", p->pName ); fprintf( pTable, " " ); - fprintf( pTable, "%d ", p->MappedDelay ); - fprintf( pTable, "%d ", p->MappedArea ); - fprintf( pTable, "%d ", nFanins ); - fprintf( pTable, "%d ", LevelMax ); + fprintf( pTable, "%d ", Gia_ManAndNum(p) ); fprintf( pTable, "%d ", nLuts ); -// fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); -// fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); + fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } else @@ -2014,7 +2006,7 @@ void Gia_ManMappingVerify( Gia_Man_t * p ) void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia ) { Gia_Obj_t * pObj; - int i, k, iFan; + int i, k, iFan, iPlace; if ( !Gia_ManHasMapping(pGia) ) return; Gia_ManMappingVerify( pGia ); @@ -2023,12 +2015,20 @@ void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia ) Vec_IntFill( p->vMapping, Gia_ManObjNum(p), 0 ); Gia_ManForEachLut( pGia, i ) { + if ( Gia_ObjValue(Gia_ManObj(pGia, i)) == ~0 ) // handle dangling LUT + continue; assert( !Abc_LitIsCompl(Gia_ObjValue(Gia_ManObj(pGia, i))) ); pObj = Gia_ManObj( p, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, i))) ); Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) ); + iPlace = Vec_IntSize( p->vMapping ); Vec_IntPush( p->vMapping, Gia_ObjLutSize(pGia, i) ); Gia_LutForEachFanin( pGia, i, iFan, k ) - Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) ); + { + if ( Gia_ObjValue(Gia_ManObj(pGia, iFan)) == ~0 ) // handle dangling LUT fanin + Vec_IntAddToEntry( p->vMapping, iPlace, -1 ); + else + Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) ); + } iFan = Abc_Lit2Var( Gia_ObjValue(Gia_ManObj(pGia, Abc_AbsInt(Gia_ObjLutMuxId(pGia, i)))) ); Vec_IntPush( p->vMapping, Gia_ObjLutIsMux(pGia, i) ? -iFan : iFan ); } -- cgit v1.2.3 From 51e3a7c2776e671738b5e6a679214df46fe205ee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 18:43:41 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdPath.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 3a040e1e..7392516d 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "sbdInt.h" +#include "misc/tim/tim.h" ABC_NAMESPACE_IMPL_START @@ -92,12 +93,28 @@ void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelF Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); if ( Gia_ObjIsCi(pObj) ) + { + Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; + int iBox = pManTime ? Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) ) : -1; + if ( iBox >= 0 ) + { + int curCo = Tim_ManBoxInputFirst( pManTime, iBox ); + int nBoxInputs = Tim_ManBoxInputNum( pManTime, iBox ); + for ( k = 0; k < nBoxInputs; k++ ) + { + Gia_Obj_t * pCo = Gia_ManCo( p, curCo + k ); + int iDriver = Gia_ObjFaninId0p( p, pCo ); + if ( (pLevels[iDriver] >= LevelFan-1) && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + } + } return; + } assert( Gia_ObjIsAnd(pObj) ); Vec_BitWriteEntry( vPath, iObj, 1 ); Gia_LutForEachFanin( p, iObj, iFan, k ) - if ( pLevels[iFan] == LevelFan ) - Sbc_ManCriticalPath_rec( p, pLevels, iFan, LevelFan-1, vPath ); + if ( pLevels[iFan] >= LevelFan-1 ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath ); } Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) { @@ -109,7 +126,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) if ( (pLevels[iDriver] == nLevels) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, nLevels-1, vPath ); + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); if ( !p->pManTime ) ABC_FREE( pLevels ); Sbc_ManAddInternalToPath( p, vPath ); -- cgit v1.2.3 From 378bb416462a0ce10ecb1964d8d9b424e762d7b5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 19:18:55 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 2 +- src/opt/sbd/sbdPath.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 63dc51ab..8b1de4aa 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1992,7 +1992,7 @@ void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) Vec_IntPushUniqueOrder( vLeaves, iObjNew ); } assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); - assert( Vec_IntSize(vLeaves) > 1 ); + //assert( Vec_IntSize(vLeaves) > 1 ); pCutNew[0] = Vec_IntSize(vLeaves); memcpy( pCutNew+1, Vec_IntArray(vLeaves), sizeof(int) * Vec_IntSize(vLeaves) ); } diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index 7392516d..a2b1a9b0 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -52,7 +52,7 @@ int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath ) Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); if ( Gia_ObjIsCi(pObj) ) - return 0; + return Vec_BitEntry(vPath, iObj); assert( Gia_ObjIsAnd(pObj) ); Gia_LutForEachFanin( p, iObj, iFan, k ) Value |= Sbc_ManAddInternalToPath_rec( p, iFan, vPath ); @@ -85,13 +85,14 @@ void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath ) SeeAlso [] ***********************************************************************/ -void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath ) +void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath, int Slack ) { Gia_Obj_t * pObj; int k, iFan; if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) return; Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); + Vec_BitWriteEntry( vPath, iObj, 1 ); if ( Gia_ObjIsCi(pObj) ) { Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; @@ -104,21 +105,20 @@ void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelF { Gia_Obj_t * pCo = Gia_ManCo( p, curCo + k ); int iDriver = Gia_ObjFaninId0p( p, pCo ); - if ( (pLevels[iDriver] >= LevelFan-1) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + if ( (pLevels[iDriver]+Slack >= LevelFan-1) && iDriver ) + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Abc_MaxInt(0, pLevels[iDriver]+Slack-(LevelFan-1)) ); } } return; } assert( Gia_ObjIsAnd(pObj) ); - Vec_BitWriteEntry( vPath, iObj, 1 ); Gia_LutForEachFanin( p, iObj, iFan, k ) - if ( pLevels[iFan] >= LevelFan-1 ) - Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath ); + if ( pLevels[iFan]+Slack >= LevelFan-1 ) + Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath, Abc_MaxInt(0, pLevels[iFan]+Slack-(LevelFan-1)) ); } Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) { - int * pLevels = NULL, k, iDriver; + int * pLevels = NULL, k, iDriver, Slack = 1; int nLevels = p->pManTime ? Gia_ManLutLevelWithBoxes(p) : Gia_ManLutLevel(p, &pLevels); Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); if ( p->pManTime ) @@ -126,7 +126,7 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) Gia_ManIncrementTravId( p ); Gia_ManForEachCoDriverId( p, iDriver, k ) if ( (pLevels[iDriver] == nLevels) && iDriver ) - Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath ); + Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Slack ); if ( !p->pManTime ) ABC_FREE( pLevels ); Sbc_ManAddInternalToPath( p, vPath ); -- cgit v1.2.3 From 58622ed032570bc7437762ff55058281677f5ee1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 5 Jan 2017 12:53:15 +0700 Subject: Adding two external APIs. --- src/aig/miniaig/abcapis.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/aig/miniaig/abcapis.h b/src/aig/miniaig/abcapis.h index f412f5ae..eb8586fe 100644 --- a/src/aig/miniaig/abcapis.h +++ b/src/aig/miniaig/abcapis.h @@ -52,6 +52,8 @@ extern int Cmd_CommandExecute( void * pAbc, char * pCommandLine ); // procedures to input/output 'mini AIG' extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig ); extern void * Abc_NtkOutputMiniAig( void * pAbc ); +extern void Abc_FrameGiaInputMiniAig( void * pAbc, void * p ); +extern void * Abc_FrameGiaOutputMiniAig( void * pAbc ); extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops ); // procedures to input/output 'mini LUT' -- cgit v1.2.3 From e9a7ad68c4c2f2b95695875996e713f7ae708912 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 5 Jan 2017 13:23:27 +0700 Subject: Updates to delay optimization project. --- src/opt/sbd/sbdCore.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 8b1de4aa..179977fb 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -2086,7 +2086,7 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) if ( RetValue >= 0 ) { Vec_IntWriteEntry( p->vMirrors, Pivot, RetValue ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); + //if ( p->pPars->fVerbose ) printf( "Node %5d: Detected constant %d.\n", Pivot, RetValue ); } else if ( p->pPars->fFindDivs && p->pPars->nLutNum >= 1 && Sbd_ManExplore2( p, Pivot, &Truth ) ) { @@ -2097,19 +2097,19 @@ void Sbd_NtkPerformOne( Sbd_Man_t * p, int Pivot ) Strs->VarIns[i] = i; Strs->Res = Truth; Sbd_ManImplement2( p, Pivot, 1, Strs ); - if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); + //if ( p->pPars->fVerbose ) printf( "Node %5d: Detected LUT%d\n", Pivot, p->pPars->nLutSize ); } else if ( p->pPars->nLutNum >= 2 && Sbd_ManExplore3( p, Pivot, &nStrs, Strs ) ) { Sbd_ManImplement2( p, Pivot, nStrs, Strs ); if ( !p->pPars->fVerbose ) return; - if ( Vec_IntSize(p->vDivSet) <= 4 ) - printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); - else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) - printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); - else - printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); + //if ( Vec_IntSize(p->vDivSet) <= 4 ) + // printf( "Node %5d: Detected %d\n", Pivot, p->pPars->nLutSize ); + //else if ( Vec_IntSize(p->vDivSet) <= 6 || (Vec_IntSize(p->vDivSet) == 7 && nStrs == 2) ) + // printf( "Node %5d: Detected %d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize ); + //else + // printf( "Node %5d: Detected %d%d%d\n", Pivot, p->pPars->nLutSize, p->pPars->nLutSize, p->pPars->nLutSize ); } else p->nUsed--; @@ -2193,17 +2193,19 @@ Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars ) } } Vec_BitFreeP( &vPath ); - printf( "K = %d. S = %d. N = %d. P = %d. ", - p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); - printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", - p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); p->timeTotal = Abc_Clock() - p->timeTotal; - Abc_PrintTime( 1, "Time", p->timeTotal ); - //Sbd_ManDeriveMapping2( p ); + if ( p->pPars->fVerbose ) + { + printf( "K = %d. S = %d. N = %d. P = %d. ", + p->pPars->nLutSize, p->pPars->nLutNum, p->pPars->nCutSize, p->pPars->nCutNum ); + printf( "Try = %d. Use = %d. C = %d. 1 = %d. 2 = %d. 3a = %d. 3b = %d. Lev = %d. ", + p->nTried, p->nUsed, p->nLuts[0], p->nLuts[1], p->nLuts[2], p->nLuts[3], p->nLuts[4], Sbd_ManDelay(p) ); + Abc_PrintTime( 1, "Time", p->timeTotal ); + } pNew = Sbd_ManDerive( p, pGia, p->vMirrors ); // print runtime statistics p->timeOther = p->timeTotal - p->timeWin - p->timeCut - p->timeCov - p->timeCnf - p->timeSat - p->timeQbf; - //if ( p->pPars->fVerbose ) + if ( p->pPars->fVerbose ) { ABC_PRTP( "Win", p->timeWin , p->timeTotal ); ABC_PRTP( "Cut", p->timeCut , p->timeTotal ); -- cgit v1.2.3 From a2fcd0710d22d79ef238e1cb9ef328ce94fa5000 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 6 Jan 2017 11:52:00 +0700 Subject: Creating file name from design name for PDR invariant. --- src/proof/pdr/pdrCore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index c020c56a..66cae36e 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -922,10 +922,11 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) } if ( p->pPars->fDumpInv ) { + char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); Abc_FrameSetStr( Pdr_ManDumpString(p) ); Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) ); - Pdr_ManDumpClauses( p, (char *)"inv.pla", RetValue==1 ); + Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); } p->tTotal += Abc_Clock() - clk; Pdr_ManStop( p ); -- cgit v1.2.3 From 5c9983d089c9cac4eb71bb5ce38838cd47b29d62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 6 Jan 2017 12:47:57 +0700 Subject: Dealing wit COs driven by inverters in MiniLUT. --- src/aig/gia/giaMini.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index a886311f..4ee92cdd 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -21,6 +21,7 @@ #include "gia.h" #include "opt/dau/dau.h" #include "base/main/main.h" +#include "misc/util/utilTruth.h" #include "aig/miniaig/miniaig.h" #include "aig/miniaig/minilut.h" @@ -245,6 +246,34 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p ) return pGia; } +/**Function************************************************************* + + Synopsis [Marks LUTs that should be complemented.] + + Description [These are LUTs whose all PO fanouts require them + in negative polarity. Other fanouts may require them in + positive polarity.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Gia_ManFindComplLuts( Gia_Man_t * pGia ) +{ + Gia_Obj_t * pObj; int i; + // mark objects pointed by COs in negative polarity + Vec_Bit_t * vMarks = Vec_BitStart( Gia_ManObjNum(pGia) ); + Gia_ManForEachCo( pGia, pObj, i ) + if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Gia_ObjFaninC0(pObj) ) + Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 1 ); + // unmark objects pointed by COs in positive polarity + Gia_ManForEachCo( pGia, pObj, i ) + if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) ) + Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 0 ); + return vMarks; +} + /**Function************************************************************* Synopsis [Converts GIA into MiniLUT.] @@ -260,8 +289,9 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) { Mini_Lut_t * p; Vec_Wrd_t * vTruths; + Vec_Bit_t * vMarks; Gia_Obj_t * pObj, * pFanin; - int i, k, LutSize, pVars[16]; + int i, k, iFanin, LutSize, pVars[16]; word Truth; assert( Gia_ManHasMapping(pGia) ); LutSize = Gia_ManLutSizeMax( pGia ); @@ -274,12 +304,17 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) pObj->Value = Mini_LutCreatePi(p); // create internal nodes vTruths = Vec_WrdStart( Gia_ManObjNum(pGia) ); + vMarks = Gia_ManFindComplLuts( pGia ); Gia_ManForEachLut( pGia, i ) { pObj = Gia_ManObj( pGia, i ); Gia_LutForEachFaninObj( pGia, i, pFanin, k ) pVars[k] = pFanin->Value; Truth = Gia_LutComputeTruth6( pGia, i, vTruths ); + Truth = Vec_BitEntry(vMarks, i) ? ~Truth : Truth; + Gia_LutForEachFanin( pGia, i, iFanin, k ) + if ( Vec_BitEntry(vMarks, iFanin) ) + Truth = Abc_Tt6Flip( Truth, k ); pObj->Value = Mini_LutCreateNode( p, Gia_ObjLutSize(pGia, i), pVars, (unsigned *)&Truth ); } Vec_WrdFree( vTruths ); @@ -288,7 +323,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) { if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(pGia) ) pObj->Value = Mini_LutCreatePo( p, Gia_ObjFaninC0(pObj) ); - else if ( !Gia_ObjFaninC0(pObj) ) + else if ( Gia_ObjFaninC0(pObj) == Vec_BitEntry(vMarks, Gia_ObjFaninId0p(pGia, pObj)) ) pObj->Value = Mini_LutCreatePo( p, Gia_ObjFanin0(pObj)->Value ); else // add inverter LUT { @@ -298,6 +333,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) pObj->Value = Mini_LutCreatePo( p, LutInv ); } } + Vec_BitFree( vMarks ); // set registers Mini_LutSetRegNum( p, Gia_ManRegNum(pGia) ); //Mini_LutPrintStats( p ); -- cgit v1.2.3 From 460167ec747aed778bfc13f2040dd8a205169fa2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 08:57:08 +0700 Subject: Compiler warnings. --- src/aig/gia/giaJf.c | 16 ++++++++-------- src/aig/gia/giaKf.c | 14 +++++++------- src/aig/gia/giaLf.c | 10 +++++----- src/aig/gia/giaMf.c | 8 ++++---- src/base/abci/abcExact.c | 2 +- src/map/if/ifDec16.c | 2 +- src/map/scl/sclLiberty.c | 8 ++++---- src/proof/acec/acecCo.c | 2 +- 8 files changed, 31 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaJf.c b/src/aig/gia/giaJf.c index 93dac301..2d75581d 100644 --- a/src/aig/gia/giaJf.c +++ b/src/aig/gia/giaJf.c @@ -1256,10 +1256,10 @@ void Jf_ManComputeCuts( Jf_Man_t * p, int fEdge ) } if ( p->pPars->fVerbose ) { - printf( "CutPair = %lu ", p->CutCount[0] ); - printf( "Merge = %lu ", p->CutCount[1] ); - printf( "Eval = %lu ", p->CutCount[2] ); - printf( "Cut = %lu ", p->CutCount[3] ); + printf( "CutPair = %lu ", (long)p->CutCount[0] ); + printf( "Merge = %lu ", (long)p->CutCount[1] ); + printf( "Eval = %lu ", (long)p->CutCount[2] ); + printf( "Cut = %lu ", (long)p->CutCount[3] ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); printf( "Memory: " ); printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) ); @@ -1702,11 +1702,11 @@ void Jf_ManPrintStats( Jf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); if ( p->pPars->fGenCnf ) - printf( "Cnf =%9lu ", p->pPars->Clause ); + printf( "Cnf =%9lu ", (long)p->pPars->Clause ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/aig/gia/giaKf.c b/src/aig/gia/giaKf.c index caa88bfc..a823f726 100644 --- a/src/aig/gia/giaKf.c +++ b/src/aig/gia/giaKf.c @@ -1125,9 +1125,9 @@ void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } @@ -1173,10 +1173,10 @@ void Kf_ManComputeMapping( Kf_Man_t * p ) Kf_ManComputeRefs( p ); if ( p->pPars->fVerbose ) { - printf( "CutPair = %lu ", p->pSett->CutCount[0] ); - printf( "Merge = %lu ", p->pSett->CutCount[1] ); - printf( "Eval = %lu ", p->pSett->CutCount[2] ); - printf( "Cut = %lu ", p->pSett->CutCount[3] ); + printf( "CutPair = %lu ", (long)p->pSett->CutCount[0] ); + printf( "Merge = %lu ", (long)p->pSett->CutCount[1] ); + printf( "Eval = %lu ", (long)p->pSett->CutCount[2] ); + printf( "Cut = %lu ", (long)p->pSett->CutCount[3] ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); printf( "Memory: " ); printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) ); diff --git a/src/aig/gia/giaLf.c b/src/aig/gia/giaLf.c index 082b1928..7973966a 100644 --- a/src/aig/gia/giaLf.c +++ b/src/aig/gia/giaLf.c @@ -2012,14 +2012,14 @@ void Lf_ManPrintStats( Lf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); - printf( "LUT =%9lu ", p->pPars->Area+p->nInverters ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); + printf( "LUT =%9lu ", (long)p->pPars->Area+p->nInverters ); if ( Vec_FltSize(&p->vSwitches) ) printf( "Swt =%8.1f ", p->Switches ); if ( p->pPars->fUseMux7 ) - printf( "Mux7 =%7lu ", p->pPars->Mux7 ); + printf( "Mux7 =%7lu ", (long)p->pPars->Mux7 ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 591f5bc5..2ded34bd 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -1415,11 +1415,11 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle ) if ( !p->pPars->fVerbose ) return; printf( "%s : ", pTitle ); - printf( "Level =%6lu ", p->pPars->Delay ); - printf( "Area =%9lu ", p->pPars->Area ); - printf( "Edge =%9lu ", p->pPars->Edge ); + printf( "Level =%6lu ", (long)p->pPars->Delay ); + printf( "Area =%9lu ", (long)p->pPars->Area ); + printf( "Edge =%9lu ", (long)p->pPars->Edge ); if ( p->pPars->fGenCnf ) - printf( "CNF =%9lu ", p->pPars->Clause ); + printf( "CNF =%9lu ", (long)p->pPars->Clause ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); fflush( stdout ); } diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c index 757034cd..adb64d79 100644 --- a/src/base/abci/abcExact.c +++ b/src/base/abci/abcExact.c @@ -873,7 +873,7 @@ static void Ses_StoreRead( Ses_Store_t * pStore, const char * pFilename, int fSy fclose( pFile ); - printf( "read %lu entries from file\n", nEntries ); + printf( "read %lu entries from file\n", (long)nEntries ); } // computes top decomposition of variables wrt. to AND and OR diff --git a/src/map/if/ifDec16.c b/src/map/if/ifDec16.c index 22de91ba..4b555bf8 100644 --- a/src/map/if/ifDec16.c +++ b/src/map/if/ifDec16.c @@ -902,7 +902,7 @@ void If_CluReverseOrder_old( word * pF, int nVars, int * V2P, int * P2V, int iVa // return the number of cofactors w.r.t. the topmost vars (nBSsize) int If_CluCountCofs( word * pF, int nVars, int nBSsize, int iShift, word pCofs[3][CLU_WRD_MAX/4] ) { - word iCofs[128], iCof, Result = 0; + word iCofs[128] = {0}, iCof, Result = 0; word * pCofA, * pCofB; int nMints = (1 << nBSsize); int i, c, w, nCofs; diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 5ecf76bb..b48cfbe1 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -765,10 +765,10 @@ Vec_Str_t * Scl_LibertyParseGenlibStr( char * pFileName, int fVerbose ) ***********************************************************************/ //#define SCL_DEBUG #ifdef SCL_DEBUG -static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); } -static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", Val ); Vec_StrPutW( vOut, Val ); } -static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); } -static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); } +static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); } +static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", (long)Val ); Vec_StrPutW( vOut, Val ); } +static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); } +static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); } static inline void Vec_StrPut_( Vec_Str_t * vOut ) { printf( "\n" ); } #else static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { Vec_StrPutI( vOut, Val ); } diff --git a/src/proof/acec/acecCo.c b/src/proof/acec/acecCo.c index 1e8ed7bb..a997eb03 100644 --- a/src/proof/acec/acecCo.c +++ b/src/proof/acec/acecCo.c @@ -109,7 +109,7 @@ Vec_Int_t * Gia_PolynCoreOrder_int( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Wec { Vec_Int_t * vOrder = Vec_IntAlloc( 1000 ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(pGia) ); - int i, k, Index, Driver, Entry1, Entry2 = -1; + int i, k, Index = -1, Driver, Entry1, Entry2 = -1; // mark roots Vec_IntForEachEntry( vRoots, Driver, i ) Vec_BitWriteEntry( vIsRoot, Driver, 1 ); -- cgit v1.2.3 From 3dd2325aa8572bbe0689a537101f138a0c7b8c87 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 09:51:38 +0700 Subject: Adding an option to not add buffers to decouple COs driven by the same internal node. --- src/base/abc/abcUtil.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index f01ef07a..dd3a75b7 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -1077,6 +1077,7 @@ void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate ) ***********************************************************************/ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate ) { + int fAddBuffers = 1; Vec_Ptr_t * vDrivers, * vCoTerms; Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin; int i, k, LevelMax, nTotal = 0; @@ -1191,6 +1192,12 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate ) // collect COs that needs fixing by adding buffers or duplicating vCoTerms = Vec_PtrAlloc( 100 ); Abc_NtkIncrementTravId( pNtk ); + + // The following cases should be addressed only if the network is written + // into a BLIF file. Otherwise, it is possible to skip them: + // (1) if a CO points to a CI with a different name + // (2) if an internal node drives more than one CO + if ( fAddBuffers ) Abc_NtkForEachCo( pNtk, pNode, i ) { // if the driver is a CI and has different name, this is an error -- cgit v1.2.3 From a2813847318bf22e0c36c7141047eaa82657f60d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 14:42:47 +0700 Subject: Bug fix in delay-opt framework. --- src/opt/sbd/sbdCore.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/opt/sbd/sbdCore.c b/src/opt/sbd/sbdCore.c index 179977fb..4f560a0a 100644 --- a/src/opt/sbd/sbdCore.c +++ b/src/opt/sbd/sbdCore.c @@ -1964,7 +1964,7 @@ void Sbd_ManDeriveMapping_rec( Sbd_Man_t * p, Gia_Man_t * pNew, int iObj ) void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) { Gia_Obj_t * pObj, * pFan; - int i, k, iFan, iObjNew, * pCut, * pCutNew; + int i, k, iFan, iObjNew, iFanNew, * pCut, * pCutNew; Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); // derive cuts for the new manager p->vLutCuts2 = Vec_IntStart( Gia_ManObjNum(pNew) * (p->pPars->nLutSize + 1) ); @@ -1986,10 +1986,10 @@ void Sbd_ManDeriveMapping( Sbd_Man_t * p, Gia_Man_t * pNew ) pFan = Gia_ManObj( p->pGia, iFan ); if ( pFan->Value == ~0 ) continue; - iObjNew = Abc_Lit2Var( pFan->Value ); - if ( iObjNew == 0 ) + iFanNew = Abc_Lit2Var( pFan->Value ); + if ( iFanNew == 0 || iFanNew == iObjNew ) continue; - Vec_IntPushUniqueOrder( vLeaves, iObjNew ); + Vec_IntPushUniqueOrder( vLeaves, iFanNew ); } assert( Vec_IntSize(vLeaves) <= p->pPars->nLutSize ); //assert( Vec_IntSize(vLeaves) > 1 ); -- cgit v1.2.3 From 8ad3d6bec8ff89c8d742869cff05735d6f023fc8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 8 Jan 2017 03:10:42 +0700 Subject: Bug fixes by Clifford Wolf. --- src/map/if/ifLibLut.c | 4 ++++ src/opt/sbd/sbdCnf.c | 4 ++-- src/opt/sfm/sfmCnf.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/map/if/ifLibLut.c b/src/map/if/ifLibLut.c index 26fa137b..1033cc1f 100644 --- a/src/map/if/ifLibLut.c +++ b/src/map/if/ifLibLut.c @@ -75,6 +75,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) Abc_Print( 1, "Error in the LUT library file \"%s\".\n", FileName ); ABC_FREE( p->pName ); ABC_FREE( p ); + fclose( pFile ); return NULL; } @@ -93,6 +94,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) ABC_FREE( p->pName ); ABC_FREE( p ); Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i ); + fclose( pFile ); return NULL; } @@ -105,6 +107,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) ABC_FREE( p->pName ); ABC_FREE( p ); Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i ); + fclose( pFile ); return NULL; } i++; @@ -136,6 +139,7 @@ If_LibLut_t * If_LibLutRead( char * FileName ) } } + fclose( pFile ); return p; } diff --git a/src/opt/sbd/sbdCnf.c b/src/opt/sbd/sbdCnf.c index 6291baed..8705858e 100644 --- a/src/opt/sbd/sbdCnf.c +++ b/src/opt/sbd/sbdCnf.c @@ -44,7 +44,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ void Sbd_PrintCnf( Vec_Str_t * vCnf ) { - char Entry; + signed char Entry; int i, Lit; Vec_StrForEachEntry( vCnf, Entry, i ) { @@ -121,7 +121,7 @@ int Sbd_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf void Sbd_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar ) { Vec_Int_t * vClause; - char Entry; + signed char Entry; int i, Lit; Vec_WecClear( vRes ); vClause = Vec_WecPushLevel( vRes ); diff --git a/src/opt/sfm/sfmCnf.c b/src/opt/sfm/sfmCnf.c index 0ab92258..b4dd11f8 100644 --- a/src/opt/sfm/sfmCnf.c +++ b/src/opt/sfm/sfmCnf.c @@ -45,7 +45,7 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ void Sfm_PrintCnf( Vec_Str_t * vCnf ) { - char Entry; + signed char Entry; int i, Lit; Vec_StrForEachEntry( vCnf, Entry, i ) { @@ -153,7 +153,7 @@ Vec_Wec_t * Sfm_CreateCnf( Sfm_Ntk_t * p ) void Sfm_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar ) { Vec_Int_t * vClause; - char Entry; + signed char Entry; int i, Lit; Vec_WecClear( vRes ); vClause = Vec_WecPushLevel( vRes ); -- cgit v1.2.3 From feb57982a999b6c6faf58b0e279d9b8949802962 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 10:46:29 +0700 Subject: Change suggested by Udi Finkelstein. --- src/base/cmd/cmd.c | 21 +-------------------- src/base/cmd/cmdLoad.c | 21 +-------------------- 2 files changed, 2 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index 0b7c1788..ab037139 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -1147,26 +1147,7 @@ usage: #if defined(WIN32) && !defined(__cplusplus) #include - -// these structures are defined in but are for some reason invisible -typedef unsigned long _fsize_t; // Could be 64 bits for Win32 - -struct _finddata_t { - unsigned attrib; - time_t time_create; // -1 for FAT file systems - time_t time_access; // -1 for FAT file systems - time_t time_write; - _fsize_t size; - char name[260]; -}; - -extern long _findfirst( char *filespec, struct _finddata_t *fileinfo ); -extern int _findnext( long handle, struct _finddata_t *fileinfo ); -extern int _findclose( long handle ); - -//extern char * _getcwd( char * buffer, int maxlen ); -//extern int _chdir( const char *dirname ); - +#include /**Function************************************************************* diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c index 7f7c1b60..accd9440 100644 --- a/src/base/cmd/cmdLoad.c +++ b/src/base/cmd/cmdLoad.c @@ -97,26 +97,7 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv ) #if defined(WIN32) && !defined(__cplusplus) #include - - -// these structures are defined in but are for some reason invisible -typedef unsigned long _fsize_t; // Could be 64 bits for Win32 - -struct _finddata_t { - unsigned attrib; - time_t time_create; // -1 for FAT file systems - time_t time_access; // -1 for FAT file systems - time_t time_write; - _fsize_t size; - char name[260]; -}; - -extern long _findfirst( char *filespec, struct _finddata_t *fileinfo ); -extern int _findnext( long handle, struct _finddata_t *fileinfo ); -extern int _findclose( long handle ); - -//extern char * _getcwd( char * buffer, int maxlen ); -//extern int _chdir( const char *dirname ); +#include /**Function************************************************************* -- cgit v1.2.3 From 9514c327e3d8703775d138fe029b247adbf06099 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:04:48 +0700 Subject: Bug fix in delay-opt framework. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 2be65ed0..a69737ea 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41153,7 +41153,7 @@ usage: Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); Abc_Print( -2, "\t-C : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit ); - Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "area": "area+edges" ); + Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" ); Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" ); Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" ); -- cgit v1.2.3 From 902377a45d9fe9ab7939f31d848b48f40a612480 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:16:28 +0700 Subject: Delay-oriented performance improvement in &dch. --- src/aig/gia/giaAig.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index 3cf01c70..cbfe86a4 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -22,6 +22,7 @@ #include "proof/fra/fra.h" #include "proof/dch/dch.h" #include "opt/dar/dar.h" +#include "opt/dau/dau.h" ABC_NAMESPACE_IMPL_START @@ -576,11 +577,16 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) ***********************************************************************/ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) { - Gia_Man_t * pGia; + Gia_Man_t * pGia, * pGia1; Aig_Man_t * pNew; if ( p->pManTime && p->vLevels == NULL ) Gia_ManLevelWithBoxes( p ); - pNew = Gia_ManToAig( p, 0 ); + if ( Gia_ManHasMapping(p) ) + pGia1 = (Gia_Man_t *)Dsm_ManDeriveGia( p, 0 ); + else + pGia1 = Gia_ManDup( p ); + pNew = Gia_ManToAig( pGia1, 0 ); + Gia_ManStop( pGia1 ); pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars ); // pGia = Gia_ManFromAig( pNew ); pGia = Gia_ManFromAigChoices( pNew ); -- cgit v1.2.3 From ab6a87a4db2b2d9b188c09d9142b96503261e9ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:35:13 +0700 Subject: Delay-oriented performance improvement in &dch (make it conditional). --- src/aig/gia/giaAig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index cbfe86a4..dfd4a467 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -577,11 +577,12 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) ***********************************************************************/ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) { + int fUseMapping = 0; Gia_Man_t * pGia, * pGia1; Aig_Man_t * pNew; if ( p->pManTime && p->vLevels == NULL ) Gia_ManLevelWithBoxes( p ); - if ( Gia_ManHasMapping(p) ) + if ( fUseMapping && Gia_ManHasMapping(p) ) pGia1 = (Gia_Man_t *)Dsm_ManDeriveGia( p, 0 ); else pGia1 = Gia_ManDup( p ); -- cgit v1.2.3 From fbdf28e4c937067737d84db37ff6e1a65348df5f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 19:50:05 +0700 Subject: Updated to arithmetic verification. --- src/aig/gia/giaDup.c | 16 +- src/base/abci/abc.c | 146 ++++++++++++------ src/proof/acec/acec.h | 18 ++- src/proof/acec/acecCore.c | 385 ++++++++++++++++++++++++++++++++++++++++++++-- src/proof/acec/acecInt.h | 13 +- src/proof/acec/acecPa.c | 16 ++ 6 files changed, 528 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index c58596b2..cdb6a208 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3879,12 +3879,20 @@ Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p ) int i, iObj, iObj2, fFlip, Count1 = 0; Vec_Int_t * vXors, * vPart[2], * vOrder; Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0); - assert( Gia_ManCoNum(p) == 1 ); vXors = Vec_IntAlloc( 100 ); - if ( Gia_ObjFaninC0(pObj) ) - Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors ); + if ( Gia_ManCoNum(p) == 1 ) + { + if ( Gia_ObjFaninC0(pObj) ) + Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors ); + else + Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); + } else - Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); + { + Gia_ManForEachCo( p, pObj, i ) + if ( Gia_ObjFaninId0p(p, pObj) > 0 ) + Vec_IntPush( vXors, Gia_ObjFaninId0p(p, pObj) ); + } // order by support size Gia_ManDupDemiterOrderXors( p, vXors ); //Vec_IntPrint( vXors ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index a69737ea..dd157afd 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40532,14 +40532,12 @@ usage: int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pFile; - Cec_ParCec_t ParsCec, * pPars = &ParsCec; - Gia_Man_t * pSecond; - char * FileName, * pTemp; + Acec_ParCec_t ParsCec, * pPars = &ParsCec; char ** pArgvNew; - int c, nArgcNew, fMiter = 0, fDualOutput = 0, fTwoOutput = 0; - Cec_ManCecSetDefaultParams( pPars ); + int c, nArgcNew; + Acec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdtvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtvh" ) ) != EOF ) { switch ( c ) { @@ -40565,17 +40563,14 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->TimeLimit < 0 ) goto usage; break; - case 'n': - pPars->fNaive ^= 1; - break; case 'm': - fMiter ^= 1; + pPars->fMiter ^= 1; break; case 'd': - fDualOutput ^= 1; + pPars->fDualOutput ^= 1; break; case 't': - fTwoOutput ^= 1; + pPars->fTwoOutput ^= 1; break; case 'v': pPars->fVerbose ^= 1; @@ -40586,15 +40581,20 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( fMiter ) + if ( pPars->fMiter ) { Gia_Man_t * pGia0, * pGia1, * pDual; + if ( argc != globalUtilOptind ) + { + Abc_Print( -1, "Abc_CommandAbc9Acec(): If the input is a miter, it cannot be given on the command line.\n" ); + return 1; + } if ( pAbc->pGia == NULL ) { Abc_Print( -1, "Abc_CommandAbc9Acec(): There is no AIG.\n" ); return 1; } - if ( fDualOutput ) + if ( pPars->fDualOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) { @@ -40604,28 +40604,28 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( !pPars->fSilent ) Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); Gia_ManDemiterDual( pAbc->pGia, &pGia0, &pGia1 ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } - else if ( fTwoOutput ) + else if ( pPars->fTwoOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) { - Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" ); + Abc_Print( -1, "The two-output miter should have an even number of outputs.\n" ); return 1; } if ( !pPars->fSilent ) Abc_Print( 1, "Assuming the current network is a two-word miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); Gia_ManDemiterTwoWords( pAbc->pGia, &pGia0, &pGia1 ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } - else + else // regular single- or multi-output miter { if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a regular single- or multi-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); pDual = Gia_ManDemiterToDual( pAbc->pGia ); Gia_ManDemiterDual( pDual, &pGia0, &pGia1 ); Gia_ManStop( pDual ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb ); Gia_ManStop( pGia0 ); @@ -40635,52 +40635,96 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 1 ) + if ( nArgcNew == 0 || nArgcNew == 1 ) { - if ( pAbc->pGia->pSpec == NULL ) + Gia_Man_t * pSecond; + char * pTemp, * FileName = NULL; + if ( nArgcNew == 0 ) { - Abc_Print( -1, "File name is not given on the command line.\n" ); - return 1; + FileName = pAbc->pGia->pSpec; + if ( FileName == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } } - FileName = pAbc->pGia->pSpec; + else // if ( nArgcNew == 1 ) + { + FileName = pArgvNew[0]; + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + } + pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pSecond == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + pAbc->Status = Acec_Solve( pAbc->pGia, pSecond, pPars ); + Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Gia_ManStop( pSecond ); } - else - FileName = pArgvNew[0]; - // fix the wrong symbol - for ( pTemp = FileName; *pTemp; pTemp++ ) - if ( *pTemp == '>' ) - *pTemp = '\\'; - if ( (pFile = fopen( FileName, "r" )) == NULL ) + else if ( nArgcNew == 2 ) { - Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); - if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", FileName ); - Abc_Print( 1, "\n" ); - return 1; + Gia_Man_t * pGias[2] = {NULL}; int i; + char * pTemp, * FileName[2] = { pArgvNew[0], pArgvNew[1] }; + for ( i = 0; i < 2; i++ ) + { + // fix the wrong symbol + for ( pTemp = FileName[i]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName[i], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName[i] ); + if ( (FileName[i] = Extra_FileGetSimilarName( FileName[i], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName[i] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[i] = Gia_AigerRead( FileName[i], 0, 0, 0 ); + if ( pGias[i] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + } + pAbc->Status = Acec_Solve( pGias[0], pGias[1], pPars ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); } - fclose( pFile ); - pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); - if ( pSecond == NULL ) + else { - Abc_Print( -1, "Reading AIGER has failed.\n" ); - return 0; + Abc_Print( -1, "Too many command-line arguments.\n" ); + return 1; } - pAbc->Status = Gia_PolynCec( pAbc->pGia, pSecond, pPars ); - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); - Gia_ManStop( pSecond ); return 0; usage: - Abc_Print( -2, "usage: &acec [-CT num] [-nmdtvh]\n" ); + Abc_Print( -2, "usage: &acec [-CT num] [-mdtvh] \n" ); Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); - Abc_Print( -2, "\t-n : toggle using naive SAT-based checking [default = %s]\n", pPars->fNaive? "yes":"no"); - Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits"); - Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no"); - Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", fTwoOutput? "yes":"no"); + Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits"); + Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no"); + Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n"); + Abc_Print( -2, "\tfile2 : (optional) the file with the second network\n"); return 1; } diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index c61b4485..058e0f56 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -38,6 +38,21 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +// combinational equivalence checking parameters +typedef struct Acec_ParCec_t_ Acec_ParCec_t; +struct Acec_ParCec_t_ +{ + int nBTLimit; // conflict limit at a node + int TimeLimit; // the runtime limit in seconds + int fMiter; // input circuit is a miter + int fDualOutput; // dual-output miter + int fTwoOutput; // two-output miter + int fSilent; // print no messages + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats + int iOutFail; // the number of failed output +}; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -51,7 +66,8 @@ ABC_NAMESPACE_HEADER_START //////////////////////////////////////////////////////////////////////// /*=== acecCore.c ========================================================*/ -extern int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars ); +extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ); +extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ); /*=== acecFadds.c ========================================================*/ extern Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose, Vec_Int_t ** vCutsXor2 ); extern Vec_Int_t * Gia_ManDetectHalfAdders( Gia_Man_t * p, int fVerbose ); diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index ac7ee67b..09ccb532 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "acecInt.h" +#include "proof/cec/cec.h" ABC_NAMESPACE_IMPL_START @@ -31,6 +32,31 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [This procedure sets default parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) +{ + memset( p, 0, sizeof(Acec_ParCec_t) ); + p->nBTLimit = 1000; // conflict limit at a node + p->TimeLimit = 0; // the runtime limit in seconds + p->fMiter = 0; // input circuit is a miter + p->fDualOutput = 0; // dual-output miter + p->fTwoOutput = 0; // two-output miter + p->fSilent = 0; // print no messages + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats + p->iOutFail = -1; // the number of failed output +} + /**Function************************************************************* Synopsis [] @@ -42,15 +68,356 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars ) -{ - Vec_Int_t * vOrder0 = Gia_PolynReorder( pGia0, pPars->fVerbose, pPars->fVeryVerbose ); - Vec_Int_t * vOrder1 = Gia_PolynReorder( pGia1, pPars->fVerbose, pPars->fVeryVerbose ); - Gia_PolynBuild( pGia0, vOrder0, 0, pPars->fVerbose, pPars->fVeryVerbose ); - Gia_PolynBuild( pGia1, vOrder1, 0, pPars->fVerbose, pPars->fVeryVerbose ); - Vec_IntFree( vOrder0 ); - Vec_IntFree( vOrder1 ); - return 1; +void Acec_BoxFree( Acec_Box_t * pBox ) +{ + Vec_WecFree( pBox->vUnique ); + Vec_WecFree( pBox->vShared ); + Vec_WecFree( pBox->vLeafLits ); + Vec_WecFree( pBox->vRootLits ); + ABC_FREE( pBox ); +} +void Acec_BoxFreeP( Acec_Box_t ** ppBox ) +{ + if ( *ppBox ) + Acec_BoxFree( *ppBox ); + *ppBox = NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) +{ + int And, Or; + Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); + And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); + Or = Gia_ManAppendOr2( pNew, Out[1], And ); + Out[0] = Abc_LitNot( Or ); +} +void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) +{ + int In2[2], Out1[2], Out2[2]; + Acec_InsertHadd( pNew, In, Out1 ); + In2[0] = Out1[0]; + In2[1] = In[2]; + Acec_InsertHadd( pNew, In2, Out2 ); + Out[0] = Out2[0]; + Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); +} +Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) +{ + Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); + Vec_Int_t * vLevel; + int i, In[3], Out[2]; + Vec_WecForEachLevel( vLeafMap, vLevel, i ) + { + if ( Vec_IntSize(vLevel) == 0 ) + { + Vec_IntPush( vRootRanks, 0 ); + continue; + } + while ( Vec_IntSize(vLevel) > 1 ) + { + if ( Vec_IntSize(vLevel) == 2 ) + Vec_IntPush( vLevel, 0 ); + In[0] = Vec_IntPop( vLevel ); + In[1] = Vec_IntPop( vLevel ); + In[2] = Vec_IntPop( vLevel ); + Acec_InsertFadd( pNew, In, Out ); + Vec_IntPush( vLevel, Out[0] ); + if ( i-1 < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i+1); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, Out[1] ); + } + assert( Vec_IntSize(vLevel) == 1 ); + Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); + } + return vRootRanks; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) +{ + Gia_Obj_t * pObj; + int i; + Gia_ManFillValue( pAdd ); + Gia_ManConst0(pAdd)->Value = 0; + if ( pBase == NULL ) + { + pBase = Gia_ManStart( Gia_ManObjNum(pAdd) ); + pBase->pName = Abc_UtilStrsav( pAdd->pName ); + pBase->pSpec = Abc_UtilStrsav( pAdd->pSpec ); + Gia_ManForEachCi( pAdd, pObj, i ) + pObj->Value = Gia_ManAppendCi(pBase); + Gia_ManHashAlloc( pBase ); + } + else + { + assert( Gia_ManCiNum(pBase) == Gia_ManCiNum(pAdd) ); + Gia_ManForEachCi( pAdd, pObj, i ) + pObj->Value = Gia_Obj2Lit( pBase, Gia_ManCi(pBase, i) ); + } + Gia_ManForEachAnd( pAdd, pObj, i ) + pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + return pBase; +} +Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd ) +{ + Gia_Obj_t * pObj; int i; + Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) ); + Gia_ManForEachCand( pAdd, pObj, i ) + Vec_IntWriteEntry( vMapNew, i, Abc_Lit2Var(pObj->Value) ); + return vMapNew; +} +void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) +{ + Gia_Man_t * pBase; + pBase = Acec_FindEquivs( NULL, pOne ); + pBase = Acec_FindEquivs( pBase, pTwo ); + *pvMap1 = Acec_CountRemap( pOne ); + *pvMap2 = Acec_CountRemap( pTwo ); + Gia_ManStop( pBase ); +} +static inline void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCosts ) +{ + int i, j, best_i; + for ( i = 0; i < nSize-1; i++ ) + { + best_i = i; + for ( j = i+1; j < nSize; j++ ) + if ( pCosts[Abc_Lit2Var(pArray[j])] > pCosts[Abc_Lit2Var(pArray[best_i])] ) + best_i = j; + ABC_SWAP( int, pArray[i], pArray[best_i] ); + } +} +int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) +{ + Vec_Int_t * vMap0, * vMap1, * vLevel; + int i, nSize, nTotal; + Acec_ComputeEquivClasses( pBox0->pGia, pBox1->pGia, &vMap0, &vMap1 ); + // sort nodes in the classes by their equivalences + Vec_WecForEachLevel( pBox0->vLeafLits, vLevel, i ) + Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); + Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) + Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); + // reorder nodes to have the same order + assert( pBox0->vShared == NULL ); + assert( pBox1->vShared == NULL ); + pBox0->vShared = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) ); + pBox1->vShared = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) ); + pBox0->vUnique = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) ); + pBox1->vUnique = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) ); + nSize = Abc_MinInt( Vec_WecSize(pBox0->vLeafLits), Vec_WecSize(pBox1->vLeafLits) ); + Vec_WecForEachLevelStart( pBox0->vLeafLits, vLevel, i, nSize ) + Vec_IntAppend( Vec_WecEntry(pBox0->vUnique, i), vLevel ); + Vec_WecForEachLevelStart( pBox1->vLeafLits, vLevel, i, nSize ) + Vec_IntAppend( Vec_WecEntry(pBox1->vUnique, i), vLevel ); + for ( i = 0; i < nSize; i++ ) + { + Vec_Int_t * vShared0 = Vec_WecEntry( pBox0->vShared, i ); + Vec_Int_t * vShared1 = Vec_WecEntry( pBox1->vShared, i ); + Vec_Int_t * vUnique0 = Vec_WecEntry( pBox0->vUnique, i ); + Vec_Int_t * vUnique1 = Vec_WecEntry( pBox1->vUnique, i ); + + Vec_Int_t * vLevel0 = Vec_WecEntry( pBox0->vLeafLits, i ); + Vec_Int_t * vLevel1 = Vec_WecEntry( pBox1->vLeafLits, i ); + int * pBeg0 = Vec_IntArray(vLevel0); + int * pBeg1 = Vec_IntArray(vLevel1); + int * pEnd0 = Vec_IntLimit(vLevel0); + int * pEnd1 = Vec_IntLimit(vLevel1); + while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) + { + if ( *pBeg0 == *pBeg1 ) + { + Vec_IntPush( vShared0, *pBeg0++ ); + Vec_IntPush( vShared1, *pBeg1++ ); + } + else if ( *pBeg0 > *pBeg1 ) + Vec_IntPush( vUnique0, *pBeg0++ ); + else + Vec_IntPush( vUnique1, *pBeg1++ ); + } + while ( pBeg0 < pEnd0 ) + Vec_IntPush( vUnique0, *pBeg0++ ); + while ( pBeg1 < pEnd1 ) + Vec_IntPush( vUnique1, *pBeg1++ ); + assert( Vec_IntSize(vShared0) == Vec_IntSize(vShared1) ); + assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); + assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); + } + nTotal = Vec_WecSizeSize(pBox0->vShared); + printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); + printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + return nTotal; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); +} +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +{ + Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); + Vec_Int_t * vLevel, * vRootRanks; + int i, k, iLit, iLitNew; + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); + iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + Vec_WecPush( vLeafMap, i, iLitNew ); + } + // construct map of root literals + vRootRanks = Acec_InsertTree( pNew, vLeafMap ); + Vec_WecFree( vLeafMap ); + return vRootRanks; +} + +Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) +{ + Gia_Man_t * p = pBox->pGia; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vRootRanks, * vLevel; + int i, k, iLit, iLitNew; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + // implement tree + if ( fAll ) + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + else + { + Vec_Wec_t * vLeafLits; + assert( pBox->vShared != NULL ); + assert( pBox->vUnique != NULL ); + vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); + // add these roots to the unique ones + vLeafLits = Vec_WecDup( pBox->vUnique ); + Vec_IntForEachEntry( vRootRanks, iLit, i ) + { + if ( i < Vec_WecSize(vLeafLits) ) + vLevel = Vec_WecEntry(vLeafLits, i); + else + vLevel = Vec_WecPushLevel(vLeafLits); + Vec_IntPush( vLevel, iLit ); + } + Vec_IntFree( vRootRanks ); + vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); + Vec_WecFree( vLeafLits ); + } + // update polarity of literals + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, k ); + pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + } + Vec_IntFree( vRootRanks ); + // construct the outputs + Gia_ManForEachCo( p, pObj, i ) + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) +{ + int status = -1; + Gia_Man_t * pMiter; + Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; + Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0 ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1 ); + if ( pBox0 == NULL || pBox1 == NULL ) // cannot match + printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); + else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching + printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" ); + else + { + pGia0n = Acec_InsertBox( pBox0, 1 ); + pGia1n = Acec_InsertBox( pBox1, 1 ); + printf( "Found, matched, and normalized arithmetic boxes in LHS and RHS. Solving resulting CEC.\n" ); + } + // solve regular CEC problem + Cec_ManCecSetDefaultParams( pCecPars ); + pCecPars->nBTLimit = pPars->nBTLimit; + pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose ); + if ( pMiter ) + { + int fDumpMiter = 1; + if ( fDumpMiter ) + { + Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" ); + Gia_AigerWrite( pMiter, "acec_miter.aig", 0, 0 ); + } + status = Cec_ManVerify( pMiter, pCecPars ); + ABC_SWAP( Abc_Cex_t *, pGia0->pCexComb, pMiter->pCexComb ); + Gia_ManStop( pMiter ); + } + else + printf( "Miter computation has failed.\n" ); + if ( pGia0n != pGia0 ) + Gia_ManStop( pGia0n ); + if ( pGia1n != pGia1 ) + Gia_ManStop( pGia1n ); + Acec_BoxFreeP( &pBox0 ); + Acec_BoxFreeP( &pBox1 ); + return status; } //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index e761e56e..d53b61c7 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////////////////// #include "aig/gia/gia.h" -#include "proof/cec/cec.h" #include "acec.h" //////////////////////////////////////////////////////////////////////// @@ -38,6 +37,16 @@ ABC_NAMESPACE_HEADER_START +typedef struct Acec_Box_t_ Acec_Box_t; +struct Acec_Box_t_ +{ + Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vLeafLits; // leaf literals by rank + Vec_Wec_t * vRootLits; // root literals by rank + Vec_Wec_t * vShared; // shared leaves + Vec_Wec_t * vUnique; // unique leaves +}; + //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// @@ -54,6 +63,8 @@ ABC_NAMESPACE_HEADER_START /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== acecPa.c ========================================================*/ +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecPa.c b/src/proof/acec/acecPa.c index ecaf2047..b59cdbef 100644 --- a/src/proof/acec/acecPa.c +++ b/src/proof/acec/acecPa.c @@ -273,6 +273,22 @@ void Pas_ManComputeCutsTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +{ + return NULL; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 5fbc0cd7f09a382241266404d78c18c5443d2b9d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 10 Jan 2017 16:58:24 +0700 Subject: Updates to arithmetic verification. --- src/aig/gia/giaShow.c | 6 ----- src/proof/acec/acec.h | 4 ++++ src/proof/acec/acecCl.c | 8 ------- src/proof/acec/acecInt.h | 7 +++++- src/proof/acec/acecPa.c | 21 ----------------- src/proof/acec/acecPool.c | 17 -------------- src/proof/acec/acecRe.c | 4 ++++ src/proof/acec/acecTree.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ src/proof/acec/module.make | 1 + 9 files changed, 71 insertions(+), 53 deletions(-) create mode 100644 src/proof/acec/acecTree.c (limited to 'src') diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index afd36fff..986d5624 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -814,18 +814,12 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In } void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Abc_ShowFile( char * FileNameDot ); static int Counter = 0; char FileNameDot[200]; FILE * pFile; Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); - Ree_ManRemoveTrivial( pMan, vAdds ); - Ree_ManRemoveContained( pMan, vAdds ); // create the file name // Gia_ShowGetFileName( pMan->pName, FileNameDot ); diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 058e0f56..918119f8 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -76,6 +76,10 @@ extern Vec_Int_t * Gia_PolynReorder( Gia_Man_t * pGia, int fVerbose, int fVery extern Vec_Int_t * Gia_PolynFindOrder( Gia_Man_t * pGia, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int fVerbose, int fVeryVerbose ); /*=== acecPolyn.c ========================================================*/ extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fSigned, int fVerbose, int fVeryVerbose ); +/*=== acecRe.c ========================================================*/ +extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); +extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); +extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 63483d57..145f2e0b 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -306,18 +306,10 @@ Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet ) ***********************************************************************/ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - abctime clk = Abc_Clock(); Gia_Man_t * pNew; Vec_Int_t * vRootXorSet; // Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); -// Ree_ManRemoveTrivial( p, vAdds ); -// Ree_ManRemoveContained( p, vAdds ); //Ree_ManPrintAdders( vAdds, 1 ); // printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index d53b61c7..065f6300 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -63,12 +63,17 @@ struct Acec_Box_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== acecPa.c ========================================================*/ +/*=== acecCo.c ========================================================*/ +extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); +extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecTree.c ========================================================*/ extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); + + ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecPa.c b/src/proof/acec/acecPa.c index b59cdbef..6b382d91 100644 --- a/src/proof/acec/acecPa.c +++ b/src/proof/acec/acecPa.c @@ -248,11 +248,6 @@ int Pas_ManComputeCuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vOrder, Ve ***********************************************************************/ void Pas_ManComputeCutsTest( Gia_Man_t * p ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); - - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); abctime clk = Abc_Clock(); Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); Vec_Int_t * vIns, * vOuts; @@ -273,22 +268,6 @@ void Pas_ManComputeCutsTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) -{ - return NULL; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecPool.c b/src/proof/acec/acecPool.c index 08ee37f2..0868545e 100644 --- a/src/proof/acec/acecPool.c +++ b/src/proof/acec/acecPool.c @@ -303,17 +303,9 @@ void Acec_ManPrintRanks( Vec_Int_t * vPairs ) ***********************************************************************/ void Acec_ManProfile( Gia_Man_t * p, int fVerbose ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - abctime clk = Abc_Clock(); Vec_Wec_t * vBoxes; int i; Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, fVerbose ); - Ree_ManRemoveTrivial( p, vAdds ); - Ree_ManRemoveContained( p, vAdds ); //Ree_ManPrintAdders( vAdds, 1 ); printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); @@ -396,13 +388,6 @@ Vec_Int_t * Acec_ManPoolTopMost( Gia_Man_t * p, Vec_Int_t * vAdds ) } void Acec_ManPool( Gia_Man_t * p ) { - extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); - extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); - - extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); - extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); - extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); - extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); Vec_Int_t * vTops, * vTree; Vec_Wec_t * vTrees; @@ -413,8 +398,6 @@ void Acec_ManPool( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - Ree_ManRemoveTrivial( p, vAdds ); - Ree_ManRemoveContained( p, vAdds ); nFadds = Ree_ManCountFadds( vAdds ); printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 26faad00..60b894c8 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -392,6 +392,8 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos } Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ) { + extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); + extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds ); Gia_Obj_t * pObj; int * pList0, * pList1, i, nCuts = 0; Hash_IntMan_t * pHash = Hash_IntManStart( 1000 ); @@ -430,6 +432,8 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) ); Vec_IntFree( vData ); Hash_IntManStop( pHash ); + Ree_ManRemoveTrivial( p, vAdds ); + Ree_ManRemoveContained( p, vAdds ); return vAdds; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c new file mode 100644 index 00000000..c2d89a1c --- /dev/null +++ b/src/proof/acec/acecTree.c @@ -0,0 +1,56 @@ +/**CFile**************************************************************** + + FileName [acecTree.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Adder tree construction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecTree.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +{ + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 4003695e..4db695c5 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -11,4 +11,5 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ src/proof/acec/acecSt.c \ + src/proof/acec/acecTree.c \ src/proof/acec/acecUtil.c -- cgit v1.2.3 From 4bfb97d3e1b313f4b72ee0fa7adfa8949236db85 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 10 Jan 2017 19:19:02 +0700 Subject: Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 10 +- src/proof/acec/acecInt.h | 2 + src/proof/acec/acecTree.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 09ccb532..a8123a5e 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -70,10 +70,12 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) ***********************************************************************/ void Acec_BoxFree( Acec_Box_t * pBox ) { - Vec_WecFree( pBox->vUnique ); - Vec_WecFree( pBox->vShared ); - Vec_WecFree( pBox->vLeafLits ); - Vec_WecFree( pBox->vRootLits ); + Vec_WecFreeP( &pBox->vLeafs ); + Vec_WecFreeP( &pBox->vRoots ); + Vec_WecFreeP( &pBox->vLeafLits ); + Vec_WecFreeP( &pBox->vRootLits ); + Vec_WecFreeP( &pBox->vUnique ); + Vec_WecFreeP( &pBox->vShared ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 065f6300..08f163e0 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -41,6 +41,8 @@ typedef struct Acec_Box_t_ Acec_Box_t; struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vLeafs; // leaf literals by rank + Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index c2d89a1c..08122584 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -31,6 +31,281 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Find internal cut points with exactly one adder fanin/fanout.] + + Description [Returns a map of point into its input/output adder.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut ) +{ + int * pPlace = Vec_IntEntryP( vMap, Abc_Var2Lit(iObj, fOut) ); + if ( *pPlace == -1 ) + *pPlace = iAdd; + else if ( *pPlace >= 0 ) + *pPlace = -2; +} +Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) ); + int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+3), i, 1 ); + Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+4), i, 1 ); + } + return vMap; +} + +/**Function************************************************************* + + Synopsis [Find adder trees as groups of adders connected vis cut-points.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeWhichPoint( Vec_Int_t * vAdds, int iAdd, int iObj ) +{ + int k; + for ( k = 0; k < 5; k++ ) + if ( Vec_IntEntry(vAdds, 6*iAdd+k) == iObj ) + return k; + assert( 0 ); + return -1; +} +void Acec_TreeFindTrees2_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iAdd, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ) +{ + extern void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ); + int k; + if ( Vec_BitEntry(vFound, iAdd) ) + return; + Vec_BitWriteEntry( vFound, iAdd, 1 ); + Vec_IntPush( vTree, iAdd ); + Vec_IntPush( vTree, Rank ); + //printf( "Assigning rank %d to (%d:%d).\n", Rank, Vec_IntEntry(vAdds, 6*iAdd+3), Vec_IntEntry(vAdds, 6*iAdd+4) ); + for ( k = 0; k < 5; k++ ) + Acec_TreeFindTrees_rec( vAdds, vMap, Vec_IntEntry(vAdds, 6*iAdd+k), k == 4 ? Rank + 1 : Rank, vTree, vFound ); +} +void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound ) +{ + int In = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 1) ); + int Out = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 0) ); + if ( In < 0 || Out < 0 ) + return; + Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); + Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); +} +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); + Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds ); + Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 ); + Vec_Int_t * vTree; + int i, k, In, Out, Box, Rank, MinRank; + // go through the cut-points + Vec_IntForEachEntryDouble( vMap, In, Out, i ) + { + if ( In < 0 || Out < 0 ) + continue; + assert( Vec_BitEntry(vFound, In) == Vec_BitEntry(vFound, Out) ); + if ( Vec_BitEntry(vFound, In) ) + continue; + vTree = Vec_WecPushLevel( vTrees ); + Acec_TreeFindTrees_rec( vAdds, vMap, i/2, 0, vTree, vFound ); + // normalize rank + MinRank = ABC_INFINITY; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MinRank = Abc_MinInt( MinRank, Rank ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + Vec_IntWriteEntry( vTree, k+1, Rank - MinRank ); + } + Vec_BitFree( vFound ); + Vec_IntFree( vMap ); + // sort by size + Vec_WecSort( vTrees, 1 ); + return vTrees; +} +void Acec_TreeFindTreesTest( Gia_Man_t * p ) +{ + Vec_Wec_t * vTrees; + + abctime clk = Abc_Clock(); + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); + int nFadds = Ree_ManCountFadds( vAdds ); + printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + clk = Abc_Clock(); + vTrees = Acec_TreeFindTrees( p, vAdds ); + printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Vec_WecPrint( vTrees, 0 ); + + Vec_WecFree( vTrees ); + Vec_IntFree( vAdds ); +} + + +/**Function************************************************************* + + Synopsis [Creates leaves and roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_PrintRootLits( Vec_Wec_t * vRoots ) +{ + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevel( vRoots, vLevel, i ) + { + printf( "Rank %d : ", i ); + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); + } + printf( "\n" ); + } +} +int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) +{ + int k, Box, Rank, MaxRank = 0; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MaxRank = Abc_MaxInt( MaxRank, Rank ); + return MaxRank; +} +void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) +{ + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box, Rank; + Vec_BitWriteEntry( vIsLeaf, 0, 1 ); + Vec_BitWriteEntry( vIsRoot, 0, 1 ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + for ( k = 0; k < 3; k++ ) + { + if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + continue; + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k), 1 ); + Vec_WecPush( vLeaves, Rank, Vec_IntEntry(vAdds, 6*Box+k) ); + } + for ( k = 3; k < 5; k++ ) + { + if ( Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + continue; + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k), 1 ); + Vec_WecPush( vRoots, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), k==4), Vec_IntEntry(vAdds, 6*Box+2)!=0) ); + } + } + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vIsRoot ); + // sort each level + Vec_WecForEachLevel( vLeaves, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + Vec_WecForEachLevel( vRoots, vLevel, i ) + Vec_IntSort( vLevel, 0 ); +} + +/**Function************************************************************* + + Synopsis [Creates polarity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ +} + +/**Function************************************************************* + + Synopsis [Derives one adder tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); + pBox->pGia = p; + + pBox->vLeafs = Vec_WecStart( Acec_CreateBoxMaxRank(vTree) + 1 ); + pBox->vRoots = Vec_WecStart( Vec_WecSize(pBox->vLeafs) + 1 ); + + Acec_BoxInsOuts( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots ); + + pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); + pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); + + Acec_BoxPhases( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits ); + + return pBox; +} +void Acec_CreateBoxTest( Gia_Man_t * p ) +{ + extern void Acec_BoxFree( Acec_Box_t * pBox ); + Acec_Box_t * pBox; + Vec_Wec_t * vTrees; + + abctime clk = Abc_Clock(); + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); + int nFadds = Ree_ManCountFadds( vAdds ); + printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + clk = Abc_Clock(); + vTrees = Acec_TreeFindTrees( p, vAdds ); + printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Vec_WecPrint( vTrees, 0 ); + + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + Vec_WecPrint( pBox->vLeafs, 0 ); + Vec_WecPrint( pBox->vRoots, 0 ); + Acec_PrintRootLits( pBox->vRoots ); + Acec_BoxFree( pBox ); + + Vec_WecFree( vTrees ); + Vec_IntFree( vAdds ); +} + /**Function************************************************************* Synopsis [] -- cgit v1.2.3 From 89d08cfd06ecb1653ef0613049447c91bc114f46 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 13:36:54 +0700 Subject: Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 2 + src/proof/acec/acecInt.h | 2 + src/proof/acec/acecRe.c | 11 +- src/proof/acec/acecTree.c | 273 +++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 257 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index a8123a5e..444e0894 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -70,12 +70,14 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) ***********************************************************************/ void Acec_BoxFree( Acec_Box_t * pBox ) { + Vec_WecFreeP( &pBox->vAdds ); Vec_WecFreeP( &pBox->vLeafs ); Vec_WecFreeP( &pBox->vRoots ); Vec_WecFreeP( &pBox->vLeafLits ); Vec_WecFreeP( &pBox->vRootLits ); Vec_WecFreeP( &pBox->vUnique ); Vec_WecFreeP( &pBox->vShared ); + Vec_BitFreeP( &pBox->vInvHadds ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 08f163e0..3f10c6aa 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -41,12 +41,14 @@ typedef struct Acec_Box_t_ Acec_Box_t; struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager + Vec_Wec_t * vAdds; // adders by rank Vec_Wec_t * vLeafs; // leaf literals by rank Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves Vec_Wec_t * vUnique; // unique leaves + Vec_Bit_t * vInvHadds; // complemented half adders }; //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 60b894c8..161b6fbb 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -370,7 +370,7 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos Vec_IntForEachEntryDouble( vXorOne, iObj, Truth, j ) Vec_IntForEachEntryDouble( vMajOne, iObj2, Truth2, k ) { - int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0xEE, 0xDD, 0xBB, 0x77}; + int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0x77, 0xBB, 0xDD, 0xEE}; int SignMaj[8] = {0xE8, 0xD4, 0xB2, 0x71, 0x8E, 0x4D, 0x2B, 0x17}; int n, SignXor = (Truth == 0x99 || Truth == 0x69) << 3; for ( n = 0; n < 8; n++ ) @@ -390,6 +390,14 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos Vec_WecFree( vMajMap ); return vAdds; } +int Ree_ManCompare( int * pCut0, int * pCut1 ) +{ + if ( pCut0[3] < pCut1[3] ) return -1; + if ( pCut0[3] > pCut1[3] ) return 1; + if ( pCut0[4] < pCut1[4] ) return -1; + if ( pCut0[4] > pCut1[4] ) return 1; + return 0; +} Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ) { extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ); @@ -427,6 +435,7 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Vec_IntFree( vTemp ); Vec_IntFree( vCuts ); vAdds = Ree_ManDeriveAdds( pHash, vData, fVerbose ); + qsort( Vec_IntArray(vAdds), Vec_IntSize(vAdds)/6, 24, (int (*)(const void *, const void *))Ree_ManCompare ); if ( fVerbose ) printf( "Adders = %d. Total cuts = %d. Hashed cuts = %d. Hashed/Adders = %.2f.\n", Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 08122584..ba08deb5 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -169,23 +169,6 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Acec_PrintRootLits( Vec_Wec_t * vRoots ) -{ - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevel( vRoots, vLevel, i ) - { - printf( "Rank %d : ", i ); - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); - } - printf( "\n" ); - } -} int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) { int k, Box, Rank, MaxRank = 0; @@ -193,7 +176,7 @@ int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) MaxRank = Abc_MaxInt( MaxRank, Rank ); return MaxRank; } -void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) +void Acec_TreeInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vBoxes, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) { Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); @@ -211,6 +194,7 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W } Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { + Vec_WecPush( vBoxes, Rank, Box ); for ( k = 0; k < 3; k++ ) { if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) @@ -229,12 +213,91 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W Vec_BitFree( vIsLeaf ); Vec_BitFree( vIsRoot ); // sort each level + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( vLeaves, vLevel, i ) Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( vRoots, vLevel, i ) Vec_IntSort( vLevel, 0 ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + int Truth0, Truth1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return pObj->Value; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + assert( !Gia_ObjIsXor(pObj) ); + Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); + Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); + Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; + Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; + return (pObj->Value = Truth0 & Truth1); +} +void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bit_t * vPhase ) +{ + Gia_Obj_t * pObj; + unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; + int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; + + //if ( !fFadd ) + // return; + + Gia_ManIncrementTravId( p ); + for ( k = 0; k < 3; k++ ) + { + iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + pObj = Gia_ManObj( p, iObj ); + pObj->Value = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~Truths[k] : Truths[k]; + Gia_ObjSetTravIdCurrent( p, pObj ); + } + + iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); + TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthXor = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthXor : TruthXor; + + iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); + TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthMaj = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthMaj : TruthMaj; + + if ( fFadd ) // FADD + { + if ( TruthXor != 0x96 ) + printf( "Fadd %d sum is wrong.\n", iBox ); + if ( TruthMaj != 0xE8 ) + printf( "Fadd %d carry is wrong.\n", iBox ); + } + else + { + if ( TruthXor != 0x66 ) + printf( "Hadd %d sum is wrong.\n", iBox ); + if ( TruthMaj != 0x88 ) + printf( "Hadd %d carry is wrong.\n", iBox ); + } +} +void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) +{ + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Acec_TreeVerifyPhaseOne( p, vAdds, Box, vPhase ); +} + /**Function************************************************************* Synopsis [Creates polarity.] @@ -246,8 +309,96 @@ void Acec_BoxInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_W SeeAlso [] ***********************************************************************/ -void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); + return vMap; +} +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, + Vec_Bit_t * vPhase, Vec_Bit_t * vInvHadds, Vec_Bit_t * vVisit ) +{ + int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + assert( Node != 0 ); + if ( Vec_BitEntry(vVisit, Node) ) + { + assert( Vec_BitEntry(vPhase, Node) == fPhase ); + return; + } + Vec_BitWriteEntry( vVisit, Node, 1 ); + if ( fPhase ) + Vec_BitWriteEntry( vPhase, Node, fPhase ); + iBox = Vec_IntEntry( vMap, Node ); + if ( iBox == -1 ) + return; + assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); + Sign = Vec_IntEntry( vAdds, 6*iBox+5 ); + fXorPhase = ((Sign >> 3) & 1); + if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) + { + fPhase ^= ((Sign >> 2) & 1); + // remember complemented HADD + if ( fPhase ) + Vec_BitWriteEntry( vInvHadds, iBox, 1 ); + } + for ( k = 0; k < 3; k++ ) + { + int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fXorPhase ^= fPhaseThis; + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); + } + if ( Vec_BitEntry(vVisit, iXor) ) + assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + if ( fXorPhase ) + Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); +} +void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, + Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, + Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits, Vec_Bit_t * vInvHadds ) { + Vec_Int_t * vMap = Acec_TreeCarryMap( p, vAdds, vBoxes ); + Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vVisit = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevelReverse( vRoots, vLevel, i ) + { + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + if ( !fCout ) + continue; + Acec_TreePhases_rec( p, vAdds, vMap, Node, fFadd, vPhase, vInvHadds, vVisit ); + } + } + Vec_IntFree( vMap ); + Vec_BitFree( vVisit ); + Acec_TreeVerifyPhases( p, vAdds, vBoxes, vPhase ); + // create leaves + Vec_WecForEachLevel( vLeaves, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + Vec_WecPush( vLeafLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); + // add constants + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + if ( Vec_BitEntry(vInvHadds, iObj) ) + Vec_WecPush( vLeafLits, i, 1 ); + // create roots + Vec_WecForEachLevel( vRoots, vLevel, i ) + Vec_IntForEachEntry( vLevel, iObj, k ) + iObj >>= 2, Vec_WecPush( vRootLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); + // cleanup + Vec_BitFree( vPhase ); } /**Function************************************************************* @@ -261,20 +412,77 @@ void Acec_BoxPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_We SeeAlso [] ***********************************************************************/ +void Acec_PrintRootLits( Vec_Wec_t * vRoots ) +{ + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevel( vRoots, vLevel, i ) + { + printf( "Rank %d : ", i ); + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); + } + printf( "\n" ); + } +} +void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) +{ + Vec_Int_t * vLevel; + int i, k, iBox; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vLevel, iBox, k ) + printf( " (%d,%d)", Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); + printf( " }\n" ); + } +} +void Vec_WecPrintLits( Vec_Wec_t * p ) +{ + Vec_Int_t * vVec; + int i, k, Entry; + Vec_WecForEachLevel( p, vVec, i ) + { + printf( " %4d : {", i ); + Vec_IntForEachEntry( vVec, Entry, k ) + printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); + printf( " }\n" ); + } +} +void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) +{ + printf( "Adders:\n" ); + Acec_PrintAdders( pBox->vAdds, vAdds ); + printf( "Inputs:\n" ); + Vec_WecPrintLits( pBox->vLeafLits ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox->vRootLits ); + //printf( "Raw outputs:\n" ); + //Acec_PrintRootLits( pBox->vRoots ); +} + Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { + int MaxRank = Acec_CreateBoxMaxRank(vTree); + Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; - pBox->vLeafs = Vec_WecStart( Acec_CreateBoxMaxRank(vTree) + 1 ); - pBox->vRoots = Vec_WecStart( Vec_WecSize(pBox->vLeafs) + 1 ); + pBox->vAdds = Vec_WecStart( MaxRank + 1 ); + pBox->vLeafs = Vec_WecStart( MaxRank + 1 ); + pBox->vRoots = Vec_WecStart( MaxRank + 2 ); - Acec_BoxInsOuts( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots ); + Acec_TreeInsOuts( p, vAdds, vTree, pBox->vAdds, pBox->vLeafs, pBox->vRoots ); pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); + pBox->vInvHadds = Vec_BitStart( Vec_IntSize(vAdds)/6 ); - Acec_BoxPhases( p, vAdds, vTree, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits ); + Acec_TreePhases( p, vAdds, pBox->vAdds, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits, pBox->vInvHadds ); return pBox; } @@ -283,10 +491,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) extern void Acec_BoxFree( Acec_Box_t * pBox ); Acec_Box_t * pBox; Vec_Wec_t * vTrees; + Vec_Int_t * vTree; abctime clk = Abc_Clock(); Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 ); - int nFadds = Ree_ManCountFadds( vAdds ); + int i, nFadds = Ree_ManCountFadds( vAdds ); printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); @@ -294,13 +503,17 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) vTrees = Acec_TreeFindTrees( p, vAdds ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); - Vec_WecPrint( vTrees, 0 ); + //Vec_WecPrint( vTrees, 0 ); - pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); - Vec_WecPrint( pBox->vLeafs, 0 ); - Vec_WecPrint( pBox->vRoots, 0 ); - Acec_PrintRootLits( pBox->vRoots ); - Acec_BoxFree( pBox ); + Vec_WecForEachLevel( vTrees, vTree, i ) + { + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, i) ); + printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", + i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), + Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); + //Acec_PrintBox( pBox ); + Acec_BoxFree( pBox ); + } Vec_WecFree( vTrees ); Vec_IntFree( vAdds ); -- cgit v1.2.3 From 8b8b410af2d9cc75de758516f8c7dcf7a6098edc Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 13:44:27 +0700 Subject: Changing file naming in 'show' and '&show'. --- src/aig/aig/aigShow.c | 5 ++--- src/aig/gia/giaShow.c | 8 ++------ 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/aig/aig/aigShow.c b/src/aig/aig/aigShow.c index eac2a510..d983602a 100644 --- a/src/aig/aig/aigShow.c +++ b/src/aig/aig/aigShow.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "aig.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -340,12 +341,10 @@ void Aig_WriteDotAig( Aig_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold ) { extern void Abc_ShowFile( char * FileNameDot ); - static int Counter = 0; char FileNameDot[200]; FILE * pFile; // create the file name -// Aig_ShowGetFileName( pMan->pName, FileNameDot ); - sprintf( FileNameDot, "temp%02d.dot", Counter++ ); + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) { diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 986d5624..5589d384 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -21,6 +21,7 @@ #include "gia.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -815,15 +816,10 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) { extern void Abc_ShowFile( char * FileNameDot ); - static int Counter = 0; char FileNameDot[200]; FILE * pFile; - Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); - - // create the file name -// Gia_ShowGetFileName( pMan->pName, FileNameDot ); - sprintf( FileNameDot, "temp%02d.dot", Counter++ ); + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) { -- cgit v1.2.3 From 55b6b4bdab816b34bfa81a58eb4e9fefe0c1cba4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 16:08:23 +0700 Subject: Updates to arithmetic verification. --- src/base/abci/abc.c | 48 ++++++++++ src/base/wlc/wlcBlast.c | 2 +- src/proof/acec/acec.h | 2 + src/proof/acec/acecCore.c | 199 ++--------------------------------------- src/proof/acec/acecInt.h | 5 +- src/proof/acec/acecNorm.c | 215 +++++++++++++++++++++++++++++++++++++++++++++ src/proof/acec/acecTree.c | 89 ++++++++++++++----- src/proof/acec/module.make | 1 + 8 files changed, 346 insertions(+), 215 deletions(-) create mode 100644 src/proof/acec/acecNorm.c (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dd157afd..20d44227 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -481,6 +481,7 @@ static int Abc_CommandAbc9Fadds ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1124,6 +1125,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&atree", Abc_CommandAbc9ATree, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 ); @@ -40728,6 +40730,52 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" ); + return 0; + } + pTemp = Acec_Normalize( pAbc->pGia, fVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &anorm [-vh]\n" ); + Abc_Print( -2, "\t normalize adder trees in the current AIG\n" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index ec3b040d..5e6a1a47 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1509,7 +1509,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) ); } - pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName ); + //pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName ); // dump the miter parts if ( 0 ) { diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 918119f8..7ad5baf9 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -80,6 +80,8 @@ extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int f extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose ); extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); +/*=== acecTree.c ========================================================*/ +extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 444e0894..3e31fa36 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -57,98 +57,6 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) p->iOutFail = -1; // the number of failed output } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Acec_BoxFree( Acec_Box_t * pBox ) -{ - Vec_WecFreeP( &pBox->vAdds ); - Vec_WecFreeP( &pBox->vLeafs ); - Vec_WecFreeP( &pBox->vRoots ); - Vec_WecFreeP( &pBox->vLeafLits ); - Vec_WecFreeP( &pBox->vRootLits ); - Vec_WecFreeP( &pBox->vUnique ); - Vec_WecFreeP( &pBox->vShared ); - Vec_BitFreeP( &pBox->vInvHadds ); - ABC_FREE( pBox ); -} -void Acec_BoxFreeP( Acec_Box_t ** ppBox ) -{ - if ( *ppBox ) - Acec_BoxFree( *ppBox ); - *ppBox = NULL; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) -{ - int And, Or; - Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); - And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); - Or = Gia_ManAppendOr2( pNew, Out[1], And ); - Out[0] = Abc_LitNot( Or ); -} -void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) -{ - int In2[2], Out1[2], Out2[2]; - Acec_InsertHadd( pNew, In, Out1 ); - In2[0] = Out1[0]; - In2[1] = In[2]; - Acec_InsertHadd( pNew, In2, Out2 ); - Out[0] = Out2[0]; - Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); -} -Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) -{ - Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); - Vec_Int_t * vLevel; - int i, In[3], Out[2]; - Vec_WecForEachLevel( vLeafMap, vLevel, i ) - { - if ( Vec_IntSize(vLevel) == 0 ) - { - Vec_IntPush( vRootRanks, 0 ); - continue; - } - while ( Vec_IntSize(vLevel) > 1 ) - { - if ( Vec_IntSize(vLevel) == 2 ) - Vec_IntPush( vLevel, 0 ); - In[0] = Vec_IntPop( vLevel ); - In[1] = Vec_IntPop( vLevel ); - In[2] = Vec_IntPop( vLevel ); - Acec_InsertFadd( pNew, In, Out ); - Vec_IntPush( vLevel, Out[0] ); - if ( i-1 < Vec_WecSize(vLeafMap) ) - vLevel = Vec_WecEntry(vLeafMap, i+1); - else - vLevel = Vec_WecPushLevel(vLeafMap); - Vec_IntPush( vLevel, Out[1] ); - } - assert( Vec_IntSize(vLevel) == 1 ); - Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); - } - return vRootRanks; -} - /**Function************************************************************* Synopsis [] @@ -251,12 +159,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int * pEnd1 = Vec_IntLimit(vLevel1); while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) { - if ( *pBeg0 == *pBeg1 ) + int Entry0 = Abc_Lit2LitV( Vec_IntArray(vMap0), *pBeg0 ); + int Entry1 = Abc_Lit2LitV( Vec_IntArray(vMap1), *pBeg1 ); + if ( Entry0 == Entry1 ) { Vec_IntPush( vShared0, *pBeg0++ ); Vec_IntPush( vShared1, *pBeg1++ ); } - else if ( *pBeg0 > *pBeg1 ) + else if ( Entry0 > Entry1 ) Vec_IntPush( vUnique0, *pBeg0++ ); else Vec_IntPush( vUnique1, *pBeg1++ ); @@ -269,105 +179,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); } + Vec_IntFree( vMap0 ); + Vec_IntFree( vMap1 ); nTotal = Vec_WecSizeSize(pBox0->vShared); printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); return nTotal; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) -{ - if ( ~pObj->Value ) - return pObj->Value; - assert( Gia_ObjIsAnd(pObj) ); - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); - return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); -} -Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) -{ - Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); - Vec_Int_t * vLevel, * vRootRanks; - int i, k, iLit, iLitNew; - Vec_WecForEachLevel( vLeafLits, vLevel, i ) - Vec_IntForEachEntry( vLevel, iLit, k ) - { - Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); - iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); - iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); - Vec_WecPush( vLeafMap, i, iLitNew ); - } - // construct map of root literals - vRootRanks = Acec_InsertTree( pNew, vLeafMap ); - Vec_WecFree( vLeafMap ); - return vRootRanks; -} - -Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) -{ - Gia_Man_t * p = pBox->pGia; - Gia_Man_t * pNew; - Gia_Obj_t * pObj; - Vec_Int_t * vRootRanks, * vLevel; - int i, k, iLit, iLitNew; - pNew = Gia_ManStart( Gia_ManObjNum(p) ); - pNew->pName = Abc_UtilStrsav( p->pName ); - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Gia_ManConst0(p)->Value = 0; - Gia_ManForEachCi( p, pObj, i ) - pObj->Value = Gia_ManAppendCi( pNew ); - // implement tree - if ( fAll ) - vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); - else - { - Vec_Wec_t * vLeafLits; - assert( pBox->vShared != NULL ); - assert( pBox->vUnique != NULL ); - vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); - // add these roots to the unique ones - vLeafLits = Vec_WecDup( pBox->vUnique ); - Vec_IntForEachEntry( vRootRanks, iLit, i ) - { - if ( i < Vec_WecSize(vLeafLits) ) - vLevel = Vec_WecEntry(vLeafLits, i); - else - vLevel = Vec_WecPushLevel(vLeafLits); - Vec_IntPush( vLevel, iLit ); - } - Vec_IntFree( vRootRanks ); - vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); - Vec_WecFree( vLeafLits ); - } - // update polarity of literals - Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) - Vec_IntForEachEntry( vLevel, iLit, k ) - { - pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); - iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, k ); - pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); - } - Vec_IntFree( vRootRanks ); - // construct the outputs - Gia_ManForEachCo( p, pObj, i ) - Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); - Gia_ManForEachCo( p, pObj, i ) - pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); - Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); - return pNew; -} - /**Function************************************************************* Synopsis [] @@ -385,8 +204,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) Gia_Man_t * pMiter; Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0 ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1 ); + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, pPars->fVerbose ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching @@ -403,7 +222,7 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose ); if ( pMiter ) { - int fDumpMiter = 1; + int fDumpMiter = 0; if ( fDumpMiter ) { Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 3f10c6aa..c0d899e1 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -70,8 +70,11 @@ struct Acec_Box_t_ /*=== acecCo.c ========================================================*/ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecNorm.c ========================================================*/ +extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ); +extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c new file mode 100644 index 00000000..9faf7acf --- /dev/null +++ b/src/proof/acec/acecNorm.c @@ -0,0 +1,215 @@ +/**CFile**************************************************************** + + FileName [acecNorm.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Adder tree normalization.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecNorm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] ) +{ + int And, Or; + Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] ); + And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) ); + Or = Gia_ManAppendOr2( pNew, Out[1], And ); + Out[0] = Abc_LitNot( Or ); +} +void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ) +{ + int In2[2], Out1[2], Out2[2]; + Acec_InsertHadd( pNew, In, Out1 ); + In2[0] = Out1[0]; + In2[1] = In[2]; + Acec_InsertHadd( pNew, In2, Out2 ); + Out[0] = Out2[0]; + Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] ); +} +Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) +{ + Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 ); + Vec_Int_t * vLevel; + int i, In[3], Out[2]; + Vec_WecForEachLevel( vLeafMap, vLevel, i ) + { + if ( Vec_IntSize(vLevel) == 0 ) + { + Vec_IntPush( vRootRanks, 0 ); + continue; + } + while ( Vec_IntSize(vLevel) > 1 ) + { + if ( Vec_IntSize(vLevel) == 2 ) + Vec_IntPush( vLevel, 0 ); + In[2] = Vec_IntPop( vLevel ); + In[1] = Vec_IntPop( vLevel ); + In[0] = Vec_IntPop( vLevel ); + Acec_InsertFadd( pNew, In, Out ); + Vec_IntPush( vLevel, Out[0] ); + if ( i+1 < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i+1); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, Out[1] ); + vLevel = Vec_WecEntry(vLeafMap, i); + } + assert( Vec_IntSize(vLevel) == 1 ); + Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) ); + } + return vRootRanks; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( ~pObj->Value ) + return pObj->Value; + assert( Gia_ObjIsAnd(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); + return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); +} +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +{ + Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); + Vec_Int_t * vLevel, * vRootRanks; + int i, k, iLit, iLitNew; + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = Acec_InsertBox_rec( pNew, p, pObj ); + iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + Vec_WecPush( vLeafMap, i, iLitNew ); + } + // construct map of root literals + vRootRanks = Acec_InsertTree( pNew, vLeafMap ); + Vec_WecFree( vLeafMap ); + return vRootRanks; +} +Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) +{ + Gia_Man_t * p = pBox->pGia; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + Vec_Int_t * vRootRanks, * vLevel; + int i, k, iLit, iLitNew; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + // implement tree + if ( fAll ) + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + else + { + Vec_Wec_t * vLeafLits; + assert( pBox->vShared != NULL ); + assert( pBox->vUnique != NULL ); + vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); + // add these roots to the unique ones + vLeafLits = Vec_WecDup( pBox->vUnique ); + Vec_IntForEachEntry( vRootRanks, iLit, i ) + { + if ( i < Vec_WecSize(vLeafLits) ) + vLevel = Vec_WecEntry(vLeafLits, i); + else + vLevel = Vec_WecPushLevel(vLeafLits); + Vec_IntPush( vLevel, iLit ); + } + Vec_IntFree( vRootRanks ); + vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); + Vec_WecFree( vLeafLits ); + } + // update polarity of literals + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, i ); + pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) ); + } + Vec_IntFree( vRootRanks ); + // construct the outputs + Gia_ManForEachCo( p, pObj, i ) + Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ) +{ + Acec_Box_t * pBox = Acec_DeriveBox( pGia, fVerbose ); + Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); + Acec_BoxFreeP( &pBox ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index ba08deb5..1c0af00a 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -31,6 +31,36 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_BoxFree( Acec_Box_t * pBox ) +{ + Vec_WecFreeP( &pBox->vAdds ); + Vec_WecFreeP( &pBox->vLeafs ); + Vec_WecFreeP( &pBox->vRoots ); + Vec_WecFreeP( &pBox->vLeafLits ); + Vec_WecFreeP( &pBox->vRootLits ); + Vec_WecFreeP( &pBox->vUnique ); + Vec_WecFreeP( &pBox->vShared ); + Vec_BitFreeP( &pBox->vInvHadds ); + ABC_FREE( pBox ); +} +void Acec_BoxFreeP( Acec_Box_t ** ppBox ) +{ + if ( *ppBox ) + Acec_BoxFree( *ppBox ); + *ppBox = NULL; +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -412,23 +442,6 @@ void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, SeeAlso [] ***********************************************************************/ -void Acec_PrintRootLits( Vec_Wec_t * vRoots ) -{ - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevel( vRoots, vLevel, i ) - { - printf( "Rank %d : ", i ); - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); - } - printf( "\n" ); - } -} void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) { Vec_Int_t * vLevel; @@ -437,7 +450,8 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) { printf( " %4d : {", i ); Vec_IntForEachEntry( vLevel, iBox, k ) - printf( " (%d,%d)", Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); + printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, + Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); printf( " }\n" ); } } @@ -453,6 +467,23 @@ void Vec_WecPrintLits( Vec_Wec_t * p ) printf( " }\n" ); } } +void Acec_PrintRootLits( Vec_Wec_t * vRoots ) +{ + Vec_Int_t * vLevel; + int i, k, iObj; + Vec_WecForEachLevel( vRoots, vLevel, i ) + { + printf( "Rank %d : ", i ); + Vec_IntForEachEntry( vLevel, iObj, k ) + { + int fFadd = Abc_LitIsCompl(iObj); + int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); + int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); + printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); + } + printf( "\n" ); + } +} void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) { printf( "Adders:\n" ); @@ -488,7 +519,6 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree } void Acec_CreateBoxTest( Gia_Man_t * p ) { - extern void Acec_BoxFree( Acec_Box_t * pBox ); Acec_Box_t * pBox; Vec_Wec_t * vTrees; Vec_Int_t * vTree; @@ -511,8 +541,8 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); - //Acec_PrintBox( pBox ); - Acec_BoxFree( pBox ); + Acec_PrintBox( pBox, vAdds ); + Acec_BoxFreeP( &pBox ); } Vec_WecFree( vTrees ); @@ -530,9 +560,22 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) { - return NULL; + Acec_Box_t * pBox = NULL; + Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds ); + if ( vTrees && Vec_WecSize(vTrees) > 0 ) + pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + if ( pBox )//&& fVerbose ) + printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", + 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), + Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); + if ( pBox && fVerbose ) + Acec_PrintBox( pBox, vAdds ); + Vec_WecFreeP( &vTrees ); + Vec_IntFree( vAdds ); + return pBox; } //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 4db695c5..25fa2548 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -8,6 +8,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecPool.c \ src/proof/acec/acecCover.c \ src/proof/acec/acecFadds.c \ + src/proof/acec/acecNorm.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ src/proof/acec/acecSt.c \ -- cgit v1.2.3 From d52dafa6c2365837543f15be7abd274f8654ba14 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 12 Jan 2017 16:12:48 +0700 Subject: Updates to arithmetic verification. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaTruth.c | 51 ++++++ src/base/wlc/wlcBlast.c | 26 +++ src/proof/acec/acecInt.h | 2 + src/proof/acec/acecMult.c | 432 +++++++++++++++++++++++++++++++++++++++++++++ src/proof/acec/acecTree.c | 26 ++- src/proof/acec/module.make | 1 + 7 files changed, 530 insertions(+), 9 deletions(-) create mode 100644 src/proof/acec/acecMult.c (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index d9b1716a..7cf1feff 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1514,6 +1514,7 @@ extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimi extern word Gia_LutComputeTruth6( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTruths ); extern word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp ); extern word Gia_ObjComputeTruthTable6( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTruths ); +extern word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ); extern void Gia_ObjCollectInternal( Gia_Man_t * p, Gia_Obj_t * pObj ); extern word * Gia_ObjComputeTruthTable( Gia_Man_t * p, Gia_Obj_t * pObj ); extern void Gia_ObjComputeTruthTableStart( Gia_Man_t * p, int nVarsMax ); diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c index ce06fa0b..f636a573 100644 --- a/src/aig/gia/giaTruth.c +++ b/src/aig/gia/giaTruth.c @@ -137,6 +137,57 @@ word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp ) return Vec_WrdEntry( vTemp, iObj ); } +/**Function************************************************************* + + Synopsis [Computes truth table up to 6 inputs in terms of CIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Gia_ObjComputeTruth6( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ) +{ + int i, Fanin; + assert( Vec_WrdSize(vTemp) == Gia_ManObjNum(p) ); + assert( Vec_IntSize(vSupp) <= 6 ); + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vSupp, Fanin, i ) + { + Gia_ObjSetTravIdCurrentId( p, Fanin ); + Vec_WrdWriteEntry( vTemp, Fanin, s_Truth6[i] ); + } + Gia_ObjComputeTruthTable6Lut_rec( p, iObj, vTemp ); + return Vec_WrdEntry( vTemp, iObj ); +} +void Gia_ObjComputeTruth6CisSupport_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp ) +{ + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPushOrder( vSupp, iObj ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId0p(p, pObj), vSupp ); + Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId1p(p, pObj), vSupp ); +} +word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp ) +{ + int iObj = Abc_Lit2Var(iLit); + Vec_IntClear( vSupp ); + if ( !iObj ) return Abc_LitIsCompl(iLit) ? ~(word)0 : (word)0; + Gia_ManIncrementTravId( p ); + Gia_ObjComputeTruth6CisSupport_rec( p, iObj, vSupp ); + Gia_ObjComputeTruth6( p, iObj, vSupp, vTemp ); + return Abc_LitIsCompl(iLit) ? ~Vec_WrdEntry(vTemp, iObj) : Vec_WrdEntry(vTemp, iObj); +} + /**Function************************************************************* Synopsis [Computes truth table up to 6 inputs.] diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 5e6a1a47..b22ac6cd 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -643,6 +643,31 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) Vec_IntInsert( vProd, i + 1, Node ); Vec_IntInsert( vLevel, i + 1, Level ); } +void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) +{ + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; word Truth; + int i, k, iLit; + Vec_WecForEachLevel( vProds, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + printf( "Obj = %4d : ", Abc_Lit2Var(iLit) ); + printf( "Compl = %d ", Abc_LitIsCompl(iLit) ); + printf( "Rank = %2d ", i ); + Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + if ( k == Vec_IntSize(vLevel)-1 ) + printf( "\n" ); + } + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); +} void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes ) { Vec_Int_t * vLevel, * vProd; @@ -812,6 +837,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int Vec_WecPush( vLevels, k, 0 ); } //Vec_WecPrint( vProds, 0 ); + //Wlc_BlastPrintMatrix( pNew, vProds ); //printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) ); Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index c0d899e1..0dc3f706 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -70,6 +70,8 @@ struct Acec_Box_t_ /*=== acecCo.c ========================================================*/ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts ); extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); +/*=== acecMult.c ========================================================*/ +extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); /*=== acecNorm.c ========================================================*/ extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c new file mode 100644 index 00000000..397f6d57 --- /dev/null +++ b/src/proof/acec/acecMult.c @@ -0,0 +1,432 @@ +/**CFile**************************************************************** + + FileName [acecMult.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Multiplier.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecMult.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +unsigned s_Classes4a[96] = { + 0xD728, 0xB748, 0x9F60, 0xD278, 0xB478, 0x96F0, 0xC66C, 0x96CC, 0x9C6C, 0x96AA, 0xA66A, 0x9A6A, + 0x28D7, 0x48B7, 0x609F, 0x2D87, 0x4B87, 0x690F, 0x3993, 0x6933, 0x6393, 0x6955, 0x5995, 0x6595, + 0xEB14, 0xED12, 0xF906, 0xE1B4, 0xE1D2, 0xF096, 0xC99C, 0xCC96, 0xC9C6, 0xAA96, 0xA99A, 0xA9A6, + 0x14EB, 0x12ED, 0x06F9, 0x1E4B, 0x1E2D, 0x0F69, 0x3663, 0x3369, 0x3639, 0x5569, 0x5665, 0x5659, + 0x7D82, 0x7B84, 0x6F90, 0x78D2, 0x78B4, 0x69F0, 0x6CC6, 0x69CC, 0x6C9C, 0x69AA, 0x6AA6, 0x6A9A, + 0x827D, 0x847B, 0x906F, 0x872D, 0x874B, 0x960F, 0x9339, 0x9633, 0x9363, 0x9655, 0x9559, 0x9565, + 0xBE41, 0xDE21, 0xF609, 0xB4E1, 0xD2E1, 0xF069, 0x9CC9, 0xCC69, 0xC6C9, 0xAA69, 0x9AA9, 0xA6A9, + 0x41BE, 0x21DE, 0x09F6, 0x4B1E, 0x2D1E, 0x0F96, 0x6336, 0x3396, 0x3936, 0x5596, 0x6556, 0x5956 +}; + +unsigned s_Classes4b[384] = { + 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0, + 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22, + 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0, + 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88, + 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A, + 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522, + 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A, + 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588, + 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570, + 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A, + 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0, + 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A, + 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025, + 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5, + 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085, + 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5, + 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B, + 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511, + 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E, + 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544, + 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1, + 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11, + 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4, + 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44, + 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207, + 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5, + 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D, + 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5, + 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752, + 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A, + 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58, + 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A +}; + +unsigned s_Classes4c[768] = { + 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0, + 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22, + 0xCA3F, 0xAC5F, 0xE23F, 0xB877, 0xD877, 0xE45F, 0xC3AF, 0xA5CF, 0xE32F, 0xB787, 0xD787, 0xE54F, + 0xCB3B, 0x9F93, 0xC3BB, 0x99F3, 0xD973, 0xD793, 0x9F95, 0xAD5D, 0xB795, 0xB975, 0x99F5, 0xA5DD, + 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0, + 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88, + 0xC53F, 0xA35F, 0xD13F, 0x8B77, 0x8D77, 0xB15F, 0xC35F, 0xA53F, 0xD31F, 0x87B7, 0x87D7, 0xB51F, + 0xC737, 0x939F, 0xC377, 0x993F, 0x9D37, 0x93D7, 0x959F, 0xA757, 0x95B7, 0x9B57, 0x995F, 0xA577, + 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A, + 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522, + 0x3ACF, 0x5CAF, 0x2EF3, 0x74BB, 0x72DD, 0x4EF5, 0x3CAF, 0x5ACF, 0x2FE3, 0x7B4B, 0x7D2D, 0x4FE5, + 0x3BCB, 0x6F63, 0x3CBB, 0x66F3, 0x73D9, 0x7D39, 0x6F65, 0x5DAD, 0x7B59, 0x75B9, 0x66F5, 0x5ADD, + 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A, + 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588, + 0x35CF, 0x53AF, 0x1DF3, 0x47BB, 0x27DD, 0x1BF5, 0x3C5F, 0x5A3F, 0x1FD3, 0x4B7B, 0x2D7D, 0x1FB5, + 0x37C7, 0x636F, 0x3C77, 0x663F, 0x379D, 0x397D, 0x656F, 0x57A7, 0x597B, 0x579B, 0x665F, 0x5A77, + 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570, + 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A, + 0xACF3, 0xCAF5, 0xB8CF, 0xE2DD, 0xE4BB, 0xD8AF, 0xAFC3, 0xCFA5, 0xBC8F, 0xED2D, 0xEB4B, 0xDA8F, + 0xBCB3, 0xF939, 0xBBC3, 0xF399, 0xE6B3, 0xEB63, 0xF959, 0xDAD5, 0xED65, 0xE6D5, 0xF599, 0xDDA5, + 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0, + 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A, + 0x5CF3, 0x3AF5, 0x74CF, 0x2EDD, 0x4EBB, 0x72AF, 0x5FC3, 0x3FA5, 0x7C4F, 0x2DED, 0x4BEB, 0x7A2F, + 0x7C73, 0x39F9, 0x77C3, 0x3F99, 0x6E3B, 0x63EB, 0x59F9, 0x7A75, 0x65ED, 0x6E5D, 0x5F99, 0x77A5, + 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025, + 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5, + 0xA3FC, 0xC5FA, 0x8BFC, 0xD1EE, 0xB1EE, 0x8DFA, 0xAF3C, 0xCF5A, 0x8FBC, 0xDE1E, 0xBE1E, 0x8FDA, + 0xB3BC, 0xF636, 0xBB3C, 0xF366, 0xB3E6, 0xBE36, 0xF656, 0xD5DA, 0xDE56, 0xD5E6, 0xF566, 0xDD5A, + 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085, + 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5, + 0x53FC, 0x35FA, 0x47FC, 0x1DEE, 0x1BEE, 0x27FA, 0x5F3C, 0x3F5A, 0x4F7C, 0x1EDE, 0x1EBE, 0x2F7A, + 0x737C, 0x36F6, 0x773C, 0x3F66, 0x3B6E, 0x36BE, 0x56F6, 0x757A, 0x56DE, 0x5D6E, 0x5F66, 0x775A, + 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B, + 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511, + 0x3FCA, 0x5FAC, 0x3FE2, 0x77B8, 0x77D8, 0x5FE4, 0x3CFA, 0x5AFC, 0x3EF2, 0x7B78, 0x7D78, 0x5EF4, + 0x3ECE, 0x6F6C, 0x3CEE, 0x66FC, 0x76DC, 0x7D6C, 0x6F6A, 0x5EAE, 0x7B6A, 0x76BA, 0x66FA, 0x5AEE, + 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E, + 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544, + 0x3FC5, 0x5FA3, 0x3FD1, 0x778B, 0x778D, 0x5FB1, 0x3CF5, 0x5AF3, 0x3DF1, 0x787B, 0x787D, 0x5BF1, + 0x3DCD, 0x6C6F, 0x3CDD, 0x66CF, 0x67CD, 0x6C7D, 0x6A6F, 0x5BAB, 0x6A7B, 0x67AB, 0x66AF, 0x5ABB, + 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1, + 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11, + 0xCF3A, 0xAF5C, 0xF32E, 0xBB74, 0xDD72, 0xF54E, 0xC3FA, 0xA5FC, 0xF23E, 0xB7B4, 0xD7D2, 0xF45E, + 0xCE3E, 0x9F9C, 0xC3EE, 0x99FC, 0xDC76, 0xD7C6, 0x9F9A, 0xAE5E, 0xB7A6, 0xBA76, 0x99FA, 0xA5EE, + 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4, + 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44, + 0xCF35, 0xAF53, 0xF31D, 0xBB47, 0xDD27, 0xF51B, 0xC3F5, 0xA5F3, 0xF13D, 0xB4B7, 0xD2D7, 0xF15B, + 0xCD3D, 0x9C9F, 0xC3DD, 0x99CF, 0xCD67, 0xC6D7, 0x9A9F, 0xAB5B, 0xA6B7, 0xAB67, 0x99AF, 0xA5BB, + 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207, + 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5, + 0xF3AC, 0xF5CA, 0xCFB8, 0xDDE2, 0xBBE4, 0xAFD8, 0xFA3C, 0xFC5A, 0xCBF8, 0xDED2, 0xBEB4, 0xADF8, + 0xE3EC, 0xF6C6, 0xEE3C, 0xFC66, 0xB9EC, 0xBE9C, 0xF6A6, 0xE5EA, 0xDE9A, 0xD9EA, 0xFA66, 0xEE5A, + 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D, + 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5, + 0xF35C, 0xF53A, 0xCF74, 0xDD2E, 0xBB4E, 0xAF72, 0xF53C, 0xF35A, 0xC7F4, 0xD2DE, 0xB4BE, 0xA7F2, + 0xD3DC, 0xC6F6, 0xDD3C, 0xCF66, 0x9BCE, 0x9CBE, 0xA6F6, 0xB5BA, 0x9ADE, 0x9DAE, 0xAF66, 0xBB5A, + 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752, + 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A, + 0xFCA3, 0xFAC5, 0xFC8B, 0xEED1, 0xEEB1, 0xFA8D, 0xFAC3, 0xFCA5, 0xF8CB, 0xEDE1, 0xEBE1, 0xF8AD, + 0xECE3, 0xF9C9, 0xEEC3, 0xFC99, 0xECB9, 0xEBC9, 0xF9A9, 0xEAE5, 0xEDA9, 0xEAD9, 0xFA99, 0xEEA5, + 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58, + 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A, + 0xFC53, 0xFA35, 0xFC47, 0xEE1D, 0xEE1B, 0xFA27, 0xF5C3, 0xF3A5, 0xF4C7, 0xE1ED, 0xE1EB, 0xF2A7, + 0xDCD3, 0xC9F9, 0xDDC3, 0xCF99, 0xCE9B, 0xC9EB, 0xA9F9, 0xBAB5, 0xA9ED, 0xAE9D, 0xAF99, 0xBBA5 +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Computes NPN-canonical form using brute-force methods.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Extra_TruthCanonNPN2( unsigned uTruth, int nVars, Vec_Int_t * vRes ) +{ + static int nVarsOld, nPerms; + static char ** pPerms = NULL; + + unsigned uTruthMin, uTruthC, uPhase, uPerm; + int nMints, k, i; + + if ( pPerms == NULL ) + { + nPerms = Extra_Factorial( nVars ); + pPerms = Extra_Permutations( nVars ); + nVarsOld = nVars; + } + else if ( nVarsOld != nVars ) + { + ABC_FREE( pPerms ); + nPerms = Extra_Factorial( nVars ); + pPerms = Extra_Permutations( nVars ); + nVarsOld = nVars; + } + + nMints = (1 << nVars); + uTruthC = (unsigned)( (~uTruth) & ((~((unsigned)0)) >> (32-nMints)) ); + uTruthMin = 0xFFFFFFFF; + for ( i = 0; i < nMints; i++ ) + { + uPhase = Extra_TruthPolarize( uTruth, i, nVars ); + for ( k = 0; k < nPerms; k++ ) + { + uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 ); + Vec_IntPushUnique( vRes, uPerm ); + if ( uTruthMin > uPerm ) + uTruthMin = uPerm; + } + uPhase = Extra_TruthPolarize( uTruthC, i, nVars ); + for ( k = 0; k < nPerms; k++ ) + { + uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 ); + Vec_IntPushUnique( vRes, uPerm ); + if ( uTruthMin > uPerm ) + uTruthMin = uPerm; + } + } + return uTruthMin; +} + +void Acec_MultFuncTest5() +{ + Vec_Int_t * vRes = Vec_IntAlloc( 1000 ); + int i, Entry; + + unsigned Truth = 0xF335ACC0; + unsigned Canon = Extra_TruthCanonNPN2( Truth, 5, vRes ); + + Extra_PrintHex( stdout, (unsigned*)&Truth, 5 ); printf( "\n" ); + Extra_PrintHex( stdout, (unsigned*)&Canon, 5 ); printf( "\n" ); + + printf( "Members = %d.\n", Vec_IntSize(vRes) ); + Vec_IntForEachEntry( vRes, Entry, i ) + { + Extra_PrintHex( stdout, (unsigned*)&Entry, 5 ); + printf( ", " ); + if ( i % 8 == 7 ) + printf( "\n" ); + } + + Vec_IntFree( vRes ); +} + +void Acec_MultFuncTest4() +{ + Vec_Int_t * vRes = Vec_IntAlloc( 1000 ); + int i, Entry; + + unsigned Truth = 0x35C0; + //unsigned Truth = 0xD728; + unsigned Canon = Extra_TruthCanonNPN2( Truth, 4, vRes ); + + Extra_PrintHex( stdout, (unsigned*)&Truth, 4 ); printf( "\n" ); + Extra_PrintHex( stdout, (unsigned*)&Canon, 4 ); printf( "\n" ); + + printf( "Members = %d.\n", Vec_IntSize(vRes) ); + Vec_IntForEachEntry( vRes, Entry, i ) + { + Extra_PrintHex( stdout, (unsigned*)&Entry, 4 ); + printf( ", " ); + if ( i % 12 == 11 ) + printf( "\n" ); + } + + Vec_IntFree( vRes ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_MultCollectInputs( Vec_Int_t * vPairs, Vec_Int_t * vRanks, int iObj ) +{ + Vec_Int_t * vItems = Vec_IntAlloc( 100 ); + int k, iObj1, iObj2; + // collect all those appearing with this one + Vec_IntForEachEntryDouble( vPairs, iObj1, iObj2, k ) + if ( iObj == iObj1 ) + Vec_IntPushUnique( vItems, iObj2 ); + else if ( iObj == iObj2 ) + Vec_IntPushUnique( vItems, iObj1 ); + // sort items by rank cost + Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks ); + return vItems; +} +Vec_Int_t * Acec_MultDetectInputs1( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ + Vec_Int_t * vInputs = Vec_IntAlloc( 100 ); + Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vPairs = Vec_IntAlloc( 100 ); + Vec_Int_t * vItems = Vec_IntAlloc( 100 ); + Vec_Int_t * vItems0; + Vec_Int_t * vItems1; + Vec_Int_t * vLevel; + int i, k, iLit, iObj, Count; + // count how many times each input appears + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + iObj = Abc_Lit2Var(iLit); + Vec_IntAddToEntry( vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), 1 ); + Vec_IntAddToEntry( vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), 1 ); +/* + printf( "Rank %2d : Leaf = %4d : (%2d, %2d)\n", i, iObj, + Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) ); + if ( k == Vec_IntSize(vLevel) - 1 ) + printf( "\n" ); +*/ + } + // count ranks for each one + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + iObj = Abc_Lit2Var(iLit); + if ( Vec_IntEntry(vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj)) < 2 ) + { + printf( "Skipping %d.\n", iObj ); + continue; + } + if ( Vec_IntEntry(vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj)) < 2 ) + { + printf( "Skipping %d.\n", iObj ); + continue; + } + Vec_IntAddToEntry( vRanks, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), i ); + Vec_IntAddToEntry( vRanks, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), i ); + + Vec_IntPushTwo( vPairs, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) ); + } + + // print statistics + Vec_IntForEachEntry( vCounts, Count, i ) + { + if ( !Count ) + continue; + if ( !Vec_IntEntry(vRanks, i) ) + continue; + Vec_IntPush( vItems, i ); + printf( "Obj = %3d Occurs = %3d Ranks = %3d\n", i, Count, Vec_IntEntry(vRanks, i) ); + } + // sort items by rank cost + Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks ); + // collect all those appearing with the last one + vItems0 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems) ); + Vec_IntAppend( vInputs, vItems0 ); + // collect all those appearing with the last one + vItems1 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems0) ); + Vec_IntAppend( vInputs, vItems1 ); + + Vec_IntPrint( vItems0 ); + Vec_IntPrint( vItems1 ); + + Vec_IntFree( vCounts ); + Vec_IntFree( vRanks ); + Vec_IntFree( vPairs ); + Vec_IntFree( vItems ); + Vec_IntFree( vItems0 ); + Vec_IntFree( vItems1 ); + return vInputs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ) +{ + Vec_Int_t * vInputs = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, iLit, iObj, j, Entry; + + ABC_FREE( p->pRefs ); + Gia_ManCreateRefs( p ); + Gia_ManForEachCiId( p, iObj, i ) + printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) ); + printf( "\n" ); + Gia_ManForEachAndId( p, iObj ) + if ( Gia_ObjRefNumId(p, iObj) >= 4 ) + printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) ); + printf( "\n" ); + + Vec_WecForEachLevel( vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); + if ( Vec_IntSize(vSupp) >= 4 ) + { + printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) ); + printf( "Rank = %2d ", i ); + printf( "Supp = %2d ", Vec_IntSize(vSupp) ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + // support rank counts + Vec_IntForEachEntry( vSupp, Entry, j ) + { + Vec_IntAddToEntry( vRanks, Entry, i ); + Vec_IntAddToEntry( vCounts, Entry, 1 ); + } + if ( k == Vec_IntSize(vLevel)-1 ) + printf( "\n" ); + } + + Vec_IntForEachEntry( vCounts, Entry, j ) + if ( Entry ) + printf( "%d=%d(%.2f) ", j, Entry, 1.0*Vec_IntEntry(vRanks, j)/Entry ); + printf( "\n" ); + + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + Vec_IntFree( vRanks ); + Vec_IntFree( vCounts ); + return vInputs; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 1c0af00a..53e1cb60 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -307,16 +307,16 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bi if ( fFadd ) // FADD { if ( TruthXor != 0x96 ) - printf( "Fadd %d sum is wrong.\n", iBox ); + printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0xE8 ) - printf( "Fadd %d carry is wrong.\n", iBox ); + printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); } else { if ( TruthXor != 0x66 ) - printf( "Hadd %d sum is wrong.\n", iBox ); + printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0x88 ) - printf( "Hadd %d carry is wrong.\n", iBox ); + printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); } } void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) @@ -356,7 +356,9 @@ void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, in assert( Node != 0 ); if ( Vec_BitEntry(vVisit, Node) ) { - assert( Vec_BitEntry(vPhase, Node) == fPhase ); + //assert( Vec_BitEntry(vPhase, Node) == fPhase ); + if ( Vec_BitEntry(vPhase, Node) != fPhase ) + printf( "Phase check failed for node %d.\n", Node ); return; } Vec_BitWriteEntry( vVisit, Node, 1 ); @@ -386,7 +388,12 @@ void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, in Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); } if ( Vec_BitEntry(vVisit, iXor) ) - assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + { + //assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); + if ( Vec_BitEntry(vPhase, iXor) != fXorPhase ) + printf( "Phase check failed for XOR %d.\n", iXor ); + return; + } if ( fXorPhase ) Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); } @@ -448,7 +455,7 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) int i, k, iBox; Vec_WecForEachLevel( vBoxes, vLevel, i ) { - printf( " %4d : {", i ); + printf( " %4d : %2d {", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iBox, k ) printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); @@ -461,7 +468,7 @@ void Vec_WecPrintLits( Vec_Wec_t * p ) int i, k, Entry; Vec_WecForEachLevel( p, vVec, i ) { - printf( " %4d : {", i ); + printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); Vec_IntForEachEntry( vVec, Entry, k ) printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); printf( " }\n" ); @@ -473,7 +480,7 @@ void Acec_PrintRootLits( Vec_Wec_t * vRoots ) int i, k, iObj; Vec_WecForEachLevel( vRoots, vLevel, i ) { - printf( "Rank %d : ", i ); + printf( "Rank %d : %2d ", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iObj, k ) { int fFadd = Abc_LitIsCompl(iObj); @@ -573,6 +580,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); +// Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index 25fa2548..dbf86ac2 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -8,6 +8,7 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecPool.c \ src/proof/acec/acecCover.c \ src/proof/acec/acecFadds.c \ + src/proof/acec/acecMult.c \ src/proof/acec/acecNorm.c \ src/proof/acec/acecOrder.c \ src/proof/acec/acecPolyn.c \ -- cgit v1.2.3 From f5240276cb29e730be44b96da9013db046683a5f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 15:25:35 +0700 Subject: Updates to arithmetic verification. --- src/aig/gia/giaTruth.c | 2 ++ src/proof/acec/acecMult.c | 2 +- src/proof/acec/acecTree.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c index f636a573..ab5f569e 100644 --- a/src/aig/gia/giaTruth.c +++ b/src/aig/gia/giaTruth.c @@ -184,6 +184,8 @@ word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wr if ( !iObj ) return Abc_LitIsCompl(iLit) ? ~(word)0 : (word)0; Gia_ManIncrementTravId( p ); Gia_ObjComputeTruth6CisSupport_rec( p, iObj, vSupp ); + if ( Vec_IntSize(vSupp) > 6 ) + return 0; Gia_ObjComputeTruth6( p, iObj, vSupp, vTemp ); return Abc_LitIsCompl(iLit) ? ~Vec_WrdEntry(vTemp, iObj) : Vec_WrdEntry(vTemp, iObj); } diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 397f6d57..33c32144 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -389,7 +389,7 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec Vec_IntForEachEntry( vLevel, iLit, k ) { word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); - if ( Vec_IntSize(vSupp) >= 4 ) + if ( Vec_IntSize(vSupp) >= 0 ) { printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) ); printf( "Rank = %2d ", i ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 53e1cb60..8be8a340 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -61,6 +61,65 @@ void Acec_BoxFreeP( Acec_Box_t ** ppBox ) *ppBox = NULL; } +/**Function************************************************************* + + Synopsis [Filters trees by removing TFO of roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ; + Gia_Obj_t * pObj; + int i, k = 0, Box, Rank; + // mark roots + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+0), 0 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+1), 0 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+2), 0 ); + } + // iterate through nodes to detect TFO of roots + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Vec_BitEntry(vIsRoot, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vIsRoot, Gia_ObjFaninId1(pObj,i)) || + Vec_BitEntry(vMarked, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vMarked, Gia_ObjFaninId1(pObj,i)) ) + Vec_BitWriteEntry( vMarked, i, 1 ); + } + // remove those that overlap with roots + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) + { + printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); + continue; + } + Vec_IntWriteEntry( vTree, k++, Box ); + Vec_IntWriteEntry( vTree, k++, Rank ); + } + Vec_IntShrink( vTree, k ); + Vec_BitFree( vIsRoot ); + Vec_BitFree( vMarked ); +} +void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees ) +{ + Vec_Int_t * vLevel; + int i; + Vec_WecForEachLevel( vTrees, vLevel, i ) + Acec_TreeFilterOne( p, vAdds, vLevel ); +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -163,6 +222,8 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) } Vec_BitFree( vFound ); Vec_IntFree( vMap ); + // filter trees + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -580,7 +641,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); -// Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; -- cgit v1.2.3 From 1a39fb39462d34e40e4ed9da4615d18a463471e0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 17:32:58 +0700 Subject: Adding print-out of critical path for mapped AIGs to &show. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaShow.c | 310 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/base/abci/abc.c | 15 ++- src/opt/sbd/sbdPath.c | 54 +++++++++ 4 files changed, 365 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 7cf1feff..68060119 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1426,7 +1426,7 @@ extern Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs ); extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ); /*=== giaShow.c ===========================================================*/ -extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ); +extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath ); /*=== giaShrink.c ===========================================================*/ extern Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose ); extern Gia_Man_t * Gia_ManMapShrink6( Gia_Man_t * p, int nFanoutMax, int fKeepLevel, int fVerbose ); diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 5589d384..28e874bf 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -34,6 +34,294 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Writes the graph structure of AIG for DOT.] + + Description [Useful for graph visualization using tools such as GraphViz: + http://www.graphviz.org/] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) +{ + FILE * pFile; + Gia_Obj_t * pNode; + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + int i, k, iFan, LevelMax, nLevels, * pLevels, Level, Prev; + int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + assert( Gia_ManHasMapping(p) ); + + // set critical CO drivers + nLevels = Gia_ManLutLevel( p, &pLevels ); + Gia_ManForEachCoDriverId( p, iFan, i ) + if ( pLevels[iFan] == nLevels ) + Vec_BitWriteEntry( vPath, iFan, 1 ); + + // set critical internal nodes + Gia_ManForEachLutReverse( p, i ) + { + nLuts++; + if ( !Vec_BitEntry(vPath, i) ) + continue; + nNodes++; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] +1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + Vec_BitWriteEntry( vPath, iFan, 1 ); + nEdges++; + //printf( "%d -> %d\n", i, iFan ); + } + } + + if ( nNodes > 500 ) + { + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); + fprintf( stdout, "Cannot visualize AIG with more than 500 critical nodes.\n" ); + return; + } + if ( (pFile = fopen( pFileName, "w" )) == NULL ) + { + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); + return; + } + + Vec_IntFreeP( &p->vLevels ); + p->vLevels = Vec_IntAllocArray( pLevels, Gia_ManObjNum(p) ); + + // compute CO levels + LevelMax = 1 + nLevels; + Gia_ManForEachCo( p, pNode, i ) + Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); + + // write the DOT header + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "digraph AIG {\n" ); + fprintf( pFile, "size = \"7.5,10\";\n" ); +// fprintf( pFile, "ranksep = 0.5;\n" ); +// fprintf( pFile, "nodesep = 0.5;\n" ); + fprintf( pFile, "center = true;\n" ); +// fprintf( pFile, "orientation = landscape;\n" ); +// fprintf( pFile, "edge [fontsize = 10];\n" ); +// fprintf( pFile, "edge [dir = none];\n" ); + fprintf( pFile, "edge [dir = back];\n" ); + fprintf( pFile, "\n" ); + + // labels on the left of the picture + fprintf( pFile, "{\n" ); + fprintf( pFile, " node [shape = plaintext];\n" ); + fprintf( pFile, " edge [style = invis];\n" ); + fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); + fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); + // generate node names with labels + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + fprintf( pFile, " [label = " ); + // label name + fprintf( pFile, "\"" ); + fprintf( pFile, "\"" ); + fprintf( pFile, "];\n" ); + } + + // genetate the sequence of visible/invisible nodes to mark levels + fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + // the connector + if ( Level != 0 ) + fprintf( pFile, " ->" ); + else + fprintf( pFile, ";" ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate title box on top + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle1;\n" ); + fprintf( pFile, " title1 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=20,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "%s", "AIG structure visualized by ABC" ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" ); +// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate statistics box + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle2;\n" ); + fprintf( pFile, " title2 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=18,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "The critical path contains %d LUTs with %d critical edges and spans %d levels.", nNodes, nEdges, nLevels ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate the COs + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", LevelMax ); + // generate the CO nodes + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ); + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + fprintf( pFile, ", shape = %s", "invtriangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate nodes of each rank + for ( Level = LevelMax - 1; Level > 0; Level-- ) + { + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", Level ); + Gia_ManForEachObj( p, pNode, i ) + { + if ( (int)Gia_ObjLevel(p, pNode) != Level || !Vec_BitEntry(vPath, i) ) + continue; + fprintf( pFile, " Node%d [label = \"%d:%d\"", i, i, Gia_ObjIsAnd(pNode)? Gia_ObjLutSize(p, i) : 0 ); + fprintf( pFile, ", shape = ellipse" ); + if ( pNode->fMark0 ) + fprintf( pFile, ", style = filled" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + } + + // generate the CI nodes + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", 0 ); + // generate the CI nodes + Gia_ManForEachCi( p, pNode, i ) + { + if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) ) + continue; + fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) ); + fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate invisible edges from the square down + fprintf( pFile, "title1 -> title2 [style = invis];\n" ); + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) ); + } + // generate invisible edges among the COs + Prev = -1; + Gia_ManForEachCo( p, pNode, i ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels ) + continue; + assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ); + if ( Prev >= 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Gia_ManForEachCi( p, pNode, i ) + { + if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) ) + continue; + if ( Prev >= 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) ); + Prev = Gia_ObjId(p, pNode); + } + + // generate edges + Gia_ManForEachObj( p, pNode, i ) + { + if ( Gia_ObjIsCo(pNode) ) + { + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels ) + { + // generate the edge from this node to the next + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Gia_ObjFaninId0p(p, pNode) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + continue; + } + if ( !Gia_ObjIsAnd(pNode) || !Vec_BitEntry(vPath, i) ) + continue; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] + 1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + // generate the edge from this node to the next + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", iFan ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + } + + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + + Vec_IntFreeP( &p->vLevels ); + Vec_BitFree( vPath ); +} + + /**Function************************************************************* Synopsis [Writes the graph structure of AIG for DOT.] @@ -79,7 +367,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); // write the DOT header - fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); fprintf( pFile, "\n" ); fprintf( pFile, "digraph AIG {\n" ); fprintf( pFile, "size = \"7.5,10\";\n" ); @@ -153,7 +441,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); + fprintf( pFile, "The AIG contains %d nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -388,6 +676,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Gia_Obj_t * pNode;//, * pTemp, * pPrev; int LevelMax, Prev, Level, i; int fConstIsUsed = 0; + int nFadds = Ree_ManCountFadds( vAdds ); if ( Gia_ManAndNum(p) > 1000 ) { @@ -406,7 +695,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax ); // write the DOT header - fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); + fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" ); fprintf( pFile, "\n" ); fprintf( pFile, "digraph AIG {\n" ); fprintf( pFile, "size = \"7.5,10\";\n" ); @@ -480,7 +769,8 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax ); + fprintf( pFile, "The AIG contains %d nodes, %d full-adders, and %d half-adders, and spans %d levels.", + Gia_ManAndNum(p), nFadds, Vec_IntSize(vAdds)/6-nFadds, LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -813,12 +1103,12 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); } -void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) +void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath ) { extern void Abc_ShowFile( char * FileNameDot ); char FileNameDot[200]; FILE * pFile; - Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 ); + Vec_Int_t * vXors = NULL, * vAdds = fAdders ? Ree_ManComputeCuts( pMan, &vXors, 0 ) : NULL; sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") ); // check that the file can be opened if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) @@ -828,15 +1118,17 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds ) } fclose( pFile ); // generate the file - if ( fAdders ) + if ( fPath ) + Gia_ShowPath( pMan, FileNameDot ); + else if ( fAdders ) Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file Abc_ShowFile( FileNameDot ); - Vec_IntFree( vAdds ); - Vec_IntFree( vXors ); + Vec_IntFreeP( &vAdds ); + Vec_IntFreeP( &vXors ); } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 20d44227..910014c6 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -28594,9 +28594,9 @@ usage: int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) { Vec_Int_t * vBold = NULL; - int c, fAdders = 0, fFadds = 0; + int c, fAdders = 0, fFadds = 0, fPath = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "afh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "afph" ) ) != EOF ) { switch ( c ) { @@ -28606,6 +28606,9 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'f': fFadds ^= 1; break; + case 'p': + fPath ^= 1; + break; case 'h': goto usage; default: @@ -28628,15 +28631,16 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManForEachLut( pAbc->pGia, c ) Vec_IntPush( vBold, c ); } - Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds ); + Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds, fPath ); Vec_IntFreeP( &vBold ); return 0; usage: - Abc_Print( -2, "usage: &show [-afh]\n" ); + Abc_Print( -2, "usage: &show [-afph]\n" ); Abc_Print( -2, "\t shows the current GIA using GSView\n" ); Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle only showing full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle showing only full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle showing the critical path of a LUT mapping [default = %s]\n", fPath? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -42679,7 +42683,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); // Gia_PolynExplore( pAbc->pGia ); -// Gia_ManTestSatEnum( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/opt/sbd/sbdPath.c b/src/opt/sbd/sbdPath.c index a2b1a9b0..270c81c8 100644 --- a/src/opt/sbd/sbdPath.c +++ b/src/opt/sbd/sbdPath.c @@ -134,6 +134,60 @@ Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sbc_ManDelayTrace( Gia_Man_t * p ) +{ + Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); + int i, k, iFan, nLevels, * pLevels; + int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + if ( !Gia_ManHasMapping(p) ) + { + printf( "No mapping is available.\n" ); + return; + } + assert( Gia_ManHasMapping(p) ); + // set critical CO drivers + nLevels = Gia_ManLutLevel( p, &pLevels ); + Gia_ManForEachCoDriverId( p, iFan, i ) + if ( pLevels[iFan] == nLevels ) + Vec_BitWriteEntry( vPath, iFan, 1 ); + // set critical internal nodes + Gia_ManForEachLutReverse( p, i ) + { + nLuts++; + if ( !Vec_BitEntry(vPath, i) ) + continue; + nNodes++; + Gia_LutForEachFanin( p, i, iFan, k ) + { + if ( pLevels[iFan] +1 < pLevels[i] ) + continue; + assert( pLevels[iFan] + 1 == pLevels[i] ); + Vec_BitWriteEntry( vPath, iFan, 1 ); + nEdges++; + //printf( "%d -> %d\n", i, iFan ); + } + } + Gia_ManForEachLut( p, i ) + Gia_LutForEachFanin( p, i, iFan, k ) + nEdgesAll += (Vec_BitEntry(vPath, i) && Vec_BitEntry(vPath, iFan)); + + ABC_FREE( pLevels ); + Vec_BitFree( vPath ); + printf( "AIG = %d. LUT = %d. Lev = %d. Path nodes = %d. Path edges = %d. (%d.)\n", + Gia_ManAndNum(p), nLuts, nLevels, nNodes, nEdges, nEdgesAll ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 6d606b51ab084c96d92848be789397700bb3591f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 21:17:00 +0700 Subject: Updates to arithmetic verification. --- src/aig/gia/giaShow.c | 28 ++- src/base/wlc/wlcBlast.c | 10 + src/proof/acec/acecInt.h | 3 - src/proof/acec/acecMult.c | 107 +++++++++++ src/proof/acec/acecTree.c | 456 +++++++++++++++++++--------------------------- 5 files changed, 326 insertions(+), 278 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 28e874bf..cf89d942 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -52,7 +52,7 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) Gia_Obj_t * pNode; Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) ); int i, k, iFan, LevelMax, nLevels, * pLevels, Level, Prev; - int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0; + int nLuts = 0, nNodes = 0, nEdges = 0; assert( Gia_ManHasMapping(p) ); // set critical CO drivers @@ -670,7 +670,7 @@ int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node ) return Vec_IntEntry( vAdds, 6*iBox+4 ); return Node; } -void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) +void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder ) { FILE * pFile; Gia_Obj_t * pNode;//, * pTemp, * pPrev; @@ -689,6 +689,11 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In return; } + // mark the nodes + if ( vBold ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) + pNode->fMark0 = 1; + // compute levels LevelMax = 1 + p->nLevels; Gia_ManForEachCo( p, pNode, i ) @@ -819,7 +824,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In else fprintf( pFile, ", shape = ellipse" ); */ - if ( Vec_IntEntry(vMapAdds, iNode) >= 0 ) + if ( !pNode->fMark0 && Vec_IntEntry(vMapAdds, iNode) >= 0 ) { int iBox = Vec_IntEntry(vMapAdds, iNode); fprintf( pFile, " Node%d [label = \"%d_%d\"", Gia_ShowAddOut(vAdds, vMapAdds, iNode), Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); @@ -848,8 +853,8 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode ); fprintf( pFile, ", shape = ellipse" ); } -// if ( pNode->fMark0 ) -// fprintf( pFile, ", style = filled" ); + if ( pNode->fMark0 ) + fprintf( pFile, ", style = filled" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); @@ -920,8 +925,6 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In Gia_ManForEachObjVec( vOrder, p, pNode, i ) { int iNode = Gia_ObjId( p, pNode ); -// if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) ) -// continue; if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pNode)) >= 0 ) { int k, iBox = Vec_IntEntry(vMapAdds, iNode); @@ -990,6 +993,11 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In fprintf( pFile, "\n" ); fclose( pFile ); + // unmark nodes + if ( vBold ) + Gia_ManForEachObjVec( vBold, p, pNode, i ) + pNode->fMark0 = 0; + Vec_IntFreeP( &p->vLevels ); } @@ -1093,12 +1101,12 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v SeeAlso [] ***********************************************************************/ -void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) +void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); - Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder ); + Gia_WriteDotAig( p, pFileName, vBold, vAdds, vXors, vMapAdds, vMapXors, vOrder ); Vec_IntFree( vMapAdds ); Vec_IntFree( vMapXors ); Vec_IntFree( vOrder ); @@ -1121,7 +1129,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, if ( fPath ) Gia_ShowPath( pMan, FileNameDot ); else if ( fAdders ) - Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors, fFadds ); + Gia_ShowProcess( pMan, FileNameDot, vBold, vAdds, vXors, fFadds ); else Gia_WriteDotAigSimple( pMan, FileNameDot, vBold ); // visualize the file diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index b22ac6cd..b49c2dd7 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -645,10 +645,20 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) } void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) { + int fVerbose = 0; Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel; word Truth; int i, k, iLit; + Vec_WecForEachLevel( vProds, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) ) + Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) ); + printf( "Booth partial products: %d pps, %d unique, %d nodes.\n", + Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) ); + Vec_IntPrint( vSupp ); + + if ( fVerbose ) Vec_WecForEachLevel( vProds, vLevel, i ) Vec_IntForEachEntry( vLevel, iLit, k ) { diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 0dc3f706..125d923f 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -42,13 +42,10 @@ struct Acec_Box_t_ { Gia_Man_t * pGia; // AIG manager Vec_Wec_t * vAdds; // adders by rank - Vec_Wec_t * vLeafs; // leaf literals by rank - Vec_Wec_t * vRoots; // root literals by rank Vec_Wec_t * vLeafLits; // leaf literals by rank Vec_Wec_t * vRootLits; // root literals by rank Vec_Wec_t * vShared; // shared leaves Vec_Wec_t * vUnique; // unique leaves - Vec_Bit_t * vInvHadds; // complemented half adders }; //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 33c32144..8ccf966e 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -20,6 +20,7 @@ #include "acecInt.h" #include "misc/extra/extra.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -400,6 +401,15 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); printf( " " ); Vec_IntPrint( vSupp ); + /* + if ( Truth == 0xF335ACC0F335ACC0 ) + { + int iObj = Abc_Lit2Var(iLit); + Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 ); + Gia_ManShow( pGia0, NULL, 0, 0, 0 ); + Gia_ManStop( pGia0 ); + } + */ } // support rank counts Vec_IntForEachEntry( vSupp, Entry, j ) @@ -423,6 +433,103 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec return vInputs; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_MultFindPPs_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vBold ) +{ + Gia_Obj_t * pObj; + pObj = Gia_ManObj( p, iObj ); + if ( pObj->fMark0 ) + return; + pObj->fMark0 = 1; + if ( !Gia_ObjIsAnd(pObj) ) + return; + Acec_MultFindPPs_rec( p, Gia_ObjFaninId0(pObj, iObj), vBold ); + Acec_MultFindPPs_rec( p, Gia_ObjFaninId1(pObj, iObj), vBold ); + Vec_IntPush( vBold, iObj ); +} +Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) +{ + word Saved[32] = { + ABC_CONST(0xF335ACC0F335ACC0), + ABC_CONST(0x35C035C035C035C0), + ABC_CONST(0xD728D728D728D728), + ABC_CONST(0xFD80FD80FD80FD80), + ABC_CONST(0xACC0ACC0ACC0ACC0), + ABC_CONST(0x7878787878787878), + ABC_CONST(0x2828282828282828), + ABC_CONST(0xD0D0D0D0D0D0D0D0), + ABC_CONST(0x8080808080808080), + ABC_CONST(0x8888888888888888), + ABC_CONST(0xAAAAAAAAAAAAAAAA), + ABC_CONST(0x5555555555555555), + + ABC_CONST(0xD5A8D5A8D5A8D5A8), + ABC_CONST(0x2A572A572A572A57), + ABC_CONST(0xF3C0F3C0F3C0F3C0), + ABC_CONST(0x5858585858585858), + ABC_CONST(0xA7A7A7A7A7A7A7A7), + ABC_CONST(0x2727272727272727), + ABC_CONST(0xD8D8D8D8D8D8D8D8) + }; + + Vec_Int_t * vBold = Vec_IntAlloc( 100 ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + int i, iObj, nProds = 0; + Gia_ManCleanMark0(p); + Gia_ManForEachAndId( p, iObj ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp ); + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + continue; + for ( i = 0; i < 32; i++ ) + { + if ( Saved[i] == 0 ) + break; + if ( Truth == Saved[i] || Truth == ~Saved[i] ) + { + //Vec_IntPush( vBold, iObj ); + Acec_MultFindPPs_rec( p, iObj, vBold ); + printf( "%d ", iObj ); + nProds++; + break; + } + } +/* + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); +*/ + } + printf( "\n" ); + Gia_ManCleanMark0(p); + printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); + + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + return vBold; +} +void Acec_MultFindPPsTest( Gia_Man_t * p ) +{ + Vec_Int_t * vBold = Acec_MultFindPPs( p ); + Gia_ManShow( p, vBold, 1, 0, 0 ); + Vec_IntFree( vBold ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 8be8a340..370e8eb6 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -45,13 +45,10 @@ ABC_NAMESPACE_IMPL_START void Acec_BoxFree( Acec_Box_t * pBox ) { Vec_WecFreeP( &pBox->vAdds ); - Vec_WecFreeP( &pBox->vLeafs ); - Vec_WecFreeP( &pBox->vRoots ); Vec_WecFreeP( &pBox->vLeafLits ); Vec_WecFreeP( &pBox->vRootLits ); Vec_WecFreeP( &pBox->vUnique ); Vec_WecFreeP( &pBox->vShared ); - Vec_BitFreeP( &pBox->vInvHadds ); ABC_FREE( pBox ); } void Acec_BoxFreeP( Acec_Box_t ** ppBox ) @@ -120,6 +117,141 @@ void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees Acec_TreeFilterOne( p, vAdds, vLevel ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + int Truth0, Truth1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return pObj->Value; + Gia_ObjSetTravIdCurrent(p, pObj); + assert( Gia_ObjIsAnd(pObj) ); + assert( !Gia_ObjIsXor(pObj) ); + Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); + Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); + Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; + Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; + return (pObj->Value = Truth0 & Truth1); +} +void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) +{ + Gia_Obj_t * pObj; + unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; + int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; + + int Sign = Vec_IntEntry( vAdds, 6*iBox+5 ), Phase[5]; + for ( k = 0; k < 5; k++ ) + Phase[k] = (Sign >> (4+k)) & 1; + + Gia_ManIncrementTravId( p ); + for ( k = 0; k < 3; k++ ) + { + iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + pObj = Gia_ManObj( p, iObj ); + pObj->Value = Phase[k] ? 0xFF & ~Truths[k] : Truths[k]; + Gia_ObjSetTravIdCurrent( p, pObj ); + } + + iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); + TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthXor = Phase[3] ? 0xFF & ~TruthXor : TruthXor; + + iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); + TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); + TruthMaj = Phase[4] ? 0xFF & ~TruthMaj : TruthMaj; + + if ( fFadd ) // FADD + { + if ( TruthXor != 0x96 ) + printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); + if ( TruthMaj != 0xE8 ) + printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); + } + else + { + if ( TruthXor != 0x66 ) + printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); + if ( TruthMaj != 0x88 ) + printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); + } +} +void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Acec_TreeVerifyPhaseOne( p, vAdds, Box ); +} + +/**Function************************************************************* + + Synopsis [Creates polarity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, Box; + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); + return vMap; +} +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase ) +{ + int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + assert( Node != 0 ); + iBox = Vec_IntEntry( vMap, Node ); + if ( iBox == -1 ) + return; + assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); + Sign = Vec_IntEntry( vAdds, 6*iBox+5 ) & 0xFFFFFFF0; + fXorPhase = ((Sign >> 3) & 1); + if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) + { + fPhase ^= ((Sign >> 2) & 1); + if ( fPhase ) // complemented HADD + Sign |= (1 << 6); + } + for ( k = 0; k < 3; k++ ) + { + int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); + if ( iObj == 0 ) + continue; + fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fXorPhase ^= fPhaseThis; + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis ); + if ( fPhaseThis ) + Sign |= (1 << (4+k)); + } + if ( fXorPhase ) + Sign |= (1 << 7); + if ( fPhase ) + Sign |= (1 << 8); + // save updated signature + Vec_IntWriteEntry( vAdds, 6*iBox+5, Sign ); +} + /**Function************************************************************* Synopsis [Find internal cut points with exactly one adder fanin/fanout.] @@ -249,256 +381,6 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) } -/**Function************************************************************* - - Synopsis [Creates leaves and roots.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) -{ - int k, Box, Rank, MaxRank = 0; - Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) - MaxRank = Abc_MaxInt( MaxRank, Rank ); - return MaxRank; -} -void Acec_TreeInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vBoxes, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots ) -{ - Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, Box, Rank; - Vec_BitWriteEntry( vIsLeaf, 0, 1 ); - Vec_BitWriteEntry( vIsRoot, 0, 1 ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); - } - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - Vec_WecPush( vBoxes, Rank, Box ); - for ( k = 0; k < 3; k++ ) - { - if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) - continue; - Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k), 1 ); - Vec_WecPush( vLeaves, Rank, Vec_IntEntry(vAdds, 6*Box+k) ); - } - for ( k = 3; k < 5; k++ ) - { - if ( Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) - continue; - Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k), 1 ); - Vec_WecPush( vRoots, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), k==4), Vec_IntEntry(vAdds, 6*Box+2)!=0) ); - } - } - Vec_BitFree( vIsLeaf ); - Vec_BitFree( vIsRoot ); - // sort each level - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntSort( vLevel, 0 ); - Vec_WecForEachLevel( vLeaves, vLevel, i ) - Vec_IntSort( vLevel, 0 ); - Vec_WecForEachLevel( vRoots, vLevel, i ) - Vec_IntSort( vLevel, 0 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) -{ - int Truth0, Truth1; - if ( Gia_ObjIsTravIdCurrent(p, pObj) ) - return pObj->Value; - Gia_ObjSetTravIdCurrent(p, pObj); - assert( Gia_ObjIsAnd(pObj) ); - assert( !Gia_ObjIsXor(pObj) ); - Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) ); - Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) ); - Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0; - Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1; - return (pObj->Value = Truth0 & Truth1); -} -void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bit_t * vPhase ) -{ - Gia_Obj_t * pObj; - unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; - int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; - - //if ( !fFadd ) - // return; - - Gia_ManIncrementTravId( p ); - for ( k = 0; k < 3; k++ ) - { - iObj = Vec_IntEntry( vAdds, 6*iBox+k ); - if ( iObj == 0 ) - continue; - pObj = Gia_ManObj( p, iObj ); - pObj->Value = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~Truths[k] : Truths[k]; - Gia_ObjSetTravIdCurrent( p, pObj ); - } - - iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); - TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthXor = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthXor : TruthXor; - - iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); - TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthMaj = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthMaj : TruthMaj; - - if ( fFadd ) // FADD - { - if ( TruthXor != 0x96 ) - printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); - if ( TruthMaj != 0xE8 ) - printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); - } - else - { - if ( TruthXor != 0x66 ) - printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); - if ( TruthMaj != 0x88 ) - printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) ); - } -} -void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase ) -{ - Vec_Int_t * vLevel; - int i, k, Box; - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, Box, k ) - Acec_TreeVerifyPhaseOne( p, vAdds, Box, vPhase ); -} - -/**Function************************************************************* - - Synopsis [Creates polarity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) -{ - Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, Box; - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, Box, k ) - Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); - return vMap; -} -void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, - Vec_Bit_t * vPhase, Vec_Bit_t * vInvHadds, Vec_Bit_t * vVisit ) -{ - int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; - assert( Node != 0 ); - if ( Vec_BitEntry(vVisit, Node) ) - { - //assert( Vec_BitEntry(vPhase, Node) == fPhase ); - if ( Vec_BitEntry(vPhase, Node) != fPhase ) - printf( "Phase check failed for node %d.\n", Node ); - return; - } - Vec_BitWriteEntry( vVisit, Node, 1 ); - if ( fPhase ) - Vec_BitWriteEntry( vPhase, Node, fPhase ); - iBox = Vec_IntEntry( vMap, Node ); - if ( iBox == -1 ) - return; - assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); - iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); - Sign = Vec_IntEntry( vAdds, 6*iBox+5 ); - fXorPhase = ((Sign >> 3) & 1); - if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) - { - fPhase ^= ((Sign >> 2) & 1); - // remember complemented HADD - if ( fPhase ) - Vec_BitWriteEntry( vInvHadds, iBox, 1 ); - } - for ( k = 0; k < 3; k++ ) - { - int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); - if ( iObj == 0 ) - continue; - fPhaseThis = ((Sign >> k) & 1) ^ fPhase; - fXorPhase ^= fPhaseThis; - Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit ); - } - if ( Vec_BitEntry(vVisit, iXor) ) - { - //assert( Vec_BitEntry(vPhase, iXor) == fXorPhase ); - if ( Vec_BitEntry(vPhase, iXor) != fXorPhase ) - printf( "Phase check failed for XOR %d.\n", iXor ); - return; - } - if ( fXorPhase ) - Vec_BitWriteEntry( vPhase, iXor, fXorPhase ); -} -void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, - Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots, - Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits, Vec_Bit_t * vInvHadds ) -{ - Vec_Int_t * vMap = Acec_TreeCarryMap( p, vAdds, vBoxes ); - Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Bit_t * vVisit = Vec_BitStart( Gia_ManObjNum(p) ); - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevelReverse( vRoots, vLevel, i ) - { - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - if ( !fCout ) - continue; - Acec_TreePhases_rec( p, vAdds, vMap, Node, fFadd, vPhase, vInvHadds, vVisit ); - } - } - Vec_IntFree( vMap ); - Vec_BitFree( vVisit ); - Acec_TreeVerifyPhases( p, vAdds, vBoxes, vPhase ); - // create leaves - Vec_WecForEachLevel( vLeaves, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - Vec_WecPush( vLeafLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); - // add constants - Vec_WecForEachLevel( vBoxes, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - if ( Vec_BitEntry(vInvHadds, iObj) ) - Vec_WecPush( vLeafLits, i, 1 ); - // create roots - Vec_WecForEachLevel( vRoots, vLevel, i ) - Vec_IntForEachEntry( vLevel, iObj, k ) - iObj >>= 2, Vec_WecPush( vRootLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) ); - // cleanup - Vec_BitFree( vPhase ); -} - /**Function************************************************************* Synopsis [Derives one adder tree.] @@ -564,25 +446,69 @@ void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) //Acec_PrintRootLits( pBox->vRoots ); } +int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) +{ + int k, Box, Rank, MaxRank = 0; + Vec_IntForEachEntryDouble( vTree, Box, Rank, k ) + MaxRank = Abc_MaxInt( MaxRank, Rank ); + return MaxRank; +} Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { int MaxRank = Acec_CreateBoxMaxRank(vTree); + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel, * vMap; + int i, k, Box, Rank; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); - pBox->pGia = p; - - pBox->vAdds = Vec_WecStart( MaxRank + 1 ); - pBox->vLeafs = Vec_WecStart( MaxRank + 1 ); - pBox->vRoots = Vec_WecStart( MaxRank + 2 ); + pBox->pGia = p; + pBox->vAdds = Vec_WecStart( MaxRank + 1 ); + pBox->vLeafLits = Vec_WecStart( MaxRank + 1 ); + pBox->vRootLits = Vec_WecStart( MaxRank + 2 ); - Acec_TreeInsOuts( p, vAdds, vTree, pBox->vAdds, pBox->vLeafs, pBox->vRoots ); - - pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) ); - pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) ); - pBox->vInvHadds = Vec_BitStart( Vec_IntSize(vAdds)/6 ); + // collect boxes; mark inputs/outputs + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_WecPush( pBox->vAdds, Rank, Box ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + // sort each level + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntSort( vLevel, 0 ); - Acec_TreePhases( p, vAdds, pBox->vAdds, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits, pBox->vInvHadds ); + // set phases + vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0 ); + Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); + Vec_IntFree( vMap ); + // collect inputs/outputs + Vec_BitWriteEntry( vIsLeaf, 0, 0 ); + Vec_BitWriteEntry( vIsRoot, 0, 0 ); + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + int Sign = Vec_IntEntry( vAdds, 6*Box+5 ); + for ( k = 0; k < 3; k++ ) + if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vLeafLits, Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (4+k)) & 1) ); + for ( k = 3; k < 5; k++ ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vRootLits, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (7+k)) & 1) ); + } + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vIsRoot ); + // sort each level + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntSort( vLevel, 0 ); return pBox; } void Acec_CreateBoxTest( Gia_Man_t * p ) @@ -641,7 +567,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); - //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; -- cgit v1.2.3 From 79701f8b4603596095d3d04a13018c8e9598f7a0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Jan 2017 16:11:59 +0700 Subject: Updates to arithmetic verification. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaEquiv.c | 27 +++++++- src/base/abci/abc.c | 20 ++++-- src/base/abci/abcDress3.c | 30 +-------- src/proof/acec/acec.h | 3 +- src/proof/acec/acecCore.c | 73 ++++++++++++++++----- src/proof/acec/acecInt.h | 3 +- src/proof/acec/acecMult.c | 19 ++++-- src/proof/acec/acecNorm.c | 6 +- src/proof/acec/acecTree.c | 161 ++++++++++++++++++++++++++-------------------- 10 files changed, 215 insertions(+), 128 deletions(-) (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 68060119..dc6c679a 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1270,6 +1270,7 @@ extern void Gia_ManOrigIdsInit( Gia_Man_t * p ); extern void Gia_ManOrigIdsStart( Gia_Man_t * p ); extern void Gia_ManOrigIdsRemap( Gia_Man_t * p, Gia_Man_t * pNew ); extern Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs ); +extern Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ); extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p ); extern int Gia_ManCheckTopoOrder( Gia_Man_t * p ); extern int * Gia_ManDeriveNexts( Gia_Man_t * p ); diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 584be4cd..1b0bce07 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -129,7 +129,7 @@ Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs ) } Gia_ManHashStop( pNew ); Gia_ManForEachCo( p, pObj, i ) - Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Vec_IntFree( vMap ); // compute equivalences assert( !p->pReprs && !p->pNexts ); @@ -169,6 +169,31 @@ Gia_Man_t * Gia_ManOrigIdsReduceTest( Gia_Man_t * p, Vec_Int_t * vPairs ) return pNew; } +/**Function************************************************************* + + Synopsis [Compute equivalence classes of nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ) +{ + Gia_Man_t * pTemp; + Cec_ParFra_t ParsFra, * pPars = &ParsFra; + Cec_ManFraSetDefaultParams( pPars ); + pPars->fUseOrigIds = 1; + pPars->fSatSweeping = 1; + pPars->nBTLimit = nConfs; + pPars->fVerbose = fVerbose; + pTemp = Cec_ManSatSweeping( pGia, pPars, 0 ); + Gia_ManStop( pTemp ); + return Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv ); +} + /**Function************************************************************* Synopsis [Returns 1 if AIG is not in the required topo order.] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 910014c6..1e94f28f 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40543,7 +40543,7 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) int c, nArgcNew; Acec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtbvh" ) ) != EOF ) { switch ( c ) { @@ -40578,6 +40578,9 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) case 't': pPars->fTwoOutput ^= 1; break; + case 'b': + pPars->fBooth ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -40720,13 +40723,14 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &acec [-CT num] [-mdtvh] \n" ); + Abc_Print( -2, "usage: &acec [-CT num] [-mdtbvh] \n" ); Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits"); Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no"); Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no"); + Abc_Print( -2, "\t-b : toggle working with Booth multipliers [default = %s]\n", pPars->fBooth? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n"); @@ -40748,12 +40752,15 @@ usage: int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; - int c, fVerbose = 0; + int c, fBooth = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) { switch ( c ) { + case 'b': + fBooth ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -40768,13 +40775,14 @@ int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" ); return 0; } - pTemp = Acec_Normalize( pAbc->pGia, fVerbose ); + pTemp = Acec_Normalize( pAbc->pGia, fBooth, fVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &anorm [-vh]\n" ); + Abc_Print( -2, "usage: &anorm [-bvh]\n" ); Abc_Print( -2, "\t normalize adder trees in the current AIG\n" ); + Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/abci/abcDress3.c b/src/base/abci/abcDress3.c index 33545f0a..ce0cb7f5 100644 --- a/src/base/abci/abcDress3.c +++ b/src/base/abci/abcDress3.c @@ -33,32 +33,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [Compute equivalence classes of nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ) -{ - Gia_Man_t * pTemp; - Cec_ParFra_t ParsFra, * pPars = &ParsFra; - Cec_ManFraSetDefaultParams( pPars ); - pPars->fUseOrigIds = 1; - pPars->fSatSweeping = 1; - pPars->nBTLimit = nConfs; - pPars->fVerbose = fVerbose; - pTemp = Cec_ManSatSweeping( pGia, pPars, 0 ); - Gia_ManStop( pTemp ); - pTemp = Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv ); - Gia_ManStop( pTemp ); -} - /**Function************************************************************* Synopsis [Converts AIG from HOP to GIA.] @@ -315,13 +289,15 @@ void Abc_NtkDumpEquivFile( char * pFileName, Vec_Int_t * vClasses, Abc_Ntk_t * p void Abc_NtkDumpEquiv( Abc_Ntk_t * pNtks[2], char * pFileName, int nConfs, int fByName, int fVerbose ) { //abctime clk = Abc_Clock(); + Gia_Man_t * pTemp; Vec_Int_t * vClasses; // derive shared AIG for the two networks Gia_Man_t * pGia = Abc_NtkAigToGiaTwo( pNtks[0], pNtks[1], fByName ); if ( fVerbose ) printf( "Computing equivalences for networks \"%s\" and \"%s\" with conflict limit %d.\n", Abc_NtkName(pNtks[0]), Abc_NtkName(pNtks[1]), nConfs ); // compute equivalences in this AIG - Abc_NtkComputeGiaEquivs( pGia, nConfs, fVerbose ); + pTemp = Gia_ManComputeGiaEquivs( pGia, nConfs, fVerbose ); + Gia_ManStop( pTemp ); //if ( fVerbose ) // Abc_PrintTime( 1, "Equivalence computation time", Abc_Clock() - clk ); if ( fVerbose ) diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 7ad5baf9..5a24bec7 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -47,6 +47,7 @@ struct Acec_ParCec_t_ int fMiter; // input circuit is a miter int fDualOutput; // dual-output miter int fTwoOutput; // two-output miter + int fBooth; // expecting Booth multiplier int fSilent; // print no messages int fVeryVerbose; // verbose stats int fVerbose; // verbose stats @@ -81,7 +82,7 @@ extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int extern int Ree_ManCountFadds( Vec_Int_t * vAdds ); extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose ); /*=== acecTree.c ========================================================*/ -extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ); +extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 3e31fa36..4a91663f 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -68,7 +68,7 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) +Gia_Man_t * Acec_CommonStart( Gia_Man_t * pBase, Gia_Man_t * pAdd ) { Gia_Obj_t * pObj; int i; @@ -93,35 +93,69 @@ Gia_Man_t * Acec_FindEquivs( Gia_Man_t * pBase, Gia_Man_t * pAdd ) pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); return pBase; } -Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd ) +void Acec_CommonFinish( Gia_Man_t * pBase ) +{ + int Id; + Gia_ManCreateRefs( pBase ); + Gia_ManForEachAndId( pBase, Id ) + if ( Gia_ObjRefNumId(pBase, Id) == 0 ) + Gia_ManAppendCo( pBase, Abc_Var2Lit(Id,0) ); +} +Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase ) { Gia_Obj_t * pObj; int i; Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) ); + Gia_ManSetPhase( pAdd ); + Vec_IntWriteEntry( vMapNew, 0, 0 ); Gia_ManForEachCand( pAdd, pObj, i ) - Vec_IntWriteEntry( vMapNew, i, Abc_Lit2Var(pObj->Value) ); + { + int iObjBase = Abc_Lit2Var(pObj->Value); + Gia_Obj_t * pObjBase = Gia_ManObj( pBase, iObjBase ); + int iObjRepr = Abc_Lit2Var(pObjBase->Value); + Vec_IntWriteEntry( vMapNew, i, Abc_Var2Lit(iObjRepr, Gia_ObjPhase(pObj)) ); + } return vMapNew; } void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) { - Gia_Man_t * pBase; - pBase = Acec_FindEquivs( NULL, pOne ); - pBase = Acec_FindEquivs( pBase, pTwo ); - *pvMap1 = Acec_CountRemap( pOne ); - *pvMap2 = Acec_CountRemap( pTwo ); + Gia_Man_t * pBase, * pRepr; + pBase = Acec_CommonStart( NULL, pOne ); + pBase = Acec_CommonStart( pBase, pTwo ); + Acec_CommonFinish( pBase ); + + //Gia_ManShow( pBase, NULL, 0, 0, 0 ); + + pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 ); + *pvMap1 = Acec_CountRemap( pOne, pBase ); + *pvMap2 = Acec_CountRemap( pTwo, pBase ); Gia_ManStop( pBase ); + Gia_ManStop( pRepr ); } -static inline void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCosts ) +void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) { int i, j, best_i; for ( i = 0; i < nSize-1; i++ ) { best_i = i; for ( j = i+1; j < nSize; j++ ) - if ( pCosts[Abc_Lit2Var(pArray[j])] > pCosts[Abc_Lit2Var(pArray[best_i])] ) + if ( Abc_Lit2LitL(pCostLits, pArray[j]) > Abc_Lit2LitL(pCostLits, pArray[best_i]) ) best_i = j; ABC_SWAP( int, pArray[i], pArray[best_i] ); } } +void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) +{ + Vec_Int_t * vLevel; + int i, k, Entry; + printf( "Leaf literals and their classes:\n" ); + Vec_WecForEachLevel( vLits, vLevel, i ) + { + printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) ); + Vec_IntForEachEntry( vLevel, Entry, k ) + printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); + printf( "\n" ); + } +} int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) { Vec_Int_t * vMap0, * vMap1, * vLevel; @@ -132,6 +166,8 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); + //Acec_MatchPrintEquivLits( pBox0->vLeafLits, Vec_IntArray(vMap0) ); + //Acec_MatchPrintEquivLits( pBox1->vLeafLits, Vec_IntArray(vMap1) ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); assert( pBox1->vShared == NULL ); @@ -159,8 +195,9 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int * pEnd1 = Vec_IntLimit(vLevel1); while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 ) { - int Entry0 = Abc_Lit2LitV( Vec_IntArray(vMap0), *pBeg0 ); - int Entry1 = Abc_Lit2LitV( Vec_IntArray(vMap1), *pBeg1 ); + int Entry0 = Abc_Lit2LitL( Vec_IntArray(vMap0), *pBeg0 ); + int Entry1 = Abc_Lit2LitL( Vec_IntArray(vMap1), *pBeg1 ); + assert( *pBeg0 && *pBeg1 ); if ( Entry0 == Entry1 ) { Vec_IntPush( vShared0, *pBeg0++ ); @@ -201,11 +238,16 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) { int status = -1; + abctime clk = Abc_Clock(); Gia_Man_t * pMiter; Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, pPars->fVerbose ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, pPars->fVerbose ); + Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; + Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, pPars->fVerbose ); + Vec_BitFreeP( &vIgnore0 ); + Vec_BitFreeP( &vIgnore1 ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching @@ -214,7 +256,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) { pGia0n = Acec_InsertBox( pBox0, 1 ); pGia1n = Acec_InsertBox( pBox1, 1 ); - printf( "Found, matched, and normalized arithmetic boxes in LHS and RHS. Solving resulting CEC.\n" ); + printf( "Matching of adder trees in LHS and RHS succeeded. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 125d923f..cc5786bb 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -69,10 +69,11 @@ extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Ve extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes ); /*=== acecMult.c ========================================================*/ extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); +extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ); /*=== acecNorm.c ========================================================*/ extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 8ccf966e..0733c00b 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -490,18 +490,16 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Gia_ManForEachAndId( p, iObj ) { word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp ); + if ( Vec_IntSize(vSupp) > 6 ) + continue; vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); if ( Vec_IntSize(vSupp) > 5 ) continue; - for ( i = 0; i < 32; i++ ) + for ( i = 0; i < 32 && Saved[i]; i++ ) { - if ( Saved[i] == 0 ) - break; if ( Truth == Saved[i] || Truth == ~Saved[i] ) { - //Vec_IntPush( vBold, iObj ); Acec_MultFindPPs_rec( p, iObj, vBold ); - printf( "%d ", iObj ); nProds++; break; } @@ -515,7 +513,6 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Vec_IntPrint( vSupp ); */ } - printf( "\n" ); Gia_ManCleanMark0(p); printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); @@ -523,6 +520,16 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) Vec_WrdFree( vTemp ); return vBold; } +Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ) +{ + Vec_Bit_t * vIgnore = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vMap = Acec_MultFindPPs( p ); + int i, Entry; + Vec_IntForEachEntry( vMap, Entry, i ) + Vec_BitWriteEntry( vIgnore, Entry, 1 ); + Vec_IntFree( vMap ); + return vIgnore; +} void Acec_MultFindPPsTest( Gia_Man_t * p ) { Vec_Int_t * vBold = Acec_MultFindPPs( p ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 9faf7acf..4ed32e7b 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -198,11 +198,13 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fVerbose ) +Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ) { - Acec_Box_t * pBox = Acec_DeriveBox( pGia, fVerbose ); + Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL; + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); Acec_BoxFreeP( &pBox ); + Vec_BitFreeP( &vIgnore ); return pNew; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 370e8eb6..fef36923 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -27,6 +27,12 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; } +static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; } + +static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); } +static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -147,10 +153,7 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) Gia_Obj_t * pObj; unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 }; int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0; - - int Sign = Vec_IntEntry( vAdds, 6*iBox+5 ), Phase[5]; - for ( k = 0; k < 5; k++ ) - Phase[k] = (Sign >> (4+k)) & 1; + int fFlip = !fFadd && Acec_SignBit2(vAdds, iBox, 2); Gia_ManIncrementTravId( p ); for ( k = 0; k < 3; k++ ) @@ -159,17 +162,17 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) if ( iObj == 0 ) continue; pObj = Gia_ManObj( p, iObj ); - pObj->Value = Phase[k] ? 0xFF & ~Truths[k] : Truths[k]; + pObj->Value = (Acec_SignBit2(vAdds, iBox, k) ^ fFlip) ? 0xFF & ~Truths[k] : Truths[k]; Gia_ObjSetTravIdCurrent( p, pObj ); } iObj = Vec_IntEntry( vAdds, 6*iBox+3 ); TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthXor = Phase[3] ? 0xFF & ~TruthXor : TruthXor; + TruthXor = (Acec_SignBit2(vAdds, iBox, 3) ^ fFlip) ? 0xFF & ~TruthXor : TruthXor; iObj = Vec_IntEntry( vAdds, 6*iBox+4 ); TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) ); - TruthMaj = Phase[4] ? 0xFF & ~TruthMaj : TruthMaj; + TruthMaj = (Acec_SignBit2(vAdds, iBox, 4) ^ fFlip) ? 0xFF & ~TruthMaj : TruthMaj; if ( fFadd ) // FADD { @@ -180,6 +183,8 @@ void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox ) } else { + //printf( "Sign1 = %d%d%d %d\n", Acec_SignBit(vAdds, iBox, 0), Acec_SignBit(vAdds, iBox, 1), Acec_SignBit(vAdds, iBox, 2), Acec_SignBit(vAdds, iBox, 3) ); + //printf( "Sign2 = %d%d%d %d%d\n", Acec_SignBit2(vAdds, iBox, 0), Acec_SignBit2(vAdds, iBox, 1), Acec_SignBit2(vAdds, iBox, 2), Acec_SignBit2(vAdds, iBox, 3), Acec_SignBit2(vAdds, iBox, 4) ); if ( TruthXor != 0x66 ) printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) ); if ( TruthMaj != 0x88 ) @@ -194,6 +199,36 @@ void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes Vec_IntForEachEntry( vLevel, Box, k ) Acec_TreeVerifyPhaseOne( p, vAdds, Box ); } +void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vRoots = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, n, Box; + // mark all output points and their values + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + { + Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+3 ), 1 ); + Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+4 ), 1 ); + Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+3 ), Acec_SignBit2(vAdds, Box, 3) ); + Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+4 ), Acec_SignBit2(vAdds, Box, 4) ); + } + // compare with input points + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + for ( n = 0; n < 3; n++ ) + { + if ( !Vec_BitEntry(vRoots, Vec_IntEntry(vAdds, 6*Box+n)) ) + continue; + if ( Vec_BitEntry(vPhase, Vec_IntEntry(vAdds, 6*Box+n)) == Acec_SignBit2(vAdds, Box, n) ) + continue; + printf( "Phase of input %d=%d is mismatched in box %d=(%d,%d).\n", + n, Vec_IntEntry(vAdds, 6*Box+n), Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4) ); + } + Vec_BitFree( vPhase ); + Vec_BitFree( vRoots ); +} /**Function************************************************************* @@ -216,40 +251,40 @@ Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBo Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box ); return vMap; } -void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase ) +void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit ) { - int k, iBox, iXor, Sign, fXorPhase, fPhaseThis; + int k, iBox, iXor, fXorPhase, fPhaseThis; assert( Node != 0 ); iBox = Vec_IntEntry( vMap, Node ); if ( iBox == -1 ) return; assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) ); + if ( Vec_BitEntry(vVisit, iBox) ) + return; + Vec_BitWriteEntry( vVisit, iBox, 1 ); iXor = Vec_IntEntry( vAdds, 6*iBox+3 ); - Sign = Vec_IntEntry( vAdds, 6*iBox+5 ) & 0xFFFFFFF0; - fXorPhase = ((Sign >> 3) & 1); + fXorPhase = Acec_SignBit(vAdds, iBox, 3); if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 ) { - fPhase ^= ((Sign >> 2) & 1); - if ( fPhase ) // complemented HADD - Sign |= (1 << 6); + //fPhaseThis = Acec_SignBit( vAdds, iBox, 2 ) ^ fPhase; + //fXorPhase ^= fPhaseThis; + //Acec_SignSetBit2( vAdds, iBox, 2, fPhaseThis ); // complemented HADD -- create const1 input + fPhase ^= Acec_SignBit( vAdds, iBox, 2 ); + fXorPhase ^= fPhase; + Acec_SignSetBit2( vAdds, iBox, 2, fPhase ); // complemented HADD -- create const1 input } for ( k = 0; k < 3; k++ ) { int iObj = Vec_IntEntry( vAdds, 6*iBox+k ); if ( iObj == 0 ) continue; - fPhaseThis = ((Sign >> k) & 1) ^ fPhase; + fPhaseThis = Acec_SignBit(vAdds, iBox, k) ^ fPhase; fXorPhase ^= fPhaseThis; - Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis ); - if ( fPhaseThis ) - Sign |= (1 << (4+k)); + Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vVisit ); + Acec_SignSetBit2( vAdds, iBox, k, fPhaseThis ); } - if ( fXorPhase ) - Sign |= (1 << 7); - if ( fPhase ) - Sign |= (1 << 8); - // save updated signature - Vec_IntWriteEntry( vAdds, 6*iBox+5, Sign ); + Acec_SignSetBit2( vAdds, iBox, 3, fXorPhase ); + Acec_SignSetBit2( vAdds, iBox, 4, fPhase ); } /**Function************************************************************* @@ -271,12 +306,14 @@ void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut ) else if ( *pPlace >= 0 ) *pPlace = -2; } -Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) { Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) ); int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 ); @@ -328,10 +365,10 @@ void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); } -Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds ) +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) { Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); - Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds ); + Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore ); Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 ); Vec_Int_t * vTree; int i, k, In, Out, Box, Rank, MinRank; @@ -371,7 +408,7 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Vec_WecPrint( vTrees, 0 ); @@ -417,23 +454,6 @@ void Vec_WecPrintLits( Vec_Wec_t * p ) printf( " }\n" ); } } -void Acec_PrintRootLits( Vec_Wec_t * vRoots ) -{ - Vec_Int_t * vLevel; - int i, k, iObj; - Vec_WecForEachLevel( vRoots, vLevel, i ) - { - printf( "Rank %d : %2d ", i, Vec_IntSize(vLevel) ); - Vec_IntForEachEntry( vLevel, iObj, k ) - { - int fFadd = Abc_LitIsCompl(iObj); - int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj)); - int Node = Abc_Lit2Var(Abc_Lit2Var(iObj)); - printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" ); - } - printf( "\n" ); - } -} void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) { printf( "Adders:\n" ); @@ -442,8 +462,6 @@ void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) Vec_WecPrintLits( pBox->vLeafLits ); printf( "Outputs:\n" ); Vec_WecPrintLits( pBox->vRootLits ); - //printf( "Raw outputs:\n" ); - //Acec_PrintRootLits( pBox->vRoots ); } int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) @@ -456,10 +474,11 @@ int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) { int MaxRank = Acec_CreateBoxMaxRank(vTree); + Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 ); Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, k, Box, Rank; + int i, j, k, Box, Rank; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -470,38 +489,42 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree // collect boxes; mark inputs/outputs Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { - Vec_WecPush( pBox->vAdds, Rank, Box ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + Vec_WecPush( pBox->vAdds, Rank, Box ); } // sort each level Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) Vec_IntSort( vLevel, 0 ); - // set phases + // set phases starting from roots vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) - Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0 ); + Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit ); Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); + Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds ); + Vec_BitFree( vVisit ); Vec_IntFree( vMap ); // collect inputs/outputs - Vec_BitWriteEntry( vIsLeaf, 0, 0 ); - Vec_BitWriteEntry( vIsRoot, 0, 0 ); - Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) - { - int Sign = Vec_IntEntry( vAdds, 6*Box+5 ); - for ( k = 0; k < 3; k++ ) - if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) - Vec_WecPush( pBox->vLeafLits, Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (4+k)) & 1) ); - for ( k = 3; k < 5; k++ ) - if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) - Vec_WecPush( pBox->vRootLits, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), (Sign >> (7+k)) & 1) ); - } + Vec_BitWriteEntry( vIsRoot, 0, 1 ); + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, j ) + { + for ( k = 0; k < 3; k++ ) + if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + for ( k = 3; k < 5; k++ ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) ) + Vec_WecPush( pBox->vLeafLits, i, 1 ); + } Vec_BitFree( vIsLeaf ); Vec_BitFree( vIsRoot ); // sort each level @@ -524,7 +547,7 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); //Vec_WecPrint( vTrees, 0 ); @@ -554,11 +577,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) { Acec_Box_t * pBox = NULL; Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); - Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); if ( pBox )//&& fVerbose ) @@ -567,7 +590,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose ) Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); - Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); + //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); return pBox; -- cgit v1.2.3 From 1b86911c4fe0b193c3a281e823de7934664da798 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Jan 2017 20:28:26 +0700 Subject: Updates to arithmetic verification. --- src/aig/gia/giaShow.c | 14 +++--- src/base/abci/abc.c | 2 +- src/misc/vec/vecInt.h | 18 ++++++++ src/misc/vec/vecWec.h | 17 ++++++++ src/proof/acec/acecCore.c | 108 +++++++++++++++++++++++++++++++++++++++++++--- src/proof/acec/acecMult.c | 20 +++++---- src/proof/acec/acecNorm.c | 2 +- src/proof/acec/acecRe.c | 27 +++++++----- src/proof/acec/acecTree.c | 28 +++++++++++- 9 files changed, 201 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index cf89d942..4dd85aab 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define NODE_MAX 2000 + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -79,11 +81,11 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) } } - if ( nNodes > 500 ) + if ( nNodes > NODE_MAX ) { ABC_FREE( pLevels ); Vec_BitFree( vPath ); - fprintf( stdout, "Cannot visualize AIG with more than 500 critical nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d critical nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -341,9 +343,9 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) int LevelMax, Prev, Level, i; int fConstIsUsed = 0; - if ( Gia_ManAndNum(p) > 500 ) + if ( Gia_ManAndNum(p) > NODE_MAX ) { - fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) @@ -678,9 +680,9 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In int fConstIsUsed = 0; int nFadds = Ree_ManCountFadds( vAdds ); - if ( Gia_ManAndNum(p) > 1000 ) + if ( Gia_ManAndNum(p) > NODE_MAX ) { - fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" ); + fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1e94f28f..9db3d7d6 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -42690,7 +42690,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); -// Gia_PolynExplore( pAbc->pGia ); + Acec_MultFindPPsTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index f09b8783..d952518f 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -1692,6 +1692,24 @@ static inline int Vec_IntTwoFindCommon( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Ve } return Vec_IntSize(vArr); } +static inline int Vec_IntTwoFindCommonReverse( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vArr ) +{ + int * pBeg1 = vArr1->pArray; + int * pBeg2 = vArr2->pArray; + int * pEnd1 = vArr1->pArray + vArr1->nSize; + int * pEnd2 = vArr2->pArray + vArr2->nSize; + Vec_IntClear( vArr ); + while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 ) + { + if ( *pBeg1 == *pBeg2 ) + Vec_IntPush( vArr, *pBeg1 ), pBeg1++, pBeg2++; + else if ( *pBeg1 > *pBeg2 ) + pBeg1++; + else + pBeg2++; + } + return Vec_IntSize(vArr); +} /**Function************************************************************* diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h index e4e92503..8180e984 100644 --- a/src/misc/vec/vecWec.h +++ b/src/misc/vec/vecWec.h @@ -303,6 +303,23 @@ static inline Vec_Int_t * Vec_WecPushLevel( Vec_Wec_t * p ) ++p->nSize; return Vec_WecEntryLast( p ); } +static inline Vec_Int_t * Vec_WecInsertLevel( Vec_Wec_t * p, int i ) +{ + Vec_Int_t * pTemp; + if ( p->nSize == p->nCap ) + { + if ( p->nCap < 16 ) + Vec_WecGrow( p, 16 ); + else + Vec_WecGrow( p, 2 * p->nCap ); + } + ++p->nSize; + assert( i >= 0 && i < p->nSize ); + for ( pTemp = p->pArray + p->nSize - 2; pTemp >= p->pArray + i; pTemp-- ) + pTemp[1] = pTemp[0]; + Vec_IntZero( p->pArray + i ); + return p->pArray + i; +} /**Function************************************************************* diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 4a91663f..6b631a1b 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -20,6 +20,8 @@ #include "acecInt.h" #include "proof/cec/cec.h" +#include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" ABC_NAMESPACE_IMPL_START @@ -118,18 +120,19 @@ Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase ) } void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 ) { + abctime clk = Abc_Clock(); Gia_Man_t * pBase, * pRepr; pBase = Acec_CommonStart( NULL, pOne ); pBase = Acec_CommonStart( pBase, pTwo ); Acec_CommonFinish( pBase ); - //Gia_ManShow( pBase, NULL, 0, 0, 0 ); - pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 ); *pvMap1 = Acec_CountRemap( pOne, pBase ); *pvMap2 = Acec_CountRemap( pTwo, pBase ); Gia_ManStop( pBase ); Gia_ManStop( pRepr ); + printf( "Finished computing equivalent nodes. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) { @@ -143,8 +146,10 @@ void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) ABC_SWAP( int, pArray[i], pArray[best_i] ); } } -void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) +void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose ) { + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel; int i, k, Entry; printf( "Leaf literals and their classes:\n" ); @@ -155,6 +160,85 @@ void Acec_MatchPrintEquivLits( Vec_Wec_t * vLits, int * pCostLits ) printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); printf( "\n" ); } + if ( !fVerbose ) + return; + Vec_WecForEachLevel( vLits, vLevel, i ) + { + if ( i != 20 ) + continue; + Vec_IntForEachEntry( vLevel, Entry, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); + printf( "Rank = %4d : ", i ); + printf( "Obj = %4d ", Abc_Lit2Var(Entry) ); + if ( Vec_IntSize(vSupp) > 6 ) + { + printf( "Supp = %d.\n", Vec_IntSize(vSupp) ); + continue; + } + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + { + printf( "Supp = %d.\n", Vec_IntSize(vSupp) ); + continue; + } + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + printf( "\n" ); + } + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); +} +Vec_Wec_t * Acec_MatchCopy( Vec_Wec_t * vLits, Vec_Int_t * vMap ) +{ + Vec_Wec_t * vRes = Vec_WecStart( Vec_WecSize(vLits) ); + Vec_Int_t * vLevel; int i, k, iLit; + Vec_WecForEachLevel( vLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + Vec_WecPush( vRes, i, Abc_Lit2LitL(Vec_IntArray(vMap), iLit) ); + return vRes; +} +int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Vec_Int_t * vLevel1, * vLevel2; + int i, nCommon = 0; + Vec_WecForEachLevel( vLits1, vLevel1, i ) + { + if ( i+Shift < 0 || i+Shift >= Vec_WecSize(vLits2) ) + continue; + vLevel2 = Vec_WecEntry( vLits2, i+Shift ); + nCommon += Vec_IntTwoFindCommonReverse( vLevel1, vLevel2, vRes ); + } + Vec_IntFree( vRes ); + return nCommon; +} +void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) +{ + Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); + Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 ); + int nCommon = Acec_MatchCountCommon( vRes0, vRes1, 0 ); + int nCommonPlus = Acec_MatchCountCommon( vRes0, vRes1, 1 ); + int nCommonMinus = Acec_MatchCountCommon( vRes0, vRes1, -1 ); + if ( nCommonPlus >= nCommonMinus && nCommonPlus > nCommon ) + { + Vec_WecInsertLevel( vLits0, 0 ); + Vec_WecInsertLevel( vRoots0, 0 ); + } + else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) + { + Vec_WecInsertLevel( vLits1, 0 ); + Vec_WecInsertLevel( vRoots1, 0 ); + } + Vec_WecPrint( vRes0, 0 ); + Vec_WecPrint( vRes1, 0 ); + Vec_WecFree( vRes0 ); + Vec_WecFree( vRes1 ); } int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) { @@ -166,8 +250,11 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); - //Acec_MatchPrintEquivLits( pBox0->vLeafLits, Vec_IntArray(vMap0) ); - //Acec_MatchPrintEquivLits( pBox1->vLeafLits, Vec_IntArray(vMap1) ); + Acec_MatchCheckShift( pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); + + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); + // reorder nodes to have the same order assert( pBox0->vShared == NULL ); assert( pBox1->vShared == NULL ); @@ -216,11 +303,15 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) ); assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) ); } - Vec_IntFree( vMap0 ); - Vec_IntFree( vMap1 ); nTotal = Vec_WecSizeSize(pBox0->vShared); printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 ); + + Vec_IntFree( vMap0 ); + Vec_IntFree( vMap1 ); return nTotal; } @@ -258,6 +349,9 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) pGia1n = Acec_InsertBox( pBox1, 1 ); printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + // remove the last output + //Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); + //Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index 0733c00b..d868c399 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -504,14 +504,18 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) break; } } -/* - Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); - if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); - if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); - if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); - printf( " " ); - Vec_IntPrint( vSupp ); -*/ + /* + if ( Saved[i] ) + { + printf( "Obj = %4d ", iObj ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + } + */ } Gia_ManCleanMark0(p); printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 4ed32e7b..0d209524 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -112,7 +112,7 @@ int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) assert( Gia_ObjIsAnd(pObj) ); Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) ); Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); - return (pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); + return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); } Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) { diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 161b6fbb..7f87df85 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -147,6 +147,7 @@ static inline int Ree_ManCutFind( int iObj, int * pCut ) } static inline int Ree_ManCutNotFind( int iObj1, int iObj2, int * pCut ) { + assert( pCut[0] == 3 ); if ( pCut[3] != iObj1 && pCut[3] != iObj2 ) return 0; if ( pCut[2] != iObj1 && pCut[2] != iObj2 ) return 1; if ( pCut[1] != iObj1 && pCut[1] != iObj2 ) return 2; @@ -162,13 +163,19 @@ static inline int Ree_ManCutTruthOne( int * pCut0, int * pCut ) Truth0 = fComp0 ? ~Truth0 : Truth0; if ( pCut0[0] == 2 ) { - int Truths[3][8] = { - { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-} - { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1} - { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1} - }; - int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7]; - return 0xFF & (fComp0 ? ~Truth : Truth); + if ( pCut[0] == 3 ) + { + int Truths[3][8] = { + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-} + { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1} + { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1} + }; + int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7]; + return 0xFF & (fComp0 ? ~Truth : Truth); + } + assert( pCut[0] == 2 ); + assert( pCut[1] == pCut0[1] && pCut[2] == pCut0[2] ); + return pCut0[pCut0[0]+1]; } if ( pCut0[0] == 1 ) { @@ -236,10 +243,10 @@ int Ree_ObjComputeTruth( Gia_Man_t * p, int iObj, int * pCut ) SeeAlso [] ***********************************************************************/ -void Ree_ManCutPrint( int * pCut, int Count, word Truth ) +void Ree_ManCutPrint( int * pCut, int Count, word Truth, int iObj ) { int c; - printf( "%d : ", Count ); + printf( "%d : %d : ", Count, iObj ); for ( c = 1; c <= pCut[0]; c++ ) printf( "%3d ", pCut[c] ); for ( ; c <= 4; c++ ) @@ -290,7 +297,7 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I Vec_IntPushThree( vData, iObj, Value, TruthC ); } if ( fVerbose ) - Ree_ManCutPrint( pCut, ++Count, TruthC ); + Ree_ManCutPrint( pCut, ++Count, TruthC, iObj ); } if ( !vXors ) return; diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index fef36923..295fd738 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -392,7 +392,7 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - Acec_TreeFilterTrees( p, vAdds, vTrees ); + //Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -478,7 +478,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, j, k, Box, Rank; + int i, j, k, Box, Rank, Count = 0; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -532,6 +532,30 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) Vec_IntSort( vLevel, 0 ); + //return pBox; + // push literals forward + //Vec_WecPrint( pBox->vLeafLits, 0 ); + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + { + int This, Prev = Vec_IntEntry(vLevel, 0); + Vec_IntForEachEntryStart( vLevel, This, j, 1 ) + { + if ( Prev != This ) + { + Prev = This; + continue; + } + if ( i+1 >= Vec_WecSize(pBox->vLeafLits) ) + continue; + Vec_IntPushOrder( Vec_WecEntry(pBox->vLeafLits, i+1), This ); + Vec_IntDrop( vLevel, j-- ); + Vec_IntDrop( vLevel, j-- ); + Prev = -1; + Count++; + } + } + printf( "Pushed forward %d input literals.\n", Count ); + //Vec_WecPrint( pBox->vLeafLits, 0 ); return pBox; } void Acec_CreateBoxTest( Gia_Man_t * p ) -- cgit v1.2.3 From 153b71c1403ed79d7650ad702bb343e0490e36c9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 15 Jan 2017 20:59:59 +0700 Subject: Updates to arithmetic verification. --- src/aig/gia/gia.h | 2 + src/aig/gia/giaDup.c | 65 ++++++++++++++++++++++ src/aig/gia/giaShow.c | 13 ++++- src/base/abci/abc.c | 54 +++++++++++++++++- src/misc/vec/vecWec.h | 12 ++++ src/proof/acec/acec.h | 2 + src/proof/acec/acecCl.c | 88 +++++++++++++++++++++++++++++ src/proof/acec/acecCore.c | 124 ++++++++++++++++++++++++++++++++++++++--- src/proof/acec/acecInt.h | 2 + src/proof/acec/acecRe.c | 5 ++ src/proof/acec/acecTree.c | 138 +++++++++++++++++++++++++++++++++++++++++----- src/proof/acec/acecUtil.c | 23 ++++++++ 12 files changed, 501 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index dc6c679a..3bc97e6b 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1242,6 +1242,8 @@ extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias ); extern Gia_Man_t * Gia_ManDupWithConstraints( Gia_Man_t * p, Vec_Int_t * vPoTypes ); extern Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis ); extern Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrimPis ); +extern Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level ); +extern Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level ); extern Gia_Man_t * Gia_ManDupOneHot( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupLevelized( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupFromVecs( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index cdb6a208..b0ba3472 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3045,6 +3045,71 @@ Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrim Vec_PtrFree( vRoots ); return pNew; +} +void Gia_ManDupAndConesLimit_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( ~pObj->Value ) + return; + if ( !Gia_ObjIsAnd(pObj) || Gia_ObjLevel(p, pObj) < Level ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + //printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); + return; + } + Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level ); + Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); +} +Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level ) +{ + Gia_Man_t * pNew; + int i; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManLevelNum( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < nAnds; i++ ) + Gia_ManDupAndConesLimit_rec( pNew, p, pAnds[i], Level ); + for ( i = 0; i < nAnds; i++ ) + Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value ); + return pNew; +} + +void Gia_ManDupAndConesLimit2_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( ~pObj->Value ) + return; + if ( !Gia_ObjIsAnd(pObj) || Level <= 0 ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + //printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); + return; + } + Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level-1 ); + Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level-1 ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj ); +} +Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level ) +{ + Gia_Man_t * pNew; + int i; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < nAnds; i++ ) + Gia_ManDupAndConesLimit2_rec( pNew, p, pAnds[i], Level ); + for ( i = 0; i < nAnds; i++ ) + Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value ); + return pNew; + } /**Function************************************************************* diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 4dd85aab..4deebd7a 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -1014,16 +1014,23 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds ) +Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds, Vec_Int_t * vBold ) { - Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + Vec_Bit_t * vIsBold = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i, Entry; + if ( vBold ) + Vec_IntForEachEntry( vBold, Entry, i ) + Vec_BitWriteEntry( vIsBold, Entry, 1 ); for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { if ( fFadds && Vec_IntEntry(vAdds, 6*i+2) == 0 ) continue; + if ( Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+4)) ) + continue; Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i ); Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i ); } + Vec_BitFree( vIsBold ); return vMapAdds; } Vec_Int_t * Gia_ShowMapXors( Gia_Man_t * p, Vec_Int_t * vXors ) @@ -1105,7 +1112,7 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v ***********************************************************************/ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds ) { - Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds ); + Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds, vBold ); Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors ); Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors ); Gia_WriteDotAig( p, pFileName, vBold, vAdds, vXors, vMapAdds, vMapXors, vOrder ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 9db3d7d6..58a14e81 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -482,6 +482,7 @@ static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Decla ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1126,6 +1127,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&decla", Abc_CommandAbc9Decla, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 ); @@ -40788,6 +40790,57 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Decla( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + int c, fBooth = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fBooth ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Decla(): There is no AIG.\n" ); + return 0; + } + pTemp = Acec_ManDecla( pAbc->pGia, fBooth, fVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &decla [-bvh]\n" ); + Abc_Print( -2, "\t removes carry look ahead adders\n" ); + Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + /**Function************************************************************* Synopsis [] @@ -42690,7 +42743,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); - Acec_MultFindPPsTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h index 8180e984..c8c89701 100644 --- a/src/misc/vec/vecWec.h +++ b/src/misc/vec/vecWec.h @@ -561,6 +561,18 @@ static inline void Vec_WecPrint( Vec_Wec_t * p, int fSkipSingles ) printf( " }\n" ); } } +static inline void Vec_WecPrintLits( Vec_Wec_t * p ) +{ + Vec_Int_t * vVec; + int i, k, iLit; + Vec_WecForEachLevel( p, vVec, i ) + { + printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); + Vec_IntForEachEntry( vVec, iLit, k ) + printf( " %c%d", Abc_LitIsCompl(iLit) ? '-' : '+', Abc_Lit2Var(iLit) ); + printf( " }\n" ); + } +} /**Function************************************************************* diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h index 5a24bec7..fcbd32df 100644 --- a/src/proof/acec/acec.h +++ b/src/proof/acec/acec.h @@ -66,6 +66,8 @@ struct Acec_ParCec_t_ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== acecCl.c ========================================================*/ +extern Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ); /*=== acecCore.c ========================================================*/ extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ); extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ); diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 145f2e0b..6a5f4040 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -335,6 +335,94 @@ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 ); + Vec_Int_t * vLevel; + int i, k, iLit; + Vec_WecPrintLits( pBox->vRootLits ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + { + int In[3] = {0}, Out[2]; + assert( Vec_IntSize(vLevel) > 0 ); + assert( Vec_IntSize(vLevel) <= 3 ); + if ( Vec_IntSize(vLevel) == 1 ) + { + Vec_IntPush( vRes, Vec_IntEntry(vLevel, 0) ); + continue; + } + Vec_IntForEachEntry( vLevel, iLit, k ) + In[k] = iLit; + Acec_InsertFadd( p, In, Out ); + Vec_IntPush( vRes, Out[0] ); + if ( i+1 < Vec_WecSize(pBox->vRootLits) ) + Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] ); + else + Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] ); + } + assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) ); + Vec_IntShrink( vRes, Gia_ManCoNum(p) ); + return vRes; +} +Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; int i; + assert( Gia_ManCoNum(p) == Vec_IntSize(vRes) ); + // create new manager + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManSetPhase( p ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + { + int iLit = Vec_IntEntry( vRes, i ); + int Phase1 = Gia_ObjPhase(pObj); + int Phase2 = Abc_LitIsCompl(iLit) ^ Gia_ObjPhase(Gia_ManObj(p, Abc_Lit2Var(iLit))); + int iLitNew = Abc_Var2Lit( Abc_Lit2Var(iLit), Phase1 ^ Phase2 ); + pObj->Value = Gia_ManAppendCo( pNew, iLitNew ); + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} +Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) +{ + int status = -1; + abctime clk = Abc_Clock(); + Gia_Man_t * pNew = NULL; + Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL; + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Vec_Int_t * vResult; + Vec_BitFreeP( &vIgnore ); + if ( pBox == NULL ) // cannot match + { + printf( "Cannot find arithmetic boxes.\n" ); + return Gia_ManDup( pGia ); + } + vResult = Acec_RewriteTop( pGia, pBox ); + pNew = Acec_RewriteReplace( pGia, vResult ); + Vec_IntFree( vResult ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 6b631a1b..4fddcfab 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define TRUTH_UNUSED 0x1234567812345678 + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -59,6 +61,79 @@ void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p ) p->iOutFail = -1; // the number of failed output } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_VerifyClasses( Gia_Man_t * p, Vec_Wec_t * vLits, Vec_Wec_t * vReprs ) +{ + Vec_Ptr_t * vFunc = Vec_PtrAlloc( Vec_WecSize(vLits) ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, j, k, Entry, Entry2, nOvers = 0, nErrors = 0; + Vec_WecForEachLevel( vLits, vLevel, i ) + { + Vec_Wrd_t * vTruths = Vec_WrdAlloc( Vec_IntSize(vLevel) ); + Vec_IntForEachEntry( vLevel, Entry, k ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); + if ( Vec_IntSize(vSupp) > 6 ) + { + nOvers++; + Vec_WrdPush( vTruths, TRUTH_UNUSED ); + continue; + } + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + { + nOvers++; + Vec_WrdPush( vTruths, TRUTH_UNUSED ); + continue; + } + Vec_WrdPush( vTruths, Truth ); + } + Vec_PtrPush( vFunc, vTruths ); + } + if ( nOvers ) + printf( "Detected %d oversize support nodes.\n", nOvers ); + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + // verify the classes + Vec_WecForEachLevel( vReprs, vLevel, i ) + { + Vec_Wrd_t * vTruths = (Vec_Wrd_t *)Vec_PtrEntry( vFunc, i ); + Vec_IntForEachEntry( vLevel, Entry, k ) + Vec_IntForEachEntryStart( vLevel, Entry2, j, k+1 ) + { + word Truth = Vec_WrdEntry( vTruths, k ); + word Truth2 = Vec_WrdEntry( vTruths, j ); + if ( Entry == Entry2 ) + { + nErrors++; + if ( Truth != Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED ) + printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j ); + } + if ( Entry == Abc_LitNot(Entry2) ) + { + nErrors++; + if ( Truth != ~Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED ) + printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j ); + } + } + } + if ( nErrors ) + printf( "Total errors in equivalence classes = %d.\n", nErrors ); + Vec_VecFree( (Vec_Vec_t *)vFunc ); +} + /**Function************************************************************* Synopsis [] @@ -148,13 +223,15 @@ void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits ) } void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose ) { - Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); - Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vSupp; + Vec_Wrd_t * vTemp; Vec_Int_t * vLevel; int i, k, Entry; printf( "Leaf literals and their classes:\n" ); Vec_WecForEachLevel( vLits, vLevel, i ) { + if ( Vec_IntSize(vLevel) == 0 ) + continue; printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, Entry, k ) printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) ); @@ -162,13 +239,25 @@ void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits } if ( !fVerbose ) return; + vSupp = Vec_IntAlloc( 100 ); + vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_WecForEachLevel( vLits, vLevel, i ) { - if ( i != 20 ) + //if ( i != 20 ) + // continue; + if ( Vec_IntSize(vLevel) == 0 ) continue; Vec_IntForEachEntry( vLevel, Entry, k ) { word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp ); +/* + { + int iObj = Abc_Lit2Var(Entry); + Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 ); + Gia_ManShow( pGia0, NULL, 0, 0, 0 ); + Gia_ManStop( pGia0 ); + } +*/ printf( "Rank = %4d : ", i ); printf( "Obj = %4d ", Abc_Lit2Var(Entry) ); if ( Vec_IntSize(vSupp) > 6 ) @@ -218,7 +307,7 @@ int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) Vec_IntFree( vRes ); return nCommon; } -void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) +void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) { Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 ); @@ -229,14 +318,24 @@ void Acec_MatchCheckShift( Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * v { Vec_WecInsertLevel( vLits0, 0 ); Vec_WecInsertLevel( vRoots0, 0 ); + printf( "Shifted one level up.\n" ); } else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) { Vec_WecInsertLevel( vLits1, 0 ); Vec_WecInsertLevel( vRoots1, 0 ); + printf( "Shifted one level down.\n" ); } - Vec_WecPrint( vRes0, 0 ); - Vec_WecPrint( vRes1, 0 ); + //printf( "Input literals:\n" ); + //Vec_WecPrintLits( vLits0 ); + printf( "Equiv classes:\n" ); + Vec_WecPrintLits( vRes0 ); + //printf( "Input literals:\n" ); + //Vec_WecPrintLits( vLits1 ); + printf( "Equiv classes:\n" ); + Vec_WecPrintLits( vRes1 ); + //Acec_VerifyClasses( pGia0, vLits0, vRes0 ); + //Acec_VerifyClasses( pGia1, vLits1, vRes1 ); Vec_WecFree( vRes0 ); Vec_WecFree( vRes1 ); } @@ -250,10 +349,14 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) ); Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i ) Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) ); - Acec_MatchCheckShift( pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); + Acec_MatchCheckShift( pBox0->pGia, pBox1->pGia, pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits ); //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox0->vRootLits ); + printf( "Outputs:\n" ); + Vec_WecPrintLits( pBox1->vRootLits ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); @@ -350,8 +453,11 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // remove the last output - //Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); - //Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); + Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 ); + Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 ); + + Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-2, 0 ); + Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-2, 0 ); } // solve regular CEC problem Cec_ManCecSetDefaultParams( pCecPars ); diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index cc5786bb..c49945db 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -71,8 +71,10 @@ extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdd extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ); /*=== acecNorm.c ========================================================*/ +extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ +extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ); extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c index 7f87df85..5e5ca688 100644 --- a/src/proof/acec/acecRe.c +++ b/src/proof/acec/acecRe.c @@ -450,6 +450,7 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose Hash_IntManStop( pHash ); Ree_ManRemoveTrivial( p, vAdds ); Ree_ManRemoveContained( p, vAdds ); + //Ree_ManPrintAdders( vAdds, 1 ); return vAdds; } @@ -523,6 +524,10 @@ void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds ) { pObjX = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+3) ); pObjM = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+4) ); + // rule out if MAJ is a fanout of XOR + //if ( pObjX == Gia_ObjFanin0(pObjM) || pObjX == Gia_ObjFanin1(pObjM) ) + // continue; + // rule out if MAJ is a fanin of XOR and has no other fanouts if ( (pObjM == Gia_ObjFanin0(pObjX) || pObjM == Gia_ObjFanin1(pObjX)) && Gia_ObjRefNum(p, pObjM) == 1 ) continue; } diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 295fd738..2b356574 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -64,6 +64,30 @@ void Acec_BoxFreeP( Acec_Box_t ** ppBox ) *ppBox = NULL; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_VerifyBoxLeaves( Acec_Box_t * pBox, Vec_Bit_t * vIgnore ) +{ + Vec_Int_t * vLevel; + int i, k, iLit, Count = 0; + if ( vIgnore == NULL ) + return; + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( Gia_ObjIsAnd(Gia_ManObj(pBox->pGia, Abc_Lit2Var(iLit))) && !Vec_BitEntry(vIgnore, Abc_Lit2Var(iLit)) ) + printf( "Internal node %d of rank %d is not part of PPG.\n", Abc_Lit2Var(iLit), i ), Count++; + printf( "Detected %d suspicious leaves.\n", Count ); +} + /**Function************************************************************* Synopsis [Filters trees by removing TFO of roots.] @@ -103,6 +127,18 @@ void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) // remove those that overlap with roots Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { +/* + if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 ) + { + printf( "**** removing special one \n" ); + continue; + } + if ( Vec_IntEntry(vAdds, 6*Box+3) == 48 && Vec_IntEntry(vAdds, 6*Box+4) == 49 ) + { + printf( "**** removing special one \n" ); + continue; + } +*/ if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) { printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); @@ -123,6 +159,73 @@ void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees Acec_TreeFilterOne( p, vAdds, vLevel ); } +/**Function************************************************************* + + Synopsis [Filters trees by removing TFO of roots.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_TreeMarkTFI_rec( Gia_Man_t * p, int Id, Vec_Bit_t * vMarked ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, Id); + if ( Vec_BitEntry(vMarked, Id) ) + return; + Vec_BitWriteEntry( vMarked, Id, 1 ); + if ( !Gia_ObjIsAnd(pObj) ) + return; + Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId0(pObj, Id), vMarked ); + Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId1(pObj, Id), vMarked ); +} +void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) +{ + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ; + Gia_Obj_t * pObj; + int i, k = 0, Box, Rank; + // mark leaves + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + } + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+3), 0 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4), 0 ); + } + // mark TFI of leaves + Gia_ManForEachAnd( p, pObj, i ) + if ( Vec_BitEntry(vIsLeaf, i) ) + Acec_TreeMarkTFI_rec( p, i, vMarked ); + // remove those that overlap with the marked TFI + Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) + { + if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) ) + { + printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank ); + continue; + } + Vec_IntWriteEntry( vTree, k++, Box ); + Vec_IntWriteEntry( vTree, k++, Rank ); + } + Vec_IntShrink( vTree, k ); + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vMarked ); +} +void Acec_TreeFilterTrees2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees ) +{ + Vec_Int_t * vLevel; + int i; + Vec_WecForEachLevel( vTrees, vLevel, i ) + Acec_TreeFilterOne2( p, vAdds, vLevel ); +} + /**Function************************************************************* Synopsis [] @@ -392,7 +495,7 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - //Acec_TreeFilterTrees( p, vAdds, vTrees ); + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -437,20 +540,11 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) { printf( " %4d : %2d {", i, Vec_IntSize(vLevel) ); Vec_IntForEachEntry( vLevel, iBox, k ) + { printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox, Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) ); - printf( " }\n" ); - } -} -void Vec_WecPrintLits( Vec_Wec_t * p ) -{ - Vec_Int_t * vVec; - int i, k, Entry; - Vec_WecForEachLevel( p, vVec, i ) - { - printf( " %4d : %2d {", i, Vec_IntSize(vVec) ); - Vec_IntForEachEntry( vVec, Entry, k ) - printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) ); + //printf( "(%d,%d,%d)", Vec_IntEntry(vAdds, 6*iBox+0), Vec_IntEntry(vAdds, 6*iBox+1), Vec_IntEntry(vAdds, 6*iBox+2) ); + } printf( " }\n" ); } } @@ -505,7 +599,10 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i ) Vec_IntForEachEntry( vLevel, Box, k ) if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + { + //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box ); Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit ); + } Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds ); Vec_BitFree( vVisit ); @@ -521,7 +618,14 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); for ( k = 3; k < 5; k++ ) if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + { + //if ( Vec_IntEntry(vAdds, 6*Box+k) == 10942 ) + //{ + // printf( "++++++++++++ Skipping special\n" ); + // continue; + //} Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + } if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) ) Vec_WecPush( pBox->vLeafLits, i, 1 ); } @@ -531,8 +635,9 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) - Vec_IntSort( vLevel, 0 ); + Vec_IntSort( vLevel, 1 ); //return pBox; +/* // push literals forward //Vec_WecPrint( pBox->vLeafLits, 0 ); Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) @@ -555,6 +660,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree } } printf( "Pushed forward %d input literals.\n", Count ); +*/ //Vec_WecPrint( pBox->vLeafLits, 0 ); return pBox; } @@ -607,13 +713,17 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) + { pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); + Acec_VerifyBoxLeaves( pBox, vIgnore ); + } if ( pBox )//&& fVerbose ) printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) Acec_PrintBox( pBox, vAdds ); + //Acec_PrintAdders( pBox0->vAdds, vAdds ); //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); Vec_IntFree( vAdds ); diff --git a/src/proof/acec/acecUtil.c b/src/proof/acec/acecUtil.c index 191856cf..be12afef 100644 --- a/src/proof/acec/acecUtil.c +++ b/src/proof/acec/acecUtil.c @@ -90,6 +90,29 @@ void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ) Vec_IntFree( vXors ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupTopMostRange( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Vec_Int_t * vTops = Vec_IntAlloc( 10 ); + int i; + for ( i = 45; i < 52; i++ ) + Vec_IntPush( vTops, Gia_ObjId( p, Gia_ObjFanin0(Gia_ManCo(p, i)) ) ); + pNew = Gia_ManDupAndConesLimit( p, Vec_IntArray(vTops), Vec_IntSize(vTops), 100 ); + Vec_IntFree( vTops ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 7457b8a64ae92880b8c04f1128298ee51becb76f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 16 Jan 2017 22:36:23 +0700 Subject: Updates to arithmetic verification. --- src/proof/acec/acecCl.c | 33 +++++++++++++++++++++++---------- src/proof/acec/acecCore.c | 20 ++++++++++---------- src/proof/acec/acecInt.h | 2 +- src/proof/acec/acecNorm.c | 2 +- src/proof/acec/acecTree.c | 28 ++++++++++++++++++++-------- 5 files changed, 55 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c index 6a5f4040..6185677b 100644 --- a/src/proof/acec/acecCl.c +++ b/src/proof/acec/acecCl.c @@ -350,9 +350,15 @@ Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) { Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 ); Vec_Int_t * vLevel; - int i, k, iLit; - Vec_WecPrintLits( pBox->vRootLits ); - Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + int i, k, iStart, iLit, Driver, Count = 0; + // determine how much to shift + Driver = Gia_ObjFaninId0p( p, Gia_ManCo(p, 0) ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, iStart ) + if ( Abc_Lit2Var(Vec_IntEntry(vLevel,0)) == Driver ) + break; + assert( iStart < Gia_ManCoNum(p) ); + //Vec_WecPrintLits( pBox->vRootLits ); + Vec_WecForEachLevelStart( pBox->vRootLits, vLevel, i, iStart ) { int In[3] = {0}, Out[2]; assert( Vec_IntSize(vLevel) > 0 ); @@ -370,9 +376,11 @@ Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox ) Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] ); else Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] ); + Count++; } assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) ); Vec_IntShrink( vRes, Gia_ManCoNum(p) ); + printf( "Added %d adders for replace CLAs. ", Count ); return vRes; } Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) @@ -384,7 +392,6 @@ Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Gia_ManSetPhase( p ); Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) @@ -394,22 +401,26 @@ Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes ) Gia_ManForEachCo( p, pObj, i ) { int iLit = Vec_IntEntry( vRes, i ); - int Phase1 = Gia_ObjPhase(pObj); - int Phase2 = Abc_LitIsCompl(iLit) ^ Gia_ObjPhase(Gia_ManObj(p, Abc_Lit2Var(iLit))); - int iLitNew = Abc_Var2Lit( Abc_Lit2Var(iLit), Phase1 ^ Phase2 ); - pObj->Value = Gia_ManAppendCo( pNew, iLitNew ); + Gia_Obj_t * pRepr = Gia_ManObj( p, Abc_Lit2Var(iLit) ); + pObj->Value = Gia_ManAppendCo( pNew, pRepr->Value ); } + // set correct phase + Gia_ManSetPhase( p ); + Gia_ManSetPhase( pNew ); + Gia_ManForEachCo( pNew, pObj, i ) + if ( Gia_ObjPhase(pObj) != Gia_ObjPhase(Gia_ManCo(p, i)) ) + Gia_ObjFlipFaninC0( pObj ); + // remove dangling nodes pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; } Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) { - int status = -1; abctime clk = Abc_Clock(); Gia_Man_t * pNew = NULL; Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL; - Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose ); Vec_Int_t * vResult; Vec_BitFreeP( &vIgnore ); if ( pBox == NULL ) // cannot match @@ -418,8 +429,10 @@ Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose ) return Gia_ManDup( pGia ); } vResult = Acec_RewriteTop( pGia, pBox ); + Acec_BoxFreeP( &pBox ); pNew = Acec_RewriteReplace( pGia, vResult ); Vec_IntFree( vResult ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return pNew; } diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 4fddcfab..06385f3c 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -328,12 +328,12 @@ void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLi } //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits0 ); - printf( "Equiv classes:\n" ); - Vec_WecPrintLits( vRes0 ); + //printf( "Equiv classes:\n" ); + //Vec_WecPrintLits( vRes0 ); //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits1 ); - printf( "Equiv classes:\n" ); - Vec_WecPrintLits( vRes1 ); + //printf( "Equiv classes:\n" ); + //Vec_WecPrintLits( vRes1 ); //Acec_VerifyClasses( pGia0, vLits0, vRes0 ); //Acec_VerifyClasses( pGia1, vLits1, vRes1 ); Vec_WecFree( vRes0 ); @@ -353,10 +353,10 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 ); - printf( "Outputs:\n" ); - Vec_WecPrintLits( pBox0->vRootLits ); - printf( "Outputs:\n" ); - Vec_WecPrintLits( pBox1->vRootLits ); + //printf( "Outputs:\n" ); + //Vec_WecPrintLits( pBox0->vRootLits ); + //printf( "Outputs:\n" ); + //Vec_WecPrintLits( pBox1->vRootLits ); // reorder nodes to have the same order assert( pBox0->vShared == NULL ); @@ -438,8 +438,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, pPars->fVerbose ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, pPars->fVerbose ); + Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose ); Vec_BitFreeP( &vIgnore0 ); Vec_BitFreeP( &vIgnore1 ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index c49945db..b8ec2455 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -75,7 +75,7 @@ extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ); -extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ); +extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 0d209524..6b36589c 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -201,7 +201,7 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose ) { Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL; - Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, fVerbose ); + Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose ); Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 ); Acec_BoxFreeP( &pBox ); Vec_BitFreeP( &vIgnore ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 2b356574..fe5ca01b 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -127,6 +127,10 @@ void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) // remove those that overlap with roots Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { + // special case of the first bit +// if ( i == 0 ) +// continue; + /* if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 ) { @@ -415,7 +419,7 @@ Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * v int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { - if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) && Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); @@ -468,7 +472,7 @@ void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound ); Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound ); } -Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore ) +Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut ) { Vec_Wec_t * vTrees = Vec_WecAlloc( 10 ); Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore ); @@ -495,7 +499,10 @@ Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vI Vec_BitFree( vFound ); Vec_IntFree( vMap ); // filter trees - Acec_TreeFilterTrees( p, vAdds, vTrees ); + if ( fFilterIn ) + Acec_TreeFilterTrees2( p, vAdds, vTrees ); + else if ( fFilterOut ) + Acec_TreeFilterTrees( p, vAdds, vTrees ); // sort by size Vec_WecSort( vTrees, 1 ); return vTrees; @@ -511,7 +518,7 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Vec_WecPrint( vTrees, 0 ); @@ -572,7 +579,7 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel, * vMap; - int i, j, k, Box, Rank, Count = 0; + int i, j, k, Box, Rank;//, Count = 0; Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); pBox->pGia = p; @@ -583,6 +590,11 @@ Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree // collect boxes; mark inputs/outputs Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { +// if ( 37 == Box && 6 == Rank ) +// { +// printf( "Skipping one adder...\n" ); +// continue; +// } Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); @@ -677,7 +689,7 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); clk = Abc_Clock(); - vTrees = Acec_TreeFindTrees( p, vAdds, NULL ); + vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 ); printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); //Vec_WecPrint( vTrees, 0 ); @@ -707,11 +719,11 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fVerbose ) +Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose ) { Acec_Box_t * pBox = NULL; Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose ); - Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore ); + Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore, fFilterIn, fFilterOut ); if ( vTrees && Vec_WecSize(vTrees) > 0 ) { pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) ); -- cgit v1.2.3 From b193ef056d2fb11d5e24b7e4f250e07d069c2ae2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 19 Jan 2017 13:24:47 +0800 Subject: Updates to arithmetic verification. --- src/proof/acec/acecCore.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-- src/proof/acec/acecNorm.c | 51 ++++++++++++++++++++++++----------------- src/proof/acec/acecTree.c | 5 +++- 3 files changed, 90 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index 06385f3c..a2341704 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -307,6 +307,50 @@ int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift ) Vec_IntFree( vRes ); return nCommon; } +void Vec_IntInsertOrder( Vec_Int_t * vLits, Vec_Int_t * vClasses, int Lit, int Class ) +{ + int i; + for ( i = Vec_IntSize(vClasses)-1; i >= 0; i-- ) + if ( Vec_IntEntry(vClasses,i) >= Class ) + break; + Vec_IntInsert( vLits, i+1, Lit ); + Vec_IntInsert( vClasses, i+1, Class ); +} +void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses ) +{ + Vec_Int_t * vLevel1, * vLevel2; + int i, k, Prev, This, Entry; + Vec_WecForEachLevel( vLits, vLevel1, i ) + { + if ( i == Vec_WecSize(vLits) - 1 ) + break; + vLevel2 = Vec_WecEntry(vClasses, i); + assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) ); + Prev = -1; + Vec_IntForEachEntry( vLevel2, This, k ) + { + if ( Prev != This ) + { + Prev = This; + continue; + } + Prev = -1; + Entry = Vec_IntEntry( vLevel1, k ); + + Vec_IntDrop( vLevel1, k ); + Vec_IntDrop( vLevel2, k-- ); + + Vec_IntDrop( vLevel1, k ); + Vec_IntDrop( vLevel2, k-- ); + + Vec_IntInsertOrder( Vec_WecEntry(vLits, i+1), Vec_WecEntry(vClasses, i+1), Entry, This ); + + assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) ); + assert( Vec_IntSize(Vec_WecEntry(vLits, i+1)) == Vec_IntSize(Vec_WecEntry(vClasses, i+1)) ); + } + } +} + void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) { Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 ); @@ -318,14 +362,20 @@ void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLi { Vec_WecInsertLevel( vLits0, 0 ); Vec_WecInsertLevel( vRoots0, 0 ); + Vec_WecInsertLevel( vRes0, 0 ); printf( "Shifted one level up.\n" ); } else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon ) { Vec_WecInsertLevel( vLits1, 0 ); Vec_WecInsertLevel( vRoots1, 0 ); + Vec_WecInsertLevel( vRes1, 0 ); printf( "Shifted one level down.\n" ); } + Acec_MoveDuplicates( vLits0, vRes0 ); + Acec_MoveDuplicates( vLits1, vRes1 ); + + //Vec_WecPrintLits( vLits1 ); //printf( "Input literals:\n" ); //Vec_WecPrintLits( vLits0 ); //printf( "Equiv classes:\n" ); @@ -410,6 +460,10 @@ int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 ) printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) ); printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) ); + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vShared, Vec_IntArray(vMap0), 0 ); + //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vShared, Vec_IntArray(vMap1), 0 ); + //printf( "\n" ); + //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 ); //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 ); @@ -448,8 +502,8 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" ); else { - pGia0n = Acec_InsertBox( pBox0, 1 ); - pGia1n = Acec_InsertBox( pBox1, 1 ); + pGia0n = Acec_InsertBox( pBox0, 0 ); + pGia1n = Acec_InsertBox( pBox1, 0 ); printf( "Matching of adder trees in LHS and RHS succeeded. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // remove the last output diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c index 6b36589c..f2acb37b 100644 --- a/src/proof/acec/acecNorm.c +++ b/src/proof/acec/acecNorm.c @@ -76,9 +76,19 @@ Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap ) { if ( Vec_IntSize(vLevel) == 2 ) Vec_IntPush( vLevel, 0 ); - In[2] = Vec_IntPop( vLevel ); - In[1] = Vec_IntPop( vLevel ); - In[0] = Vec_IntPop( vLevel ); + //In[2] = Vec_IntPop( vLevel ); + //In[1] = Vec_IntPop( vLevel ); + //In[0] = Vec_IntPop( vLevel ); + + In[0] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + + In[1] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + + In[2] = Vec_IntEntry( vLevel, 0 ); + Vec_IntDrop( vLevel, 0 ); + Acec_InsertFadd( pNew, In, Out ); Vec_IntPush( vLevel, Out[0] ); if ( i+1 < Vec_WecSize(vLeafMap) ) @@ -114,11 +124,22 @@ int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) ); return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) )); } -Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits ) +Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Int_t * vRootLits ) { Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) ); Vec_Int_t * vLevel, * vRootRanks; int i, k, iLit, iLitNew; + // add roo literals + if ( vRootLits ) + Vec_IntForEachEntry( vRootLits, iLit, i ) + { + if ( i < Vec_WecSize(vLeafMap) ) + vLevel = Vec_WecEntry(vLeafMap, i); + else + vLevel = Vec_WecPushLevel(vLeafMap); + Vec_IntPush( vLevel, iLit ); + } + // add other literals Vec_WecForEachLevel( vLeafLits, vLevel, i ) Vec_IntForEachEntry( vLevel, iLit, k ) { @@ -137,7 +158,7 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) Gia_Man_t * p = pBox->pGia; Gia_Man_t * pNew; Gia_Obj_t * pObj; - Vec_Int_t * vRootRanks, * vLevel; + Vec_Int_t * vRootRanks, * vLevel, * vTemp; int i, k, iLit, iLitNew; pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); @@ -148,26 +169,14 @@ Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ) pObj->Value = Gia_ManAppendCi( pNew ); // implement tree if ( fAll ) - vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits, NULL ); else { - Vec_Wec_t * vLeafLits; assert( pBox->vShared != NULL ); assert( pBox->vUnique != NULL ); - vRootRanks = Acec_BuildTree( p, p, pBox->vShared ); - // add these roots to the unique ones - vLeafLits = Vec_WecDup( pBox->vUnique ); - Vec_IntForEachEntry( vRootRanks, iLit, i ) - { - if ( i < Vec_WecSize(vLeafLits) ) - vLevel = Vec_WecEntry(vLeafLits, i); - else - vLevel = Vec_WecPushLevel(vLeafLits); - Vec_IntPush( vLevel, iLit ); - } - Vec_IntFree( vRootRanks ); - vRootRanks = Acec_BuildTree( pNew, p, vLeafLits ); - Vec_WecFree( vLeafLits ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vShared, NULL ); + vRootRanks = Acec_BuildTree( pNew, p, pBox->vUnique, vTemp = vRootRanks ); + Vec_IntFree( vTemp ); } // update polarity of literals Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index fe5ca01b..2461c89b 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -207,6 +207,9 @@ void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree ) Gia_ManForEachAnd( p, pObj, i ) if ( Vec_BitEntry(vIsLeaf, i) ) Acec_TreeMarkTFI_rec( p, i, vMarked ); + // additional one +//if ( 10942 < Gia_ManObjNum(p) ) +// Acec_TreeMarkTFI_rec( p, 10942, vMarked ); // remove those that overlap with the marked TFI Vec_IntForEachEntryDouble( vTree, Box, Rank, i ) { @@ -419,7 +422,7 @@ Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * v int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { - if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) && Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) + if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) ) continue; Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 ); Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 ); -- cgit v1.2.3 From a28be94ac79c0cbb0960565573985838d7a27a79 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Jan 2017 11:59:01 +0800 Subject: Small fixes and a change to &cec to allow two files names given as command-line arguments. --- src/aig/gia/giaIf.c | 16 +++--- src/aig/gia/giaTim.c | 2 + src/base/abci/abc.c | 121 +++++++++++++++++++++++++++++++--------------- src/base/abci/abcVerify.c | 14 ++++-- 4 files changed, 101 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index ac748f8c..ab80a762 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -544,20 +544,20 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) fprintf( pTable, "%d ", Gia_ManAndNum(p) ); fprintf( pTable, "%d ", nLuts ); fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); - fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); - fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); - fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); + //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + //fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } else { - printf( "This part of the code is currently not used.\n" ); - assert( 0 ); + //printf( "This part of the code is currently not used.\n" ); + //assert( 0 ); fprintf( pTable, " " ); fprintf( pTable, "%d ", nLuts ); - fprintf( pTable, "%d ", LevelMax ); - fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); - fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); + fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); + //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); + //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } diff --git a/src/aig/gia/giaTim.c b/src/aig/gia/giaTim.c index 71b9a475..29aa93f8 100644 --- a/src/aig/gia/giaTim.c +++ b/src/aig/gia/giaTim.c @@ -584,6 +584,8 @@ int Gia_ManLutLevelWithBoxes( Gia_Man_t * p ) Gia_Obj_t * pObj, * pObjIn; int i, k, j, curCi, curCo, LevelMax; assert( Gia_ManRegNum(p) == 0 ); + if ( pManTime == NULL ) + return Gia_ManLutLevel(p, NULL); // copy const and real PIs Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); Gia_ObjSetLevel( p, Gia_ManConst0(p), 0 ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 58a14e81..806a5de7 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -32927,8 +32927,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) { Cec_ParCec_t ParsCec, * pPars = &ParsCec; FILE * pFile; - Gia_Man_t * pSecond, * pMiter; - char * FileName, * pTemp; + Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; char ** pArgvNew; int c, nArgcNew, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; Cec_ManCecSetDefaultParams( pPars ); @@ -32983,13 +32982,15 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( pAbc->pGia == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no AIG.\n" ); - return 1; - } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; if ( fMiter ) { + if ( pAbc->pGia == NULL || nArgcNew != 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): A miter cannot be given as an argument of command &cec and should be entered using &r.\n" ); + return 1; + } if ( fDualOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) @@ -32998,14 +32999,14 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a double-output miter.\n" ); pAbc->Status = Cec_ManVerify( pAbc->pGia, pPars ); } else { Gia_Man_t * pTemp; if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a single-output miter.\n" ); pTemp = Gia_ManDemiterToDual( pAbc->pGia ); pAbc->Status = Cec_ManVerify( pTemp, pPars ); ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb ); @@ -33014,41 +33015,81 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); return 0; } - - pArgvNew = argv + globalUtilOptind; - nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 1 ) + if ( nArgcNew > 2 ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" ); + return 1; + } + if ( nArgcNew == 2 ) { - if ( pAbc->pGia->pSpec == NULL ) + char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp; + int n; + for ( n = 0; n < 2; n++ ) { - Abc_Print( -1, "File name is not given on the command line.\n" ); - return 1; + // fix the wrong symbol + for ( pTemp = pFileNames[n]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( pFileNames[n], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] ); + if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 ); + if ( pGias[n] == NULL ) + { + Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] ); + return 0; + } } - FileName = pAbc->pGia->pSpec; } else - FileName = pArgvNew[0]; - // fix the wrong symbol - for ( pTemp = FileName; *pTemp; pTemp++ ) - if ( *pTemp == '>' ) - *pTemp = '\\'; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); - if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", FileName ); - Abc_Print( 1, "\n" ); - return 1; - } - fclose( pFile ); - pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); - if ( pSecond == NULL ) { - Abc_Print( -1, "Reading AIGER has failed.\n" ); - return 0; + char * FileName, * pTemp; + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" ); + return 1; + } + pGias[0] = pAbc->pGia; + if ( nArgcNew == 1 ) + FileName = pArgvNew[0]; + else + { + assert( nArgcNew == 0 ); + if ( pAbc->pGia->pSpec == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } + FileName = pAbc->pGia->pSpec; + } + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pGias[1] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } } // compute the miter - pMiter = Gia_ManMiter( pAbc->pGia, pSecond, 0, 1, 0, 0, pPars->fVerbose ); + pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, 1, 0, 0, pPars->fVerbose ); if ( pMiter ) { if ( fDumpMiter ) @@ -33057,10 +33098,12 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0 ); } pAbc->Status = Cec_ManVerify( pMiter, pPars ); - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); Gia_ManStop( pMiter ); } - Gia_ManStop( pSecond ); + if ( pGias[0] != pAbc->pGia ) + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); return 0; usage: @@ -36178,7 +36221,7 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: &satlut [-NICDQ num] [-drwvh]\n" ); - Abc_Print( -2, "\t performs SAT-based remapping of the 4-LUT network\n" ); + Abc_Print( -2, "\t performs SAT-based remapping of the LUT-mapped network\n" ); Abc_Print( -2, "\t-N num : the limit on AIG nodes in the window (num <= 128) [default = %d]\n", nNumber ); Abc_Print( -2, "\t-I num : the limit on the number of improved windows [default = %d]\n", nImproves ); Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nBTLimit ); diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c index 25d1d113..7199c529 100644 --- a/src/base/abci/abcVerify.c +++ b/src/base/abci/abcVerify.c @@ -122,6 +122,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI ***********************************************************************/ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ) { + abctime clk = Abc_Clock(); Prove_Params_t Params, * pParams = &Params; // Fraig_Params_t Params; // Fraig_Man_t * pMan; @@ -170,18 +171,20 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV RetValue = Abc_NtkMiterIsConstant( pMiter ); if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); + printf( "Networks are NOT EQUIVALENT after structural hashing. " ); // report the error pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 ); Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); ABC_FREE( pMiter->pModel ); Abc_NtkDelete( pMiter ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return; } if ( RetValue == 1 ) { - printf( "Networks are equivalent after structural hashing.\n" ); + printf( "Networks are equivalent after structural hashing. " ); Abc_NtkDelete( pMiter ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return; } /* @@ -220,18 +223,19 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV // pParams->fVerbose = 1; RetValue = Abc_NtkIvyProve( &pMiter, pParams ); if ( RetValue == -1 ) - printf( "Networks are undecided (resource limits is reached).\n" ); + printf( "Networks are undecided (resource limits is reached). " ); else if ( RetValue == 0 ) { int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel ); if ( pSimInfo[0] != 1 ) printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" ); else - printf( "Networks are NOT EQUIVALENT.\n" ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_FREE( pSimInfo ); } else - printf( "Networks are equivalent.\n" ); + printf( "Networks are equivalent. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); if ( pMiter->pModel ) Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); Abc_NtkDelete( pMiter ); -- cgit v1.2.3 From cf539dcca475d1c7f862834e8718bb318b54d5fd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Jan 2017 12:48:40 +0800 Subject: Fix mismatch in output formatting. --- src/aig/saig/saigMiter.c | 4 ++-- src/base/abci/abcDar.c | 12 ++++++------ src/proof/cec/cecCec.c | 6 +++--- src/proof/fra/fraCec.c | 6 +++--- src/proof/fra/fraSec.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c index 67aed490..598103de 100644 --- a/src/aig/saig/saigMiter.c +++ b/src/aig/saig/saigMiter.c @@ -1111,12 +1111,12 @@ int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int nFrames, int fVe // report the miter if ( RetValue == 1 ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); if ( pMiterCec->pData == NULL ) printf( "Counter-example is not available.\n" ); diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 9f672485..147f7c2f 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -1946,17 +1946,17 @@ finish: // report the miter if ( RetValue == 1 ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); @@ -3695,17 +3695,17 @@ int Abc_NtkDarInduction( Abc_Ntk_t * pNtk, int nTimeOut, int nFramesMax, int nCo RetValue = Saig_ManInduction( pMan, nTimeOut, nFramesMax, nConfMax, fUnique, fUniqueAll, fGetCex, fVerbose, fVeryVerbose ); if ( RetValue == 1 ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( fGetCex ) diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c index 77a6ed4a..f7e45c57 100644 --- a/src/proof/cec/cecCec.c +++ b/src/proof/cec/cecCec.c @@ -85,7 +85,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime { if ( !fSilent ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } } @@ -93,7 +93,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime { if ( !fSilent ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } if ( pMiterCec->pData == NULL ) @@ -120,7 +120,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime } else if ( !fSilent ) { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); diff --git a/src/proof/fra/fraCec.c b/src/proof/fra/fraCec.c index 130036a6..84f37930 100644 --- a/src/proof/fra/fraCec.c +++ b/src/proof/fra/fraCec.c @@ -547,17 +547,17 @@ int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int n // report the miter if ( RetValue == 1 ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - printf( "Networks are UNDECIDED. " ); + printf( "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); diff --git a/src/proof/fra/fraSec.c b/src/proof/fra/fraSec.c index 06011d2e..7e382fc8 100644 --- a/src/proof/fra/fraSec.c +++ b/src/proof/fra/fraSec.c @@ -606,7 +606,7 @@ finish: { if ( !pParSec->fSilent ) { - printf( "Networks are equivalent. " ); + printf( "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( pParSec->fReportSolution && !pParSec->fRecursive ) @@ -630,7 +630,7 @@ ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( !pParSec->fSilent ) { - printf( "Networks are NOT EQUIVALENT. " ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( pParSec->fReportSolution && !pParSec->fRecursive ) -- cgit v1.2.3 From 51f4dab475af1ffd22d23b5aeb8d7cf243739f75 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:02:19 -0800 Subject: Adding features for invariant minimization. --- src/base/main/mainFrame.c | 4 - src/base/main/mainInt.h | 2 - src/base/wlc/wlcAbc.c | 151 ++++++++++++++++----- src/base/wlc/wlcCom.c | 338 +++++++++++++++++++++++++++++++++++++--------- src/proof/pdr/pdrCore.c | 4 +- src/proof/pdr/pdrInv.c | 228 +++++++++++++++++++++++++++++++ src/proof/pdr/pdrUtil.c | 2 +- 7 files changed, 625 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index 05cb09c1..9647d020 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -95,8 +95,6 @@ void Abc_FrameSetStatus( int Status ) { ABC_FREE( s_Globa void Abc_FrameSetManDsd( void * pMan ) { if (s_GlobalFrame->pManDsd && s_GlobalFrame->pManDsd != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd, 0); s_GlobalFrame->pManDsd = pMan; } void Abc_FrameSetManDsd2( void * pMan ) { if (s_GlobalFrame->pManDsd2 && s_GlobalFrame->pManDsd2 != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd2, 0); s_GlobalFrame->pManDsd2 = pMan; } void Abc_FrameSetInv( Vec_Int_t * vInv ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcInv); s_GlobalFrame->pAbcWlcInv = vInv; } -void Abc_FrameSetCnf( Vec_Int_t * vCnf ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcCnf); s_GlobalFrame->pAbcWlcCnf = vCnf; } -void Abc_FrameSetStr( Vec_Str_t * vStr ) { Vec_StrFreeP(&s_GlobalFrame->pAbcWlcStr); s_GlobalFrame->pAbcWlcStr = vStr; } void Abc_FrameSetJsonStrs( Abc_Nam_t * pStrs ) { Abc_NamDeref( s_GlobalFrame->pJsonStrs ); s_GlobalFrame->pJsonStrs = pStrs; } void Abc_FrameSetJsonObjs( Vec_Wec_t * vObjs ) { Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); s_GlobalFrame->vJsonObjs = vObjs; } @@ -227,8 +225,6 @@ void Abc_FrameDeallocate( Abc_Frame_t * p ) ABC_FREE( p->pCex2 ); ABC_FREE( p->pCex ); Vec_IntFreeP( &p->pAbcWlcInv ); - Vec_IntFreeP( &p->pAbcWlcCnf ); - Vec_StrFreeP( &p->pAbcWlcStr ); Abc_NamDeref( s_GlobalFrame->pJsonStrs ); Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); ABC_FREE( p ); diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index ff59b81a..278a9191 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -129,8 +129,6 @@ struct Abc_Frame_t_ void * pAbc85Delay; void * pAbcWlc; Vec_Int_t * pAbcWlcInv; - Vec_Int_t * pAbcWlcCnf; - Vec_Str_t * pAbcWlcStr; void * pAbcBac; void * pAbcCba; void * pAbcPla; diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 0bf27f7b..1a98fb71 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) +void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose ) { Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; @@ -53,7 +53,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) nRange = Wlc_ObjRange(pObj); for ( k = 0; k < nRange; k++ ) { - nNum = Vec_IntEntry(vInv, nBits + k); + nNum = Vec_IntEntry(vCounts, nBits + k); if ( nNum ) break; } @@ -65,7 +65,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); for ( k = 0; k < nRange; k++ ) { - nNum = Vec_IntEntry( vInv, nBits + k ); + nNum = Vec_IntEntry( vCounts, nBits + k ); if ( nNum == 0 ) continue; printf( " [%d] -> %d", k, nNum ); @@ -73,8 +73,8 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) printf( "\n"); nBits += nRange; } - //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); - assert( Vec_IntSize(vInv) == nBits ); + //printf( "%d %d\n", Vec_IntSize(vCounts), nBits ); + assert( Vec_IntSize(vCounts) == nBits ); } /**Function************************************************************* @@ -88,8 +88,14 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ) +Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) { + extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); + extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ); + + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts ); + Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; Abc_Ntk_t * pMainNtk = NULL; @@ -98,46 +104,69 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, // start the network pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); // duplicate the name and the spec - pMainNtk->pName = Extra_UtilStrsav(pNtk->pName); + pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv"); // create primary inputs - Wlc_NtkForEachCi( pNtk, pObj, i ) + if ( pNtk == NULL ) { - if ( pObj->Type != WLC_OBJ_FO ) - continue; - nRange = Wlc_ObjRange(pObj); - for ( k = 0; k < nRange; k++ ) + int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) ); + Vec_IntForEachEntry( vCounts, Entry, i ) { - nNum = Vec_IntEntry(vInv, nBits + k); - if ( nNum ) - break; + if ( Entry == 0 ) + continue; + pMainObj = Abc_NtkCreatePi( pMainNtk ); + sprintf( Buffer, "pi%d", i ); + Abc_ObjAssignName( pMainObj, Buffer, NULL ); } - if ( k == nRange ) + if ( Abc_NtkPiNum(pMainNtk) != nInputs ) { - nBits += nRange; - continue; + printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" ); + Abc_NtkDelete( pMainNtk ); + return NULL; } - //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); - for ( k = 0; k < nRange; k++ ) + } + else + { + Wlc_NtkForEachCi( pNtk, pObj, i ) { - nNum = Vec_IntEntry( vInv, nBits + k ); - if ( nNum == 0 ) + if ( pObj->Type != WLC_OBJ_FO ) continue; - //printf( " [%d] -> %d", k, nNum ); - pMainObj = Abc_NtkCreatePi( pMainNtk ); - sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); - Abc_ObjAssignName( pMainObj, Buffer, NULL ); - + nRange = Wlc_ObjRange(pObj); + for ( k = 0; k < nRange; k++ ) + { + nNum = Vec_IntEntry(vCounts, nBits + k); + if ( nNum ) + break; + } + if ( k == nRange ) + { + nBits += nRange; + continue; + } + //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); + for ( k = 0; k < nRange; k++ ) + { + nNum = Vec_IntEntry( vCounts, nBits + k ); + if ( nNum == 0 ) + continue; + //printf( " [%d] -> %d", k, nNum ); + pMainObj = Abc_NtkCreatePi( pMainNtk ); + sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); + Abc_ObjAssignName( pMainObj, Buffer, NULL ); + + } + //printf( "\n"); + nBits += nRange; } - //printf( "\n"); - nBits += nRange; } - //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); - assert( Vec_IntSize(vInv) == nBits ); + //printf( "%d %d\n", Vec_IntSize(vCounts), nBits ); + assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits ); // create node pMainObj = Abc_NtkCreateNode( pMainNtk ); Abc_NtkForEachPi( pMainNtk, pMainTemp, i ) Abc_ObjAddFanin( pMainObj, pMainTemp ); pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vSop ); // create PO pMainTemp = Abc_NtkCreatePo( pMainNtk ); Abc_ObjAddFanin( pMainTemp, pMainObj ); @@ -145,6 +174,66 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, return pMainNtk; } +/**Function************************************************************* + + Synopsis [Translate current network into an interpolant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) +{ + Vec_Int_t * vRes = NULL; + if ( Abc_NtkPoNum(pNtk) != 1 ) + printf( "The number of outputs is other than 1.\n" ); + else if ( Abc_NtkNodeNum(pNtk) != 1 ) + printf( "The number of internal nodes is other than 1.\n" ); + else + { + Abc_Obj_t * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); + char * pName, * pCube, * pSop = (char *)pNode->pData; + Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) ); + Abc_Obj_t * pFanin; int i, k, Value, nLits; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + assert( Abc_ObjIsCi(pFanin) ); + pName = Abc_ObjName(pFanin); + for ( k = (int)strlen(pName)-1; k >= 0; k-- ) + if ( pName[k] < '0' || pName[k] > '9' ) + break; + if ( k == (int)strlen(pName)-1 ) + { + printf( "Cannot read input name of fanin %d.\n", i ); + Value = i; + } + else + Value = atoi(pName + k + 1); + Vec_IntPush( vFanins, Value ); + } + assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) ); + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) ); + Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube ) + { + nLits = 0; + Abc_CubeForEachVar( pCube, Value, k ) + if ( Value != '-' ) + nLits++; + Vec_IntPush( vRes, nLits ); + Abc_CubeForEachVar( pCube, Value, k ) + if ( Value != '-' ) + Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') ); + } + Vec_IntPush( vRes, nRegs ); + Vec_IntFree( vFanins ); + } + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index f3eb6dd7..93614938 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,18 +32,21 @@ static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); + static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; } static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; } -static inline Vec_Int_t * Wlc_AbcGetCnf( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcCnf; } -static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcStr; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -66,10 +69,15 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); + + Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); } /**Function******************************************************************** @@ -440,10 +448,108 @@ usage: SeeAlso [] ******************************************************************************/ -int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv ) { + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" ); + return 0; + } + Wlc_WinProfileArith( pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%profile [-vh]\n" ); + Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p ); + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" ); + return 0; + } + // transform + //pNtk = Wlc_NtkUifNodePairs( pNtk, NULL ); + //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL ); + //Wlc_AbcUpdateNtk( pAbc, pNtk ); + //Wlc_GenerateSmtStdout( pAbc ); + //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc ); + pNtk = Wlc_NtkDupSingleNodes( pNtk ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%test [-vh]\n" ); + Abc_Print( -2, "\t experiments with word-level networks\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ); Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Vec_Int_t * vCounts; int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -461,24 +567,66 @@ int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pNtk == NULL ) { - Abc_Print( 1, "Abc_CommandPsInv(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandInvPs(): There is no current design.\n" ); return 0; } - if ( Wlc_AbcGetNtk(pAbc) == NULL ) + if ( Wlc_AbcGetInv(pAbc) == NULL ) { - Abc_Print( 1, "Abc_CommandPsInv(): There is no saved invariant.\n" ); + Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); return 0; } + vCounts = Pdr_InvCounts( Wlc_AbcGetInv(pAbc) ); + Wlc_NtkPrintInvStats( pNtk, vCounts, fVerbose ); + Vec_IntFree( vCounts ); + return 0; +usage: + Abc_Print( -2, "usage: inv_ps [-vh]\n" ); + Abc_Print( -2, "\t prints statistics for inductive invariant\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Pdr_InvPrint( Vec_Int_t * vInv ); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } if ( Wlc_AbcGetInv(pAbc) == NULL ) { - Abc_Print( 1, "Abc_CommandPsInv(): Invariant is not available.\n" ); + Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); return 0; } - Wlc_NtkPrintInvStats( pNtk, Wlc_AbcGetInv(pAbc), fVerbose ); + Pdr_InvPrint( Wlc_AbcGetInv(pAbc) ); return 0; - usage: - Abc_Print( -2, "usage: %%psinv [-vh]\n" ); - Abc_Print( -2, "\t prints statistics for inductive invariant\n" ); +usage: + Abc_Print( -2, "usage: inv_print [-vh]\n" ); + Abc_Print( -2, "\t prints the current inductive invariant\n" ); Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); @@ -496,11 +644,9 @@ int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv ) SeeAlso [] ******************************************************************************/ -int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ); - Abc_Ntk_t * pMainNtk; - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + extern Vec_Int_t * Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -516,28 +662,76 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( pNtk == NULL ) + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" ); + return 0; + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) { - Abc_Print( 1, "Abc_CommandGetInv(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandInvMin(): There is no saved invariant.\n" ); return 0; } - if ( Wlc_AbcGetNtk(pAbc) == NULL ) + if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(Wlc_AbcGetInv(pAbc)) ) { - Abc_Print( 1, "Abc_CommandGetInv(): There is no saved invariant.\n" ); + Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } + Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + return 0; +usage: + Abc_Print( -2, "usage: inv_check [-vh]\n" ); + Abc_Print( -2, "\t checks that the invariant is indeed an inductive invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ); + Abc_Ntk_t * pMainNtk; + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } if ( Wlc_AbcGetInv(pAbc) == NULL ) { - Abc_Print( 1, "Abc_CommandGetInv(): Invariant is not available.\n" ); + Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" ); return 0; } // derive the network - pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), Wlc_AbcGetStr(pAbc), fVerbose ); + pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) ); // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); + if ( pMainNtk ) + Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); return 0; - usage: - Abc_Print( -2, "usage: %%getinv [-vh]\n" ); +usage: + Abc_Print( -2, "usage: inv_get [-vh]\n" ); Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" ); Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); @@ -556,34 +750,45 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) SeeAlso [] ******************************************************************************/ -int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ); + Vec_Int_t * vInv = NULL; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) { switch ( c ) { - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; } } if ( pNtk == NULL ) { - Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandInvPut(): There is no current design.\n" ); return 0; } - Wlc_WinProfileArith( pNtk ); + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPut(): There is no current AIG.\n" ); + return 0; + } + // derive the network + vInv = Wlc_NtkGetPut( pNtk, Gia_ManRegNum(pAbc->pGia) ); + if ( vInv ) + Abc_FrameSetInv( vInv ); return 0; usage: - Abc_Print( -2, "usage: %%profile [-vh]\n" ); - Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" ); + Abc_Print( -2, "usage: inv_put [-vh]\n" ); + Abc_Print( -2, "\t inputs the current network in the main-space as an invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -600,42 +805,49 @@ usage: SeeAlso [] ******************************************************************************/ -int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p ); - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); + Vec_Int_t * vInv, * vInv2; int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) { switch ( c ) { - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; } } - if ( pNtk == NULL ) + if ( pAbc->pGia == NULL ) { - Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" ); return 0; } - // transform - //pNtk = Wlc_NtkUifNodePairs( pNtk, NULL ); - //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL ); - //Wlc_AbcUpdateNtk( pAbc, pNtk ); - //Wlc_GenerateSmtStdout( pAbc ); - //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc ); - pNtk = Wlc_NtkDupSingleNodes( pNtk ); - Wlc_AbcUpdateNtk( pAbc, pNtk ); + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): Invariant is not available.\n" ); + return 0; + } + vInv = Wlc_AbcGetInv(pAbc); + if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(vInv) ) + { + Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); + return 0; + } + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + if ( vInv2 ) + Abc_FrameSetInv( vInv2 ); return 0; usage: - Abc_Print( -2, "usage: %%test [-vh]\n" ); - Abc_Print( -2, "\t experiments with word-level networks\n" ); + Abc_Print( -2, "usage: inv_min [-vh]\n" ); + Abc_Print( -2, "\t minimizes the number of clauses in the current invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 66cae36e..c625e366 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -923,9 +923,7 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) if ( p->pPars->fDumpInv ) { char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); - Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); - Abc_FrameSetStr( Pdr_ManDumpString(p) ); - Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) ); + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); } p->tTotal += Abc_Clock() - clk; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 02b90a36..f29b792c 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -605,9 +605,237 @@ Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce ) //Vec_PtrFree( vCubes ); Vec_PtrFreeP( &p->vInfCubes ); p->vInfCubes = vCubes; + Vec_IntPush( vResult, Aig_ManRegNum(p->pAig) ); return vResult; } + + +/**Function************************************************************* + + Synopsis [Remove clauses while maintaining the invariant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#define Pdr_ForEachCube( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 1 ) + +extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + +Vec_Int_t * Pdr_InvMap( Vec_Int_t * vCounts ) +{ + int i, k = 0, Count; + Vec_Int_t * vMap = Vec_IntStart( Vec_IntSize(vCounts) ); + Vec_IntForEachEntry( vCounts, Count, i ) + if ( Count ) + Vec_IntWriteEntry( vMap, i, k++ ); + return vMap; +} +Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ) +{ + int i, k, * pCube, * pList = Vec_IntArray(vInv); + Vec_Int_t * vCounts = Vec_IntStart( Vec_IntEntryLast(vInv) ); + Pdr_ForEachCube( pList, pCube, i ) + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntAddToEntry( vCounts, Abc_Lit2Var(pCube[k+1]), 1 ); + return vCounts; +} +int Pdr_InvUsedFlopNum( Vec_Int_t * vInv ) +{ + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + int nZeros = Vec_IntCountZero( vCounts ); + Vec_IntFree( vCounts ); + return Vec_IntEntryLast(vInv) - nZeros; +} + +Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ) +{ + Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); + Vec_Int_t * vMap = Pdr_InvMap( vCounts ); + int nVars = Vec_IntSize(vCounts) - Vec_IntCountZero(vCounts); + int i, k, * pCube, * pList = Vec_IntArray(vInv); + char * pBuffer = ABC_ALLOC( char, nVars ); + for ( i = 0; i < nVars; i++ ) + pBuffer[i] = '-'; + Pdr_ForEachCube( pList, pCube, i ) + { + for ( k = 0; k < pCube[0]; k++ ) + pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '0' + !Abc_LitIsCompl(pCube[k+1]); + for ( k = 0; k < nVars; k++ ) + Vec_StrPush( vStr, pBuffer[k] ); + Vec_StrPush( vStr, ' ' ); + Vec_StrPush( vStr, '1' ); + Vec_StrPush( vStr, '\n' ); + for ( k = 0; k < pCube[0]; k++ ) + pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '-'; + } + Vec_StrPush( vStr, '\0' ); + ABC_FREE( pBuffer ); + Vec_IntFree( vMap ); + return vStr; +} +void Pdr_InvPrint( Vec_Int_t * vInv ) +{ + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts ); + printf( "Invariant contains %d clauses with %d literals and %d flops (out of %d).\n", Vec_IntEntry(vInv, 0), Vec_IntSize(vInv)-Vec_IntEntry(vInv, 0)-2, Pdr_InvUsedFlopNum(vInv), Vec_IntEntryLast(vInv) ); + printf( "%s", Vec_StrArray( vStr ) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vStr ); +} + +void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) +{ + int nBTLimit = 0; + int i, k, status, nFailed = 0; + // create SAT solver + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + // collect cubes + int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; + // create variables + Vec_Int_t * vLits = Vec_IntAlloc(100); + int nVars = Gia_ManRegNum(p); + int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); + int iFiVarBeg = 1 + Gia_ManPoNum(p); + assert( Gia_ManPoNum(p) == 1 ); + // add cubes + Pdr_ForEachCube( pList, pCube, i ) + { + // collect literals + Vec_IntClear( vLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + // add it to the solver + status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); + assert( status == 1 ); + } + // iterate through cubes in the direct order + Pdr_ForEachCube( pList, pCube, i ) + { + // collect cube + Vec_IntClear( vLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); + // check if this cube intersects with the complement of other cubes in the solver + // if it does not intersect, then it is redundant and can be skipped + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + break; + if ( status == l_False ) // unsat -- correct + continue; + assert( status == l_True ); + nFailed++; + } + if ( nFailed ) + printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, nCubes ); + else + printf( "Invariant verification passes.\n" ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_IntFree( vLits ); +} + +Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) +{ + int nBTLimit = 0; + int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; + Vec_Int_t * vRes = NULL; + // create SAT solver + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; + // create variables + Vec_Int_t * vLits = Vec_IntAlloc(100); + Vec_Bit_t * vRemoved = Vec_BitStart( nCubes ); + int nVars = Gia_ManRegNum(p); + int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); + int iFiVarBeg = 1 + Gia_ManPoNum(p); + int iAuxVarBeg = sat_solver_nvars(pSat); + assert( Gia_ManPoNum(p) == 1 ); + // allocate auxiliary variables + sat_solver_setnvars( pSat, sat_solver_nvars(pSat) + nCubes ); + // add clauses + Pdr_ForEachCube( pList, pCube, i ) + { + // collect literals + Vec_IntFill( vLits, 1, Abc_Var2Lit(iAuxVarBeg + i, 1) ); // neg aux literal + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + // add it to the solver + status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); + assert( status == 1 ); + } + // iterate through clauses + Pdr_ForEachCube( pList, pCube, i ) + { + if ( Vec_BitEntry(vRemoved, i) ) + continue; + // collect aux literals for remaining clauses + Vec_IntClear( vLits ); + for ( k = 0; k < nCubes; k++ ) + if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes + Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal + nLits = Vec_IntSize( vLits ); + // try removing other clauses + fCannot = 0; + Pdr_ForEachCube( pList, pCube, n ) + { + if ( Vec_BitEntry(vRemoved, n) || n == i ) + continue; + // collect cube + Vec_IntShrink( vLits, nLits ); + for ( k = 0; k < pCube[0]; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); + // check if this cube intersects with the complement of other cubes in the solver + // if it does not intersect, then it is redundant and can be skipped + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + { + fFailed = 1; + break; + } + if ( status == l_False ) // unsat -- correct + continue; + assert( status == l_True ); + // cannot remove + fCannot = 1; + break; + } + if ( fFailed ) + break; + if ( fCannot ) + continue; + printf( "Removing clause %d.\n", i ); + Vec_BitWriteEntry( vRemoved, i, 1 ); + nRemoved++; + } + if ( nRemoved ) + printf( "Invariant minimization reduced %d clauses (out of %d).\n", nRemoved, nCubes ); + else + printf( "Invariant minimization did not change the invariant.\n" ); + // cleanup cover + if ( !fFailed && nRemoved > 0 ) // finished without timeout and removed some cubes + { + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, nCubes-nRemoved ); + Pdr_ForEachCube( pList, pCube, i ) + if ( !Vec_BitEntry(vRemoved, i) ) + for ( k = 0; k <= pCube[0]; k++ ) + Vec_IntPush( vRes, pCube[k] ); + Vec_IntPush( vRes, Vec_IntEntryLast(vInv) ); + } + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + Vec_BitFree( vRemoved ); + Vec_IntFree( vLits ); + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c index 53a8a54a..32e97772 100644 --- a/src/proof/pdr/pdrUtil.c +++ b/src/proof/pdr/pdrUtil.c @@ -284,7 +284,7 @@ void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vF } Vec_StrPushBuffer( vStr, pBuff, k ); Vec_StrPush( vStr, ' ' ); - Vec_StrPush( vStr, '0' ); + Vec_StrPush( vStr, '1' ); Vec_StrPush( vStr, '\n' ); ABC_FREE( pBuff ); } -- cgit v1.2.3 From 849f18076411a54c21e593e3bd9e72bf6d56883e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:44:25 -0800 Subject: Adding features for invariant minimization. --- src/base/wlc/wlcAbc.c | 2 +- src/base/wlc/wlcCom.c | 28 ++++++++++++----- src/proof/pdr/pdrInv.c | 81 +++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 92 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 1a98fb71..1f10d7b0 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -176,7 +176,7 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) /**Function************************************************************* - Synopsis [Translate current network into an interpolant.] + Synopsis [Translate current network into an invariant.] Description [] diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 93614938..85b3b35d 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -646,8 +646,8 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); - int c, fVerbose = 0; + extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); + int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) { @@ -677,7 +677,11 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + if ( nFailed ) + printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); + else + printf( "Invariant verification passes.\n" ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); @@ -808,13 +812,17 @@ usage: int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); + extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ); Vec_Int_t * vInv, * vInv2; - int c, fVerbose = 0; + int c, fLits = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "lvh" ) ) != EOF ) { switch ( c ) { + case 'l': + fLits ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -840,14 +848,18 @@ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + if ( fLits ) + vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv ); + else + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); if ( vInv2 ) Abc_FrameSetInv( vInv2 ); return 0; usage: - Abc_Print( -2, "usage: inv_min [-vh]\n" ); - Abc_Print( -2, "\t minimizes the number of clauses in the current invariant\n" ); + Abc_Print( -2, "usage: inv_min [-lvh]\n" ); + Abc_Print( -2, "\t performs minimization of the current invariant\n" ); Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + Abc_Print( -2, "\t-l : toggle minimizing literals rather than clauses [default = %s]\n", fLits? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index f29b792c..8cfc7450 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -688,7 +688,7 @@ void Pdr_InvPrint( Vec_Int_t * vInv ) Vec_StrFree( vStr ); } -void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) +int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) { int nBTLimit = 0; int i, k, status, nFailed = 0; @@ -699,7 +699,6 @@ void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; // create variables Vec_Int_t * vLits = Vec_IntAlloc(100); - int nVars = Gia_ManRegNum(p); int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); int iFiVarBeg = 1 + Gia_ManPoNum(p); assert( Gia_ManPoNum(p) == 1 ); @@ -709,7 +708,8 @@ void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) // collect literals Vec_IntClear( vLits ); for ( k = 0; k < pCube[0]; k++ ) - Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + if ( pCube[k+1] != -1 ) + Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); // add it to the solver status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); assert( status == 1 ); @@ -720,7 +720,8 @@ void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) // collect cube Vec_IntClear( vLits ); for ( k = 0; k < pCube[0]; k++ ) - Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); + if ( pCube[k+1] != -1 ) + Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) ); // check if this cube intersects with the complement of other cubes in the solver // if it does not intersect, then it is redundant and can be skipped status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); @@ -731,18 +732,16 @@ void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) assert( status == l_True ); nFailed++; } - if ( nFailed ) - printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, nCubes ); - else - printf( "Invariant verification passes.\n" ); Cnf_DataFree( pCnf ); sat_solver_delete( pSat ); Vec_IntFree( vLits ); + return nFailed; } Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) { int nBTLimit = 0; + int fCheckProperty = 0; int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; Vec_Int_t * vRes = NULL; // create SAT solver @@ -752,7 +751,6 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) // create variables Vec_Int_t * vLits = Vec_IntAlloc(100); Vec_Bit_t * vRemoved = Vec_BitStart( nCubes ); - int nVars = Gia_ManRegNum(p); int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); int iFiVarBeg = 1 + Gia_ManPoNum(p); int iAuxVarBeg = sat_solver_nvars(pSat); @@ -781,7 +779,26 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal nLits = Vec_IntSize( vLits ); - // try removing other clauses + + // check if the property still holds + if ( fCheckProperty ) + { + Vec_IntPush( vLits, Abc_Var2Lit(1, 0) ); + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + { + fFailed = 1; + break; + } + if ( status == l_True ) // sat - property fails + { + //printf( "property fails if clause %d is removed\n", i ); + continue; + } + assert( status == l_False ); // unsat - property holds + } + + // check other clauses fCannot = 0; Pdr_ForEachCube( pList, pCube, n ) { @@ -836,6 +853,50 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) return vRes; } +Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ) +{ + Vec_Int_t * vRes = NULL; + int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0; + Pdr_ForEachCube( pList, pCube, i ) + { + nLits += pCube[0]; + for ( k = 0; k < pCube[0]; k++ ) + { + int Save = pCube[k+1]; + pCube[k+1] = -1; + if ( Pdr_InvCheck(p, vInv) ) + { + pCube[k+1] = Save; + continue; + } + printf( "Removing lit %d from clause %d.\n", k, i ); + nRemoved++; + } + } + if ( nRemoved ) + printf( "Invariant minimization reduced %d literals (out of %d).\n", nRemoved, nLits ); + else + printf( "Invariant minimization did not change the invariant.\n" ); + if ( nRemoved > 0 ) // finished without timeout and removed some lits + { + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, pList[0] ); + Pdr_ForEachCube( pList, pCube, i ) + { + int nLits = 0; + for ( k = 0; k < pCube[0]; k++ ) + if ( pCube[k+1] != -1 ) + nLits++; + Vec_IntPush( vRes, nLits ); + for ( k = 0; k < pCube[0]; k++ ) + if ( pCube[k+1] != -1 ) + Vec_IntPush( vRes, pCube[k+1] ); + } + Vec_IntPush( vRes, Vec_IntEntryLast(vInv) ); + } + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 88e887d1a08649cec01d508c4c24c08911a29eea Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:46:03 -0800 Subject: Fixing gcc compilation problem. --- src/sat/xsat/xsatHeap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h index 2e873e59..409ce460 100644 --- a/src/sat/xsat/xsatHeap.h +++ b/src/sat/xsat/xsatHeap.h @@ -48,7 +48,7 @@ struct xSAT_Heap_t_ SeeAlso [] ***********************************************************************/ -inline int xSAT_HeapSize( xSAT_Heap_t * h ) +static inline int xSAT_HeapSize( xSAT_Heap_t * h ) { return Vec_IntSize( h->vHeap ); } @@ -64,7 +64,7 @@ inline int xSAT_HeapSize( xSAT_Heap_t * h ) SeeAlso [] ***********************************************************************/ -inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) +static inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var ) { return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 ); } -- cgit v1.2.3 From c3dfec7467ee4d0dab6e031a92e046729f2cff00 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:49:47 -0800 Subject: Fixing windows compilation problem. --- src/sat/xsat/xsatBQueue.h | 3 ++- src/sat/xsat/xsatSolver.c | 2 +- src/sat/xsat/xsatSolver.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h index 560f75c0..f75f3650 100644 --- a/src/sat/xsat/xsatBQueue.h +++ b/src/sat/xsat/xsatBQueue.h @@ -125,8 +125,9 @@ static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, unsigned Value ) ***********************************************************************/ static inline int xSAT_BQueuePop( xSAT_BQueue_t * p ) { + int RetValue; assert( p->nSize >= 1 ); - int RetValue = p->pData[p->iFirst]; + RetValue = p->pData[p->iFirst]; p->nSum -= RetValue; p->iFirst = ( p->iFirst + 1 ) % p->nCap; p->nSize--; diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index 467f5f8d..9a98eec0 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -334,7 +334,7 @@ int xSAT_SolverEnqueue( xSAT_Solver_t * s, int Lit, unsigned Reason ) { int Var = xSAT_Lit2Var( Lit ); - Vec_StrWriteEntry( s->vAssigns, Var, xSAT_LitSign( Lit ) ); + Vec_StrWriteEntry( s->vAssigns, Var, (char)xSAT_LitSign( Lit ) ); Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) ); Vec_IntWriteEntry( s->vReasons, Var, ( int ) Reason ); Vec_IntPush( s->vTrail, Lit ); diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h index bf8bf419..36432e03 100644 --- a/src/sat/xsat/xsatSolver.h +++ b/src/sat/xsat/xsatSolver.h @@ -143,7 +143,7 @@ struct xSAT_Solver_t_ int nAssignSimplify; /* Number of top-level assignments since last * execution of 'simplify()'. */ - int64_t nPropSimplify; /* Remaining number of propagations that must be + iword nPropSimplify; /* Remaining number of propagations that must be * made before next execution of 'simplify()'. */ /* Temporary data used by Search method */ -- cgit v1.2.3 From cf1106aba8d940a6d9d5f410b6773c24bdf0d393 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 22:28:28 -0800 Subject: Adding features for invariant minimization. --- src/base/wlc/wlcCom.c | 16 ++++++++-------- src/proof/pdr/pdrInv.c | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 85b3b35d..be9ba7f6 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -601,7 +601,7 @@ usage: ******************************************************************************/ int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Pdr_InvPrint( Vec_Int_t * vInv ); + extern void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ); int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -622,7 +622,7 @@ int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); return 0; } - Pdr_InvPrint( Wlc_AbcGetInv(pAbc) ); + Pdr_InvPrint( Wlc_AbcGetInv(pAbc), fVerbose ); return 0; usage: Abc_Print( -2, "usage: inv_print [-vh]\n" ); @@ -646,7 +646,7 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); + extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -677,7 +677,7 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc), fVerbose ); if ( nFailed ) printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else @@ -811,8 +811,8 @@ usage: ******************************************************************************/ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); - extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ); + extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); + extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); Vec_Int_t * vInv, * vInv2; int c, fLits = 0, fVerbose = 0; Extra_UtilGetoptReset(); @@ -849,9 +849,9 @@ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } if ( fLits ) - vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv ); + vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv, fVerbose ); else - vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv, fVerbose ); if ( vInv2 ) Abc_FrameSetInv( vInv2 ); return 0; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 8cfc7450..19e6c90e 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -678,17 +678,20 @@ Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ) Vec_IntFree( vMap ); return vStr; } -void Pdr_InvPrint( Vec_Int_t * vInv ) +void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ) { - Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); - Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts ); printf( "Invariant contains %d clauses with %d literals and %d flops (out of %d).\n", Vec_IntEntry(vInv, 0), Vec_IntSize(vInv)-Vec_IntEntry(vInv, 0)-2, Pdr_InvUsedFlopNum(vInv), Vec_IntEntryLast(vInv) ); - printf( "%s", Vec_StrArray( vStr ) ); - Vec_IntFree( vCounts ); - Vec_StrFree( vStr ); + if ( fVerbose ) + { + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts ); + printf( "%s", Vec_StrArray( vStr ) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vStr ); + } } -int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) +int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { int nBTLimit = 0; int i, k, status, nFailed = 0; @@ -696,7 +699,7 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // collect cubes - int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; + int * pCube, * pList = Vec_IntArray(vInv); // create variables Vec_Int_t * vLits = Vec_IntAlloc(100); int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); @@ -731,6 +734,8 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) continue; assert( status == l_True ); nFailed++; + if ( fVerbose ) + printf( "Verification failed for clause %d.\n", i ); } Cnf_DataFree( pCnf ); sat_solver_delete( pSat ); @@ -738,10 +743,11 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ) return nFailed; } -Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) +Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { int nBTLimit = 0; - int fCheckProperty = 0; + int fCheckProperty = 1; + abctime clk = Abc_Clock(); int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; Vec_Int_t * vRes = NULL; // create SAT solver @@ -827,14 +833,16 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) break; if ( fCannot ) continue; + if ( fVerbose ) printf( "Removing clause %d.\n", i ); Vec_BitWriteEntry( vRemoved, i, 1 ); nRemoved++; } if ( nRemoved ) - printf( "Invariant minimization reduced %d clauses (out of %d).\n", nRemoved, nCubes ); + printf( "Invariant minimization reduced %d clauses (out of %d). ", nRemoved, nCubes ); else - printf( "Invariant minimization did not change the invariant.\n" ); + printf( "Invariant minimization did not change the invariant. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // cleanup cover if ( !fFailed && nRemoved > 0 ) // finished without timeout and removed some cubes { @@ -853,9 +861,10 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ) return vRes; } -Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ) +Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { Vec_Int_t * vRes = NULL; + abctime clk = Abc_Clock(); int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0; Pdr_ForEachCube( pList, pCube, i ) { @@ -864,19 +873,21 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ) { int Save = pCube[k+1]; pCube[k+1] = -1; - if ( Pdr_InvCheck(p, vInv) ) + if ( Pdr_InvCheck(p, vInv, 0) ) { pCube[k+1] = Save; continue; } + if ( fVerbose ) printf( "Removing lit %d from clause %d.\n", k, i ); nRemoved++; } } if ( nRemoved ) - printf( "Invariant minimization reduced %d literals (out of %d).\n", nRemoved, nLits ); + printf( "Invariant minimization reduced %d literals (out of %d). ", nRemoved, nLits ); else - printf( "Invariant minimization did not change the invariant.\n" ); + printf( "Invariant minimization did not change the invariant. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); if ( nRemoved > 0 ) // finished without timeout and removed some lits { vRes = Vec_IntAlloc( 1000 ); -- cgit v1.2.3 From 3119e1e30f8a44eb6236792c69f8cca64c99f7a8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 13:56:16 -0800 Subject: Adding features for invariant minimization. --- src/base/wlc/wlcCom.c | 2 +- src/proof/pdr/pdrInv.c | 102 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 74 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index be9ba7f6..2828fea3 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -681,7 +681,7 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nFailed ) printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else - printf( "Invariant verification passes.\n" ); + printf( "Invariant verification succeeded.\n" ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 19e6c90e..bd32953a 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -691,20 +691,17 @@ void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ) } } -int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) +int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver * pSat ) { int nBTLimit = 0; - int i, k, status, nFailed = 0; - // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); - sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + int fCheckProperty = 1; + int i, k, status, nFailed = 0, nFailedOuts = 0; // collect cubes int * pCube, * pList = Vec_IntArray(vInv); // create variables Vec_Int_t * vLits = Vec_IntAlloc(100); - int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); + int iFoVarBeg = sat_solver_nvars(pSat) - Gia_ManRegNum(p); int iFiVarBeg = 1 + Gia_ManPoNum(p); - assert( Gia_ManPoNum(p) == 1 ); // add cubes Pdr_ForEachCube( pList, pCube, i ) { @@ -713,10 +710,34 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) for ( k = 0; k < pCube[0]; k++ ) if ( pCube[k+1] != -1 ) Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) ); + if ( Vec_IntSize(vLits) == 0 ) + { + Vec_IntFree( vLits ); + return 1; + } // add it to the solver status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ); assert( status == 1 ); } + // verify property output + if ( fCheckProperty ) + { + for ( i = 0; i < Gia_ManPoNum(p); i++ ) + { + Vec_IntFill( vLits, 1, Abc_Var2Lit(1+i, 0) ); + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + break; + if ( status == l_True ) // sat - property fails + { + if ( fVerbose ) + printf( "Coverage check failed for output %d.\n", i ); + nFailedOuts++; + continue; + } + assert( status == l_False ); // unsat - property holds + } + } // iterate through cubes in the direct order Pdr_ForEachCube( pList, pCube, i ) { @@ -735,12 +756,22 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) assert( status == l_True ); nFailed++; if ( fVerbose ) - printf( "Verification failed for clause %d.\n", i ); + printf( "Inductiveness check failed for clause %d.\n", i ); } + Vec_IntFree( vLits ); + return nFailed + nFailedOuts; +} + +int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) +{ + int RetValue; + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + assert( sat_solver_nvars(pSat) == pCnf->nVars ); Cnf_DataFree( pCnf ); + RetValue = Pdr_InvCheck_int( p, vInv, fVerbose, pSat ); sat_solver_delete( pSat ); - Vec_IntFree( vLits ); - return nFailed; + return RetValue; } Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) @@ -760,8 +791,8 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p); int iFiVarBeg = 1 + Gia_ManPoNum(p); int iAuxVarBeg = sat_solver_nvars(pSat); - assert( Gia_ManPoNum(p) == 1 ); // allocate auxiliary variables + assert( sat_solver_nvars(pSat) == pCnf->nVars ); sat_solver_setnvars( pSat, sat_solver_nvars(pSat) + nCubes ); // add clauses Pdr_ForEachCube( pList, pCube, i ) @@ -785,25 +816,28 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal nLits = Vec_IntSize( vLits ); - // check if the property still holds if ( fCheckProperty ) { - Vec_IntPush( vLits, Abc_Var2Lit(1, 0) ); - status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); - if ( status == l_Undef ) // timeout + for ( k = 0; k < Gia_ManPoNum(p); k++ ) { - fFailed = 1; - break; + Vec_IntShrink( vLits, nLits ); + Vec_IntPush( vLits, Abc_Var2Lit(1+k, 0) ); + status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status == l_Undef ) // timeout + { + fFailed = 1; + break; + } + if ( status == l_True ) // sat - property fails + break; + assert( status == l_False ); // unsat - property holds } - if ( status == l_True ) // sat - property fails - { - //printf( "property fails if clause %d is removed\n", i ); + if ( fFailed ) + break; + if ( k < Gia_ManPoNum(p) ) continue; - } - assert( status == l_False ); // unsat - property holds } - // check other clauses fCannot = 0; Pdr_ForEachCube( pList, pCube, n ) @@ -866,6 +900,9 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) Vec_Int_t * vRes = NULL; abctime clk = Abc_Clock(); int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0; + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + sat_solver * pSat; +// sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Pdr_ForEachCube( pList, pCube, i ) { nLits += pCube[0]; @@ -873,16 +910,23 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { int Save = pCube[k+1]; pCube[k+1] = -1; - if ( Pdr_InvCheck(p, vInv, 0) ) - { + //sat_solver_bookmark( pSat ); + pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + if ( Pdr_InvCheck_int(p, vInv, 0, pSat) ) pCube[k+1] = Save; - continue; + else + { + if ( fVerbose ) + printf( "Removing lit %d from clause %d.\n", k, i ); + nRemoved++; } - if ( fVerbose ) - printf( "Removing lit %d from clause %d.\n", k, i ); - nRemoved++; + sat_solver_delete( pSat ); + //sat_solver_rollback( pSat ); + //sat_solver_bookmark( pSat ); } } + Cnf_DataFree( pCnf ); + //sat_solver_delete( pSat ); if ( nRemoved ) printf( "Invariant minimization reduced %d literals (out of %d). ", nRemoved, nLits ); else -- cgit v1.2.3 From 32288c696493a223966ed334554f0a113d9134f0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 14:02:14 -0800 Subject: Adding features for invariant minimization. --- src/proof/pdr/pdrCore.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index c625e366..b81a1a2a 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -926,6 +926,8 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); } + else if ( RetValue == 1 ) + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); p->tTotal += Abc_Clock() - clk; Pdr_ManStop( p ); pPars->iFrame--; -- cgit v1.2.3 From a02bdebcc484ce18f388a7f172355da9cda9395e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 14:58:06 -0800 Subject: Corner-case bug in MiniLUT. --- src/aig/gia/giaMini.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 4ee92cdd..67805d44 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -295,6 +295,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) word Truth; assert( Gia_ManHasMapping(pGia) ); LutSize = Gia_ManLutSizeMax( pGia ); + LutSize = Abc_MaxInt( LutSize, 2 ); assert( LutSize >= 2 ); // create the manager p = Mini_LutStart( LutSize ); -- cgit v1.2.3 From 636332c63e31d15112f89e89a4689351ed3b66ca Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 22:27:46 -0800 Subject: Adding features for invariant minimization. --- src/proof/pdr/pdrInv.c | 16 +++- src/sat/bmc/bmcEnum.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+), 3 deletions(-) create mode 100644 src/sat/bmc/bmcEnum.c (limited to 'src') diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index bd32953a..0d27ce7e 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -691,7 +691,7 @@ void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ) } } -int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver * pSat ) +int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver * pSat, int fSkip ) { int nBTLimit = 0; int fCheckProperty = 1; @@ -733,6 +733,11 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver if ( fVerbose ) printf( "Coverage check failed for output %d.\n", i ); nFailedOuts++; + if ( fSkip ) + { + Vec_IntFree( vLits ); + return 1; + } continue; } assert( status == l_False ); // unsat - property holds @@ -755,6 +760,11 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver continue; assert( status == l_True ); nFailed++; + if ( fSkip ) + { + Vec_IntFree( vLits ); + return 1; + } if ( fVerbose ) printf( "Inductiveness check failed for clause %d.\n", i ); } @@ -769,7 +779,7 @@ int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); assert( sat_solver_nvars(pSat) == pCnf->nVars ); Cnf_DataFree( pCnf ); - RetValue = Pdr_InvCheck_int( p, vInv, fVerbose, pSat ); + RetValue = Pdr_InvCheck_int( p, vInv, fVerbose, pSat, 0 ); sat_solver_delete( pSat ); return RetValue; } @@ -912,7 +922,7 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) pCube[k+1] = -1; //sat_solver_bookmark( pSat ); pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); - if ( Pdr_InvCheck_int(p, vInv, 0, pSat) ) + if ( Pdr_InvCheck_int(p, vInv, 0, pSat, 1) ) pCube[k+1] = Save; else { diff --git a/src/sat/bmc/bmcEnum.c b/src/sat/bmc/bmcEnum.c new file mode 100644 index 00000000..5fe2c1ed --- /dev/null +++ b/src/sat/bmc/bmcEnum.c @@ -0,0 +1,225 @@ +/**CFile**************************************************************** + + FileName [bmcEnum.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based bounded model checking.] + + Synopsis [Enumeration.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: bmcEnum.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bmc.h" +#include "sat/cnf/cnf.h" +#include "sat/bsat/satSolver.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDeriveOne( Gia_Man_t * p, Vec_Int_t * vValues ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; int i, fPhase0, fPhase1; + assert( Vec_IntSize(vValues) == Gia_ManCiNum(p) ); + // propagate forward + Gia_ManForEachCi( p, pObj, i ) + pObj->fPhase = Vec_IntEntry(vValues, i); + Gia_ManForEachAnd( p, pObj, i ) + { + fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj); + fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj); + pObj->fPhase = fPhase0 & fPhase1; + } + // propagate backward + Gia_ManCleanMark0(p); + Gia_ManForEachCo( p, pObj, i ) + Gia_ObjFanin0(pObj)->fMark0 = 1; + Gia_ManForEachAndReverse( p, pObj, i ) + { + if ( !pObj->fMark0 ) + continue; + fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj); + fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj); + if ( fPhase0 == fPhase1 ) + { + assert( (int)pObj->fPhase == fPhase0 ); + Gia_ObjFanin0(pObj)->fMark0 = 1; + Gia_ObjFanin1(pObj)->fMark0 = 1; + } + else if ( fPhase0 ) + { + assert( fPhase1 == 0 ); + assert( pObj->fPhase == 0 ); + Gia_ObjFanin1(pObj)->fMark0 = 1; + } + else if ( fPhase1 ) + { + assert( fPhase0 == 0 ); + assert( pObj->fPhase == 0 ); + Gia_ObjFanin0(pObj)->fMark0 = 1; + } + } + // create new + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Abc_LitNotCond( Gia_ManAppendCi(pNew), !Vec_IntEntry(vValues, i) ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !pObj->fMark0 ) + continue; + fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj); + fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj); + if ( fPhase0 == fPhase1 ) + { + assert( (int)pObj->fPhase == fPhase0 ); + if ( pObj->fPhase ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value ); + else + pObj->Value = Gia_ManAppendOr( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value ); + } + else if ( fPhase0 ) + { + assert( fPhase1 == 0 ); + assert( pObj->fPhase == 0 ); + pObj->Value = Gia_ObjFanin1(pObj)->Value; + } + else if ( fPhase1 ) + { + assert( fPhase0 == 0 ); + assert( pObj->fPhase == 0 ); + pObj->Value = Gia_ObjFanin0(pObj)->Value; + } + } + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0(pObj)->Value ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Gia_ManCleanMark0(p); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDeriveOneTest2( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); + //Vec_IntFill( vValues, Gia_ManCiNum(p), 1 ); + pNew = Gia_ManDeriveOne( p, vValues ); + Vec_IntFree( vValues ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDeriveOneTest( Gia_Man_t * p ) +{ + int fVerbose = 1; + Gia_Man_t * pNew; + Gia_Obj_t * pObj, * pRoot; + Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + int i, iVar, nIter, iPoVarBeg = pCnf->nVars - Gia_ManCiNum(p); + sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + Vec_IntPush( vLits, Abc_Var2Lit( 1, 1 ) ); + for ( nIter = 0; nIter < 10000; nIter++ ) + { + int status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 ); + if ( status == l_False ) + break; + // derive new set + assert( status == l_True ); + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + { + Vec_IntWriteEntry( vValues, i, sat_solver_var_value(pSat, iPoVarBeg+i) ); + printf( "%d", sat_solver_var_value(pSat, iPoVarBeg+i) ); + } + printf( " : " ); + + pNew = Gia_ManDeriveOne( p, vValues ); + // assign variables + Gia_ManForEachCi( pNew, pObj, i ) + pObj->Value = iPoVarBeg+i; + iVar = sat_solver_nvars(pSat); + Gia_ManForEachAnd( pNew, pObj, i ) + pObj->Value = iVar++; + sat_solver_setnvars( pSat, iVar ); + // create new clauses + Gia_ManForEachAnd( pNew, pObj, i ) + sat_solver_add_and( pSat, pObj->Value, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 ); + // add to the assumptions + pRoot = Gia_ManCo(pNew, 0); + Vec_IntPush( vLits, Abc_Var2Lit(Gia_ObjFanin0(pRoot)->Value, !Gia_ObjFaninC0(pRoot)) ); + if ( fVerbose ) + { + printf( "Iter = %5d : ", nIter ); + printf( "And = %4d ", Gia_ManAndNum(pNew) ); + printf( "\n" ); + } + Gia_ManStop( pNew ); + } + Vec_IntFree( vLits ); + Vec_IntFree( vValues ); + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3 From 57286e8ab692d2df5df6e4077134b913229ba33f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 22:29:51 -0800 Subject: Adding features for invariant minimization. --- src/proof/pdr/pdrInv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 0d27ce7e..8b04c53b 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -759,14 +759,14 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver if ( status == l_False ) // unsat -- correct continue; assert( status == l_True ); + if ( fVerbose ) + printf( "Inductiveness check failed for clause %d.\n", i ); nFailed++; if ( fSkip ) { Vec_IntFree( vLits ); return 1; } - if ( fVerbose ) - printf( "Inductiveness check failed for clause %d.\n", i ); } Vec_IntFree( vLits ); return nFailed + nFailedOuts; -- cgit v1.2.3 From 3c8c807ac16dbfc9b1960f77dd49fd244e3d718d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 11:56:17 -0800 Subject: Improvements to SMT-LIB parser. --- src/base/wlc/wlc.h | 1 + src/base/wlc/wlcNtk.c | 6 +- src/base/wlc/wlcReadSmt.c | 320 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 243 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 1df3e5e9..6f64b47a 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -140,6 +140,7 @@ struct Wlc_Ntk_t_ int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type int nAnds[WLC_OBJ_NUMBER]; // counter of AND gates after blasting int fSmtLib; // the network comes from an SMT-LIB file + int nAssert; // the number of asserts // memory for objects Wlc_Obj_t * pObjs; int iObj; diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 6f396771..a0799ba0 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -195,14 +195,14 @@ void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ) { assert( pObj->nFanins == 0 ); pObj->nFanins = Vec_IntSize(vFanins); - if ( Wlc_ObjHasArray(pObj) ) - pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) ); - memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) ); // special treatment of CONST, SELECT and TABLE if ( pObj->Type == WLC_OBJ_CONST ) pObj->nFanins = 0; else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE ) pObj->nFanins = 1; + if ( Wlc_ObjHasArray(pObj) ) + pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) ); + memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) ); } void Wlc_NtkFree( Wlc_Ntk_t * p ) { diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index d07a54c4..61d0bca8 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -219,6 +219,8 @@ static inline int Smt_StrToType( char * pName, int * pfSigned ) Type = WLC_OBJ_ARI_REM, *pfSigned = 1; // 40: arithmetic remainder else if ( !strcmp(pName, "bvsmod") ) Type = WLC_OBJ_ARI_MODULUS, *pfSigned = 1; // 40: arithmetic modulus + else if ( !strcmp(pName, "=") ) + Type = WLC_OBJ_COMP_EQU; // 40: arithmetic modulus // else if ( !strcmp(pName, "") ) // Type = WLC_OBJ_ARI_POWER; // 41: arithmetic power else if ( !strcmp(pName, "bvneg") ) @@ -255,6 +257,8 @@ static inline int Smt_PrsReadType( Smt_Prs_t * p, int iSig, int * pfSigned, int } } +static inline int Smt_StrType( char * str ) { return Smt_StrToType(str, NULL); } + /**Function************************************************************* Synopsis [] @@ -274,20 +278,27 @@ static inline int Smt_PrsCreateNodeOld( Wlc_Ntk_t * pNtk, int Type, int fSigned, assert( Type > 0 ); assert( Range >= 0 ); assert( fSigned >= 0 ); - Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); - if ( fSigned ) - Wlc_NtkObj(pNtk, iObj)->Signed = fSigned; - if ( Type == WLC_OBJ_SHIFT_RA ) - Wlc_NtkObj(pNtk, iObj)->Signed = 1; + + // add node's name if ( pName == NULL ) { sprintf( Buffer, "_n%d_", iObj ); pName = Buffer; } - // add node's name NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); assert( !fFound ); assert( iObj == NameId ); + + Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); + if ( fSigned ) + { + Wlc_NtkObj(pNtk, iObj)->Signed = fSigned; +// if ( Vec_IntSize(vFanins) > 0 ) +// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 0))->Signed = fSigned; +// if ( Vec_IntSize(vFanins) > 1 ) +// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 1))->Signed = fSigned; + } + return iObj; } static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, int Range, Vec_Int_t * vFanins, char * pName ) @@ -302,8 +313,7 @@ static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, in assert( Range >= 0 ); assert( fSigned >= 0 ); - // allow more than 2 fanins for specific operators - // if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX ) + //if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX ) // explicitely secify allowed multi operators if (Vec_IntSize(vFanins)<=2 || !( Type == WLC_OBJ_BIT_AND || // 16:`` bitwise AND @@ -362,17 +372,17 @@ FINISHED_WITH_FANINS: Vec_IntFree(v2Fanins); - // to deal with long shifts create extra bit select (ROTATE as well ??) + //added to deal with long shifts create extra bit select (ROTATE as well ??) // this is a temporary hack - // basically we keep only 32 bits. - // bits 0 - 30 are kept same as original - // bit 31 will be the reduction or of all bits from 31 to Range-1 + // basically we keep only 32 bits. + // bit[31] will be the copy of original MSB (sign bit, just in case) UPDATE: assume it is unsigned first???? + // bit[31] will be the reduction or of any bits from [31] to Range if (Type == WLC_OBJ_SHIFT_R || Type == WLC_OBJ_SHIFT_RA || Type == WLC_OBJ_SHIFT_L) { - int iFanin1 = Vec_IntEntry(vFanins,1); - int range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) ); - int iObj1, iObj2, iObj3; + int range1, iObj1, iObj2, iObj3; assert(Vec_IntSize(vFanins)>=2); + iFanin1 = Vec_IntEntry(vFanins,1); + range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) ); if (range1>32) { Vec_Int_t * newFanins = Vec_IntAlloc(10); @@ -389,6 +399,8 @@ FINISHED_WITH_FANINS: Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj1), newFanins ); + //printf("obj1: %d\n",iObj1); + // bit select of larger bits Vec_IntPop(newFanins); Vec_IntPop(newFanins); @@ -402,6 +414,7 @@ FINISHED_WITH_FANINS: assert( iObj2 == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj2), newFanins ); + //printf("obj2: %d\n",iObj2); // reduction or Vec_IntPop( newFanins ); @@ -416,6 +429,7 @@ FINISHED_WITH_FANINS: assert( iObj3 == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj3), newFanins ); + //printf("obj3: %d\n",iObj3); // concat all together Vec_IntWriteEntry( newFanins, 0, iObj3 ); @@ -429,6 +443,7 @@ FINISHED_WITH_FANINS: assert( iObj == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), newFanins ); + //printf("obj: %d\n",iObj); // pushing the new node Vec_IntWriteEntry(vFanins, 1, iObj); @@ -461,34 +476,22 @@ FINISHED_WITH_FANINS: return iObj; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ static inline char * Smt_GetHexFromDecimalString(char * pStr) { int i,k=0, nDigits = strlen(pStr); int digit, carry = 0; - int metNonZeroBit; - int nBits; - char * hex; + int metNonZeroBit = 0; Vec_Int_t * decimal = Vec_IntAlloc(nDigits); Vec_Int_t * rev; + int nBits; + char * hex; for (i=0;i= '0' && pStr[0] <= '9' ) { + // added: sanity check for large constants + /* + Vec_Int_t * temp = Vec_IntAlloc(10); + int fullBits = -1; + Smt_GetBinaryFromDecimalString(pStr,temp,&fullBits); + Vec_IntFree(temp); + assert(fullBits < 32);*/ + + char * pHex = Smt_GetHexFromDecimalString(pStr); + + if ( nBits == -1 ) + nBits = strlen(pHex)*4; + + //printf("nbits: %d\n",nBits); + + Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); + nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex ); + ABC_FREE( pHex ); + /* int w, nWords, Number = atoi( pStr ); if ( nBits == -1 ) @@ -589,15 +616,6 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits for ( w = 0; w < nWords; w++ ) Vec_IntPush( vFanins, w ? 0 : Number ); */ - - // convert decimal to hex to parse large constants - char * pHex = Smt_GetHexFromDecimalString(pStr); - - if ( nBits == -1 ) - nBits = strlen(pHex)*4; - - Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); - nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex ); } else { @@ -648,12 +666,6 @@ int Smt_PrsBuildNode( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int RangeOut, // s3087 int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); assert( fFound ); - // create buffer if the name of the fanin has different name - if ( pName && strcmp(pStr, pName) ) - { - Vec_IntFill( &p->vTempFans, 1, iObj ); - iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, RangeOut, &p->vTempFans, pName ); - } return iObj; } } @@ -804,13 +816,6 @@ Wlc_Ntk_t * Smt_PrsBuild( Smt_Prs_t * p ) // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); - vFans2 = Smt_VecEntryNode(p, vFans, 2); - if ( Vec_IntSize(vFans2) > 0 ) - { - printf( "File parsing error: Uninterpreted functions are not supported.\n" ); - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } // check type (Bool or BitVec) Fan = Vec_IntEntry(vFans, 3); if ( Smt_EntryIsName(Fan) ) @@ -1006,6 +1011,14 @@ char * Smt_PrsGenName( Smt_Prs_t * p ) } int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pName ) { + char suffix[100]; + sprintf(suffix,"_as%d",pNtk->nAssert); + + //char * prepStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode)); + //printf("prestr: %s\n",prepStr); + + //printf("inode: %d %d\n",iNode,Smt_EntryIsName(iNode)); + if ( Smt_EntryIsName(iNode) ) { char * pStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode)); @@ -1018,7 +1031,27 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, return Smt_PrsBuildConstant( pNtk, pStr, -1, pName ? pName : Smt_PrsGenName(p) ); else { - int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); + int fFound, iObj; + // look either for global DECLARE-FUN variable or local LET + char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb + char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1); + strcpy(pStr_glb,pStr); + strcat(pStr_glb,"_glb"); + strcpy(pStr_loc,pStr); + strcat(pStr_loc,suffix); + + fFound = Abc_NamStrFind( pNtk->pManName, pStr_glb ); + + if (fFound) + pStr = pStr_glb; + else + { + assert( Abc_NamStrFind( pNtk->pManName, pStr_loc )); + pStr = pStr_loc; + } + // FIXME: delete memory of pStr + + iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); assert( fFound ); // create buffer if the name of the fanin has different name if ( pName && strcmp(Wlc_ObjName(pNtk, iObj), pName) ) @@ -1026,9 +1059,11 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, Vec_IntFill( &p->vTempFans, 1, iObj ); iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, Wlc_ObjRange(Wlc_NtkObj(pNtk, iObj)), &p->vTempFans, pName ); } + ABC_FREE( pStr_glb ); + ABC_FREE( pStr_loc ); return iObj; } - } + } else { Vec_Int_t * vRoots, * vRoots1, * vFans3; @@ -1039,7 +1074,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, if ( Smt_EntryIsName(iRoot0) ) { char * pName2, * pStr0 = Abc_NamStr(p->pStrs, Abc_Lit2Var(iRoot0)); - if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET ) + if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET || Abc_Lit2Var(iRoot0) == SMT_PRS_DEFINE_FUN) //added define-fun is similar to let { // let ((s35550 (bvor s48 s35549))) assert( Vec_IntSize(vRoots) == 3 ); @@ -1051,6 +1086,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, // iterate through the parts Vec_IntForEachEntry( vRoots1, Fan, k ) { + char * temp; // s35550 (bvor s48 s35549) assert( !Smt_EntryIsName(Fan) ); vFans3 = Smt_EntryNode(p, Fan); @@ -1059,11 +1095,26 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, Fan3 = Vec_IntEntry(vFans3, 0); assert( Smt_EntryIsName(Fan3) ); pName2 = Smt_EntryName(p, Fan3); + // create a local name with suffix + if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET ) + { + temp = (char *)malloc(strlen(pName2) + strlen(suffix) + 1); + strcpy(temp, pName2); + strcat(temp,suffix); + } + else + { temp = (char *)malloc(strlen(pName2) + 4 + 1); + strcpy(temp, pName2); + strcat(temp,"_glb"); + } + // FIXME: need to delete memory of pName2 + pName2 = temp; // get function Fan3 = Vec_IntEntry(vFans3, 1); //assert( !Smt_EntryIsName(Fan3) ); // solve the problem iObj = Smt_PrsBuild2_rec( pNtk, p, Fan3, -1, pName2 ); // NULL ); //pName2 ); + ABC_FREE( temp ); if ( iObj == 0 ) return 0; // create buffer @@ -1133,7 +1184,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, int iObj = Abc_NamStrFind( pNtk->pManName, pStr0 ); if ( iObj ) return iObj; - Type0 = Smt_StrToType( pStr0, &fSigned ); if ( Type0 == 0 ) return 0; @@ -1151,7 +1201,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, } Vec_IntPush( vFanins, iObj ); } - // find range Range = 0; if ( Type0 >= WLC_OBJ_LOGIC_NOT && Type0 <= WLC_OBJ_REDUCT_XOR ) @@ -1197,7 +1246,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Wlc_Ntk_t * pNtk; Vec_Int_t * vFansRoot, * vFans, * vFans2; Vec_Int_t * vAsserts = Vec_IntAlloc(100); - int i, Root, Fan, iObj, NameId, Range, Status, nBits = 0; + int i, Root, Fan, iObj, NameId, Range, nBits = 0; char * pName, * pRange; // start network and create primary inputs pNtk = Wlc_NtkAlloc( p->pName, 1000 ); @@ -1214,22 +1263,22 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // create variables if ( Abc_Lit2Var(Fan) == SMT_PRS_DECLARE_FUN ) { + char * pName_glb; assert( Vec_IntSize(vFans) == 4 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DECLARE_FUN) ); // get name Fan = Vec_IntEntry(vFans, 1); assert( Smt_EntryIsName(Fan) ); pName = Smt_EntryName(p, Fan); + // added: giving a global suffix + pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); - vFans2 = Smt_VecEntryNode(p, vFans, 2); - if ( Vec_IntSize(vFans2) > 0 ) - { - printf( "File parsing error: Uninterpreted functions are not supported.\n" ); - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } // check type (Bool or BitVec) Fan = Vec_IntEntry(vFans, 3); if ( Smt_EntryIsName(Fan) ) @@ -1259,9 +1308,11 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Vec_IntPush( &pNtk->vValues, nBits ); Vec_IntPush( &pNtk->vValues, Range ); nBits += Range; + ABC_FREE( pName_glb ); } // create constants - else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) + /* + else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) // added: we parse DEFINE_FUN in LET { assert( Vec_IntSize(vFans) == 5 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) ); @@ -1269,6 +1320,14 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Fan = Vec_IntEntry(vFans, 1); assert( Smt_EntryIsName(Fan) ); pName = Smt_EntryName(p, Fan); + + // added: giving a global suffix + char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; + // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); @@ -1278,13 +1337,17 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) { // (define-fun s_2 () Bool false) assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) ); - iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), -1, pName ); - if ( iObj == 0 ) - { - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } - continue; + Range = 1; + pValue = Smt_VecEntryName(p, vFans, 4); + + //printf("value: %s\n",pValue); + + if ( !strcmp("false", pValue) ) + pValue = "#b0"; + else if ( !strcmp("true", pValue) ) + pValue = "#b1"; + else assert( 0 ); + Status = Smt_PrsBuildConstant( pNtk, pValue, Range, pName ); } else { @@ -1292,6 +1355,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // (define-fun s1 () (_ BitVec 8) (bvneg #x7f)) // get range Fan = Vec_IntEntry(vFans, 3); + assert( !Smt_EntryIsName(Fan) ); vFans2 = Smt_VecEntryNode(p, vFans, 3); assert( Vec_IntSize(vFans2) == 3 ); @@ -1299,11 +1363,24 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) ); // get range Fan = Vec_IntEntry(vFans2, 2); + assert( Smt_EntryIsName(Fan) ); pRange = Smt_EntryName(p, Fan); Range = atoi(pRange); + + // added: can parse functions too + Vec_Int_t * vFans3 = Smt_VecEntryNode(p, vFans, 4); + Fan = Vec_IntEntry(vFans3, 0); + // get constant - Fan = Vec_IntEntry(vFans, 4); + //Fan = Vec_IntEntry(vFans, 4); + + //printf("fan3: %s\n",Fan); + //printf("fan0: %s\n",Smt_VecEntryName(p, vFans3, 0)); + //printf("fan1: %s\n",Smt_VecEntryName(p, vFans3, 1)); + //printf("fan2: %s\n",Smt_VecEntryName(p, vFans3, 2)); + //printf("fan3: %s\n",Smt_VecEntryName(p, vFans3, 3)); + Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName ); } if ( !Status ) @@ -1312,6 +1389,57 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) goto finish; } } + */ + // added: new way to parse define-fun + // create constants + else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) + { + char * pName_glb; + // (define-fun def_16001 () Bool (or def_15999 def_16000)) + // (define-fun def_15990 () (_ BitVec 24) (concat def_15988 def_15989)) + assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) ); + assert( Vec_IntSize(vFans) == 5 ); // const or definition + + // get name + Fan = Vec_IntEntry(vFans, 1); + assert( Smt_EntryIsName(Fan) ); + pName = Smt_EntryName(p, Fan); + // added: giving a global suffix + pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; + + //get range + Fan = Vec_IntEntry(vFans, 3); + if ( Smt_EntryIsName(Fan) ) + { + // (define-fun s_2 () Bool false) + assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) ); + Range = 1; + } + else + { + // (define-fun s702 () (_ BitVec 4) #xe) + // (define-fun s1 () (_ BitVec 8) (bvneg #x7f)) + assert( !Smt_EntryIsName(Fan) ); + vFans2 = Smt_VecEntryNode(p, vFans, 3); + assert( Vec_IntSize(vFans2) == 3 ); + assert( !strcmp("_", Smt_VecEntryName(p, vFans2, 0)) ); + assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) ); + // get range + Fan = Vec_IntEntry(vFans2, 2); + assert( Smt_EntryIsName(Fan) ); + pRange = Smt_EntryName(p, Fan); + Range = atoi(pRange); + } + + iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), Range, pName ); + assert( iObj ); + ABC_FREE( pName_glb ); + } + // collect assertion outputs else if ( Abc_Lit2Var(Fan) == SMT_PRS_ASSERT ) { @@ -1321,6 +1449,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) //(assert (not (= s0 #x00))) assert( Vec_IntSize(vFans) == 2 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_ASSERT) ); + pNtk->nAssert++; // added iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 1), -1, NULL ); if ( iObj == 0 ) { @@ -1336,6 +1465,9 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // build AND of asserts if ( Vec_IntSize(vAsserts) == 1 ) iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, 1, vAsserts, "miter" ); + // added: 0 asserts + else if ( Vec_IntSize(vAsserts) == 0 ) + iObj = Smt_PrsBuildConstant( pNtk, "#b1", 1, "miter" ); else { iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vAsserts), vAsserts, NULL ); @@ -1413,18 +1545,35 @@ static inline char * Smt_PrsLoadFile( char * pFileName, char ** ppLimit ) static inline int Smt_PrsRemoveComments( char * pBuffer, char * pLimit ) { char * pTemp; int nCount1 = 0, nCount2 = 0, fHaveBar = 0; + int backslash = 0; for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ ) { if ( *pTemp == '(' ) - nCount1++; + { if ( !fHaveBar ) nCount1++; } else if ( *pTemp == ')' ) - nCount2++; + { if ( !fHaveBar ) nCount2++; } else if ( *pTemp == '|' ) fHaveBar ^= 1; else if ( *pTemp == ';' && !fHaveBar ) while ( *pTemp && *pTemp != '\n' ) *pTemp++ = ' '; + // added: hack to remove quotes + else if ( *pTemp == '\"' && *(pTemp-1) != '\\' && !fHaveBar ) + { + *pTemp++ = ' '; + while ( *pTemp && (*pTemp != '\"' || backslash)) + { + if (*pTemp == '\\') + backslash = 1; + else + backslash = 0; + *pTemp++ = ' '; + } + // remove the last quote symbol + *pTemp = ' '; + } } + if ( nCount1 != nCount2 ) printf( "The input SMTLIB file has different number of opening and closing parentheses (%d and %d).\n", nCount1, nCount2 ); else if ( nCount1 == 0 ) @@ -1455,7 +1604,6 @@ static inline void Smt_PrsFree( Smt_Prs_t * p ) Vec_IntErase( &p->vStack ); Vec_IntErase( &p->vTempFans ); //Vec_WecErase( &p->vDepth ); - Vec_WecErase( &p->vObjs ); ABC_FREE( p ); } @@ -1499,6 +1647,15 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ ) { Smt_PrsSkipSpaces( p ); + if ( *p->pCur == '|' ) + { + *p->pCur = ' '; + while ( *p->pCur && *p->pCur != '|' ) + *p->pCur++ = ' '; + if ( *p->pCur == '|' ) + *p->pCur = ' '; + continue; + } if ( *p->pCur == '(' ) { // add new node at this depth @@ -1524,12 +1681,13 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) { // remove strange characters (this can lead to name clashes) int iToken; + /* commented out for SMT comp char * pTemp; if ( *pStart == '?' ) *pStart = '_'; for ( pTemp = pStart; pTemp < p->pCur; pTemp++ ) if ( *pTemp == '.' ) - *pTemp = '_'; + *pTemp = '_';*/ // create and save token for this string iToken = Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur--, NULL ); Vec_IntPush( Vec_WecEntry(&p->vObjs, Vec_IntEntryLast(&p->vStack)), Abc_Var2Lit(iToken, 1) ); -- cgit v1.2.3 From 7d82819d519595854c4e1b9dbf99d91e1d2ab9f9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 15:17:02 -0800 Subject: Adding visualization of word-level networks Wlc_Ntk_t. --- src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 12 +- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcCom.c | 116 ++++++++++++++++ src/base/wlc/wlcNtk.c | 162 ++++++++++++++++++++++- src/base/wlc/wlcReadVer.c | 2 +- src/base/wlc/wlcShow.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 617 insertions(+), 11 deletions(-) create mode 100644 src/base/wlc/wlcShow.c (limited to 'src') diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index 5a95a63f..ae7899ec 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -7,6 +7,7 @@ SRC += src/base/wlc/wlcAbs.c \ src/base/wlc/wlcReadSmt.c \ src/base/wlc/wlcReadVer.c \ src/base/wlc/wlcSim.c \ + src/base/wlc/wlcShow.c \ src/base/wlc/wlcStdin.c \ src/base/wlc/wlcWin.c \ src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 6f64b47a..e4a818e5 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -157,6 +157,7 @@ struct Wlc_Ntk_t_ Vec_Int_t vTravIds; // trav IDs of the objects Vec_Int_t vCopies; // object first bits Vec_Int_t vBits; // object mapping into AIG nodes + Vec_Int_t vLevels; // object levels }; static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } @@ -206,6 +207,8 @@ static inline int Wlc_ObjSign( Wlc_Obj_t * p ) static inline int * Wlc_ObjConstValue( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_CONST); return Wlc_ObjFanins(p); } static inline int Wlc_ObjTableId( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_TABLE); return p->Fanins[1]; } static inline word * Wlc_ObjTable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return (word *)Vec_PtrEntry( p->vTables, Wlc_ObjTableId(pObj) ); } +static inline int Wlc_ObjLevelId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vLevels, iObj ); } +static inline int Wlc_ObjLevel( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_ObjLevelId( p, Wlc_ObjId(p, pObj) ); } static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vCopies, p->nObjsAlloc, 0 ); } static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; } @@ -230,6 +233,8 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) #define Wlc_NtkForEachObj( p, pObj, i ) \ for ( i = 1; (i < Wlc_NtkObjNumMax(p)) && (((pObj) = Wlc_NtkObj(p, i)), 1); i++ ) +#define Wlc_NtkForEachObjReverse( p, pObj, i ) \ + for ( i = Wlc_NtkObjNumMax(p) - 1; (i > 0) && (((pObj) = Wlc_NtkObj(p, i)), 1); i-- ) #define Wlc_NtkForEachObjVec( vVec, p, pObj, i ) \ for ( i = 0; (i < Vec_IntSize(vVec)) && (((pObj) = Wlc_NtkObj(p, Vec_IntEntry(vVec, i))), 1); i++ ) #define Wlc_NtkForEachPi( p, pPi, i ) \ @@ -266,6 +271,7 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i /*=== wlcCom.c ========================================================*/ extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ +extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); extern int Wlc_ObjCreate( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg, Vec_Int_t * vFanins ); @@ -275,12 +281,16 @@ extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj ); extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type ); extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ); extern void Wlc_NtkFree( Wlc_Ntk_t * p ); +extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ); +extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ); extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ); extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray ); extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); +extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 73ff7328..368652d6 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p ); + pNew = Wlc_NtkDupDfs( p, 0 ); Wlc_NtkTransferNames( pNew, p ); return pNew; } @@ -278,7 +278,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p ); + pNew = Wlc_NtkDupDfs( p, 0 ); Wlc_NtkTransferNames( pNew, p ); return pNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 2828fea3..316d2883 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -31,8 +31,10 @@ ABC_NAMESPACE_IMPL_START static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -68,8 +70,10 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); @@ -332,6 +336,70 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, iOutput = -1, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Ovh" ) ) != EOF ) + { + switch ( c ) + { + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + iOutput = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( iOutput < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + if ( iOutput < 0 || iOutput >= Wlc_NtkPoNum(pNtk) ) + { + Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkPoNum(pNtk) ); + return 0; + } + printf( "Extracting output %d.\n", iOutput ); + Wlc_NtkMarkCone( pNtk, iOutput ); + pNtk = Wlc_NtkDupDfs( pNtk, 1 ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%cone [-O num] [-vh]\n" ); + Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); + Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] @@ -481,6 +549,54 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandShow( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold ); + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + // set defaults + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + Wlc_NtkShow( pNtk, NULL ); + return 0; + +usage: + Abc_Print( -2, "usage: %%show [-h]\n" ); + Abc_Print( -2, " visualizes the network structure using DOT and GSVIEW\n" ); +#ifdef WIN32 + Abc_Print( -2, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); + Abc_Print( -2, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); +#endif + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index a0799ba0..fa0074d3 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -88,6 +88,8 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { NULL // 54: unused }; +char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -224,6 +226,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vValues.pArray ); ABC_FREE( p->vCopies.pArray ); ABC_FREE( p->vBits.pArray ); + ABC_FREE( p->vLevels.pArray ); ABC_FREE( p->pInits ); ABC_FREE( p->pObjs ); ABC_FREE( p->pName ); @@ -244,6 +247,81 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p ) return Mem; } +/**Function************************************************************* + + Synopsis [Assigns object levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, k, iFanin, Level, LevelMax = 0; + Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObj( p, pObj, i ) + { + Level = 0; + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Level = Abc_MaxInt( Level, Wlc_ObjLevelId(p, iFanin) + 1 ); + Vec_IntWriteEntry( &p->vLevels, i, Level ); + LevelMax = Abc_MaxInt( LevelMax, Level ); + } + return LevelMax; +} +int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, k, iFanin, Level, LevelMax = 0; + Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObjReverse( p, pObj, i ) + { + if ( Wlc_ObjIsCi(pObj) ) + continue; + Level = Wlc_ObjLevel(p, pObj) + 1; + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Vec_IntUpdateEntry( &p->vLevels, iFanin, Level ); + LevelMax = Abc_MaxInt( LevelMax, Level ); + } + // reverse the values + Wlc_NtkForEachObj( p, pObj, i ) + Vec_IntWriteEntry( &p->vLevels, i, LevelMax - Wlc_ObjLevelId(p, i) ); + Wlc_NtkForEachCi( p, pObj, i ) + Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), 0 ); + return LevelMax; +} + +/**Function************************************************************* + + Synopsis [Collects statistics for each side of the miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) +{ + Wlc_Obj_t * pObj; + int n, i; + if ( Wlc_NtkPoNum(p) != 2 ) + return; + for ( n = 0; n < 2; n++ ) + { + Wlc_NtkMarkCone( p, n ); + Wlc_NtkForEachObj( p, pObj, i ) + if ( pObj->Mark ) + nObjs[n][pObj->Type]++; + } + Wlc_NtkCleanMarks( p ); +} + /**Function************************************************************* Synopsis [Prints distribution of operator types.] @@ -300,11 +378,13 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty } void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) { + int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0; Vec_Ptr_t * vTypes, * vOccurs; Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER ); word Sign; int i, k, s, s0, s1; + Wlc_NtkCollectStats( p, nObjs ); // allocate statistics arrays vTypes = Vec_PtrStart( WLC_OBJ_NUMBER ); vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER ); @@ -435,28 +515,40 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) else if ( pObj->Type == WLC_OBJ_ARI_SQUARE ) Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQUARE, 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) ); } - if ( nCountRange ) + if ( nCountRange && Vec_IntSize(&p->vNameIds) > 0 ) { printf( "Warning: %d objects of the design have non-zero-based ranges.\n", nCountRange ); printf( "In particular, object %6d with name \"%s\" has range %d=[%d:%d]\n", Wlc_ObjId(p, pObjRange), Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg ); } // print by occurrence - printf( "ID : name occurrence and2 (occurrence)=. ...\n" ); + printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", Wlc_NtkPoNum(p) == 2 ? " Left Share Right":"" ); for ( i = 0; i < WLC_OBJ_NUMBER; i++ ) { Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i ); Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, i ); if ( p->nObjs[i] == 0 ) continue; - printf( "%2d : %-8s %6d%8d ", i, Wlc_Names[i], p->nObjs[i], Vec_IntEntry(vAnds, i) ); + printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] ); + if ( Wlc_NtkPoNum(p) == 2 ) + { + printf( " " ); + printf( "%6d", nObjs[0][i] ); + printf( "%6d", nObjs[0][i]+nObjs[1][i]-p->nObjs[i] ); + printf( "%6d", nObjs[1][i] ); + } + printf( "%8d ", Vec_IntEntry(vAnds, i) ); // sort by occurence Wlc_NtkPrintDistribSortOne( vTypes, vOccurs, i ); Vec_WrdForEachEntry( vType, Sign, k ) { Wlc_NtkPrintDistribFromSign( Sign, &s, &s0, &s1 ); if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) ) + { printf( "\n " ); + if ( Wlc_NtkPoNum(p) == 2 ) + printf( " " ); + } printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) ); printf( "%s%d", Abc_LitIsCompl(s)?"-":"", Abc_Lit2Var(s) ); if ( s0 ) @@ -623,7 +715,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -634,11 +726,14 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ) pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; Wlc_NtkForEachCi( p, pObj, i ) - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + if ( !fMarked || pObj->Mark ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + if ( !fMarked || pObj->Mark ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); + if ( !fMarked || pObj->Mark ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); if ( p->vInits ) pNew->vInits = Vec_IntDup( p->vInits ); if ( p->pInits ) @@ -666,6 +761,59 @@ void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) pNew->vTables = p->vTables; p->vTables = NULL; } +/**Function************************************************************* + + Synopsis [Select the cone of the given output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i; + Wlc_NtkForEachObj( p, pObj, i ) + pObj->Mark = 0; +} +void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Wlc_ObjIsCi(pObj) ) + { + if ( !Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); +} +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) +{ + Vec_Int_t * vFlops; + Wlc_Obj_t * pObj; + int i, CiId, CoId; + Wlc_NtkCleanMarks( p ); + Wlc_NtkForEachPi( p, pObj, i ) + pObj->Mark = 1; + vFlops = Vec_IntAlloc( 100 ); + Wlc_NtkForEachPo( p, pObj, i ) + if ( i == iPo ) + Wlc_NtkMarkCone_rec( p, pObj, vFlops ); + Vec_IntForEachEntry( vFlops, CiId, i ) + { + CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); + Wlc_NtkMarkCone_rec( p, Wlc_NtkCo(p, CoId), vFlops ); + } + Vec_IntFree( vFlops ); +} + /**Function************************************************************* Synopsis [Duplicates the network by copying each node.] diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index fa3efacd..2959f4a1 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0 ); Wlc_NtkTransferNames( pNtk, p->pNtk ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c new file mode 100644 index 00000000..dd25c7a3 --- /dev/null +++ b/src/base/wlc/wlcShow.c @@ -0,0 +1,331 @@ +/**CFile**************************************************************** + + FileName [wlcShow.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Parses several flavors of word-level Verilog.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcShow.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Writes the graph structure of WLC for DOT.] + + Description [Useful for graph visualization using tools such as GraphViz: + http://www.graphviz.org/] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) +{ + FILE * pFile; + Wlc_Obj_t * pNode; + int LevelMax, Prev, Level, i; + + if ( Wlc_NtkObjNum(p) > 500 ) + { + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 500 ); + return; + } + if ( (pFile = fopen( pFileName, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); + return; + } + + // mark the nodes + if ( vBold ) + Wlc_NtkForEachObjVec( vBold, p, pNode, i ) + pNode->Mark = 1; + + // compute levels + LevelMax = 1 + Wlc_NtkCreateLevelsRev( p ); + + // write the DOT header + fprintf( pFile, "# %s\n", "WLC structure generated by ABC" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "digraph WLC {\n" ); + fprintf( pFile, "size = \"7.5,10\";\n" ); +// fprintf( pFile, "ranksep = 0.5;\n" ); +// fprintf( pFile, "nodesep = 0.5;\n" ); + fprintf( pFile, "center = true;\n" ); +// fprintf( pFile, "orientation = landscape;\n" ); +// fprintf( pFile, "edge [fontsize = 10];\n" ); +// fprintf( pFile, "edge [dir = none];\n" ); + fprintf( pFile, "edge [dir = back];\n" ); + fprintf( pFile, "\n" ); + + // labels on the left of the picture + fprintf( pFile, "{\n" ); + fprintf( pFile, " node [shape = plaintext];\n" ); + fprintf( pFile, " edge [style = invis];\n" ); + fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); + fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); + // generate node names with labels + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + fprintf( pFile, " [label = " ); + // label name + fprintf( pFile, "\"" ); + fprintf( pFile, "\"" ); + fprintf( pFile, "];\n" ); + } + + // genetate the sequence of visible/invisible nodes to mark levels + fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + // the connector + if ( Level != 0 ) + fprintf( pFile, " ->" ); + else + fprintf( pFile, ";" ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate title box on top + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle1;\n" ); + fprintf( pFile, " title1 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=20,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "%s", "WLC structure generated by ABC" ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "Benchmark \\\"%s\\\". ", p->pName ); +// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate statistics box + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle2;\n" ); + fprintf( pFile, " title2 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=18,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkPiNum(p)-Wlc_NtkPoNum(p)-Wlc_NtkFfNum(p), LevelMax-1 ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate the COs + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", LevelMax ); + // generate the CO nodes + Wlc_NtkForEachCo( p, pNode, i ) + { + fprintf( pFile, " NodePo%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", "invtriangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate nodes of each rank + for ( Level = LevelMax - 1; Level > 0; Level-- ) + { + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", Level ); + Wlc_NtkForEachObj( p, pNode, i ) + { + if ( (int)Wlc_ObjLevel(p, pNode) != Level ) + continue; + + if ( pNode->Type == WLC_OBJ_CONST ) + { + fprintf( pFile, " Node%d [label = \"0x", i ); + Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 ); + fprintf( pFile, "\"" ); + } + else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_MUX ) + fprintf( pFile, " Node%d [label = \"%d\"", i, Wlc_ObjRange(pNode) ); + else if ( pNode->Type >= WLC_OBJ_LOGIC_NOT && pNode->Type <= WLC_OBJ_COMP_MOREEQU ) + fprintf( pFile, " Node%d [label = \"%s\"", i, Wlc_ObjTypeName(pNode) ); + else + fprintf( pFile, " Node%d [label = \"%s %d\"", i, Wlc_ObjTypeName(pNode), Wlc_ObjRange(pNode) ); + + if ( pNode->Type == WLC_OBJ_ARI_MULTI ) + fprintf( pFile, ", shape = doublecircle" ); + else if ( pNode->Type >= WLC_OBJ_COMP_EQU && pNode->Type <= WLC_OBJ_COMP_MOREEQU ) + fprintf( pFile, ", shape = diamond" ); + else if ( pNode->Type == WLC_OBJ_BIT_SELECT || pNode->Type == WLC_OBJ_BIT_CONCAT ) + fprintf( pFile, ", shape = box" ); + else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_BIT_ZEROPAD || pNode->Type == WLC_OBJ_BIT_SIGNEXT ) + fprintf( pFile, ", shape = triangle" ); + else if ( pNode->Type == WLC_OBJ_MUX ) + fprintf( pFile, ", shape = trapezium" ); + else + fprintf( pFile, ", shape = ellipse" ); + + if ( vBold ? pNode->Mark : ((pNode->Type >= WLC_OBJ_ARI_ADD && pNode->Type <= WLC_OBJ_ARI_SQUARE) || pNode->Type == WLC_OBJ_BIT_NOT) ) + fprintf( pFile, ", style = filled" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + } + + // generate the CI nodes + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", 0 ); + // generate the CI nodes + Wlc_NtkForEachCi( p, pNode, i ) + { + fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate invisible edges from the square down + fprintf( pFile, "title1 -> title2 [style = invis];\n" ); + Wlc_NtkForEachCo( p, pNode, i ) + fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) ); + // generate invisible edges among the COs + Prev = -1; + Wlc_NtkForEachCo( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); + Prev = Wlc_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Wlc_NtkForEachCi( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); + Prev = Wlc_ObjId(p, pNode); + } + + // generate edges + Wlc_NtkForEachObj( p, pNode, i ) + { + int k, iFanin; + if ( Wlc_ObjIsCi(pNode) ) + continue; + if ( Wlc_ObjIsCo(pNode) ) + { + // generate the edge from this node to the next + fprintf( pFile, "NodePo%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + // generate the edge from this node to the next + Wlc_ObjForEachFanin( pNode, iFanin, k ) + { + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", iFanin ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + + // unmark nodes + if ( vBold ) + Wlc_NtkCleanMarks( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold ) +{ + extern void Abc_ShowFile( char * FileNameDot ); + FILE * pFile; + char FileNameDot[200]; + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(p->pName, ".dot") ); + // check that the file can be opened + if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot ); + return; + } + fclose( pFile ); + // generate the file + Wlc_NtkDumpDot( p, FileNameDot, vBold ); + // visualize the file + Abc_ShowFile( FileNameDot ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3 From 64d7119ddc7fb1720542b8071f490763466a5d31 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 21:43:28 -0800 Subject: Adding visualization of word-level networks Wlc_Ntk_t. --- src/base/wlc/wlc.h | 13 ++- src/base/wlc/wlcAbs.c | 6 +- src/base/wlc/wlcCom.c | 156 ++++++++++++++++++++++--------- src/base/wlc/wlcNtk.c | 226 ++++++++++++++++++++++++++++++++++++--------- src/base/wlc/wlcReadVer.c | 5 +- src/base/wlc/wlcShow.c | 38 ++++---- src/base/wlc/wlcWriteVer.c | 2 +- 7 files changed, 331 insertions(+), 115 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index e4a818e5..b898078f 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -221,7 +221,8 @@ static inline int Wlc_NtkHasNameId( Wlc_Ntk_t * p ) static inline void Wlc_ObjSetNameId( Wlc_Ntk_t * p, int iObj, int i ) { Vec_IntWriteEntry( &p->vNameIds, iObj, i ); } static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vNameIds, iObj ); } -static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkCoNum(p) - Wlc_NtkCiNum(p) + Wlc_ObjCiId(pObj)); } +static inline Wlc_Obj_t * Wlc_ObjFo2Fi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkPoNum(p) + Wlc_ObjCiId(pObj) - Wlc_NtkPiNum(p)); } +static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) { return iCoId < Wlc_NtkPoNum(p) ? Wlc_NtkPo(p, iCoId) : Wlc_NtkCi(p, Wlc_NtkPiNum(p) + iCoId - Wlc_NtkPoNum(p)); } //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// @@ -283,15 +284,19 @@ extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int extern void Wlc_NtkFree( Wlc_Ntk_t * p ); extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ); extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ); +extern int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ); extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ); extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray ); extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); -extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ); +extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); +extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); -extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); +extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 368652d6..ce6b8de9 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,8 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0 ); - Wlc_NtkTransferNames( pNew, p ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } @@ -278,8 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0 ); - Wlc_NtkTransferNames( pNew, p ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 316d2883..9f36ad56 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -28,21 +28,22 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } @@ -67,21 +68,22 @@ static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) ******************************************************************************/ void Wlc_Init( Abc_Frame_t * pAbc ) { - Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); - - Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); + + Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); } /**Function******************************************************************** @@ -287,15 +289,20 @@ usage: int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int fShowCones = 0; int fShowMulti = 0; int fShowAdder = 0; int fDistrib = 0; + int fTwoSides = 0; int c, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "madvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "cmadtvh" ) ) != EOF ) { switch ( c ) { + case 'c': + fShowCones ^= 1; + break; case 'm': fShowMulti ^= 1; break; @@ -305,6 +312,9 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'd': fDistrib ^= 1; break; + case 't': + fTwoSides ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -319,19 +329,23 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandPs(): There is no current design.\n" ); return 0; } - Wlc_NtkPrintStats( pNtk, fDistrib, fVerbose ); + Wlc_NtkPrintStats( pNtk, fDistrib, fTwoSides, fVerbose ); + if ( fShowCones ) + Wlc_NtkProfileCones( pNtk ); if ( fShowMulti ) Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_MULTI ); if ( fShowAdder ) Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_ADD ); return 0; usage: - Abc_Print( -2, "usage: %%ps [-madvh]\n" ); + Abc_Print( -2, "usage: %%ps [-cmadtvh]\n" ); Abc_Print( -2, "\t prints statistics\n" ); - Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" ); - Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" ); - Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle printing cones [default = %s]\n", fShowCones? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" ); + Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle printing stats for LHS and RHS [default = %s]\n", fTwoSides? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -350,9 +364,10 @@ usage: int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, iOutput = -1, fVerbose = 0; + int c, iOutput = -1, fSeq = 0, fVerbose = 0; + char * pName; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Ovh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Osvh" ) ) != EOF ) { switch ( c ) { @@ -367,6 +382,9 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( iOutput < 0 ) goto usage; break; + case 's': + fSeq ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -381,20 +399,24 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - if ( iOutput < 0 || iOutput >= Wlc_NtkPoNum(pNtk) ) + if ( iOutput < 0 || iOutput >= Wlc_NtkCoNum(pNtk) ) { - Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkPoNum(pNtk) ); + Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkCoNum(pNtk) ); return 0; } - printf( "Extracting output %d.\n", iOutput ); - Wlc_NtkMarkCone( pNtk, iOutput ); - pNtk = Wlc_NtkDupDfs( pNtk, 1 ); + printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); + pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); + Wlc_NtkMarkCone( pNtk, iOutput, fSeq ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); + ABC_FREE( pNtk->pName ); + pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); return 0; usage: - Abc_Print( -2, "usage: %%cone [-O num] [-vh]\n" ); + Abc_Print( -2, "usage: %%cone [-O num] [-svh]\n" ); Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-s : toggle performing extracting sequential cones [default = %s]\n", fSeq? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -549,6 +571,50 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" ); + return 0; + } + Wlc_NtkShortNames( pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%short_names [-vh]\n" ); + Abc_Print( -2, "\t derives short names for all objects of the network\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index fa0074d3..822c2eb5 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -314,13 +314,23 @@ void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) return; for ( n = 0; n < 2; n++ ) { - Wlc_NtkMarkCone( p, n ); + Wlc_NtkMarkCone( p, n, 1 ); Wlc_NtkForEachObj( p, pObj, i ) if ( pObj->Mark ) nObjs[n][pObj->Type]++; } Wlc_NtkCleanMarks( p ); } +int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, Count = 0; + Wlc_NtkMarkCone( p, -1, 1 ); + Wlc_NtkForEachPi( p, pObj, i ) + Count += pObj->Mark; + Wlc_NtkCleanMarks( p ); + return Count; +} /**Function************************************************************* @@ -376,7 +386,7 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty Vec_WrdReverseOrder( vType ); Vec_WrdReverseOrder( vOccur ); } -void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) +void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fTwoSides, int fVerbose ) { int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0; @@ -384,7 +394,10 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER ); word Sign; int i, k, s, s0, s1; - Wlc_NtkCollectStats( p, nObjs ); + if ( Wlc_NtkPoNum(p) != 2 ) + fTwoSides = 0; + if ( fTwoSides ) + Wlc_NtkCollectStats( p, nObjs ); // allocate statistics arrays vTypes = Vec_PtrStart( WLC_OBJ_NUMBER ); vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER ); @@ -489,11 +502,11 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) else if ( pObj->Type == WLC_OBJ_REDUCT_XOR ) Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_XOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NAND ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NOR ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NXOR ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); else if ( pObj->Type == WLC_OBJ_ARI_ADD ) Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_ADD, 9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) ); else if ( pObj->Type == WLC_OBJ_ARI_SUB ) @@ -522,7 +535,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg ); } // print by occurrence - printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", Wlc_NtkPoNum(p) == 2 ? " Left Share Right":"" ); + printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", fTwoSides ? " Left Share Right":"" ); for ( i = 0; i < WLC_OBJ_NUMBER; i++ ) { Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i ); @@ -530,11 +543,12 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) if ( p->nObjs[i] == 0 ) continue; printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] ); - if ( Wlc_NtkPoNum(p) == 2 ) + if ( fTwoSides ) { + int nTotal = i == WLC_OBJ_PI ? Wlc_NtkCountRealPis(p) : p->nObjs[i]; printf( " " ); printf( "%6d", nObjs[0][i] ); - printf( "%6d", nObjs[0][i]+nObjs[1][i]-p->nObjs[i] ); + printf( "%6d", nObjs[0][i]+nObjs[1][i]-nTotal ); printf( "%6d", nObjs[1][i] ); } printf( "%8d ", Vec_IntEntry(vAnds, i) ); @@ -546,7 +560,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) ) { printf( "\n " ); - if ( Wlc_NtkPoNum(p) == 2 ) + if ( fTwoSides ) printf( " " ); } printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) ); @@ -627,11 +641,11 @@ void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ) Wlc_NtkPrintNode( p, pObj ); } } -void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) +void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ) { int i; printf( "%-20s : ", p->pName ); - printf( "PI = %4d ", Wlc_NtkPiNum(p) ); + printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) ); printf( "PO = %4d ", Wlc_NtkPoNum(p) ); printf( "FF = %4d ", Wlc_NtkFfNum(p) ); printf( "Obj = %6d ", Wlc_NtkObjNum(p) ); @@ -639,7 +653,7 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) printf( "\n" ); if ( fDistrib ) { - Wlc_NtkPrintDistrib( p, fVerbose ); + Wlc_NtkPrintDistrib( p, fTwoSides, fVerbose ); return; } if ( !fVerbose ) @@ -656,6 +670,41 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) } } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) +{ + int i; + assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) ); + assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) ); + assert( pNew->pManName == NULL && p->pManName != NULL ); + Wlc_NtkCleanNameId( pNew ); + for ( i = 0; i < p->nObjsAlloc; i++ ) + if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) ) + Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) ); + pNew->pManName = p->pManName; + p->pManName = NULL; + Vec_IntErase( &p->vNameIds ); + // transfer table + pNew->pMemTable = p->pMemTable; p->pMemTable = NULL; + pNew->vTables = p->vTables; p->vTables = NULL; +} +char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ) +{ + static char pBuffer[1000]; + sprintf( pBuffer, "%s_o%d_%s", p->pName, iCoId, fSeq ? "seq": "comb" ); + return pBuffer; +} + /**Function************************************************************* Synopsis [Duplicates the network in a topological order.] @@ -715,51 +764,43 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; Vec_Int_t * vFanins; int i; - Wlc_NtkCleanCopy( p ); vFanins = Vec_IntAlloc( 100 ); + Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; Wlc_NtkForEachCi( p, pObj, i ) if ( !fMarked || pObj->Mark ) + { + unsigned Type = pObj->Type; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) - Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); - if ( p->vInits ) - pNew->vInits = Vec_IntDup( p->vInits ); - if ( p->pInits ) - pNew->pInits = Abc_UtilStrsav( p->pInits ); + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); Vec_IntFree( vFanins ); + if ( !fMarked ) + { + if ( p->vInits ) + pNew->vInits = Vec_IntDup( p->vInits ); + if ( p->pInits ) + pNew->pInits = Abc_UtilStrsav( p->pInits ); + } if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Wlc_NtkTransferNames( pNew, p ); return pNew; } -void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) -{ - int i; - assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) ); - assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) ); - assert( pNew->pManName == NULL && p->pManName != NULL ); - Wlc_NtkCleanNameId( pNew ); - for ( i = 0; i < p->nObjsAlloc; i++ ) - if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) ) - Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) ); - pNew->pManName = p->pManName; - p->pManName = NULL; - Vec_IntErase( &p->vNameIds ); - // transfer table - pNew->pMemTable = p->pMemTable; p->pMemTable = NULL; - pNew->vTables = p->vTables; p->vTables = NULL; -} /**Function************************************************************* @@ -779,6 +820,30 @@ void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ) Wlc_NtkForEachObj( p, pObj, i ) pObj->Mark = 0; } +int Wlc_NtkCountMarked( Wlc_Ntk_t * p, int * pnPis, int * pnFos, int * pnAdders, int * pnMults ) +{ + Wlc_Obj_t * pObj; + int i, nNodes = 0; + *pnPis = *pnFos = *pnAdders = *pnMults = 0; + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( !pObj->Mark ) + continue; + if ( Wlc_ObjIsPi(pObj) ) + (*pnPis)++; + else if ( Wlc_ObjIsCi(pObj) ) + (*pnFos)++; + else if ( pObj->Mark ) + { + nNodes++; + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB ) + (*pnAdders)++; + else if ( pObj->Type == WLC_OBJ_ARI_MULTI ) + (*pnMults)++; + } + } + return nNodes; +} void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) { int i, iFanin; @@ -794,18 +859,19 @@ void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); } -void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ) { Vec_Int_t * vFlops; Wlc_Obj_t * pObj; int i, CiId, CoId; Wlc_NtkCleanMarks( p ); - Wlc_NtkForEachPi( p, pObj, i ) - pObj->Mark = 1; +// Wlc_NtkForEachPi( p, pObj, i ) +// pObj->Mark = 1; vFlops = Vec_IntAlloc( 100 ); - Wlc_NtkForEachPo( p, pObj, i ) - if ( i == iPo ) + Wlc_NtkForEachCo( p, pObj, i ) + if ( iCoId == -1 || i == iCoId ) Wlc_NtkMarkCone_rec( p, pObj, vFlops ); + if ( fSeq ) Vec_IntForEachEntry( vFlops, CiId, i ) { CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); @@ -813,6 +879,24 @@ void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) } Vec_IntFree( vFlops ); } +void Wlc_NtkProfileCones( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, nPis, nFos, nNodes, nAdders, nMults; + Wlc_NtkForEachCo( p, pObj, i ) + { + Wlc_NtkMarkCone( p, i, 0 ); + nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults ); + printf( "Cone %5d : ", i ); + printf( "PI = %4d ", nPis ); + printf( "FO = %4d ", nFos ); + printf( "Node = %6d ", nNodes ); + printf( "Add/Sub = %4d ", nAdders ); + printf( "Mult = %4d ", nMults ); + printf( "\n" ); + } + Wlc_NtkCleanMarks( p ); +} /**Function************************************************************* @@ -871,6 +955,64 @@ Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Creates short names for all objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkShortNames( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + char pBuffer[100]; + int nDigits, NameId, fFound, i; + int nFlops = Wlc_NtkCoNum(p) - Wlc_NtkPoNum(p); + nDigits = Abc_Base10Log( nFlops ); + Wlc_NtkForEachCo( p, pObj, i ) + { + if ( Wlc_ObjIsPo(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "fi", nDigits, i - Wlc_NtkPoNum(p) ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + Wlc_NtkForEachCi( p, pObj, i ) + { + if ( Wlc_ObjIsPi(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "fo", nDigits, i - Wlc_NtkPiNum(p) ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkPoNum(p) ); + Wlc_NtkForEachPo( p, pObj, i ) + { + sprintf( pBuffer, "%s%0*d", "po", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkPiNum(p) ); + Wlc_NtkForEachPi( p, pObj, i ) + { + sprintf( pBuffer, "%s%0*d", "pi", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkObjNum(p) ); + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( Wlc_ObjIsCi(pObj) || Wlc_ObjIsCo(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "n", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 2959f4a1..e4a65ecf 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -28,7 +28,7 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// // Word-level Verilog file parser -#define WLV_PRS_MAX_LINE 1000 +#define WLV_PRS_MAX_LINE 10000 typedef struct Wlc_Prs_t_ Wlc_Prs_t; struct Wlc_Prs_t_ @@ -1265,8 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0 ); - Wlc_NtkTransferNames( pNtk, p->pNtk ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index dd25c7a3..8ef21d29 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -143,7 +143,7 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkPiNum(p)-Wlc_NtkPoNum(p)-Wlc_NtkFfNum(p), LevelMax-1 ); + fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkCiNum(p), LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -159,8 +159,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) // generate the CO nodes Wlc_NtkForEachCo( p, pNode, i ) { - fprintf( pFile, " NodePo%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); - fprintf( pFile, ", shape = %s", "invtriangle" ); + pNode = Wlc_ObjCo2PoFo(p, i); + fprintf( pFile, " NodePo%d [label = \"%s_in %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", i < Wlc_NtkPoNum(p) ? "invtriangle" : "box" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } @@ -224,7 +225,7 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_NtkForEachCi( p, pNode, i ) { fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); - fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", shape = %s", i < Wlc_NtkPiNum(p) ? "triangle" : "box" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } @@ -235,11 +236,15 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) // generate invisible edges from the square down fprintf( pFile, "title1 -> title2 [style = invis];\n" ); Wlc_NtkForEachCo( p, pNode, i ) + { + pNode = Wlc_ObjCo2PoFo( p, i ); fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) ); + } // generate invisible edges among the COs Prev = -1; Wlc_NtkForEachCo( p, pNode, i ) { + pNode = Wlc_ObjCo2PoFo( p, i ); if ( i > 0 ) fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); Prev = Wlc_ObjId(p, pNode); @@ -254,22 +259,21 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) } // generate edges + Wlc_NtkForEachCo( p, pNode, i ) + { + fprintf( pFile, "NodePo%d", Wlc_ObjId(p, Wlc_ObjCo2PoFo(p, i)) ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Wlc_ObjId(p, pNode) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "solid" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } Wlc_NtkForEachObj( p, pNode, i ) { int k, iFanin; if ( Wlc_ObjIsCi(pNode) ) continue; - if ( Wlc_ObjIsCo(pNode) ) - { - // generate the edge from this node to the next - fprintf( pFile, "NodePo%d", i ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", i ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "bold" ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - } // generate the edge from this node to the next Wlc_ObjForEachFanin( pNode, iFanin, k ) { @@ -277,7 +281,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", iFanin ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "solid" ); + if ( pNode->Type == WLC_OBJ_MUX && k == 0 ) + fprintf( pFile, ", style = %s", "bold" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index cf0e528f..c4dee094 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -409,7 +409,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, " reg%d (", i ); fprintf( pFile, " .q( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) ); fprintf( pFile, " .qbar()," ); - fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFoToFi(p, pObj))) ); + fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj))) ); fprintf( pFile, " .clk( %s ),", "1\'b0" ); fprintf( pFile, " .arst( %s ),", "1\'b0" ); if ( p->vInits ) -- cgit v1.2.3 From c2b805dc85fa3c6e96cac04fa1d8ea182e9aab62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 22:22:22 -0800 Subject: Adding visualization of word-level networks Wlc_Ntk_t. --- src/base/wlc/wlc.h | 2 +- src/base/wlc/wlcCom.c | 28 ++++++++++++++++++++++------ src/base/wlc/wlcNtk.c | 15 ++++++++------- 3 files changed, 31 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index b898078f..d51b699c 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -293,7 +293,7 @@ extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); -extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 9f36ad56..82321d3b 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -364,10 +364,10 @@ usage: int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, iOutput = -1, fSeq = 0, fVerbose = 0; + int c, iOutput = -1, Range = 1, fAllPis = 0, fSeq = 0, fVerbose = 0; char * pName; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Osvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORisvh" ) ) != EOF ) { switch ( c ) { @@ -382,6 +382,20 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( iOutput < 0 ) goto usage; break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); + goto usage; + } + Range = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Range < 0 ) + goto usage; + break; + case 'i': + fAllPis ^= 1; + break; case 's': fSeq ^= 1; break; @@ -406,16 +420,18 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) } printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); - Wlc_NtkMarkCone( pNtk, iOutput, fSeq ); + Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); return 0; usage: - Abc_Print( -2, "usage: %%cone [-O num] [-svh]\n" ); - Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); - Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "usage: %%cone [-OR num] [-isvh]\n" ); + Abc_Print( -2, "\t extracts logic cone of one or more word-level outputs\n" ); + Abc_Print( -2, "\t-O num : zero-based index of the first word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-R num : total number of word-level outputs to extract [default = %d]\n", Range ); + Abc_Print( -2, "\t-i : toggle using support composed of all primary inputs [default = %s]\n", fAllPis? "yes": "no" ); Abc_Print( -2, "\t-s : toggle performing extracting sequential cones [default = %s]\n", fSeq? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 822c2eb5..bd00a570 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -314,7 +314,7 @@ void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) return; for ( n = 0; n < 2; n++ ) { - Wlc_NtkMarkCone( p, n, 1 ); + Wlc_NtkMarkCone( p, n, 1, 1, 0 ); Wlc_NtkForEachObj( p, pObj, i ) if ( pObj->Mark ) nObjs[n][pObj->Type]++; @@ -325,7 +325,7 @@ int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ) { Wlc_Obj_t * pObj; int i, Count = 0; - Wlc_NtkMarkCone( p, -1, 1 ); + Wlc_NtkMarkCone( p, -1, -1, 1, 0 ); Wlc_NtkForEachPi( p, pObj, i ) Count += pObj->Mark; Wlc_NtkCleanMarks( p ); @@ -859,17 +859,18 @@ void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); } -void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ) +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ) { Vec_Int_t * vFlops; Wlc_Obj_t * pObj; int i, CiId, CoId; Wlc_NtkCleanMarks( p ); -// Wlc_NtkForEachPi( p, pObj, i ) -// pObj->Mark = 1; + if ( fAllPis ) + Wlc_NtkForEachPi( p, pObj, i ) + pObj->Mark = 1; vFlops = Vec_IntAlloc( 100 ); Wlc_NtkForEachCo( p, pObj, i ) - if ( iCoId == -1 || i == iCoId ) + if ( iCoId == -1 || (i >= iCoId && i < iCoId + Range) ) Wlc_NtkMarkCone_rec( p, pObj, vFlops ); if ( fSeq ) Vec_IntForEachEntry( vFlops, CiId, i ) @@ -885,7 +886,7 @@ void Wlc_NtkProfileCones( Wlc_Ntk_t * p ) int i, nPis, nFos, nNodes, nAdders, nMults; Wlc_NtkForEachCo( p, pObj, i ) { - Wlc_NtkMarkCone( p, i, 0 ); + Wlc_NtkMarkCone( p, i, 1, 0, 0 ); nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults ); printf( "Cone %5d : ", i ); printf( "PI = %4d ", nPis ); -- cgit v1.2.3 From f701a0c659c57b8aa452bed93143a45cf5dcfeb8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 27 Jan 2017 10:48:56 -0800 Subject: Commenting out &mfs report message. --- src/aig/gia/giaMfs.c | 1 + src/base/wlc/wlcShow.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaMfs.c b/src/aig/gia/giaMfs.c index 3ff16978..3229e0d0 100644 --- a/src/aig/gia/giaMfs.c +++ b/src/aig/gia/giaMfs.c @@ -451,6 +451,7 @@ Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars ) nNodes = Sfm_NtkPerform( pNtk, pPars ); if ( nNodes == 0 ) { + if ( p->pManTime ) Abc_Print( 1, "The network is not changed by \"&mfs\".\n" ); pNew = Gia_ManDup( p ); pNew->vMapping = Vec_IntDup( p->vMapping ); diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index 8ef21d29..7914cd7a 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -49,9 +49,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_Obj_t * pNode; int LevelMax, Prev, Level, i; - if ( Wlc_NtkObjNum(p) > 500 ) + if ( Wlc_NtkObjNum(p) > 1000 ) { - fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 500 ); + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 1000 ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) -- cgit v1.2.3 From 596276152c0933f4251c53206ff1d98533b45ab2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 27 Jan 2017 15:22:23 -0800 Subject: Fixing non-reproducability related to floating-point numbers. --- src/aig/gia/giaJf.c | 14 ++++++++------ src/aig/gia/giaLf.c | 11 ++++++----- src/aig/gia/giaMf.c | 7 ++++--- src/aig/gia/giaNf.c | 17 +++++++++-------- 4 files changed, 27 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaJf.c b/src/aig/gia/giaJf.c index 2d75581d..205ab408 100644 --- a/src/aig/gia/giaJf.c +++ b/src/aig/gia/giaJf.c @@ -36,6 +36,7 @@ ABC_NAMESPACE_IMPL_START #define JF_LEAF_MAX 8 #define JF_WORD_MAX ((JF_LEAF_MAX > 6) ? 1 << (JF_LEAF_MAX-6) : 1) #define JF_CUT_MAX 16 +#define JF_EPSILON 0.005 typedef struct Jf_Cut_t_ Jf_Cut_t; struct Jf_Cut_t_ @@ -940,15 +941,16 @@ float Jf_CutCompareDelay( Jf_Cut_t * pOld, Jf_Cut_t * pNew ) { if ( pOld->Time != pNew->Time ) return pOld->Time - pNew->Time; if ( pOld->pCut[0] != pNew->pCut[0] ) return pOld->pCut[0] - pNew->pCut[0]; - if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow; +// if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow; + if ( pOld->Flow < pNew->Flow - JF_EPSILON ) return -1; + if ( pOld->Flow > pNew->Flow + JF_EPSILON ) return 1; return 0; } float Jf_CutCompareArea( Jf_Cut_t * pOld, Jf_Cut_t * pNew ) { -// float Epsilon = (float)0.001; -// if ( pOld->Flow > pNew->Flow + Epsilon ) return 1; -// if ( pOld->Flow < pNew->Flow - Epsilon ) return -1; - if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow; +// if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow; + if ( pOld->Flow < pNew->Flow - JF_EPSILON ) return -1; + if ( pOld->Flow > pNew->Flow + JF_EPSILON ) return 1; if ( pOld->pCut[0] != pNew->pCut[0] ) return pOld->pCut[0] - pNew->pCut[0]; if ( pOld->Time != pNew->Time ) return pOld->Time - pNew->Time; return 0; @@ -1367,7 +1369,7 @@ void Jf_ObjComputeBestCut( Jf_Man_t * p, Gia_Obj_t * pObj, int fEdge, int fEla ) if ( fEdge && !fEla ) Jf_CutSetCost(pCut, Jf_CutSize(pCut)); Area = fEla ? Jf_CutArea(p, pCut, fEdge) : Jf_CutFlow(p, pCut) + Jf_CutCost(pCut); - if ( pCutBest == NULL || AreaBest > Area || (AreaBest == Area && TimeBest > (Time = Jf_CutArr(p, pCut))) ) + if ( pCutBest == NULL || AreaBest > Area + JF_EPSILON || (AreaBest > Area - JF_EPSILON && TimeBest > (Time = Jf_CutArr(p, pCut))) ) pCutBest = pCut, AreaBest = Area, TimeBest = Time; } Vec_IntWriteEntry( &p->vArr, iObj, Jf_CutArr(p, pCutBest) ); diff --git a/src/aig/gia/giaLf.c b/src/aig/gia/giaLf.c index 7973966a..2c216a9b 100644 --- a/src/aig/gia/giaLf.c +++ b/src/aig/gia/giaLf.c @@ -36,6 +36,7 @@ ABC_NAMESPACE_IMPL_START #define LF_NO_LEAF 255 #define LF_CUT_WORDS (4+LF_LEAF_MAX/2) #define LF_TT_WORDS ((LF_LEAF_MAX > 6) ? 1 << (LF_LEAF_MAX-6) : 1) +#define LF_EPSILON 0.005 typedef struct Lf_Cut_t_ Lf_Cut_t; struct Lf_Cut_t_ @@ -847,16 +848,16 @@ static inline int Lf_CutCompareDelay( Lf_Cut_t * pCut0, Lf_Cut_t * pCut1 ) if ( pCut0->Delay > pCut1->Delay ) return 1; if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; if ( pCut0->nLeaves > pCut1->nLeaves ) return 1; - if ( pCut0->Flow < pCut1->Flow ) return -1; - if ( pCut0->Flow > pCut1->Flow ) return 1; + if ( pCut0->Flow < pCut1->Flow - LF_EPSILON ) return -1; + if ( pCut0->Flow > pCut1->Flow + LF_EPSILON ) return 1; return 0; } static inline int Lf_CutCompareArea( Lf_Cut_t * pCut0, Lf_Cut_t * pCut1 ) { if ( pCut0->fLate < pCut1->fLate ) return -1; if ( pCut0->fLate > pCut1->fLate ) return 1; - if ( pCut0->Flow < pCut1->Flow ) return -1; - if ( pCut0->Flow > pCut1->Flow ) return 1; + if ( pCut0->Flow < pCut1->Flow - LF_EPSILON ) return -1; + if ( pCut0->Flow > pCut1->Flow + LF_EPSILON ) return 1; if ( pCut0->Delay < pCut1->Delay ) return -1; if ( pCut0->Delay > pCut1->Delay ) return 1; if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; @@ -1304,7 +1305,7 @@ void Lf_ObjMergeOrder( Lf_Man_t * p, int iObj ) p->nCutEqual++; // area cut iCutUsed = 0; - if ( nCutsR > 1 && pCutsR[0]->Flow > pCutsR[1]->Flow )//&& !pCutsR[1]->fLate ) // can remove !fLate + if ( nCutsR > 1 && pCutsR[0]->Flow > pCutsR[1]->Flow + LF_EPSILON )//&& !pCutsR[1]->fLate ) // can remove !fLate { pBest->Cut[1].Handle = Lf_MemSaveCut(&p->vStoreNew, pCutsR[1], iObj); pBest->Delay[1] = pCutsR[1]->Delay; diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 2ded34bd..a500a839 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -37,6 +37,7 @@ ABC_NAMESPACE_IMPL_START #define MF_NO_LEAF 31 #define MF_TT_WORDS ((MF_LEAF_MAX > 6) ? 1 << (MF_LEAF_MAX-6) : 1) #define MF_NO_FUNC 134217727 // (1<<27)-1 +#define MF_EPSILON 0.005 typedef struct Mf_Cut_t_ Mf_Cut_t; struct Mf_Cut_t_ @@ -920,8 +921,8 @@ static inline int Mf_SetLastCutContainsArea( Mf_Cut_t ** pCuts, int nCuts ) } static inline int Mf_CutCompareArea( Mf_Cut_t * pCut0, Mf_Cut_t * pCut1 ) { - if ( pCut0->Flow < pCut1->Flow ) return -1; - if ( pCut0->Flow > pCut1->Flow ) return 1; + if ( pCut0->Flow < pCut1->Flow - MF_EPSILON ) return -1; + if ( pCut0->Flow > pCut1->Flow + MF_EPSILON ) return 1; if ( pCut0->Delay < pCut1->Delay ) return -1; if ( pCut0->Delay > pCut1->Delay ) return 1; if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; @@ -1544,7 +1545,7 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj ) assert( !Mf_CutIsTriv(pCut, iObj) ); assert( Mf_CutSize(pCut) <= p->pPars->nLutSize ); Flow = p->fUseEla ? Mf_CutAreaDerefed(p, pCut) : Mf_CutFlow(p, pCut, &Time); - if ( pCutBest == NULL || FlowBest > Flow || (FlowBest == Flow && TimeBest > Time) ) + if ( pCutBest == NULL || FlowBest > Flow + MF_EPSILON || (FlowBest > Flow - MF_EPSILON && TimeBest > Time) ) pCutBest = pCut, FlowBest = Flow, TimeBest = Time; } assert( pCutBest != NULL ); diff --git a/src/aig/gia/giaNf.c b/src/aig/gia/giaNf.c index 6761b617..6f1d0c8d 100644 --- a/src/aig/gia/giaNf.c +++ b/src/aig/gia/giaNf.c @@ -41,6 +41,7 @@ ABC_NAMESPACE_IMPL_START #define NF_CUT_MAX 32 #define NF_NO_LEAF 31 #define NF_NO_FUNC 0x3FFFFFF +#define NF_EPSILON 0.001 typedef struct Nf_Cut_t_ Nf_Cut_t; struct Nf_Cut_t_ @@ -171,7 +172,7 @@ static inline int Nf_CfgCompl( Nf_Cfg_t Cfg, int i ) int Nf_StoCellIsDominated( Mio_Cell2_t * pCell, int * pFans, int * pProf ) { int k; - if ( pCell->AreaF < Abc_Int2Float(pProf[0]) ) + if ( pCell->AreaF + NF_EPSILON < Abc_Int2Float(pProf[0]) ) return 0; for ( k = 0; k < (int)pCell->nFanins; k++ ) if ( pCell->iDelays[Abc_Lit2Var(pFans[k])] < pProf[k+1] ) @@ -802,8 +803,8 @@ static inline int Nf_CutCompareArea( Nf_Cut_t * pCut0, Nf_Cut_t * pCut1 ) { if ( pCut0->Useless < pCut1->Useless ) return -1; if ( pCut0->Useless > pCut1->Useless ) return 1; - if ( pCut0->Flow < pCut1->Flow ) return -1; - if ( pCut0->Flow > pCut1->Flow ) return 1; + if ( pCut0->Flow < pCut1->Flow - NF_EPSILON ) return -1; + if ( pCut0->Flow > pCut1->Flow + NF_EPSILON ) return 1; if ( pCut0->Delay < pCut1->Delay ) return -1; if ( pCut0->Delay > pCut1->Delay ) return 1; if ( pCut0->nLeaves < pCut1->nLeaves ) return -1; @@ -1162,7 +1163,7 @@ void Nf_ManCutMatchOne( Nf_Man_t * p, int iObj, int * pCut, int * pCutSet ) pD->Cfg.fCompl = 0; } - if ( pA->F > AreaF ) + if ( pA->F > AreaF + NF_EPSILON ) { pA->D = Delay; pA->F = AreaF; @@ -1310,7 +1311,7 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj ) } //assert( pAp->F < FLT_MAX || pAn->F < FLT_MAX ); // try replacing pos with neg - if ( pAp->D == SCL_INFINITY || (pAp->F > pAn->F + p->InvAreaF && pAn->D + p->InvDelayI <= Required[0]) ) + if ( pAp->D == SCL_INFINITY || (pAp->F > pAn->F + p->InvAreaF + NF_EPSILON && pAn->D + p->InvDelayI <= Required[0]) ) { assert( p->Iter > 0 ); *pAp = *pAn; @@ -1322,7 +1323,7 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj ) //printf( "Using inverter to improve area at node %d in phase %d.\n", iObj, 1 ); } // try replacing neg with pos - else if ( pAn->D == SCL_INFINITY || (pAn->F > pAp->F + p->InvAreaF && pAp->D + p->InvDelayI <= Required[1]) ) + else if ( pAn->D == SCL_INFINITY || (pAn->F > pAp->F + p->InvAreaF + NF_EPSILON && pAp->D + p->InvDelayI <= Required[1]) ) { assert( p->Iter > 0 ); *pAn = *pAp; @@ -1778,7 +1779,7 @@ void Nf_ManElaBestMatchOne( Nf_Man_t * p, int iObj, int c, int * pCut, int * pCu pMb->Cfg = Nf_Int2Cfg(0); pMb->fBest = 1; // compare - if ( pRes->F > pMb->F || (pRes->F == pMb->F && pRes->D > pMb->D) ) + if ( pRes->F > pMb->F + NF_EPSILON || (pRes->F > pMb->F - NF_EPSILON && pRes->D > pMb->D) ) *pRes = *pMb; return; } @@ -1814,7 +1815,7 @@ void Nf_ManElaBestMatchOne( Nf_Man_t * p, int iObj, int c, int * pCut, int * pCu // compute area pMb->F = Scl_Int2Flt((int)Nf_MatchRefArea(p, iObj, c, pMb, Required)); // compare - if ( pRes->F > pMb->F || (pRes->F == pMb->F && pRes->D > pMb->D) ) + if ( pRes->F > pMb->F + NF_EPSILON || (pRes->F > pMb->F - NF_EPSILON && pRes->D > pMb->D) ) *pRes = *pMb; } } -- cgit v1.2.3 From ec6b765314f029ca9ddf5a2f3adc5b496d560f43 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 28 Jan 2017 11:46:47 -0800 Subject: Custom floating-point number. --- src/sat/xsat/xsatFloat.h | 213 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 src/sat/xsat/xsatFloat.h (limited to 'src') diff --git a/src/sat/xsat/xsatFloat.h b/src/sat/xsat/xsatFloat.h new file mode 100644 index 00000000..73b74ff7 --- /dev/null +++ b/src/sat/xsat/xsatFloat.h @@ -0,0 +1,213 @@ +/**CFile**************************************************************** + + FileName [xsatFloat.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [xSAT - A SAT solver written in C. + Read the license file for more info.] + + Synopsis [Floating point number implementation.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - January 28, 2017.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatFloat_h +#define ABC__sat__xSAT__xsatFloat_h + +#include "misc/util/abc_global.h" +#include "misc/vec/vecInt.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/* + The xFloat_t floating-point number is represented as a 32-bit unsigned int. + The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a + 16-bit mantissa. The decimal point is located between the MSB of Mnt, + which is always 1, and the remaining 15 digits of Mnt. + + Currently, only positive numbers are represented. + + The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] + that is, the smallest possible number is 1.0 and the largest possible + number is 2^(---16 ones---).(1.---15 ones---) + + Comparison of numbers can be done by comparing the underlying unsigned ints. + + Only addition, multiplication, and division by 2^n are currently implemented. +*/ + +typedef struct xFloat_t_ xFloat_t; +struct xFloat_t_ +{ + unsigned Mnt : 16; + unsigned Exp : 16; +}; + +static inline unsigned xSat_Float2Uint( xFloat_t f ) { union { xFloat_t f; unsigned u; } temp; temp.f = f; return temp.u; } +static inline xFloat_t xSat_Uint2Float( unsigned u ) { union { xFloat_t f; unsigned u; } temp; temp.u = u; return temp.f; } +static inline int xSat_LessThan( xFloat_t a, xFloat_t b ) { return a.Exp < b.Exp || (a.Exp == b.Exp && a.Mnt < b.Mnt); } +static inline int xSat_Equal( xFloat_t a, xFloat_t b ) { return a.Exp == b.Exp && a.Mnt == b.Mnt; } + +static inline xFloat_t xSat_FloatCreate( unsigned Exp, unsigned Mnt ) { xFloat_t res; res.Exp = Exp; res.Mnt = Mnt; return res; } + +static inline xFloat_t xSat_FloatCreateConst1() { return xSat_FloatCreate( 0, 1 << 15 ); } +static inline xFloat_t xSat_FloatCreateConst2() { return xSat_FloatCreate( 1, 1 << 15 ); } +static inline xFloat_t xSat_FloatCreateConst3() { return xSat_FloatCreate( 1, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst12() { return xSat_FloatCreate( 3, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst1point5() { return xSat_FloatCreate( 0, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst2point5() { return xSat_FloatCreate( 1, 5 << 13 ); } +static inline xFloat_t xSat_FloatCreateMaximum() { return xSat_Uint2Float( 0xFFFFFFFF ); } + +static inline float xSat_Float2Float( xFloat_t a ) { assert(a.Exp < 127); return Abc_Int2Float(((a.Exp + 127) << 23) | ((a.Mnt & 0x7FFF) << 8)); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Adding two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatAdd( xFloat_t a, xFloat_t b ) +{ + unsigned Exp, Mnt; + if ( a.Exp < b.Exp ) + return xSat_FloatAdd(b, a); + assert( a.Exp >= b.Exp ); + // compute new mantissa + Mnt = a.Mnt + (b.Mnt >> (a.Exp - b.Exp)); + // compute new exponent + Exp = a.Exp; + // update exponent and mantissa if new MSB is created + if ( Mnt & 0xFFFF0000 ) // new MSB bit is created + Exp++, Mnt >>= 1; + // check overflow + if ( Exp & 0xFFFF0000 ) // overflow + return xSat_Uint2Float( 0xFFFFFFFF ); + assert( (Exp & 0xFFFF0000) == 0 ); + assert( (Mnt & 0xFFFF0000) == 0 ); + assert( Mnt & 0x00008000 ); + return xSat_FloatCreate( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Multiplying two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatMul( xFloat_t a, xFloat_t b ) +{ + unsigned Exp, Mnt; + if ( a.Exp < b.Exp ) + return xSat_FloatMul(b, a); + assert( a.Exp >= b.Exp ); + // compute new mantissa + Mnt = (a.Mnt * b.Mnt) >> 15; + // compute new exponent + Exp = a.Exp + b.Exp; + // update exponent and mantissa if new MSB is created + if ( Mnt & 0xFFFF0000 ) // new MSB bit is created + Exp++, Mnt >>= 1; + // check overflow + if ( Exp & 0xFFFF0000 ) // overflow + return xSat_Uint2Float( 0xFFFFFFFF ); + assert( (Exp & 0xFFFF0000) == 0 ); + assert( (Mnt & 0xFFFF0000) == 0 ); + assert( Mnt & 0x00008000 ); + return xSat_FloatCreate( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Dividing floating point number by a degree of 2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatDiv( xFloat_t a, unsigned Deg2 ) +{ + assert( Deg2 < 0xFFFF ); + if ( a.Exp >= Deg2 ) + return xSat_FloatCreate( a.Exp - Deg2, a.Mnt ); + return xSat_FloatCreateConst1(); // underflow +} + +/**Function************************************************************* + + Synopsis [Testing procedure.] + + Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSat_FloatTest() +{ + xFloat_t c1 = xSat_FloatCreateConst1(); + xFloat_t c2 = xSat_FloatCreateConst2(); + xFloat_t c3 = xSat_FloatCreateConst3(); + xFloat_t c12 = xSat_FloatCreateConst12(); + xFloat_t c1p5 = xSat_FloatCreateConst1point5(); + xFloat_t c2p5 = xSat_FloatCreateConst2point5(); + + xFloat_t sum1 = xSat_FloatAdd(c1, c1p5); + xFloat_t mul1 = xSat_FloatMul(c2, c1p5); + + xFloat_t sum2 = xSat_FloatAdd(c1p5, c2p5); + xFloat_t mul2 = xSat_FloatMul(c1p5, c2p5); + +// float f1 = xSat_Float2Float(c1); +// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" ); +// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" ); + + printf( "1 = %f\n", xSat_Float2Float(c1) ); + printf( "2 = %f\n", xSat_Float2Float(c2) ); + printf( "3 = %f\n", xSat_Float2Float(c3) ); + printf( "12 = %f\n", xSat_Float2Float(c12) ); + printf( "1.5 = %f\n", xSat_Float2Float(c1p5) ); + printf( "2.5 = %f\n", xSat_Float2Float(c2p5) ); + + printf( "1.0 + 1.5 = %f\n", xSat_Float2Float(sum1) ); + printf( "2.0 * 1.5 = %f\n", xSat_Float2Float(mul1) ); + + printf( "1.5 + 2.5 = %f\n", xSat_Float2Float(sum2) ); + printf( "1.5 * 2.5 = %f\n", xSat_Float2Float(mul2) ); + printf( "12 / 2^2 = %f\n", xSat_Float2Float(xSat_FloatDiv(c12, 2)) ); + + assert( xSat_Equal(sum1, c2p5) ); + assert( xSat_Equal(mul1, c3) ); +} + +ABC_NAMESPACE_HEADER_END + +#endif -- cgit v1.2.3 From 782125c61e78d7f14e129667433b54e2fc434d50 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 28 Jan 2017 12:01:32 -0800 Subject: Custom floating-point number. --- src/sat/xsat/xsatFloat.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/sat/xsat/xsatFloat.h b/src/sat/xsat/xsatFloat.h index 73b74ff7..90149783 100644 --- a/src/sat/xsat/xsatFloat.h +++ b/src/sat/xsat/xsatFloat.h @@ -70,6 +70,7 @@ static inline xFloat_t xSat_FloatCreateConst2point5() { retur static inline xFloat_t xSat_FloatCreateMaximum() { return xSat_Uint2Float( 0xFFFFFFFF ); } static inline float xSat_Float2Float( xFloat_t a ) { assert(a.Exp < 127); return Abc_Int2Float(((a.Exp + 127) << 23) | ((a.Mnt & 0x7FFF) << 8)); } +static inline xFloat_t xSat_FloatFromFloat( float a ) { int A = Abc_Float2Int(a); assert(a >= 1.0); return xSat_FloatCreate((A >> 23)-127, 0x8000 | ((A >> 8) & 0x7FFF)); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -180,6 +181,13 @@ static inline void xSat_FloatTest() xFloat_t c1p5 = xSat_FloatCreateConst1point5(); xFloat_t c2p5 = xSat_FloatCreateConst2point5(); + xFloat_t c1_ = xSat_FloatFromFloat(1.0); + xFloat_t c2_ = xSat_FloatFromFloat(2.0); + xFloat_t c3_ = xSat_FloatFromFloat(3.0); + xFloat_t c12_ = xSat_FloatFromFloat(12.0); + xFloat_t c1p5_ = xSat_FloatFromFloat(1.5); + xFloat_t c2p5_ = xSat_FloatFromFloat(2.5); + xFloat_t sum1 = xSat_FloatAdd(c1, c1p5); xFloat_t mul1 = xSat_FloatMul(c2, c1p5); @@ -197,6 +205,13 @@ static inline void xSat_FloatTest() printf( "1.5 = %f\n", xSat_Float2Float(c1p5) ); printf( "2.5 = %f\n", xSat_Float2Float(c2p5) ); + printf( "Converted 1 = %f\n", xSat_Float2Float(c1_) ); + printf( "Converted 2 = %f\n", xSat_Float2Float(c2_) ); + printf( "Converted 3 = %f\n", xSat_Float2Float(c3_) ); + printf( "Converted 12 = %f\n", xSat_Float2Float(c12_) ); + printf( "Converted 1.5 = %f\n", xSat_Float2Float(c1p5_) ); + printf( "Converted 2.5 = %f\n", xSat_Float2Float(c2p5_) ); + printf( "1.0 + 1.5 = %f\n", xSat_Float2Float(sum1) ); printf( "2.0 * 1.5 = %f\n", xSat_Float2Float(mul1) ); -- cgit v1.2.3 From 9171bb32ad332d2b76e3c85ff64308065b89367d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 28 Jan 2017 17:04:22 -0800 Subject: Updates to arithmetic verification. --- src/proof/acec/acecInt.h | 9 + src/proof/acec/acecMult.c | 1 + src/proof/acec/acecTree.c | 12 +- src/proof/acec/acecXor.c | 407 +++++++++++++++++++++++++++++++++++++++++++++ src/proof/acec/module.make | 3 +- 5 files changed, 422 insertions(+), 10 deletions(-) create mode 100644 src/proof/acec/acecXor.c (limited to 'src') diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index b8ec2455..47a32e78 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -56,6 +56,12 @@ struct Acec_Box_t_ /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; } +static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; } + +static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); } +static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); } + //////////////////////////////////////////////////////////////////////// /// ITERATORS /// //////////////////////////////////////////////////////////////////////// @@ -75,11 +81,14 @@ extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); /*=== acecTree.c ========================================================*/ extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ); +extern void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ); extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose ); extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); /*=== acecUtil.c ========================================================*/ extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); +/*=== acecUtil.c ========================================================*/ +extern Acec_Box_t * Acec_DetectXorTrees( Gia_Man_t * p, int fVerbose ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index d868c399..ba9405ac 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -499,6 +499,7 @@ Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p ) { if ( Truth == Saved[i] || Truth == ~Saved[i] ) { + //printf( "*** Node %d is PP with support %d.\n", iObj, Vec_IntSize(vSupp) ); Acec_MultFindPPs_rec( p, iObj, vBold ); nProds++; break; diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 2461c89b..330a5d58 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -27,12 +27,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; } -static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; } - -static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); } -static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -558,7 +552,7 @@ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) printf( " }\n" ); } } -void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) +void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) { printf( "Adders:\n" ); Acec_PrintAdders( pBox->vAdds, vAdds ); @@ -703,7 +697,7 @@ void Acec_CreateBoxTest( Gia_Man_t * p ) printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n", i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); - Acec_PrintBox( pBox, vAdds ); + Acec_TreePrintBox( pBox, vAdds ); Acec_BoxFreeP( &pBox ); } @@ -737,7 +731,7 @@ Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds), Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) ); if ( pBox && fVerbose ) - Acec_PrintBox( pBox, vAdds ); + Acec_TreePrintBox( pBox, vAdds ); //Acec_PrintAdders( pBox0->vAdds, vAdds ); //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits ); Vec_WecFreeP( &vTrees ); diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c new file mode 100644 index 00000000..ae5aeff7 --- /dev/null +++ b/src/proof/acec/acecXor.c @@ -0,0 +1,407 @@ +/**CFile**************************************************************** + + FileName [acecXor.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Detection of XOR trees.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecXor.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/vec/vecWec.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_OrderXorRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Wec_t * vXorTrees, Vec_Int_t * vMap ) +{ + Vec_Int_t * vOrder = Vec_IntAlloc( Vec_WecSize(vXorTrees) ); + Vec_Int_t * vReMap = Vec_IntStartFull( Vec_WecSize(vXorTrees) ); + int i, k, Entry, This; + // iterate through adders and for each try mark the next one + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + int Node = Vec_IntEntry(vAdds, 6*i+4); + if ( Vec_IntEntry(vMap, Node) == -1 ) + continue; + for ( k = 0; k < 3; k++ ) + { + int Fanin = Vec_IntEntry(vAdds, 6*i+k); + if ( Vec_IntEntry(vMap, Fanin) == -1 ) + continue; + //printf( "%4d: %2d -> %2d\n", Node, Vec_IntEntry(vMap, Node), Vec_IntEntry(vMap, Fanin) ); + Vec_IntWriteEntry( vReMap, Vec_IntEntry(vMap, Node), Vec_IntEntry(vMap, Fanin) ); + } + } +//Vec_IntPrint( vReMap ); + // find reodering + Vec_IntForEachEntry( vReMap, Entry, i ) + if ( Entry == -1 && Vec_IntFind(vReMap, i) >= 0 ) + break; + assert( i < Vec_IntSize(vReMap) ); + while ( 1 ) + { + Vec_IntPush( vOrder, Vec_IntEntry(vXorRoots, i) ); + Entry = i; + Vec_IntForEachEntry( vReMap, This, i ) + if ( This == Entry ) + break; + if ( i == Vec_IntSize(vReMap) ) + break; + } + Vec_IntFree( vReMap ); +//Vec_IntPrint( vOrder ); + return vOrder; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// marks nodes appearing as fanins to XORs +Vec_Bit_t * Acec_MapXorIns( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + { + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+1), 1 ); + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+2), 1 ); + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+3), 1 ); + } + return vMap; +} +// marks nodes having XOR cuts +Vec_Bit_t * Acec_MapXorOuts( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 ); + return vMap; +} +// marks nodes appearing as outputs of MAJs +Vec_Bit_t * Acec_MapMajOuts( Gia_Man_t * p, Vec_Int_t * vAdds ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + Vec_BitWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), 1 ); + return vMap; +} +// maps MAJ outputs into their FAs and HAs +Vec_Int_t * Acec_MapMajOutsToAdds( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vXorOuts, Vec_Int_t * vMapRank ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; + for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + { + int Xor = Vec_IntEntry(vAdds, 6*i+3); + int Maj = Vec_IntEntry(vAdds, 6*i+4); + if ( Vec_IntEntry(vMap, Maj) >= 0 ) + { + int i2 = Vec_IntEntry(vMap, Maj); + int Xor2 = Vec_IntEntry(vAdds, 6*i2+3); + int Maj2 = Vec_IntEntry(vAdds, 6*i2+4); + printf( "*** Node %d has two MAJ adder drivers: %d%s (%d rank %d) and %d%s (%d rank %d).\n", + Maj, + i, Vec_IntEntry(vAdds, 6*i+2) ? "":"*", Vec_BitEntry(vXorOuts, Xor), Vec_IntEntry(vMapRank, Xor), + i2, Vec_IntEntry(vAdds, 6*i2+2) ? "":"*", Vec_BitEntry(vXorOuts, Xor2), Vec_IntEntry(vMapRank, Xor2) ); + } + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), i ); + } + return vMap; +} +// collects XOR roots (XOR nodes not appearing as fanins of other XORs) +Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Bit_t * vMapXorIns = Acec_MapXorIns( p, vXors ); + Vec_Int_t * vXorRoots = Vec_IntAlloc( 100 ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + if ( !Vec_BitEntry(vMapXorIns, Vec_IntEntry(vXors, 4*i)) ) + Vec_IntPushUniqueOrder( vXorRoots, Vec_IntEntry(vXors, 4*i) ); + Vec_BitFree( vMapXorIns ); +//Vec_IntRemove( vXorRoots, 54 ); + return vXorRoots; +} +// collects XOR trees belonging to each of XOR roots +Vec_Wec_t * Acec_FindXorTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRoots, Vec_Int_t ** pvMap ) +{ + Vec_Int_t * vDoubles = Vec_IntAlloc( 100 ); + Vec_Wec_t * vXorTrees = Vec_WecStart( Vec_IntSize(vXorRoots) ); + Vec_Int_t * vLevel; + int i, k, Entry; + // map roots into their classes + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_IntForEachEntry( vXorRoots, Entry, i ) + { + Vec_IntWriteEntry( vMap, Entry, i ); + Vec_WecPush( vXorTrees, i, Entry ); + } + // map nodes into their classes + for ( i = Vec_IntSize(vXors)/4 - 1; i >= 0; i-- ) + { + int Root = Vec_IntEntry( vXors, 4*i ); + int Repr = Vec_IntEntry( vMap, Root ); + //assert( Repr != -1 ); + if ( Repr == -1 ) + continue; + for ( k = 1; k < 4; k++ ) + { + int Node = Vec_IntEntry( vXors, 4*i+k ); + if ( Node == 0 ) + continue; + Entry = Vec_IntEntry( vMap, Node ); + if ( Entry == Repr ) + continue; + if ( Entry == -1 ) + { + Vec_IntWriteEntry( vMap, Node, Repr ); + Vec_WecPush( vXorTrees, Repr, Node ); + continue; + } + //printf( "Node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Repr ); + Vec_IntPushUnique( Vec_WecEntry(vXorTrees, Entry), Node ); + Vec_IntPush( vDoubles, Node ); + } + } + // clean map + Vec_IntForEachEntry( vDoubles, Entry, i ) + Vec_IntWriteEntry( vMap, Entry, -1 ); + Vec_IntFree( vDoubles ); + // sort nodes + Vec_WecForEachLevel( vXorTrees, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + if ( pvMap ) + *pvMap = vMap; + else + Vec_IntFree( vMap ); + return vXorTrees; +} +// collects leaves of each XOR tree +Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vAdds, Vec_Wec_t * vXorTrees, Vec_Int_t * vMap, Vec_Wec_t ** pvAddBoxes ) +{ + Vec_Bit_t * vMapXorOuts = Acec_MapXorOuts( p, vXors ); + Vec_Int_t * vMapMajOuts = Acec_MapMajOutsToAdds( p, vAdds, vMapXorOuts, vMap ); + Vec_Wec_t * vXorLeaves = Vec_WecStart( Vec_WecSize(vXorTrees) ); + int i, k; + if ( pvAddBoxes ) + *pvAddBoxes = Vec_WecStart( Vec_WecSize(vXorTrees) ); + // collect leaves + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + { + int Xor = Vec_IntEntry(vXors, 4*i); + for ( k = 1; k < 4; k++ ) + { + int Node = Vec_IntEntry(vXors, 4*i+k); + if ( Node == 0 ) + continue; + if ( Vec_BitEntry(vMapXorOuts, Node) || Vec_IntEntry(vMap, Xor) == -1 ) + continue; + if ( Vec_IntEntry(vMapMajOuts, Node) == -1 ) // no maj driver + Vec_WecPush( vXorLeaves, Vec_IntEntry(vMap, Xor), Node ); + else if ( pvAddBoxes && Vec_IntEntry(vMap, Xor) > 0 ) // save adder box + Vec_WecPush( *pvAddBoxes, Vec_IntEntry(vMap, Xor)-1, Vec_IntEntry(vMapMajOuts, Node) ); + } + } +/* + if ( pvAddBoxes ) + { + Vec_Int_t * vLevel; + //Vec_WecPrint( *pvAddBoxes, 0 ); + Vec_WecForEachLevelReverse( *pvAddBoxes, vLevel, i ) + if ( Vec_IntSize(vLevel) > 0 ) + break; + Vec_WecShrink( *pvAddBoxes, i+1 ); + //Vec_WecPrint( *pvAddBoxes, 0 ); + } +*/ + Vec_BitFree( vMapXorOuts ); + Vec_IntFree( vMapMajOuts ); + return vXorLeaves; +} + +Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorTrees, Vec_Wec_t * vXorLeaves ) +{ + extern Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); + extern void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit ); + extern void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); + extern void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); + + int MaxRank = Vec_WecSize( vAddBoxes ); + Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 ); + Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel, * vLevel2, * vMap; + int i, j, k, Box, Node; + + Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 ); + pBox->pGia = p; + pBox->vAdds = vAddBoxes; // Vec_WecDup( vAddBoxes ); + pBox->vLeafLits = Vec_WecStart( MaxRank + 0 ); + pBox->vRootLits = Vec_WecStart( MaxRank + 0 ); + + assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorTrees) ); + assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorLeaves) ); + + // collect boxes; mark inputs/outputs + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + { + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 ); + Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 ); + Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 ); + } + // sort each level + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + + // set phases starting from roots + vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds ); + Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) ) + { + //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box ); + Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit ); + } + Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds ); + Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds ); + Vec_BitFree( vVisit ); + Vec_IntFree( vMap ); + + // collect inputs/outputs + Vec_BitWriteEntry( vIsRoot, 0, 1 ); + Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, j ) + { + for ( k = 0; k < 3; k++ ) + if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + for ( k = 3; k < 5; k++ ) + if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) ) + Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) ); + if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) ) + Vec_WecPush( pBox->vLeafLits, i, 1 ); + } + Vec_BitFree( vIsLeaf ); + Vec_BitFree( vIsRoot ); + + // collect last bit + vLevel = Vec_WecEntry( pBox->vLeafLits, Vec_WecSize(pBox->vLeafLits)-1 ); + vLevel2 = Vec_WecEntry( vXorLeaves, Vec_WecSize(vXorLeaves)-1 ); + if ( Vec_IntSize(vLevel) == 0 && Vec_IntSize(vLevel2) > 0 ) + { + Vec_IntForEachEntry( vLevel2, Node, k ) + Vec_IntPush( vLevel, Abc_Var2Lit(Node, 0) ); + } + vLevel = Vec_WecEntry( pBox->vRootLits, Vec_WecSize(pBox->vRootLits)-1 ); + vLevel2 = Vec_WecEntry( vXorTrees, Vec_WecSize(vXorTrees)-1 ); + Vec_IntClear( vLevel ); + if ( Vec_IntSize(vLevel) == 0 && Vec_IntSize(vLevel2) > 0 ) + { + Vec_IntPush( vLevel, Abc_Var2Lit(Vec_IntEntryLast(vLevel2), 0) ); + } + + // sort each level + Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) + Vec_IntSort( vLevel, 0 ); + Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) + Vec_IntSort( vLevel, 1 ); + return pBox; +} + +Acec_Box_t * Acec_DetectXorTrees( Gia_Man_t * p, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Acec_Box_t * pBox = NULL; + Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); + Vec_Int_t * vMap, * vXorRootsNew; + Vec_Int_t * vXorRoots = Acec_FindXorRoots( p, vXors ); + Vec_Wec_t * vXorTrees = Acec_FindXorTrees( p, vXors, vXorRoots, &vMap ); + Vec_Wec_t * vXorLeaves, * vAddBoxes = NULL; + + //Ree_ManPrintAdders( vAdds, 1 ); + printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + +// printf( "XOR roots: \n" ); +// Vec_IntPrint( vXorRoots ); +// Vec_WecPrint( vXorTrees, 0 ); + + vXorRootsNew = Acec_OrderXorRoots( p, vAdds, vXorRoots, vXorTrees, vMap ); + Vec_IntFree( vXorRoots ); + Vec_WecFree( vXorTrees ); + Vec_IntFree( vMap ); + + vXorRoots = vXorRootsNew; vXorRootsNew = NULL; + vXorTrees = Acec_FindXorTrees( p, vXors, vXorRoots, &vMap ); + vXorLeaves = Acec_FindXorLeaves( p, vXors, vAdds, vXorTrees, vMap, &vAddBoxes ); + + printf( "XOR roots: \n" ); + Vec_IntPrint( vXorRoots ); + printf( "XOR leaves: \n" ); + Vec_WecPrint( vXorLeaves, 0 ); + printf( "Adder boxes: \n" ); + Vec_WecPrint( vAddBoxes, 0 ); + + pBox = Acec_FindBox( p, vAdds, vAddBoxes, vXorTrees, vXorLeaves ); + + Acec_TreePrintBox( pBox, vAdds ); + + Vec_IntFree( vXorRoots ); + Vec_WecFree( vXorTrees ); + Vec_WecFree( vXorLeaves ); + //Vec_WecFree( vAddBoxes ); + + Vec_IntFree( vMap ); + Vec_IntFree( vXors ); + Vec_IntFree( vAdds ); + + return pBox; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make index dbf86ac2..f4c69892 100644 --- a/src/proof/acec/module.make +++ b/src/proof/acec/module.make @@ -14,4 +14,5 @@ SRC += src/proof/acec/acecCl.c \ src/proof/acec/acecPolyn.c \ src/proof/acec/acecSt.c \ src/proof/acec/acecTree.c \ - src/proof/acec/acecUtil.c + src/proof/acec/acecUtil.c \ + src/proof/acec/acecXor.c -- cgit v1.2.3 From e9566a1e3db178a6111d227439354fcbb935ffa7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 29 Jan 2017 13:37:29 -0800 Subject: Updates to arithmetic verification. --- src/base/wlc/wlcReadVer.c | 1 + src/proof/acec/acecCore.c | 18 ++-- src/proof/acec/acecInt.h | 2 +- src/proof/acec/acecTree.c | 37 ++++++- src/proof/acec/acecXor.c | 238 ++++++++++++++++++++-------------------------- 5 files changed, 153 insertions(+), 143 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index e4a65ecf..16de4943 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -429,6 +429,7 @@ char * Wlc_PrsConvertInitValues( Wlc_Ntk_t * p ) Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); Vec_IntForEachEntry( p->vInits, Value, i ) { + char * pname = Wlc_ObjName( p, Value ); if ( Value < 0 ) { for ( k = 0; k < -Value; k++ ) diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c index a2341704..1a575fbe 100644 --- a/src/proof/acec/acecCore.c +++ b/src/proof/acec/acecCore.c @@ -319,7 +319,7 @@ void Vec_IntInsertOrder( Vec_Int_t * vLits, Vec_Int_t * vClasses, int Lit, int C void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses ) { Vec_Int_t * vLevel1, * vLevel2; - int i, k, Prev, This, Entry; + int i, k, Prev, This, Entry, Counter = 0; Vec_WecForEachLevel( vLits, vLevel1, i ) { if ( i == Vec_WecSize(vLits) - 1 ) @@ -347,8 +347,10 @@ void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses ) assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) ); assert( Vec_IntSize(Vec_WecEntry(vLits, i+1)) == Vec_IntSize(Vec_WecEntry(vClasses, i+1)) ); + Counter++; } } + printf( "Moved %d pairs of PPs to normalize the matrix.\n", Counter ); } void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 ) @@ -490,12 +492,14 @@ int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars ) Gia_Man_t * pMiter; Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1; Cec_ParCec_t ParsCec, * pCecPars = &ParsCec; - Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; - Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; - Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose ); - Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose ); - Vec_BitFreeP( &vIgnore0 ); - Vec_BitFreeP( &vIgnore1 ); +// Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL; +// Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL; +// Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose ); +// Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose ); +// Vec_BitFreeP( &vIgnore0 ); +// Vec_BitFreeP( &vIgnore1 ); + Acec_Box_t * pBox0 = Acec_ProduceBox( pGia0, pPars->fVerbose ); + Acec_Box_t * pBox1 = Acec_ProduceBox( pGia1, pPars->fVerbose ); if ( pBox0 == NULL || pBox1 == NULL ) // cannot match printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" ); else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 47a32e78..381ab8d1 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -88,7 +88,7 @@ extern void Acec_BoxFreeP( Acec_Box_t ** ppBox ); extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose ); extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose ); /*=== acecUtil.c ========================================================*/ -extern Acec_Box_t * Acec_DetectXorTrees( Gia_Man_t * p, int fVerbose ); +extern Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose ); diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c index 330a5d58..ab17d7b9 100644 --- a/src/proof/acec/acecTree.c +++ b/src/proof/acec/acecTree.c @@ -333,6 +333,37 @@ void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxe Vec_BitFree( vPhase ); Vec_BitFree( vRoots ); } +void Acec_TreeVerifyConnections( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ) +{ + Vec_Int_t * vCounts = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; + int i, k, n, Box; + // mark outputs + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + { + Vec_IntWriteEntry( vCounts, Vec_IntEntry( vAdds, 6*Box+3 ), 0 ); + Vec_IntWriteEntry( vCounts, Vec_IntEntry( vAdds, 6*Box+4 ), 0 ); + } + // count fanouts + Vec_WecForEachLevel( vBoxes, vLevel, i ) + Vec_IntForEachEntry( vLevel, Box, k ) + for ( n = 0; n < 3; n++ ) + if ( Vec_IntEntry( vCounts, Vec_IntEntry(vAdds, 6*Box+n) ) != -1 ) + Vec_IntAddToEntry( vCounts, Vec_IntEntry(vAdds, 6*Box+n), 1 ); + // print out + printf( "The adder tree has %d internal cut points. ", Vec_IntCountLarger(vCounts, -1) ); + if ( Vec_IntCountLarger(vCounts, 1) == 0 ) + printf( "There is no internal fanouts.\n" ); + else + { + printf( "These %d points have more than one fanout:\n", Vec_IntCountLarger(vCounts, 1) ); + Vec_IntForEachEntry( vCounts, Box, i ) + if ( Box > 1 ) + printf( "Node %d(lev %d) has fanout %d.\n", i, Gia_ObjLevelId(p, i), Box ); + } + Vec_IntFree( vCounts ); +} /**Function************************************************************* @@ -534,7 +565,7 @@ void Acec_TreeFindTreesTest( Gia_Man_t * p ) SideEffects [] SeeAlso [] - +` ***********************************************************************/ void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds ) { @@ -560,6 +591,10 @@ void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds ) Vec_WecPrintLits( pBox->vLeafLits ); printf( "Outputs:\n" ); Vec_WecPrintLits( pBox->vRootLits ); +// printf( "Node %d has level %d.\n", 3715, Gia_ObjLevelId(pBox->pGia, 3715) ); +// printf( "Node %d has level %d.\n", 167, Gia_ObjLevelId(pBox->pGia, 167) ); +// printf( "Node %d has level %d.\n", 278, Gia_ObjLevelId(pBox->pGia, 278) ); +// printf( "Node %d has level %d.\n", 597, Gia_ObjLevelId(pBox->pGia, 597) ); } int Acec_CreateBoxMaxRank( Vec_Int_t * vTree ) diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c index ae5aeff7..acbde1a0 100644 --- a/src/proof/acec/acecXor.c +++ b/src/proof/acec/acecXor.c @@ -44,43 +44,43 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Vec_Int_t * Acec_OrderXorRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Wec_t * vXorTrees, Vec_Int_t * vMap ) +Vec_Int_t * Acec_OrderTreeRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks ) { - Vec_Int_t * vOrder = Vec_IntAlloc( Vec_WecSize(vXorTrees) ); - Vec_Int_t * vReMap = Vec_IntStartFull( Vec_WecSize(vXorTrees) ); + Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXorRoots) ); + Vec_Int_t * vMove = Vec_IntStartFull( Vec_IntSize(vXorRoots) ); int i, k, Entry, This; // iterate through adders and for each try mark the next one for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) { int Node = Vec_IntEntry(vAdds, 6*i+4); - if ( Vec_IntEntry(vMap, Node) == -1 ) + if ( Vec_IntEntry(vRanks, Node) == -1 ) continue; for ( k = 0; k < 3; k++ ) { int Fanin = Vec_IntEntry(vAdds, 6*i+k); - if ( Vec_IntEntry(vMap, Fanin) == -1 ) + if ( Vec_IntEntry(vRanks, Fanin) == -1 ) continue; - //printf( "%4d: %2d -> %2d\n", Node, Vec_IntEntry(vMap, Node), Vec_IntEntry(vMap, Fanin) ); - Vec_IntWriteEntry( vReMap, Vec_IntEntry(vMap, Node), Vec_IntEntry(vMap, Fanin) ); + //printf( "%4d: %2d -> %2d\n", Node, Vec_IntEntry(vRanks, Node), Vec_IntEntry(vRanks, Fanin) ); + Vec_IntWriteEntry( vMove, Vec_IntEntry(vRanks, Node), Vec_IntEntry(vRanks, Fanin) ); } } -//Vec_IntPrint( vReMap ); +//Vec_IntPrint( vMove ); // find reodering - Vec_IntForEachEntry( vReMap, Entry, i ) - if ( Entry == -1 && Vec_IntFind(vReMap, i) >= 0 ) + Vec_IntForEachEntry( vMove, Entry, i ) + if ( Entry == -1 && Vec_IntFind(vMove, i) >= 0 ) break; - assert( i < Vec_IntSize(vReMap) ); + assert( i < Vec_IntSize(vMove) ); while ( 1 ) { Vec_IntPush( vOrder, Vec_IntEntry(vXorRoots, i) ); Entry = i; - Vec_IntForEachEntry( vReMap, This, i ) + Vec_IntForEachEntry( vMove, This, i ) if ( This == Entry ) break; - if ( i == Vec_IntSize(vReMap) ) + if ( i == Vec_IntSize(vMove) ) break; } - Vec_IntFree( vReMap ); + Vec_IntFree( vMove ); //Vec_IntPrint( vOrder ); return vOrder; } @@ -96,27 +96,24 @@ Vec_Int_t * Acec_OrderXorRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vX SeeAlso [] ***********************************************************************/ -// marks nodes appearing as fanins to XORs -Vec_Bit_t * Acec_MapXorIns( Gia_Man_t * p, Vec_Int_t * vXors ) +// marks XOR outputs +Vec_Bit_t * Acec_MapXorOuts( Gia_Man_t * p, Vec_Int_t * vXors ) { Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) - { - Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+1), 1 ); - Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+2), 1 ); - Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+3), 1 ); - } + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 ); return vMap; } -// marks nodes having XOR cuts -Vec_Bit_t * Acec_MapXorOuts( Gia_Man_t * p, Vec_Int_t * vXors ) +// marks XOR outputs participating in trees +Vec_Bit_t * Acec_MapXorOuts2( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vRanks ) { Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) - Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 ); + if ( Vec_IntEntry(vRanks, Vec_IntEntry(vXors, 4*i)) != -1 ) + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 ); return vMap; } -// marks nodes appearing as outputs of MAJs +// marks MAJ outputs Vec_Bit_t * Acec_MapMajOuts( Gia_Man_t * p, Vec_Int_t * vAdds ) { Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; @@ -124,25 +121,24 @@ Vec_Bit_t * Acec_MapMajOuts( Gia_Man_t * p, Vec_Int_t * vAdds ) Vec_BitWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), 1 ); return vMap; } -// maps MAJ outputs into their FAs and HAs -Vec_Int_t * Acec_MapMajOutsToAdds( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vXorOuts, Vec_Int_t * vMapRank ) +// marks MAJ outputs participating in trees +Vec_Int_t * Acec_MapMajOuts2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vRanks ) { Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); int i; for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ ) + if ( Vec_IntEntry(vRanks, Vec_IntEntry(vAdds, 6*i+4)) != -1 ) + Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), i ); + return vMap; +} +// marks nodes appearing as fanins to XORs +Vec_Bit_t * Acec_MapXorIns( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) { - int Xor = Vec_IntEntry(vAdds, 6*i+3); - int Maj = Vec_IntEntry(vAdds, 6*i+4); - if ( Vec_IntEntry(vMap, Maj) >= 0 ) - { - int i2 = Vec_IntEntry(vMap, Maj); - int Xor2 = Vec_IntEntry(vAdds, 6*i2+3); - int Maj2 = Vec_IntEntry(vAdds, 6*i2+4); - printf( "*** Node %d has two MAJ adder drivers: %d%s (%d rank %d) and %d%s (%d rank %d).\n", - Maj, - i, Vec_IntEntry(vAdds, 6*i+2) ? "":"*", Vec_BitEntry(vXorOuts, Xor), Vec_IntEntry(vMapRank, Xor), - i2, Vec_IntEntry(vAdds, 6*i2+2) ? "":"*", Vec_BitEntry(vXorOuts, Xor2), Vec_IntEntry(vMapRank, Xor2) ); - } - Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), i ); + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+1), 1 ); + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+2), 1 ); + Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+3), 1 ); } return vMap; } @@ -159,103 +155,83 @@ Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors ) return vXorRoots; } // collects XOR trees belonging to each of XOR roots -Vec_Wec_t * Acec_FindXorTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRoots, Vec_Int_t ** pvMap ) +Vec_Int_t * Acec_RankTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRoots ) { Vec_Int_t * vDoubles = Vec_IntAlloc( 100 ); - Vec_Wec_t * vXorTrees = Vec_WecStart( Vec_IntSize(vXorRoots) ); - Vec_Int_t * vLevel; int i, k, Entry; - // map roots into their classes - Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + // map roots into their ranks + Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) ); Vec_IntForEachEntry( vXorRoots, Entry, i ) - { - Vec_IntWriteEntry( vMap, Entry, i ); - Vec_WecPush( vXorTrees, i, Entry ); - } - // map nodes into their classes + Vec_IntWriteEntry( vRanks, Entry, i ); + // map nodes into their ranks for ( i = Vec_IntSize(vXors)/4 - 1; i >= 0; i-- ) { int Root = Vec_IntEntry( vXors, 4*i ); - int Repr = Vec_IntEntry( vMap, Root ); - //assert( Repr != -1 ); - if ( Repr == -1 ) + int Rank = Vec_IntEntry( vRanks, Root ); + // skip XORs that are not part of any tree + if ( Rank == -1 ) continue; + // iterate through XOR inputs for ( k = 1; k < 4; k++ ) { int Node = Vec_IntEntry( vXors, 4*i+k ); - if ( Node == 0 ) + if ( Node == 0 ) // HA continue; - Entry = Vec_IntEntry( vMap, Node ); - if ( Entry == Repr ) + Entry = Vec_IntEntry( vRanks, Node ); + if ( Entry == Rank ) // the same tree continue; if ( Entry == -1 ) - { - Vec_IntWriteEntry( vMap, Node, Repr ); - Vec_WecPush( vXorTrees, Repr, Node ); - continue; - } - //printf( "Node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Repr ); - Vec_IntPushUnique( Vec_WecEntry(vXorTrees, Entry), Node ); - Vec_IntPush( vDoubles, Node ); + Vec_IntWriteEntry( vRanks, Node, Rank ); + else + Vec_IntPush( vDoubles, Node ); + //if ( Entry != -1 ) + //printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Rank ); } } - // clean map + // remove duplicated entries Vec_IntForEachEntry( vDoubles, Entry, i ) - Vec_IntWriteEntry( vMap, Entry, -1 ); + Vec_IntWriteEntry( vRanks, Entry, -1 ); Vec_IntFree( vDoubles ); - // sort nodes - Vec_WecForEachLevel( vXorTrees, vLevel, i ) - Vec_IntSort( vLevel, 0 ); - if ( pvMap ) - *pvMap = vMap; - else - Vec_IntFree( vMap ); - return vXorTrees; + return vRanks; } // collects leaves of each XOR tree -Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vAdds, Vec_Wec_t * vXorTrees, Vec_Int_t * vMap, Vec_Wec_t ** pvAddBoxes ) +Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks, Vec_Wec_t ** pvAddBoxes ) { - Vec_Bit_t * vMapXorOuts = Acec_MapXorOuts( p, vXors ); - Vec_Int_t * vMapMajOuts = Acec_MapMajOutsToAdds( p, vAdds, vMapXorOuts, vMap ); - Vec_Wec_t * vXorLeaves = Vec_WecStart( Vec_WecSize(vXorTrees) ); + Vec_Bit_t * vMapXors = Acec_MapXorOuts2( p, vXors, vRanks ); + Vec_Int_t * vMapMajs = Acec_MapMajOuts2( p, vAdds, vRanks ); + Vec_Wec_t * vXorLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) ); + Vec_Wec_t * vAddBoxes = Vec_WecStart( Vec_IntSize(vXorRoots) ); int i, k; - if ( pvAddBoxes ) - *pvAddBoxes = Vec_WecStart( Vec_WecSize(vXorTrees) ); - // collect leaves for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) { int Xor = Vec_IntEntry(vXors, 4*i); + int Rank = Vec_IntEntry(vRanks, Xor); + if ( Rank == -1 ) + continue; for ( k = 1; k < 4; k++ ) { - int Node = Vec_IntEntry(vXors, 4*i+k); - if ( Node == 0 ) + int Fanin = Vec_IntEntry(vXors, 4*i+k); + if ( Fanin == 0 ) continue; - if ( Vec_BitEntry(vMapXorOuts, Node) || Vec_IntEntry(vMap, Xor) == -1 ) + if ( Vec_BitEntry(vMapXors, Fanin) ) + { + assert( Rank == Vec_IntEntry(vRanks, Fanin) ); continue; - if ( Vec_IntEntry(vMapMajOuts, Node) == -1 ) // no maj driver - Vec_WecPush( vXorLeaves, Vec_IntEntry(vMap, Xor), Node ); - else if ( pvAddBoxes && Vec_IntEntry(vMap, Xor) > 0 ) // save adder box - Vec_WecPush( *pvAddBoxes, Vec_IntEntry(vMap, Xor)-1, Vec_IntEntry(vMapMajOuts, Node) ); + } + if ( Vec_IntEntry(vMapMajs, Fanin) == -1 ) // no adder driving this input + Vec_WecPush( vXorLeaves, Rank, Fanin ); + else if ( Vec_IntEntry(vRanks, Xor) > 0 ) // save adder box + Vec_WecPush( vAddBoxes, Rank-1, Vec_IntEntry(vMapMajs, Fanin) ); } } -/* + Vec_BitFree( vMapXors ); + Vec_IntFree( vMapMajs ); if ( pvAddBoxes ) - { - Vec_Int_t * vLevel; - //Vec_WecPrint( *pvAddBoxes, 0 ); - Vec_WecForEachLevelReverse( *pvAddBoxes, vLevel, i ) - if ( Vec_IntSize(vLevel) > 0 ) - break; - Vec_WecShrink( *pvAddBoxes, i+1 ); - //Vec_WecPrint( *pvAddBoxes, 0 ); - } -*/ - Vec_BitFree( vMapXorOuts ); - Vec_IntFree( vMapMajOuts ); + *pvAddBoxes = vAddBoxes; return vXorLeaves; } -Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorTrees, Vec_Wec_t * vXorLeaves ) +Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorLeaves, Vec_Int_t * vXorRoots ) { extern Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); extern void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit ); @@ -275,8 +251,8 @@ Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBox pBox->vLeafLits = Vec_WecStart( MaxRank + 0 ); pBox->vRootLits = Vec_WecStart( MaxRank + 0 ); - assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorTrees) ); assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorLeaves) ); + assert( Vec_WecSize(vAddBoxes) == Vec_IntSize(vXorRoots) ); // collect boxes; mark inputs/outputs Vec_WecForEachLevel( pBox->vAdds, vLevel, i ) @@ -332,12 +308,7 @@ Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBox Vec_IntPush( vLevel, Abc_Var2Lit(Node, 0) ); } vLevel = Vec_WecEntry( pBox->vRootLits, Vec_WecSize(pBox->vRootLits)-1 ); - vLevel2 = Vec_WecEntry( vXorTrees, Vec_WecSize(vXorTrees)-1 ); - Vec_IntClear( vLevel ); - if ( Vec_IntSize(vLevel) == 0 && Vec_IntSize(vLevel2) > 0 ) - { - Vec_IntPush( vLevel, Abc_Var2Lit(Vec_IntEntryLast(vLevel2), 0) ); - } + Vec_IntFill( vLevel, 1, Abc_Var2Lit(Vec_IntEntryLast(vXorRoots), 0) ); // sort each level Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i ) @@ -347,50 +318,49 @@ Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBox return pBox; } -Acec_Box_t * Acec_DetectXorTrees( Gia_Man_t * p, int fVerbose ) +Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose ) { + extern void Acec_TreeVerifyConnections( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); + abctime clk = Abc_Clock(); Acec_Box_t * pBox = NULL; Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 ); - Vec_Int_t * vMap, * vXorRootsNew; - Vec_Int_t * vXorRoots = Acec_FindXorRoots( p, vXors ); - Vec_Wec_t * vXorTrees = Acec_FindXorTrees( p, vXors, vXorRoots, &vMap ); + Vec_Int_t * vTemp, * vXorRoots = Acec_FindXorRoots( p, vXors ); + Vec_Int_t * vRanks = Acec_RankTrees( p, vXors, vXorRoots ); Vec_Wec_t * vXorLeaves, * vAddBoxes = NULL; + Gia_ManLevelNum(p); + //Ree_ManPrintAdders( vAdds, 1 ); printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); -// printf( "XOR roots: \n" ); -// Vec_IntPrint( vXorRoots ); -// Vec_WecPrint( vXorTrees, 0 ); + vXorRoots = Acec_OrderTreeRoots( p, vAdds, vTemp = vXorRoots, vRanks ); + Vec_IntFree( vTemp ); + Vec_IntFree( vRanks ); - vXorRootsNew = Acec_OrderXorRoots( p, vAdds, vXorRoots, vXorTrees, vMap ); - Vec_IntFree( vXorRoots ); - Vec_WecFree( vXorTrees ); - Vec_IntFree( vMap ); + vRanks = Acec_RankTrees( p, vXors, vXorRoots ); + vXorLeaves = Acec_FindXorLeaves( p, vXors, vAdds, vXorRoots, vRanks, &vAddBoxes ); + Vec_IntFree( vRanks ); - vXorRoots = vXorRootsNew; vXorRootsNew = NULL; - vXorTrees = Acec_FindXorTrees( p, vXors, vXorRoots, &vMap ); - vXorLeaves = Acec_FindXorLeaves( p, vXors, vAdds, vXorTrees, vMap, &vAddBoxes ); + //printf( "XOR roots after reordering: \n" ); + //Vec_IntPrint( vXorRoots ); + //printf( "XOR leaves: \n" ); + //Vec_WecPrint( vXorLeaves, 0 ); + //printf( "Adder boxes: \n" ); + //Vec_WecPrint( vAddBoxes, 0 ); - printf( "XOR roots: \n" ); - Vec_IntPrint( vXorRoots ); - printf( "XOR leaves: \n" ); - Vec_WecPrint( vXorLeaves, 0 ); - printf( "Adder boxes: \n" ); - Vec_WecPrint( vAddBoxes, 0 ); + Acec_TreeVerifyConnections( p, vAdds, vAddBoxes ); - pBox = Acec_FindBox( p, vAdds, vAddBoxes, vXorTrees, vXorLeaves ); + pBox = Acec_FindBox( p, vAdds, vAddBoxes, vXorLeaves, vXorRoots ); + //Vec_WecFree( vAddBoxes ); - Acec_TreePrintBox( pBox, vAdds ); + if ( fVerbose ) + Acec_TreePrintBox( pBox, vAdds ); Vec_IntFree( vXorRoots ); - Vec_WecFree( vXorTrees ); Vec_WecFree( vXorLeaves ); - //Vec_WecFree( vAddBoxes ); - Vec_IntFree( vMap ); Vec_IntFree( vXors ); Vec_IntFree( vAdds ); -- cgit v1.2.3 From 3020d57ea67f7f897c93524b9c3025767db3933b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 29 Jan 2017 13:39:35 -0800 Subject: Commenting out debug code. --- src/base/wlc/wlcReadVer.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 16de4943..e4a65ecf 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -429,7 +429,6 @@ char * Wlc_PrsConvertInitValues( Wlc_Ntk_t * p ) Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); Vec_IntForEachEntry( p->vInits, Value, i ) { - char * pname = Wlc_ObjName( p, Value ); if ( Value < 0 ) { for ( k = 0; k < -Value; k++ ) -- cgit v1.2.3 From e21c7d72f3f43f38e5af10a38602de6f6ce9a20e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 30 Jan 2017 08:39:26 -0800 Subject: Updates to arithmetic verification. --- src/aig/gia/giaUtil.c | 4 +- src/base/io/io.c | 2 +- src/proof/acec/acecInt.h | 1 + src/proof/acec/acecMult.c | 66 +++++++++++ src/proof/acec/acecStruct.c | 271 ++++++++++++++++++++++++++++++++++++++++++++ src/proof/acec/acecXor.c | 67 ++++++++++- 6 files changed, 403 insertions(+), 8 deletions(-) create mode 100644 src/proof/acec/acecStruct.c (limited to 'src') diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index eccdbc73..c7af642e 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -937,8 +937,8 @@ int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** pp return 0; if ( Gia_ObjFaninC0(p0) == Gia_ObjFaninC0(p1) || Gia_ObjFaninC1(p0) == Gia_ObjFaninC1(p1) ) return 0; - *ppFan0 = Gia_ObjChild0(p0); - *ppFan1 = Gia_ObjChild1(p0); + if ( ppFan0 ) *ppFan0 = Gia_ObjChild0(p0); + if ( ppFan1 ) *ppFan1 = Gia_ObjChild1(p0); return 1; } diff --git a/src/base/io/io.c b/src/base/io/io.c index 093eccca..4cec0157 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2150,7 +2150,7 @@ int IoCommandWriteCnf2( Abc_Frame_t * pAbc, int argc, char **argv ) extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); FILE * pFile; char * pFileName; - int nLutSize = 6; + int nLutSize = 8; int fNewAlgo = 1; int fCnfObjIds = 0; int fAddOrCla = 1; diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h index 381ab8d1..c4c8061e 100644 --- a/src/proof/acec/acecInt.h +++ b/src/proof/acec/acecInt.h @@ -76,6 +76,7 @@ extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdd /*=== acecMult.c ========================================================*/ extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits ); extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p ); +extern Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p ); /*=== acecNorm.c ========================================================*/ extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] ); extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll ); diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c index ba9405ac..c63fdde2 100644 --- a/src/proof/acec/acecMult.c +++ b/src/proof/acec/acecMult.c @@ -433,6 +433,72 @@ Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec return vInputs; } +/**Function************************************************************* + + Synopsis [Mark nodes whose function is exactly that of a Booth PP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p ) +{ + word Saved[32] = { + ABC_CONST(0xF335ACC0F335ACC0), + ABC_CONST(0x35C035C035C035C0), + ABC_CONST(0xD728D728D728D728), + ABC_CONST(0xFD80FD80FD80FD80), + ABC_CONST(0xACC0ACC0ACC0ACC0), + ABC_CONST(0x7878787878787878), + ABC_CONST(0x2828282828282828), + ABC_CONST(0xD0D0D0D0D0D0D0D0), + ABC_CONST(0x8080808080808080), + ABC_CONST(0x8888888888888888), + ABC_CONST(0xAAAAAAAAAAAAAAAA), + ABC_CONST(0x5555555555555555), + + ABC_CONST(0xD5A8D5A8D5A8D5A8), + ABC_CONST(0x2A572A572A572A57), + ABC_CONST(0xF3C0F3C0F3C0F3C0), + ABC_CONST(0x5858585858585858), + ABC_CONST(0xA7A7A7A7A7A7A7A7), + ABC_CONST(0x2727272727272727), + ABC_CONST(0xD8D8D8D8D8D8D8D8) + }; + + Vec_Bit_t * vRes = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + int i, iObj, nProds = 0; + Gia_ManCleanMark0(p); + Gia_ManForEachAndId( p, iObj ) + { + word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp ); + if ( Vec_IntSize(vSupp) > 6 ) + continue; + vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize ); + if ( Vec_IntSize(vSupp) > 5 ) + continue; + for ( i = 0; i < 32 && Saved[i]; i++ ) + { + if ( Truth == Saved[i] || Truth == ~Saved[i] ) + { + Vec_BitWriteEntry( vRes, iObj, 1 ); + nProds++; + break; + } + } + } + Gia_ManCleanMark0(p); + printf( "Collected %d pps.\n", nProds ); + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); + return vRes; +} + /**Function************************************************************* Synopsis [] diff --git a/src/proof/acec/acecStruct.c b/src/proof/acec/acecStruct.c new file mode 100644 index 00000000..6702e13b --- /dev/null +++ b/src/proof/acec/acecStruct.c @@ -0,0 +1,271 @@ +/**CFile**************************************************************** + + FileName [acecStruct.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [CEC for arithmetic circuits.] + + Synopsis [Core procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: acecStruct.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acecInt.h" +#include "misc/vec/vecWec.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_StructDetectXorRoots( Gia_Man_t * p ) +{ + Vec_Int_t * vXors = Vec_IntAlloc( 100 ); + Vec_Bit_t * vXorIns = Vec_BitStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pFan0, * pFan1, * pObj; + int i, k = 0, Entry; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + continue; + Vec_IntPush( vXors, i ); + Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan0)), 1 ); + Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan1)), 1 ); + } + // collect XORs that not inputs of other XORs + Vec_IntForEachEntry( vXors, Entry, i ) + if ( !Vec_BitEntry(vXorIns, Entry) ) + Vec_IntWriteEntry( vXors, k++, Entry ); + Vec_IntShrink( vXors, k ); + Vec_BitFree( vXorIns ); + return vXors; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_StructAssignRanks( Gia_Man_t * p, Vec_Int_t * vXorRoots ) +{ + Vec_Int_t * vDoubles = Vec_IntAlloc( 100 ); + Gia_Obj_t * pFan0, * pFan1, * pObj; + int i, k, Fanins[2], Entry, Rank; + // map roots into their ranks + Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_IntForEachEntry( vXorRoots, Entry, i ) + Vec_IntWriteEntry( vRanks, Entry, i ); + // map nodes into their ranks + Gia_ManForEachAndReverse( p, pObj, i ) + { + if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + continue; + Rank = Vec_IntEntry( vRanks, i ); + // skip XORs that are not part of any tree + if ( Rank == -1 ) + continue; + // iterate through XOR inputs + Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + for ( k = 0; k < 2; k++ ) + { + Entry = Vec_IntEntry( vRanks, Fanins[k] ); + if ( Entry == Rank ) // the same tree -- allow fanout in this tree + continue; + if ( Entry == -1 ) + Vec_IntWriteEntry( vRanks, Fanins[k], Rank ); + else + Vec_IntPush( vDoubles, Fanins[k] ); + if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Fanins[k]))) + printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Fanins[k], Entry, Rank ); + } + } + // remove duplicated entries + Vec_IntForEachEntry( vDoubles, Entry, i ) + Vec_IntWriteEntry( vRanks, Entry, -1 ); + Vec_IntFree( vDoubles ); + return vRanks; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Acec_FindTreeLeaves( Gia_Man_t * p, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks ) +{ + Vec_Bit_t * vMapXors = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Wec_t * vTreeLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) ); + Gia_Obj_t * pFan0, * pFan1, * pObj; + int i, k, Fanins[2], Rank; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + continue; + Vec_BitWriteEntry( vMapXors, i, 1 ); + Rank = Vec_IntEntry( vRanks, i ); + // skip XORs that are not part of any tree + if ( Rank == -1 ) + continue; + // iterate through XOR inputs + Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0)); + Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1)); + for ( k = 0; k < 2; k++ ) + { + if ( Vec_BitEntry(vMapXors, Fanins[k]) ) + { + assert( Rank == Vec_IntEntry(vRanks, Fanins[k]) ); + continue; + } + Vec_WecPush( vTreeLeaves, Rank, Fanins[k] ); + } + } + Vec_BitFree( vMapXors ); + return vTreeLeaves; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Acec_FindShadows( Gia_Man_t * p, Vec_Int_t * vRanks ) +{ + Vec_Int_t * vShadows = Vec_IntDup( vRanks ); + Gia_Obj_t * pObj; int i, Shad0, Shad1; + Gia_ManForEachCi( p, pObj, i ) + Vec_IntWriteEntry( vShadows, Gia_ObjId(p, pObj), -1 ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Vec_IntEntry(vShadows, i) >= 0 ) + continue; + Shad0 = Vec_IntEntry(vShadows, Gia_ObjFaninId0(pObj, i)); + Shad1 = Vec_IntEntry(vShadows, Gia_ObjFaninId1(pObj, i)); + if ( Shad0 == Shad1 && Shad0 != -1 ) + Vec_IntWriteEntry(vShadows, i, Shad0); + } + return vShadows; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Acec_CollectSupp_rec( Gia_Man_t * p, int iNode, int Rank, Vec_Int_t * vRanks ) +{ + Gia_Obj_t * pObj; + int nSize; + if ( Gia_ObjIsTravIdCurrentId(p, iNode) ) + return 0; + Gia_ObjSetTravIdCurrentId(p, iNode); + pObj = Gia_ManObj(p, iNode); + assert( Gia_ObjIsAnd(pObj) ); + if ( Vec_IntEntry(vRanks, iNode) == Rank ) + return 1; + nSize = Acec_CollectSupp_rec( p, Gia_ObjFaninId0(pObj, iNode), Rank, vRanks ); + nSize += Acec_CollectSupp_rec( p, Gia_ObjFaninId1(pObj, iNode), Rank, vRanks ); + return nSize; +} +Vec_Wec_t * Acec_FindNexts( Gia_Man_t * p, Vec_Int_t * vRanks, Vec_Int_t * vShadows, Vec_Wec_t * vTreeLeaves ) +{ + Vec_Wec_t * vNexts = Vec_WecStart( Vec_WecSize(vTreeLeaves) ); + Vec_Int_t * vTree; + int i, k, Node, Fanins[2], Shad0, Shad1, Rank, nSupp; + Vec_WecForEachLevel( vTreeLeaves, vTree, i ) + Vec_IntForEachEntry( vTree, Node, k ) + { + Gia_Obj_t * pObj = Gia_ManObj(p, Node); + if ( !Gia_ObjIsAnd(pObj) ) + continue; + Fanins[0] = Gia_ObjFaninId0(pObj, Node); + Fanins[1] = Gia_ObjFaninId1(pObj, Node); + Shad0 = Vec_IntEntry(vShadows, Fanins[0]); + Shad1 = Vec_IntEntry(vShadows, Fanins[1]); + if ( Shad0 != Shad1 || Shad0 == -1 ) + continue; + // check support size of Node in terms of the shadow of its fanins + Rank = Vec_IntEntry( vRanks, Node ); + assert( Rank != Shad0 ); + Gia_ManIncrementTravId( p ); + nSupp = Acec_CollectSupp_rec( p, Node, Shad0, vRanks ); + assert( nSupp > 1 ); + if ( nSupp > 3 ) + continue; + Vec_IntPushUniqueOrder( Vec_WecEntry(vNexts, Shad0), Rank ); + } + return vNexts; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_StructTest( Gia_Man_t * p ) +{ +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c index acbde1a0..71e0b7b3 100644 --- a/src/proof/acec/acecXor.c +++ b/src/proof/acec/acecXor.c @@ -33,6 +33,35 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_CheckXors( Gia_Man_t * p, Vec_Int_t * vXors ) +{ + Gia_Obj_t * pFan0, * pFan1; + Vec_Int_t * vCount2 = Vec_IntAlloc( Gia_ManObjNum(p) ); + int i, Entry, Count = 0; + for ( i = 0; 4*i < Vec_IntSize(vXors); i++ ) + if ( Vec_IntEntry(vXors, 4*i+3) == 0 ) + Vec_IntAddToEntry( vCount2, Vec_IntEntry(vXors, 4*i), 1 ); + Vec_IntForEachEntry( vCount2, Entry, i ) + if ( Entry > 1 ) + printf( "*** Obj %d has %d two-input XOR cuts.\n", i, Entry ), Count++; + else if ( Entry == 1 && Gia_ObjRecognizeExor(Gia_ManObj(p, i), &pFan0, &pFan1) ) + printf( "*** Obj %d cannot be recognized as XOR.\n", i ); + if ( Count == 0 ) + printf( "*** There no multiple two-input XOR cuts.\n" ); + Vec_IntFree( vCount2 ); +} + /**Function************************************************************* Synopsis [] @@ -151,7 +180,6 @@ Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors ) if ( !Vec_BitEntry(vMapXorIns, Vec_IntEntry(vXors, 4*i)) ) Vec_IntPushUniqueOrder( vXorRoots, Vec_IntEntry(vXors, 4*i) ); Vec_BitFree( vMapXorIns ); -//Vec_IntRemove( vXorRoots, 54 ); return vXorRoots; } // collects XOR trees belonging to each of XOR roots @@ -184,8 +212,9 @@ Vec_Int_t * Acec_RankTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRo Vec_IntWriteEntry( vRanks, Node, Rank ); else Vec_IntPush( vDoubles, Node ); - //if ( Entry != -1 ) - //printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Rank ); + + if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Node))) + printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Rank ); } } // remove duplicated entries @@ -211,6 +240,7 @@ Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vA for ( k = 1; k < 4; k++ ) { int Fanin = Vec_IntEntry(vXors, 4*i+k); + //int RankFanin = Vec_IntEntry(vRanks, Fanin); if ( Fanin == 0 ) continue; if ( Vec_BitEntry(vMapXors, Fanin) ) @@ -218,6 +248,8 @@ Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vA assert( Rank == Vec_IntEntry(vRanks, Fanin) ); continue; } +// if ( Vec_BitEntry(vMapXors, Fanin) && Rank == RankFanin ) +// continue; if ( Vec_IntEntry(vMapMajs, Fanin) == -1 ) // no adder driving this input Vec_WecPush( vXorLeaves, Rank, Fanin ); else if ( Vec_IntEntry(vRanks, Xor) > 0 ) // save adder box @@ -230,7 +262,26 @@ Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vA *pvAddBoxes = vAddBoxes; return vXorLeaves; } +void Acec_CheckBoothPPs( Gia_Man_t * p, Vec_Wec_t * vLitLeaves ) +{ + Vec_Bit_t * vMarked = Acec_MultMarkPPs( p ); + Vec_Int_t * vLevel; + int i, k, iLit; + Vec_WecForEachLevel( vLitLeaves, vLevel, i ) + { + int CountPI = 0, CountB = 0, CountNB = 0; + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( !Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) ) + CountPI++; + else if ( Vec_BitEntry( vMarked, Abc_Lit2Var(iLit) ) ) + CountB++; + else + CountNB++; + printf( "Rank %2d : Lits = %5d PI = %d Booth = %5d Non-Booth = %5d\n", i, Vec_IntSize(vLevel), CountPI, CountB, CountNB ); + } + Vec_BitFree( vMarked ); +} Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorLeaves, Vec_Int_t * vXorRoots ) { extern Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes ); @@ -315,6 +366,8 @@ Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBox Vec_IntSort( vLevel, 0 ); Vec_WecForEachLevel( pBox->vRootLits, vLevel, i ) Vec_IntSort( vLevel, 1 ); + + //Acec_CheckBoothPPs( p, pBox->vLeafLits ); return pBox; } @@ -331,9 +384,13 @@ Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose ) Gia_ManLevelNum(p); + //Acec_CheckXors( p, vXors ); + //Ree_ManPrintAdders( vAdds, 1 ); - printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( fVerbose ) + printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); vXorRoots = Acec_OrderTreeRoots( p, vAdds, vTemp = vXorRoots, vRanks ); Vec_IntFree( vTemp ); -- cgit v1.2.3 From 452a19f70c692372ef694af7f00ea38bf546cf01 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 30 Jan 2017 18:30:59 -0800 Subject: Improvements to SMT-LIB parser (bug fixes). --- src/base/wlc/wlcReadSmt.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index 61d0bca8..69a01ab0 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -48,6 +48,9 @@ struct Smt_Prs_t_ char ErrorStr[1000]; }; +//#define SMT_GLO_SUFFIX "_glb" +#define SMT_GLO_SUFFIX "" + // parser name types typedef enum { SMT_PRS_NONE = 0, @@ -634,7 +637,10 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits if ( pStr[2+i] == '1' ) Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i ); else if ( pStr[2+i] != '0' ) + { + Vec_IntFree( vFanins ); return 0; + } } else if ( pStr[1] == 'x' ) // hexadecimal { @@ -643,9 +649,16 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 ); if ( nDigits != (nBits + 3)/4 ) + { + Vec_IntFree( vFanins ); return 0; + } + } + else + { + Vec_IntFree( vFanins ); + return 0; } - else return 0; // create constant node iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_CONST, 0, nBits, vFanins, pName ); Vec_IntFree( vFanins ); @@ -1036,7 +1049,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1); strcpy(pStr_glb,pStr); - strcat(pStr_glb,"_glb"); + strcat(pStr_glb,SMT_GLO_SUFFIX); strcpy(pStr_loc,pStr); strcat(pStr_loc,suffix); @@ -1105,7 +1118,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, else { temp = (char *)malloc(strlen(pName2) + 4 + 1); strcpy(temp, pName2); - strcat(temp,"_glb"); + strcat(temp,SMT_GLO_SUFFIX); } // FIXME: need to delete memory of pName2 pName2 = temp; @@ -1273,7 +1286,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; // skip () @@ -1324,7 +1337,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; @@ -1407,7 +1420,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; @@ -1604,6 +1617,7 @@ static inline void Smt_PrsFree( Smt_Prs_t * p ) Vec_IntErase( &p->vStack ); Vec_IntErase( &p->vTempFans ); //Vec_WecErase( &p->vDepth ); + Vec_WecErase( &p->vObjs ); ABC_FREE( p ); } @@ -1634,6 +1648,7 @@ static inline void Smt_PrsSkipNonSpaces( Smt_Prs_t * p ) } void Smt_PrsReadLines( Smt_Prs_t * p ) { + int fFirstTime = 1; assert( Vec_IntSize(&p->vStack) == 0 ); //assert( Vec_WecSize(&p->vDepth) == 0 ); assert( Vec_WecSize(&p->vObjs) == 0 ); @@ -1647,8 +1662,9 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ ) { Smt_PrsSkipSpaces( p ); - if ( *p->pCur == '|' ) + if ( fFirstTime && *p->pCur == '|' ) { + fFirstTime = 0; *p->pCur = ' '; while ( *p->pCur && *p->pCur != '|' ) *p->pCur++ = ' '; -- cgit v1.2.3 From dc7445e435a56503a7e8e9e3889ef79ae89c4794 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 31 Jan 2017 11:09:38 -0800 Subject: Typo. --- src/map/scl/scl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index bd6d1cea..9d4653a7 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -259,7 +259,7 @@ usage: fprintf( pAbc->Err, "\t-d : toggle dumping the parsed library into file \"*_temp.lib\" [default = %s]\n", fDump? "yes": "no" ); fprintf( pAbc->Err, "\t-n : toggle replacing gate/pin names by short strings [default = %s]\n", fShortNames? "yes": "no" ); fprintf( pAbc->Err, "\t-v : toggle writing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pAbc->Err, "\t-v : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" ); + fprintf( pAbc->Err, "\t-w : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" ); fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); fprintf( pAbc->Err, "\t : the name of a file to read\n" ); return 1; -- cgit v1.2.3 From a226496bf9174b5d50df5a438e1ee52770492f4d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 31 Jan 2017 19:53:57 -0800 Subject: Adding API for generating a monitor of a set of internal signals in a sequential logic network. --- src/base/abc/abcUtil.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) (limited to 'src') diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index dd3a75b7..77b55bb3 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -2933,6 +2933,160 @@ void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk ) Vec_IntWriteEntry( pNtkNew->vPhases, Abc_ObjId( (Abc_Obj_t *)pObj->pCopy ), Vec_IntEntry(pNtk->vPhases, i) ); } +/**Function************************************************************* + + Synopsis [Starts a new network using existing network as a model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkDeriveWithOnePo( Abc_Ntk_t * pNtk, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues ) +{ + int fCopyNames = 1; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pFanin, * pObjNew, * pOutputNew; + Vec_Ptr_t * vFanins = Vec_PtrAlloc( 100 ); + int i, k, Id, Value; + // start the network + pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); + // duplicate the name and the spec + pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); + pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); + // clean the node copy fields + Abc_NtkCleanCopy( pNtk ); + // map the constant nodes + if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); + // clone CIs/CIs/boxes + Abc_NtkForEachPi( pNtk, pObj, i ) + Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); + //Abc_NtkForEachPo( pNtk, pObj, i ) + // Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); + // create one PO + pObjNew = Abc_NtkCreateObj( pNtkNew, ABC_OBJ_PO ); + Abc_ObjAssignName( pObjNew, "monitor", NULL ); + // create boxes + Abc_NtkForEachBox( pNtk, pObj, i ) + Abc_NtkDupBox( pNtkNew, pObj, fCopyNames ); + + // duplicate nodes (CIs/COs/latches are already duplicated) + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( pObj->pCopy == NULL && !Abc_ObjIsPo(pObj) ) + Abc_NtkDupObj(pNtkNew, pObj, 0); + // reconnect all objects except boxes (they are already connected) and POs (they will be connected later) + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( !Abc_ObjIsPo(pObj) && !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + + // AND nodes (with interters if needed) + pOutputNew = NULL; + Vec_IntForEachEntryTwo( vNodeIds, vNodeValues, Id, Value, i ) + { + pObjNew = Abc_NtkObj( pNtk, Id )->pCopy; + if ( Value == 0 ) // negative polarity - add inverter + pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew ); + if ( pOutputNew == NULL ) + pOutputNew = pObjNew; + else + { + Vec_PtrFillTwo( vFanins, 2, pOutputNew, pObjNew ); + pOutputNew = Abc_NtkCreateNodeAnd( pNtkNew, vFanins ); + } + } + Vec_PtrFree( vFanins ); + // create the only POs, which is the AND of the corresponding nodes + Abc_ObjAddFanin( Abc_NtkPo(pNtkNew, 0), pOutputNew ); + + // check that the CI/CO/latches are copied correctly + assert( Abc_NtkPoNum(pNtkNew) == 1 ); + assert( Abc_NtkCiNum(pNtkNew) == Abc_NtkCiNum(pNtk) ); + assert( Abc_NtkLatchNum(pNtkNew) == Abc_NtkLatchNum(pNtk) ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Derives the AIG representing a property.] + + Description [Given is a sequential logic network (Abc_Ntk_t) and + an array of nodes (vector of object IDs) and their values (vector of 0s or 1s). + This procedure creates a sequential AIG (Abc_Ntk_t), which can be given to a + sequential model checker (in particular "pdr") to prove that the given + combination of values never appears at the intenal nodes of the network, + or produce a counter-example showing that it can appear.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreatePropertyMonitor( Abc_Ntk_t * p, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues ) +{ + Abc_Ntk_t * pMonitor, * pStrashed, * pResult; + // sequential cleanup parameters + int fLatchConst = 1; + int fLatchEqual = 1; + int fSaveNames = 1; + int fUseMvSweep = 0; + int nFramesSymb = 1; + int nFramesSatur = 512; + int fVerbose = 0; + int fVeryVerbose = 0; + // expecting sequential logic network + assert( Abc_NtkIsLogic(p) ); + assert( Abc_NtkLatchNum(p) > 0 ); + assert( Vec_IntSize(vNodeIds) > 0 ); + assert( Vec_IntSize(vNodeIds) == Vec_IntSize(vNodeValues) ); + // derive ABC network whose only output is 1 iff the given nodes have the given values + pMonitor = Abc_NtkDeriveWithOnePo( p, vNodeIds, vNodeValues ); + // perform structural hashing + pStrashed = Abc_NtkStrash( pMonitor, 0, 1, 0 ); + Abc_NtkDelete( pMonitor ); + // it is a good idea to run sequential cleanup before giving the network to PDR + pResult = Abc_NtkDarLatchSweep( pStrashed, fLatchConst, fLatchEqual, fSaveNames, fUseMvSweep, nFramesSymb, nFramesSatur, fVerbose, fVeryVerbose ); + Abc_NtkDelete( pStrashed ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Testbench.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreatePropertyMonitorTest( Abc_Ntk_t * p ) +{ + Abc_Ntk_t * pNtk; + Vec_Int_t * vNodeIds = Vec_IntAlloc( 100 ); + Vec_Int_t * vNodeValues = Vec_IntAlloc( 100 ); + + // this test will only work for the network, which has nodes with internal IDs such as these + Vec_IntPush( vNodeIds, 90 ); + Vec_IntPush( vNodeIds, 80 ); + Vec_IntPush( vNodeIds, 100 ); + + Vec_IntPush( vNodeValues, 1 ); + Vec_IntPush( vNodeValues, 0 ); + Vec_IntPush( vNodeValues, 1 ); + + pNtk = Abc_NtkCreatePropertyMonitor( p, vNodeIds, vNodeValues ); + + Vec_IntFree( vNodeIds ); + Vec_IntFree( vNodeValues ); + + return pNtk; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From f14ee271abe8d38a6dad8789d4b4dbc207fe23c4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Feb 2017 12:44:54 -0800 Subject: Reordering if-statements in the xsat solver. --- src/sat/xsat/xsatSolver.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c index 9a98eec0..9807e1b7 100644 --- a/src/sat/xsat/xsatSolver.c +++ b/src/sat/xsat/xsatSolver.c @@ -680,12 +680,10 @@ unsigned xSAT_SolverPropagate( xSAT_Solver_t* s ) nProp++; for ( i = begin; i < end; i++ ) { - if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( xSAT_NegLit( i->Blocker ) ) ) - { - return i->CRef; - } - else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == VarX ) + if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == VarX ) xSAT_SolverEnqueue( s, i->Blocker, i->CRef ); + else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( xSAT_NegLit( i->Blocker ) ) ) + return i->CRef; } ws = xSAT_VecWatchListEntry( s->vWatches, p ); -- cgit v1.2.3 From e91abd6307e15d9d4a4985146025e12ae6780cff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Feb 2017 16:03:40 -0800 Subject: Improvements to inductive generalization in IC3/PDR by Zyad Hassan. --- src/base/abci/abc.c | 35 ++++++- src/proof/pdr/pdr.h | 3 + src/proof/pdr/pdrCore.c | 255 +++++++++++++++++++++++++++++++++++++++++++++-- src/proof/pdr/pdrInt.h | 4 + src/proof/pdr/pdrSat.c | 6 +- src/proof/pdr/pdrTsim.c | 4 +- src/proof/pdr/pdrUtil.c | 79 +++++++++++++++ src/sat/bsat/satSolver.c | 120 ++++++++++++++++++++++ src/sat/bsat/satSolver.h | 2 + 9 files changed, 495 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 806a5de7..7ff404b0 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGaxrmsipdegovwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmsipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26100,6 +26100,17 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nTimeOutGap < 0 ) goto usage; break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRandomSeed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRandomSeed < 0 ) + goto usage; + break; case 'a': pPars->fSolveAll ^= 1; break; @@ -26133,6 +26144,12 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'o': pPars->fUsePropOut ^= 1; break; + case 'n': + pPars->fSkipDown ^= 1; + break; + case 'c': + pPars->fCtgs ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26174,9 +26191,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHG ] [-axrmsipdegovwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmsipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); - Abc_Print( -2, "\t pioneered by Aaron Bradley (http://ecee.colorado.edu/~bradleya/ic3/)\n" ); + Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); @@ -26186,6 +26203,7 @@ usage: Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); + Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); @@ -26197,10 +26215,19 @@ usage: Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); + Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); + Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t-h : print the command usage\n\n"); + Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); + Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); + Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); + Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); + + + return 1; } diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 529a161f..b73a54df 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -49,6 +49,7 @@ struct Pdr_Par_t_ int nTimeOut; // timeout in seconds int nTimeOutGap; // approximate timeout in seconds since the last change int nTimeOutOne; // approximate timeout in seconds per one output + int nRandomSeed; // value to seed the SAT solver with int fTwoRounds; // use two rounds for generalization int fMonoCnf; // monolythic CNF int fDumpInv; // dump inductive invariant @@ -57,6 +58,8 @@ struct Pdr_Par_t_ int fShiftStart; // allows clause pushing to start from an intermediate frame int fReuseProofOblig; // reuses proof-obligationgs in the last timeframe int fSkipGeneral; // skips expensive generalization step + int fSkipDown; // skips the application of down + int fCtgs; // handle CTGs in down int fVerbose; // verbose output` int fVeryVerbose; // very verbose output int fNotVerbose; // not printing line by line progress diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index b81a1a2a..71a61c81 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -20,6 +20,7 @@ #include "pdrInt.h" #include "base/main/main.h" +#include "misc/hash/hash.h" ABC_NAMESPACE_IMPL_START @@ -57,7 +58,10 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->nConfLimit = 0; // limit on SAT solver conflicts pPars->nConfGenLimit = 0; // limit on SAT solver conflicts during generalization pPars->nRestLimit = 0; // limit on the number of proof-obligations + pPars->nRandomSeed = 91648253; // value to seed the SAT solver with pPars->fTwoRounds = 0; // use two rounds for generalization + pPars->fSkipDown = 1; // apply down in generalization + pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF pPars->fDumpInv = 0; // dump inductive invariant pPars->fUseSupp = 1; // using support variables in the invariant @@ -294,6 +298,190 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube ) +{ + int * pOrder; + int i, j, n, Lit, RetValue; + Pdr_Set_t * pCubeTmp; + // perform generalization + if ( p->pPars->fSkipGeneral ) + return 0; + + // sort literals by their occurences + pOrder = Pdr_ManSortByPriority( p, *ppCube ); + // try removing literals + for ( j = 0; j < (*ppCube)->nLits; j++ ) + { + // use ordering + // i = j; + i = pOrder[j]; + + assert( (*ppCube)->Lits[i] != -1 ); + // check init state + if ( Pdr_SetIsInit(*ppCube, i) ) + continue; + // try removing this literal + Lit = (*ppCube)->Lits[i]; (*ppCube)->Lits[i] = -1; + RetValue = Pdr_ManCheckCube( p, k, *ppCube, NULL, p->pPars->nConfLimit, 0 ); + if ( RetValue == -1 ) + return -1; + (*ppCube)->Lits[i] = Lit; + if ( RetValue == 0 ) + continue; + + // remove j-th entry + for ( n = j; n < (*ppCube)->nLits-1; n++ ) + pOrder[n] = pOrder[n+1]; + j--; + + // success - update the cube + *ppCube = Pdr_SetCreateFrom( pCubeTmp = *ppCube, i ); + Pdr_SetDeref( pCubeTmp ); + assert( (*ppCube)->nLits > 0 ); + i--; + + // get the ordering by decreasing priorit + pOrder = Pdr_ManSortByPriority( p, *ppCube ); + } + return 0; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, Hash_Int_t * keep, Pdr_Set_t * pIndCube, int * added ) +{ + int RetValue = 0, CtgRetValue, i, ctgAttempts, l, micResult; + int kMax = Vec_PtrSize(p->vSolvers)-1; + Pdr_Set_t * pCubeTmp, * pCubeMin, * pCtg; + while ( RetValue == 0 ) + { + ctgAttempts = 0; + while ( p->pPars->fCtgs && RetValue == 0 && k > 1 && ctgAttempts < 3 ) + { + pCtg = Pdr_SetDup ( pPred ); + //Check CTG for inductiveness + if ( Pdr_SetIsInit( pCtg, -1 ) ) + { + Pdr_SetDeref( pCtg ); + break; + } + if (*added == 0) + { + for ( i = 1; i <= k; i++ ) + Pdr_ManSolverAddClause( p, i, pIndCube); + *added = 1; + } + ctgAttempts++; + CtgRetValue = Pdr_ManCheckCube ( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0 ); + if ( CtgRetValue != 1 ) + { + Pdr_SetDeref( pCtg ); + break; + } + pCubeMin = Pdr_ManReduceClause( p, k-1, pCtg ); + if ( pCubeMin == NULL ) + pCubeMin = Pdr_SetDup ( pCtg ); + + for ( l = k; l < kMax; l++ ) + if ( !Pdr_ManCheckCube( p, l, pCubeMin, NULL, 0, 0 ) ) + break; + micResult = ZPdr_ManSimpleMic( p, l-1, &pCubeMin ); + assert ( micResult != -1 ); + + // add new clause + if ( p->pPars->fVeryVerbose ) + { + Abc_Print( 1, "Adding cube " ); + Pdr_SetPrint( stdout, pCubeMin, Aig_ManRegNum(p->pAig), NULL ); + Abc_Print( 1, " to frame %d.\n", l ); + } + // set priority flops + for ( i = 0; i < pCubeMin->nLits; i++ ) + { + assert( pCubeMin->Lits[i] >= 0 ); + assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); + Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 ); + } + + Vec_VecPush( p->vClauses, l, pCubeMin ); // consume ref + p->nCubes++; + // add clause + for ( i = 1; i <= l; i++ ) + Pdr_ManSolverAddClause( p, i, pCubeMin ); + RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); + assert( RetValue >= 0 ); + Pdr_SetDeref( pCtg ); + if ( RetValue == 1 ) + { + //printf ("IT'S A ONE\n"); + return 1; + } + } + + //join + if ( p->pPars->fVeryVerbose ) + { + printf("Cube:\n"); + ZPdr_SetPrint( *ppCube ); + printf("\nPred:\n"); + ZPdr_SetPrint( pPred ); + } + *ppCube = ZPdr_SetIntersection( pCubeTmp = *ppCube, pPred, keep ); + Pdr_SetDeref( pCubeTmp ); + Pdr_SetDeref( pPred ); + if ( *ppCube == NULL ) + return 0; + if ( p->pPars->fVeryVerbose ) + { + printf("Intersection:\n"); + ZPdr_SetPrint( *ppCube ); + } + if ( Pdr_SetIsInit( *ppCube, -1 ) ) + { + if ( p->pPars->fVeryVerbose ) + printf ("Failed initiation\n"); + return 0; + } + RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); + if ( RetValue == -1 ) + return -1; + if ( RetValue == 1 ) + { + //printf ("*********IT'S A ONE\n"); + break; + } + if ( RetValue == 0 && (*ppCube)->nLits == 1) + { + Pdr_SetDeref( pPred ); // fixed memory leak + // A workaround for the incomplete assignment returned by the SAT + // solver + return 0; + } + } + return 1; +} /**Function************************************************************* Synopsis [Returns 1 if the state could be blocked.] @@ -307,10 +495,12 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube ) ***********************************************************************/ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, Pdr_Set_t ** ppCubeMin ) { - Pdr_Set_t * pCubeMin, * pCubeTmp = NULL; + Pdr_Set_t * pCubeMin, * pCubeTmp = NULL, * pPred = NULL, * pCubeCpy = NULL; int i, j, n, Lit, RetValue; abctime clk = Abc_Clock(); int * pOrder; + int added = 0; + Hash_Int_t * keep = NULL; // if there is no induction, return *ppCubeMin = NULL; RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0 ); @@ -318,9 +508,11 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP return -1; if ( RetValue == 0 ) { - p->tGeneral += Abc_Clock() - clk; + p->tGeneral += clock() - clk; return 0; } + + keep = p->pPars->fSkipDown ? NULL : Hash_IntAlloc( 1 ); // reduce clause using assumptions // pCubeMin = Pdr_SetDup( pCube ); @@ -340,13 +532,22 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP // i = j; i = pOrder[j]; - // check init state assert( pCubeMin->Lits[i] != -1 ); + if ( keep && Hash_IntExists( keep, pCubeMin->Lits[i] ) ) + { + //printf("Undroppable\n"); + continue; + } + + // check init state if ( Pdr_SetIsInit(pCubeMin, i) ) continue; // try removing this literal - Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); + Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; + if ( p->pPars->fSkipDown ) + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); + else + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1 ); if ( RetValue == -1 ) { Pdr_SetDeref( pCubeMin ); @@ -354,7 +555,39 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP } pCubeMin->Lits[i] = Lit; if ( RetValue == 0 ) + { + if ( p->pPars->fSkipDown ) + continue; + pCubeCpy = Pdr_SetCreateFrom ( pCubeMin, i ); + RetValue = ZPdr_ManDown ( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); + if ( p->pPars->fCtgs ) + //CTG handling code messes up with the internal order array + pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + if ( RetValue == -1 ) + { + Pdr_SetDeref( pCubeMin ); + Pdr_SetDeref( pCubeCpy ); + Pdr_SetDeref( pPred ); + return -1; + } + if ( RetValue == 0 ) + { + if ( keep ) + Hash_IntWriteEntry( keep, pCubeMin->Lits[i], 0 ); + if ( pCubeCpy ) + Pdr_SetDeref( pCubeCpy ); continue; + } + //Inductive subclause + added = 0; + Pdr_SetDeref( pCubeMin ); + pCubeMin = pCubeCpy; + assert( pCubeMin->nLits > 0 ); + pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + j = -1; + continue; + } + added = 0; // remove j-th entry for ( n = j; n < pCubeMin->nLits-1; n++ ) @@ -383,7 +616,7 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP if ( Pdr_SetIsInit(pCubeMin, i) ) continue; // try removing this literal - Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; + Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0 ); if ( RetValue == -1 ) { @@ -411,8 +644,18 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP } assert( ppCubeMin != NULL ); + if ( p->pPars->fVeryVerbose ) + { + printf("Cube:\n"); + for ( i = 0; i < pCubeMin->nLits; i++) + { + printf ("%d ", pCubeMin->Lits[i]); + } + printf("\n"); + } *ppCubeMin = pCubeMin; p->tGeneral += Abc_Clock() - clk; + if ( keep ) Hash_IntFree( keep ); return 1; } diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index 6a08a150..9c1e9840 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -30,6 +30,7 @@ #include "sat/cnf/cnf.h" #include "sat/bsat/satSolver.h" #include "pdr.h" +#include "misc/hash/hashInt.h" ABC_NAMESPACE_HEADER_START @@ -196,10 +197,13 @@ extern Pdr_Set_t * Pdr_SetCreateSubset( Pdr_Set_t * pSet, int * pLits, int n extern Pdr_Set_t * Pdr_SetDup( Pdr_Set_t * pSet ); extern Pdr_Set_t * Pdr_SetRef( Pdr_Set_t * p ); extern void Pdr_SetDeref( Pdr_Set_t * p ); +extern Pdr_Set_t * ZPdr_SetIntersection( Pdr_Set_t * p1, Pdr_Set_t * p2, Hash_Int_t * keep ); extern int Pdr_SetContains( Pdr_Set_t * pOld, Pdr_Set_t * pNew ); extern int Pdr_SetContainsSimple( Pdr_Set_t * pOld, Pdr_Set_t * pNew ); extern int Pdr_SetIsInit( Pdr_Set_t * p, int iRemove ); +extern int ZPdr_SetIsInit( Pdr_Set_t * p ); extern void Pdr_SetPrint( FILE * pFile, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts ); +extern void ZPdr_SetPrint( Pdr_Set_t * p ); extern void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts ); extern int Pdr_SetCompare( Pdr_Set_t ** pp1, Pdr_Set_t ** pp2 ); extern Pdr_Obl_t * Pdr_OblStart( int k, int prio, Pdr_Set_t * pState, Pdr_Obl_t * pNext ); diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index 2e6130aa..eb94a826 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -51,7 +51,8 @@ sat_solver * Pdr_ManCreateSolver( Pdr_Man_t * p, int k ) assert( Vec_VecSize(p->vClauses) == k ); assert( Vec_IntSize(p->vActVars) == k ); // create new solver - pSat = sat_solver_new(); +// pSat = sat_solver_new(); + pSat = zsat_solver_new_seed(p->pPars->nRandomSeed); pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) ); Vec_PtrPush( p->vSolvers, pSat ); Vec_VecExpand( p->vClauses, k ); @@ -86,7 +87,8 @@ sat_solver * Pdr_ManFetchSolver( Pdr_Man_t * p, int k ) p->nStarts++; // sat_solver_delete( pSat ); // pSat = sat_solver_new(); - sat_solver_restart( pSat ); +// sat_solver_restart( pSat ); + zsat_solver_restart_seed( pSat, p->pPars->nRandomSeed ); // create new SAT solver pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) ); // write new SAT solver diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 32d1c857..37f84667 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -476,7 +476,9 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); assert( Vec_IntSize(vRes) > 0 ); p->tTsim += Abc_Clock() - clk; pRes = Pdr_SetCreate( vRes, vPiLits ); - assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); + //ZH: Disabled assertion because this invariant doesn't hold with down + //because of the join operation which can bring in initial states + //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); return pRes; } diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c index 32e97772..8fb83fd2 100644 --- a/src/proof/pdr/pdrUtil.c +++ b/src/proof/pdr/pdrUtil.c @@ -249,6 +249,85 @@ void Pdr_SetPrint( FILE * pFile, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCoun ABC_FREE( pBuff ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void ZPdr_SetPrint( Pdr_Set_t * p ) +{ + int i; + for ( i = 0; i < p->nLits; i++) + printf ("%d ", p->Lits[i]); + printf ("\n"); + +} + +/**Function************************************************************* + + Synopsis [Return the intersection of p1 and p2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Pdr_Set_t * ZPdr_SetIntersection( Pdr_Set_t * p1, Pdr_Set_t * p2, Hash_Int_t * keep ) +{ + Pdr_Set_t * pIntersection; + Vec_Int_t * vCommonLits, * vPiLits; + int i, j, nLits; + nLits = p1->nLits; + if ( p2->nLits < nLits ) + nLits = p2->nLits; + vCommonLits = Vec_IntAlloc( nLits ); + vPiLits = Vec_IntAlloc( 1 ); + for ( i = 0, j = 0; i < p1->nLits && j < p2->nLits; ) + { + if ( p1->Lits[i] > p2->Lits[j] ) + { + if ( Hash_IntExists( keep, p2->Lits[j] ) ) + { + //about to drop a literal that should not be dropped + Vec_IntFree( vCommonLits ); + Vec_IntFree( vPiLits ); + return NULL; + } + j++; + } + else if ( p1->Lits[i] < p2->Lits[j] ) + { + if ( Hash_IntExists( keep, p1->Lits[i] ) ) + { + //about to drop a literal that should not be dropped + Vec_IntFree( vCommonLits ); + Vec_IntFree( vPiLits ); + return NULL; + } + i++; + } + else + { + Vec_IntPush( vCommonLits, p1->Lits[i] ); + i++; + j++; + } + } + pIntersection = Pdr_SetCreate( vCommonLits, vPiLits ); + Vec_IntFree( vCommonLits ); + Vec_IntFree( vPiLits ); + return pIntersection; +} + + /**Function************************************************************* Synopsis [] diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 88a05093..3295fc6f 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -1085,6 +1085,77 @@ sat_solver* sat_solver_new(void) return s; } +sat_solver* zsat_solver_new_seed(double seed) +{ + sat_solver* s = (sat_solver*)ABC_CALLOC( char, sizeof(sat_solver)); + +// Vec_SetAlloc_(&s->Mem, 15); + Sat_MemAlloc_(&s->Mem, 15); + s->hLearnts = -1; + s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 ); + s->binary = clause_read( s, s->hBinary ); + + s->nLearntStart = LEARNT_MAX_START_DEFAULT; // starting learned clause limit + s->nLearntDelta = LEARNT_MAX_INCRE_DEFAULT; // delta of learned clause limit + s->nLearntRatio = LEARNT_MAX_RATIO_DEFAULT; // ratio of learned clause limit + s->nLearntMax = s->nLearntStart; + + // initialize vectors + veci_new(&s->order); + veci_new(&s->trail_lim); + veci_new(&s->tagged); +// veci_new(&s->learned); + veci_new(&s->act_clas); + veci_new(&s->stack); +// veci_new(&s->model); + veci_new(&s->act_vars); + veci_new(&s->unit_lits); + veci_new(&s->temp_clause); + veci_new(&s->conf_final); + + // initialize arrays + s->wlists = 0; + s->activity = 0; + s->orderpos = 0; + s->reasons = 0; + s->trail = 0; + + // initialize other vars + s->size = 0; + s->cap = 0; + s->qhead = 0; + s->qtail = 0; +#ifdef USE_FLOAT_ACTIVITY + s->var_inc = 1; + s->cla_inc = 1; + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999); +#else + s->var_inc = (1 << 5); + s->cla_inc = (1 << 11); +#endif + s->root_level = 0; +// s->simpdb_assigns = 0; +// s->simpdb_props = 0; + s->random_seed = seed; + s->progress_estimate = 0; +// s->binary = (clause*)ABC_ALLOC( char, sizeof(clause) + sizeof(lit)*2); +// s->binary->size_learnt = (2 << 1); + s->verbosity = 0; + + s->stats.starts = 0; + s->stats.decisions = 0; + s->stats.propagations = 0; + s->stats.inspects = 0; + s->stats.conflicts = 0; + s->stats.clauses = 0; + s->stats.clauses_literals = 0; + s->stats.learnts = 0; + s->stats.learnts_literals = 0; + s->stats.tot_literals = 0; + return s; +} + void sat_solver_setnvars(sat_solver* s,int n) { int var; @@ -1248,6 +1319,55 @@ void sat_solver_restart( sat_solver* s ) s->stats.tot_literals = 0; } +void zsat_solver_restart_seed( sat_solver* s, double seed ) +{ + int i; + Sat_MemRestart( &s->Mem ); + s->hLearnts = -1; + s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 ); + s->binary = clause_read( s, s->hBinary ); + + veci_resize(&s->act_clas, 0); + veci_resize(&s->trail_lim, 0); + veci_resize(&s->order, 0); + for ( i = 0; i < s->size*2; i++ ) + s->wlists[i].size = 0; + + s->nDBreduces = 0; + + // initialize other vars + s->size = 0; +// s->cap = 0; + s->qhead = 0; + s->qtail = 0; +#ifdef USE_FLOAT_ACTIVITY + s->var_inc = 1; + s->cla_inc = 1; + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999 ); +#else + s->var_inc = (1 << 5); + s->cla_inc = (1 << 11); +#endif + s->root_level = 0; +// s->simpdb_assigns = 0; +// s->simpdb_props = 0; + s->random_seed = seed; + s->progress_estimate = 0; + s->verbosity = 0; + + s->stats.starts = 0; + s->stats.decisions = 0; + s->stats.propagations = 0; + s->stats.inspects = 0; + s->stats.conflicts = 0; + s->stats.clauses = 0; + s->stats.clauses_literals = 0; + s->stats.learnts = 0; + s->stats.learnts_literals = 0; + s->stats.tot_literals = 0; +} + // returns memory in bytes used by the SAT solver double sat_solver_memory( sat_solver* s ) { diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 162b91e5..6ed611e1 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -42,6 +42,7 @@ struct sat_solver_t; typedef struct sat_solver_t sat_solver; extern sat_solver* sat_solver_new(void); +extern sat_solver* zsat_solver_new_seed(double seed); extern void sat_solver_delete(sat_solver* s); extern int sat_solver_addclause(sat_solver* s, lit* begin, lit* end); @@ -54,6 +55,7 @@ extern int sat_solver_push(sat_solver* s, int p); extern void sat_solver_pop(sat_solver* s); extern void sat_solver_set_resource_limits(sat_solver* s, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal); extern void sat_solver_restart( sat_solver* s ); +extern void zsat_solver_restart_seed( sat_solver* s, double seed ); extern void sat_solver_rollback( sat_solver* s ); extern int sat_solver_nvars(sat_solver* s); -- cgit v1.2.3 From 6d088bc440fb6b7a5b3eb2c9ea7b9950a1698166 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 17:02:36 -0800 Subject: Enabling new X-valued simulation in 'pdr'. --- src/base/abci/abc.c | 8 +- src/proof/pdr/module.make | 1 + src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 1 + src/proof/pdr/pdrInt.h | 8 + src/proof/pdr/pdrMan.c | 4 + src/proof/pdr/pdrSat.c | 9 +- src/proof/pdr/pdrTsim.c | 4 +- src/proof/pdr/pdrTsim2.c | 389 ++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 420 insertions(+), 5 deletions(-) create mode 100644 src/proof/pdr/pdrTsim2.c (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7ff404b0..b8a0a301 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmsipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmusipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26123,6 +26123,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'm': pPars->fMonoCnf ^= 1; break; + case 'u': + pPars->fNewXSim ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26191,7 +26194,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmsipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmusipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26208,6 +26211,7 @@ usage: Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); + Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); diff --git a/src/proof/pdr/module.make b/src/proof/pdr/module.make index 5bee83f8..2967aeb8 100644 --- a/src/proof/pdr/module.make +++ b/src/proof/pdr/module.make @@ -4,4 +4,5 @@ SRC += src/proof/pdr/pdrCnf.c \ src/proof/pdr/pdrMan.c \ src/proof/pdr/pdrSat.c \ src/proof/pdr/pdrTsim.c \ + src/proof/pdr/pdrTsim2.c \ src/proof/pdr/pdrUtil.c diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index b73a54df..9f9ef238 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -52,6 +52,7 @@ struct Pdr_Par_t_ int nRandomSeed; // value to seed the SAT solver with int fTwoRounds; // use two rounds for generalization int fMonoCnf; // monolythic CNF + int fNewXSim; // updated X-valued simulation int fDumpInv; // dump inductive invariant int fUseSupp; // use support in the invariant int fShortest; // forces bug traces to be shortest diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 71a61c81..38792ef8 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -63,6 +63,7 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->fSkipDown = 1; // apply down in generalization pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF + pPars->fNewXSim = 0; // updated X-valued simulation pPars->fDumpInv = 0; // dump inductive invariant pPars->fUseSupp = 1; // using support variables in the invariant pPars->fShortest = 0; // forces bug traces to be shortest diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index 9c1e9840..f47c08a9 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -42,6 +42,8 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// +typedef struct Txs_Man_t_ Txs_Man_t; + typedef struct Pdr_Set_t_ Pdr_Set_t; struct Pdr_Set_t_ { @@ -87,6 +89,8 @@ struct Pdr_Man_t_ int * pOrder; // ordering of the lits Vec_Int_t * vActVars; // the counter of activation variables int iUseFrame; // the first used frame + // terminary simulation + Txs_Man_t * pTxs; // internal use Vec_Int_t * vPrio; // priority flops Vec_Int_t * vLits; // array of literals @@ -189,6 +193,10 @@ extern int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCu extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf ); /*=== pdrTsim.c ==========================================================*/ extern Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); +/*=== pdrTsim2.c ==========================================================*/ +extern Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio ); +extern void Txs_ManStop( Txs_Man_t * ); +extern Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube ); /*=== pdrUtil.c ==========================================================*/ extern Pdr_Set_t * Pdr_SetAlloc( int nSize ); extern Pdr_Set_t * Pdr_SetCreate( Vec_Int_t * vLits, Vec_Int_t * vPiLits ); diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index b58c479b..eb12e341 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -70,6 +70,8 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vSuppLits= Vec_IntAlloc( 100 ); // support literals p->pCubeJust= Pdr_SetAlloc( Saig_ManRegNum(pAig) ); p->pCnfMan = Cnf_ManStart(); + // ternary simulation + p->pTxs = Txs_ManStart( p, pAig, p->vPrio ); // additional AIG data-members if ( pAig->pFanData == NULL ) Aig_ManFanoutStart( pAig ); @@ -150,6 +152,8 @@ void Pdr_ManStop( Pdr_Man_t * p ) Vec_WecFreeP( &p->vVLits ); // CNF manager Cnf_ManStop( p->pCnfMan ); + // terminary simulation + Txs_ManStop( p->pTxs ); // internal use Vec_IntFreeP( &p->vPrio ); // priority flops Vec_IntFree( p->vLits ); // array of literals diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index eb94a826..49b0448a 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -377,7 +377,14 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr p->tSatSat += clk; p->nCallsS++; if ( ppPred ) - *ppPred = Pdr_ManTernarySim( p, k, pCube ); + { + abctime clk = Abc_Clock(); + if ( p->pPars->fNewXSim ) + *ppPred = Txs_ManTernarySim( p->pTxs, k, pCube ); + else + *ppPred = Pdr_ManTernarySim( p, k, pCube ); + p->tTsim += Abc_Clock() - clk; + } RetValue = 0; } diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 37f84667..43f2ddb0 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -364,7 +364,7 @@ Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ) Vec_Int_t * vRes = p->vRes; // final result (flop literals) Aig_Obj_t * pObj; int i, Entry, RetValue; - abctime clk = Abc_Clock(); + //abctime clk = Abc_Clock(); // collect CO objects Vec_IntClear( vCoObjs ); @@ -474,7 +474,7 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); // derive the set of resulting registers Pdr_ManDeriveResult( p->pAig, vCiObjs, vCiVals, vCi2Rem, vRes, vPiLits ); assert( Vec_IntSize(vRes) > 0 ); - p->tTsim += Abc_Clock() - clk; + //p->tTsim += Abc_Clock() - clk; pRes = Pdr_SetCreate( vRes, vPiLits ); //ZH: Disabled assertion because this invariant doesn't hold with down //because of the join operation which can bring in initial states diff --git a/src/proof/pdr/pdrTsim2.c b/src/proof/pdr/pdrTsim2.c new file mode 100644 index 00000000..82e9a56c --- /dev/null +++ b/src/proof/pdr/pdrTsim2.c @@ -0,0 +1,389 @@ +/**CFile**************************************************************** + + FileName [pdrTsim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Property driven reachability.] + + Synopsis [Improved ternary simulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 20, 2010.] + + Revision [$Id: pdrTsim.c,v 1.00 2010/11/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pdrInt.h" +#include "aig/gia/giaAig.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Txs_Man_t_ +{ + Gia_Man_t * pGia; // user's AIG + Vec_Int_t * vPrio; // priority of each flop + Vec_Int_t * vCiObjs; // cone leaves (CI obj IDs) + Vec_Int_t * vCoObjs; // cone roots (CO obj IDs) + Vec_Int_t * vCiVals; // cone leaf values (0/1 CI values) + Vec_Int_t * vCoVals; // cone root values (0/1 CO values) + Vec_Int_t * vNodes; // cone nodes (node obj IDs) + Vec_Int_t * vPiLits; // resulting array of PI literals + Vec_Int_t * vFfLits; // resulting array of flop literals + Pdr_Man_t * pMan; // calling manager +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Start and stop the ternary simulation engine.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio ) +{ + Txs_Man_t * p; +// Aig_Obj_t * pObj; +// int i; + assert( Vec_IntSize(vPrio) == Aig_ManRegNum(pAig) ); + p = ABC_CALLOC( Txs_Man_t, 1 ); + p->pGia = Gia_ManFromAigSimple(pAig); // user's AIG +// Aig_ManForEachObj( pAig, pObj, i ) +// assert( i == 0 || pObj->iData == Abc_Var2Lit(i, 0) ); + p->vPrio = vPrio; // priority of each flop + p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves (CI obj IDs) + p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots (CO obj IDs) + p->vCiVals = Vec_IntAlloc( 100 ); // cone leaf values (0/1 CI values) + p->vCoVals = Vec_IntAlloc( 100 ); // cone root values (0/1 CO values) + p->vNodes = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs) + p->vPiLits = Vec_IntAlloc( 100 ); // resulting array of PI literals + p->vFfLits = Vec_IntAlloc( 100 ); // resulting array of flop literals + p->pMan = pMan; // calling manager + return p; +} +void Txs_ManStop( Txs_Man_t * p ) +{ + Gia_ManStop( p->pGia ); + Vec_IntFree( p->vCiObjs ); + Vec_IntFree( p->vCoObjs ); + Vec_IntFree( p->vCiVals ); + Vec_IntFree( p->vCoVals ); + Vec_IntFree( p->vNodes ); + Vec_IntFree( p->vPiLits ); + Vec_IntFree( p->vFfLits ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Marks the TFI cone and collects CIs and nodes.] + + Description [For this procedure to work Value should not be ~0 + at the beginning.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Txs_ManCollectCone_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes ) +{ + if ( !~pObj->Value ) + return; + pObj->Value = ~0; + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vCiObjs, Gia_ObjId(p, pObj) ); + return; + } + assert( Gia_ObjIsAnd(pObj) ); + Txs_ManCollectCone_rec( p, Gia_ObjFanin0(pObj), vCiObjs, vNodes ); + Txs_ManCollectCone_rec( p, Gia_ObjFanin1(pObj), vCiObjs, vNodes ); + Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); +} +void Txs_ManCollectCone( Gia_Man_t * p, Vec_Int_t * vCoObjs, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes ) +{ + Gia_Obj_t * pObj; int i; +// printf( "Collecting cones for clause with %d literals.\n", Vec_IntSize(vCoObjs) ); + Vec_IntClear( vCiObjs ); + Vec_IntClear( vNodes ); + Gia_ManConst0(p)->Value = ~0; + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + Txs_ManCollectCone_rec( p, Gia_ObjFanin0(pObj), vCiObjs, vNodes ); +} + +/**Function************************************************************* + + Synopsis [Propagate values and assign priority.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Txs_ManForwardPass( Gia_Man_t * p, + Vec_Int_t * vPrio, Vec_Int_t * vCiObjs, Vec_Int_t * vCiVals, + Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; int i; + pObj = Gia_ManConst0(p); + pObj->fMark0 = 0; + pObj->fMark1 = 0; + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + { + pObj->fMark0 = Vec_IntEntry(vCiVals, i); + pObj->fMark1 = 0; + pObj->Value = Gia_ObjIsPi(p, pObj) ? 0x7FFFFFFF : Vec_IntEntry(vPrio, Gia_ObjCioId(pObj)-Gia_ManPiNum(p)); + assert( ~pObj->Value ); + } + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + { + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + pObj->fMark0 = (pFan0->fMark0 ^ Gia_ObjFaninC0(pObj)) & (pFan1->fMark0 ^ Gia_ObjFaninC1(pObj)); + pObj->fMark1 = 0; + if ( pObj->fMark0 ) + pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value ); + else if ( pFan0->fMark0 ) + pObj->Value = pFan1->Value; + else if ( pFan1->fMark0 ) + pObj->Value = pFan0->Value; + else // if ( pFan0->fMark0 == 0 && pFan1->fMark0 == 0 ) + pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value ); + assert( ~pObj->Value ); + } + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + { + pFan0 = Gia_ObjFanin0(pObj); + pObj->fMark0 = (pFan0->fMark0 ^ Gia_ObjFaninC0(pObj)); + pFan0->fMark1 = 1; + assert( (int)pObj->fMark0 == Vec_IntEntry(vCoVals, i) ); + } +} + +/**Function************************************************************* + + Synopsis [Propagate requirements and collect results.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Txs_ObjIsJust( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pFan0 = Gia_ObjFanin0(pObj); + Gia_Obj_t * pFan1 = Gia_ObjFanin1(pObj); + int value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + int value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + assert( Gia_ObjIsAnd(pObj) ); + if ( pObj->fMark0 ) + return pFan0->fMark1 && pFan1->fMark1; + assert( !pObj->fMark0 ); + assert( !value0 || !value1 ); + if ( value0 ) + return pFan1->fMark1; + if ( value1 ) + return pFan0->fMark1; + assert( !value0 && !value1 ); + return pFan0->fMark1 || pFan1->fMark1 || Gia_ObjIsPi(p, pFan0) || Gia_ObjIsPi(p, pFan1); +} +void Txs_ManBackwardPass( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_Int_t * vPiLits, Vec_Int_t * vFfLits ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; int i, value0, value1; + Gia_ManForEachObjVecReverse( vNodes, p, pObj, i ) + { + if ( !pObj->fMark1 ) + continue; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( pObj->fMark0 ) + { + pFan0->fMark1 = 1; + pFan1->fMark1 = 1; + continue; + } + value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + assert( !value0 || !value1 ); + if ( value0 ) + pFan1->fMark1 = 1; + else if ( value1 ) + pFan0->fMark1 = 1; + else // if ( !value0 && !value1 ) + { + if ( pFan0->fMark1 || pFan1->fMark1 ) + continue; + if ( Gia_ObjIsPi(p, pFan0) ) + pFan0->fMark1 = 1; + else if ( Gia_ObjIsPi(p, pFan1) ) + pFan1->fMark1 = 1; + else if ( Gia_ObjIsAnd(pFan0) && Txs_ObjIsJust(p, pFan0) ) + pFan0->fMark1 = 1; + else if ( Gia_ObjIsAnd(pFan1) && Txs_ObjIsJust(p, pFan1) ) + pFan1->fMark1 = 1; + else + { + if ( pFan0->Value >= pFan1->Value ) + pFan0->fMark1 = 1; + else + pFan1->fMark1 = 1; + } + } + } + Vec_IntClear( vPiLits ); + Vec_IntClear( vFfLits ); + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + { + if ( !pObj->fMark1 ) + continue; + if ( Gia_ObjIsPi(p, pObj) ) + Vec_IntPush( vPiLits, Abc_Var2Lit(Gia_ObjCioId(pObj), !pObj->fMark0) ); + else + Vec_IntPush( vFfLits, Abc_Var2Lit(Gia_ObjCioId(pObj)-Gia_ManPiNum(p), !pObj->fMark0) ); + } + assert( Vec_IntSize(vFfLits) > 0 ); +} + +/**Function************************************************************* + + Synopsis [Verify the result.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Txs_ManVerify( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_Int_t * vPiLits, Vec_Int_t * vFfLits, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals ) +{ + Gia_Obj_t * pObj; + int i, iLit; + Gia_ObjTerSimSet0( Gia_ManConst0(p) ); + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + Gia_ObjTerSimSetX( pObj ); + Vec_IntForEachEntry( vPiLits, iLit, i ) + { + pObj = Gia_ManPi( p, Abc_Lit2Var(iLit) ); + assert( Gia_ObjTerSimGetX(pObj) ); + if ( Abc_LitIsCompl(iLit) ) + Gia_ObjTerSimSet0( pObj ); + else + Gia_ObjTerSimSet1( pObj ); + } + Vec_IntForEachEntry( vFfLits, iLit, i ) + { + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Abc_Lit2Var(iLit) ); + assert( Gia_ObjTerSimGetX(pObj) ); + if ( Abc_LitIsCompl(iLit) ) + Gia_ObjTerSimSet0( pObj ); + else + Gia_ObjTerSimSet1( pObj ); + } + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + Gia_ObjTerSimAnd( pObj ); + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + { + Gia_ObjTerSimCo( pObj ); + if ( Vec_IntEntry(vCoVals, i) ) + assert( Gia_ObjTerSimGet1(pObj) ); + else + assert( Gia_ObjTerSimGet0(pObj) ); + } +} + +/**Function************************************************************* + + Synopsis [Shrinks values using ternary simulation.] + + Description [The cube contains the set of flop index literals which, + when converted into a clause and applied to the combinational outputs, + led to a satisfiable SAT run in frame k (values stored in the SAT solver). + If the cube is NULL, it is assumed that the first property output was + asserted and failed. + The resulting array is a set of flop index literals that asserts the COs. + Priority contains 0 for i-th entry if the i-th FF is desirable to remove.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube ) +{ + Pdr_Set_t * pRes; + Gia_Obj_t * pObj; + // collect CO objects + Vec_IntClear( p->vCoObjs ); + if ( pCube == NULL ) // the target is the property output + { + pObj = Gia_ManCo(p->pGia, p->pMan->iOutCur); + Vec_IntPush( p->vCoObjs, Gia_ObjId(p->pGia, pObj) ); + } + else // the target is the cube + { + int i; + for ( i = 0; i < pCube->nLits; i++ ) + { + if ( pCube->Lits[i] == -1 ) + continue; + pObj = Gia_ManCo(p->pGia, Gia_ManPoNum(p->pGia) + Abc_Lit2Var(pCube->Lits[i])); + Vec_IntPush( p->vCoObjs, Gia_ObjId(p->pGia, pObj) ); + } + } +if ( 0 ) +{ +Abc_Print( 1, "Trying to justify cube " ); +if ( pCube ) + Pdr_SetPrint( stdout, pCube, Gia_ManRegNum(p->pGia), NULL ); +else + Abc_Print( 1, "" ); +Abc_Print( 1, " in frame %d.\n", k ); +} + + // collect CI objects + Txs_ManCollectCone( p->pGia, p->vCoObjs, p->vCiObjs, p->vNodes ); + // collect values + Pdr_ManCollectValues( p->pMan, k, p->vCiObjs, p->vCiVals ); + Pdr_ManCollectValues( p->pMan, k, p->vCoObjs, p->vCoVals ); + + // perform two passes + Txs_ManForwardPass( p->pGia, p->vPrio, p->vCiObjs, p->vCiVals, p->vNodes, p->vCoObjs, p->vCoVals ); + Txs_ManBackwardPass( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits ); + Txs_ManVerify( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits, p->vCoObjs, p->vCoVals ); + + // derive the final set + pRes = Pdr_SetCreate( p->vFfLits, p->vPiLits ); + //ZH: Disabled assertion because this invariant doesn't hold with down + //because of the join operation which can bring in initial states + //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); + return pRes; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END -- cgit v1.2.3 From a2cebd3e205751bf6e01d509c9568926069b6ab5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 17:32:44 -0800 Subject: Removing dead code in 'pdr'. --- src/proof/pdr/pdrInt.h | 3 --- src/proof/pdr/pdrMan.c | 4 ---- src/proof/pdr/pdrSat.c | 18 ---------------- src/proof/pdr/pdrUtil.c | 56 ------------------------------------------------- 4 files changed, 81 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index f47c08a9..89b6f0d0 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -103,8 +103,6 @@ struct Pdr_Man_t_ Vec_Int_t * vVisits; // intermediate Vec_Int_t * vCi2Rem; // CIs to be removed Vec_Int_t * vRes; // final result - Vec_Int_t * vSuppLits; // support literals - Pdr_Set_t * pCubeJust; // justification abctime * pTime4Outs;// timeout per output Vec_Ptr_t * vInfCubes; // infinity clauses/cubes // statistics @@ -224,7 +222,6 @@ extern void Pdr_QueueClean( Pdr_Man_t * p ); extern void Pdr_QueuePush( Pdr_Man_t * p, Pdr_Obl_t * pObl ); extern void Pdr_QueuePrint( Pdr_Man_t * p ); extern void Pdr_QueueStop( Pdr_Man_t * p ); -extern int Pdr_ManCubeJust( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); ABC_NAMESPACE_HEADER_END diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index eb12e341..31446290 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -67,8 +67,6 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vVisits = Vec_IntAlloc( 100 ); // intermediate p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed p->vRes = Vec_IntAlloc( 100 ); // final result - p->vSuppLits= Vec_IntAlloc( 100 ); // support literals - p->pCubeJust= Pdr_SetAlloc( Saig_ManRegNum(pAig) ); p->pCnfMan = Cnf_ManStart(); // ternary simulation p->pTxs = Txs_ManStart( p, pAig, p->vPrio ); @@ -166,9 +164,7 @@ void Pdr_ManStop( Pdr_Man_t * p ) Vec_IntFree( p->vVisits ); // intermediate Vec_IntFree( p->vCi2Rem ); // CIs to be removed Vec_IntFree( p->vRes ); // final result - Vec_IntFree( p->vSuppLits ); // support literals Vec_PtrFreeP( &p->vInfCubes ); - ABC_FREE( p->pCubeJust ); ABC_FREE( p->pTime4Outs ); if ( p->vCexes ) Vec_PtrFreeFree( p->vCexes ); diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index 49b0448a..936a8f90 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -342,24 +342,6 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr else return -1; } -/* - if ( RetValue == l_True ) - { - int RetValue2 = Pdr_ManCubeJust( p, k, pCube ); - if ( RetValue2 ) - p->nCasesSS++; - else - p->nCasesSU++; - } - else - { - int RetValue2 = Pdr_ManCubeJust( p, k, pCube ); - if ( RetValue2 ) - p->nCasesUS++; - else - p->nCasesUU++; - } -*/ } clk = Abc_Clock() - clk; p->tSat += clk; diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c index 8fb83fd2..986697ac 100644 --- a/src/proof/pdr/pdrUtil.c +++ b/src/proof/pdr/pdrUtil.c @@ -753,8 +753,6 @@ int Pdr_NtkFindSatAssign_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, int Value, Pd pNode->fMarkA = Value; if ( Aig_ObjIsCi(pNode) ) { -// if ( vSuppLits ) -// Vec_IntPush( vSuppLits, Abc_Var2Lit( Aig_ObjCioId(pNode), !Value ) ); if ( Saig_ObjIsLo(pAig, pNode) ) { // pCube->Lits[pCube->nLits++] = Abc_Var2Lit( Aig_ObjCioId(pNode) - Saig_ManPiNum(pAig), !Value ); @@ -793,60 +791,6 @@ int Pdr_NtkFindSatAssign_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, int Value, Pd return Pdr_NtkFindSatAssign_rec(pAig, Aig_ObjFanin0(pNode), Aig_ObjFaninC0(pNode), pCube, Heur); } -/**Function************************************************************* - - Synopsis [Returns 1 if SAT assignment is found; 0 otherwise.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Pdr_ManCubeJust( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ) -{ - Aig_Obj_t * pNode; - int i, v, fCompl; -// return 0; - for ( i = 0; i < 4; i++ ) - { - // derive new assignment - p->pCubeJust->nLits = 0; - p->pCubeJust->Sign = 0; - Aig_ManIncrementTravId( p->pAig ); - for ( v = 0; v < pCube->nLits; v++ ) - { - if ( pCube->Lits[v] == -1 ) - continue; - pNode = Saig_ManLi( p->pAig, lit_var(pCube->Lits[v]) ); - fCompl = lit_sign(pCube->Lits[v]) ^ Aig_ObjFaninC0(pNode); - if ( !Pdr_NtkFindSatAssign_rec( p->pAig, Aig_ObjFanin0(pNode), !fCompl, p->pCubeJust, i ) ) - break; - } - if ( v < pCube->nLits ) - continue; - // figure this out!!! - if ( p->pCubeJust->nLits == 0 ) - continue; - // successfully derived new assignment - Vec_IntSelectSort( p->pCubeJust->Lits, p->pCubeJust->nLits ); - // check assignment against this cube - if ( Pdr_SetContainsSimple( p->pCubeJust, pCube ) ) - continue; -//printf( "\n" ); -//Pdr_SetPrint( stdout, pCube, Saig_ManRegNum(p->pAig), NULL ); printf( "\n" ); -//Pdr_SetPrint( stdout, p->pCubeJust, Saig_ManRegNum(p->pAig), NULL ); printf( "\n" ); - // check assignment against the clauses - if ( Pdr_ManCheckContainment( p, k, p->pCubeJust ) ) - continue; - // find good assignment - return 1; - } - return 0; -} - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 45bf0369a84f9fdc55dd8cdc6227bdfd7c146dee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 19:51:53 -0800 Subject: Adding structural flop priority heuristics in 'pdr'. --- src/base/abci/abc.c | 8 +++- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 106 ++++++++++++++++++++------------------------- src/proof/pdr/pdrInt.h | 3 ++ src/proof/pdr/pdrInv.c | 2 + src/proof/pdr/pdrMan.c | 102 +++++++++++++++++++++++++++++++++++++++++-- src/proof/pdr/pdrSat.c | 2 + src/proof/pdr/pdrTsim.c | 112 ++++++++++++++++++++++++------------------------ 8 files changed, 214 insertions(+), 122 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index b8a0a301..319525cf 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmusipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuysipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26126,6 +26126,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'u': pPars->fNewXSim ^= 1; break; + case 'y': + pPars->fFlopPrio ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26194,7 +26197,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmusipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuysipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26212,6 +26215,7 @@ usage: Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 9f9ef238..18b059c6 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -53,6 +53,7 @@ struct Pdr_Par_t_ int fTwoRounds; // use two rounds for generalization int fMonoCnf; // monolythic CNF int fNewXSim; // updated X-valued simulation + int fFlopPrio; // use structural flop priorities int fDumpInv; // dump inductive invariant int fUseSupp; // use support in the invariant int fShortest; // forces bug traces to be shortest diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 38792ef8..cfc79d85 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -63,6 +63,7 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->fSkipDown = 1; // apply down in generalization pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF + pPars->fFlopPrio = 0; // use structural flop priorities pPars->fNewXSim = 0; // updated X-valued simulation pPars->fDumpInv = 0; // dump inductive invariant pPars->fUseSupp = 1; // using support variables in the invariant @@ -313,7 +314,7 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube ) int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube ) { int * pOrder; - int i, j, n, Lit, RetValue; + int i, j, Lit, RetValue; Pdr_Set_t * pCubeTmp; // perform generalization if ( p->pPars->fSkipGeneral ) @@ -341,19 +342,14 @@ int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube ) if ( RetValue == 0 ) continue; - // remove j-th entry - for ( n = j; n < (*ppCube)->nLits-1; n++ ) - pOrder[n] = pOrder[n+1]; - j--; - // success - update the cube *ppCube = Pdr_SetCreateFrom( pCubeTmp = *ppCube, i ); Pdr_SetDeref( pCubeTmp ); assert( (*ppCube)->nLits > 0 ); - i--; - // get the ordering by decreasing priorit + // get the ordering by decreasing priority pOrder = Pdr_ManSortByPriority( p, *ppCube ); + j--; } return 0; } @@ -423,7 +419,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, { assert( pCubeMin->Lits[i] >= 0 ); assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); - Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 ); + Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift ); } Vec_VecPush( p->vClauses, l, pCubeMin ); // consume ref @@ -456,14 +452,14 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, return 0; if ( p->pPars->fVeryVerbose ) { - printf("Intersection:\n"); - ZPdr_SetPrint( *ppCube ); + printf("Intersection:\n"); + ZPdr_SetPrint( *ppCube ); } if ( Pdr_SetIsInit( *ppCube, -1 ) ) { - if ( p->pPars->fVeryVerbose ) - printf ("Failed initiation\n"); - return 0; + if ( p->pPars->fVeryVerbose ) + printf ("Failed initiation\n"); + return 0; } RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); if ( RetValue == -1 ) @@ -497,7 +493,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, Pdr_Set_t ** ppCubeMin ) { Pdr_Set_t * pCubeMin, * pCubeTmp = NULL, * pPred = NULL, * pCubeCpy = NULL; - int i, j, n, Lit, RetValue; + int i, j, Lit, RetValue; abctime clk = Abc_Clock(); int * pOrder; int added = 0; @@ -546,9 +542,9 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP // try removing this literal Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; if ( p->pPars->fSkipDown ) - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); else - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1 ); if ( RetValue == -1 ) { Pdr_SetDeref( pCubeMin ); @@ -557,52 +553,47 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP pCubeMin->Lits[i] = Lit; if ( RetValue == 0 ) { - if ( p->pPars->fSkipDown ) - continue; - pCubeCpy = Pdr_SetCreateFrom ( pCubeMin, i ); - RetValue = ZPdr_ManDown ( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); - if ( p->pPars->fCtgs ) - //CTG handling code messes up with the internal order array + if ( p->pPars->fSkipDown ) + continue; + pCubeCpy = Pdr_SetCreateFrom ( pCubeMin, i ); + RetValue = ZPdr_ManDown ( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); + if ( p->pPars->fCtgs ) + //CTG handling code messes up with the internal order array + pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + if ( RetValue == -1 ) + { + Pdr_SetDeref( pCubeMin ); + Pdr_SetDeref( pCubeCpy ); + Pdr_SetDeref( pPred ); + return -1; + } + if ( RetValue == 0 ) + { + if ( keep ) + Hash_IntWriteEntry( keep, pCubeMin->Lits[i], 0 ); + if ( pCubeCpy ) + Pdr_SetDeref( pCubeCpy ); + continue; + } + //Inductive subclause + added = 0; + Pdr_SetDeref( pCubeMin ); + pCubeMin = pCubeCpy; + assert( pCubeMin->nLits > 0 ); pOrder = Pdr_ManSortByPriority( p, pCubeMin ); - if ( RetValue == -1 ) - { - Pdr_SetDeref( pCubeMin ); - Pdr_SetDeref( pCubeCpy ); - Pdr_SetDeref( pPred ); - return -1; - } - if ( RetValue == 0 ) - { - if ( keep ) - Hash_IntWriteEntry( keep, pCubeMin->Lits[i], 0 ); - if ( pCubeCpy ) - Pdr_SetDeref( pCubeCpy ); + j = -1; continue; - } - //Inductive subclause - added = 0; - Pdr_SetDeref( pCubeMin ); - pCubeMin = pCubeCpy; - assert( pCubeMin->nLits > 0 ); - pOrder = Pdr_ManSortByPriority( p, pCubeMin ); - j = -1; - continue; } added = 0; - // remove j-th entry - for ( n = j; n < pCubeMin->nLits-1; n++ ) - pOrder[n] = pOrder[n+1]; - j--; - // success - update the cube pCubeMin = Pdr_SetCreateFrom( pCubeTmp = pCubeMin, i ); Pdr_SetDeref( pCubeTmp ); assert( pCubeMin->nLits > 0 ); - i--; - // get the ordering by decreasing priorit + // get the ordering by decreasing priority pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + j--; } if ( p->pPars->fTwoRounds ) @@ -628,19 +619,14 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP if ( RetValue == 0 ) continue; - // remove j-th entry - for ( n = j; n < pCubeMin->nLits-1; n++ ) - pOrder[n] = pOrder[n+1]; - j--; - // success - update the cube pCubeMin = Pdr_SetCreateFrom( pCubeTmp = pCubeMin, i ); Pdr_SetDeref( pCubeTmp ); assert( pCubeMin->nLits > 0 ); - i--; - // get the ordering by decreasing priorit + // get the ordering by decreasing priority pOrder = Pdr_ManSortByPriority( p, pCubeMin ); + j--; } } @@ -762,7 +748,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ) { assert( pCubeMin->Lits[i] >= 0 ); assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); - Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 ); + Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift ); } Vec_VecPush( p->vClauses, k, pCubeMin ); // consume ref p->nCubes++; diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index 89b6f0d0..dae20f0c 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -82,6 +82,7 @@ struct Pdr_Man_t_ Vec_Wec_t * vVLits; // CNF literals // data representation int iOutCur; // current output + int nPrioShift;// priority shift Vec_Ptr_t * vCexes; // counter-examples for each output Vec_Ptr_t * vSolvers; // SAT solvers Vec_Vec_t * vClauses; // clauses by timeframe @@ -121,6 +122,8 @@ struct Pdr_Man_t_ int nQueCur; int nQueMax; int nQueLim; + int nXsimRuns; + int nXsimLits; // runtime abctime timeToStop; abctime timeToStopOne; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 8b04c53b..16d98a36 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -467,6 +467,8 @@ void Pdr_ManReportInvariant( Pdr_Man_t * p ) Vec_Ptr_t * vCubes; int kStart = Pdr_ManFindInvariantStart( p ); vCubes = Pdr_ManCollectCubes( p, kStart ); +// Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (%.2f)\n", +// kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), 1.0*p->nXsimLits/p->nXsimRuns ); Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n", kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) ); Vec_PtrFree( vCubes ); diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index 31446290..6fe4c28d 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "pdrInt.h" +#include "aig/gia/giaAig.h" ABC_NAMESPACE_IMPL_START @@ -31,6 +32,94 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [Structural analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pnPrioShift ) +{ + Vec_Int_t * vRes = NULL; + Gia_Obj_t * pObj; + int MaxEntry = 0; + int i, * pPerm; + // create flop costs + Vec_Int_t * vCosts = Vec_IntStart( Gia_ManRegNum(p) ); + Gia_ManCreateRefs(p); + Gia_ManForEachRo( p, pObj, i ) + { + Vec_IntWriteEntry( vCosts, i, Gia_ObjRefNum(p, pObj) ); + MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) ); + } + MaxEntry++; + ABC_FREE( p->pRefs ); + // add costs due to MUX inputs + if ( fMuxCtrls ) + { + int fVerbose = 0; + Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pCtrl, * pData1, * pData0; + int nCtrls = 0, nDatas = 0, nBoth = 0; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 ); + pCtrl = Gia_Regular(pCtrl); + pData1 = Gia_Regular(pData1); + pData0 = Gia_Regular(pData0); + Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 ); + Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 ); + Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 ); + } + Gia_ManForEachRo( p, pObj, i ) + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) + Vec_IntAddToEntry( vCosts, i, 2*MaxEntry ); + //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + // Vec_IntAddToEntry( vCosts, i, MaxEntry ); + MaxEntry *= 3; + // print out + if ( fVerbose ) + { + Gia_ManForEachRo( p, pObj, i ) + { + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) + nCtrls++; + if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + nDatas++; + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + nBoth++; + } + printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth ); + } + Vec_BitFree( vCtrls ); + Vec_BitFree( vDatas ); + } + *pnPrioShift = 1 + Abc_Base2Log( MaxEntry ); + // create ordering based on costs + pPerm = Abc_MergeSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts) ); + vRes = Vec_IntAllocArray( pPerm, Vec_IntSize(vCosts) ); + Vec_IntFree( vCosts ); + vCosts = Vec_IntInvert( vRes, -1 ); + Vec_IntFree( vRes ); +//Vec_IntPrint( vCosts ); + return vCosts; +} +Vec_Int_t * Pdr_ManDeriveFlopPriorities( Aig_Man_t * pAig, int fMuxCtrls, int * pnPrioShift ) +{ + Gia_Man_t * pGia = Gia_ManFromAigSimple(pAig); + Vec_Int_t * vRes = Pdr_ManDeriveFlopPriorities2(pGia, fMuxCtrls, pnPrioShift); + Gia_ManStop( pGia ); + return vRes; +} + /**Function************************************************************* Synopsis [Creates manager.] @@ -56,7 +145,13 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio if ( !p->pPars->fMonoCnf ) p->vVLits = Vec_WecStart( 1+Abc_MaxInt(1, Aig_ManLevels(pAig)) ); // internal use - p->vPrio = vPrioInit ? vPrioInit : Vec_IntStart( Aig_ManRegNum(pAig) ); // priority flops + p->nPrioShift = 0; + if ( vPrioInit ) + p->vPrio = vPrioInit; + else if ( pPars->fFlopPrio ) + p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 0, &p->nPrioShift); + else + p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) ); p->vLits = Vec_IntAlloc( 100 ); // array of literals p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots @@ -69,7 +164,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vRes = Vec_IntAlloc( 100 ); // final result p->pCnfMan = Cnf_ManStart(); // ternary simulation - p->pTxs = Txs_ManStart( p, pAig, p->vPrio ); + p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL; // additional AIG data-members if ( pAig->pFanData == NULL ) Aig_ManFanoutStart( pAig ); @@ -151,7 +246,8 @@ void Pdr_ManStop( Pdr_Man_t * p ) // CNF manager Cnf_ManStop( p->pCnfMan ); // terminary simulation - Txs_ManStop( p->pTxs ); + if ( p->pPars->fNewXSim ) + Txs_ManStop( p->pTxs ); // internal use Vec_IntFreeP( &p->vPrio ); // priority flops Vec_IntFree( p->vLits ); // array of literals diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index 936a8f90..b9403e6f 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -366,6 +366,8 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr else *ppPred = Pdr_ManTernarySim( p, k, pCube ); p->tTsim += Abc_Clock() - clk; + p->nXsimLits += (*ppPred)->nLits; + p->nXsimRuns++; } RetValue = 0; } diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 43f2ddb0..0bcb6e0c 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -404,67 +404,65 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, NULL ); RetValue = Pdr_ManSimDataInit( p->pAig, vCiObjs, vCiVals, vNodes, vCoObjs, vCoVals, NULL ); assert( RetValue ); -#if 1 - // try removing high-priority flops - Vec_IntClear( vCi2Rem ); - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + // iteratively remove flops + if ( p->pPars->fFlopPrio ) { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 ) - continue; - Vec_IntClear( vUndo ); - if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) - Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); - else - Pdr_ManExtendUndo( p->pAig, vUndo ); - } - // try removing low-priority flops - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) - { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 ) - continue; - Vec_IntClear( vUndo ); - if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) - Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); - else - Pdr_ManExtendUndo( p->pAig, vUndo ); - } -#else - // try removing low-priority flops - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) - { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 ) - continue; - Vec_IntClear( vUndo ); - if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) - Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); - else - Pdr_ManExtendUndo( p->pAig, vUndo ); + // collect flops and sort them by priority + Vec_IntClear( vRes ); + Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + { + if ( !Saig_ObjIsLo( p->pAig, pObj ) ) + continue; + Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); + Vec_IntPush( vRes, Entry ); + } + Vec_IntSelectSortCost( Vec_IntArray(vRes), Vec_IntSize(vRes), vPrio ); + + // try removing flops starting from low-priority to high-priority + Vec_IntClear( vCi2Rem ); + Vec_IntForEachEntry( vRes, Entry, i ) + { + pObj = Aig_ManCi( p->pAig, Saig_ManPiNum(p->pAig) + Entry ); + assert( Saig_ObjIsLo( p->pAig, pObj ) ); + Vec_IntClear( vUndo ); + if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) + Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); + else + Pdr_ManExtendUndo( p->pAig, vUndo ); + } } - // try removing high-priority flops - Vec_IntClear( vCi2Rem ); - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + else { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 ) - continue; - Vec_IntClear( vUndo ); - if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) - Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); - else - Pdr_ManExtendUndo( p->pAig, vUndo ); + // try removing low-priority flops first + Vec_IntClear( vCi2Rem ); + Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + { + if ( !Saig_ObjIsLo( p->pAig, pObj ) ) + continue; + Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); + if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 ) + continue; + Vec_IntClear( vUndo ); + if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) + Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); + else + Pdr_ManExtendUndo( p->pAig, vUndo ); + } + // try removing high-priority flops next + Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + { + if ( !Saig_ObjIsLo( p->pAig, pObj ) ) + continue; + Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); + if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 ) + continue; + Vec_IntClear( vUndo ); + if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) + Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) ); + else + Pdr_ManExtendUndo( p->pAig, vUndo ); + } } -#endif if ( p->pPars->fVeryVerbose ) Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); -- cgit v1.2.3 From 2c4c464ab0a0f5a7ff91dd3abb1c39dbadefa1de Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 21:31:40 -0800 Subject: Adding structural flop priority heuristics in 'pdr' (bug fix). --- src/proof/pdr/pdrMan.c | 135 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 126 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index 6fe4c28d..f682e946 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -43,15 +43,134 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pnPrioShift ) +Vec_Int_t * Pdr_ManDeriveFlopPriorities3( Gia_Man_t * p, int fMuxCtrls ) { + int fDiscount = 0; + Vec_Wec_t * vLevels; + Vec_Int_t * vRes, * vLevel, * vCosts; + Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1; + int i, k, Entry, MaxEntry = 0; + Gia_ManCreateRefs(p); + // discount references + if ( fDiscount ) + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); + pData0 = Gia_Regular(pData0); + pData1 = Gia_Regular(pData1); + p->pRefs[Gia_ObjId(p, pCtrl)]--; + if ( pData0 == pData1 ) + p->pRefs[Gia_ObjId(p, pData0)]--; + } + // create flop costs + vCosts = Vec_IntAlloc( Gia_ManRegNum(p) ); + Gia_ManForEachRo( p, pObj, i ) + { + Vec_IntPush( vCosts, Gia_ObjRefNum(p, pObj) ); + MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) ); + //printf( "%d(%d) ", i, Gia_ObjRefNum(p, pObj) ); + } + //printf( "\n" ); + MaxEntry++; + // add costs due to MUX inputs + if ( fMuxCtrls ) + { + int fVerbose = 0; + Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) ); + Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pCtrl, * pData1, * pData0; + int nCtrls = 0, nDatas = 0, nBoth = 0; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 ); + pCtrl = Gia_Regular(pCtrl); + pData1 = Gia_Regular(pData1); + pData0 = Gia_Regular(pData0); + Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 ); + Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 ); + Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 ); + } + Gia_ManForEachRo( p, pObj, i ) + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) + Vec_IntAddToEntry( vCosts, i, MaxEntry ); + //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + // Vec_IntAddToEntry( vCosts, i, MaxEntry ); + MaxEntry = 2*MaxEntry + 1; + // print out + if ( fVerbose ) + { + Gia_ManForEachRo( p, pObj, i ) + { + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) + nCtrls++; + if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + nDatas++; + if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) + nBoth++; + } + printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth ); + } + Vec_BitFree( vCtrls ); + Vec_BitFree( vDatas ); + } + // create levelized structure + vLevels = Vec_WecStart( MaxEntry ); + Vec_IntForEachEntry( vCosts, Entry, i ) + Vec_WecPush( vLevels, Entry, i ); + // collect in this order + MaxEntry = 0; + vRes = Vec_IntStart( Gia_ManRegNum(p) ); + Vec_WecForEachLevel( vLevels, vLevel, i ) + Vec_IntForEachEntry( vLevel, Entry, k ) + Vec_IntWriteEntry( vRes, Entry, MaxEntry++ ); + //printf( "%d ", Gia_ObjRefNum(p, Gia_ManCi(p, Gia_ManPiNum(p)+Entry)) ); + //printf( "\n" ); + assert( MaxEntry == Gia_ManRegNum(p) ); + Vec_WecFree( vLevels ); + Vec_IntFree( vCosts ); + ABC_FREE( p->pRefs ); +//Vec_IntPrint( vRes ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Structural analysis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls ) +{ + int fDiscount = 0; Vec_Int_t * vRes = NULL; - Gia_Obj_t * pObj; + Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1; int MaxEntry = 0; int i, * pPerm; // create flop costs Vec_Int_t * vCosts = Vec_IntStart( Gia_ManRegNum(p) ); Gia_ManCreateRefs(p); + // discount references + if ( fDiscount ) + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); + pData0 = Gia_Regular(pData0); + pData1 = Gia_Regular(pData1); + p->pRefs[Gia_ObjId(p, pCtrl)]--; + if ( pData0 == pData1 ) + p->pRefs[Gia_ObjId(p, pData0)]--; + } Gia_ManForEachRo( p, pObj, i ) { Vec_IntWriteEntry( vCosts, i, Gia_ObjRefNum(p, pObj) ); @@ -81,10 +200,9 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pn } Gia_ManForEachRo( p, pObj, i ) if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) ) - Vec_IntAddToEntry( vCosts, i, 2*MaxEntry ); + Vec_IntAddToEntry( vCosts, i, MaxEntry ); //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) ) // Vec_IntAddToEntry( vCosts, i, MaxEntry ); - MaxEntry *= 3; // print out if ( fVerbose ) { @@ -102,7 +220,6 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pn Vec_BitFree( vCtrls ); Vec_BitFree( vDatas ); } - *pnPrioShift = 1 + Abc_Base2Log( MaxEntry ); // create ordering based on costs pPerm = Abc_MergeSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts) ); vRes = Vec_IntAllocArray( pPerm, Vec_IntSize(vCosts) ); @@ -112,10 +229,10 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls, int * pn //Vec_IntPrint( vCosts ); return vCosts; } -Vec_Int_t * Pdr_ManDeriveFlopPriorities( Aig_Man_t * pAig, int fMuxCtrls, int * pnPrioShift ) +Vec_Int_t * Pdr_ManDeriveFlopPriorities( Aig_Man_t * pAig, int fMuxCtrls ) { Gia_Man_t * pGia = Gia_ManFromAigSimple(pAig); - Vec_Int_t * vRes = Pdr_ManDeriveFlopPriorities2(pGia, fMuxCtrls, pnPrioShift); + Vec_Int_t * vRes = Pdr_ManDeriveFlopPriorities2(pGia, fMuxCtrls); Gia_ManStop( pGia ); return vRes; } @@ -145,11 +262,11 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio if ( !p->pPars->fMonoCnf ) p->vVLits = Vec_WecStart( 1+Abc_MaxInt(1, Aig_ManLevels(pAig)) ); // internal use - p->nPrioShift = 0; + p->nPrioShift = Abc_Base2Log(Aig_ManRegNum(pAig)); if ( vPrioInit ) p->vPrio = vPrioInit; else if ( pPars->fFlopPrio ) - p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 0, &p->nPrioShift); + p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 1); else p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) ); p->vLits = Vec_IntAlloc( 100 ); // array of literals -- cgit v1.2.3 From afcbb09717b9b76b6895dee66d42b9f9be0160e2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Feb 2017 10:43:07 -0800 Subject: Corner-case bug-fix in library preprocessor for standard-cell mapping. --- src/map/mio/mioUtils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c index 7572b27c..428eb92b 100644 --- a/src/map/mio/mioUtils.c +++ b/src/map/mio/mioUtils.c @@ -569,7 +569,7 @@ Mio_Cell_t * Mio_CollectRootsNew( Mio_Library_t * pLib, int nInputs, int * pnGat if ( ppCells[3].pName == NULL ) { printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; } // sort by delay - if ( iCell > 1 ) + if ( iCell > 5 ) { qsort( (void *)(ppCells + 4), iCell - 4, sizeof(Mio_Cell_t), (int (*)(const void *, const void *)) Mio_AreaCompare ); @@ -726,7 +726,7 @@ Mio_Cell2_t * Mio_CollectRootsNew2( Mio_Library_t * pLib, int nInputs, int * pnG if ( ppCells[3].pName == NULL ) { printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; } // sort by delay - if ( iCell > 1 ) + if ( iCell > 5 ) { qsort( (void *)(ppCells + 4), iCell - 4, sizeof(Mio_Cell2_t), (int (*)(const void *, const void *)) Mio_AreaCompare2 ); -- cgit v1.2.3 From 8b6de217f6476649763ba95a0acf18fcea69557a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Feb 2017 11:08:44 -0800 Subject: Compiler warnings. --- src/proof/pdr/pdrMan.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index f682e946..13e0b23c 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -53,16 +53,18 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities3( Gia_Man_t * p, int fMuxCtrls ) Gia_ManCreateRefs(p); // discount references if ( fDiscount ) - Gia_ManForEachAnd( p, pObj, i ) { - if ( !Gia_ObjIsMuxType(pObj) ) - continue; - pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); - pData0 = Gia_Regular(pData0); - pData1 = Gia_Regular(pData1); - p->pRefs[Gia_ObjId(p, pCtrl)]--; - if ( pData0 == pData1 ) - p->pRefs[Gia_ObjId(p, pData0)]--; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); + pData0 = Gia_Regular(pData0); + pData1 = Gia_Regular(pData1); + p->pRefs[Gia_ObjId(p, pCtrl)]--; + if ( pData0 == pData1 ) + p->pRefs[Gia_ObjId(p, pData0)]--; + } } // create flop costs vCosts = Vec_IntAlloc( Gia_ManRegNum(p) ); @@ -160,16 +162,18 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls ) Gia_ManCreateRefs(p); // discount references if ( fDiscount ) - Gia_ManForEachAnd( p, pObj, i ) { - if ( !Gia_ObjIsMuxType(pObj) ) - continue; - pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); - pData0 = Gia_Regular(pData0); - pData1 = Gia_Regular(pData1); - p->pRefs[Gia_ObjId(p, pCtrl)]--; - if ( pData0 == pData1 ) - p->pRefs[Gia_ObjId(p, pData0)]--; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( !Gia_ObjIsMuxType(pObj) ) + continue; + pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0)); + pData0 = Gia_Regular(pData0); + pData1 = Gia_Regular(pData1); + p->pRefs[Gia_ObjId(p, pCtrl)]--; + if ( pData0 == pData1 ) + p->pRefs[Gia_ObjId(p, pData0)]--; + } } Gia_ManForEachRo( p, pObj, i ) { -- cgit v1.2.3 From f34029dd09a3ddb5ec726ef5ae541e2342544cd9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Feb 2017 12:28:34 -0800 Subject: Improvements in AIG visualization. --- src/aig/gia/giaShow.c | 27 +++++++++++++++------------ src/base/io/ioWriteDot.c | 4 ++-- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c index 4deebd7a..3ca31d55 100644 --- a/src/aig/gia/giaShow.c +++ b/src/aig/gia/giaShow.c @@ -290,7 +290,7 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ObjFaninId0p(p, pNode) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "style = %s", "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -308,7 +308,7 @@ void Gia_ShowPath( Gia_Man_t * p, char * pFileName ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", iFan ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", "bold" ); + fprintf( pFile, "style = %s", "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -583,7 +583,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ObjFaninId0(pNode, i) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" ); // if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL0(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) ); fprintf( pFile, "]" ); @@ -595,7 +595,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ObjFaninId1(pNode, i) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "solid" ); // if ( Gia_NtkIsSeq(pNode->p) && Seq_ObjFaninL1(pNode) > 0 ) // fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) ); fprintf( pFile, "]" ); @@ -624,7 +624,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, "Node%d", pPrev->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pTemp->Id ); - fprintf( pFile, " [style = %s]", Gia_IsComplement(pTemp->pEquiv)? "dotted" : "bold" ); + fprintf( pFile, " [style = %s]", Gia_IsComplement(pTemp->pEquiv)? "dotted" : "solid" ); fprintf( pFile, ";\n" ); pPrev = pTemp; } @@ -632,7 +632,7 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, "Node%d", pPrev->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pNode->Id ); - fprintf( pFile, " [style = %s]", Gia_IsComplement(pPrev->pEquiv)? "dotted" : "bold" ); + fprintf( pFile, " [style = %s]", Gia_IsComplement(pPrev->pEquiv)? "dotted" : "solid" ); fprintf( pFile, ";\n" ); } */ @@ -920,7 +920,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -933,11 +933,13 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In for ( k = 0; k < 3; k++ ) if ( Vec_IntEntry(vAdds, 6*iBox+k) ) { + int iBox2 = Vec_IntEntry(vMapAdds, Vec_IntEntry(vAdds, 6*iBox+k)); + int fXor2 = iBox2 >= 0 ? (int)(Vec_IntEntry(vAdds, 6*iBox2+3) == Vec_IntEntry(vAdds, 6*iBox+k)) : 0; fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, iNode) ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vAdds, 6*iBox+k)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", 0? "dotted" : "bold" ); + fprintf( pFile, "style = %s", fXor2? "bold" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -949,11 +951,12 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In for ( k = 1; k < 4; k++ ) if ( Vec_IntEntry(vXors, 4*iXor+k) ) { + int iXor2 = Vec_IntEntry(vMapXors, Vec_IntEntry(vXors, 4*iXor+k)); fprintf( pFile, "Node%d", iNode ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Vec_IntEntry(vXors, 4*iXor+k)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", 0? "dotted" : "bold" ); + fprintf( pFile, "style = %s", iXor2 >= 0? "bold" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -964,7 +967,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId0(pNode, iNode)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC0(pNode)? "dotted" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); if ( !Gia_ObjIsAnd(pNode) ) @@ -974,7 +977,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId1(pNode, iNode)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC1(pNode)? "dotted" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -985,7 +988,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", Gia_ShowAddOut(vAdds, vMapAdds, Gia_ObjFaninId2(p, iNode)) ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Gia_ObjFaninC2(p, pNode)? "dotted" : "solid" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c index 3431c761..d9687c6e 100644 --- a/src/base/io/ioWriteDot.c +++ b/src/base/io/ioWriteDot.c @@ -394,7 +394,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho fprintf( pFile, "Node%d", pNode->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pFanin->Id ); - fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" ); + fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" ); // fprintf( pFile, ", label = \"%c\"", 'a' + k ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -764,7 +764,7 @@ void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho fprintf( pFile, "Node%d", pNode->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pFanin->Id ); - fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" ); + fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" ); // fprintf( pFile, ", label = \"%c\"", 'a' + k ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); -- cgit v1.2.3 From 89e8e50069b62afa021bfd16b340d56cd5b4c113 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 00:21:28 -0800 Subject: Improving new X-valued simulation in 'pdr'. --- src/proof/pdr/pdrInv.c | 8 +-- src/proof/pdr/pdrMan.c | 4 +- src/proof/pdr/pdrTsim2.c | 177 ++++++++++++++++++++++++++++++++++++++++++++--- src/sat/bmc/bmcCexCare.c | 31 +++++++-- 4 files changed, 203 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 16d98a36..8130d0a3 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -467,10 +467,10 @@ void Pdr_ManReportInvariant( Pdr_Man_t * p ) Vec_Ptr_t * vCubes; int kStart = Pdr_ManFindInvariantStart( p ); vCubes = Pdr_ManCollectCubes( p, kStart ); -// Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (%.2f)\n", -// kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), 1.0*p->nXsimLits/p->nXsimRuns ); - Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n", - kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) ); + Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (%.2f)\n", + kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), 1.0*p->nXsimLits/p->nXsimRuns ); +// Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n", +// kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) ); Vec_PtrFree( vCubes ); } diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index 13e0b23c..f9a14a07 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -271,7 +271,9 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vPrio = vPrioInit; else if ( pPars->fFlopPrio ) p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 1); - else + else if ( p->pPars->fNewXSim ) + p->vPrio = Vec_IntStartNatural( Aig_ManRegNum(pAig) ); + else p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) ); p->vLits = Vec_IntAlloc( 100 ); // array of literals p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves diff --git a/src/proof/pdr/pdrTsim2.c b/src/proof/pdr/pdrTsim2.c index 82e9a56c..8a86eecc 100644 --- a/src/proof/pdr/pdrTsim2.c +++ b/src/proof/pdr/pdrTsim2.c @@ -36,6 +36,7 @@ struct Txs_Man_t_ Vec_Int_t * vCiVals; // cone leaf values (0/1 CI values) Vec_Int_t * vCoVals; // cone root values (0/1 CO values) Vec_Int_t * vNodes; // cone nodes (node obj IDs) + Vec_Int_t * vTemp; // cone nodes (node obj IDs) Vec_Int_t * vPiLits; // resulting array of PI literals Vec_Int_t * vFfLits; // resulting array of flop literals Pdr_Man_t * pMan; // calling manager @@ -72,6 +73,7 @@ Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio p->vCiVals = Vec_IntAlloc( 100 ); // cone leaf values (0/1 CI values) p->vCoVals = Vec_IntAlloc( 100 ); // cone root values (0/1 CO values) p->vNodes = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs) + p->vTemp = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs) p->vPiLits = Vec_IntAlloc( 100 ); // resulting array of PI literals p->vFfLits = Vec_IntAlloc( 100 ); // resulting array of flop literals p->pMan = pMan; // calling manager @@ -85,6 +87,7 @@ void Txs_ManStop( Txs_Man_t * p ) Vec_IntFree( p->vCiVals ); Vec_IntFree( p->vCoVals ); Vec_IntFree( p->vNodes ); + Vec_IntFree( p->vTemp ); Vec_IntFree( p->vPiLits ); Vec_IntFree( p->vFfLits ); ABC_FREE( p ); @@ -143,7 +146,8 @@ void Txs_ManForwardPass( Gia_Man_t * p, Vec_Int_t * vPrio, Vec_Int_t * vCiObjs, Vec_Int_t * vCiVals, Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals ) { - Gia_Obj_t * pObj, * pFan0, * pFan1; int i; + Gia_Obj_t * pObj, * pFan0, * pFan1; + int i, value0, value1; pObj = Gia_ManConst0(p); pObj->fMark0 = 0; pObj->fMark1 = 0; @@ -158,15 +162,17 @@ void Txs_ManForwardPass( Gia_Man_t * p, { pFan0 = Gia_ObjFanin0(pObj); pFan1 = Gia_ObjFanin1(pObj); - pObj->fMark0 = (pFan0->fMark0 ^ Gia_ObjFaninC0(pObj)) & (pFan1->fMark0 ^ Gia_ObjFaninC1(pObj)); + value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + pObj->fMark0 = value0 && value1; pObj->fMark1 = 0; if ( pObj->fMark0 ) pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value ); - else if ( pFan0->fMark0 ) + else if ( value0 ) pObj->Value = pFan1->Value; - else if ( pFan1->fMark0 ) + else if ( value1 ) pObj->Value = pFan0->Value; - else // if ( pFan0->fMark0 == 0 && pFan1->fMark0 == 0 ) + else // if ( value0 == 0 && value1 == 0 ) pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value ); assert( ~pObj->Value ); } @@ -202,9 +208,9 @@ static inline int Txs_ObjIsJust( Gia_Man_t * p, Gia_Obj_t * pObj ) assert( !pObj->fMark0 ); assert( !value0 || !value1 ); if ( value0 ) - return pFan1->fMark1; + return pFan1->fMark1 || Gia_ObjIsPi(p, pFan1); if ( value1 ) - return pFan0->fMark1; + return pFan0->fMark1 || Gia_ObjIsPi(p, pFan0); assert( !value0 && !value1 ); return pFan0->fMark1 || pFan1->fMark1 || Gia_ObjIsPi(p, pFan0) || Gia_ObjIsPi(p, pFan1); } @@ -215,6 +221,7 @@ void Txs_ManBackwardPass( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes { if ( !pObj->fMark1 ) continue; + pObj->fMark1 = 0; pFan0 = Gia_ObjFanin0(pObj); pFan1 = Gia_ObjFanin1(pObj); if ( pObj->fMark0 ) @@ -265,6 +272,156 @@ void Txs_ManBackwardPass( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes assert( Vec_IntSize(vFfLits) > 0 ); } +/**Function************************************************************* + + Synopsis [Collects justification path.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Txs_ManSelectJustPath( Gia_Man_t * p, Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vRes ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; + int i, value0, value1; + // mark CO drivers + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + Gia_ObjFanin0(pObj)->fMark1 = 1; + // collect just paths + Vec_IntClear( vRes ); + Gia_ManForEachObjVecReverse( vNodes, p, pObj, i ) + { + if ( !pObj->fMark1 ) + continue; + pObj->fMark1 = 0; + Vec_IntPush( vRes, Gia_ObjId(p, pObj) ); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( pObj->fMark0 ) + { + pFan0->fMark1 = 1; + pFan1->fMark1 = 1; + continue; + } + value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + assert( !value0 || !value1 ); + if ( value0 ) + pFan1->fMark1 = 1; + else if ( value1 ) + pFan0->fMark1 = 1; + else // if ( !value0 && !value1 ) + { + pFan0->fMark1 = 1; + pFan1->fMark1 = 1; + } + } + Vec_IntReverseOrder( vRes ); +} +void Txs_ManCollectJustPis( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vPiLits ) +{ + Gia_Obj_t * pObj; int i; + Vec_IntClear( vPiLits ); + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + if ( pObj->fMark1 && Gia_ObjIsPi(p, pObj) ) + Vec_IntPush( vPiLits, Abc_Var2Lit(Gia_ObjCioId(pObj), !pObj->fMark0) ); +} +void Txs_ManInitPrio( Gia_Man_t * p, Vec_Int_t * vCiObjs ) +{ + Gia_Obj_t * pObj; int i; + Gia_ManConst0(p)->Value = 0x7FFFFFFF; + Gia_ManForEachObjVec( vCiObjs, p, pObj, i ) + pObj->Value = Gia_ObjIsPi(p, pObj) ? 0x7FFFFFFF : Gia_ObjCioId(pObj) - Gia_ManPiNum(p); +} +void Txs_ManPropagatePrio( Gia_Man_t * p, Vec_Int_t * vNodes, Vec_Int_t * vPrio ) +{ + Gia_Obj_t * pObj, * pFan0, * pFan1; + int i, value0, value1; + Gia_ManForEachObjVec( vNodes, p, pObj, i ) + { + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( pObj->fMark0 ) + { +// pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value ); + if ( pFan0->Value == 0x7FFFFFFF ) + pObj->Value = pFan1->Value; + else if ( pFan1->Value == 0x7FFFFFFF ) + pObj->Value = pFan0->Value; + else if ( Vec_IntEntry(vPrio, pFan0->Value) < Vec_IntEntry(vPrio, pFan1->Value) ) + pObj->Value = pFan0->Value; + else + pObj->Value = pFan1->Value; + continue; + } + value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj); + value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj); + assert( !value0 || !value1 ); + if ( value0 ) + pObj->Value = pFan1->Value; + else if ( value1 ) + pObj->Value = pFan0->Value; + else // if ( value0 == 0 && value1 == 0 ) + { +// pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value ); + if ( pFan0->Value == 0x7FFFFFFF || pFan1->Value == 0x7FFFFFFF ) + pObj->Value = 0x7FFFFFFF; + else if ( Vec_IntEntry(vPrio, pFan0->Value) >= Vec_IntEntry(vPrio, pFan1->Value) ) + pObj->Value = pFan0->Value; + else + pObj->Value = pFan1->Value; + } + assert( ~pObj->Value ); + } +} +int Txs_ManFindMinId( Gia_Man_t * p, Vec_Int_t * vCoObjs, Vec_Int_t * vPrio ) +{ + Gia_Obj_t * pObj; int i, iMinId = -1; + Gia_ManForEachObjVec( vCoObjs, p, pObj, i ) + if ( Gia_ObjFanin0(pObj)->Value != 0x7FFFFFFF ) + { + if ( iMinId == -1 || Vec_IntEntry(vPrio, iMinId) > Vec_IntEntry(vPrio, Gia_ObjFanin0(pObj)->Value) ) + iMinId = Gia_ObjFanin0(pObj)->Value; + } + return iMinId; +} +void Txs_ManFindCiReduction( Gia_Man_t * p, + Vec_Int_t * vPrio, Vec_Int_t * vCiObjs, + Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, + Vec_Int_t * vPiLits, Vec_Int_t * vFfLits, Vec_Int_t * vTemp ) +{ + Gia_Obj_t * pObj; + int iPrioCi; + // propagate PI influence + Txs_ManSelectJustPath( p, vNodes, vCoObjs, vTemp ); + Txs_ManCollectJustPis( p, vCiObjs, vPiLits ); +// printf( "%d -> %d ", Vec_IntSize(vNodes), Vec_IntSize(vTemp) ); + // iteratively detect and remove smallest IDs + Vec_IntClear( vFfLits ); + Txs_ManInitPrio( p, vCiObjs ); + while ( 1 ) + { + Txs_ManPropagatePrio( p, vTemp, vPrio ); + iPrioCi = Txs_ManFindMinId( p, vCoObjs, vPrio ); + if ( iPrioCi == -1 ) + break; + pObj = Gia_ManCi( p, Gia_ManPiNum(p)+iPrioCi ); + Vec_IntPush( vFfLits, Abc_Var2Lit(iPrioCi, !pObj->fMark0) ); + pObj->Value = 0x7FFFFFFF; + } +} +void Txs_ManPrintFlopLits( Vec_Int_t * vFfLits, Vec_Int_t * vPrio ) +{ + int i, Entry; + printf( "%3d : ", Vec_IntSize(vFfLits) ); + Vec_IntForEachEntry( vFfLits, Entry, i ) + printf( "%s%d(%d) ", Abc_LitIsCompl(Entry)? "+":"-", Abc_Lit2Var(Entry), Vec_IntEntry(vPrio, Abc_Lit2Var(Entry)) ); + printf( "\n" ); +} + /**Function************************************************************* Synopsis [Verify the result.] @@ -332,6 +489,7 @@ void Txs_ManVerify( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_ ***********************************************************************/ Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube ) { + int fTryNew = 1; Pdr_Set_t * pRes; Gia_Obj_t * pObj; // collect CO objects @@ -370,7 +528,10 @@ Abc_Print( 1, " in frame %d.\n", k ); // perform two passes Txs_ManForwardPass( p->pGia, p->vPrio, p->vCiObjs, p->vCiVals, p->vNodes, p->vCoObjs, p->vCoVals ); - Txs_ManBackwardPass( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits ); + if ( fTryNew ) + Txs_ManFindCiReduction( p->pGia, p->vPrio, p->vCiObjs, p->vNodes, p->vCoObjs, p->vPiLits, p->vFfLits, p->vTemp ); + else + Txs_ManBackwardPass( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits ); Txs_ManVerify( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits, p->vCoObjs, p->vCoVals ); // derive the final set diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c index 21fea429..a6613891 100644 --- a/src/sat/bmc/bmcCexCare.c +++ b/src/sat/bmc/bmcCexCare.c @@ -158,7 +158,7 @@ void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_In SeeAlso [] ***********************************************************************/ -void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex_t * pCexMin ) +void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGrow, Abc_Cex_t * pCexMin ) { Gia_Obj_t * pObj; int i, Phase0, Phase1; @@ -184,10 +184,33 @@ void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex Gia_ObjFanin0(pObj)->fPhase = 1; else // if ( !Phase0 && !Phase1 ) { - if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) <= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) + if ( Gia_ObjFanin0(pObj)->fPhase || Gia_ObjFanin1(pObj)->fPhase ) + continue; + if ( Gia_ObjIsPi(p, Gia_ObjFanin0(pObj)) ) Gia_ObjFanin0(pObj)->fPhase = 1; - else + else if ( Gia_ObjIsPi(p, Gia_ObjFanin1(pObj)) ) Gia_ObjFanin1(pObj)->fPhase = 1; +// else if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Txs_ObjIsJust(p, Gia_ObjFanin0(pObj)) ) +// Gia_ObjFanin0(pObj)->fPhase = 1; +// else if ( Gia_ObjIsAnd(Gia_ObjFanin1(pObj)) && Txs_ObjIsJust(p, Gia_ObjFanin1(pObj)) ) +// Gia_ObjFanin1(pObj)->fPhase = 1; + else + { + if ( fGrow & 1 ) + { + if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) >= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) + Gia_ObjFanin0(pObj)->fPhase = 1; + else + Gia_ObjFanin1(pObj)->fPhase = 1; + } + else + { + if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) <= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) + Gia_ObjFanin0(pObj)->fPhase = 1; + else + Gia_ObjFanin1(pObj)->fPhase = 1; + } + } } } Gia_ManForEachPi( p, pObj, i ) @@ -210,7 +233,7 @@ Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t Gia_ManForEachRo( p, pObj, i ) pObj->Value = Vec_IntEntry( vPrios, f * pCex->nRegs + i ); Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow ); - Bmc_CexCarePropagateBwdOne( p, pCex, f, pCexMin ); + Bmc_CexCarePropagateBwdOne( p, pCex, f, fGrow, pCexMin ); Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) pObjRi->fPhase = pObjRo->fPhase; } -- cgit v1.2.3 From aed9a87282bcb7937fd74e078d30ed74786abc75 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 00:54:18 -0800 Subject: Adding specialized flop ordering before generalization in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 319525cf..008adbae 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuysipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26129,6 +26129,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'y': pPars->fFlopPrio ^= 1; break; + case 'f': + pPars->fFlopOrder ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26197,7 +26200,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuysipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26216,6 +26219,7 @@ usage: Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 18b059c6..66990bfb 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -54,6 +54,7 @@ struct Pdr_Par_t_ int fMonoCnf; // monolythic CNF int fNewXSim; // updated X-valued simulation int fFlopPrio; // use structural flop priorities + int fFlopOrder; // order flops for 'analyze_final' during generalization int fDumpInv; // dump inductive invariant int fUseSupp; // use support in the invariant int fShortest; // forces bug traces to be shortest diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index cfc79d85..74a15e40 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -63,8 +63,9 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->fSkipDown = 1; // apply down in generalization pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF - pPars->fFlopPrio = 0; // use structural flop priorities pPars->fNewXSim = 0; // updated X-valued simulation + pPars->fFlopPrio = 0; // use structural flop priorities + pPars->fFlopOrder = 0; // order flops for 'analyze_final' during generalization pPars->fDumpInv = 0; // dump inductive invariant pPars->fUseSupp = 1; // using support variables in the invariant pPars->fShortest = 0; // forces bug traces to be shortest @@ -479,6 +480,31 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, } return 1; } + +/**Function************************************************************* + + Synopsis [Specialized sorting of flops based on cost.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_IntSelectSortCostReverseLit( int * pArray, int nSize, Vec_Int_t * vCosts ) +{ + int i, j, best_i; + for ( i = 0; i < nSize-1; i++ ) + { + best_i = i; + for ( j = i+1; j < nSize; j++ ) + if ( Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[j])) > Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[best_i])) ) + best_i = j; + ABC_SWAP( int, pArray[i], pArray[best_i] ); + } +} + /**Function************************************************************* Synopsis [Returns 1 if the state could be blocked.] @@ -500,7 +526,11 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP Hash_Int_t * keep = NULL; // if there is no induction, return *ppCubeMin = NULL; + if ( p->pPars->fFlopOrder ) + Vec_IntSelectSortCostReverseLit( pCube->Lits, pCube->nLits, p->vPrio ); RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0 ); + if ( p->pPars->fFlopOrder ) + Vec_IntSelectSort( pCube->Lits, pCube->nLits ); if ( RetValue == -1 ) return -1; if ( RetValue == 0 ) -- cgit v1.2.3 From cac3967b52ae44fae3962ee9eba456221e0efda3 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 6 Feb 2017 11:34:52 -0800 Subject: =?UTF-8?q?Adding=20a=20new=20SAT=20solver=20to=20ABC.=20(Satoko)?= =?UTF-8?q?=20The=20command=20is=20=E2=80=98satoko=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/abci/abc.c | 82 ++++- src/sat/satoko/LICENSE | 22 ++ src/sat/satoko/act_clause.h | 80 ++++ src/sat/satoko/act_var.h | 84 +++++ src/sat/satoko/cdb.h | 100 +++++ src/sat/satoko/clause.h | 63 ++++ src/sat/satoko/cnf_reader.c | 156 ++++++++ src/sat/satoko/module.make | 3 + src/sat/satoko/satoko.h | 85 +++++ src/sat/satoko/solver.c | 704 ++++++++++++++++++++++++++++++++++++ src/sat/satoko/solver.h | 242 +++++++++++++ src/sat/satoko/solver_api.c | 310 ++++++++++++++++ src/sat/satoko/types.h | 50 +++ src/sat/satoko/utils/b_queue.h | 81 +++++ src/sat/satoko/utils/heap.h | 181 +++++++++ src/sat/satoko/utils/mem.h | 23 ++ src/sat/satoko/utils/misc.h | 37 ++ src/sat/satoko/utils/sort.h | 65 ++++ src/sat/satoko/utils/vec/vec_char.h | 259 +++++++++++++ src/sat/satoko/utils/vec/vec_dble.h | 246 +++++++++++++ src/sat/satoko/utils/vec/vec_int.h | 240 ++++++++++++ src/sat/satoko/utils/vec/vec_uint.h | 268 ++++++++++++++ src/sat/satoko/watch_list.h | 152 ++++++++ 23 files changed, 3532 insertions(+), 1 deletion(-) create mode 100644 src/sat/satoko/LICENSE create mode 100644 src/sat/satoko/act_clause.h create mode 100644 src/sat/satoko/act_var.h create mode 100644 src/sat/satoko/cdb.h create mode 100644 src/sat/satoko/clause.h create mode 100644 src/sat/satoko/cnf_reader.c create mode 100644 src/sat/satoko/module.make create mode 100644 src/sat/satoko/satoko.h create mode 100644 src/sat/satoko/solver.c create mode 100644 src/sat/satoko/solver.h create mode 100644 src/sat/satoko/solver_api.c create mode 100644 src/sat/satoko/types.h create mode 100644 src/sat/satoko/utils/b_queue.h create mode 100644 src/sat/satoko/utils/heap.h create mode 100755 src/sat/satoko/utils/mem.h create mode 100755 src/sat/satoko/utils/misc.h create mode 100644 src/sat/satoko/utils/sort.h create mode 100644 src/sat/satoko/utils/vec/vec_char.h create mode 100755 src/sat/satoko/utils/vec/vec_dble.h create mode 100755 src/sat/satoko/utils/vec/vec_int.h create mode 100755 src/sat/satoko/utils/vec/vec_uint.h create mode 100644 src/sat/satoko/watch_list.h (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 008adbae..efb82fcc 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43,6 +43,7 @@ #include "map/amap/amap.h" #include "opt/ret/retInt.h" #include "sat/xsat/xsat.h" +#include "sat/satoko/satoko.h" #include "sat/cnf/cnf.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" @@ -308,6 +309,7 @@ static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -956,6 +958,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -23302,6 +23305,83 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + abctime clk; + int c; + satoko_opts_t opts; + + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Chv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + goto usage; + break; + case 'h': + goto usage; + case 'v': + opts.verbose ^= 1; + break; + + default: + goto usage; + } + } + + if ( argc == globalUtilOptind + 1 ) + { + char * pFileName = argv[globalUtilOptind]; + satoko_t * p; + int status; + + satoko_parse_dimacs( pFileName, &p ); + satoko_configure(p, &opts); + + clk = Abc_Clock(); + status = satoko_solve( p ); + + if ( status == SATOKO_UNDEC ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == SATOKO_SAT ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + satoko_destroy( p ); + return 0; + } + +usage: + Abc_Print( -2, "usage: satoko [-CILDE num] [-hv].cnf\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} /**Function************************************************************* Synopsis [] @@ -26238,7 +26318,7 @@ usage: Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); - + return 1; } diff --git a/src/sat/satoko/LICENSE b/src/sat/satoko/LICENSE new file mode 100644 index 00000000..51938137 --- /dev/null +++ b/src/sat/satoko/LICENSE @@ -0,0 +1,22 @@ +Copyright 2017, Bruno Schmitt - UC Berkeley / UFRGS (bruno@oschmitt.com) + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h new file mode 100644 index 00000000..5a2fda2b --- /dev/null +++ b/src/sat/satoko/act_clause.h @@ -0,0 +1,80 @@ +//===--- act_var.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__act_clause_h +#define satoko__act_clause_h + +#include "solver.h" +#include "types.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#ifdef SATOKO_ACT_CLAUSE_FLOAT + +/** Re-scale the activity value for all clauses. + */ +static inline void clause_act_rescale(solver_t *s) +{ + unsigned i, cref; + struct clause *clause; + + vec_uint_foreach(s->learnts, cref, i) { + clause = clause_read(s, cref); + clause->data[clause->size].act *= 1e-20; + } + s->clause_act_inc *= 1e-20; +} + +/** Increment the activity value of one clause ('clause') + */ +static inline void clause_act_bump(solver_t *s, struct clause *clause) +{ + clause->data[clause->size].act += s->clause_act_inc; + if (clause->data[clause->size].act > 1e20) + clause_act_rescale(s); +} + +/** Increment the value by which clauses activity values are incremented + */ +static inline void clause_act_decay(solver_t *s) +{ + s->clause_act_inc *= (1 / s->opts.clause_decay); +} + +#else /* SATOKO_ACT_CLAUSE_FLOAT */ + +static inline void clause_act_rescale(solver_t *s) +{ + unsigned i, cref; + struct clause *clause; + + vec_uint_foreach(s->learnts, cref, i) { + clause = clause_read(s, cref); + clause->data[clause->size].act >>= 14; + } + s->clause_act_inc >>= 14; + s->clause_act_inc = mkt_uint_max(s->clause_act_inc, (1 << 10)); +} + +static inline void clause_act_bump(solver_t *s, struct clause *clause) +{ + clause->data[clause->size].act += s->clause_act_inc; + if (clause->data[clause->size].act & 0x80000000) + clause_act_rescale(s); +} + +static inline void clause_act_decay(solver_t *s) +{ + s->clause_act_inc += (s->clause_act_inc >> 10); +} + +#endif /* SATOKO_ACT_CLAUSE_FLOAT */ + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__act_clause_h */ diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h new file mode 100644 index 00000000..161e9d9a --- /dev/null +++ b/src/sat/satoko/act_var.h @@ -0,0 +1,84 @@ +//===--- act_var.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__act_var_h +#define satoko__act_var_h + +#include "solver.h" +#include "types.h" +#include "utils/heap.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#ifdef SATOKO_ACT_VAR_DBLE +/** Re-scale the activity value for all variables. + */ +static inline void var_act_rescale(solver_t *s) +{ + unsigned i; + double *activity = vec_dble_data(s->activity); + + for (i = 0; i < vec_dble_size(s->activity); i++) + activity[i] *= 1e-100; + s->var_act_inc *= 1e-100; +} + +/** Increment the activity value of one variable ('var') + */ +static inline void var_act_bump(solver_t *s, unsigned var) +{ + double *activity = vec_dble_data(s->activity); + + activity[var] += s->var_act_inc; + if (activity[var] > 1e100) + var_act_rescale(s); + if (heap_in_heap(s->var_order, var)) + heap_decrease(s->var_order, var); +} + +/** Increment the value by which variables activity values are incremented + */ +static inline void var_act_decay(solver_t *s) +{ + s->var_act_inc *= (1 / s->opts.var_decay); +} + +#else /* SATOKO_ACT_VAR_DBLE */ + +static inline void var_act_rescale(solver_t *s) +{ + unsigned i; + unsigned *activity = vec_uint_data(s->activity); + + for (i = 0; i < vec_uint_size(s->activity); i++) + activity[i] >>= 19; + s->var_act_inc >>= 19; + s->var_act_inc = mkt_uint_max(s->var_act_inc, (1 << 5)); +} + +static inline void var_act_bump(solver_t *s, unsigned var) +{ + unsigned *activity = vec_uint_data(s->activity); + + activity[var] += s->var_act_inc; + if (activity[var] & 0x80000000) + var_act_rescale(s); + if (heap_in_heap(s->var_order, var)) + heap_decrease(s->var_order, var); +} + +static inline void var_act_decay(solver_t *s) +{ + s->var_act_inc += (s->var_act_inc >> 4); +} + +#endif /* SATOKO_ACT_VAR_DBLE */ + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__act_var_h */ diff --git a/src/sat/satoko/cdb.h b/src/sat/satoko/cdb.h new file mode 100644 index 00000000..28686ff2 --- /dev/null +++ b/src/sat/satoko/cdb.h @@ -0,0 +1,100 @@ +//===--- cdb.h --------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__cdb_h +#define satoko__cdb_h + +#include "clause.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +/* Clauses DB data structure */ +struct cdb { + unsigned size; + unsigned cap; + unsigned wasted; + unsigned *data; +}; + +//===------------------------------------------------------------------------=== +// Clause DB API +//===------------------------------------------------------------------------=== +static inline struct clause *cdb_handler(struct cdb *p, unsigned cref) +{ + return cref != 0xFFFFFFFF ? (struct clause *)(p->data + cref) : NULL; +} + +static inline unsigned cdb_cref(struct cdb *p, unsigned *clause) +{ + return (unsigned)(clause - &(p->data[0])); +} + +static inline void cdb_grow(struct cdb *p, unsigned cap) +{ + unsigned prev_cap = p->cap; + + if (p->cap >= cap) + return; + while (p->cap < cap) { + unsigned delta = ((p->cap >> 1) + (p->cap >> 3) + 2) & (unsigned)(~1); + p->cap += delta; + assert(p->cap >= prev_cap); + } + assert(p->cap > 0); + p->data = satoko_realloc(unsigned, p->data, p->cap); +} + +static inline struct cdb *cdb_alloc(unsigned cap) +{ + struct cdb *p = satoko_calloc(struct cdb, 1); + if (cap <= 0) + cap = 1024 * 1024; + cdb_grow(p, cap); + return p; +} + +static inline void cdb_free(struct cdb *p) +{ + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned cdb_append(struct cdb *p, unsigned size) +{ + unsigned prev_size; + assert(size > 0); + cdb_grow(p, p->size + size); + prev_size = p->size; + p->size += size; + assert(p->size > prev_size); + return prev_size; +} + +static inline void cdb_remove(struct cdb *p, struct clause *clause) +{ + p->wasted += clause->size; +} + +static inline unsigned cdb_capacity(struct cdb *p) +{ + return p->cap; +} + +static inline unsigned cdb_size(struct cdb *p) +{ + return p->size; +} + +static inline unsigned cdb_wasted(struct cdb *p) +{ + return p->wasted; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__cdb_h */ diff --git a/src/sat/satoko/clause.h b/src/sat/satoko/clause.h new file mode 100644 index 00000000..2be18cd6 --- /dev/null +++ b/src/sat/satoko/clause.h @@ -0,0 +1,63 @@ +//===--- clause.h -----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__clause_h +#define satoko__clause_h + +#include "types.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +struct clause { + unsigned f_learnt : 1; + unsigned f_mark : 1; + unsigned f_reallocd : 1; + unsigned f_deletable : 1; + unsigned lbd : 28; + unsigned size; + union { + unsigned lit; + clause_act_t act; + } data[0]; +}; + +//===------------------------------------------------------------------------=== +// Clause API +//===------------------------------------------------------------------------=== +static inline int clause_compare(const void *p1, const void *p2) +{ + const struct clause *c1 = (const struct clause *)p1; + const struct clause *c2 = (const struct clause *)p2; + + if (c1->size > 2 && c2->size == 2) + return 1; + if (c1->size == 2 && c2->size > 2) + return 0; + if (c1->size == 2 && c2->size == 2) + return 0; + + if (c1->lbd > c2->lbd) + return 1; + if (c1->lbd < c2->lbd) + return 0; + + return c1->data[c1->size].act < c2->data[c2->size].act; +} + +static inline void clause_print(struct clause *clause) +{ + unsigned i; + printf("{ "); + for (i = 0; i < clause->size; i++) + printf("%u ", clause->data[i].lit); + printf("}\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__clause_h */ diff --git a/src/sat/satoko/cnf_reader.c b/src/sat/satoko/cnf_reader.c new file mode 100644 index 00000000..5e4b92f9 --- /dev/null +++ b/src/sat/satoko/cnf_reader.c @@ -0,0 +1,156 @@ +//===--- cnf_reader.h -------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#include +#include +#include +#include +#include + +#include "satoko.h" +#include "solver.h" +#include "utils/mem.h" +#include "utils/vec/vec_uint.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_IMPL_START + +/** Read the file into an internal buffer. + * + * This function will receive a file name. The return data is a string ended + * with '\0'. + * + */ +static char * file_open(const char *fname) +{ + FILE *file = fopen(fname, "rb"); + char *buffer; + int sz_file; + int ret; + + if (file == NULL) { + printf("Couldn't open file: %s\n", fname); + return NULL; + } + fseek(file, 0, SEEK_END); + sz_file = ftell(file); + rewind(file); + buffer = satoko_alloc(char, sz_file + 3); + ret = fread(buffer, sz_file, 1, file); + buffer[sz_file + 0] = '\n'; + buffer[sz_file + 1] = '\0'; + return buffer; +} + +static void skip_spaces(char **pos) +{ + assert(pos != NULL); + for (; isspace(**pos); (*pos)++); +} + +static void skip_line(char **pos) +{ + assert(pos != NULL); + for(; **pos != '\n' && **pos != '\r' && **pos != EOF; (*pos)++); + if (**pos != EOF) + (*pos)++; + return; +} + +static int read_int(char **token) +{ + int value = 0; + int neg = 0; + + skip_spaces(token); + if (**token == '-') { + neg = 1; + (*token)++; + } else if (**token == '+') + (*token)++; + + if (!isdigit(**token)) { + printf("Parsing error. Unexpected char: %c.\n", **token); + exit(EXIT_FAILURE); + } + while (isdigit(**token)) { + value = (value * 10) + (**token - '0'); + (*token)++; + } + return neg ? -value : value; +} + +static void read_clause(char **token, vec_uint_t *lits) +{ + int var; + unsigned sign; + + vec_uint_clear(lits); + while (1) { + var = read_int(token); + if (var == 0) + break; + sign = (var > 0); + var = abs(var) - 1; + vec_uint_push_back(lits, var2lit((unsigned) var, !sign)); + } +} + +/** Start the solver and reads the DIMAC file. + * + * Returns false upon immediate conflict. + */ +int satoko_parse_dimacs(char *fname, satoko_t **solver) +{ + satoko_t *p = NULL; + vec_uint_t *lits = NULL; + int n_var; + int n_clause; + char *buffer = file_open(fname); + char *token; + + if (buffer == NULL) + return -1; + + token = buffer; + while (1) { + skip_spaces(&token); + if (*token == 0) + break; + else if (*token == 'c') + skip_line(&token); + else if (*token == 'p') { + token++; + skip_spaces(&token); + for(; !isspace(*token); token++); /* skip 'cnf' */ + + n_var = read_int(&token); + n_clause = read_int(&token); + skip_line(&token); + lits = vec_uint_alloc((unsigned) n_var); + p = satoko_create(); + } else { + if (lits == NULL) { + printf("There is no parameter line.\n"); + satoko_free(buffer); + return -1; + } + read_clause(&token, lits); + if (!satoko_add_clause(p, vec_uint_data(lits), vec_uint_size(lits))) { + vec_uint_print(lits); + return 0; + } + } + } + vec_uint_free(lits); + satoko_free(buffer); + *solver = p; + return satoko_simplify(p); +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/satoko/module.make b/src/sat/satoko/module.make new file mode 100644 index 00000000..512094ee --- /dev/null +++ b/src/sat/satoko/module.make @@ -0,0 +1,3 @@ +SRC += src/sat/satoko/solver.c \ + src/sat/satoko/solver_api.c \ + src/sat/satoko/cnf_reader.c diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h new file mode 100644 index 00000000..49c7837e --- /dev/null +++ b/src/sat/satoko/satoko.h @@ -0,0 +1,85 @@ +//===--- satoko.h -----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__satoko_h +#define satoko__satoko_h + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +/** Return valeus */ +enum { + SATOKO_ERR = 0, + SATOKO_OK = 1 +}; + +enum { + SATOKO_UNDEC = 0, /* Undecided */ + SATOKO_SAT = 1, + SATOKO_UNSAT = -1 +}; + +struct solver_t_; +typedef struct solver_t_ satoko_t; + +typedef struct satoko_opts satoko_opts_t; +struct satoko_opts { + /* Limits */ + long long conf_limit; /* Limit on the n.of conflicts */ + long long prop_limit; /* Limit on the n.of implications */ + + /* Constants used for restart heuristic */ + double f_rst; /* Used to force a restart */ + double b_rst; /* Used to block a restart */ + unsigned fst_block_rst; /* Lower bound n.of conflicts for start blocking restarts */ + unsigned sz_lbd_bqueue; /* Size of the moving avarege queue for LBD (force restart) */ + unsigned sz_trail_bqueue; /* Size of the moving avarege queue for Trail size (block restart) */ + + /* Constants used for clause database reduction heuristic */ + unsigned n_conf_fst_reduce; /* N.of conflicts before first reduction */ + unsigned inc_reduce; /* Increment to reduce */ + unsigned inc_special_reduce; /* Special increment to reduce */ + unsigned lbd_freeze_clause; + + /* VSIDS heuristic */ + float clause_decay; + double var_decay; + + /* Binary resolution */ + unsigned clause_max_sz_bin_resol; + unsigned clause_min_lbd_bin_resol; + float garbage_max_ratio; + char verbose; +}; + +//===------------------------------------------------------------------------=== +extern satoko_t *satoko_create(void); +extern void satoko_destroy(satoko_t *); +extern void satoko_default_opts(satoko_opts_t *); +extern void satoko_configure(satoko_t *, satoko_opts_t *); +extern int satoko_parse_dimacs(char *, satoko_t **); +extern void satoko_add_variable(satoko_t *, char); +extern int satoko_add_clause(satoko_t *, unsigned *, unsigned); +extern void satoko_assump_push(satoko_t *s, unsigned); +extern void satoko_assump_pop(satoko_t *s); +extern int satoko_simplify(satoko_t *); +extern int satoko_solve(satoko_t *); + +/* If problem is unsatisfiable under assumptions, this function is used to + * obtain the final conflict clause expressed in the assumptions. + * + * - It receives as inputs the solver and a pointer to a array where clause + * will be copied. The memory is allocated by the solver, but must be freed by + * the caller. + * - The return value is either the size of the array or -1 in case the final + * conflict cluase was not generated. + */ +extern int satoko_final_conflict(satoko_t *, unsigned *); + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__satoko_h */ diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c new file mode 100644 index 00000000..b2861bad --- /dev/null +++ b/src/sat/satoko/solver.c @@ -0,0 +1,704 @@ +//===--- solver.c -----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#include +#include +#include +#include + +#include "act_clause.h" +#include "act_var.h" +#include "solver.h" +#include "utils/heap.h" +#include "utils/mem.h" +#include "utils/sort.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_IMPL_START + +//===------------------------------------------------------------------------=== +// Lit funtions +//===------------------------------------------------------------------------=== +/** + * A literal is said to be redundant in a given clause if and only if all + * variables in its reason are either present in that clause or (recursevely) + * redundant. + */ +static inline int lit_is_removable(solver_t* s, unsigned lit, unsigned min_level) +{ + unsigned top = vec_uint_size(s->tagged); + + assert(lit_reason(s, lit) != UNDEF); + vec_uint_clear(s->stack); + vec_uint_push_back(s->stack, lit2var(lit)); + while (vec_uint_size(s->stack)) { + unsigned i; + unsigned var = vec_uint_pop_back(s->stack); + struct clause *c = clause_read(s, var_reason(s, var)); + unsigned *lits = &(c->data[0].lit); + + assert(var_reason(s, var) != UNDEF); + if (c->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) { + assert(lit_value(s, lits[1]) == LIT_TRUE); + mkt_swap(unsigned, lits[0], lits[1]); + } + + /* Check scan the literals of the reason clause. + * The first literal is skiped because is the literal itself. */ + for (i = 1; i < c->size; i++) { + var = lit2var(lits[i]); + + /* Check if the variable has already been seen or if it + * was assinged a value at the decision level 0. In a + * positive case, there is no need to look any further */ + if (vec_char_at(s->seen, var) || var_dlevel(s, var) == 0) + continue; + + /* If the variable has a reason clause and if it was + * assingned at a 'possible' level, then we need to + * check if it is recursively redundant, otherwise the + * literal being checked is not redundant */ + if (var_reason(s, var) != UNDEF && ((1 << (var_dlevel(s, var) & 31)) & min_level)) { + vec_uint_push_back(s->stack, var); + vec_uint_push_back(s->tagged, var); + vec_char_assign(s->seen, var, 1); + } else { + vec_uint_foreach_start(s->tagged, var, i, top) + vec_char_assign(s->seen, var, 0); + vec_uint_shrink(s->tagged, top); + return 0; + } + } + } + return 1; +} + +//===------------------------------------------------------------------------=== +// Clause functions +//===------------------------------------------------------------------------=== +/* Calculate clause LBD (Literal Block Distance): + * - It's the number of variables in the final conflict clause that come from + * different decision levels + */ +static inline unsigned clause_clac_lbd(solver_t *s, unsigned *lits, unsigned size) +{ + unsigned i; + unsigned lbd = 0; + + s->cur_stamp++; + for (i = 0; i < size; i++) { + unsigned level = lit_dlevel(s, lits[i]); + if (vec_uint_at(s->stamps, level) != s->cur_stamp) { + vec_uint_assign(s->stamps, level, s->cur_stamp); + lbd++; + } + } + return lbd; +} + +static inline void clause_bin_resolution(solver_t *s, vec_uint_t *clause_lits) +{ + unsigned *lits = vec_uint_data(clause_lits); + unsigned counter, sz, i; + unsigned lit; + unsigned neg_lit = lit_neg(lits[0]); + struct watcher *w; + + s->cur_stamp++; + vec_uint_foreach(clause_lits, lit, i) + vec_uint_assign(s->stamps, lit2var(lit), s->cur_stamp); + + counter = 0; + watch_list_foreach(s->bin_watches, w, neg_lit) { + unsigned imp_lit = w->blocker; + if (vec_uint_at(s->stamps, lit2var(imp_lit)) == s->cur_stamp && + lit_value(s, imp_lit) == LIT_TRUE) { + counter++; + vec_uint_assign(s->stamps, lit2var(imp_lit), (s->cur_stamp - 1)); + } + } + if (counter > 0) { + sz = vec_uint_size(clause_lits) - 1; + for (i = 1; i < vec_uint_size(clause_lits) - counter; i++) + if (vec_uint_at(s->stamps, lit2var(lits[i])) != s->cur_stamp) { + mkt_swap(unsigned, lits[i], lits[sz]); + i--; + sz--; + } + vec_uint_shrink(clause_lits, vec_uint_size(clause_lits) - counter); + } +} + +static inline void clause_minimize(solver_t *s, vec_uint_t *clause_lits) +{ + unsigned i, j; + unsigned *lits = vec_uint_data(clause_lits); + unsigned min_level = 0; + unsigned clause_size; + + for (i = 1; i < vec_uint_size(clause_lits); i++) { + unsigned level = lit_dlevel(s, lits[i]); + min_level |= 1 << (level & 31); + } + + /* Remove reduntant literals */ + vec_uint_foreach(clause_lits, i, j) + vec_uint_push_back(s->tagged, lit2var(i)); + for (i = j = 1; i < vec_uint_size(clause_lits); i++) + if (lit_reason(s, lits[i]) == UNDEF || !lit_is_removable(s, lits[i], min_level)) + lits[j++] = lits[i]; + vec_uint_shrink(clause_lits, j); + + /* Binary Resolution */ + clause_size = vec_uint_size(clause_lits); + if (clause_size <= s->opts.clause_max_sz_bin_resol && + clause_clac_lbd(s, lits, clause_size) <= s->opts.clause_min_lbd_bin_resol) + clause_bin_resolution(s, clause_lits); +} + +static inline void clause_realloc(struct cdb *dest, struct cdb *src, unsigned *cref) +{ + unsigned new_cref; + struct clause *new_clause; + struct clause *old_clause = cdb_handler(src, *cref); + + if (old_clause->f_reallocd) { + *cref = (unsigned) old_clause->size; + return; + } + new_cref = cdb_append(dest, 3 + old_clause->f_learnt + old_clause->size); + new_clause = cdb_handler(dest, new_cref); + memcpy(new_clause, old_clause, (3 + old_clause->f_learnt + old_clause->size) * 4); + old_clause->f_reallocd = 1; + old_clause->size = (unsigned) new_cref; + *cref = new_cref; +} + +//===------------------------------------------------------------------------=== +// Solver internal functions +//===------------------------------------------------------------------------=== +static inline unsigned solver_decide(solver_t *s) +{ + unsigned next_var = UNDEF; + + while (next_var == UNDEF || var_value(s, next_var) != VAR_UNASSING) { + if (heap_size(s->var_order) == 0) { + next_var = UNDEF; + return UNDEF; + } else + next_var = heap_remove_min(s->var_order); + } + return var2lit(next_var, vec_char_at(s->polarity, next_var)); +} + +static inline void solver_new_decision(solver_t *s, unsigned lit) +{ + assert(var_value(s, lit2var(lit)) == VAR_UNASSING); + vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail)); + solver_enqueue(s, lit, UNDEF); +} + +/* Calculate Backtrack Level from the learnt clause */ +static inline unsigned solver_calc_bt_level(solver_t *s, vec_uint_t *learnt) +{ + unsigned i, tmp; + unsigned i_max = 1; + unsigned *lits = vec_uint_data(learnt); + unsigned max = lit_dlevel(s, lits[1]); + + if (vec_uint_size(learnt) == 1) + return 0; + for (i = 2; i < vec_uint_size(learnt); i++) { + if (lit_dlevel(s, lits[i]) > max) { + max = lit_dlevel(s, lits[i]); + i_max = i; + } + } + tmp = lits[1]; + lits[1] = lits[i_max]; + lits[i_max] = tmp; + return lit_dlevel(s, lits[1]); +} + +/** + * Most books and papers explain conflict analysis and the calculation of the + * 1UIP (first Unique Implication Point) using an implication graph. This + * function, however, do not explicity constructs the graph! It inspects the + * trail in reverse and figure out which literals should be added to the + * to-be-learnt clause using the reasons of each assignment. + * + * cur_lit: current literal being analyzed. + * n_paths: number of unprocessed paths from conlfict node to the current + * literal being analyzed (cur_lit). + * + * This functions performs a backward BFS (breadth-first search) for 1UIP node. + * The trail works as the BFS queue. The counter of unprocessed but seen + * variables (n_paths) allows us to identify when 'cur_lit' is the closest + * cause of conflict. + * + * When 'n_paths' reaches zero it means there are no unprocessed reverse paths + * back from the conflict node to 'cur_lit' - meaning it is the 1UIP decision + * variable. + * + */ +static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt, + unsigned *bt_level, unsigned *lbd) +{ + unsigned i; + unsigned *trail = vec_uint_data(s->trail); + unsigned idx = vec_uint_size(s->trail) - 1; + unsigned n_paths = 0; + unsigned p = UNDEF; + unsigned var; + + vec_uint_push_back(learnt, UNDEF); + do { + struct clause *clause; + unsigned *lits; + unsigned j; + + assert(cref != UNDEF); + clause = clause_read(s, cref); + lits = &(clause->data[0].lit); + + if (p != UNDEF && clause->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) { + assert(lit_value(s, lits[1]) == LIT_TRUE); + mkt_swap(unsigned, lits[0], lits[1] ); + } + + if (clause->f_learnt) + clause_act_bump(s, clause); + + if (clause->f_learnt && clause->lbd > 2) { + unsigned n_levels = clause_clac_lbd(s, lits, clause->size); + if (n_levels + 1 < clause->lbd) { + if (clause->lbd <= s->opts.lbd_freeze_clause) + clause->f_deletable = 0; + clause->lbd = n_levels; + } + } + + for (j = (p == UNDEF ? 0 : 1); j < clause->size; j++) { + var = lit2var(lits[j]); + if (vec_char_at(s->seen, var) || var_dlevel(s, var) == 0) + continue; + vec_char_assign(s->seen, var, 1); + var_act_bump(s, var); + if (var_dlevel(s, var) == solver_dlevel(s)) { + n_paths++; + if (var_reason(s, var) != UNDEF && clause_read(s, var_reason(s, var))->f_learnt) + vec_uint_push_back(s->last_dlevel, var); + } else + vec_uint_push_back(learnt, lits[j]); + } + + while (!vec_char_at(s->seen, lit2var(trail[idx--]))); + + p = trail[idx + 1]; + cref = lit_reason(s, p); + vec_char_assign(s->seen, lit2var(p), 0); + n_paths--; + } while (n_paths > 0); + + vec_uint_data(learnt)[0] = lit_neg(p); + clause_minimize(s, learnt); + *bt_level = solver_calc_bt_level(s, learnt); + *lbd = clause_clac_lbd(s, vec_uint_data(learnt), vec_uint_size(learnt)); + + if (vec_uint_size( s->last_dlevel) > 0) { + vec_uint_foreach(s->last_dlevel, var, i) { + if (clause_read(s, var_reason(s, var))->lbd < *lbd) + var_act_bump(s, var); + } + vec_uint_clear(s->last_dlevel); + } + vec_uint_foreach(s->tagged, var, i) + vec_char_assign(s->seen, var, 0); + vec_uint_clear(s->tagged); +} + +static inline int solver_rst(solver_t *s) +{ + return b_queue_is_valid(s->bq_lbd) && + (((long long)b_queue_avg(s->bq_lbd) * s->opts.f_rst) > (s->sum_lbd / s->stats.n_conflicts)); +} + +static inline int solver_block_rst(solver_t *s) +{ + return s->stats.n_conflicts > s->opts.fst_block_rst && + b_queue_is_valid(s->bq_lbd) && + (vec_uint_size(s->trail) > (s->opts.b_rst * (long long)b_queue_avg(s->bq_trail))); +} + +static inline void solver_handle_conflict(solver_t *s, unsigned confl_cref) +{ + unsigned bt_level; + unsigned lbd; + unsigned cref; + + vec_uint_clear(s->temp_lits); + solver_analyze(s, confl_cref, s->temp_lits, &bt_level, &lbd); + s->sum_lbd += lbd; + b_queue_push(s->bq_lbd, lbd); + solver_cancel_until(s, bt_level); + cref = UNDEF; + if (vec_uint_size(s->temp_lits) > 1) { + cref = solver_clause_create(s, s->temp_lits, 1); + clause_watch(s, cref); + } + solver_enqueue(s, vec_uint_at(s->temp_lits, 0), cref); + var_act_decay(s); + clause_act_decay(s); +} + +static inline void solver_analyze_final(solver_t *s, unsigned lit) +{ + unsigned i; + + vec_uint_push_back(s->final_conflict, lit); + if (solver_dlevel(s) == 0) + return; + vec_char_assign(s->seen, lit2var(lit), 1); + for (i = vec_uint_size(s->trail) - 1; i <= vec_uint_at(s->trail_lim, 0); i--) { + unsigned var = lit2var(vec_uint_at(s->trail, i)); + + if (vec_char_at(s->seen, var)) { + unsigned reason = var_reason(s, var); + if (reason == UNDEF) { + assert(var_dlevel(s, var) > 0); + vec_uint_push_back(s->final_conflict, lit_neg(vec_uint_at(s->trail, i))); + } else { + unsigned j; + struct clause *clause = clause_read(s, reason); + for (j = (clause->size == 2 ? 0 : 1); j < clause->size; j++) { + if (lit_dlevel(s, clause->data[j].lit) > 0) + vec_char_assign(s->seen, lit2var(clause->data[j].lit), 1); + } + } + vec_char_assign(s->seen, var, 0); + } + } + vec_char_assign(s->seen, lit2var(lit), 0); +} + +static inline void solver_garbage_collect(solver_t *s) +{ + unsigned i; + unsigned *array; + struct cdb *new_cdb = cdb_alloc(cdb_capacity(s->all_clauses) - cdb_wasted(s->all_clauses)); + + for (i = 0; i < 2 * vec_char_size(s->assigns); i++) { + struct watcher *w; + watch_list_foreach(s->watches, w, i) + clause_realloc(new_cdb, s->all_clauses, &(w->cref)); + watch_list_foreach(s->bin_watches, w, i) + clause_realloc(new_cdb, s->all_clauses, &(w->cref)); + } + + for (i = 0; i < vec_uint_size(s->trail); i++) + if (lit_reason(s, vec_uint_at(s->trail, i)) != UNDEF) + clause_realloc(new_cdb, s->all_clauses, &(vec_uint_data(s->reasons)[lit2var(vec_uint_at(s->trail, i))])); + + array = vec_uint_data(s->learnts); + for (i = 0; i < vec_uint_size(s->learnts); i++) + clause_realloc(new_cdb, s->all_clauses, &(array[i])); + + array = vec_uint_data(s->originals); + for (i = 0; i < vec_uint_size(s->originals); i++) + clause_realloc(new_cdb, s->all_clauses, &(array[i])); + + cdb_free(s->all_clauses); + s->all_clauses = new_cdb; +} + +static inline void solver_reduce_cdb(solver_t *s) +{ + unsigned i, limit; + unsigned n_learnts = vec_uint_size(s->learnts); + unsigned cref; + struct clause *clause; + struct clause **learnts_cls; + + learnts_cls = satoko_alloc(struct clause *, n_learnts); + vec_uint_foreach(s->learnts, cref, i) + learnts_cls[i] = clause_read(s, cref); + + limit = n_learnts / 2; + + satoko_sort((void *)learnts_cls, n_learnts, + (int (*)(const void *, const void *)) clause_compare); + + if (learnts_cls[n_learnts / 2]->lbd <= 3) + s->RC2 += s->opts.inc_special_reduce; + if (learnts_cls[n_learnts - 1]->lbd <= 6) + s->RC2 += s->opts.inc_special_reduce; + + vec_uint_clear(s->learnts); + for (i = 0; i < n_learnts; i++) { + clause = learnts_cls[i]; + cref = cdb_cref(s->all_clauses, (unsigned *)clause); + assert(clause->f_mark == 0); + if (clause->f_deletable && clause->lbd > 2 && clause->size > 2 && lit_reason(s, clause->data[0].lit) != cref && (i < limit)) { + clause->f_mark = 1; + s->stats.n_learnt_lits -= clause->size; + clause_unwatch(s, cref); + cdb_remove(s->all_clauses, clause); + } else { + if (!clause->f_deletable) + limit++; + clause->f_deletable = 1; + vec_uint_push_back(s->learnts, cref); + } + } + satoko_free(learnts_cls); + + if (s->opts.verbose) { + printf("reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) \n", + vec_uint_size(s->learnts), n_learnts, + 100.0 * vec_uint_size(s->learnts) / n_learnts); + fflush(stdout); + } + if (cdb_wasted(s->all_clauses) > cdb_size(s->all_clauses) * s->opts.garbage_max_ratio) + solver_garbage_collect(s); +} + +//===------------------------------------------------------------------------=== +// Solver external functions +//===------------------------------------------------------------------------=== +unsigned solver_clause_create(solver_t *s, vec_uint_t *lits, unsigned f_learnt) +{ + struct clause *clause; + unsigned cref; + unsigned n_words; + + assert(vec_uint_size(lits) > 1); + assert(f_learnt == 0 || f_learnt == 1); + + n_words = 3 + f_learnt + vec_uint_size(lits); + cref = cdb_append(s->all_clauses, n_words); + clause = clause_read(s, cref); + clause->f_learnt = f_learnt; + clause->f_mark = 0; + clause->f_reallocd = 0; + clause->f_deletable = f_learnt; + clause->size = vec_uint_size(lits); + memcpy(&(clause->data[0].lit), vec_uint_data(lits), sizeof(unsigned) * vec_uint_size(lits)); + + if (f_learnt) { + vec_uint_push_back(s->learnts, cref); + clause->lbd = clause_clac_lbd(s, vec_uint_data(lits), vec_uint_size(lits)); + clause->data[clause->size].act = 0; + s->stats.n_learnt_lits += vec_uint_size(lits); + clause_act_bump(s, clause); + } else { + vec_uint_push_back(s->originals, cref); + s->stats.n_original_lits += vec_uint_size(lits); + } + return cref; +} + +void solver_cancel_until(solver_t * s, unsigned level) +{ + int i; + + if (solver_dlevel(s) <= level) + return; + for (i = (int) vec_uint_size(s->trail) - 1; i >= (int) vec_uint_at(s->trail_lim, level); i--) { + unsigned var = lit2var(vec_uint_at(s->trail, (unsigned) i)); + + vec_char_assign(s->assigns, var, VAR_UNASSING); + vec_uint_assign(s->reasons, var, UNDEF); + vec_char_assign(s->polarity, var, lit_polarity(vec_uint_at(s->trail, (unsigned) i))); + if (!heap_in_heap(s->var_order, var)) + heap_insert(s->var_order, var); + } + s->i_qhead = vec_uint_at(s->trail_lim, level); + vec_uint_shrink(s->trail, vec_uint_at(s->trail_lim, level)); + vec_uint_shrink(s->trail_lim, level); +} + +unsigned solver_propagate(solver_t *s) +{ + unsigned conf_cref = UNDEF; + unsigned *lits; + unsigned neg_lit; + unsigned n_propagations = 0; + + while (s->i_qhead < vec_uint_size(s->trail)) { + unsigned p = vec_uint_at(s->trail, s->i_qhead++); + struct watch_list *ws; + struct watcher *begin; + struct watcher *end; + struct watcher *i, *j; + + n_propagations++; + watch_list_foreach(s->bin_watches, i, p) { + if (var_value(s, lit2var(i->blocker)) == VAR_UNASSING) + solver_enqueue(s, i->blocker, i->cref); + else if (lit_value(s, i->blocker) == LIT_FALSE) + return i->cref; + } + + ws = vec_wl_at(s->watches, p); + begin = watch_list_array(ws); + end = begin + watch_list_size(ws); + for (i = j = begin; i < end;) { + struct clause *clause; + struct watcher w; + + if (lit_value(s, i->blocker) == LIT_TRUE) { + *j++ = *i++; + continue; + } + + clause = clause_read(s, i->cref); + lits = &(clause->data[0].lit); + + // Make sure the false literal is data[1]: + neg_lit = lit_neg(p); + if (lits[0] == neg_lit) + mkt_swap(unsigned, lits[0], lits[1]); + assert(lits[1] == neg_lit); + + w.cref = i->cref; + w.blocker = lits[0]; + + /* If 0th watch is true, then clause is already satisfied. */ + if (lits[0] != i->blocker && lit_value(s, lits[0]) == LIT_TRUE) + *j++ = w; + else { + /* Look for new watch */ + unsigned k; + for (k = 2; k < clause->size; k++) { + if (lit_value(s, lits[k]) != LIT_FALSE) { + lits[1] = lits[k]; + lits[k] = neg_lit; + watch_list_push(vec_wl_at(s->watches, lit_neg(lits[1])), w); + goto next; + } + } + + *j++ = w; + + /* Clause becomes unit under this assignment */ + if (lit_value(s, lits[0]) == LIT_FALSE) { + conf_cref = i->cref; + s->i_qhead = vec_uint_size(s->trail); + i++; + // Copy the remaining watches: + while (i < end) + *j++ = *i++; + } else + solver_enqueue(s, lits[0], i->cref); + } + next: + i++; + } + + s->stats.n_inspects += j - watch_list_array(ws); + watch_list_shrink(ws, j - watch_list_array(ws)); + } + s->stats.n_propagations += n_propagations; + s->n_props_simplify -= n_propagations; + return conf_cref; +} + +char solver_search(solver_t *s) +{ + s->stats.n_starts++; + while (1) { + unsigned confl_cref = solver_propagate(s); + if (confl_cref != UNDEF) { + s->stats.n_conflicts++; + if (solver_dlevel(s) == 0) + return SATOKO_UNSAT; + /* Restart heuristic */ + b_queue_push(s->bq_trail, vec_uint_size(s->trail)); + if (solver_block_rst(s)) + b_queue_clean(s->bq_lbd); + solver_handle_conflict(s, confl_cref); + } else { + /* No conflict */ + unsigned next_lit; + + if (solver_rst(s)) { + b_queue_clean(s->bq_lbd); + solver_cancel_until(s, 0); + return SATOKO_UNDEC; + } + if (solver_dlevel(s) == 0) + satoko_simplify(s); + + /* Reduce the set of learnt clauses */ + if (s->stats.n_conflicts >= s->n_confl_bfr_reduce) { + s->RC1 = (s->stats.n_conflicts / s->RC2) + 1; + solver_reduce_cdb(s); + s->RC2 += s->opts.inc_reduce; + s->n_confl_bfr_reduce = s->RC1 * s->RC2; + } + + /* Make decisions based on user assumptions */ + next_lit = UNDEF; + while (solver_dlevel(s) < vec_uint_size(s->assumptions)) { + unsigned lit = vec_uint_at(s->assumptions, solver_dlevel(s)); + if (lit_value(s, lit) == LIT_TRUE) { + vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail)); + } else if (lit_value(s, lit) == LIT_FALSE) { + solver_analyze_final(s, lit_neg(lit)); + return SATOKO_UNSAT; + } else { + next_lit = lit; + break; + } + + } + if (next_lit == UNDEF) { + s->stats.n_decisions++; + next_lit = solver_decide(s); + if (next_lit == UNDEF) + return SATOKO_SAT; + } + solver_new_decision(s, next_lit); + } + } +} + +//===------------------------------------------------------------------------=== +// Debug procedure +//===------------------------------------------------------------------------=== +void solver_debug_check(solver_t *s, int result) +{ + unsigned cref, i; + unsigned *array; + + printf("Checking for trail(%u) inconsistencies...", vec_uint_size(s->trail)); + array = vec_uint_data(s->trail); + for (i = 1; i < vec_uint_size(s->trail); i++) + if (array[i - 1] == lit_neg(array[i])) { + printf("Inconsistent trail: %u %u\n", array[i - 1], array[i]); + return; + } + printf(" TRAIL OK\n"); + + printf("Checking clauses... \n"); + vec_uint_foreach(s->originals, cref, i) { + unsigned j; + struct clause *clause = clause_read(s, cref); + for (j = 0; j < clause->size; j++) { + if (vec_uint_find(s->trail, clause->data[j].lit)) { + break; + } + } + if (result == SATOKO_SAT && j == clause->size) { + printf("FOUND UNSAT CLAUSE!!!!\n"); + clause_print(clause); + } + } +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h new file mode 100644 index 00000000..65b86c68 --- /dev/null +++ b/src/sat/satoko/solver.h @@ -0,0 +1,242 @@ +//===--- solver.h -----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__solver_h +#define satoko__solver_h + +#include +#include +#include +#include + +#include "clause.h" +#include "cdb.h" +#include "satoko.h" +#include "types.h" +#include "watch_list.h" +#include "utils/b_queue.h" +#include "utils/heap.h" +#include "utils/mem.h" +#include "utils/misc.h" +#include "utils/vec/vec_char.h" +#include "utils/vec/vec_dble.h" +#include "utils/vec/vec_uint.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +enum { + LIT_FALSE = 1, + LIT_TRUE = 0, + VAR_UNASSING = 3 +}; + +#define UNDEF 0xFFFFFFFF + +struct satoko_stats { + unsigned n_starts; + unsigned n_reduce_db; + + long long n_decisions; + long long n_propagations; + long long n_inspects; + long long n_conflicts; + + long long n_original_lits; + long long n_learnt_lits; +}; + +typedef struct solver_t_ solver_t; +struct solver_t_ { + /* User data */ + vec_uint_t *assumptions; + vec_uint_t *final_conflict; + + /* Clauses Database */ + struct cdb *all_clauses; + vec_uint_t *learnts; + vec_uint_t *originals; + vec_wl_t *watches; + vec_wl_t *bin_watches; + + /* Activity heuristic */ + act_t var_act_inc; /* Amount to bump next variable with. */ + clause_act_t clause_act_inc; /* Amount to bump next clause with. */ + + /* Variable Information */ + vec_act_t *activity; /* A heuristic measurement of the activity of a variable. */ + heap_t *var_order; + vec_uint_t *levels; /* Decision level of the current assignment */ + vec_uint_t *reasons; /* Reason (clause) of the current assignment */ + vec_char_t *assigns; + vec_char_t *polarity; + + /* Assignments */ + vec_uint_t *trail; + vec_uint_t *trail_lim; /* Separator indices for different decision levels in 'trail'. */ + unsigned i_qhead; /* Head of propagation queue (as index into the trail). */ + unsigned n_assigns_simplify; /* Number of top-level assignments since + last execution of 'simplify()'. */ + long long n_props_simplify; /* Remaining number of propagations that + must be made before next execution of + 'simplify()'. */ + + /* Temporary data used by Search method */ + b_queue_t *bq_trail; + b_queue_t *bq_lbd; + long RC1; + long RC2; + unsigned n_confl_bfr_reduce; + float sum_lbd; + + /* Temporary data used by Analyze */ + vec_uint_t *temp_lits; + vec_char_t *seen; + vec_uint_t *tagged; /* Stack */ + vec_uint_t *stack; + vec_uint_t *last_dlevel; + + /* Misc temporary */ + vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and + * clauses minimization with binary resolution */ + unsigned cur_stamp; /* Used for marking literals and levels of interest */ + + struct satoko_stats stats; + struct satoko_opts opts; +}; + +//===------------------------------------------------------------------------=== +extern unsigned solver_clause_create(solver_t *, vec_uint_t *, unsigned); +extern char solver_search(solver_t *); +extern void solver_cancel_until(solver_t *, unsigned); +extern unsigned solver_propagate(solver_t *); +extern void solver_debug_check(solver_t *, int); + +//===------------------------------------------------------------------------=== +// Inline var/lit functions +//===------------------------------------------------------------------------=== +static inline unsigned var2lit(unsigned var, char polarity) +{ + return var + var + ((unsigned) polarity != 0); +} + +static inline unsigned lit2var(unsigned lit) +{ + return lit >> 1; +} +//===------------------------------------------------------------------------=== +// Inline var functions +//===------------------------------------------------------------------------=== +static inline char var_value(solver_t *s, unsigned var) +{ + return vec_char_at(s->assigns, var); +} + +static inline unsigned var_dlevel(solver_t *s, unsigned var) +{ + return vec_uint_at(s->levels, var); +} + +static inline unsigned var_reason(solver_t *s, unsigned var) +{ + return vec_uint_at(s->reasons, var); +} +//===------------------------------------------------------------------------=== +// Inline lit functions +//===------------------------------------------------------------------------=== +static inline unsigned lit_neg(unsigned lit) +{ + return lit ^ 1; +} + +static inline char lit_polarity(unsigned lit) +{ + return (char)(lit & 1); +} + +static inline char lit_value(solver_t *s, unsigned lit) +{ + return lit_polarity(lit) ^ vec_char_at(s->assigns, lit2var(lit)); +} + +static inline unsigned lit_dlevel(solver_t *s, unsigned lit) +{ + return vec_uint_at(s->levels, lit2var(lit)); +} + +static inline unsigned lit_reason(solver_t *s, unsigned lit) +{ + return vec_uint_at(s->reasons, lit2var(lit)); +} +//===------------------------------------------------------------------------=== +// Inline solver minor functions +//===------------------------------------------------------------------------=== +static inline unsigned solver_check_limits(solver_t *s) +{ + return (s->opts.conf_limit == 0 || s->opts.conf_limit >= s->stats.n_conflicts) && + (s->opts.prop_limit == 0 || s->opts.prop_limit >= s->stats.n_propagations); +} + +/** Returns current decision level */ +static inline unsigned solver_dlevel(solver_t *s) +{ + return vec_uint_size(s->trail_lim); +} + +static inline int solver_enqueue(solver_t *s, unsigned lit, unsigned reason) +{ + unsigned var = lit2var(lit); + + vec_char_assign(s->assigns, var, lit_polarity(lit)); + vec_uint_assign(s->levels, var, solver_dlevel(s)); + vec_uint_assign(s->reasons, var, reason); + vec_uint_push_back(s->trail, lit); + return SATOKO_OK; +} + +//===------------------------------------------------------------------------=== +// Inline clause functions +//===------------------------------------------------------------------------=== +static inline struct clause *clause_read(solver_t *s, unsigned cref) +{ + return cdb_handler(s->all_clauses, cref); +} + +static inline void clause_watch(solver_t *s, unsigned cref) +{ + struct clause *clause = cdb_handler(s->all_clauses, cref); + struct watcher w1; + struct watcher w2; + + w1.cref = cref; + w2.cref = cref; + w1.blocker = clause->data[1].lit; + w2.blocker = clause->data[0].lit; + if (clause->size == 2) { + watch_list_push(vec_wl_at(s->bin_watches, lit_neg(clause->data[0].lit)), w1); + watch_list_push(vec_wl_at(s->bin_watches, lit_neg(clause->data[1].lit)), w2); + } else { + watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), w1); + watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), w2); + } +} + +static inline void clause_unwatch(solver_t *s, unsigned cref) +{ + struct clause *clause = cdb_handler(s->all_clauses, cref); + if (clause->size == 2) { + watch_list_remove(vec_wl_at(s->bin_watches, lit_neg(clause->data[0].lit)), cref); + watch_list_remove(vec_wl_at(s->bin_watches, lit_neg(clause->data[1].lit)), cref); + } else { + watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), cref); + watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), cref); + } +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__solver_h */ diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c new file mode 100644 index 00000000..db9a267b --- /dev/null +++ b/src/sat/satoko/solver_api.c @@ -0,0 +1,310 @@ +//===--- solver_api.h -------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#include +#include +#include +#include + +#include "act_var.h" +#include "utils/misc.h" +#include "solver.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_IMPL_START + +//===------------------------------------------------------------------------=== +// Satoko internal functions +//===------------------------------------------------------------------------=== +static inline void solver_rebuild_order(solver_t *s) +{ + unsigned var; + vec_uint_t *vars = vec_uint_alloc(vec_char_size(s->assigns)); + + for (var = 0; var < vec_char_size(s->assigns); var++) + if (var_value(s, var) == VAR_UNASSING) + vec_uint_push_back(vars, var); + heap_build(s->var_order, vars); + vec_uint_free(vars); +} + +static inline int clause_is_satisfied(solver_t *s, struct clause *clause) +{ + unsigned i; + unsigned *lits = &(clause->data[0].lit); + for (i = 0; i < clause->size; i++) + if (lit_value(s, lits[i]) == LIT_TRUE) + return SATOKO_OK; + return SATOKO_ERR; +} + +static inline void print_opts(solver_t *s) +{ + printf( "+-[ BLACK MAGIC - PARAMETERS ]-+\n"); + printf( "| |\n"); + printf( "|--> Restarts heuristic |\n"); + printf( "| * LBD Queue = %6d |\n", s->opts.sz_lbd_bqueue); + printf( "| * Trail Queue = %6d |\n", s->opts.sz_trail_bqueue); + printf( "| * f_rst = %6.2f |\n", s->opts.f_rst); + printf( "| * b_rst = %6.2f |\n", s->opts.b_rst); + printf( "| |\n"); + printf( "|--> Clause DB reduction: |\n"); + printf( "| * First = %6d |\n", s->opts.n_conf_fst_reduce); + printf( "| * Inc = %6d |\n", s->opts.inc_reduce); + printf( "| * Special Inc = %6d |\n", s->opts.inc_special_reduce); + printf( "| * Protected (LBD) < %2d |\n", s->opts.lbd_freeze_clause); + printf( "| |\n"); + printf( "|--> Binary resolution: |\n"); + printf( "| * Clause size < %3d |\n", s->opts.clause_max_sz_bin_resol); + printf( "| * Clause lbd < %3d |\n", s->opts.clause_min_lbd_bin_resol); + printf( "+------------------------------+\n\n"); +} + +static inline void print_stats(solver_t *s) +{ + printf("starts : %10d\n", s->stats.n_starts); + printf("conflicts : %10lld\n", s->stats.n_conflicts); + printf("decisions : %10lld\n", s->stats.n_decisions); + printf("propagations : %10lld\n", s->stats.n_propagations); +} + +//===------------------------------------------------------------------------=== +// Satoko external functions +//===------------------------------------------------------------------------=== +solver_t * satoko_create() +{ + solver_t *s = satoko_calloc(solver_t, 1); + + satoko_default_opts(&s->opts); + /* User data */ + s->assumptions = vec_uint_alloc(0); + s->final_conflict = vec_uint_alloc(0); + /* Clauses Database */ + s->all_clauses = cdb_alloc(0); + s->originals = vec_uint_alloc(0); + s->learnts = vec_uint_alloc(0); + s->watches = vec_wl_alloc(0); + s->bin_watches = vec_wl_alloc(0); + /* Activity heuristic */ + s->var_act_inc = VAR_ACT_INIT_INC; + s->clause_act_inc = CLAUSE_ACT_INIT_INC; + /* Variable Information */ + s->activity = vec_act_alloc(0); + s->var_order = heap_alloc(s->activity); + s->levels = vec_uint_alloc(0); + s->reasons = vec_uint_alloc(0); + s->assigns = vec_char_alloc(0); + s->polarity = vec_char_alloc(0); + /* Assignments */ + s->trail = vec_uint_alloc(0); + s->trail_lim = vec_uint_alloc(0); + /* Temporary data used by Search method */ + s->bq_trail = b_queue_alloc(s->opts.sz_trail_bqueue); + s->bq_lbd = b_queue_alloc(s->opts.sz_lbd_bqueue); + s->n_confl_bfr_reduce = s->opts.n_conf_fst_reduce; + s->RC1 = 1; + s->RC2 = s->opts.n_conf_fst_reduce; + /* Temporary data used by Analyze */ + s->temp_lits = vec_uint_alloc(0); + s->seen = vec_char_alloc(0); + s->tagged = vec_uint_alloc(0); + s->stack = vec_uint_alloc(0); + s->last_dlevel = vec_uint_alloc(0); + /* Misc temporary */ + s->stamps = vec_uint_alloc(0); + return s; +} + +void satoko_destroy(solver_t *s) +{ + vec_uint_free(s->assumptions); + vec_uint_free(s->final_conflict); + cdb_free(s->all_clauses); + vec_uint_free(s->originals); + vec_uint_free(s->learnts); + vec_wl_free(s->watches); + vec_wl_free(s->bin_watches); + vec_act_free(s->activity); + heap_free(s->var_order); + vec_uint_free(s->levels); + vec_uint_free(s->reasons); + vec_char_free(s->assigns); + vec_char_free(s->polarity); + vec_uint_free(s->trail); + vec_uint_free(s->trail_lim); + b_queue_free(s->bq_lbd); + b_queue_free(s->bq_trail); + vec_uint_free(s->temp_lits); + vec_char_free(s->seen); + vec_uint_free(s->tagged); + vec_uint_free(s->stack); + vec_uint_free(s->last_dlevel); + vec_uint_free(s->stamps); + satoko_free(s); +} + +void satoko_default_opts(satoko_opts_t *opts) +{ + opts->verbose = 0; + /* Limits */ + opts->conf_limit = 0; + opts->prop_limit = 0; + /* Constants used for restart heuristic */ + opts->f_rst = 0.8; + opts->b_rst = 1.4; + opts->fst_block_rst = 10000; + opts->sz_lbd_bqueue = 50; + opts->sz_trail_bqueue = 5000; + /* Constants used for clause database reduction heuristic */ + opts->n_conf_fst_reduce = 2000; + opts->inc_reduce = 300; + opts->inc_special_reduce = 1000; + opts->lbd_freeze_clause = 30; + /* VSIDS heuristic */ + opts->var_decay = 0.95; + opts->clause_decay = 0.995; + /* Binary resolution */ + opts->clause_max_sz_bin_resol = 30; + opts->clause_min_lbd_bin_resol = 6; + + opts->garbage_max_ratio = 0.3; +} + +/** + * TODO: sanity check on configuration options + */ +void satoko_configure(satoko_t *s, satoko_opts_t *user_opts) +{ + assert(user_opts); + memcpy(&s->opts, user_opts, sizeof(satoko_opts_t)); +} + +int satoko_simplify(solver_t * s) +{ + unsigned i, j = 0; + unsigned cref; + + assert(solver_dlevel(s) == 0); + if (solver_propagate(s) != UNDEF) + return SATOKO_ERR; + if (s->n_assigns_simplify == vec_uint_size(s->trail) || s->n_props_simplify > 0) + return SATOKO_OK; + + vec_uint_foreach(s->originals, cref, i) { + struct clause *clause = clause_read(s, cref); + + if (clause_is_satisfied(s, clause)) { + clause->f_mark = 1; + s->stats.n_original_lits -= clause->size; + clause_unwatch(s, cref); + } else + vec_uint_assign(s->originals, j++, cref); + } + vec_uint_shrink(s->originals, j); + solver_rebuild_order(s); + s->n_assigns_simplify = vec_uint_size(s->trail); + s->n_props_simplify = s->stats.n_original_lits + s->stats.n_learnt_lits; + return SATOKO_OK; +} + +void satoko_add_variable(solver_t *s, char sign) +{ + unsigned var = vec_act_size(s->activity); + vec_wl_push(s->bin_watches); + vec_wl_push(s->bin_watches); + vec_wl_push(s->watches); + vec_wl_push(s->watches); + vec_act_push_back(s->activity, 0); + vec_uint_push_back(s->levels, 0); + vec_char_push_back(s->assigns, VAR_UNASSING); + vec_char_push_back(s->polarity, sign); + vec_uint_push_back(s->reasons, UNDEF); + vec_uint_push_back(s->stamps, 0); + vec_char_push_back(s->seen, 0); + heap_insert(s->var_order, var); +} + +int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) +{ + unsigned i, j; + unsigned prev_lit; + unsigned max_var; + unsigned cref; + + qsort((void *) lits, size, sizeof(unsigned), mkt_uint_compare); + max_var = lit2var(lits[size - 1]); + while (max_var >= vec_act_size(s->activity)) + satoko_add_variable(s, LIT_FALSE); + + vec_uint_clear(s->temp_lits); + j = 0; + prev_lit = UNDEF; + for (i = 0; i < size; i++) { + if (lits[i] == lit_neg(prev_lit) || lit_value(s, lits[i]) == LIT_TRUE) + return SATOKO_OK; + else if (lits[i] != prev_lit && var_value(s, lit2var(lits[i])) == VAR_UNASSING) { + prev_lit = lits[i]; + vec_uint_push_back(s->temp_lits, lits[i]); + } + } + + if (vec_uint_size(s->temp_lits) == 0) + return SATOKO_ERR; + if (vec_uint_size(s->temp_lits) == 1) { + solver_enqueue(s, vec_uint_at(s->temp_lits, 0), UNDEF); + return (solver_propagate(s) == UNDEF); + } + + cref = solver_clause_create(s, s->temp_lits, 0); + clause_watch(s, cref); + return SATOKO_OK; +} + +void satoko_assump_push(solver_t *s, unsigned lit) +{ + vec_uint_push_back(s->assumptions, lit); +} + +void satoko_assump_pop(solver_t *s) +{ + assert(vec_uint_size(s->assumptions) > 0); + vec_uint_pop_back(s->assumptions); + solver_cancel_until(s, vec_uint_size(s->assumptions)); +} + +int satoko_solve(solver_t *s) +{ + char status = SATOKO_UNDEC; + + assert(s); + if (s->opts.verbose) + print_opts(s); + + while (status == SATOKO_UNDEC) { + status = solver_search(s); + if (solver_check_limits(s) == 0) + break; + } + if (s->opts.verbose) + print_stats(s); + solver_cancel_until(s, vec_uint_size(s->assumptions)); + return status; +} + +int satoko_final_conflict(solver_t *s, unsigned *out) +{ + if (vec_uint_size(s->final_conflict) == 0) + return -1; + out = satoko_alloc(unsigned, vec_uint_size(s->final_conflict)); + memcpy(out, vec_uint_data(s->final_conflict), + sizeof(unsigned) * vec_uint_size(s->final_conflict)); + return vec_uint_size(s->final_conflict); + +} + +ABC_NAMESPACE_IMPL_END diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h new file mode 100644 index 00000000..2811c2c6 --- /dev/null +++ b/src/sat/satoko/types.h @@ -0,0 +1,50 @@ +//===--- types.h ------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__types_h +#define satoko__types_h + +#include "utils/vec/vec_dble.h" +#include "utils/vec/vec_uint.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#define SATOKO_ACT_VAR_DBLE +#define SATOKO_ACT_CLAUSE_FLOAT + +#ifdef SATOKO_ACT_VAR_DBLE + #define VAR_ACT_INIT_INC 1.0 + typedef double act_t; + typedef vec_dble_t vec_act_t ; + #define vec_act_alloc(size) vec_dble_alloc(size) + #define vec_act_free(vec) vec_dble_free(vec) + #define vec_act_size(vec) vec_dble_size(vec) + #define vec_act_at(vec, idx) vec_dble_at(vec, idx) + #define vec_act_push_back(vec, value) vec_dble_push_back(vec, value) +#else + #define VAR_ACT_INIT_INC (1 << 5) + typedef unsigned act_t; + typedef vec_uint_t vec_act_t; + #define vec_act_alloc(size) vec_uint_alloc(size) + #define vec_act_free(vec) vec_uint_free(vec) + #define vec_act_size(vec) vec_uint_size(vec) + #define vec_act_at(vec, idx) vec_uint_at(vec, idx) + #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) +#endif /* SATOKO_ACT_VAR_DBLE */ + +#ifdef SATOKO_ACT_CLAUSE_FLOAT + #define CLAUSE_ACT_INIT_INC 1.0 + typedef float clause_act_t; +#else + #define CLAUSE_ACT_INIT_INC (1 << 11) + typedef unsigned clause_act_t; +#endif /* SATOKO_ACT_CLAUSE_FLOAT */ + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__types_h */ diff --git a/src/sat/satoko/utils/b_queue.h b/src/sat/satoko/utils/b_queue.h new file mode 100644 index 00000000..926edf29 --- /dev/null +++ b/src/sat/satoko/utils/b_queue.h @@ -0,0 +1,81 @@ +//===--- b_queue.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__b_queue_h +#define satoko__utils__b_queue_h + +#include "mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +/* Bounded Queue */ +typedef struct b_queue_t_ b_queue_t; +struct b_queue_t_ { + unsigned size; + unsigned cap; + unsigned i_first; + unsigned i_empty; + unsigned long long sum; + unsigned *data; +}; + +//===------------------------------------------------------------------------=== +// Bounded Queue API +//===------------------------------------------------------------------------=== +static inline b_queue_t *b_queue_alloc(unsigned cap) +{ + b_queue_t *p = satoko_calloc(b_queue_t, 1); + p->cap = cap; + p->data = satoko_calloc(unsigned, cap); + return p; +} + +static inline void b_queue_free(b_queue_t *p) +{ + satoko_free(p->data); + satoko_free(p); +} + +static inline void b_queue_push(b_queue_t *p, unsigned Value) +{ + if (p->size == p->cap) { + assert(p->i_first == p->i_empty); + p->sum -= p->data[p->i_first]; + p->i_first = (p->i_first + 1) % p->cap; + } else + p->size++; + + p->sum += Value; + p->data[p->i_empty] = Value; + if ((++p->i_empty) == p->cap) { + p->i_empty = 0; + p->i_first = 0; + } +} + +static inline unsigned b_queue_avg(b_queue_t *p) +{ + return (unsigned)(p->sum / ((unsigned long long) p->size)); +} + +static inline unsigned b_queue_is_valid(b_queue_t *p) +{ + return (p->cap == p->size); +} + +static inline void b_queue_clean(b_queue_t *p) +{ + p->i_first = 0; + p->i_empty = 0; + p->size = 0; + p->sum = 0; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__b_queue_h */ diff --git a/src/sat/satoko/utils/heap.h b/src/sat/satoko/utils/heap.h new file mode 100644 index 00000000..e1611e95 --- /dev/null +++ b/src/sat/satoko/utils/heap.h @@ -0,0 +1,181 @@ +//===--- heap.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__heap_h +#define satoko__utils__heap_h + +#include "mem.h" +#include "../types.h" +#include "vec/vec_dble.h" +#include "vec/vec_int.h" +#include "vec/vec_uint.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct heap_t_ heap_t; +struct heap_t_ { + vec_int_t *indices; + vec_uint_t *data; + vec_act_t *weights; +}; +//===------------------------------------------------------------------------=== +// Heap internal functions +//===------------------------------------------------------------------------=== +static inline unsigned left(unsigned i) { return 2 * i + 1; } +static inline unsigned right(unsigned i) { return (i + 1) * 2; } +static inline unsigned parent(unsigned i) { return (i - 1) >> 1; } + +static inline int compare(heap_t *p, unsigned x, unsigned y) +{ + return vec_act_at(p->weights, x) > vec_act_at(p->weights, y); +} + +static inline void heap_percolate_up(heap_t *h, unsigned i) +{ + unsigned x = vec_uint_at(h->data, i); + unsigned p = parent(i); + + while (i != 0 && compare(h, x, vec_uint_at(h->data, p))) { + vec_uint_assign(h->data, i, vec_uint_at(h->data, p)); + vec_int_assign(h->indices, vec_uint_at(h->data, p), (int) i); + i = p; + p = parent(p); + } + vec_uint_assign(h->data, i, x); + vec_int_assign(h->indices, x, (int) i); +} + +static inline void heap_percolate_down(heap_t *h, unsigned i) +{ + unsigned x = vec_uint_at(h->data, i); + + while (left(i) < vec_uint_size(h->data)) { + unsigned child = right(i) < vec_uint_size(h->data) && + compare(h, vec_uint_at(h->data, right(i)), vec_uint_at(h->data, left(i))) + ? right(i) + : left(i); + + if (!compare(h, vec_uint_at(h->data, child), x)) + break; + + vec_uint_assign(h->data, i, vec_uint_at(h->data, child)); + vec_int_assign(h->indices, vec_uint_at(h->data, i), (int) i); + i = child; + } + vec_uint_assign(h->data, i, x); + vec_int_assign(h->indices, x, (int) i); +} + +//===------------------------------------------------------------------------=== +// Heap API +//===------------------------------------------------------------------------=== +static inline heap_t *heap_alloc(vec_act_t *weights) +{ + heap_t *p = satoko_alloc(heap_t, 1); + p->weights = weights; + p->indices = vec_int_alloc(0); + p->data = vec_uint_alloc(0); + return p; +} + +static inline void heap_free(heap_t *p) +{ + vec_int_free(p->indices); + vec_uint_free(p->data); + satoko_free(p); +} + +static inline unsigned heap_size(heap_t *p) +{ + return vec_uint_size(p->data); +} + +static inline int heap_in_heap(heap_t *p, unsigned entry) +{ + return (entry < vec_int_size(p->indices)) && + (vec_int_at(p->indices, entry) >= 0); +} + +static inline void heap_increase(heap_t *p, unsigned entry) +{ + assert(heap_in_heap(p, entry)); + heap_percolate_down(p, (unsigned) vec_int_at(p->indices, entry)); +} + +static inline void heap_decrease(heap_t *p, unsigned entry) +{ + assert(heap_in_heap(p, entry)); + heap_percolate_up(p, (unsigned) vec_int_at(p->indices, entry)); +} + +static inline void heap_insert(heap_t *p, unsigned entry) +{ + if (vec_int_size(p->indices) < entry + 1) { + unsigned old_size = vec_int_size(p->indices); + unsigned i; + int e; + vec_int_resize(p->indices, entry + 1); + vec_int_foreach_start(p->indices, e, i, old_size) + vec_int_assign(p->indices, i, -1); + } + assert(!heap_in_heap(p, entry)); + vec_int_assign(p->indices, entry, (int) vec_uint_size(p->data)); + vec_uint_push_back(p->data, entry); + heap_percolate_up(p, (unsigned) vec_int_at(p->indices, entry)); +} + +static inline void heap_update(heap_t *p, unsigned i) +{ + if (!heap_in_heap(p, i)) + heap_insert(p, i); + else { + heap_percolate_up(p, (unsigned) vec_int_at(p->indices, i)); + heap_percolate_down(p, (unsigned) vec_int_at(p->indices, i)); + } +} + +static inline void heap_build(heap_t *p, vec_uint_t *entries) +{ + int i; + unsigned j, entry; + + vec_uint_foreach(p->data, entry, j) + vec_int_assign(p->indices, entry, -1); + vec_uint_clear(p->data); + vec_uint_foreach(entries, entry, j) { + vec_int_assign(p->indices, entry, (int) j); + vec_uint_push_back(p->data, entry); + } + for ((i = vec_uint_size(p->data) / 2 - 1); i >= 0; i--) + heap_percolate_down(p, (unsigned) i); +} + +static inline void heap_clear(heap_t *p) +{ + unsigned i; + int entry; + vec_int_foreach(p->indices, entry, i) + vec_int_assign(p->indices, i, -1); + vec_uint_clear(p->data); +} + +static inline unsigned heap_remove_min(heap_t *p) +{ + unsigned x = vec_uint_at(p->data, 0); + vec_uint_assign(p->data, 0, vec_uint_at(p->data, vec_uint_size(p->data) - 1)); + vec_int_assign(p->indices, vec_uint_at(p->data, 0), 0); + vec_int_assign(p->indices, x, -1); + vec_uint_pop_back(p->data); + if (vec_uint_size(p->data) > 1) + heap_percolate_down(p, 0); + return x; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__heap_h */ diff --git a/src/sat/satoko/utils/mem.h b/src/sat/satoko/utils/mem.h new file mode 100755 index 00000000..5ff9873d --- /dev/null +++ b/src/sat/satoko/utils/mem.h @@ -0,0 +1,23 @@ +//===--- mem.h --------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__mem_h +#define satoko__utils__mem_h + +#include + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#define satoko_alloc(type, n_elements) ((type *) malloc((n_elements) * sizeof(type))) +#define satoko_calloc(type, n_elements) ((type *) calloc((n_elements), sizeof(type))) +#define satoko_realloc(type, ptr, n_elements) ((type *) realloc(ptr, (n_elements) * sizeof(type))) +#define satoko_free(p) do { free(p); p = NULL; } while(0) + +ABC_NAMESPACE_HEADER_END +#endif diff --git a/src/sat/satoko/utils/misc.h b/src/sat/satoko/utils/misc.h new file mode 100755 index 00000000..aa8bcb8c --- /dev/null +++ b/src/sat/satoko/utils/misc.h @@ -0,0 +1,37 @@ +//===--- misc.h -------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__misc_h +#define satoko__utils__misc_h + +#include + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +#define mkt_swap(type, a, b) { type t = a; a = b; b = t; } + +static inline unsigned mkt_uint_max(unsigned a, unsigned b) +{ + return a > b ? a : b; +} + +static inline int mkt_uint_compare(const void *p1, const void *p2) +{ + const unsigned pp1 = *(const unsigned *)p1; + const unsigned pp2 = *(const unsigned *)p2; + + if (pp1 < pp2) + return -1; + if (pp1 > pp2) + return 1; + return 0; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__misc_h */ diff --git a/src/sat/satoko/utils/sort.h b/src/sat/satoko/utils/sort.h new file mode 100644 index 00000000..285f4b91 --- /dev/null +++ b/src/sat/satoko/utils/sort.h @@ -0,0 +1,65 @@ +//===--- sort.h -------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__sort_h +#define satoko__utils__sort_h + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +static inline void select_sort(void **data, unsigned size, + int (*comp_fn)(const void *, const void *)) +{ + unsigned i, j, i_best; + void *temp; + + for (i = 0; i < (size - 1); i++) { + i_best = i; + for (j = i + 1; j < size; j++) { + if (comp_fn(data[j], data[i_best])) + i_best = j; + } + temp = data[i]; + data[i] = data[i_best]; + data[i_best] = temp; + } +} + +static void satoko_sort(void **data, unsigned size, + int (*comp_fn)(const void *, const void *)) +{ + if (size <= 15) + select_sort(data, size, comp_fn); + else { + void *pivot = data[size / 2]; + void *temp; + unsigned j = size; + int i = -1; + + for (;;) { + do { + i++; + } while (comp_fn(data[i], pivot)); + do { + j--; + } while (comp_fn(pivot, data[j])); + + if ((unsigned) i >= j) + break; + + temp = data[i]; + data[i] = data[j]; + data[j] = temp; + } + satoko_sort(data, (unsigned) i, comp_fn); + satoko_sort(data + i, (size - (unsigned) i), comp_fn); + } +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__sort_h */ diff --git a/src/sat/satoko/utils/vec/vec_char.h b/src/sat/satoko/utils/vec/vec_char.h new file mode 100644 index 00000000..fe88797a --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_char.h @@ -0,0 +1,259 @@ +//===--- vec_char.h ---------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_char_h +#define satoko__utils__vec__vec_char_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_char_t_ vec_char_t; +struct vec_char_t_ { + unsigned cap; + unsigned size; + char *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_char_foreach(vec, entry, i) \ + for (i = 0; (i < vec_char_size(vec)) && (((entry) = vec_char_at(vec, i)), 1); i++) + +#define vec_char_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_char_size(vec)) && (((entry) = vec_char_at(vec, i)), 1); i++) + +#define vec_char_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_char_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_char_t * vec_char_alloc(unsigned cap) +{ + vec_char_t *p = satoko_alloc(vec_char_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(char, p->cap) : NULL; + return p; +} + +static inline vec_char_t * vec_char_alloc_exact(unsigned cap) +{ + vec_char_t *p = satoko_alloc(vec_char_t, 1); + + cap = 0; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(char, p->cap ) : NULL; + return p; +} + +static inline vec_char_t * vec_char_init(unsigned size, char value) +{ + vec_char_t *p = satoko_alloc(vec_char_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(char, p->cap) : NULL; + memset(p->data, value, sizeof(char) * p->size); + return p; +} + +static inline void vec_char_free(vec_char_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_char_size(vec_char_t *p) +{ + return p->size; +} + +static inline void vec_char_resize(vec_char_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(char, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_char_shrink(vec_char_t *p, unsigned new_size) +{ + assert(p->cap > new_size); + p->size = new_size; +} + +static inline void vec_char_reserve(vec_char_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(char, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_char_capacity(vec_char_t *p) +{ + return p->cap; +} + +static inline int vec_char_empty(vec_char_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_char_erase(vec_char_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline char vec_char_at(vec_char_t *p, unsigned idx) +{ + assert(idx >= 0 && idx < p->size); + return p->data[idx]; +} + +static inline char * vec_char_at_ptr(vec_char_t *p, unsigned idx) +{ + assert(idx >= 0 && idx < p->size); + return p->data + idx; +} + +static inline char * vec_char_data(vec_char_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_char_duplicate(vec_char_t *dest, const vec_char_t *src) +{ + assert(dest != NULL && src != NULL); + vec_char_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(char) * src->cap); + dest->size = src->size; +} + +static inline void vec_char_copy(vec_char_t *dest, const vec_char_t *src) +{ + assert(dest != NULL && src != NULL); + vec_char_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(char) * src->size); + dest->size = src->size; +} + +static inline void vec_char_push_back(vec_char_t *p, char value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_char_reserve(p, 16); + else + vec_char_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline char vec_char_pop_back(vec_char_t *p) +{ + assert(p && p->size); + return p->data[--p->size]; +} + +static inline void vec_char_assign(vec_char_t *p, unsigned idx, char value) +{ + assert((idx >= 0) && (idx < vec_char_size(p))); + p->data[idx] = value; +} + +static inline void vec_char_insert(vec_char_t *p, unsigned idx, char value) +{ + assert((idx >= 0) && (idx < vec_char_size(p))); + vec_char_push_back(p, 0); + memmove(p->data + idx + 1, p->data + idx, (p->size - idx - 2) * sizeof(char)); + p->data[idx] = value; +} + +static inline void vec_char_drop(vec_char_t *p, unsigned idx) +{ + assert((idx >= 0) && (idx < vec_char_size(p))); + memmove(p->data + idx, p->data + idx + 1, (p->size - idx - 1) * sizeof(char)); + p->size -= 1; +} + +static inline void vec_char_clear(vec_char_t *p) +{ + p->size = 0; +} + +static inline int vec_char_asc_compare(const void *p1, const void *p2) +{ + const char *pp1 = (const char *)p1; + const char *pp2 = (const char *)p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_char_desc_compare(const void *p1, const void *p2) +{ + const char *pp1 = (const char *)p1; + const char *pp2 = (const char *)p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_char_sort(vec_char_t *p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(char), + (int (*)(const void *, const void *)) vec_char_asc_compare); + else + qsort((void*) p->data, p->size, sizeof(char), + (int (*)(const void *, const void *)) vec_char_desc_compare); +} + + +static inline long vec_char_memory(vec_char_t *p) +{ + return p == NULL ? 0 : sizeof(char) * p->cap + sizeof(vec_char_t); +} + +static inline void vec_char_print(vec_char_t* p) +{ + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (unsigned i = 0; i < p->size; i++) + fprintf(stdout, " %d", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_char_h */ diff --git a/src/sat/satoko/utils/vec/vec_dble.h b/src/sat/satoko/utils/vec/vec_dble.h new file mode 100755 index 00000000..50281c2a --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_dble.h @@ -0,0 +1,246 @@ +//===--- vec_int.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_dble_h +#define satoko__utils__vec__vec_dble_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_dble_t_ vec_dble_t; +struct vec_dble_t_ { + unsigned cap; + unsigned size; + double *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_dble_foreach(vec, entry, i) \ + for (i = 0; (i < vec->size) && (((entry) = vec_dble_at(vec, i)), 1); i++) + +#define vec_dble_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_dble_size(vec)) && (((entry) = vec_dble_at(vec, i)), 1); i++) + +#define vec_dble_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_dble_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_dble_t *vec_dble_alloc(unsigned cap) +{ + vec_dble_t* p = satoko_alloc(vec_dble_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; + return p; +} + +static inline vec_dble_t *vec_dble_alloc_exact(unsigned cap) +{ + vec_dble_t* p = satoko_alloc(vec_dble_t, 1); + + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; + return p; +} + +static inline vec_dble_t *vec_dble_init(unsigned size, double value) +{ + vec_dble_t* p = satoko_alloc(vec_dble_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; + memset(p->data, value, sizeof(double) * p->size); + return p; +} + +static inline void vec_dble_free(vec_dble_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_dble_size(vec_dble_t *p) +{ + return p->size; +} + +static inline void vec_dble_resize(vec_dble_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(double, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_dble_reserve(vec_dble_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(double, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_dble_capacity(vec_dble_t *p) +{ + return p->cap; +} + +static inline int vec_dble_empty(vec_dble_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_dble_erase(vec_dble_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline double vec_dble_at(vec_dble_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data[i]; +} + +static inline double *vec_dble_at_ptr(vec_dble_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data + i; +} + +static inline double *vec_dble_data(vec_dble_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_dble_duplicate(vec_dble_t *dest, const vec_dble_t *src) +{ + assert(dest != NULL && src != NULL); + vec_dble_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(double) * src->cap); + dest->size = src->size; +} + +static inline void vec_dble_copy(vec_dble_t *dest, const vec_dble_t *src) +{ + assert(dest != NULL && src != NULL); + vec_dble_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(double) * src->size); + dest->size = src->size; +} + +static inline void vec_dble_push_back(vec_dble_t *p, double value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_dble_reserve(p, 16); + else + vec_dble_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline void vec_dble_assign(vec_dble_t *p, unsigned i, double value) +{ + assert((i >= 0) && (i < vec_dble_size(p))); + p->data[i] = value; +} + +static inline void vec_dble_insert(vec_dble_t *p, unsigned i, double value) +{ + assert((i >= 0) && (i < vec_dble_size(p))); + vec_dble_push_back(p, 0); + memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(double)); + p->data[i] = value; +} + +static inline void vec_dble_drop(vec_dble_t *p, unsigned i) +{ + assert((i >= 0) && (i < vec_dble_size(p))); + memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(double)); + p->size -= 1; +} + +static inline void vec_dble_clear(vec_dble_t *p) +{ + p->size = 0; +} + +static inline int vec_dble_asc_compare(const void *p1, const void *p2) +{ + const double *pp1 = (const double *) p1; + const double *pp2 = (const double *) p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_dble_desc_compare(const void* p1, const void* p2) +{ + const double *pp1 = (const double *) p1; + const double *pp2 = (const double *) p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_dble_sort(vec_dble_t* p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(double), + (int (*)(const void*, const void*)) vec_dble_asc_compare); + else + qsort((void *) p->data, p->size, sizeof(double), + (int (*)(const void*, const void*)) vec_dble_desc_compare); +} + +static inline long vec_dble_memory(vec_dble_t *p) +{ + return p == NULL ? 0 : sizeof(double) * p->cap + sizeof(vec_dble_t); +} + +static inline void vec_dble_print(vec_dble_t *p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %f", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_dble_h */ diff --git a/src/sat/satoko/utils/vec/vec_int.h b/src/sat/satoko/utils/vec/vec_int.h new file mode 100755 index 00000000..75c5d134 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_int.h @@ -0,0 +1,240 @@ +//===--- vec_int.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_int_h +#define satoko__utils__vec__vec_int_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_int_t_ vec_int_t; +struct vec_int_t_ { + unsigned cap; + unsigned size; + int *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_int_foreach(vec, entry, i) \ + for (i = 0; (i < vec->size) && (((entry) = vec_int_at(vec, i)), 1); i++) + +#define vec_int_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_int_size(vec)) && (((entry) = vec_int_at(vec, i)), 1); i++) + +#define vec_int_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_int_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_int_t *vec_int_alloc(unsigned cap) +{ + vec_int_t* p = satoko_alloc(vec_int_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(int, p->cap) : NULL; + return p; +} + +static inline vec_int_t *vec_int_alloc_exact(unsigned cap) +{ + vec_int_t* p = satoko_alloc(vec_int_t, 1); + + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(int, p->cap) : NULL; + return p; +} + +static inline vec_int_t *vec_int_init(unsigned size, int value) +{ + vec_int_t* p = satoko_alloc(vec_int_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(int, p->cap) : NULL; + memset(p->data, value, sizeof(int) * p->size); + return p; +} + +static inline void vec_int_free(vec_int_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_int_size(vec_int_t *p) +{ + return p->size; +} + +static inline void vec_int_resize(vec_int_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(int, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_int_reserve(vec_int_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(int, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_int_capacity(vec_int_t *p) +{ + return p->cap; +} + +static inline int vec_int_empty(vec_int_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_int_erase(vec_int_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline int vec_int_at(vec_int_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data[i]; +} + +static inline int *vec_int_at_ptr(vec_int_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data + i; +} + +static inline void vec_int_duplicate(vec_int_t *dest, const vec_int_t *src) +{ + assert(dest != NULL && src != NULL); + vec_int_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(int) * src->cap); + dest->size = src->size; +} + +static inline void vec_int_copy(vec_int_t *dest, const vec_int_t *src) +{ + assert(dest != NULL && src != NULL); + vec_int_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(int) * src->size); + dest->size = src->size; +} + +static inline void vec_int_push_back(vec_int_t *p, int value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_int_reserve(p, 16); + else + vec_int_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline void vec_int_assign(vec_int_t *p, unsigned i, int value) +{ + assert((i >= 0) && (i < vec_int_size(p))); + p->data[i] = value; +} + +static inline void vec_int_insert(vec_int_t *p, unsigned i, int value) +{ + assert((i >= 0) && (i < vec_int_size(p))); + vec_int_push_back(p, 0); + memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(int)); + p->data[i] = value; +} + +static inline void vec_int_drop(vec_int_t *p, unsigned i) +{ + assert((i >= 0) && (i < vec_int_size(p))); + memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(int)); + p->size -= 1; +} + +static inline void vec_int_clear(vec_int_t *p) +{ + p->size = 0; +} + +static inline int vec_int_asc_compare(const void *p1, const void *p2) +{ + const int *pp1 = (const int *) p1; + const int *pp2 = (const int *) p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_int_desc_compare(const void* p1, const void* p2) +{ + const int *pp1 = (const int *) p1; + const int *pp2 = (const int *) p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_int_sort(vec_int_t* p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(int), + (int (*)(const void*, const void*)) vec_int_asc_compare); + else + qsort((void *) p->data, p->size, sizeof(int), + (int (*)(const void*, const void*)) vec_int_desc_compare); +} + +static inline long vec_int_memory(vec_int_t *p) +{ + return p == NULL ? 0 : sizeof(int) * p->cap + sizeof(vec_int_t); +} + +static inline void vec_int_print(vec_int_t *p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %d", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_int_h */ diff --git a/src/sat/satoko/utils/vec/vec_uint.h b/src/sat/satoko/utils/vec/vec_uint.h new file mode 100755 index 00000000..e6719ca3 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_uint.h @@ -0,0 +1,268 @@ +//===--- vec_uint.h ---------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_uint_h +#define satoko__utils__vec__vec_uint_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_uint_t_ vec_uint_t; +struct vec_uint_t_ { + unsigned cap; + unsigned size; + unsigned* data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_uint_foreach(vec, entry, i) \ + for (i = 0; (i < vec_uint_size(vec)) && (((entry) = vec_uint_at(vec, i)), 1); i++) + +#define vec_uint_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_uint_size(vec)) && (((entry) = vec_uint_at(vec, i)), 1); i++) + +#define vec_uint_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_uint_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_uint_t * vec_uint_alloc(unsigned cap) +{ + vec_uint_t *p = satoko_alloc(vec_uint_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(unsigned, p->cap) : NULL; + return p; +} + +static inline vec_uint_t * vec_uint_alloc_exact(unsigned cap) +{ + vec_uint_t *p = satoko_alloc(vec_uint_t, 1); + + cap = 0; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(unsigned, p->cap ) : NULL; + return p; +} + +static inline vec_uint_t * vec_uint_init(unsigned size, unsigned value) +{ + vec_uint_t *p = satoko_alloc(vec_uint_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(unsigned, p->cap ) : NULL; + memset(p->data, value, sizeof(unsigned) * p->size); + return p; +} + +static inline void vec_uint_free(vec_uint_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_uint_size(vec_uint_t *p) +{ + return p->size; +} + +static inline void vec_uint_resize(vec_uint_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(unsigned, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_uint_shrink(vec_uint_t *p, unsigned new_size) +{ + assert(p->cap >= new_size); + p->size = new_size; +} + +static inline void vec_uint_reserve(vec_uint_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(unsigned, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_uint_capacity(vec_uint_t *p) +{ + return p->cap; +} + +static inline int vec_uint_empty(vec_uint_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_uint_erase(vec_uint_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline unsigned vec_uint_at(vec_uint_t *p, unsigned idx) +{ + assert(idx >= 0 && idx < p->size); + return p->data[idx]; +} + +static inline unsigned * vec_uint_at_ptr(vec_uint_t *p, unsigned idx) +{ + assert(idx >= 0 && idx < p->size); + return p->data + idx; +} + +static inline unsigned vec_uint_find(vec_uint_t *p, unsigned entry) +{ + unsigned i; + for (i = 0; i < p->size; i++) + if (p->data[i] == entry) + return 1; + return 0; +} + +static inline unsigned * vec_uint_data(vec_uint_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_uint_duplicate(vec_uint_t *dest, const vec_uint_t *src) +{ + assert(dest != NULL && src != NULL); + vec_uint_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(unsigned) * src->cap); + dest->size = src->size; +} + +static inline void vec_uint_copy(vec_uint_t *dest, const vec_uint_t *src) +{ + assert(dest != NULL && src != NULL); + vec_uint_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(unsigned) * src->size); + dest->size = src->size; +} + +static inline void vec_uint_push_back(vec_uint_t *p, unsigned value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_uint_reserve(p, 16); + else + vec_uint_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline unsigned vec_uint_pop_back(vec_uint_t *p) +{ + assert(p && p->size); + return p->data[--p->size]; +} + +static inline void vec_uint_assign(vec_uint_t *p, unsigned idx, unsigned value) +{ + assert((idx >= 0) && (idx < vec_uint_size(p))); + p->data[idx] = value; +} + +static inline void vec_uint_insert(vec_uint_t *p, unsigned idx, unsigned value) +{ + assert((idx >= 0) && (idx < vec_uint_size(p))); + vec_uint_push_back(p, 0); + memmove(p->data + idx + 1, p->data + idx, (p->size - idx - 2) * sizeof(unsigned)); + p->data[idx] = value; +} + +static inline void vec_uint_drop(vec_uint_t *p, unsigned idx) +{ + assert((idx >= 0) && (idx < vec_uint_size(p))); + memmove(p->data + idx, p->data + idx + 1, (p->size - idx - 1) * sizeof(unsigned)); + p->size -= 1; +} + +static inline void vec_uint_clear(vec_uint_t *p) +{ + p->size = 0; +} + +static inline int vec_uint_asc_compare(const void *p1, const void *p2) +{ + const unsigned *pp1 = (const unsigned *) p1; + const unsigned *pp2 = (const unsigned *) p2; + + if ( *pp1 < *pp2 ) + return -1; + if ( *pp1 > *pp2 ) + return 1; + return 0; +} + +static inline int vec_uint_desc_compare(const void *p1, const void *p2) +{ + const unsigned *pp1 = (const unsigned *) p1; + const unsigned *pp2 = (const unsigned *) p2; + + if ( *pp1 > *pp2 ) + return -1; + if ( *pp1 < *pp2 ) + return 1; + return 0; +} + +static inline void vec_uint_sort(vec_uint_t *p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(unsigned), + (int (*)(const void *, const void *)) vec_uint_asc_compare); + else + qsort((void*) p->data, p->size, sizeof(unsigned), + (int (*)(const void *, const void *)) vec_uint_desc_compare); +} + +static inline long vec_uint_memory(vec_uint_t *p) +{ + return p == NULL ? 0 : sizeof(unsigned) * p->cap + sizeof(vec_uint_t); +} + +static inline void vec_uint_print(vec_uint_t* p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %u", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_uint_h */ diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h new file mode 100644 index 00000000..f492904a --- /dev/null +++ b/src/sat/satoko/watch_list.h @@ -0,0 +1,152 @@ +//===--- watch_list.h -------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__watch_list_h +#define satoko__watch_list_h + +#include "utils/mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +struct watcher { + unsigned cref; + unsigned blocker; +}; + +struct watch_list { + unsigned cap; + unsigned size; + struct watcher *watchers; +}; + +typedef struct vec_wl_t_ vec_wl_t; +struct vec_wl_t_ { + unsigned cap; + unsigned size; + struct watch_list *watch_lists; +}; + +//===------------------------------------------------------------------------=== +// Watch list Macros +//===------------------------------------------------------------------------=== +#define watch_list_foreach(vec, watch, lit) \ + for (watch = watch_list_array(vec_wl_at(vec, lit)); \ + watch < watch_list_array(vec_wl_at(vec, lit)) + watch_list_size(vec_wl_at(vec, lit)); \ + watch++) + +//===------------------------------------------------------------------------=== +// Watch list API +//===------------------------------------------------------------------------=== +static inline void watch_list_free(struct watch_list *wl) +{ + if (wl->watchers) + satoko_free(wl->watchers); +} + +static inline unsigned watch_list_size(struct watch_list *wl) +{ + return wl->size; +} + +static inline void watch_list_shrink(struct watch_list *wl, unsigned size) +{ + assert(size <= wl->size); + wl->size = size; +} + +static inline void watch_list_push(struct watch_list *wl, struct watcher w) +{ + assert(wl); + if (wl->size == wl->cap) { + unsigned new_size = (wl->cap < 4) ? 4 : (wl->cap / 2) * 3; + struct watcher *watchers = + satoko_realloc(struct watcher, wl->watchers, new_size); + if (watchers == NULL) { + printf("Failed to realloc memory from %.1f MB to %.1f " + "MB.\n", + 1.0 * wl->cap / (1 << 20), + 1.0 * new_size / (1 << 20)); + fflush(stdout); + return; + } + wl->watchers = watchers; + wl->cap = new_size; + } + wl->watchers[wl->size++] = w; +} + +static inline struct watcher *watch_list_array(struct watch_list *wl) +{ + return wl->watchers; +} + +static inline void watch_list_remove(struct watch_list *wl, unsigned cref) +{ + struct watcher *watchers = watch_list_array(wl); + unsigned i; + for (i = 0; watchers[i].cref != cref; i++); + assert(i < watch_list_size(wl)); + memmove((wl->watchers + i), (wl->watchers + i + 1), + (wl->size - i - 1) * sizeof(struct watcher)); + wl->size -= 1; +} + +static inline vec_wl_t *vec_wl_alloc(unsigned cap) +{ + vec_wl_t *vec_wl = satoko_alloc(vec_wl_t, 1); + + if (cap == 0) + vec_wl->cap = 4; + else + vec_wl->cap = cap; + vec_wl->size = 0; + vec_wl->watch_lists = satoko_calloc( + struct watch_list, sizeof(struct watch_list) * vec_wl->cap); + return vec_wl; +} + +static inline void vec_wl_free(vec_wl_t *vec_wl) +{ + for (unsigned i = 0; i < vec_wl->size; i++) + watch_list_free(vec_wl->watch_lists + i); + satoko_free(vec_wl->watch_lists); + satoko_free(vec_wl); +} + +static inline void vec_wl_push(vec_wl_t *vec_wl) +{ + if (vec_wl->size == vec_wl->cap) { + unsigned new_size = + (vec_wl->cap < 4) ? vec_wl->cap * 2 : (vec_wl->cap / 2) * 3; + + vec_wl->watch_lists = satoko_realloc( + struct watch_list, vec_wl->watch_lists, new_size); + memset(vec_wl->watch_lists + vec_wl->cap, 0, + sizeof(struct watch_list) * (new_size - vec_wl->cap)); + if (vec_wl->watch_lists == NULL) { + printf("failed to realloc memory from %.1f mb to %.1f " + "mb.\n", + 1.0 * vec_wl->cap / (1 << 20), + 1.0 * new_size / (1 << 20)); + fflush(stdout); + } + vec_wl->cap = new_size; + } + vec_wl->size++; +} + +static inline struct watch_list *vec_wl_at(vec_wl_t *vec_wl, unsigned idx) +{ + assert(idx < vec_wl->cap); + assert(idx < vec_wl->size); + return vec_wl->watch_lists + idx; +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__watch_list_h */ -- cgit v1.2.3 From 495a34e3ce1a0a0ac664748c991be437dd1c7ea7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 18:53:35 -0800 Subject: Fixing compilation problem in 'dsc' package. --- src/opt/dsc/dsc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/opt/dsc/dsc.c b/src/opt/dsc/dsc.c index ce180fe3..7ddeeed9 100644 --- a/src/opt/dsc/dsc.c +++ b/src/opt/dsc/dsc.c @@ -51,14 +51,14 @@ struct Dsc_node_t_ /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -inline void xorInPlace( word * pOut, word * pIn2, int nWords) +static inline void xorInPlace( word * pOut, word * pIn2, int nWords) { int w; for ( w = 0; w < nWords; w++ ) pOut[w] ^= pIn2[w]; } -void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) { +static inline void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) { int i; printf("Node:\t%s\n",pNode->exp); printf("\tneg cof:\t");Abc_TtPrintHexRev(stdout, pNode->pNegCof, nVars); @@ -75,7 +75,7 @@ void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) { printf("\n"); } -inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) { +static inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) { if (Abc_TtEqual(ni->pNegCof, nj->pNegCof, TRUTH_WORDS)) {*ci=1; *cj=1; return 1;} else if (Abc_TtEqual(ni->pNegCof, nj->pPosCof, TRUTH_WORDS)) {*ci=1; *cj=0; return 1;} else if (Abc_TtEqual(ni->pPosCof, nj->pNegCof, TRUTH_WORDS)) {*ci=0; *cj=1; return 1;} @@ -83,11 +83,11 @@ inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, i return 0; } -inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) { +static inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) { return Abc_TtEqual(ni->pBoolDiff, nj->pBoolDiff, TRUTH_WORDS); } -void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) { +static inline void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) { *target++ = begin; //s1 if (!s1Polarity) @@ -104,7 +104,7 @@ void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* *target = '\0'; } -void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) { +static inline void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) { int size = cubeCof[0]; int i; for (i = 1; i <= size; i++) { @@ -117,7 +117,7 @@ void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const } } -void merge(unsigned int * const pOut, const unsigned int * const pIn) { +static inline void merge(unsigned int * const pOut, const unsigned int * const pIn) { const int elementsToCopy = pIn[0]; int i, j; for (i = pOut[0]+1, j = 1; j <= elementsToCopy; i++, j++) { -- cgit v1.2.3 From 0fb4442a8208ccc36067db034c12a840095c0911 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 6 Feb 2017 19:50:57 -0800 Subject: Small changes to support old compilers. --- src/base/abci/abc.c | 2 +- src/sat/satoko/satoko.h | 4 ++-- src/sat/satoko/solver.c | 4 ++-- src/sat/satoko/solver.h | 36 ++++++++++++++++++------------------ src/sat/satoko/solver_api.c | 12 ++++++------ src/sat/satoko/utils/b_queue.h | 4 ++-- src/sat/satoko/utils/misc.h | 2 -- src/sat/satoko/utils/vec/vec_char.h | 3 ++- src/sat/satoko/watch_list.h | 3 ++- 9 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index efb82fcc..65974acb 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23357,7 +23357,7 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) int status; satoko_parse_dimacs( pFileName, &p ); - satoko_configure(p, &opts); + satoko_configure(p, &opts); clk = Abc_Clock(); status = satoko_solve( p ); diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 49c7837e..55790714 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -30,8 +30,8 @@ typedef struct solver_t_ satoko_t; typedef struct satoko_opts satoko_opts_t; struct satoko_opts { /* Limits */ - long long conf_limit; /* Limit on the n.of conflicts */ - long long prop_limit; /* Limit on the n.of implications */ + long conf_limit; /* Limit on the n.of conflicts */ + long prop_limit; /* Limit on the n.of implications */ /* Constants used for restart heuristic */ double f_rst; /* Used to force a restart */ diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index b2861bad..8c06bbe8 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -325,14 +325,14 @@ static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt static inline int solver_rst(solver_t *s) { return b_queue_is_valid(s->bq_lbd) && - (((long long)b_queue_avg(s->bq_lbd) * s->opts.f_rst) > (s->sum_lbd / s->stats.n_conflicts)); + (((long)b_queue_avg(s->bq_lbd) * s->opts.f_rst) > (s->sum_lbd / s->stats.n_conflicts)); } static inline int solver_block_rst(solver_t *s) { return s->stats.n_conflicts > s->opts.fst_block_rst && b_queue_is_valid(s->bq_lbd) && - (vec_uint_size(s->trail) > (s->opts.b_rst * (long long)b_queue_avg(s->bq_trail))); + ((long)vec_uint_size(s->trail) > (s->opts.b_rst * (long)b_queue_avg(s->bq_trail))); } static inline void solver_handle_conflict(solver_t *s, unsigned confl_cref) diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 65b86c68..fe1d1ef5 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -42,13 +42,13 @@ struct satoko_stats { unsigned n_starts; unsigned n_reduce_db; - long long n_decisions; - long long n_propagations; - long long n_inspects; - long long n_conflicts; + long n_decisions; + long n_propagations; + long n_inspects; + long n_conflicts; - long long n_original_lits; - long long n_learnt_lits; + long n_original_lits; + long n_learnt_lits; }; typedef struct solver_t_ solver_t; @@ -82,17 +82,9 @@ struct solver_t_ { unsigned i_qhead; /* Head of propagation queue (as index into the trail). */ unsigned n_assigns_simplify; /* Number of top-level assignments since last execution of 'simplify()'. */ - long long n_props_simplify; /* Remaining number of propagations that - must be made before next execution of - 'simplify()'. */ - - /* Temporary data used by Search method */ - b_queue_t *bq_trail; - b_queue_t *bq_lbd; - long RC1; - long RC2; - unsigned n_confl_bfr_reduce; - float sum_lbd; + long n_props_simplify; /* Remaining number of propagations that + must be made before next execution of + 'simplify()'. */ /* Temporary data used by Analyze */ vec_uint_t *temp_lits; @@ -101,10 +93,18 @@ struct solver_t_ { vec_uint_t *stack; vec_uint_t *last_dlevel; + /* Temporary data used by Search method */ + b_queue_t *bq_trail; + b_queue_t *bq_lbd; + long RC1; + long RC2; + long n_confl_bfr_reduce; + float sum_lbd; + /* Misc temporary */ + unsigned cur_stamp; /* Used for marking literals and levels of interest */ vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and * clauses minimization with binary resolution */ - unsigned cur_stamp; /* Used for marking literals and levels of interest */ struct satoko_stats stats; struct satoko_opts opts; diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index db9a267b..e041cc62 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -68,9 +68,9 @@ static inline void print_opts(solver_t *s) static inline void print_stats(solver_t *s) { printf("starts : %10d\n", s->stats.n_starts); - printf("conflicts : %10lld\n", s->stats.n_conflicts); - printf("decisions : %10lld\n", s->stats.n_decisions); - printf("propagations : %10lld\n", s->stats.n_propagations); + printf("conflicts : %10ld\n", s->stats.n_conflicts); + printf("decisions : %10ld\n", s->stats.n_decisions); + printf("propagations : %10ld\n", s->stats.n_propagations); } //===------------------------------------------------------------------------=== @@ -166,13 +166,13 @@ void satoko_default_opts(satoko_opts_t *opts) opts->inc_special_reduce = 1000; opts->lbd_freeze_clause = 30; /* VSIDS heuristic */ - opts->var_decay = 0.95; - opts->clause_decay = 0.995; + opts->var_decay = (act_t) 0.95; + opts->clause_decay = (clause_act_t) 0.995; /* Binary resolution */ opts->clause_max_sz_bin_resol = 30; opts->clause_min_lbd_bin_resol = 6; - opts->garbage_max_ratio = 0.3; + opts->garbage_max_ratio = (float) 0.3; } /** diff --git a/src/sat/satoko/utils/b_queue.h b/src/sat/satoko/utils/b_queue.h index 926edf29..b9b62676 100644 --- a/src/sat/satoko/utils/b_queue.h +++ b/src/sat/satoko/utils/b_queue.h @@ -21,7 +21,7 @@ struct b_queue_t_ { unsigned cap; unsigned i_first; unsigned i_empty; - unsigned long long sum; + unsigned long sum; unsigned *data; }; @@ -61,7 +61,7 @@ static inline void b_queue_push(b_queue_t *p, unsigned Value) static inline unsigned b_queue_avg(b_queue_t *p) { - return (unsigned)(p->sum / ((unsigned long long) p->size)); + return (unsigned)(p->sum / ((unsigned long) p->size)); } static inline unsigned b_queue_is_valid(b_queue_t *p) diff --git a/src/sat/satoko/utils/misc.h b/src/sat/satoko/utils/misc.h index aa8bcb8c..481e23b7 100755 --- a/src/sat/satoko/utils/misc.h +++ b/src/sat/satoko/utils/misc.h @@ -9,8 +9,6 @@ #ifndef satoko__utils__misc_h #define satoko__utils__misc_h -#include - #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START diff --git a/src/sat/satoko/utils/vec/vec_char.h b/src/sat/satoko/utils/vec/vec_char.h index fe88797a..7d5732ec 100644 --- a/src/sat/satoko/utils/vec/vec_char.h +++ b/src/sat/satoko/utils/vec/vec_char.h @@ -248,9 +248,10 @@ static inline long vec_char_memory(vec_char_t *p) static inline void vec_char_print(vec_char_t* p) { + unsigned i; assert(p != NULL); fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); - for (unsigned i = 0; i < p->size; i++) + for (i = 0; i < p->size; i++) fprintf(stdout, " %d", p->data[i]); fprintf(stdout, " }\n"); } diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index f492904a..ef1c1a07 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -113,7 +113,8 @@ static inline vec_wl_t *vec_wl_alloc(unsigned cap) static inline void vec_wl_free(vec_wl_t *vec_wl) { - for (unsigned i = 0; i < vec_wl->size; i++) + unsigned i; + for (i = 0; i < vec_wl->size; i++) watch_list_free(vec_wl->watch_lists + i); satoko_free(vec_wl->watch_lists); satoko_free(vec_wl); -- cgit v1.2.3 From 542f84d2fb059a0779ee1878ee3c1cc2fdbad2df Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 20:54:41 -0800 Subject: Small changes to compile satoko on Windows. --- src/sat/satoko/act_clause.h | 4 ++-- src/sat/satoko/cnf_reader.c | 2 +- src/sat/satoko/solver.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h index 5a2fda2b..2e80a1e6 100644 --- a/src/sat/satoko/act_clause.h +++ b/src/sat/satoko/act_clause.h @@ -26,9 +26,9 @@ static inline void clause_act_rescale(solver_t *s) vec_uint_foreach(s->learnts, cref, i) { clause = clause_read(s, cref); - clause->data[clause->size].act *= 1e-20; + clause->data[clause->size].act *= (float)1e-20; } - s->clause_act_inc *= 1e-20; + s->clause_act_inc *= (float)1e-20; } /** Increment the activity value of one clause ('clause') diff --git a/src/sat/satoko/cnf_reader.c b/src/sat/satoko/cnf_reader.c index 5e4b92f9..9fbbda65 100644 --- a/src/sat/satoko/cnf_reader.c +++ b/src/sat/satoko/cnf_reader.c @@ -97,7 +97,7 @@ static void read_clause(char **token, vec_uint_t *lits) break; sign = (var > 0); var = abs(var) - 1; - vec_uint_push_back(lits, var2lit((unsigned) var, !sign)); + vec_uint_push_back(lits, var2lit((unsigned) var, (char)!sign)); } } diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 8c06bbe8..a4114e54 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -330,7 +330,7 @@ static inline int solver_rst(solver_t *s) static inline int solver_block_rst(solver_t *s) { - return s->stats.n_conflicts > s->opts.fst_block_rst && + return s->stats.n_conflicts > (int)s->opts.fst_block_rst && b_queue_is_valid(s->bq_lbd) && ((long)vec_uint_size(s->trail) > (s->opts.b_rst * (long)b_queue_avg(s->bq_trail))); } -- cgit v1.2.3 From 44dbf992a7e32f3e09a789b95222a18ed54f8f5b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 23:28:00 -0800 Subject: Re-introducing floating-point activity in the SAT solver. --- src/sat/bsat/satSolver.c | 174 ++++++++++++++++++++++++++++++++++++----------- src/sat/bsat/satSolver.h | 36 ++++++++++ 2 files changed, 171 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 3295fc6f..73d0cf36 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -145,12 +145,22 @@ static inline void order_update(sat_solver* s, int v) // updateorder assert(s->orderpos[v] != -1); +#ifdef USE_FLOAT_ACTIVITY_NEW + while (i != 0 && xSat_LessThan(s->activity[heap[parent]], s->activity[x]) ){ + heap[i] = heap[parent]; + orderpos[heap[i]] = i; + i = parent; + parent = (i - 1) / 2; + } +#else while (i != 0 && s->activity[x] > s->activity[heap[parent]]){ heap[i] = heap[parent]; orderpos[heap[i]] = i; i = parent; parent = (i - 1) / 2; } +#endif + heap[i] = x; orderpos[x] = i; } @@ -192,11 +202,21 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv int i = 0; int child = 1; while (child < size){ + +#ifdef USE_FLOAT_ACTIVITY_NEW + if (child+1 < size && xSat_LessThan(s->activity[heap[child]], s->activity[heap[child+1]]) ) + child++; + assert(child < size); + if ( !xSat_LessThan(s->activity[x], s->activity[heap[child]]) ) + break; +#else if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]]) child++; assert(child < size); if (s->activity[x] >= s->activity[heap[child]]) break; +#endif + heap[i] = heap[child]; orderpos[heap[i]] = i; i = child; @@ -213,6 +233,7 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars) { +#ifndef USE_FLOAT_ACTIVITY_NEW int i; for (i = 0; i < s->size; i++) s->activity[i] = 0; @@ -223,6 +244,7 @@ void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars) s->activity[iVar] = nVars-i; order_update( s, iVar ); } +#endif } //================================================================================================= @@ -230,6 +252,46 @@ void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars) #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + +static inline void act_var_rescale(sat_solver* s) { + xFloat_t * activity = s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] = xSat_FloatDiv( activity[i], 1<<10 ); // activity[i] / 2^1024 + s->var_inc = xSat_FloatDiv( s->var_inc, 1<<10 ); +} +static inline void act_clause_rescale(sat_solver* s) { + xFloat_t* activity = (xFloat_t *)veci_begin(&s->act_clas); + int i; + for (i = 0; i < veci_size(&s->act_clas); i++) + activity[i] = xSat_FloatDiv( activity[i], 1<<10 ); // activity[i] / 2^1024 + s->cla_inc = xSat_FloatDiv( s->cla_inc, 1<<10 ); +} +static inline void act_var_bump(sat_solver* s, int v) { + s->activity[v] = xSat_FloatAdd( s->activity[v], s->var_inc ); + if ( xSat_LessThan(xSat_FloatCreate(1 << 12, 1 << 15), s->activity[v]) ) // 2^4096 < s->activity[v] + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); +} +static inline void act_var_bump_global(sat_solver* s, int v) { + assert(0); +} +static inline void act_var_bump_factor(sat_solver* s, int v) { + assert(0); +} +static inline void act_clause_bump(sat_solver* s, clause *c) { + xFloat_t* act = (xFloat_t *)veci_begin(&s->act_clas) + c->lits[c->size]; + *act = xSat_FloatAdd( *act, s->cla_inc ); + if ( xSat_LessThan(xSat_FloatCreate(1 << 12, 1 << 15), *act) ) // 2^4096 < *act + act_clause_rescale(s); +} +static inline void act_var_decay(sat_solver* s) { s->var_inc = xSat_FloatMul(s->var_inc, s->var_decay); } +static inline void act_clause_decay(sat_solver* s) { s->cla_inc = xSat_FloatMul(s->cla_inc, s->cla_decay); } + +#else + static inline void act_var_rescale(sat_solver* s) { double* activity = s->activity; int i; @@ -238,18 +300,11 @@ static inline void act_var_rescale(sat_solver* s) { s->var_inc *= 1e-100; } static inline void act_clause_rescale(sat_solver* s) { -// static abctime Total = 0; - clause** cs = (clause**)veci_begin(&s->learnts); - int i;//, clk = Abc_Clock(); - for (i = 0; i < veci_size(&s->learnts); i++){ - float a = clause_activity(cs[i]); - clause_setactivity(cs[i], a * (float)1e-20); - } + float* activity = (float *)veci_begin(&s->act_clas); + int i; + for (i = 0; i < veci_size(&s->act_clas); i++) + activity[i] *= (float)1e-20; s->cla_inc *= (float)1e-20; - - Total += Abc_Clock() - clk; -// printf( "Rescaling... Cla inc = %10.3f Conf = %10d ", s->cla_inc, s->stats.conflicts ); -// Abc_PrintTime( 1, "Time", Total ); } static inline void act_var_bump(sat_solver* s, int v) { s->activity[v] += s->var_inc; @@ -259,31 +314,22 @@ static inline void act_var_bump(sat_solver* s, int v) { order_update(s,v); } static inline void act_var_bump_global(sat_solver* s, int v) { - if ( !s->pGlobalVars ) - return; - s->activity[v] += (s->var_inc * 3.0 * s->pGlobalVars[v]); - if (s->activity[v] > 1e100) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); + assert(0); } static inline void act_var_bump_factor(sat_solver* s, int v) { - if ( !s->factors ) - return; - s->activity[v] += (s->var_inc * s->factors[v]); - if (s->activity[v] > 1e100) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); + assert(0); } static inline void act_clause_bump(sat_solver* s, clause *c) { - float a = clause_activity(c) + s->cla_inc; - clause_setactivity(c,a); - if (a > 1e20) act_clause_rescale(s); + float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size]; + *act += s->cla_inc; + if (*act > 1e20) + act_clause_rescale(s); } static inline void act_var_decay(sat_solver* s) { s->var_inc *= s->var_decay; } static inline void act_clause_decay(sat_solver* s) { s->cla_inc *= s->cla_decay; } +#endif + #else static inline void act_var_rescale(sat_solver* s) { @@ -296,17 +342,12 @@ static inline void act_var_rescale(sat_solver* s) { } static inline void act_clause_rescale(sat_solver* s) { - static abctime Total = 0; - abctime clk = Abc_Clock(); unsigned* activity = (unsigned *)veci_begin(&s->act_clas); int i; for (i = 0; i < veci_size(&s->act_clas); i++) activity[i] >>= 14; s->cla_inc >>= 14; s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) ); - Total += Abc_Clock() - clk; -// printf( "Rescaling... Cla inc = %5d Conf = %10d ", s->cla_inc, s->stats.conflicts ); -// Abc_PrintTime( 1, "Time", Total ); } static inline void act_var_bump(sat_solver* s, int v) { @@ -447,7 +488,15 @@ int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt) assert( clause_id(c) == veci_size(&s->act_clas) ); // veci_push(&s->learned, h); // act_clause_bump(s,clause_read(s, h)); +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + veci_push(&s->act_clas, xSat_Float2Uint(xSat_FloatCreateConst1())); +#else + veci_push(&s->act_clas, 0); +#endif +#else veci_push(&s->act_clas, (1<<10)); +#endif s->stats.learnts++; s->stats.learnts_literals += size; } @@ -1055,10 +1104,17 @@ sat_solver* sat_solver_new(void) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; s->var_decay = (float)(1 / 0.95 ); s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); @@ -1126,10 +1182,17 @@ sat_solver* zsat_solver_new_seed(double seed) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; s->var_decay = (float)(1 / 0.95 ); s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); @@ -1174,7 +1237,11 @@ void sat_solver_setnvars(sat_solver* s,int n) s->tags = ABC_REALLOC(char, s->tags, s->cap); s->loads = ABC_REALLOC(char, s->loads, s->cap); #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->activity = ABC_REALLOC(xFloat_t, s->activity, s->cap); +#else s->activity = ABC_REALLOC(double, s->activity, s->cap); +#endif #else s->activity = ABC_REALLOC(unsigned, s->activity, s->cap); s->activity2 = ABC_REALLOC(unsigned, s->activity2,s->cap); @@ -1198,7 +1265,11 @@ void sat_solver_setnvars(sat_solver* s,int n) if ( s->wlists[2*var+1].ptr == NULL ) veci_new(&s->wlists[2*var+1]); #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->activity[var] = xSat_FloatCreateConst1(); +#else s->activity[var] = 0; +#endif #else s->activity[var] = (1<<10); #endif @@ -1292,10 +1363,17 @@ void sat_solver_restart( sat_solver* s ) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999 ); + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); @@ -1341,10 +1419,17 @@ void zsat_solver_restart_seed( sat_solver* s, double seed ) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999 ); + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); @@ -1382,7 +1467,11 @@ double sat_solver_memory( sat_solver* s ) Mem += s->cap * sizeof(char); // ABC_FREE(s->tags ); Mem += s->cap * sizeof(char); // ABC_FREE(s->loads ); #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + Mem += s->cap * sizeof(xFloat_t); // ABC_FREE(s->activity ); +#else Mem += s->cap * sizeof(double); // ABC_FREE(s->activity ); +#endif #else Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity ); if ( s->activity2 ) @@ -1600,10 +1689,17 @@ void sat_solver_rollback( sat_solver* s ) s->qhead = 0; s->qtail = 0; #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc = xSat_FloatCreateConst1(); + s->cla_inc = xSat_FloatCreateConst1(); + s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); + s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); +#else s->var_inc = 1; s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999 ); + s->var_decay = (float)(1 / 0.95 ); + s->cla_decay = (float)(1 / 0.999); +#endif #else s->var_inc = (1 << 5); s->cla_inc = (1 << 11); diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 6ed611e1..226d8c7a 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -30,10 +30,12 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "satVec.h" #include "satClause.h" +#include "sat/xsat/xsatFloat.h" ABC_NAMESPACE_HEADER_START //#define USE_FLOAT_ACTIVITY +//#define USE_FLOAT_ACTIVITY_NEW //================================================================================================= // Public interface: @@ -117,11 +119,23 @@ struct sat_solver_t // activities #ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + xFloat_t var_inc; // Amount to bump next variable with. + xFloat_t var_inc2; // Amount to bump next variable with. + xFloat_t var_decay; // INVERSE decay factor for variable activity: stores 1/decay. + xFloat_t cla_inc; // Amount to bump next clause with. + xFloat_t cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. + xFloat_t* activity; // A heuristic measurement of the activity of a variable. + xFloat_t* activity2; // backup variable activity +#else double var_inc; // Amount to bump next variable with. + double var_inc2; // Amount to bump next variable with. double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. float cla_inc; // Amount to bump next clause with. float cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. double* activity; // A heuristic measurement of the activity of a variable. + double* activity2; // A heuristic measurement of the activity of a variable. +#endif #else int var_inc; // Amount to bump next variable with. int var_inc2; // Amount to bump next variable with. @@ -218,9 +232,21 @@ static int sat_solver_var_literal( sat_solver* s, int v ) static void sat_solver_act_var_clear(sat_solver* s) { int i; +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + for (i = 0; i < s->size; i++) + s->activity[i] = xSat_FloatCreateConst1(); + s->var_inc = xSat_FloatCreateConst1(); +#else for (i = 0; i < s->size; i++) s->activity[i] = 0; s->var_inc = 1; +#endif +#else + for (i = 0; i < s->size; i++) + s->activity[i] = 0; + s->var_inc = (1 << 5); +#endif } static void sat_solver_compress(sat_solver* s) { @@ -286,8 +312,18 @@ static inline void sat_solver_bookmark(sat_solver* s) Sat_MemBookMark( &s->Mem ); if ( s->activity2 ) { +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + s->var_inc2 = s->var_inc; + memcpy( s->activity2, s->activity, sizeof(xFloat_t) * s->iVarPivot ); +#else + s->var_inc2 = s->var_inc; + memcpy( s->activity2, s->activity, sizeof(double) * s->iVarPivot ); +#endif +#else s->var_inc2 = s->var_inc; memcpy( s->activity2, s->activity, sizeof(unsigned) * s->iVarPivot ); +#endif } } static inline void sat_solver_set_pivot_variables( sat_solver* s, int * pPivots, int nPivots ) -- cgit v1.2.3 From 80f5070dbe270f7b1e90df07c5f52c46f0c0c969 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 7 Feb 2017 02:05:03 -0800 Subject: Re-introducing floating-point activity in the SAT solver. --- src/sat/bsat/satSolver.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 73d0cf36..1a2a393d 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -492,7 +492,7 @@ int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt) #ifdef USE_FLOAT_ACTIVITY_NEW veci_push(&s->act_clas, xSat_Float2Uint(xSat_FloatCreateConst1())); #else - veci_push(&s->act_clas, 0); + veci_push(&s->act_clas, s->cla_inc); #endif #else veci_push(&s->act_clas, (1<<10)); @@ -1532,8 +1532,16 @@ void sat_solver_reducedb(sat_solver* s) Sat_MemForEachLearned( pMem, c, i, k ) { Id = clause_id(c); - pSortValues[Id] = (((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4)); // pSortValues[Id] = act[Id]; +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); +#else + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4); +#endif +#else + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); +#endif assert( pSortValues[Id] >= 0 ); } @@ -1639,7 +1647,15 @@ void sat_solver_rollback( sat_solver* s ) if ( s->activity2 ) { s->var_inc = s->var_inc2; +#ifdef USE_FLOAT_ACTIVITY +#ifdef USE_FLOAT_ACTIVITY_NEW + memcpy( s->activity, s->activity2, sizeof(xFloat_t) * s->iVarPivot ); +#else + memcpy( s->activity, s->activity2, sizeof(double) * s->iVarPivot ); +#endif +#else memcpy( s->activity, s->activity2, sizeof(unsigned) * s->iVarPivot ); +#endif } veci_resize(&s->order, 0); for ( i = 0; i < s->iVarPivot; i++ ) -- cgit v1.2.3 From de4bf41c53665ca8389d74b15be24ab407e8ff65 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 14:10:08 -0800 Subject: New command &satoko. --- src/aig/gia/giaSatoko.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 1 + src/base/abci/abc.c | 73 +++++++++++++++++++++++++++- src/base/wlc/wlcShow.c | 4 +- 4 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 src/aig/gia/giaSatoko.c (limited to 'src') diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c new file mode 100644 index 00000000..62bc7713 --- /dev/null +++ b/src/aig/gia/giaSatoko.c @@ -0,0 +1,126 @@ +/**CFile**************************************************************** + + FileName [giaSatoko.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Interface to Satoko solver.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSatoko.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "sat/cnf/cnf.h" +#include "sat/satoko/satoko.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) +{ + satoko_t * pSat = satoko_create(); + Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 1, 0 ); + int i, status; + //sat_solver_setnvars( pSat, p->nVars ); + for ( i = 0; i < pCnf->nClauses; i++ ) + { + if ( !satoko_add_clause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) + { + Cnf_DataFree( pCnf ); + satoko_destroy( pSat ); + return NULL; + } + } + Cnf_DataFree( pCnf ); + status = satoko_simplify(pSat); + if ( status == SATOKO_OK ) + return pSat; + satoko_destroy( pSat ); + return NULL; +} +void Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) +{ + abctime clk = Abc_Clock(); + satoko_t * pSat; + int status; + + pSat = Gia_ManCreateSatoko( p ); + if ( pSat ) + { + satoko_configure(pSat, opts); + status = satoko_solve( pSat ); + satoko_destroy( pSat ); + } + else + status = SATOKO_UNSAT; + + if ( iOutput >= 0 ) + Abc_Print( 1, "Output %6d : ", iOutput ); + else + Abc_Print( 1, "Total: " ); + + if ( status == SATOKO_UNDEC ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == SATOKO_SAT ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} +void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ) +{ + if ( fSplit ) + { + Gia_Man_t * pOne; + Gia_Obj_t * pRoot; + int i; + Gia_ManForEachCo( p, pRoot, i ) + { + pOne = Gia_ManDupDfsCone( p, pRoot ); + Gia_ManCallSatokoOne( pOne, opts, i ); + Gia_ManStop( pOne ); + } + return; + } + Gia_ManCallSatokoOne( p, opts, -1 ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 0066bfd2..0ddf9833 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -59,6 +59,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaSatLE.c \ src/aig/gia/giaSatLut.c \ src/aig/gia/giaSatMap.c \ + src/aig/gia/giaSatoko.c \ src/aig/gia/giaScl.c \ src/aig/gia/giaScript.c \ src/aig/gia/giaShow.c \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 65974acb..1ecc5e68 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -310,6 +310,7 @@ static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Satoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -959,6 +960,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "&satoko", Abc_CommandAbc9Satoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -23356,11 +23358,12 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) satoko_t * p; int status; - satoko_parse_dimacs( pFileName, &p ); + status = satoko_parse_dimacs( pFileName, &p ); satoko_configure(p, &opts); clk = Abc_Clock(); - status = satoko_solve( p ); + if ( status == SATOKO_OK ) + status = satoko_solve( p ); if ( status == SATOKO_UNDEC ) Abc_Print( 1, "UNDECIDED " ); @@ -23382,6 +23385,72 @@ usage: Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ); + int c, fSplit = 0; + + satoko_opts_t opts; + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Csvh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + goto usage; + break; + case 's': + fSplit ^= 1; + break; + case 'v': + opts.verbose ^= 1; + break; + case 'h': + goto usage; + + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" ); + return 1; + } + Gia_ManCallSatoko( pAbc->pGia, &opts, fSplit ); + return 0; + +usage: + Abc_Print( -2, "usage: &satoko [-C num] [-svh]\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\t-s : split multi-output miter into individual outputs [default = %s]\n", fSplit? "yes": "no" ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index 7914cd7a..1601d602 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -49,9 +49,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_Obj_t * pNode; int LevelMax, Prev, Level, i; - if ( Wlc_NtkObjNum(p) > 1000 ) + if ( Wlc_NtkObjNum(p) > 2000 ) { - fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 1000 ); + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 2000 ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) -- cgit v1.2.3 From cf24a0eb0c630e19bf1d81622fc05327371c63cf Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 14:12:49 -0800 Subject: Compiler warning. --- src/aig/gia/giaSatoko.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index 62bc7713..5506c7e4 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -54,7 +54,7 @@ satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) //sat_solver_setnvars( pSat, p->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) { - if ( !satoko_add_clause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) + if ( !satoko_add_clause( pSat, (unsigned *)pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) { Cnf_DataFree( pCnf ); satoko_destroy( pSat ); -- cgit v1.2.3 From 77e2b1ff53bd806a681c9a887cd5b026681d271b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 18:57:16 -0800 Subject: Autotuner for 'satoko'. --- src/aig/gia/giaSatoko.c | 8 +- src/base/abci/abc.c | 27 ++- src/base/cmd/cmd.c | 114 +++++++++ src/base/cmd/cmdAuto.c | 522 +++++++++++++++++++++++++++++++++++++++++ src/base/cmd/module.make | 1 + src/misc/extra/extraUtilUtil.c | 54 +++-- 6 files changed, 698 insertions(+), 28 deletions(-) create mode 100644 src/base/cmd/cmdAuto.c (limited to 'src') diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index 5506c7e4..fc8e5c28 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -21,6 +21,7 @@ #include "gia.h" #include "sat/cnf/cnf.h" #include "sat/satoko/satoko.h" +#include "sat/satoko/solver.h" ABC_NAMESPACE_IMPL_START @@ -68,17 +69,19 @@ satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) satoko_destroy( pSat ); return NULL; } -void Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) +int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) { abctime clk = Abc_Clock(); satoko_t * pSat; - int status; + int status, Cost = 0; + pSat = Gia_ManCreateSatoko( p ); if ( pSat ) { satoko_configure(pSat, opts); status = satoko_solve( pSat ); + Cost = (unsigned)pSat->stats.n_conflicts; satoko_destroy( pSat ); } else @@ -97,6 +100,7 @@ void Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) Abc_Print( 1, "UNSATISFIABLE " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return Cost; } void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ) { diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1ecc5e68..38a555d8 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -16782,7 +16782,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) If_ManSetDefaultPars( pPars ); pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "K:CFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) { switch ( c ) { @@ -38135,9 +38135,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; Vec_Int_t * vPos; - int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fVerbose = 0; + int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWavh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaevh" ) ) != EOF ) { switch ( c ) { @@ -38199,6 +38199,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'a': fUseAllCis ^= 1; break; + case 'e': + fExtractAll ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -38213,6 +38216,21 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Cone(): There is no AIG.\n" ); return 1; } + if ( fExtractAll ) + { + char Buffer[1000]; + Gia_Obj_t * pObj; + int i, nDigits = Abc_Base10Log(Gia_ManPoNum(pAbc->pGia)); + Gia_ManForEachPo( pAbc->pGia, pObj, i ) + { + Gia_Man_t * pOne = Gia_ManDupDfsCone( pAbc->pGia, pObj ); + sprintf( Buffer, "%s_%0*d.aig", Extra_FileNameGeneric(pAbc->pGia->pSpec), nDigits, i ); + Gia_AigerWrite( pOne, Buffer, 0, 0 ); + Gia_ManStop( pOne ); + } + printf( "Dumped all outputs into individual AIGER files.\n" ); + return 0; + } if ( nLevelMax || nTimeWindow ) { if ( nLevelMax && nTimeWindow ) @@ -38260,7 +38278,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &cone [-ORPLW num] [-avh]\n" ); + Abc_Print( -2, "usage: &cone [-ORPLW num] [-aevh]\n" ); Abc_Print( -2, "\t extracting multi-output sequential logic cones\n" ); Abc_Print( -2, "\t-O num : the index of first PO to extract [default = %d]\n", iOutNum ); Abc_Print( -2, "\t-R num : (optional) the number of outputs to extract [default = %d]\n", nOutRange ); @@ -38268,6 +38286,7 @@ usage: Abc_Print( -2, "\t-L num : (optional) extract cones with higher level [default = %d]\n", nLevelMax ); Abc_Print( -2, "\t-W num : (optional) extract cones falling into this window [default = %d]\n", nTimeWindow ); Abc_Print( -2, "\t-a : toggle keeping all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" ); + Abc_Print( -2, "\t-e : toggle writing all outputs into individual files [default = %s]\n", fExtractAll? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index ab037139..ec4a0c86 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -60,6 +60,7 @@ static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int CmdCommandStarter ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int CmdCommandAutoTuner ( Abc_Frame_t * pAbc, int argc, char ** argv ); extern int Cmd_CommandAbcLoadPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -110,6 +111,7 @@ void Cmd_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1 ); Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0 ); Cmd_CommandAdd( pAbc, "Various", "starter", CmdCommandStarter, 0 ); + Cmd_CommandAdd( pAbc, "Various", "autotuner", CmdCommandAutoTuner, 0 ); Cmd_CommandAdd( pAbc, "Various", "load_plugin", Cmd_CommandAbcLoadPlugIn, 0 ); } @@ -2457,6 +2459,118 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ); + FILE * pFile; + char * pFileConf = NULL; + char * pFileList = NULL; + char * pFileName; + int c, nCores = 3; + int fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "NCFvh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nCores = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCores < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by a string (possibly in quotes).\n" ); + goto usage; + } + pFileConf = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by a string (possibly in quotes).\n" ); + goto usage; + } + pFileList = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pFileConf == NULL ) + { + Abc_Print( -2, "File containing configuration for autotuning is not given.\n" ); + return 1; + } + if ( pFileList == NULL ) + { + Abc_Print( -2, "File contining list of files for autotuning is not given.\n" ); + return 1; + } + // get the input file name + pFileName = pFileConf; + if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL ) +// if ( (pFile = fopen( pFileName, "rb" )) == NULL ) + { + Abc_Print( -2, "Cannot open configuration file \"%s\". ", pFileName ); + if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) )) + Abc_Print( -2, "Did you mean \"%s\"?", pFileName ); + Abc_Print( -2, "\n" ); + return 1; + } + fclose( pFile ); + // get the input file name + pFileName = pFileList; + if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL ) +// if ( (pFile = fopen( pFileName, "rb" )) == NULL ) + { + Abc_Print( -2, "Cannot open the file list \"%s\". ", pFileName ); + if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) )) + Abc_Print( -2, "Did you mean \"%s\"?", pFileName ); + Abc_Print( -2, "\n" ); + return 1; + } + fclose( pFile ); + // run commands + Cmd_RunAutoTuner( pFileConf, pFileList, nCores ); + return 0; + +usage: + Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" ); + Abc_Print( -2, "\t runs command lines listed in concurrently on CPUs\n" ); + Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores ); + Abc_Print( -2, "\t-C cmd : configuration file for autotuning\n" ); + Abc_Print( -2, "\t-F cmd : list of files to be used for autotuning\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [Print the version string.] diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c new file mode 100644 index 00000000..28b209fa --- /dev/null +++ b/src/base/cmd/cmdAuto.c @@ -0,0 +1,522 @@ +/**CFile**************************************************************** + + FileName [cmdAuto.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Autotuner.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cmdAuto.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include +#include +#include +#include +#include "misc/util/abc_global.h" +#include "misc/extra/extra.h" +#include "aig/gia/gia.h" +#include "sat/satoko/satoko.h" + +#ifdef ABC_USE_PTHREADS + +#ifdef _WIN32 +#include "../lib/pthread.h" +#else +#include +#include +#endif + +#endif + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string +#define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call + +extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Printing option structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) +{ + printf( "-C %d ", pOpts->conf_limit ); + printf( "-V %.3f ", pOpts->var_decay ); + printf( "-W %.3f ", pOpts->clause_decay ); + if ( pOpts->verbose ) + printf( "-v", pOpts->verbose ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [The main evaluation procedure for an array of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts ) +{ + Gia_Man_t * pGia; + int i, TotalCost = 0; + //printf( "Tuning with options: " ); + //Cmd_RunAutoTunerPrintOptions( pOpts ); + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) + TotalCost += Gia_ManCallSatokoOne( pGia, pOpts, -1 ); + return TotalCost; +} + +/**Function************************************************************* + + Synopsis [The main evaluation procedure for the set of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#ifndef ABC_USE_PTHREADS + +int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nCores ) +{ + return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts ); +} + +#else // pthreads are used + + +#define CMD_THR_MAX 100 +typedef struct Cmd_AutoData_t_ +{ + Gia_Man_t * pGia; + satoko_opts_t * pOpts; + int iThread; + int nTimeOut; + int fWorking; + int Result; +} Cmd_AutoData_t; + +void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) +{ + Cmd_AutoData_t * pThData = (Cmd_AutoData_t *)pArg; + volatile int * pPlace = &pThData->fWorking; + while ( 1 ) + { + while ( *pPlace == 0 ); + assert( pThData->fWorking ); + if ( pThData->pGia == NULL ) // kills itself when there is nothing to do + { + pthread_exit( NULL ); + assert( 0 ); + return NULL; + } + pThData->Result = Gia_ManCallSatokoOne( pThData->pGia, pThData->pOpts, -1 ); + pThData->fWorking = 0; + } + assert( 0 ); + return NULL; +} +int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs ) +{ + abctime clkTotal = Abc_Clock(); + Cmd_AutoData_t ThData[CMD_THR_MAX]; + pthread_t WorkerThread[CMD_THR_MAX]; + int i, status, fWorkToDo = 1, TotalCost = 0; + Vec_Ptr_t * vStack; + if ( nProcs == 1 ) + return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts ); + // subtract manager thread + nProcs--; + assert( nProcs >= 1 && nProcs <= CMD_THR_MAX ); + // start threads + for ( i = 0; i < nProcs; i++ ) + { + ThData[i].pGia = NULL; + ThData[i].pOpts = pOpts; + ThData[i].iThread = i; + ThData[i].nTimeOut = -1; + ThData[i].fWorking = 0; + ThData[i].Result = -1; + status = pthread_create( WorkerThread + i, NULL,Cmd_RunAutoTunerEvalWorkerThread, (void *)(ThData + i) ); assert( status == 0 ); + } + // look at the threads + vStack = Vec_PtrDup(vAigs); + while ( fWorkToDo ) + { + fWorkToDo = (int)(Vec_PtrSize(vStack) > 0); + for ( i = 0; i < nProcs; i++ ) + { + // check if this thread is working + if ( ThData[i].fWorking ) + { + fWorkToDo = 1; + continue; + } + // check if this thread has recently finished + if ( ThData[i].pGia != NULL ) + { + assert( ThData[i].Result >= 0 ); + TotalCost += ThData[i].Result; + ThData[i].pGia = NULL; + } + if ( Vec_PtrSize(vStack) == 0 ) + continue; + // give this thread a new job + assert( ThData[i].pGia == NULL ); + ThData[i].pGia = (Gia_Man_t *)Vec_PtrPop( vStack ); + ThData[i].fWorking = 1; + } + } + Vec_PtrFree( vStack ); + // stop threads + for ( i = 0; i < nProcs; i++ ) + { + assert( !ThData[i].fWorking ); + // stop + ThData[i].pGia = NULL; + ThData[i].fWorking = 1; + } + return TotalCost; +} + +#endif // pthreads are used + + +/**Function************************************************************* + + Synopsis [Derives all possible param stucts according to the config file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Cmd_DeriveConvertIntoString( int argc, char ** argv ) +{ + char pBuffer[CMD_AUTO_LINE_MAX] = {0}; + int i; + for ( i = 0; i < argc; i++ ) + { + strcat( pBuffer, argv[i] ); + strcat( pBuffer, " " ); + } + return Abc_UtilStrsav(pBuffer); +} +satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) +{ + int c; + satoko_opts_t opts, * pOpts; + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CVWhv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + return NULL; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + return NULL; + break; + case 'V': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-V\" should be followed by an integer.\n" ); + return NULL; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + return NULL; + break; + case 'W': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + return NULL; + break; + case 'v': + opts.verbose ^= 1; + break; + default: + return NULL; + } + } + // return a copy of this parameter structure + pOpts = ABC_ALLOC( satoko_opts_t, 1 ); + memcpy( pOpts, &opts, sizeof(satoko_opts_t) ); + return pOpts; +} +void Cmf_CreateOptions_rec( Vec_Wec_t * vPars, int iPar, char Argv[CMD_AUTO_ARG_MAX][20], int Argc, Vec_Ptr_t * vOpts ) +{ + Vec_Int_t * vLine; + int Symb, Num, i; + assert( Argc <= CMD_AUTO_ARG_MAX ); + if ( Vec_WecSize(vPars) == iPar ) + { + satoko_opts_t * pOpts; + char * pArgv[CMD_AUTO_ARG_MAX]; + for ( i = 0; i < Argc; i++ ) + pArgv[i] = Argv[i]; + pOpts = Cmd_DeriveOptionFromSettings( Argc, pArgv ); + if ( pOpts == NULL ) + printf( "Cannot parse command line options...\n" ); + else + { + Vec_PtrPush( vOpts, pOpts ); + Vec_PtrPush( vOpts, Cmd_DeriveConvertIntoString(Argc, pArgv) ); + printf( "Adding settings %s\n", (char *)Vec_PtrEntryLast(vOpts) ); + } + return; + } + vLine = Vec_WecEntry( vPars, iPar ); + // consider binary option + if ( Vec_IntSize(vLine) == 2 ) + { + Symb = Vec_IntEntry( vLine, 0 ); + Num = Vec_IntEntry( vLine, 1 ); + assert( Abc_Int2Float(Num) == -1.0 ); + // create one setting without this option + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc, vOpts ); + // create another setting with this option + sprintf( Argv[Argc], "-%c", Symb ); + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+1, vOpts ); + return; + } + // consider numeric option + Vec_IntForEachEntryDouble( vLine, Symb, Num, i ) + { + float NumF = Abc_Int2Float(Num); + // create setting with this option + assert( NumF >= 0 ); + sprintf( Argv[Argc], "-%c", Symb ); + if ( NumF == (float)(int)NumF ) + sprintf( Argv[Argc+1], "%d", (int)NumF ); + else + sprintf( Argv[Argc+1], "%.3f", NumF ); + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+2, vOpts ); + } +} +Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars ) +{ + char Argv[CMD_AUTO_ARG_MAX][20]; + int Symb, Num, i, Argc = 0; + Vec_Ptr_t * vOpts = Vec_PtrAlloc( 100 ); + Vec_Int_t * vLine = Vec_WecEntry( vPars, 0 ); + printf( "Creating all possible settings to be used by the autotuner:\n" ); + sprintf( Argv[Argc++], "autotuner" ); + Vec_IntForEachEntryDouble( vLine, Symb, Num, i ) + { + float NumF = Abc_Int2Float(Num); + sprintf( Argv[Argc++], "-%c", Symb ); + if ( NumF < 0.0 ) + continue; + if ( NumF == (float)(int)NumF ) + sprintf( Argv[Argc++], "%d", (int)NumF ); + else + sprintf( Argv[Argc++], "%.3f", NumF ); + } + Cmf_CreateOptions_rec( vPars, 1, Argv, Argc, vOpts ); + printf( "Finished creating %d settings.\n\n", Vec_PtrSize(vOpts)/2 ); + return vOpts; +} + + +/**Function************************************************************* + + Synopsis [Parses config file and derives AIGs listed in file list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } +static inline Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } +static inline Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } +static inline Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } + +Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig ) +{ + Vec_Wec_t * vPars; + Vec_Int_t * vLine; + char * pThis, pBuffer[CMD_AUTO_LINE_MAX]; + FILE * pFile = fopen( pConfig, "rb" ); + if ( pFile == NULL ) + { printf( "File containing list of files \"%s\" cannot be opened.\n", pConfig ); return NULL; } + vPars = Vec_WecAlloc( 100 ); + while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL ) + { + // get the command from the file + if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#') + continue; + // skip trailing spaces + while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) ) + pBuffer[strlen(pBuffer)-1] = 0; + // read the line + vLine = Vec_WecPushLevel( vPars ); + for ( pThis = pBuffer; *pThis; ) + { + if ( Cmf_IsLowerCaseChar(*pThis) ) + { + Vec_IntPushTwo( vLine, (int)*pThis, Abc_Float2Int((float)-1.0) ); + pThis++; + while ( Cmf_IsSpace(*pThis) ) + pThis++; + continue; + } + if ( Cmf_IsUpperCaseChar(*pThis) ) + { + char Param = *pThis++; + if ( !Cmf_IsDigit(*pThis) ) + { printf( "Upper-case character (%c) should be followed by a number without space in line \"%s\".\n", Param, pBuffer ); return NULL; } + Vec_IntPushTwo( vLine, (int)Param, Abc_Float2Int(atof(pThis)) ); + while ( Cmf_IsDigit(*pThis) ) + pThis++; + while ( Cmf_IsSpace(*pThis) ) + pThis++; + continue; + } + printf( "Expecting a leading lower-case or upper-case digit in line \"%s\".\n", pBuffer ); + return NULL; + } + } + fclose( pFile ); + return vPars; +} +Vec_Ptr_t * Cmd_ReadFiles( char * pFileList ) +{ + Gia_Man_t * pGia; + Vec_Ptr_t * vAigs; + char pBuffer[CMD_AUTO_LINE_MAX]; + FILE * pFile = fopen( pFileList, "rb" ); + if ( pFile == NULL ) + { printf( "File containing list of files \"%s\" cannot be opened.\n", pFileList ); return NULL; } + vAigs = Vec_PtrAlloc( 100 ); + while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL ) + { + // get the command from the file + if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#') + continue; + // skip trailing spaces + while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) ) + pBuffer[strlen(pBuffer)-1] = 0; + // read the file + pGia = Gia_AigerRead( pBuffer, 0, 0, 0 ); + if ( pGia == NULL ) + { + printf( "Cannot read AIG from file \"%s\".\n", pBuffer ); + continue; + } + Vec_PtrPush( vAigs, pGia ); + } + fclose( pFile ); + return vAigs; +} + +/**Function************************************************************* + + Synopsis [Autotuner for SAT solver "satoko".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) +{ + abctime clk = Abc_Clock(); + Vec_Wec_t * vPars = Cmd_ReadParamChoices( pConfig ); + Vec_Ptr_t * vAigs = Cmd_ReadFiles( pFileList ); + Vec_Ptr_t * vOpts = vPars ? Cmf_CreateOptions( vPars ) : NULL; + int i; char * pString, * pStringBest = NULL; + satoko_opts_t * pOpts, * pOptsBest = NULL; + int Result, ResultBest = 0x7FFFFFFF; + Gia_Man_t * pGia; + // iterate through all possible option settings + if ( vAigs && vOpts ) + { + Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i ) + { + abctime clk = Abc_Clock(); + printf( "Evaluating options %20s... ", pString ); + Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores ); + printf( "Cost = %6d. ", Result ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( ResultBest > Result ) + { + ResultBest = Result; + pStringBest = pString; + pOptsBest = pOpts; + } + } + printf( "The best options are: %20s ", pStringBest ); + printf( "Best cost = %6d. ", ResultBest ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + // cleanup + if ( vPars ) Vec_WecFree( vPars ); + if ( vOpts ) Vec_PtrFreeFree( vOpts ); + if ( vAigs ) + { + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) + Gia_ManStop( pGia ); + Vec_PtrFree( vAigs ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/cmd/module.make b/src/base/cmd/module.make index b09ffa81..1042fbb0 100644 --- a/src/base/cmd/module.make +++ b/src/base/cmd/module.make @@ -1,6 +1,7 @@ SRC += src/base/cmd/cmd.c \ src/base/cmd/cmdAlias.c \ src/base/cmd/cmdApi.c \ + src/base/cmd/cmdAuto.c \ src/base/cmd/cmdFlag.c \ src/base/cmd/cmdHist.c \ src/base/cmd/cmdLoad.c \ diff --git a/src/misc/extra/extraUtilUtil.c b/src/misc/extra/extraUtilUtil.c index 253d9e3c..2f0f4559 100644 --- a/src/misc/extra/extraUtilUtil.c +++ b/src/misc/extra/extraUtilUtil.c @@ -102,35 +102,45 @@ int Extra_UtilGetopt( int argc, char *argv[], const char *optstring ) globalUtilOptarg = NULL; - if (pScanStr == NULL || *pScanStr == '\0') { - if (globalUtilOptind == 0) globalUtilOptind++; - if (globalUtilOptind >= argc) return EOF; - place = argv[globalUtilOptind]; - if (place[0] != '-' || place[1] == '\0') return EOF; - globalUtilOptind++; - if (place[1] == '-' && place[2] == '\0') return EOF; - pScanStr = place+1; + if (pScanStr == NULL || *pScanStr == '\0') + { + if (globalUtilOptind == 0) + globalUtilOptind++; + if (globalUtilOptind >= argc) + return EOF; + place = argv[globalUtilOptind]; + if (place[0] != '-' || place[1] == '\0') + return EOF; + globalUtilOptind++; + if (place[1] == '-' && place[2] == '\0') + return EOF; + pScanStr = place+1; } c = *pScanStr++; place = strchr(optstring, c); if (place == NULL || c == ':') { - (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c); - return '?'; - } - if (*++place == ':') { - if (*pScanStr != '\0') { - globalUtilOptarg = pScanStr; - pScanStr = NULL; - } else { - if (globalUtilOptind >= argc) { - (void) fprintf(stderr, "%s: %c requires an argument\n", - argv[0], c); + (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c); return '?'; - } - globalUtilOptarg = argv[globalUtilOptind]; - globalUtilOptind++; } + if (*++place == ':') + { + if (*pScanStr != '\0') + { + globalUtilOptarg = pScanStr; + pScanStr = NULL; + } + else + { + if (globalUtilOptind >= argc) + { + (void) fprintf(stderr, "%s: %c requires an argument\n", + argv[0], c); + return '?'; + } + globalUtilOptarg = argv[globalUtilOptind]; + globalUtilOptind++; + } } return c; } -- cgit v1.2.3 From 1e62fb4a92b49639b8ee554a8fb6aafde428daf8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 18:59:07 -0800 Subject: Compiler warning. --- src/base/cmd/cmdAuto.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 28b209fa..e029f6d2 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -66,11 +66,11 @@ extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutpu ***********************************************************************/ void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) { - printf( "-C %d ", pOpts->conf_limit ); + printf( "-C %d ", (int)pOpts->conf_limit ); printf( "-V %.3f ", pOpts->var_decay ); printf( "-W %.3f ", pOpts->clause_decay ); if ( pOpts->verbose ) - printf( "-v", pOpts->verbose ); + printf( "-v" ); printf( "\n" ); } @@ -150,7 +150,6 @@ void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) } int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs ) { - abctime clkTotal = Abc_Clock(); Cmd_AutoData_t ThData[CMD_THR_MAX]; pthread_t WorkerThread[CMD_THR_MAX]; int i, status, fWorkToDo = 1, TotalCost = 0; @@ -377,10 +376,10 @@ Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars ) SeeAlso [] ***********************************************************************/ -static inline Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } -static inline Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } -static inline Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } -static inline Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } +static inline int Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } +static inline int Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } +static inline int Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } +static inline int Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig ) { -- cgit v1.2.3 From 778ea6bb8ac56a716f457932fbc1a211692f238c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:07:21 -0800 Subject: Editing output messages. --- src/base/cmd/cmdAuto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index e029f6d2..7d0cc8af 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -486,7 +486,7 @@ void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i ) { abctime clk = Abc_Clock(); - printf( "Evaluating options %20s... ", pString ); + printf( "Evaluating settings: %20s... \n", pString ); Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores ); printf( "Cost = %6d. ", Result ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); @@ -497,9 +497,9 @@ void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) pOptsBest = pOpts; } } - printf( "The best options are: %20s ", pStringBest ); + printf( "The best settings are: %20s \n", pStringBest ); printf( "Best cost = %6d. ", ResultBest ); - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); } // cleanup if ( vPars ) Vec_WecFree( vPars ); -- cgit v1.2.3 From 2a9902eec7287735db933a8d55f7f7458aa9d939 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:10:15 -0800 Subject: Accidental change. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 38a555d8..26e9c0f8 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -16782,7 +16782,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) If_ManSetDefaultPars( pPars ); pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "K:CFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) { switch ( c ) { -- cgit v1.2.3 From 040b88a7c6bc437f6f9dc792510d5d905b516eb5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:12:57 -0800 Subject: Editing output messages. --- src/base/cmd/cmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index ec4a0c86..853f5710 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -2562,10 +2562,10 @@ int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" ); - Abc_Print( -2, "\t runs command lines listed in concurrently on CPUs\n" ); + Abc_Print( -2, "\t performs autotuning\n" ); Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores ); - Abc_Print( -2, "\t-C cmd : configuration file for autotuning\n" ); - Abc_Print( -2, "\t-F cmd : list of files to be used for autotuning\n" ); + Abc_Print( -2, "\t-C cmd : configuration file with settings for autotuning\n" ); + Abc_Print( -2, "\t-F cmd : list of AIGER files to be used for autotuning\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; -- cgit v1.2.3 From 871899dceac294f2b76c055a42d87176224028f2 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Thu, 9 Feb 2017 05:17:50 -0800 Subject: =?UTF-8?q?-=20Adding=20a=20compile=20time=20option=20to=20use=20f?= =?UTF-8?q?loats=20for=20var=20activity=20(now=20it=20can=20be=20either=20?= =?UTF-8?q?=E2=80=98double=E2=80=99,=20=E2=80=98float=E2=80=99=20or=20?= =?UTF-8?q?=E2=80=98unsigned=E2=80=99=20(default))=20-=20Adding=20vector?= =?UTF-8?q?=20of=20=E2=80=98float=E2=80=99=20-=20Adding=20an=20option=20to?= =?UTF-8?q?=20configure=20the=20ratio=20of=20learnt=20clauses=20to=20be=20?= =?UTF-8?q?kept=20in=20clause=20database=20at=20each=20reduction=20(0=20me?= =?UTF-8?q?ans=20no=20reduction).=20-=20Other=20small=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sat/satoko/act_clause.h | 5 +- src/sat/satoko/act_var.h | 29 +++-- src/sat/satoko/satoko.h | 4 +- src/sat/satoko/solver.c | 15 +-- src/sat/satoko/solver_api.c | 7 +- src/sat/satoko/types.h | 22 +++- src/sat/satoko/utils/misc.h | 6 +- src/sat/satoko/utils/vec/vec_flt.h | 246 +++++++++++++++++++++++++++++++++++++ 8 files changed, 300 insertions(+), 34 deletions(-) create mode 100644 src/sat/satoko/utils/vec/vec_flt.h (limited to 'src') diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h index 2e80a1e6..1465e5ee 100644 --- a/src/sat/satoko/act_clause.h +++ b/src/sat/satoko/act_clause.h @@ -56,10 +56,9 @@ static inline void clause_act_rescale(solver_t *s) vec_uint_foreach(s->learnts, cref, i) { clause = clause_read(s, cref); - clause->data[clause->size].act >>= 14; + clause->data[clause->size].act >>= 10; } - s->clause_act_inc >>= 14; - s->clause_act_inc = mkt_uint_max(s->clause_act_inc, (1 << 10)); + s->clause_act_inc = stk_uint_max((s->clause_act_inc >> 10), (1 << 11)); } static inline void clause_act_bump(solver_t *s, struct clause *clause) diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h index 161e9d9a..aa8a76ab 100644 --- a/src/sat/satoko/act_var.h +++ b/src/sat/satoko/act_var.h @@ -16,27 +16,27 @@ #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#ifdef SATOKO_ACT_VAR_DBLE +#if defined SATOKO_ACT_VAR_DBLE || defined SATOKO_ACT_VAR_FLOAT /** Re-scale the activity value for all variables. */ static inline void var_act_rescale(solver_t *s) { unsigned i; - double *activity = vec_dble_data(s->activity); + act_t *activity = vec_act_data(s->activity); - for (i = 0; i < vec_dble_size(s->activity); i++) - activity[i] *= 1e-100; - s->var_act_inc *= 1e-100; + for (i = 0; i < vec_act_size(s->activity); i++) + activity[i] *= VAR_ACT_RESCALE; + s->var_act_inc *= VAR_ACT_RESCALE; } /** Increment the activity value of one variable ('var') */ static inline void var_act_bump(solver_t *s, unsigned var) { - double *activity = vec_dble_data(s->activity); + act_t *activity = vec_act_data(s->activity); activity[var] += s->var_act_inc; - if (activity[var] > 1e100) + if (activity[var] > VAR_ACT_LIMIT) var_act_rescale(s); if (heap_in_heap(s->var_order, var)) heap_decrease(s->var_order, var); @@ -49,25 +49,24 @@ static inline void var_act_decay(solver_t *s) s->var_act_inc *= (1 / s->opts.var_decay); } -#else /* SATOKO_ACT_VAR_DBLE */ +#else static inline void var_act_rescale(solver_t *s) { unsigned i; - unsigned *activity = vec_uint_data(s->activity); + act_t *activity = vec_act_data(s->activity); - for (i = 0; i < vec_uint_size(s->activity); i++) + for (i = 0; i < vec_act_size(s->activity); i++) activity[i] >>= 19; - s->var_act_inc >>= 19; - s->var_act_inc = mkt_uint_max(s->var_act_inc, (1 << 5)); + s->var_act_inc = stk_uint_max((s->var_act_inc >> 19), (1 << 5)); } static inline void var_act_bump(solver_t *s, unsigned var) { - unsigned *activity = vec_uint_data(s->activity); + act_t *activity = vec_act_data(s->activity); activity[var] += s->var_act_inc; - if (activity[var] & 0x80000000) + if (activity[var] & 0xF0000000) var_act_rescale(s); if (heap_in_heap(s->var_order, var)) heap_decrease(s->var_order, var); @@ -78,7 +77,7 @@ static inline void var_act_decay(solver_t *s) s->var_act_inc += (s->var_act_inc >> 4); } -#endif /* SATOKO_ACT_VAR_DBLE */ +#endif /* SATOKO_ACT_VAR_DBLE || SATOKO_ACT_VAR_FLOAT */ ABC_NAMESPACE_HEADER_END #endif /* satoko__act_var_h */ diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 55790714..fb07c6f9 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -9,6 +9,7 @@ #ifndef satoko__satoko_h #define satoko__satoko_h +#include "types.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START @@ -45,10 +46,11 @@ struct satoko_opts { unsigned inc_reduce; /* Increment to reduce */ unsigned inc_special_reduce; /* Special increment to reduce */ unsigned lbd_freeze_clause; + float learnt_ratio; /* Percentage of learned clauses to remove */ /* VSIDS heuristic */ float clause_decay; - double var_decay; + act_t var_decay; /* Binary resolution */ unsigned clause_max_sz_bin_resol; diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index a4114e54..cdd3141e 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -45,7 +45,7 @@ static inline int lit_is_removable(solver_t* s, unsigned lit, unsigned min_level assert(var_reason(s, var) != UNDEF); if (c->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) { assert(lit_value(s, lits[1]) == LIT_TRUE); - mkt_swap(unsigned, lits[0], lits[1]); + stk_swap(unsigned, lits[0], lits[1]); } /* Check scan the literals of the reason clause. @@ -126,7 +126,7 @@ static inline void clause_bin_resolution(solver_t *s, vec_uint_t *clause_lits) sz = vec_uint_size(clause_lits) - 1; for (i = 1; i < vec_uint_size(clause_lits) - counter; i++) if (vec_uint_at(s->stamps, lit2var(lits[i])) != s->cur_stamp) { - mkt_swap(unsigned, lits[i], lits[sz]); + stk_swap(unsigned, lits[i], lits[sz]); i--; sz--; } @@ -268,7 +268,7 @@ static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt if (p != UNDEF && clause->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) { assert(lit_value(s, lits[1]) == LIT_TRUE); - mkt_swap(unsigned, lits[0], lits[1] ); + stk_swap(unsigned, lits[0], lits[1] ); } if (clause->f_learnt) @@ -310,7 +310,7 @@ static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt *bt_level = solver_calc_bt_level(s, learnt); *lbd = clause_clac_lbd(s, vec_uint_data(learnt), vec_uint_size(learnt)); - if (vec_uint_size( s->last_dlevel) > 0) { + if (vec_uint_size(s->last_dlevel) > 0) { vec_uint_foreach(s->last_dlevel, var, i) { if (clause_read(s, var_reason(s, var))->lbd < *lbd) var_act_bump(s, var); @@ -428,7 +428,7 @@ static inline void solver_reduce_cdb(solver_t *s) vec_uint_foreach(s->learnts, cref, i) learnts_cls[i] = clause_read(s, cref); - limit = n_learnts / 2; + limit = (unsigned)(n_learnts * s->opts.learnt_ratio); satoko_sort((void *)learnts_cls, n_learnts, (int (*)(const void *, const void *)) clause_compare); @@ -562,7 +562,7 @@ unsigned solver_propagate(solver_t *s) // Make sure the false literal is data[1]: neg_lit = lit_neg(p); if (lits[0] == neg_lit) - mkt_swap(unsigned, lits[0], lits[1]); + stk_swap(unsigned, lits[0], lits[1]); assert(lits[1] == neg_lit); w.cref = i->cref; @@ -635,7 +635,8 @@ char solver_search(solver_t *s) satoko_simplify(s); /* Reduce the set of learnt clauses */ - if (s->stats.n_conflicts >= s->n_confl_bfr_reduce) { + if (s->opts.learnt_ratio && + s->stats.n_conflicts >= s->n_confl_bfr_reduce) { s->RC1 = (s->stats.n_conflicts / s->RC2) + 1; solver_reduce_cdb(s); s->RC2 += s->opts.inc_reduce; diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index e041cc62..980cc160 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -165,6 +165,7 @@ void satoko_default_opts(satoko_opts_t *opts) opts->inc_reduce = 300; opts->inc_special_reduce = 1000; opts->lbd_freeze_clause = 30; + opts->learnt_ratio = 0.5; /* VSIDS heuristic */ opts->var_decay = (act_t) 0.95; opts->clause_decay = (clause_act_t) 0.995; @@ -187,7 +188,7 @@ void satoko_configure(satoko_t *s, satoko_opts_t *user_opts) int satoko_simplify(solver_t * s) { unsigned i, j = 0; - unsigned cref; + unsigned cref; assert(solver_dlevel(s) == 0); if (solver_propagate(s) != UNDEF) @@ -198,7 +199,7 @@ int satoko_simplify(solver_t * s) vec_uint_foreach(s->originals, cref, i) { struct clause *clause = clause_read(s, cref); - if (clause_is_satisfied(s, clause)) { + if (clause_is_satisfied(s, clause)) { clause->f_mark = 1; s->stats.n_original_lits -= clause->size; clause_unwatch(s, cref); @@ -236,7 +237,7 @@ int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) unsigned max_var; unsigned cref; - qsort((void *) lits, size, sizeof(unsigned), mkt_uint_compare); + qsort((void *) lits, size, sizeof(unsigned), stk_uint_compare); max_var = lit2var(lits[size - 1]); while (max_var >= vec_act_size(s->activity)) satoko_add_variable(s, LIT_FALSE); diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index 2811c2c6..ee9363bc 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -10,23 +10,40 @@ #define satoko__types_h #include "utils/vec/vec_dble.h" +#include "utils/vec/vec_flt.h" #include "utils/vec/vec_uint.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#define SATOKO_ACT_VAR_DBLE -#define SATOKO_ACT_CLAUSE_FLOAT +// #define SATOKO_ACT_VAR_DBLE +// #define SATOKO_ACT_VAR_FLOAT +// #define SATOKO_ACT_CLAUSE_FLOAT #ifdef SATOKO_ACT_VAR_DBLE #define VAR_ACT_INIT_INC 1.0 + #define VAR_ACT_LIMIT (double)1e100 + #define VAR_ACT_RESCALE (double)1e-100 typedef double act_t; typedef vec_dble_t vec_act_t ; #define vec_act_alloc(size) vec_dble_alloc(size) #define vec_act_free(vec) vec_dble_free(vec) #define vec_act_size(vec) vec_dble_size(vec) + #define vec_act_data(vec) vec_dble_data(vec) #define vec_act_at(vec, idx) vec_dble_at(vec, idx) #define vec_act_push_back(vec, value) vec_dble_push_back(vec, value) +#elif defined(SATOKO_ACT_VAR_FLOAT) + #define VAR_ACT_INIT_INC 1.0 + #define VAR_ACT_LIMIT (float)1e20 + #define VAR_ACT_RESCALE (float)1e-20 + typedef float act_t; + typedef vec_flt_t vec_act_t ; + #define vec_act_alloc(size) vec_flt_alloc(size) + #define vec_act_free(vec) vec_flt_free(vec) + #define vec_act_size(vec) vec_flt_size(vec) + #define vec_act_data(vec) vec_flt_data(vec) + #define vec_act_at(vec, idx) vec_flt_at(vec, idx) + #define vec_act_push_back(vec, value) vec_flt_push_back(vec, value) #else #define VAR_ACT_INIT_INC (1 << 5) typedef unsigned act_t; @@ -34,6 +51,7 @@ ABC_NAMESPACE_HEADER_START #define vec_act_alloc(size) vec_uint_alloc(size) #define vec_act_free(vec) vec_uint_free(vec) #define vec_act_size(vec) vec_uint_size(vec) + #define vec_act_data(vec) vec_uint_data(vec) #define vec_act_at(vec, idx) vec_uint_at(vec, idx) #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) #endif /* SATOKO_ACT_VAR_DBLE */ diff --git a/src/sat/satoko/utils/misc.h b/src/sat/satoko/utils/misc.h index 481e23b7..7205a096 100755 --- a/src/sat/satoko/utils/misc.h +++ b/src/sat/satoko/utils/misc.h @@ -12,14 +12,14 @@ #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#define mkt_swap(type, a, b) { type t = a; a = b; b = t; } +#define stk_swap(type, a, b) { type t = a; a = b; b = t; } -static inline unsigned mkt_uint_max(unsigned a, unsigned b) +static inline unsigned stk_uint_max(unsigned a, unsigned b) { return a > b ? a : b; } -static inline int mkt_uint_compare(const void *p1, const void *p2) +static inline int stk_uint_compare(const void *p1, const void *p2) { const unsigned pp1 = *(const unsigned *)p1; const unsigned pp2 = *(const unsigned *)p2; diff --git a/src/sat/satoko/utils/vec/vec_flt.h b/src/sat/satoko/utils/vec/vec_flt.h new file mode 100644 index 00000000..d7c896d9 --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_flt.h @@ -0,0 +1,246 @@ +//===--- vec_int.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_flt_h +#define satoko__utils__vec__vec_flt_h + +#include +#include +#include + +#include "../mem.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_flt_t_ vec_flt_t; +struct vec_flt_t_ { + unsigned cap; + unsigned size; + float *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_flt_foreach(vec, entry, i) \ + for (i = 0; (i < vec->size) && (((entry) = vec_flt_at(vec, i)), 1); i++) + +#define vec_flt_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_flt_size(vec)) && (((entry) = vec_flt_at(vec, i)), 1); i++) + +#define vec_flt_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_flt_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_flt_t *vec_flt_alloc(unsigned cap) +{ + vec_flt_t* p = satoko_alloc(vec_flt_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(float, p->cap) : NULL; + return p; +} + +static inline vec_flt_t *vec_flt_alloc_exact(unsigned cap) +{ + vec_flt_t* p = satoko_alloc(vec_flt_t, 1); + + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(float, p->cap) : NULL; + return p; +} + +static inline vec_flt_t *vec_flt_init(unsigned size, float value) +{ + vec_flt_t* p = satoko_alloc(vec_flt_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(float, p->cap) : NULL; + memset(p->data, value, sizeof(float) * p->size); + return p; +} + +static inline void vec_flt_free(vec_flt_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_flt_size(vec_flt_t *p) +{ + return p->size; +} + +static inline void vec_flt_resize(vec_flt_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(float, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_flt_reserve(vec_flt_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(float, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_flt_capacity(vec_flt_t *p) +{ + return p->cap; +} + +static inline int vec_flt_empty(vec_flt_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_flt_erase(vec_flt_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline float vec_flt_at(vec_flt_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data[i]; +} + +static inline float *vec_flt_at_ptr(vec_flt_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data + i; +} + +static inline float *vec_flt_data(vec_flt_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_flt_duplicate(vec_flt_t *dest, const vec_flt_t *src) +{ + assert(dest != NULL && src != NULL); + vec_flt_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(float) * src->cap); + dest->size = src->size; +} + +static inline void vec_flt_copy(vec_flt_t *dest, const vec_flt_t *src) +{ + assert(dest != NULL && src != NULL); + vec_flt_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(float) * src->size); + dest->size = src->size; +} + +static inline void vec_flt_push_back(vec_flt_t *p, float value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_flt_reserve(p, 16); + else + vec_flt_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline void vec_flt_assign(vec_flt_t *p, unsigned i, float value) +{ + assert((i >= 0) && (i < vec_flt_size(p))); + p->data[i] = value; +} + +static inline void vec_flt_insert(vec_flt_t *p, unsigned i, float value) +{ + assert((i >= 0) && (i < vec_flt_size(p))); + vec_flt_push_back(p, 0); + memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(float)); + p->data[i] = value; +} + +static inline void vec_flt_drop(vec_flt_t *p, unsigned i) +{ + assert((i >= 0) && (i < vec_flt_size(p))); + memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(float)); + p->size -= 1; +} + +static inline void vec_flt_clear(vec_flt_t *p) +{ + p->size = 0; +} + +static inline int vec_flt_asc_compare(const void *p1, const void *p2) +{ + const float *pp1 = (const float *) p1; + const float *pp2 = (const float *) p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_flt_desc_compare(const void* p1, const void* p2) +{ + const float *pp1 = (const float *) p1; + const float *pp2 = (const float *) p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_flt_sort(vec_flt_t* p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(float), + (int (*)(const void*, const void*)) vec_flt_asc_compare); + else + qsort((void *) p->data, p->size, sizeof(float), + (int (*)(const void*, const void*)) vec_flt_desc_compare); +} + +static inline long vec_flt_memory(vec_flt_t *p) +{ + return p == NULL ? 0 : sizeof(float) * p->cap + sizeof(vec_flt_t); +} + +static inline void vec_flt_print(vec_flt_t *p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %f", p->data[i]); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_flt_h */ -- cgit v1.2.3 From e20ef654d99d5cf1f0f73466b931d53833f6a1eb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 13:31:07 -0800 Subject: Word-level abstraction. --- src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 15 +++- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcAbs2.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcCom.c | 99 +++++++++++++++++++++++- src/base/wlc/wlcNtk.c | 86 ++++++++++++++++++--- src/base/wlc/wlcReadVer.c | 2 +- 7 files changed, 379 insertions(+), 14 deletions(-) create mode 100644 src/base/wlc/wlcAbs2.c (limited to 'src') diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index ae7899ec..3485bd4d 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -1,4 +1,5 @@ SRC += src/base/wlc/wlcAbs.c \ + src/base/wlc/wlcAbs2.c \ src/base/wlc/wlcAbc.c \ src/base/wlc/wlcBlast.c \ src/base/wlc/wlcCom.c \ diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index d51b699c..0a17cfe6 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -160,6 +160,16 @@ struct Wlc_Ntk_t_ Vec_Int_t vLevels; // object levels }; +typedef struct Wlc_Par_t_ Wlc_Par_t; +struct Wlc_Par_t_ +{ + int nBitsAdd; // adder bit-width + int nBitsMul; // multiplier bit-widht + int nBitsMux; // MUX bit-width + int nBitsFlop; // flop bit-width + int fVerbose; // verbose output` +}; + static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -267,6 +277,9 @@ extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); +/*=== wlcAbs2.c ========================================================*/ +extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); +extern Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth ); /*=== wlcCom.c ========================================================*/ @@ -291,7 +304,7 @@ extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index ce6b8de9..8662e509 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); + pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); return pNew; } @@ -277,7 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); + pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); return pNew; } diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c new file mode 100644 index 00000000..9da59f42 --- /dev/null +++ b/src/base/wlc/wlcAbs2.c @@ -0,0 +1,186 @@ +/**CFile**************************************************************** + + FileName [wlcAbs2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Abstraction for word-level networks.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcAbs2.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Wabs_Par_t_ Wabs_Par_t; +struct Wabs_Par_t_ +{ + Wlc_Ntk_t * pNtk; + Wlc_Par_t * pPars; + Vec_Bit_t * vLeaves; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Wlc_Par_t) ); + pPars->nBitsAdd = 16; // adder bit-width + pPars->nBitsMul = 8; // multiplier bit-widht + pPars->nBitsMux = 32; // MUX bit-width + pPars->nBitsFlop = 32; // flop bit-width + pPars->fVerbose = 0; // verbose output` +} + +/**Function************************************************************* + + Synopsis [Mark operators that meet the criteria.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + Wlc_Obj_t * pObj; int i; + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( pObj->Type == WLC_OBJ_MUX ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + } + return vLeaves; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vFlops, Vec_Int_t * vPisNew ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) + { + Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); + return; + } + if ( Wlc_ObjIsCi(pObj) ) + { + if ( !Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vFlops, vPisNew ); +} + +Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) +{ + Vec_Int_t * vFlops; + Vec_Int_t * vPisNew; + Wlc_Obj_t * pObj; + int i, CiId, CoId; + Wlc_NtkCleanMarks( p ); + vFlops = Vec_IntAlloc( 100 ); + vPisNew = Vec_IntAlloc( 100 ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vFlops, vPisNew ); + Vec_IntForEachEntry( vFlops, CiId, i ) + { + CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkCo(p, CoId), vLeaves, vFlops, vPisNew ); + } + Vec_IntFree( vFlops ); + return vPisNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); + Vec_Int_t * vPisNew = Wlc_NtkAbsMarkNodes( p, vLeaves ); + Wlc_Ntk_t * pNtkNew = Wlc_NtkDupDfs( p, 1, 1, vPisNew ); + Vec_IntFree( vPisNew ); + Vec_BitFree( vLeaves ); + return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 82321d3b..3bbe843f 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,6 +32,7 @@ static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -72,6 +73,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); @@ -421,7 +423,7 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); - pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq, NULL ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); @@ -438,6 +440,101 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFvh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + pNtk = Wlc_NtkAbs( pNtk, pPars ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%abs [-AMXF num] [-vh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index bd00a570..6eab4442 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -705,6 +705,45 @@ char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ) return pBuffer; } +/**Function************************************************************* + + Synopsis [Reduce init vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit ) +{ + Vec_Int_t * vInitNew = Vec_IntDup( vInit ); + Wlc_Obj_t * pObj; int i, k = 0; + assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) ); + Wlc_NtkForEachCi( p, pObj, i ) + if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) + Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i) ); + Vec_IntShrink( vInitNew, k ); + return vInitNew; +} +char * Wlc_ReduceMarkedInitStr( Wlc_Ntk_t * p, char * pInit ) +{ + char * pInitNew = Abc_UtilStrsav( pInit ); + Wlc_Obj_t * pObj; int i, b, nBits = 0, k = 0; + Wlc_NtkForEachCi( p, pObj, i ) + { + if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + pInitNew[k++] = pInitNew[nBits+b]; + if ( !Wlc_ObjIsPi(pObj) ) + nBits += Wlc_ObjRange(pObj); + } + pInitNew[k] = '\0'; + assert( nBits == (int)strlen(pInit) ); + return pInitNew; +} + /**Function************************************************************* Synopsis [Duplicates the network in a topological order.] @@ -764,7 +803,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -774,14 +813,33 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; - Wlc_NtkForEachCi( p, pObj, i ) - if ( !fMarked || pObj->Mark ) + if ( vPisNew ) + { + // duplicate marked PIs + Wlc_NtkForEachPi( p, pObj, i ) + if ( pObj->Mark ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + // duplicated additional PIs + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) { unsigned Type = pObj->Type; - if ( !fSeq ) pObj->Type = WLC_OBJ_PI; + assert( !Wlc_ObjIsPi(pObj) ); + pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); pObj->Type = Type; } + } + else + { + Wlc_NtkForEachCi( p, pObj, i ) + if ( !fMarked || pObj->Mark ) + { + unsigned Type = pObj->Type; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + } + } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); @@ -789,12 +847,22 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) if ( !fMarked || pObj->Mark ) Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); Vec_IntFree( vFanins ); - if ( !fMarked ) + if ( fSeq ) { - if ( p->vInits ) - pNew->vInits = Vec_IntDup( p->vInits ); - if ( p->pInits ) - pNew->pInits = Abc_UtilStrsav( p->pInits ); + if ( fMarked ) + { + if ( p->vInits ) + pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits ); + if ( p->pInits ) + pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits ); + } + else + { + if ( p->vInits ) + pNew->vInits = Vec_IntDup( p->vInits ); + if ( p->pInits ) + pNew->pInits = Abc_UtilStrsav( p->pInits ); + } } if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index e4a65ecf..f7546b5b 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1, NULL ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); -- cgit v1.2.3 From 32712ec9abb3f27e3bd00690838b054f5bdc0f77 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 14:17:19 -0800 Subject: Making sure 'inv_out' can match flops by name. --- src/base/wlc/wlcAbc.c | 54 +++++++++++++++++++++++++++++++++++++++---------- src/base/wlc/wlcBlast.c | 11 +++++----- src/base/wlc/wlcCom.c | 4 ++-- src/proof/pdr/pdrInv.c | 2 ++ 4 files changed, 53 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 1f10d7b0..e19aaaec 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -185,8 +185,9 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) +Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ) { + int nRegs = Gia_ManRegNum(pGia); Vec_Int_t * vRes = NULL; if ( Abc_NtkPoNum(pNtk) != 1 ) printf( "The number of outputs is other than 1.\n" ); @@ -194,26 +195,57 @@ Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) printf( "The number of internal nodes is other than 1.\n" ); else { - Abc_Obj_t * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); + Abc_Nam_t * pNames = NULL; + Abc_Obj_t * pFanin, * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); char * pName, * pCube, * pSop = (char *)pNode->pData; Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) ); - Abc_Obj_t * pFanin; int i, k, Value, nLits; + int i, k, Value, nLits, Counter = 0; + if ( pGia->vNamesIn ) + { + // hash the names + pNames = Abc_NamStart( 100, 16 ); + Vec_PtrForEachEntry( char *, pGia->vNamesIn, pName, i ) + { + Value = Abc_NamStrFindOrAdd( pNames, pName, NULL ); + assert( Value == i+1 ); + //printf( "%s(%d) ", pName, i ); + } + //printf( "\n" ); + } Abc_ObjForEachFanin( pNode, pFanin, i ) { assert( Abc_ObjIsCi(pFanin) ); pName = Abc_ObjName(pFanin); - for ( k = (int)strlen(pName)-1; k >= 0; k-- ) - if ( pName[k] < '0' || pName[k] > '9' ) - break; - if ( k == (int)strlen(pName)-1 ) + if ( pNames ) + { + Value = Abc_NamStrFind(pNames, pName) - 1; + if ( Value == -1 ) + { + if ( Counter++ == 0 ) + printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); + Value = i; + } + } + else { - printf( "Cannot read input name of fanin %d.\n", i ); - Value = i; + for ( k = (int)strlen(pName)-1; k >= 0; k-- ) + if ( pName[k] < '0' || pName[k] > '9' ) + break; + if ( k == (int)strlen(pName)-1 ) + { + if ( Counter++ == 0 ) + printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); + Value = i; + } + else + Value = atoi(pName + k + 1); } - else - Value = atoi(pName + k + 1); Vec_IntPush( vFanins, Value ); } + if ( Counter ) + printf( "Cannot read names for %d inputs of the invariant.\n", Counter ); + if ( pNames ) + Abc_NamStop( pNames ); assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) ); vRes = Vec_IntAlloc( 1000 ); Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) ); diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index b49c2dd7..67d7c902 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -872,6 +872,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { int fVerbose = 0; int fUseOldMultiplierBlasting = 0; + int fSkipBitRange = 0; Tim_Man_t * pManTime = NULL; Gia_Man_t * pTemp, * pNew, * pExtra = NULL; Wlc_Obj_t * pObj; @@ -1448,7 +1449,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1475,7 +1476,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1498,7 +1499,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1513,7 +1514,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1532,7 +1533,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 3bbe843f..cc69c636 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -1051,7 +1051,7 @@ usage: ******************************************************************************/ int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ); + extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ); Vec_Int_t * vInv = NULL; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c, fVerbose = 0; @@ -1080,7 +1080,7 @@ int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // derive the network - vInv = Wlc_NtkGetPut( pNtk, Gia_ManRegNum(pAbc->pGia) ); + vInv = Wlc_NtkGetPut( pNtk, pAbc->pGia ); if ( vInv ) Abc_FrameSetInv( vInv ); return 0; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 8130d0a3..95adb10c 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -756,6 +756,8 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver // check if this cube intersects with the complement of other cubes in the solver // if it does not intersect, then it is redundant and can be skipped status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 ); + if ( status != l_True && fVerbose ) + printf( "Finished checking clause %d (out of %d)...\r", i, pList[0] ); if ( status == l_Undef ) // timeout break; if ( status == l_False ) // unsat -- correct -- cgit v1.2.3 From 2fe17c1f4bf2a4df4076ad2fee336f568c52786f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 14:30:10 -0800 Subject: Word-level abstraction. --- src/base/cmd/cmdAuto.c | 4 ++-- src/base/wlc/wlcAbc.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 7d0cc8af..35f155fa 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -67,8 +67,8 @@ extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutpu void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) { printf( "-C %d ", (int)pOpts->conf_limit ); - printf( "-V %.3f ", pOpts->var_decay ); - printf( "-W %.3f ", pOpts->clause_decay ); + printf( "-V %.3f ", (float)pOpts->var_decay ); + printf( "-W %.3f ", (float)pOpts->clause_decay ); if ( pOpts->verbose ) printf( "-v" ); printf( "\n" ); diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index e19aaaec..1836f4ed 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -218,8 +218,8 @@ Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ) pName = Abc_ObjName(pFanin); if ( pNames ) { - Value = Abc_NamStrFind(pNames, pName) - 1; - if ( Value == -1 ) + Value = Abc_NamStrFind(pNames, pName) - 1 - Gia_ManPiNum(pGia); + if ( Value < 0 ) { if ( Counter++ == 0 ) printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); -- cgit v1.2.3 From 7a2984bbe9e2d9e76851c0ce440e08f6788fcb70 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 16:38:08 -0800 Subject: Word-level abstraction. --- src/base/wlc/wlc.h | 3 +- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcAbs2.c | 76 ++++++++++++++++++++---------------- src/base/wlc/wlcCom.c | 8 ++-- src/base/wlc/wlcNtk.c | 98 ++++++++++++++++++++++++++++++++++------------- src/base/wlc/wlcReadVer.c | 2 +- 6 files changed, 125 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 0a17cfe6..21ba73a3 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -304,7 +304,8 @@ extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8662e509..ce6b8de9 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } @@ -277,7 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c index 9da59f42..f5a7b46d 100644 --- a/src/base/wlc/wlcAbs2.c +++ b/src/base/wlc/wlcAbs2.c @@ -52,11 +52,11 @@ struct Wabs_Par_t_ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) { memset( pPars, 0, sizeof(Wlc_Par_t) ); - pPars->nBitsAdd = 16; // adder bit-width - pPars->nBitsMul = 8; // multiplier bit-widht - pPars->nBitsMux = 32; // MUX bit-width - pPars->nBitsFlop = 32; // flop bit-width - pPars->fVerbose = 0; // verbose output` + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->fVerbose = 0; // verbose output` } /**Function************************************************************* @@ -73,40 +73,41 @@ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); - Wlc_Obj_t * pObj; int i; + Wlc_Obj_t * pObj; int i, Count[4] = {0}; Wlc_NtkForEachObj( p, pObj, i ) { if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++; continue; } if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++; continue; } if ( pObj->Type == WLC_OBJ_MUX ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++; continue; } if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++; continue; } } + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); return vLeaves; } /**Function************************************************************* - Synopsis [] + Synopsis [Marks nodes to be included in the abstracted network.] Description [] @@ -115,7 +116,7 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vFlops, Vec_Int_t * vPisNew ) +void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { int i, iFanin; if ( pObj->Mark ) @@ -123,42 +124,45 @@ void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeav pObj->Mark = 1; if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) { + assert( !Wlc_ObjIsPi(pObj) ); Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); return; } if ( Wlc_ObjIsCi(pObj) ) { - if ( !Wlc_ObjIsPi(pObj) ) - Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + if ( Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) ); + else + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); return; } Wlc_ObjForEachFanin( pObj, iFanin, i ) - Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vFlops, vPisNew ); + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); } -Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) +void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { - Vec_Int_t * vFlops; - Vec_Int_t * vPisNew; Wlc_Obj_t * pObj; - int i, CiId, CoId; + int i, Count = 0; Wlc_NtkCleanMarks( p ); - vFlops = Vec_IntAlloc( 100 ); - vPisNew = Vec_IntAlloc( 100 ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vFlops, vPisNew ); - Vec_IntForEachEntry( vFlops, CiId, i ) - { - CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); - Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkCo(p, CoId), vLeaves, vFlops, vPisNew ); - } - Vec_IntFree( vFlops ); - return vPisNew; + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObj( p, pObj, i ) + Count += pObj->Mark; +// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n", +// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops), +// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) ); + Vec_IntSort( vPisOld, 0 ); + Vec_IntSort( vPisNew, 0 ); + Vec_IntSort( vFlops, 0 ); + Wlc_NtkCleanMarks( p ); } /**Function************************************************************* - Synopsis [] + Synopsis [Derive abstraction based on the parameter values.] Description [] @@ -169,11 +173,17 @@ Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) ***********************************************************************/ Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { + Wlc_Ntk_t * pNtkNew = NULL; + Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); + Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); + Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); - Vec_Int_t * vPisNew = Wlc_NtkAbsMarkNodes( p, vLeaves ); - Wlc_Ntk_t * pNtkNew = Wlc_NtkDupDfs( p, 1, 1, vPisNew ); - Vec_IntFree( vPisNew ); + Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); Vec_BitFree( vLeaves ); + pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); + Vec_IntFree( vPisOld ); + Vec_IntFree( vPisNew ); + Vec_IntFree( vFlops ); return pNtkNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index cc69c636..346a9076 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -423,7 +423,7 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); - pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq, NULL ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); @@ -941,6 +941,7 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { + abctime clk = Abc_Clock(); extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); @@ -974,9 +975,10 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) } nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc), fVerbose ); if ( nFailed ) - printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); + printf( "Invariant verification failed for %d clauses (out of %d). ", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else - printf( "Invariant verification succeeded.\n" ); + printf( "Invariant verification succeeded. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 6eab4442..86b0c17e 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -648,7 +648,7 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) ); printf( "PO = %4d ", Wlc_NtkPoNum(p) ); printf( "FF = %4d ", Wlc_NtkFfNum(p) ); - printf( "Obj = %6d ", Wlc_NtkObjNum(p) ); + printf( "Obj = %6d ", Wlc_NtkObjNum(p) - Wlc_NtkPiNum(p) - Wlc_NtkPoNum(p) - Wlc_NtkFfNum(p) ); printf( "Mem = %.3f MB", 1.0*Wlc_NtkMemUsage(p)/(1<<20) ); printf( "\n" ); if ( fDistrib ) @@ -723,7 +723,7 @@ Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit ) assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) ); Wlc_NtkForEachCi( p, pObj, i ) if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) - Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i) ); + Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i - Wlc_NtkPiNum(p)) ); Vec_IntShrink( vInitNew, k ); return vInitNew; } @@ -803,7 +803,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -813,33 +813,14 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPi Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; - if ( vPisNew ) - { - // duplicate marked PIs - Wlc_NtkForEachPi( p, pObj, i ) - if ( pObj->Mark ) - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); - // duplicated additional PIs - Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + Wlc_NtkForEachCi( p, pObj, i ) + if ( !fMarked || pObj->Mark ) { unsigned Type = pObj->Type; - assert( !Wlc_ObjIsPi(pObj) ); - pObj->Type = WLC_OBJ_PI; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); pObj->Type = Type; } - } - else - { - Wlc_NtkForEachCi( p, pObj, i ) - if ( !fMarked || pObj->Mark ) - { - unsigned Type = pObj->Type; - if ( !fSeq ) pObj->Type = WLC_OBJ_PI; - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); - pObj->Type = Type; - } - } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); @@ -865,7 +846,72 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPi } } if ( p->pSpec ) - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Wlc_NtkTransferNames( pNew, p ); + return pNew; +} +Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +{ + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + Vec_Int_t * vFanins; + int i; + Wlc_NtkCleanCopy( p ); + pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); + pNew->fSmtLib = p->fSmtLib; + + // duplicate marked PIs + vFanins = Vec_IntAlloc( 100 ); + Wlc_NtkForEachObjVec( vPisOld, p, pObj, i ) + { + assert( Wlc_ObjIsPi(pObj) ); + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + } + // duplicate additional PIs + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + { + unsigned Type = pObj->Type; + int nFanins = Wlc_ObjFaninNum(pObj); + assert( !Wlc_ObjIsPi(pObj) ); + pObj->Type = WLC_OBJ_PI; + pObj->nFanins = 0; + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + pObj->nFanins = (unsigned)nFanins; + } + // duplicate flop outputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + { + assert( !Wlc_ObjIsPi(pObj) && Wlc_ObjIsCi(pObj) ); + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + } + + // duplicate logic cones of primary outputs + Wlc_NtkForEachPo( p, pObj, i ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + // duplidate logic cone of flop inputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj)), vFanins ); + + // duplicate POs + Wlc_NtkForEachPo( p, pObj, i ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), 0 ); + // duplicate flop inputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, Wlc_ObjFo2Fi(p, pObj)), 1 ); + Vec_IntFree( vFanins ); + + // mark flop outputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + pObj->Mark = 1; + if ( p->vInits ) + pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits ); + if ( p->pInits ) + pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits ); + Wlc_NtkCleanMarks( p ); + + if ( p->pSpec ) + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Wlc_NtkTransferNames( pNew, p ); return pNew; } diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index f7546b5b..e4a65ecf 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1, NULL ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); -- cgit v1.2.3 From 4e6978f242c867f060075f19796a64a986d722da Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 18:05:55 -0800 Subject: Profiling CEX minimization. --- src/sat/bmc/bmcCexCare.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c index a6613891..8ca916c3 100644 --- a/src/sat/bmc/bmcCexCare.c +++ b/src/sat/bmc/bmcCexCare.c @@ -251,6 +251,20 @@ Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t SeeAlso [] ***********************************************************************/ +Abc_Cex_t * Bmc_CexCareTotal( Abc_Cex_t ** pCexes, int nCexes ) +{ + int i, k, nWords = Abc_BitWordNum( pCexes[0]->nBits ); + Abc_Cex_t * pCexMin = Abc_CexAlloc( pCexes[0]->nRegs, pCexes[0]->nPis, pCexes[0]->iFrame + 1 ); + pCexMin->iPo = pCexes[0]->iPo; + pCexMin->iFrame = pCexes[0]->iFrame; + for ( i = 0; i < nWords; i++ ) + { + pCexMin->pData[i] = pCexes[0]->pData[i]; + for ( k = 1; k < nCexes; k++ ) + pCexMin->pData[i] &= pCexes[k]->pData[i]; + } + return pCexMin; +} Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose ) { int nTryCexes = 4; // belongs to range [1;4] @@ -314,15 +328,19 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, pCexBest = pCexMin[k]; } } - for ( k = 0; k < nTryCexes; k++ ) - if ( pCexBest != pCexMin[k] ) - Abc_CexFreeP( &pCexMin[k] ); - // verify and return if ( fVerbose ) { + Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes ); printf( "Final : " ); Bmc_CexPrint( pCexBest, Gia_ManPiNum(p), 0 ); + printf( "Total : " ); + Bmc_CexPrint( pTotal, Gia_ManPiNum(p), 0 ); + Abc_CexFreeP( &pTotal ); } + for ( k = 0; k < nTryCexes; k++ ) + if ( pCexBest != pCexMin[k] ) + Abc_CexFreeP( &pCexMin[k] ); + // verify and return if ( !Bmc_CexVerify( p, pCex, pCexBest ) ) printf( "Counter-example verification has failed.\n" ); else if ( fCheck ) -- cgit v1.2.3 From d335ee096e902844b9a94076e8ce5855f74d9bde Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 11:05:00 -0800 Subject: Standardizing the use of new CNF generator. Adding CNF variable connectivity information. --- src/aig/gia/gia.h | 2 ++ src/aig/gia/giaMf.c | 58 ++++++++++++++++++++++++++++++++++++++------- src/aig/gia/giaQbf.c | 12 ++++------ src/aig/gia/giaSatoko.c | 4 +--- src/base/abci/abcCollapse.c | 4 +--- src/base/abci/abcDetect.c | 3 +-- src/proof/cec/cecCec.c | 3 +-- src/proof/pdr/pdrInv.c | 8 +++---- src/sat/bmc/bmcBmcAnd.c | 3 +-- src/sat/bmc/bmcChain.c | 3 +-- src/sat/bmc/bmcClp.c | 10 ++++---- src/sat/bmc/bmcEnum.c | 4 +--- src/sat/bmc/bmcExpand.c | 4 +--- src/sat/bmc/bmcFault.c | 2 +- src/sat/bmc/bmcFx.c | 6 ++--- src/sat/bmc/bmcGen.c | 4 +--- src/sat/bmc/bmcICheck.c | 3 +-- 17 files changed, 76 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 3bc97e6b..6677e0ad 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -311,6 +311,7 @@ struct Jf_Par_t_ int fGenCnf; int fCnfObjIds; int fAddOrCla; + int fCnfMapping; int fPureAig; int fDoAverage; int fCutHashing; @@ -1405,6 +1406,7 @@ extern int Gia_MmStepReadMemUsage( Gia_MmStep_t * p ); /*=== giaMf.c ===========================================================*/ extern void Mf_ManSetDefaultPars( Jf_Par_t * pPars ); extern Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ); +extern void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose ); /*=== giaMini.c ===========================================================*/ extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName ); extern void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName ); diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index a500a839..24c1e6a0 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -388,6 +388,8 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla ) Gia_ManForEachCoId( p->pGia, Id, i ) pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[Id], 0); } + if ( p->pPars->fCnfMapping ) + pCnf->vMapping = Vec_IntStart( nVars ); // add clauses for the COs Gia_ManForEachCo( p->pGia, pObj, i ) { @@ -401,6 +403,14 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla ) pCnf->pClauses[iCla++] = pCnf->pClauses[0] + iLit; pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[Id], 1); pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[DriId], Gia_ObjFaninC0(pObj)); + // generate mapping + if ( pCnf->vMapping ) + { + Vec_IntWriteEntry( pCnf->vMapping, pCnfIds[Id], Vec_IntSize(pCnf->vMapping) ); + Vec_IntPush( pCnf->vMapping, 1 ); + Vec_IntPush( pCnf->vMapping, pCnfIds[DriId] ); + Vec_IntPush( pCnf->vMapping, Gia_ObjFaninC0(pObj) ? 0x55555555 : 0xAAAAAAAA ); + } } // add clauses for the mapping Gia_ManForEachAndReverseId( p->pGia, Id ) @@ -427,6 +437,35 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla ) if ( Mf_CubeLit(pCubes[c], k) ) pCnf->pClauses[0][iLit++] = Abc_Var2Lit( pFanins[k], Mf_CubeLit(pCubes[c], k) == 2 ); } + // generate mapping + if ( pCnf->vMapping ) + { + word pTruth[4], * pTruthP = Vec_MemReadEntry(p->vTtMem, iFunc); + assert( p->pPars->nLutSize <= 8 ); + Abc_TtCopy( pTruth, pTruthP, Abc_Truth6WordNum(p->pPars->nLutSize), Abc_LitIsCompl(iFunc) ); + assert( pCnfIds[Id] >= 0 && pCnfIds[Id] < nVars ); + Vec_IntWriteEntry( pCnf->vMapping, pCnfIds[Id], Vec_IntSize(pCnf->vMapping) ); + Vec_IntPush( pCnf->vMapping, Mf_CutSize(pCut) ); + for ( k = 0; k < Mf_CutSize(pCut); k++ ) + Vec_IntPush( pCnf->vMapping, pCnfIds[pCut[k+1]] ); + Vec_IntPush( pCnf->vMapping, (unsigned)pTruth[0] ); + if ( Mf_CutSize(pCut) >= 6 ) + { + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[0] >> 32) ); + if ( Mf_CutSize(pCut) >= 7 ) + { + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[1]) ); + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[1] >> 32) ); + } + if ( Mf_CutSize(pCut) >= 8 ) + { + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[2]) ); + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[2] >> 32) ); + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[3]) ); + Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[3] >> 32) ); + } + } + } } // constant clause pCnf->pClauses[iCla++] = pCnf->pClauses[0] + iLit; @@ -1636,28 +1675,29 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ) +void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose ) { Gia_Man_t * pNew; Jf_Par_t Pars, * pPars = &Pars; assert( nLutSize >= 3 && nLutSize <= 8 ); Mf_ManSetDefaultPars( pPars ); - pPars->fGenCnf = 1; - pPars->fCoarsen = !fCnfObjIds; - pPars->nLutSize = nLutSize; - pPars->fCnfObjIds = fCnfObjIds; - pPars->fAddOrCla = fAddOrCla; - pPars->fVerbose = fVerbose; + pPars->fGenCnf = 1; + pPars->fCoarsen = !fCnfObjIds; + pPars->nLutSize = nLutSize; + pPars->fCnfObjIds = fCnfObjIds; + pPars->fAddOrCla = fAddOrCla; + pPars->fCnfMapping = fMapping; + pPars->fVerbose = fVerbose; pNew = Mf_ManPerformMapping( pGia, pPars ); Gia_ManStopP( &pNew ); // Cnf_DataPrint( (Cnf_Dat_t *)pGia->pData, 1 ); - return (Cnf_Dat_t*)pGia->pData; + return pGia->pData; } void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ) { abctime clk = Abc_Clock(); Cnf_Dat_t * pCnf; - pCnf = Mf_ManGenerateCnf( p, nLutSize, fCnfObjIds, fAddOrCla, fVerbose ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, nLutSize, fCnfObjIds, fAddOrCla, 0, fVerbose ); Cnf_DataWriteIntoFile( pCnf, pFileName, 0, NULL, NULL ); // if ( fVerbose ) { diff --git a/src/aig/gia/giaQbf.c b/src/aig/gia/giaQbf.c index 4ca0bac3..2dfd83fc 100644 --- a/src/aig/gia/giaQbf.c +++ b/src/aig/gia/giaQbf.c @@ -48,8 +48,6 @@ struct Qbf_Man_t_ abctime clkSat; // SAT solver time }; -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -192,7 +190,7 @@ int Gia_ManSatEnum( Gia_Man_t * pGia, int nConfLimit, int nTimeOut, int fVerbose int i, iLit, iParVarBeg, Iter; int nSolutions = 0, RetValue = 0; abctime clkStart = Abc_Clock(); - pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); iParVarBeg = pCnf->nVars - Gia_ManPiNum(pGia);// - 1; Cnf_DataFree( pCnf ); @@ -247,7 +245,7 @@ void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars ) { // original problem: \exists p \forall x \exists y. M(p,x,y) // negated problem: \forall p \exists x \exists y. !M(p,x,y) - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); Vec_Int_t * vVarMap, * vForAlls, * vExists; Gia_Obj_t * pObj; char * pFileName; @@ -291,7 +289,7 @@ Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fVerbose ) Qbf_Man_t * p; Cnf_Dat_t * pCnf; Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) ); - pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) ); p = ABC_CALLOC( Qbf_Man_t, 1 ); p->clkStart = Abc_Clock(); @@ -426,7 +424,7 @@ Gia_Man_t * Gia_QbfCofactor( Gia_Man_t * p, int nPars, Vec_Int_t * vValues, Vec_ /* int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof ) { - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 ); int i, iFirstVar = sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof);// - 1; pCnf->pMan = NULL; Cnf_DataLift( pCnf, sat_solver_nvars(p->pSatSyn) ); @@ -459,7 +457,7 @@ void Cnf_SpecialDataLift( Cnf_Dat_t * p, int nVarsPlus, int firstPiVar, int last int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof ) { - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 ); int i, useold = 0; int iFirstVar = useold ? sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof) : pCnf->nVars - Gia_ManPiNum(pCof); //-1 pCnf->pMan = NULL; diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index fc8e5c28..db81bd85 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -50,7 +48,7 @@ extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfOb satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) { satoko_t * pSat = satoko_create(); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 1, 0, 0 ); int i, status; //sat_solver_setnvars( pSat, p->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c index 8c2b3b39..1542c25a 100644 --- a/src/base/abci/abcCollapse.c +++ b/src/base/abci/abcCollapse.c @@ -537,8 +537,6 @@ extern Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose ); extern int Gia_ManCoLargestSupp( Gia_Man_t * p, Vec_Wec_t * vSupps ); extern Vec_Wec_t * Gia_ManIsoStrashReduceInt( Gia_Man_t * p, Vec_Wec_t * vSupps, int fVerbose ); -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - /**Function************************************************************* Synopsis [Derives GIA for the network.] @@ -802,7 +800,7 @@ Vec_Ptr_t * Abc_GiaDeriveSops( Abc_Ntk_t * pNtkNew, Gia_Man_t * p, Vec_Wec_t * v if ( fCnfShared ) { vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); - pCnf = Mf_ManGenerateCnf( p, 8, 1, 0, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 1, 0, 0, 0 ); } vSopsRepr = Vec_PtrStart( Vec_IntSize(vReprs) ); pProgress = Extra_ProgressBarStart( stdout, Vec_IntSize(vReprs) ); diff --git a/src/base/abci/abcDetect.c b/src/base/abci/abcDetect.c index 8b8bba64..7adbed5d 100644 --- a/src/base/abci/abcDetect.c +++ b/src/base/abci/abcDetect.c @@ -901,8 +901,7 @@ Vec_Int_t * Abc_NtkFinCheckPair( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t } else { - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c index f7e45c57..be6df65f 100644 --- a/src/proof/cec/cecCec.c +++ b/src/proof/cec/cecCec.c @@ -225,8 +225,7 @@ int Cec_ManHandleSpecialCases( Gia_Man_t * p, Cec_ParCec_t * pPars ) ***********************************************************************/ int Cec_ManVerifyNaive( Gia_Man_t * p, Cec_ParCec_t * pPars ) { - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Gia_Obj_t * pObj0, * pObj1; abctime clkStart = Abc_Clock(); diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 95adb10c..fe759fff 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -626,8 +626,6 @@ Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce ) ***********************************************************************/ #define Pdr_ForEachCube( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 1 ) -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - Vec_Int_t * Pdr_InvMap( Vec_Int_t * vCounts ) { int i, k = 0, Count; @@ -779,7 +777,7 @@ int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) { int RetValue; - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); assert( sat_solver_nvars(pSat) == pCnf->nVars ); Cnf_DataFree( pCnf ); @@ -796,7 +794,7 @@ Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0; Vec_Int_t * vRes = NULL; // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0]; // create variables @@ -914,7 +912,7 @@ Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ) Vec_Int_t * vRes = NULL; abctime clk = Abc_Clock(); int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0; - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat; // sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Pdr_ForEachCube( pList, pCube, i ) diff --git a/src/sat/bmc/bmcBmcAnd.c b/src/sat/bmc/bmcBmcAnd.c index 8087046a..3490d34f 100644 --- a/src/sat/bmc/bmcBmcAnd.c +++ b/src/sat/bmc/bmcBmcAnd.c @@ -986,8 +986,7 @@ int Gia_ManBmcPerformInt( Gia_Man_t * pGia, Bmc_AndPar_t * pPars ) { // p->pFrames = Jf_ManDeriveCnf( pTemp = p->pFrames, 1 ); Gia_ManStop( pTemp ); // p->pCnf = (Cnf_Dat_t *)p->pFrames->pData; p->pFrames->pData = NULL; - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - p->pCnf = Mf_ManGenerateCnf( p->pFrames, pPars->nLutSize, 1, 0, pPars->fVerbose ); + p->pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p->pFrames, pPars->nLutSize, 1, 0, 0, pPars->fVerbose ); } Vec_IntFillExtra( p->vId2Var, Gia_ManObjNum(p->pFrames), 0 ); // create clauses for constant node diff --git a/src/sat/bmc/bmcChain.c b/src/sat/bmc/bmcChain.c index 324c7f6d..5af54306 100644 --- a/src/sat/bmc/bmcChain.c +++ b/src/sat/bmc/bmcChain.c @@ -185,10 +185,9 @@ Gia_Man_t * Gia_ManDupPosAndPropagateInit( Gia_Man_t * p ) } sat_solver * Gia_ManDeriveSatSolver( Gia_Man_t * p, Vec_Int_t * vSatIds ) { -// extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); sat_solver * pSat; Aig_Man_t * pAig = Gia_ManToAigSimple( p ); -// Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); +// Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); Cnf_Dat_t * pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) ); // save SAT vars for the primary inputs if ( vSatIds ) diff --git a/src/sat/bmc/bmcClp.c b/src/sat/bmc/bmcClp.c index 8a69fe56..cfc608b1 100644 --- a/src/sat/bmc/bmcClp.c +++ b/src/sat/bmc/bmcClp.c @@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -651,7 +649,7 @@ Vec_Str_t * Bmc_CollapseOneInt2( Gia_Man_t * p, int nCubeLim, int nBTLimit, int int iOut = 0, iLit, iVar, status, n, Count, Start; // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat[3] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), @@ -841,7 +839,7 @@ Vec_Str_t * Bmc_CollapseOneOld( Gia_Man_t * p, int nCubeLim, int nBTLimit, int f { int fVeryVerbose = fVerbose; int nVars = Gia_ManCiNum(p); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat[2] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0) }; sat_solver * pSatClean[2] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0) }; Vec_Str_t * vSop[2] = { Vec_StrAlloc(1000), Vec_StrAlloc(1000) }, * vRes = NULL; @@ -1173,7 +1171,7 @@ cleanup: } Vec_Str_t * Bmc_CollapseOne3( Gia_Man_t * p, int nCubeLim, int nBTLimit, int fCanon, int fReverse, int fVerbose ) { - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat0 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); sat_solver * pSat1 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); sat_solver * pSat2 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); @@ -1507,7 +1505,7 @@ cleanup: } Vec_Str_t * Bmc_CollapseOne( Gia_Man_t * p, int nCubeLim, int nBTLimit, int fCanon, int fReverse, int fVerbose ) { - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); Vec_Str_t * vSop = Bmc_CollapseOne_int( pSat, Gia_ManCiNum(p), nCubeLim, nBTLimit, fCanon, fReverse, fVerbose ); sat_solver_delete( pSat ); diff --git a/src/sat/bmc/bmcEnum.c b/src/sat/bmc/bmcEnum.c index 5fe2c1ed..45aeb2b3 100644 --- a/src/sat/bmc/bmcEnum.c +++ b/src/sat/bmc/bmcEnum.c @@ -29,8 +29,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -169,7 +167,7 @@ void Gia_ManDeriveOneTest( Gia_Man_t * p ) Gia_Man_t * pNew; Gia_Obj_t * pObj, * pRoot; Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); int i, iVar, nIter, iPoVarBeg = pCnf->nVars - Gia_ManCiNum(p); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Vec_Int_t * vLits = Vec_IntAlloc( 100 ); diff --git a/src/sat/bmc/bmcExpand.c b/src/sat/bmc/bmcExpand.c index f3ec999e..6c7a5988 100644 --- a/src/sat/bmc/bmcExpand.c +++ b/src/sat/bmc/bmcExpand.c @@ -33,8 +33,6 @@ ABC_NAMESPACE_IMPL_START // iterator thought the cubes #define Bmc_SopForEachCube( pSop, nVars, pCube ) for ( pCube = (pSop); *pCube; pCube += (nVars) + 3 ) -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -93,7 +91,7 @@ int Abc_ObjExpandCubes( Vec_Str_t * vSop, Gia_Man_t * p, int nVars ) int fReverse = 0; Vec_Int_t * vVars = Vec_IntAlloc( nVars ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); int v, n, iLit, status, nCubesNew, iCiVarBeg = sat_solver_nvars(pSat) - nVars; diff --git a/src/sat/bmc/bmcFault.c b/src/sat/bmc/bmcFault.c index 8dc2a57f..71eef2c4 100644 --- a/src/sat/bmc/bmcFault.c +++ b/src/sat/bmc/bmcFault.c @@ -280,7 +280,7 @@ static inline Cnf_Dat_t * Cnf_DeriveGiaRemapped( Gia_Man_t * p ) pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) ); Aig_ManStop( pAig ); return pCnf; -// return Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); +// return (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); } /**Function************************************************************* diff --git a/src/sat/bmc/bmcFx.c b/src/sat/bmc/bmcFx.c index 9cd37c88..15ea4f05 100644 --- a/src/sat/bmc/bmcFx.c +++ b/src/sat/bmc/bmcFx.c @@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -598,7 +596,7 @@ int Bmc_FxCompute( Gia_Man_t * p ) extern Gia_Man_t * Gia_ManDupOnsetOffset( Gia_Man_t * p ); Gia_Man_t * p2 = Gia_ManDupOnsetOffset( p ); // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p2, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p2, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // compute parameters int nOuts = Gia_ManCoNum(p); @@ -674,7 +672,7 @@ int Bmc_FxComputeOne( Gia_Man_t * p, int nIterMax, int nDiv2Add ) { int Extra = 1000; // create SAT solver - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); // compute parameters int nCiVars = Gia_ManCiNum(p); // PI count diff --git a/src/sat/bmc/bmcGen.c b/src/sat/bmc/bmcGen.c index 74af1b78..5d84ce87 100644 --- a/src/sat/bmc/bmcGen.c +++ b/src/sat/bmc/bmcGen.c @@ -29,8 +29,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -131,7 +129,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords ) int Gia_ManTestSatEnum( Gia_Man_t * p ) { abctime clk = Abc_Clock(), clk2, clkTotal = 0; - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0); int i, v, status, iLit, nWords = 1, iOutVar = 1, Count = 0; Vec_Int_t * vVars = Vec_IntAlloc( 1000 ); diff --git a/src/sat/bmc/bmcICheck.c b/src/sat/bmc/bmcICheck.c index a779b1ed..8d8c7c6b 100644 --- a/src/sat/bmc/bmcICheck.c +++ b/src/sat/bmc/bmcICheck.c @@ -392,11 +392,10 @@ int Bmc_PerformISearchOne( Gia_Man_t * p, int nFramesMax, int nTimeOut, int fRev pCnf = Cnf_DeriveGiaRemapped( pMiter ); else { - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); //pMiter = Jf_ManDeriveCnf( pTemp = pMiter, 0 ); //Gia_ManStop( pTemp ); //pCnf = (Cnf_Dat_t *)pMiter->pData; pMiter->pData = NULL; - pCnf = Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0, 0 ); } /* // collect positive literals -- cgit v1.2.3 From f2d096c9f04acf95e959842d63b6febf2f8eb786 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 13:20:20 -0800 Subject: Improving CEX minimization. --- src/base/io/io.c | 2 +- src/misc/util/utilCex.c | 25 +++-- src/sat/bmc/bmc.h | 4 +- src/sat/bmc/bmcCexCare.c | 263 ++++++++++++++++++++++++++++++---------------- src/sat/bmc/bmcCexTools.c | 6 +- 5 files changed, 196 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/base/io/io.c b/src/base/io/io.c index 4cec0157..c2cf15d4 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv ) Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose ); } else - pCare = Bmc_CexCareMinimize( pAig, pCex, fCheckCex, fVerbose ); + pCare = Bmc_CexCareMinimize( pAig, 0, pCex, fCheckCex, fVerbose ); Aig_ManStop( pAig ); } // output flop values (unaffected by the minimization) diff --git a/src/misc/util/utilCex.c b/src/misc/util/utilCex.c index 3acd7f77..59107dc9 100644 --- a/src/misc/util/utilCex.c +++ b/src/misc/util/utilCex.c @@ -272,9 +272,9 @@ void Abc_CexPrintStats( Abc_Cex_t * p ) p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits, Counter, 100.0 * Counter / (p->nBits - p->nRegs) ); } -void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nInputs ) +void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nRealPis ) { - int k, Counter = 0, Counter2 = 0; + int k, Counter = 0, CounterPi = 0, CounterPpi = 0; if ( p == NULL ) { printf( "The counter example is NULL.\n" ); @@ -285,16 +285,27 @@ void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nInputs ) printf( "The counter example is present but not available (pointer has value \"1\").\n" ); return; } + assert( nRealPis <= p->nPis ); for ( k = 0; k < p->nBits; k++ ) { Counter += Abc_InfoHasBit(p->pData, k); - if ( (k - p->nRegs) % p->nPis < nInputs ) - Counter2 += Abc_InfoHasBit(p->pData, k); + if ( nRealPis == p->nPis ) + continue; + if ( (k - p->nRegs) % p->nPis < nRealPis ) + CounterPi += Abc_InfoHasBit(p->pData, k); + else + CounterPpi += Abc_InfoHasBit(p->pData, k); } - printf( "CEX: Po =%4d Frame =%4d FF = %d PI = %d Bit =%8d 1s =%8d (%5.2f %%) 1sIn =%8d (%5.2f %%)\n", + printf( "CEX: Po =%4d Fr =%4d FF = %d PI = %d Bit =%7d 1 =%8d (%5.2f %%)", p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits, - Counter, 100.0 * Counter / (p->nBits - p->nRegs), - Counter2, 100.0 * Counter2 / (p->nBits - p->nRegs - (p->iFrame + 1) * (p->nPis - nInputs)) ); + Counter, 100.0 * Counter / ((p->iFrame + 1) * p->nPis ) ); + if ( nRealPis < p->nPis ) + { + printf( " 1pi =%8d (%5.2f %%) 1ppi =%8d (%5.2f %%)", + CounterPi, 100.0 * CounterPi / ((p->iFrame + 1) * nRealPis ), + CounterPpi, 100.0 * CounterPpi / ((p->iFrame + 1) * (p->nPis - nRealPis)) ); + } + printf( "\n" ); } /**Function************************************************************* diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h index 30538253..7820ebe6 100644 --- a/src/sat/bmc/bmc.h +++ b/src/sat/bmc/bmc.h @@ -164,7 +164,7 @@ extern int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t * extern int Gia_ManBmcPerform( Gia_Man_t * p, Bmc_AndPar_t * pPars ); /*=== bmcCexCare.c ==========================================================*/ extern Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare ); -extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose ); +extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ); extern void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, int fVerbose ); /*=== bmcCexCut.c ==========================================================*/ extern Gia_Man_t * Bmc_GiaTargetStates( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrBeg, int iFrEnd, int fCombOnly, int fGenAll, int fAllFrames, int fVerbose ); @@ -172,7 +172,7 @@ extern Aig_Man_t * Bmc_AigTargetStates( Aig_Man_t * p, Abc_Cex_t * pCex, i /*=== bmcCexMin.c ==========================================================*/ extern Abc_Cex_t * Saig_ManCexMinPerform( Aig_Man_t * pAig, Abc_Cex_t * pCex ); /*=== bmcCexTool.c ==========================================================*/ -extern void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose ); +extern void Bmc_CexPrint( Abc_Cex_t * pCex, int nRealPis, int fVerbose ); extern int Bmc_CexVerify( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare ); /*=== bmcICheck.c ==========================================================*/ extern void Bmc_PerformICheck( Gia_Man_t * p, int nFramesMax, int nTimeOut, int fEmpty, int fVerbose ); diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c index 8ca916c3..9c0a30d3 100644 --- a/src/sat/bmc/bmcCexCare.c +++ b/src/sat/bmc/bmcCexCare.c @@ -88,7 +88,7 @@ Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex /**Function************************************************************* - Synopsis [Backward propagation.] + Synopsis [Forward propagation.] Description [] @@ -97,21 +97,14 @@ Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex SeeAlso [] ***********************************************************************/ -void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGrow ) +void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Vec_Int_t * vPriosIn ) { Gia_Obj_t * pObj; int Prio, Prio0, Prio1; int i, Phase0, Phase1; - if ( (fGrow & 2) ) - { - Gia_ManForEachPi( p, pObj, i ) - pObj->Value = Abc_Var2Lit( f * pCex->nPis + (pCex->nPis-1-i) + 1, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) ); - } - else - { - Gia_ManForEachPi( p, pObj, i ) - pObj->Value = Abc_Var2Lit( f * pCex->nPis + i + 1, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) ); - } + assert( Vec_IntSize(vPriosIn) == pCex->nPis * (pCex->iFrame + 1) ); + Gia_ManForEachPi( p, pObj, i ) + pObj->Value = Vec_IntEntry( vPriosIn, f * pCex->nPis + i ); Gia_ManForEachAnd( p, pObj, i ) { Prio0 = Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value); @@ -119,37 +112,38 @@ void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGr Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj); Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj); if ( Phase0 && Phase1 ) - Prio = (fGrow & 1) ? Abc_MinInt(Prio0, Prio1) : Abc_MaxInt(Prio0, Prio1); - else if ( Phase0 && !Phase1 ) + Prio = Abc_MinInt(Prio0, Prio1); + else if ( Phase0 ) Prio = Prio1; - else if ( !Phase0 && Phase1 ) + else if ( Phase1 ) Prio = Prio0; else // if ( !Phase0 && !Phase1 ) - Prio = (fGrow & 1) ? Abc_MaxInt(Prio0, Prio1) : Abc_MinInt(Prio0, Prio1); - pObj->Value = Abc_Var2Lit( Prio, Phase0 & Phase1 ); + Prio = Abc_MaxInt(Prio0, Prio1); + pObj->Value = Abc_Var2Lit( Prio, Phase0 && Phase1 ); + pObj->fPhase = 0; } Gia_ManForEachCo( p, pObj, i ) pObj->Value = Abc_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) ); } -void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_Int_t * vPrios ) +void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPriosIn, Vec_Int_t * vPriosFf ) { - Gia_Obj_t * pObj, * pObjRo, * pObjRi; - int f, i; - Gia_ManConst0( p )->Value = 0; - Gia_ManForEachRi( p, pObj, i ) - pObj->Value = 0; - Vec_IntClear( vPrios ); + Gia_Obj_t * pObjRo, * pObjRi; + int i, f, ValueMax = Abc_Var2Lit( pCex->nPis * (pCex->iFrame + 1), 0 ); + Gia_ManConst0( p )->Value = ValueMax; + Gia_ManForEachRi( p, pObjRi, i ) + pObjRi->Value = ValueMax; + Vec_IntClear( vPriosFf ); for ( f = 0; f <= pCex->iFrame; f++ ) { Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) - Vec_IntPush( vPrios, (pObjRo->Value = pObjRi->Value) ); - Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow ); + Vec_IntPush( vPriosFf, (pObjRo->Value = pObjRi->Value) ); + Bmc_CexCarePropagateFwdOne( p, pCex, f, vPriosIn ); } } /**Function************************************************************* - Synopsis [Forward propagation.] + Synopsis [Backward propagation.] Description [] @@ -158,11 +152,11 @@ void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_In SeeAlso [] ***********************************************************************/ -void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGrow, Abc_Cex_t * pCexMin ) +void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex_t * pCexMin ) { - Gia_Obj_t * pObj; + Gia_Obj_t * pObj, * pFan0, * pFan1; int i, Phase0, Phase1; - Gia_ManForEachCand( p, pObj, i ) + Gia_ManForEachCi( p, pObj, i ) pObj->fPhase = 0; Gia_ManForEachCo( p, pObj, i ) if ( pObj->fPhase ) @@ -171,45 +165,37 @@ void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGr { if ( !pObj->fPhase ) continue; - Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj); - Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + Phase0 = Abc_LitIsCompl(pFan0->Value) ^ Gia_ObjFaninC0(pObj); + Phase1 = Abc_LitIsCompl(pFan1->Value) ^ Gia_ObjFaninC1(pObj); if ( Phase0 && Phase1 ) { - Gia_ObjFanin0(pObj)->fPhase = 1; - Gia_ObjFanin1(pObj)->fPhase = 1; + pFan0->fPhase = 1; + pFan1->fPhase = 1; } - else if ( Phase0 && !Phase1 ) - Gia_ObjFanin1(pObj)->fPhase = 1; - else if ( !Phase0 && Phase1 ) - Gia_ObjFanin0(pObj)->fPhase = 1; + else if ( Phase0 ) + pFan1->fPhase = 1; + else if ( Phase1 ) + pFan0->fPhase = 1; else // if ( !Phase0 && !Phase1 ) { - if ( Gia_ObjFanin0(pObj)->fPhase || Gia_ObjFanin1(pObj)->fPhase ) + if ( pFan0->fPhase || pFan1->fPhase ) continue; - if ( Gia_ObjIsPi(p, Gia_ObjFanin0(pObj)) ) - Gia_ObjFanin0(pObj)->fPhase = 1; - else if ( Gia_ObjIsPi(p, Gia_ObjFanin1(pObj)) ) - Gia_ObjFanin1(pObj)->fPhase = 1; -// else if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Txs_ObjIsJust(p, Gia_ObjFanin0(pObj)) ) -// Gia_ObjFanin0(pObj)->fPhase = 1; -// else if ( Gia_ObjIsAnd(Gia_ObjFanin1(pObj)) && Txs_ObjIsJust(p, Gia_ObjFanin1(pObj)) ) -// Gia_ObjFanin1(pObj)->fPhase = 1; + if ( Gia_ObjIsPi(p, pFan0) ) + pFan0->fPhase = 1; + else if ( Gia_ObjIsPi(p, pFan1) ) + pFan1->fPhase = 1; +// else if ( Gia_ObjIsAnd(pFan0) && Txs_ObjIsJust(p, pFan0) ) +// pFan0->fPhase = 1; +// else if ( Gia_ObjIsAnd(pFan1) && Txs_ObjIsJust(p, pFan1) ) +// pFan1->fPhase = 1; else { - if ( fGrow & 1 ) - { - if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) >= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) - Gia_ObjFanin0(pObj)->fPhase = 1; - else - Gia_ObjFanin1(pObj)->fPhase = 1; - } + if ( Abc_Lit2Var(pFan0->Value) > Abc_Lit2Var(pFan1->Value) ) + pFan0->fPhase = 1; else - { - if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) <= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) ) - Gia_ObjFanin0(pObj)->fPhase = 1; - else - Gia_ObjFanin1(pObj)->fPhase = 1; - } + pFan1->fPhase = 1; } } } @@ -217,23 +203,23 @@ void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGr if ( pObj->fPhase ) Abc_InfoSetBit( pCexMin->pData, pCexMin->nRegs + pCexMin->nPis * f + i ); } -Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPrios, int fGrow ) +Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPriosIn, Vec_Int_t * vPriosFf ) { Abc_Cex_t * pCexMin; - Gia_Obj_t * pObj, * pObjRo, * pObjRi; + Gia_Obj_t * pObjRo, * pObjRi; int f, i; pCexMin = Abc_CexAlloc( pCex->nRegs, pCex->nPis, pCex->iFrame + 1 ); pCexMin->iPo = pCex->iPo; pCexMin->iFrame = pCex->iFrame; - Gia_ManForEachCo( p, pObj, i ) - pObj->fPhase = 0; + Gia_ManForEachCo( p, pObjRi, i ) + pObjRi->fPhase = 0; for ( f = pCex->iFrame; f >= 0; f-- ) { Gia_ManPo(p, pCex->iPo)->fPhase = (int)(f == pCex->iFrame); - Gia_ManForEachRo( p, pObj, i ) - pObj->Value = Vec_IntEntry( vPrios, f * pCex->nRegs + i ); - Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow ); - Bmc_CexCarePropagateBwdOne( p, pCex, f, fGrow, pCexMin ); + Gia_ManForEachRo( p, pObjRo, i ) + pObjRo->Value = Vec_IntEntry( vPriosFf, f * pCex->nRegs + i ); + Bmc_CexCarePropagateFwdOne( p, pCex, f, vPriosIn ); + Bmc_CexCarePropagateBwdOne( p, pCex, f, pCexMin ); Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) pObjRi->fPhase = pObjRo->fPhase; } @@ -265,12 +251,12 @@ Abc_Cex_t * Bmc_CexCareTotal( Abc_Cex_t ** pCexes, int nCexes ) } return pCexMin; } -Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose ) +Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ) { int nTryCexes = 4; // belongs to range [1;4] Abc_Cex_t * pCexBest, * pCexMin[4] = {NULL}; - int k, nOnesBest, nOnesCur; - Vec_Int_t * vPrios; + int k, f, i, nOnesBest, nOnesCur, Counter = 0; + Vec_Int_t * vPriosIn, * vPriosFf; if ( pCex->nPis != Gia_ManPiNum(p) ) { printf( "Given CEX does to have same number of inputs as the AIG.\n" ); @@ -292,30 +278,118 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, if ( fVerbose ) { printf( "Original : " ); - Bmc_CexPrint( pCex, Gia_ManPiNum(p), 0 ); + Bmc_CexPrint( pCex, Gia_ManPiNum(p) - nPPis, 0 ); } - vPrios = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) ); + vPriosIn = Vec_IntAlloc( pCex->nPis * (pCex->iFrame + 1) ); + vPriosFf = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) ); for ( k = 0; k < nTryCexes; k++ ) { - Bmc_CexCarePropagateFwd(p, pCex, k, vPrios ); - assert( Vec_IntSize(vPrios) == pCex->nRegs * (pCex->iFrame + 1) ); + Counter = 0; + Vec_IntFill( vPriosIn, pCex->nPis * (pCex->iFrame + 1), 0 ); +/* + if ( k == 0 ) + { + for ( f = 0; f <= pCex->iFrame; f++ ) + for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = 0; f <= pCex->iFrame; f++ ) + for ( i = 0; i < nPPis; i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 1 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = 0; i < nPPis; i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 2 ) + { + for ( f = 0; f <= pCex->iFrame; f++ ) + for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = 0; f <= pCex->iFrame; f++ ) + for ( i = nPPis - 1; i >= 0; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 3 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis - 1; i >= 0; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else assert( 0 ); +*/ + if ( k == 0 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = 0; i < nPPis; i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 1 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis - 1; i >= 0; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 2 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = 0; i < nPPis; i++ ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else if ( k == 3 ) + { + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + for ( f = pCex->iFrame; f >= 0; f-- ) + for ( i = nPPis - 1; i >= 0; i-- ) + Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); + } + else assert( 0 ); + + assert( Counter == pCex->nPis * (pCex->iFrame + 1) ); + Bmc_CexCarePropagateFwd( p, pCex, vPriosIn, vPriosFf ); + assert( Vec_IntSize(vPriosFf) == pCex->nRegs * (pCex->iFrame + 1) ); if ( !Abc_LitIsCompl(Gia_ManPo(p, pCex->iPo)->Value) ) { printf( "Counter-example is invalid.\n" ); - Vec_IntFree( vPrios ); + Vec_IntFree( vPriosIn ); + Vec_IntFree( vPriosFf ); return NULL; } - pCexMin[k] = Bmc_CexCarePropagateBwd( p, pCex, vPrios, k ); + pCexMin[k] = Bmc_CexCarePropagateBwd( p, pCex, vPriosIn, vPriosFf ); if ( fVerbose ) { - if ( (k & 1) ) - printf( "Decrease : " ); - else - printf( "Increase : " ); - Bmc_CexPrint( pCexMin[k], Gia_ManPiNum(p), 0 ); + if ( k == 0 ) + printf( "PiUp FrUp: " ); + else if ( k == 1 ) + printf( "PiUp FrDn: " ); + else if ( k == 2 ) + printf( "PiDn FrUp: " ); + else if ( k == 3 ) + printf( "PiDn FrDn: " ); + else assert( 0 ); + Bmc_CexPrint( pCexMin[k], Gia_ManPiNum(p) - nPPis, 0 ); } } - Vec_IntFree( vPrios ); + Vec_IntFree( vPriosIn ); + Vec_IntFree( vPriosFf ); // select the best one pCexBest = pCexMin[0]; nOnesBest = Abc_CexCountOnes(pCexMin[0]); @@ -330,12 +404,12 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, } if ( fVerbose ) { - Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes ); + //Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes ); printf( "Final : " ); - Bmc_CexPrint( pCexBest, Gia_ManPiNum(p), 0 ); - printf( "Total : " ); - Bmc_CexPrint( pTotal, Gia_ManPiNum(p), 0 ); - Abc_CexFreeP( &pTotal ); + Bmc_CexPrint( pCexBest, Gia_ManPiNum(p) - nPPis, 0 ); + //printf( "Total : " ); + //Bmc_CexPrint( pTotal, Gia_ManPiNum(p) - nPPis, 0 ); + //Abc_CexFreeP( &pTotal ); } for ( k = 0; k < nTryCexes; k++ ) if ( pCexBest != pCexMin[k] ) @@ -347,10 +421,10 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, printf( "Counter-example verification succeeded.\n" ); return pCexBest; } -Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose ) +Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ) { Gia_Man_t * pGia = Gia_ManFromAigSimple( p ); - Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, pCex, fCheck, fVerbose ); + Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, nPPis, pCex, fCheck, fVerbose ); Gia_ManStop( pGia ); return pCexMin; } @@ -382,7 +456,14 @@ void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, in printf( "Counter-example verification succeeded.\n" ); Gia_ManStop( pGia ); } - +/* + { + Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 ); + Abc_Cex_t * pCex = Bmc_CexCareMinimize( pAig, 3*Saig_ManPiNum(pAig)/4, pAbc->pCex, 1, 1 ); + Aig_ManStop( pAig ); + Abc_CexFree( pCex ); + } +*/ //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/sat/bmc/bmcCexTools.c b/src/sat/bmc/bmcCexTools.c index 1c0d798c..9c80b278 100644 --- a/src/sat/bmc/bmcCexTools.c +++ b/src/sat/bmc/bmcCexTools.c @@ -304,10 +304,10 @@ void Bmc_CexBuildNetworkTest( Gia_Man_t * p, Abc_Cex_t * pCex ) SeeAlso [] ***********************************************************************/ -void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose ) +void Bmc_CexPrint( Abc_Cex_t * pCex, int nRealPis, int fVerbose ) { int i, k, Count, iBit = pCex->nRegs; - Abc_CexPrintStatsInputs( pCex, nInputs ); + Abc_CexPrintStatsInputs( pCex, nRealPis ); if ( !fVerbose ) return; @@ -315,7 +315,7 @@ void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose ) { Count = 0; printf( "%3d : ", i ); - for ( k = 0; k < nInputs; k++ ) + for ( k = 0; k < nRealPis; k++ ) { Count += Abc_InfoHasBit(pCex->pData, iBit); printf( "%d", Abc_InfoHasBit(pCex->pData, iBit++) ); -- cgit v1.2.3 From fce2b16a602dcdd3bef8529e51f9a06c2aaf1fec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 13:31:29 -0800 Subject: Re-introducing floating-point activity in the SAT solver. --- src/base/abci/abc.c | 8 ++++++-- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrInt.h | 1 + src/proof/pdr/pdrMan.c | 3 +++ 4 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 26e9c0f8..72fcafe2 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26157,7 +26157,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26308,6 +26308,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'c': pPars->fCtgs ^= 1; break; + case 't': + pPars->fUseAbs ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26349,7 +26352,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26378,6 +26381,7 @@ usage: Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 66990bfb..33397588 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -63,6 +63,7 @@ struct Pdr_Par_t_ int fSkipGeneral; // skips expensive generalization step int fSkipDown; // skips the application of down int fCtgs; // handle CTGs in down + int fUseAbs; // use abstraction int fVerbose; // verbose output` int fVeryVerbose; // very verbose output int fNotVerbose; // not printing line by line progress diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index dae20f0c..fb671700 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -90,6 +90,7 @@ struct Pdr_Man_t_ int * pOrder; // ordering of the lits Vec_Int_t * vActVars; // the counter of activation variables int iUseFrame; // the first used frame + Vec_Int_t * vAbs; // abstraction (mapping abstracted flop ID into its PPIs number) // terminary simulation Txs_Man_t * pTxs; // internal use diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index f9a14a07..b2df5e01 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -286,6 +286,8 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed p->vRes = Vec_IntAlloc( 100 ); // final result p->pCnfMan = Cnf_ManStart(); + if ( p->vAbs ) + p->vAbs = Vec_IntStart( Aig_ManRegNum(pAig) ); // ternary simulation p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL; // additional AIG data-members @@ -368,6 +370,7 @@ void Pdr_ManStop( Pdr_Man_t * p ) Vec_WecFreeP( &p->vVLits ); // CNF manager Cnf_ManStop( p->pCnfMan ); + Vec_IntFreeP( &p->vAbs ); // terminary simulation if ( p->pPars->fNewXSim ) Txs_ManStop( p->pTxs ); -- cgit v1.2.3 From 342d2d9f5cd3f89289d84e2dc695516ec959e252 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Fri, 10 Feb 2017 17:26:45 -0800 Subject: New fixed point data type. Expose all options to command line. Expose search statistics to users. --- src/base/abci/abc.c | 218 ++++++++++++++++++++++++++++++++++++++++++- src/sat/satoko/act_var.h | 38 +++++++- src/sat/satoko/satoko.h | 27 +++++- src/sat/satoko/solver.h | 13 --- src/sat/satoko/solver_api.c | 11 ++- src/sat/satoko/types.h | 32 ++++--- src/sat/satoko/utils/fixed.h | 67 +++++++++++++ 7 files changed, 363 insertions(+), 43 deletions(-) create mode 100644 src/sat/satoko/utils/fixed.h (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 26e9c0f8..ea0ed377 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23326,7 +23326,11 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Chv" ) ) != EOF ) +#ifdef SATOKO_ACT_VAR_FIXED + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) +#else + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) +#endif { switch ( c ) { @@ -23341,6 +23345,184 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( opts.conf_limit < 0 ) goto usage; break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + opts.prop_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.prop_limit < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); + goto usage; + } + opts.f_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.f_rst < 0 ) + goto usage; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); + goto usage; + } + opts.b_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.b_rst < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + goto usage; + } + opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + goto usage; + } + opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'J': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); + goto usage; + } + opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + goto usage; + } + opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.learnt_ratio < 0 ) + goto usage; + break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.garbage_max_ratio < 0 ) + goto usage; + break; + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); + goto usage; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); + goto usage; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + goto usage; + break; +#ifdef SATOKO_ACT_VAR_FIXED + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); + goto usage; + } + opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; + case 'U': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); + goto usage; + } + opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; +#endif case 'h': goto usage; case 'v': @@ -23379,9 +23561,37 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) } usage: - Abc_Print( -2, "usage: satoko [-CILDE num] [-hv].cnf\n" ); +#ifdef SATOKO_ACT_VAR_FIXED + Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRSTU num] [-hv].cnf\n" ); +#else + Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRS num] [-hv].cnf\n" ); +#endif Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); - Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-P num : limit on the number of propagations [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\n\tConstants used for restart heuristic:\n"); + Abc_Print( -2, "\t-D num : Constant value used by restart heuristics in forcing restarts [default = %f]\n", opts.f_rst ); + Abc_Print( -2, "\t-E num : Constant value used by restart heuristics in blocking restarts [default = %f]\n", opts.b_rst ); + Abc_Print( -2, "\t-F num : Lower bound n.of conflicts for start blocking restarts [default = %d]\n", opts.fst_block_rst ); + Abc_Print( -2, "\t-G num : Size of the moving avarege queue for LBD (force restart) [default = %d]\n", opts.sz_lbd_bqueue ); + Abc_Print( -2, "\t-H num : Size of the moving avarege queue for Trail size (block restart) [default = %d]\n", opts.sz_trail_bqueue ); + Abc_Print( -2, "\n\tConstants used for clause database reduction heuristic:\n"); + Abc_Print( -2, "\t-I num : N.of conflicts before first clause databese reduction [default = %d]\n", opts.n_conf_fst_reduce ); + Abc_Print( -2, "\t-J num : Increment to reduce [default = %d]\n", opts.inc_reduce ); + Abc_Print( -2, "\t-K num : Special increment to reduce [default = %d]\n", opts.inc_special_reduce ); + Abc_Print( -2, "\t-L num : Protecs clauses from deletion for one turn if its LBD is lower [default = %d]\n", opts.lbd_freeze_clause ); + Abc_Print( -2, "\t-M num : Percentage of learned clauses to remove [default = %d]\n", ( int )( 100 * opts.learnt_ratio ) ); + Abc_Print( -2, "\t-N num : Max percentage of garbage in clause database [default = %d]\n", ( int )( 100 * opts.garbage_max_ratio ) ); + Abc_Print( -2, "\n\tConstants used for binary resolution (clause minimization):\n"); + Abc_Print( -2, "\t-O num : Max clause size for binary resolution [default = %d]\n", opts.clause_max_sz_bin_resol ); + Abc_Print( -2, "\t-Q num : Min clause LBD for binary resolution [default = %d]\n", opts.clause_min_lbd_bin_resol ); + Abc_Print( -2, "\n\tConstants used for branching (VSIDS heuristic):\n"); + Abc_Print( -2, "\t-R num : Clause activity decay factor (when using float clause activity) [default = %f]\n", opts.clause_decay ); + Abc_Print( -2, "\t-S num : Varibale activity decay factor [default = %f]\n", opts.var_decay ); +#ifdef SATOKO_ACT_VAR_FIXED + Abc_Print( -2, "\t-T num : Variable activity limit valeu [default = 0x%08X]\n", opts.var_act_limit ); + Abc_Print( -2, "\t-U num : Variable activity re-scale factor [default = 0x%08X]\n", opts.var_act_rescale ); +#endif + Abc_Print( -2, "\n\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -38219,7 +38429,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fExtractAll ) { char Buffer[1000]; - Gia_Obj_t * pObj; + Gia_Obj_t * pObj; int i, nDigits = Abc_Base10Log(Gia_ManPoNum(pAbc->pGia)); Gia_ManForEachPo( pAbc->pGia, pObj, i ) { diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h index aa8a76ab..b1fdb756 100644 --- a/src/sat/satoko/act_var.h +++ b/src/sat/satoko/act_var.h @@ -16,7 +16,7 @@ #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#if defined SATOKO_ACT_VAR_DBLE || defined SATOKO_ACT_VAR_FLOAT +#if defined SATOKO_ACT_VAR_DBLE /** Re-scale the activity value for all variables. */ static inline void var_act_rescale(solver_t *s) @@ -25,8 +25,8 @@ static inline void var_act_rescale(solver_t *s) act_t *activity = vec_act_data(s->activity); for (i = 0; i < vec_act_size(s->activity); i++) - activity[i] *= VAR_ACT_RESCALE; - s->var_act_inc *= VAR_ACT_RESCALE; + activity[i] *= s->opts.var_act_rescale; + s->var_act_inc *= s->opts.var_act_rescale; } /** Increment the activity value of one variable ('var') @@ -36,7 +36,7 @@ static inline void var_act_bump(solver_t *s, unsigned var) act_t *activity = vec_act_data(s->activity); activity[var] += s->var_act_inc; - if (activity[var] > VAR_ACT_LIMIT) + if (activity[var] > s->opts.var_act_limit) var_act_rescale(s); if (heap_in_heap(s->var_order, var)) heap_decrease(s->var_order, var); @@ -49,6 +49,34 @@ static inline void var_act_decay(solver_t *s) s->var_act_inc *= (1 / s->opts.var_decay); } +#elif defined(SATOKO_ACT_VAR_FIXED) + +static inline void var_act_rescale(solver_t *s) +{ + unsigned i; + act_t *activity = (act_t *)vec_act_data(s->activity); + + for (i = 0; i < vec_act_size(s->activity); i++) + activity[i] = fixed_mult(activity[i], VAR_ACT_RESCALE); + s->var_act_inc = fixed_mult(s->var_act_inc, VAR_ACT_RESCALE); +} + +static inline void var_act_bump(solver_t *s, unsigned var) +{ + act_t *activity = (act_t *)vec_act_data(s->activity); + + activity[var] = fixed_add(activity[var], s->var_act_inc); + if (activity[var] > VAR_ACT_LIMIT) + var_act_rescale(s); + if (heap_in_heap(s->var_order, var)) + heap_decrease(s->var_order, var); +} + +static inline void var_act_decay(solver_t *s) +{ + s->var_act_inc = fixed_mult(s->var_act_inc, dble2fixed(1 / s->opts.var_decay)); +} + #else static inline void var_act_rescale(solver_t *s) @@ -77,7 +105,7 @@ static inline void var_act_decay(solver_t *s) s->var_act_inc += (s->var_act_inc >> 4); } -#endif /* SATOKO_ACT_VAR_DBLE || SATOKO_ACT_VAR_FLOAT */ +#endif /* SATOKO_ACT_VAR_DBLE || SATOKO_ACT_VAR_FIXED */ ABC_NAMESPACE_HEADER_END #endif /* satoko__act_var_h */ diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index fb07c6f9..363fe2fd 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -32,7 +32,7 @@ typedef struct satoko_opts satoko_opts_t; struct satoko_opts { /* Limits */ long conf_limit; /* Limit on the n.of conflicts */ - long prop_limit; /* Limit on the n.of implications */ + long prop_limit; /* Limit on the n.of propagations */ /* Constants used for restart heuristic */ double f_rst; /* Used to force a restart */ @@ -42,7 +42,7 @@ struct satoko_opts { unsigned sz_trail_bqueue; /* Size of the moving avarege queue for Trail size (block restart) */ /* Constants used for clause database reduction heuristic */ - unsigned n_conf_fst_reduce; /* N.of conflicts before first reduction */ + unsigned n_conf_fst_reduce; /* N.of conflicts before first clause databese reduction */ unsigned inc_reduce; /* Increment to reduce */ unsigned inc_special_reduce; /* Special increment to reduce */ unsigned lbd_freeze_clause; @@ -50,7 +50,9 @@ struct satoko_opts { /* VSIDS heuristic */ float clause_decay; - act_t var_decay; + double var_decay; + act_t var_act_limit; + act_t var_act_rescale; /* Binary resolution */ unsigned clause_max_sz_bin_resol; @@ -59,6 +61,21 @@ struct satoko_opts { char verbose; }; +typedef struct satoko_stats satoko_stats_t; +struct satoko_stats { + unsigned n_starts; + unsigned n_reduce_db; + + long n_decisions; + long n_propagations; + long n_inspects; + long n_conflicts; + + long n_original_lits; + long n_learnt_lits; +}; + + //===------------------------------------------------------------------------=== extern satoko_t *satoko_create(void); extern void satoko_destroy(satoko_t *); @@ -81,7 +98,9 @@ extern int satoko_solve(satoko_t *); * - The return value is either the size of the array or -1 in case the final * conflict cluase was not generated. */ -extern int satoko_final_conflict(satoko_t *, unsigned *); +extern int satoko_final_conflict(satoko_t *, unsigned *); + +extern satoko_stats_t satoko_stats(satoko_t *); ABC_NAMESPACE_HEADER_END #endif /* satoko__satoko_h */ diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index fe1d1ef5..a46b0c9d 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -38,19 +38,6 @@ enum { #define UNDEF 0xFFFFFFFF -struct satoko_stats { - unsigned n_starts; - unsigned n_reduce_db; - - long n_decisions; - long n_propagations; - long n_inspects; - long n_conflicts; - - long n_original_lits; - long n_learnt_lits; -}; - typedef struct solver_t_ solver_t; struct solver_t_ { /* User data */ diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 980cc160..ccab7685 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -12,8 +12,8 @@ #include #include "act_var.h" -#include "utils/misc.h" #include "solver.h" +#include "utils/misc.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_IMPL_START @@ -167,7 +167,9 @@ void satoko_default_opts(satoko_opts_t *opts) opts->lbd_freeze_clause = 30; opts->learnt_ratio = 0.5; /* VSIDS heuristic */ - opts->var_decay = (act_t) 0.95; + opts->var_act_limit = VAR_ACT_LIMIT; + opts->var_act_rescale = VAR_ACT_RESCALE; + opts->var_decay = VAR_ACT_DECAY; opts->clause_decay = (clause_act_t) 0.995; /* Binary resolution */ opts->clause_max_sz_bin_resol = 30; @@ -308,4 +310,9 @@ int satoko_final_conflict(solver_t *s, unsigned *out) } +satoko_stats_t satoko_stats(satoko_t *s) +{ + return s->stats; +} + ABC_NAMESPACE_IMPL_END diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index ee9363bc..7865ab0e 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -9,21 +9,22 @@ #ifndef satoko__types_h #define satoko__types_h +#include "utils/fixed.h" #include "utils/vec/vec_dble.h" -#include "utils/vec/vec_flt.h" #include "utils/vec/vec_uint.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -// #define SATOKO_ACT_VAR_DBLE -// #define SATOKO_ACT_VAR_FLOAT +#define SATOKO_ACT_VAR_DBLE +// #define SATOKO_ACT_VAR_FIXED // #define SATOKO_ACT_CLAUSE_FLOAT #ifdef SATOKO_ACT_VAR_DBLE #define VAR_ACT_INIT_INC 1.0 #define VAR_ACT_LIMIT (double)1e100 #define VAR_ACT_RESCALE (double)1e-100 + #define VAR_ACT_DECAY (double)0.95 typedef double act_t; typedef vec_dble_t vec_act_t ; #define vec_act_alloc(size) vec_dble_alloc(size) @@ -32,18 +33,19 @@ ABC_NAMESPACE_HEADER_START #define vec_act_data(vec) vec_dble_data(vec) #define vec_act_at(vec, idx) vec_dble_at(vec, idx) #define vec_act_push_back(vec, value) vec_dble_push_back(vec, value) -#elif defined(SATOKO_ACT_VAR_FLOAT) - #define VAR_ACT_INIT_INC 1.0 - #define VAR_ACT_LIMIT (float)1e20 - #define VAR_ACT_RESCALE (float)1e-20 - typedef float act_t; - typedef vec_flt_t vec_act_t ; - #define vec_act_alloc(size) vec_flt_alloc(size) - #define vec_act_free(vec) vec_flt_free(vec) - #define vec_act_size(vec) vec_flt_size(vec) - #define vec_act_data(vec) vec_flt_data(vec) - #define vec_act_at(vec, idx) vec_flt_at(vec, idx) - #define vec_act_push_back(vec, value) vec_flt_push_back(vec, value) +#elif defined(SATOKO_ACT_VAR_FIXED) + #define VAR_ACT_INIT_INC FIXED_ONE + #define VAR_ACT_LIMIT (fixed_t)0xDFFFFFFF + #define VAR_ACT_RESCALE (fixed_t)0x00000012 + #define VAR_ACT_DECAY (double)0.96 + typedef fixed_t act_t; + typedef vec_uint_t vec_act_t; + #define vec_act_alloc(size) vec_uint_alloc(size) + #define vec_act_free(vec) vec_uint_free(vec) + #define vec_act_size(vec) vec_uint_size(vec) + #define vec_act_data(vec) vec_uint_data(vec) + #define vec_act_at(vec, idx) vec_uint_at(vec, idx) + #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) #else #define VAR_ACT_INIT_INC (1 << 5) typedef unsigned act_t; diff --git a/src/sat/satoko/utils/fixed.h b/src/sat/satoko/utils/fixed.h new file mode 100644 index 00000000..91fc9b79 --- /dev/null +++ b/src/sat/satoko/utils/fixed.h @@ -0,0 +1,67 @@ +//===--- sort.h -------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__fixed_h +#define satoko__utils__fixed_h + +#include "misc.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef unsigned fixed_t; +static const int FIXED_W_BITS = 16; /* */ +static const int FIXED_F_BITS = 32 - FIXED_W_BITS; +static const int FIXED_F_MASK = (1 << FIXED_F_BITS) - 1; +static const fixed_t FIXED_MAX = 0xFFFFFFFF; +static const fixed_t FIXED_MIN = 0x00000000; +static const fixed_t FIXED_ONE = (1 << FIXED_F_BITS); + +/* Conversion functions */ +static inline fixed_t uint2fixed(unsigned a) { return a * FIXED_ONE; } +static inline unsigned fixed2uint(fixed_t a) +{ + return (a + (FIXED_ONE >> 1)) / FIXED_ONE; +} + +static inline float fixed2float(fixed_t a) { return (float)a / FIXED_ONE; } +static inline fixed_t float2fixed(float a) +{ + float temp = a * FIXED_ONE; + temp += (temp >= 0) ? 0.5f : -0.5f; + return (fixed_t)temp; +} + +static inline double fixed2dble(fixed_t a) { return (double)a / FIXED_ONE; } +static inline fixed_t dble2fixed(double a) +{ + double temp = a * FIXED_ONE; + temp += (temp >= 0) ? 0.5f : -0.5f; + return (fixed_t)temp; +} + +static inline fixed_t fixed_add(fixed_t a, fixed_t b) { return (a + b); } +static inline fixed_t fixed_mult(fixed_t a, fixed_t b) +{ + unsigned hi_a = (a >> FIXED_F_BITS), lo_a = (a & FIXED_F_MASK); + unsigned hi_b = (b >> FIXED_F_BITS), lo_b = (b & FIXED_F_MASK); + unsigned lo_ab = lo_a * lo_b; + unsigned ab_ab = (hi_a * lo_b) + (lo_a * hi_b); + unsigned hi_ret = (hi_a * hi_b) + (ab_ab >> FIXED_F_BITS); + unsigned lo_ret = lo_ab + (ab_ab << FIXED_W_BITS); + + /* Carry */ + if (lo_ret < lo_ab) + hi_ret++; + + return (hi_ret << FIXED_F_BITS) | (lo_ret >> FIXED_W_BITS); +} + +ABC_NAMESPACE_HEADER_END + +#endif /* satoko__utils__fixed_h */ -- cgit v1.2.3 From 8bff9aa1cd118028db47d886254dc4c76c516166 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 17:36:20 -0800 Subject: Adding PDR with abstraction. --- src/aig/gia/giaDup.c | 74 ++++++++++++++++++++++++++ src/base/io/io.c | 2 +- src/proof/pdr/pdrCore.c | 132 ++++++++++++++++++++++++++++------------------- src/proof/pdr/pdrInt.h | 10 ++-- src/proof/pdr/pdrInv.c | 1 + src/proof/pdr/pdrMan.c | 113 +++++++++++++++++++++++++++++++++++----- src/proof/pdr/pdrTsim.c | 36 ++++++++++++- src/sat/bmc/bmc.h | 3 +- src/sat/bmc/bmcCexCare.c | 62 +++++++++++----------- 9 files changed, 330 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index b0ba3472..2a0fe6e3 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -220,6 +220,80 @@ Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Duplicates AIG while putting objects in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int k, Flop, Used; + assert( Vec_IntSize(vMapFf2Ppi) == Vec_IntSize(vMapPpi2Ff) + Vec_IntCountEntry(vMapFf2Ppi, -1) ); + Gia_ManFillValue( p ); + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + // create inputs + Gia_ManForEachPi( p, pObj, k ) + pObj->Value = Gia_ManAppendCi(pNew); + Vec_IntForEachEntry( vMapPpi2Ff, Flop, k ) + { + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); + pObj->Value = Gia_ManAppendCi(pNew); + } + Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop ) + { + if ( Used >= 0 ) + { + assert( pObj->Value != ~0 ); + continue; + } + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); + assert( pObj->Value == ~0 ); + pObj->Value = Gia_ManAppendCi(pNew); + } + Gia_ManForEachCi( p, pObj, k ) + assert( pObj->Value != ~0 ); + // create nodes + Gia_ManForEachPo( p, pObj, k ) + Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop ) + { + if ( Used >= 0 ) + continue; + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); + pObj = Gia_ObjRoToRi( p, pObj ); + Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); + } + // create outputs + Gia_ManForEachPo( p, pObj, k ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop ) + { + if ( Used >= 0 ) + continue; + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); + pObj = Gia_ObjRoToRi( p, pObj ); + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) - Vec_IntSize(vMapPpi2Ff) ); + assert( Gia_ManPiNum(pNew) == Gia_ManPiNum(p) + Vec_IntSize(vMapPpi2Ff) ); + assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); + assert( Gia_ManPoNum(pNew) == Gia_ManPoNum(p) ); + assert( Gia_ManCoNum(pNew) == Gia_ManCoNum(p) - Vec_IntSize(vMapPpi2Ff) ); + return pNew; +} + + /**Function************************************************************* Synopsis [Duplicates AIG while putting objects in the DFS order.] diff --git a/src/base/io/io.c b/src/base/io/io.c index c2cf15d4..2e1ae591 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv ) Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose ); } else - pCare = Bmc_CexCareMinimize( pAig, 0, pCex, fCheckCex, fVerbose ); + pCare = Bmc_CexCareMinimize( pAig, Saig_ManPiNum(pAig), pCex, 4, fCheckCex, fVerbose ); Aig_ManStop( pAig ); } // output flop values (unaffected by the minimization) diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 74a15e40..47f0ac8b 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -420,6 +420,8 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, { assert( pCubeMin->Lits[i] >= 0 ); assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); + if ( (Vec_IntEntry(p->vPrio, pCubeMin->Lits[i] / 2) >> p->nPrioShift) == 0 ) + p->nAbsFlops++; Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift ); } @@ -778,6 +780,8 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ) { assert( pCubeMin->Lits[i] >= 0 ); assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) ); + if ( (Vec_IntEntry(p->vPrio, pCubeMin->Lits[i] / 2) >> p->nPrioShift) == 0 ) + p->nAbsFlops++; Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift ); } Vec_VecPush( p->vClauses, k, pCubeMin ); // consume ref @@ -837,29 +841,43 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Pdr_Set_t * pCube = NULL; Aig_Obj_t * pObj; Abc_Cex_t * pCexNew; - int k, RetValue = -1; + int iFrame, RetValue = -1; int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) ); abctime clkStart = Abc_Clock(), clkOne = 0; p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0; assert( Vec_PtrSize(p->vSolvers) == 0 ); // in the multi-output mode, mark trivial POs (those fed by const0) as solved if ( p->pPars->fSolveAll ) - Saig_ManForEachPo( p->pAig, pObj, k ) + Saig_ManForEachPo( p->pAig, pObj, iFrame ) if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) ) { - Vec_IntWriteEntry( p->pPars->vOutMap, k, 1 ); // unsat + Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat p->pPars->nProveOuts++; if ( p->pPars->fUseBridge ) - Gia_ManToBridgeResult( stdout, 1, NULL, k ); + Gia_ManToBridgeResult( stdout, 1, NULL, iFrame ); } // create the first timeframe p->pPars->timeLastSolved = Abc_Clock(); - Pdr_ManCreateSolver( p, (k = 0) ); + Pdr_ManCreateSolver( p, (iFrame = 0) ); while ( 1 ) { - p->nFrames = k; - assert( k == Vec_PtrSize(p->vSolvers)-1 ); - p->iUseFrame = Abc_MaxInt(k, 1); + if ( p->pPars->fUseAbs && iFrame == 2 ) + { + int i, Prio, Num = Saig_ManPiNum(p->pAig); + assert( p->vAbsFlops == NULL ); + p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) ); + p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) ); + p->vMapPpi2Ff = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( p->vPrio, Prio, i ) + if ( Prio >> p->nPrioShift ) + Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); + } + if ( p->pPars->fUseAbs && p->vAbsFlops ) + printf( "Starting frame %d with %d flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops) ); + + p->nFrames = iFrame; + assert( iFrame == Vec_PtrSize(p->vSolvers)-1 ); + p->iUseFrame = Abc_MaxInt(iFrame, 1); Saig_ManForEachPo( p->pAig, pObj, p->iOutCur ) { // skip disproved outputs @@ -876,16 +894,16 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) { if ( !p->pPars->fSolveAll ) { - pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), k*Saig_ManPoNum(p->pAig)+p->iOutCur ); + pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ); p->pAig->pSeqModel = pCexNew; return 0; // SAT } - pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), k*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1; + pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1; p->pPars->nFailOuts++; if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 ); if ( !p->pPars->fNotVerbose ) Abc_Print( 1, "Output %*d was trivially asserted in frame %2d (solved %*d out of %*d outputs).\n", - nOutDigits, p->iOutCur, k, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); + nOutDigits, p->iOutCur, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ); if ( p->pPars->fUseBridge ) Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo ); @@ -895,8 +913,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Quitting due to callback on fail.\n" ); - p->pPars->iFrame = k; + Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( p->pPars->nFailOuts + p->pPars->nDropOuts == Saig_ManPoNum(p->pAig) ) @@ -918,11 +936,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap ); - p->pPars->iFrame = k; + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + p->pPars->iFrame = iFrame; return -1; } - RetValue = Pdr_ManCheckCube( p, k, NULL, &pCube, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0 ); if ( RetValue == 1 ) break; if ( RetValue == -1 ) @@ -930,9 +948,9 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( p->timeToStop && Abc_Clock() > p->timeToStop ) - Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut ); + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) - Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap ); + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne ) { Pdr_QueueClean( p ); @@ -940,10 +958,10 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) break; // keep solving } else if ( p->pPars->nConfLimit ) - Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit ); + Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame ); else if ( p->pPars->fVerbose ) - Abc_Print( 1, "Computation cancelled by the callback.\n" ); - p->pPars->iFrame = k; + Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( RetValue == 0 ) @@ -954,9 +972,9 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( p->timeToStop && Abc_Clock() > p->timeToStop ) - Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut ); + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) - Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap ); + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne ) { Pdr_QueueClean( p ); @@ -964,25 +982,33 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) break; // keep solving } else if ( p->pPars->nConfLimit ) - Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit ); + Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame ); else if ( p->pPars->fVerbose ) - Abc_Print( 1, "Computation cancelled by the callback.\n" ); - p->pPars->iFrame = k; + Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( RetValue == 0 ) { if ( fPrintClauses ) { - Abc_Print( 1, "*** Clauses after frame %d:\n", k ); + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart ); - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; if ( !p->pPars->fSolveAll ) { - p->pAig->pSeqModel = Pdr_ManDeriveCex(p); + Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p); + if ( pCex == NULL ) + { + assert( p->pPars->fUseAbs ); + Pdr_QueueClean( p ); + pCube = NULL; + break; // keep solving + } + p->pAig->pSeqModel = pCex; return 0; // SAT } p->pPars->nFailOuts++; @@ -997,13 +1023,13 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Quitting due to callback on fail.\n" ); - p->pPars->iFrame = k; + Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( !p->pPars->fNotVerbose ) Abc_Print( 1, "Output %*d was asserted in frame %2d (%2d) (solved %*d out of %*d outputs).\n", - nOutDigits, p->iOutCur, k, k, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); + nOutDigits, p->iOutCur, iFrame, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); if ( p->pPars->nFailOuts == Saig_ManPoNum(p->pAig) ) return 0; // all SAT Pdr_QueueClean( p ); @@ -1025,7 +1051,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, -1 ); if ( !p->pPars->fNotVerbose ) - Abc_Print( 1, "Timing out on output %*d.\n", nOutDigits, p->iOutCur ); + Abc_Print( 1, "Timing out on output %*d in frame %d.\n", nOutDigits, p->iOutCur, iFrame ); } p->timeToStopOne = 0; } @@ -1036,11 +1062,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) // open a new timeframe p->nQueLim = p->pPars->nRestLimit; assert( pCube == NULL ); - Pdr_ManSetPropertyOutput( p, k ); - Pdr_ManCreateSolver( p, ++k ); + Pdr_ManSetPropertyOutput( p, iFrame ); + Pdr_ManCreateSolver( p, ++iFrame ); if ( fPrintClauses ) { - Abc_Print( 1, "*** Clauses after frame %d:\n", k ); + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } // push clauses into this timeframe @@ -1052,11 +1078,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( !p->pPars->fSilent ) { if ( p->timeToStop && Abc_Clock() > p->timeToStop ) - Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut ); + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); else - Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit ); + Abc_Print( 1, "Reached conflict limit (%d) in frame.\n", p->pPars->nConfLimit, iFrame ); } - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; return -1; } if ( RetValue ) @@ -1067,17 +1093,17 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Pdr_ManReportInvariant( p ); if ( !p->pPars->fSilent ) Pdr_ManVerifyInvariant( p ); - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; // count the number of UNSAT outputs p->pPars->nProveOuts = Saig_ManPoNum(p->pAig) - p->pPars->nFailOuts - p->pPars->nDropOuts; // convert previously 'unknown' into 'unsat' if ( p->pPars->vOutMap ) - for ( k = 0; k < Saig_ManPoNum(p->pAig); k++ ) - if ( Vec_IntEntry(p->pPars->vOutMap, k) == -2 ) // unknown + for ( iFrame = 0; iFrame < Saig_ManPoNum(p->pAig); iFrame++ ) + if ( Vec_IntEntry(p->pPars->vOutMap, iFrame) == -2 ) // unknown { - Vec_IntWriteEntry( p->pPars->vOutMap, k, 1 ); // unsat + Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat if ( p->pPars->fUseBridge ) - Gia_ManToBridgeResult( stdout, 1, NULL, k ); + Gia_ManToBridgeResult( stdout, 1, NULL, iFrame ); } if ( p->pPars->nProveOuts == Saig_ManPoNum(p->pAig) ) return 1; // UNSAT @@ -1091,44 +1117,44 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) // check termination if ( p->pPars->pFuncStop && p->pPars->pFuncStop(p->pPars->RunId) ) { - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; return -1; } if ( p->timeToStop && Abc_Clock() > p->timeToStop ) { if ( fPrintClauses ) { - Abc_Print( 1, "*** Clauses after frame %d:\n", k ); + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut ); - p->pPars->iFrame = k; + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + p->pPars->iFrame = iFrame; return -1; } if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) { if ( fPrintClauses ) { - Abc_Print( 1, "*** Clauses after frame %d:\n", k ); + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) - Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap ); - p->pPars->iFrame = k; + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + p->pPars->iFrame = iFrame; return -1; } - if ( p->pPars->nFrameMax && k >= p->pPars->nFrameMax ) + if ( p->pPars->nFrameMax && iFrame >= p->pPars->nFrameMax ) { if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); if ( !p->pPars->fSilent ) Abc_Print( 1, "Reached limit on the number of timeframes (%d).\n", p->pPars->nFrameMax ); - p->pPars->iFrame = k; + p->pPars->iFrame = iFrame; return -1; } } diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index fb671700..2ee4ae09 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -31,6 +31,7 @@ #include "sat/bsat/satSolver.h" #include "pdr.h" #include "misc/hash/hashInt.h" +#include "aig/gia/giaAig.h" ABC_NAMESPACE_HEADER_START @@ -71,6 +72,7 @@ struct Pdr_Man_t_ // input problem Pdr_Par_t * pPars; // parameters Aig_Man_t * pAig; // user's AIG + Gia_Man_t * pGia; // user's AIG // static CNF representation Cnf_Man_t * pCnfMan; // CNF manager Cnf_Dat_t * pCnf1; // CNF for this AIG @@ -90,7 +92,10 @@ struct Pdr_Man_t_ int * pOrder; // ordering of the lits Vec_Int_t * vActVars; // the counter of activation variables int iUseFrame; // the first used frame - Vec_Int_t * vAbs; // abstraction (mapping abstracted flop ID into its PPIs number) + int nAbsFlops; // the number of flops used + Vec_Int_t * vAbsFlops; // flops currently used + Vec_Int_t * vMapFf2Ppi; + Vec_Int_t * vMapPpi2Ff; // terminary simulation Txs_Man_t * pTxs; // internal use @@ -161,8 +166,6 @@ static inline abctime Pdr_ManTimeLimit( Pdr_Man_t * p ) /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== pdrCex.c ==========================================================*/ -extern Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ); /*=== pdrCnf.c ==========================================================*/ extern int Pdr_ObjSatVar( Pdr_Man_t * p, int k, int Pol, Aig_Obj_t * pObj ); extern int Pdr_ObjRegNum( Pdr_Man_t * p, int k, int iSatVar ); @@ -183,6 +186,7 @@ extern Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce extern Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrioInit ); extern void Pdr_ManStop( Pdr_Man_t * p ); extern Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ); +extern Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ); /*=== pdrSat.c ==========================================================*/ extern sat_solver * Pdr_ManCreateSolver( Pdr_Man_t * p, int k ); extern sat_solver * Pdr_ManFetchSolver( Pdr_Man_t * p, int k ); diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index fe759fff..7a8a66d6 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -81,6 +81,7 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) for ( i = ThisSize; i < 70; i++ ) Abc_Print( 1, " " ); Abc_Print( 1, "%6d", p->nQueMax ); + Abc_Print( 1, "%6d", p->nAbsFlops ); Abc_Print( 1, "%10.2f sec", 1.0*Time/CLOCKS_PER_SEC ); if ( p->pPars->fSolveAll ) Abc_Print( 1, " CEX =%4d", p->pPars->nFailOuts ); diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index b2df5e01..e2807c92 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -19,7 +19,7 @@ ***********************************************************************/ #include "pdrInt.h" -#include "aig/gia/giaAig.h" +#include "sat/bmc/bmc.h" ABC_NAMESPACE_IMPL_START @@ -233,13 +233,6 @@ Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls ) //Vec_IntPrint( vCosts ); return vCosts; } -Vec_Int_t * Pdr_ManDeriveFlopPriorities( Aig_Man_t * pAig, int fMuxCtrls ) -{ - Gia_Man_t * pGia = Gia_ManFromAigSimple(pAig); - Vec_Int_t * vRes = Pdr_ManDeriveFlopPriorities2(pGia, fMuxCtrls); - Gia_ManStop( pGia ); - return vRes; -} /**Function************************************************************* @@ -258,6 +251,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p = ABC_CALLOC( Pdr_Man_t, 1 ); p->pPars = pPars; p->pAig = pAig; + p->pGia = (pPars->fFlopPrio || p->pPars->fNewXSim || p->pPars->fUseAbs) ? Gia_ManFromAigSimple(pAig) : NULL; p->vSolvers = Vec_PtrAlloc( 0 ); p->vClauses = Vec_VecAlloc( 0 ); p->pQueue = NULL; @@ -270,7 +264,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio if ( vPrioInit ) p->vPrio = vPrioInit; else if ( pPars->fFlopPrio ) - p->vPrio = Pdr_ManDeriveFlopPriorities(pAig, 1); + p->vPrio = Pdr_ManDeriveFlopPriorities2(p->pGia, 1); else if ( p->pPars->fNewXSim ) p->vPrio = Vec_IntStartNatural( Aig_ManRegNum(pAig) ); else @@ -286,8 +280,6 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed p->vRes = Vec_IntAlloc( 100 ); // final result p->pCnfMan = Cnf_ManStart(); - if ( p->vAbs ) - p->vAbs = Vec_IntStart( Aig_ManRegNum(pAig) ); // ternary simulation p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL; // additional AIG data-members @@ -328,6 +320,7 @@ void Pdr_ManStop( Pdr_Man_t * p ) Pdr_Set_t * pCla; sat_solver * pSat; int i, k; + Gia_ManStopP( &p->pGia ); Aig_ManCleanMarkAB( p->pAig ); if ( p->pPars->fVerbose ) { @@ -370,7 +363,9 @@ void Pdr_ManStop( Pdr_Man_t * p ) Vec_WecFreeP( &p->vVLits ); // CNF manager Cnf_ManStop( p->pCnfMan ); - Vec_IntFreeP( &p->vAbs ); + Vec_IntFreeP( &p->vAbsFlops ); + Vec_IntFreeP( &p->vMapFf2Ppi ); + Vec_IntFreeP( &p->vMapPpi2Ff ); // terminary simulation if ( p->pPars->fNewXSim ) Txs_ManStop( p->pTxs ); @@ -419,7 +414,6 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ) nFrames++; // create the counter-example pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), nFrames ); -// pCex->iPo = (p->pPars->iOutput==-1)? 0 : p->pPars->iOutput; pCex->iPo = p->iOutCur; pCex->iFrame = nFrames-1; for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) @@ -428,6 +422,8 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ) Lit = pObl->pState->Lits[i]; if ( lit_sign(Lit) ) continue; + if ( lit_var(Lit) >= pCex->nPis ) // allows PPI literals to be thrown away + continue; assert( lit_var(Lit) < pCex->nPis ); Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) ); } @@ -437,6 +433,97 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p ) return pCex; } +/**Function************************************************************* + + Synopsis [Derives counter-example when abstraction is used.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) +{ + extern Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi ); + + Gia_Man_t * pAbs; + Abc_Cex_t * pCex, * pCexCare; + Pdr_Obl_t * pObl; + int i, f, Lit, Flop, nFrames = 0; + int nPis = Saig_ManPiNum(p->pAig); + int nFfRefined = 0; + if ( !p->pPars->fUseAbs ) + return Pdr_ManDeriveCex(p); + // restore previous map + Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i ) + { + assert( Vec_IntEntry( p->vMapFf2Ppi, Flop ) == i ); + Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, -1 ); + } + Vec_IntClear( p->vMapPpi2Ff ); + // count the number of frames + for ( pObl = p->pQueue; pObl; pObl = pObl->pNext ) + { + for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ ) + { + Lit = pObl->pState->Lits[i]; + if ( lit_var(Lit) < nPis ) // PI literal + continue; + Flop = lit_var(Lit) - nPis; + if ( Vec_IntEntry(p->vMapFf2Ppi, Flop) >= 0 ) // already used PPI literal + continue; + Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, Vec_IntSize(p->vMapPpi2Ff) ); + Vec_IntPush( p->vMapPpi2Ff, Flop ); + } + nFrames++; + } + if ( Vec_IntSize(p->vMapPpi2Ff) == 0 ) // no PPIs -- this is a real CEX + return Pdr_ManDeriveCex(p); + // create the counter-example + pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames ); + pCex->iPo = p->iOutCur; + pCex->iFrame = nFrames-1; + for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) + for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ ) + { + Lit = pObl->pState->Lits[i]; + if ( lit_sign(Lit) ) + continue; + if ( lit_var(Lit) < nPis ) // PI literal + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) ); + else + { + int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis); + assert( iPPI < pCex->nPis ); + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI ); + } + } + assert( f == nFrames ); + // perform CEX minimization + pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi ); + pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 1, 1 ); + Gia_ManStop( pAbs ); + assert( pCexCare->nPis == pCex->nPis ); + Abc_CexFree( pCex ); + // detect care PPIs + for ( f = 0; f < nFrames; f++ ) + { + for ( i = nPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + { + if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted + Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++; + } + } + Abc_CexFree( pCexCare ); + if ( nFfRefined == 0 ) // no refinement -- this is a real CEX + return Pdr_ManDeriveCex(p); + printf( "CEX-based refinement refined %d flops.\n", nFfRefined ); + return NULL; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 0bcb6e0c..1cff03c7 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -440,7 +440,7 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, NULL ); if ( !Saig_ObjIsLo( p->pAig, pObj ) ) continue; Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 ) + if ( Vec_IntEntry(vPrio, Entry) ) continue; Vec_IntClear( vUndo ); if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) @@ -454,7 +454,7 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, NULL ); if ( !Saig_ObjIsLo( p->pAig, pObj ) ) continue; Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 ) + if ( !Vec_IntEntry(vPrio, Entry) ) continue; Vec_IntClear( vUndo ); if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) ) @@ -473,7 +473,39 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); Pdr_ManDeriveResult( p->pAig, vCiObjs, vCiVals, vCi2Rem, vRes, vPiLits ); assert( Vec_IntSize(vRes) > 0 ); //p->tTsim += Abc_Clock() - clk; + // move abstracted literals from flops to inputs + if ( p->pPars->fUseAbs && p->vAbsFlops ) + { + int i, iLit, k = 0, fAllNegs = 1; + Vec_IntForEachEntry( vRes, iLit, i ) + { + if ( Vec_IntEntry(p->vAbsFlops, Abc_Lit2Var(iLit)) ) // used flop + { + Vec_IntWriteEntry( vRes, k++, iLit ); + fAllNegs &= Abc_LitIsCompl(iLit); + } + else + Vec_IntPush( vPiLits, 2*Saig_ManPiNum(p->pAig) + iLit ); + } + Vec_IntShrink( vRes, k ); + if ( fAllNegs ) // insert any positive literal + { + Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) + { + if ( !Saig_ObjIsLo( p->pAig, pObj ) ) + continue; + if ( Vec_IntEntry(vCiVals, i) ) + { + Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); + Vec_IntPush( vRes, Abc_Var2Lit(Entry, 0) ); + break; + } + } + } + } pRes = Pdr_SetCreate( vRes, vPiLits ); + assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); + //ZH: Disabled assertion because this invariant doesn't hold with down //because of the join operation which can bring in initial states //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h index 7820ebe6..a3f353c2 100644 --- a/src/sat/bmc/bmc.h +++ b/src/sat/bmc/bmc.h @@ -164,7 +164,8 @@ extern int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t * extern int Gia_ManBmcPerform( Gia_Man_t * p, Bmc_AndPar_t * pPars ); /*=== bmcCexCare.c ==========================================================*/ extern Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare ); -extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ); +extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose ); +extern Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose ); extern void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, int fVerbose ); /*=== bmcCexCut.c ==========================================================*/ extern Gia_Man_t * Bmc_GiaTargetStates( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrBeg, int iFrEnd, int fCombOnly, int fGenAll, int fAllFrames, int fVerbose ); diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c index 9c0a30d3..cc3e85ea 100644 --- a/src/sat/bmc/bmcCexCare.c +++ b/src/sat/bmc/bmcCexCare.c @@ -251,9 +251,9 @@ Abc_Cex_t * Bmc_CexCareTotal( Abc_Cex_t ** pCexes, int nCexes ) } return pCexMin; } -Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ) +Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose ) { - int nTryCexes = 4; // belongs to range [1;4] + //int nTryCexes = 4; // belongs to range [1;4] Abc_Cex_t * pCexBest, * pCexMin[4] = {NULL}; int k, f, i, nOnesBest, nOnesCur, Counter = 0; Vec_Int_t * vPriosIn, * vPriosFf; @@ -278,7 +278,7 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, if ( fVerbose ) { printf( "Original : " ); - Bmc_CexPrint( pCex, Gia_ManPiNum(p) - nPPis, 0 ); + Bmc_CexPrint( pCex, nRealPis, 0 ); } vPriosIn = Vec_IntAlloc( pCex->nPis * (pCex->iFrame + 1) ); vPriosFf = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) ); @@ -290,37 +290,37 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, if ( k == 0 ) { for ( f = 0; f <= pCex->iFrame; f++ ) - for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + for ( i = nRealPis; i < Gia_ManPiNum(p); i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = 0; f <= pCex->iFrame; f++ ) - for ( i = 0; i < nPPis; i++ ) + for ( i = 0; i < nRealPis; i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 1 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + for ( i = nRealPis; i < Gia_ManPiNum(p); i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = 0; i < nPPis; i++ ) + for ( i = 0; i < nRealPis; i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 2 ) { for ( f = 0; f <= pCex->iFrame; f++ ) - for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = 0; f <= pCex->iFrame; f++ ) - for ( i = nPPis - 1; i >= 0; i-- ) + for ( i = nRealPis - 1; i >= 0; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 3 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis - 1; i >= 0; i-- ) + for ( i = nRealPis - 1; i >= 0; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else assert( 0 ); @@ -328,37 +328,37 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, if ( k == 0 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = 0; i < nPPis; i++ ) + for ( i = nRealPis - 1; i >= 0; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 1 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis; i < Gia_ManPiNum(p); i++ ) + for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis - 1; i >= 0; i-- ) + for ( i = 0; i < nRealPis; i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 2 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + for ( i = nRealPis; i < Gia_ManPiNum(p); i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = 0; i < nPPis; i++ ) + for ( i = nRealPis - 1; i >= 0; i-- ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else if ( k == 3 ) { for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = Gia_ManPiNum(p) - 1; i >= nPPis; i-- ) + for ( i = nRealPis; i < Gia_ManPiNum(p); i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); for ( f = pCex->iFrame; f >= 0; f-- ) - for ( i = nPPis - 1; i >= 0; i-- ) + for ( i = 0; i < nRealPis; i++ ) Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) ); } else assert( 0 ); @@ -377,15 +377,15 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, if ( fVerbose ) { if ( k == 0 ) - printf( "PiUp FrUp: " ); + printf( "PI- PPI-: " ); else if ( k == 1 ) - printf( "PiUp FrDn: " ); + printf( "PI+ PPI-: " ); else if ( k == 2 ) - printf( "PiDn FrUp: " ); + printf( "PI- PPI+: " ); else if ( k == 3 ) - printf( "PiDn FrDn: " ); + printf( "PI+ PPI+: " ); else assert( 0 ); - Bmc_CexPrint( pCexMin[k], Gia_ManPiNum(p) - nPPis, 0 ); + Bmc_CexPrint( pCexMin[k], nRealPis, 0 ); } } Vec_IntFree( vPriosIn ); @@ -395,6 +395,8 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, nOnesBest = Abc_CexCountOnes(pCexMin[0]); for ( k = 1; k < nTryCexes; k++ ) { + if ( pCexMin[k] == NULL ) + continue; nOnesCur = Abc_CexCountOnes(pCexMin[k]); if ( nOnesBest > nOnesCur ) { @@ -406,13 +408,13 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, { //Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes ); printf( "Final : " ); - Bmc_CexPrint( pCexBest, Gia_ManPiNum(p) - nPPis, 0 ); + Bmc_CexPrint( pCexBest, nRealPis, 0 ); //printf( "Total : " ); - //Bmc_CexPrint( pTotal, Gia_ManPiNum(p) - nPPis, 0 ); + //Bmc_CexPrint( pTotal, nRealPis, 0 ); //Abc_CexFreeP( &pTotal ); } for ( k = 0; k < nTryCexes; k++ ) - if ( pCexBest != pCexMin[k] ) + if ( pCexMin[k] && pCexBest != pCexMin[k] ) Abc_CexFreeP( &pCexMin[k] ); // verify and return if ( !Bmc_CexVerify( p, pCex, pCexBest ) ) @@ -421,10 +423,10 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nPPis, Abc_Cex_t * pCex, printf( "Counter-example verification succeeded.\n" ); return pCexBest; } -Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nPPis, Abc_Cex_t * pCex, int fCheck, int fVerbose ) +Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose ) { Gia_Man_t * pGia = Gia_ManFromAigSimple( p ); - Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, nPPis, pCex, fCheck, fVerbose ); + Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, nTryCexes, fCheck, fVerbose ); Gia_ManStop( pGia ); return pCexMin; } @@ -459,7 +461,7 @@ void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, in /* { Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 ); - Abc_Cex_t * pCex = Bmc_CexCareMinimize( pAig, 3*Saig_ManPiNum(pAig)/4, pAbc->pCex, 1, 1 ); + Abc_Cex_t * pCex = Bmc_CexCareMinimize( pAig, 3*Saig_ManPiNum(pAig)/4, 4, pAbc->pCex, 1, 1 ); Aig_ManStop( pAig ); Abc_CexFree( pCex ); } -- cgit v1.2.3 From 1bdbea66120292d821fc594b9a6637135bde6244 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 17:40:34 -0800 Subject: Compiler warnings. --- src/aig/gia/giaDup.c | 2 +- src/proof/pdr/pdrCore.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 2a0fe6e3..56d1d29d 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -252,12 +252,12 @@ Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vM } Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop ) { + pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); if ( Used >= 0 ) { assert( pObj->Value != ~0 ); continue; } - pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop ); assert( pObj->Value == ~0 ); pObj->Value = Gia_ManAppendCi(pNew); } diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 47f0ac8b..fb35269d 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -863,7 +863,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) { if ( p->pPars->fUseAbs && iFrame == 2 ) { - int i, Prio, Num = Saig_ManPiNum(p->pAig); + int i, Prio; assert( p->vAbsFlops == NULL ); p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) ); p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) ); -- cgit v1.2.3 From d4b491d849c32195408b0fcc3e5eb42085186824 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 17:51:42 -0800 Subject: Changes to compile on Windows. --- src/sat/satoko/utils/fixed.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sat/satoko/utils/fixed.h b/src/sat/satoko/utils/fixed.h index 91fc9b79..bddd1bb4 100644 --- a/src/sat/satoko/utils/fixed.h +++ b/src/sat/satoko/utils/fixed.h @@ -16,11 +16,11 @@ ABC_NAMESPACE_HEADER_START typedef unsigned fixed_t; static const int FIXED_W_BITS = 16; /* */ -static const int FIXED_F_BITS = 32 - FIXED_W_BITS; -static const int FIXED_F_MASK = (1 << FIXED_F_BITS) - 1; +static const int FIXED_F_BITS = 16;//32 - FIXED_W_BITS; +static const int FIXED_F_MASK = 0xFFFF; //(1 << FIXED_F_BITS) - 1; static const fixed_t FIXED_MAX = 0xFFFFFFFF; static const fixed_t FIXED_MIN = 0x00000000; -static const fixed_t FIXED_ONE = (1 << FIXED_F_BITS); +static const fixed_t FIXED_ONE = 0x10000;//(1 << FIXED_F_BITS); /* Conversion functions */ static inline fixed_t uint2fixed(unsigned a) { return a * FIXED_ONE; } -- cgit v1.2.3 From 5d717256d3b856d8f29c4a5e442af624f0b0bb69 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 18:14:06 -0800 Subject: Updates to the autotuner. --- src/base/abci/abc.c | 220 +++---------------------------------------------- src/base/cmd/cmdAuto.c | 209 ++++++++++++++++++++++++++++++++++++++++------ src/sat/satoko/types.h | 2 +- 3 files changed, 197 insertions(+), 234 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 933f9778..f10be02b 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23320,222 +23320,22 @@ usage: ***********************************************************************/ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) { - abctime clk; - int c; - satoko_opts_t opts; + extern satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ); + // create default options + satoko_opts_t opts, * popts; satoko_default_opts(&opts); - Extra_UtilGetoptReset(); -#ifdef SATOKO_ACT_VAR_FIXED - while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) -#else - while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) -#endif - { - switch ( c ) - { - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - opts.conf_limit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.conf_limit < 0 ) - goto usage; - break; - case 'P': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); - goto usage; - } - opts.prop_limit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.prop_limit < 0 ) - goto usage; - break; - case 'D': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); - goto usage; - } - opts.f_rst = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.f_rst < 0 ) - goto usage; - break; - case 'E': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); - goto usage; - } - opts.b_rst = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.b_rst < 0 ) - goto usage; - break; - case 'F': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'G': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); - goto usage; - } - opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'H': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); - goto usage; - } - opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'I': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); - goto usage; - } - opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'J': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); - goto usage; - } - opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'K': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); - goto usage; - } - opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'L': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); - goto usage; - } - opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'M': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; - globalUtilOptind++; - if ( opts.learnt_ratio < 0 ) - goto usage; - break; - case 'N': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; - globalUtilOptind++; - if ( opts.garbage_max_ratio < 0 ) - goto usage; - break; - case 'O': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); - goto usage; - } - opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'Q': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); - goto usage; - } - opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'R': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); - goto usage; - } - opts.clause_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.clause_decay < 0 ) - goto usage; - break; - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); - goto usage; - } - opts.var_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.var_decay < 0 ) - goto usage; - break; -#ifdef SATOKO_ACT_VAR_FIXED - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); - goto usage; - } - opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); - globalUtilOptind++; - break; - case 'U': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); - goto usage; - } - opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); - globalUtilOptind++; - break; -#endif - case 'h': - goto usage; - case 'v': - opts.verbose ^= 1; - break; - default: - goto usage; - } - } + // override default options + popts = Cmd_DeriveOptionFromSettings( argc, argv ); + if ( popts == NULL ) + goto usage; + memcpy( &opts, popts, sizeof(satoko_opts_t) ); + ABC_FREE( popts ); if ( argc == globalUtilOptind + 1 ) { + abctime clk; char * pFileName = argv[globalUtilOptind]; satoko_t * p; int status; diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 35f155fa..e279b19d 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -241,7 +241,11 @@ satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) satoko_opts_t opts, * pOpts; satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CVWhv" ) ) != EOF ) +#ifdef SATOKO_ACT_VAR_FIXED + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) +#else + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) +#endif { switch ( c ) { @@ -256,31 +260,190 @@ satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) if ( opts.conf_limit < 0 ) return NULL; break; - case 'V': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-V\" should be followed by an integer.\n" ); - return NULL; - } - opts.var_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.var_decay < 0 ) - return NULL; - break; - case 'W': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); - return NULL; - } - opts.clause_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.clause_decay < 0 ) - return NULL; - break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + return NULL; + } + opts.prop_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.prop_limit < 0 ) + return NULL; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); + return NULL; + } + opts.f_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.f_rst < 0 ) + return NULL; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); + return NULL; + } + opts.b_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.b_rst < 0 ) + return NULL; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + return NULL; + } + opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + return NULL; + } + opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + return NULL; + } + opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + return NULL; + } + opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'J': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); + return NULL; + } + opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + return NULL; + } + opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + return NULL; + } + opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + return NULL; + } + opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.learnt_ratio < 0 ) + return NULL; + break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + return NULL; + } + opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.garbage_max_ratio < 0 ) + return NULL; + break; + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); + return NULL; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + return NULL; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); + return NULL; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + return NULL; + break; +#ifdef SATOKO_ACT_VAR_FIXED + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); + return NULL; + } + opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; + case 'U': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); + return NULL; + } + opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; +#endif + case 'h': + return NULL; case 'v': opts.verbose ^= 1; break; + default: return NULL; } diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index 7865ab0e..5d5d4b98 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -18,7 +18,7 @@ ABC_NAMESPACE_HEADER_START #define SATOKO_ACT_VAR_DBLE // #define SATOKO_ACT_VAR_FIXED -// #define SATOKO_ACT_CLAUSE_FLOAT +#define SATOKO_ACT_CLAUSE_FLOAT #ifdef SATOKO_ACT_VAR_DBLE #define VAR_ACT_INIT_INC 1.0 -- cgit v1.2.3 From dd96bb7477fc568ef8fc8d86d330af22c8fa2f26 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 18:53:39 -0800 Subject: Adding PDR with abstraction. --- src/proof/pdr/pdrCore.c | 13 ++++++++----- src/proof/pdr/pdrInt.h | 3 +++ src/proof/pdr/pdrInv.c | 8 +++++--- src/proof/pdr/pdrMan.c | 11 +++++++---- src/proof/pdr/pdrTsim.c | 17 ++++++++++++++++- 5 files changed, 39 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index fb35269d..5aa689f5 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -861,7 +861,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Pdr_ManCreateSolver( p, (iFrame = 0) ); while ( 1 ) { - if ( p->pPars->fUseAbs && iFrame == 2 ) + int fRefined = 0; + if ( p->pPars->fUseAbs && iFrame == 3 ) { int i, Prio; assert( p->vAbsFlops == NULL ); @@ -872,9 +873,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) if ( Prio >> p->nPrioShift ) Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); } - if ( p->pPars->fUseAbs && p->vAbsFlops ) - printf( "Starting frame %d with %d flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops) ); - + //if ( p->pPars->fUseAbs && p->vAbsFlops ) + // printf( "Starting frame %d with %d flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops) ); p->nFrames = iFrame; assert( iFrame == Vec_PtrSize(p->vSolvers)-1 ); p->iUseFrame = Abc_MaxInt(iFrame, 1); @@ -1000,12 +1000,15 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) p->pPars->iFrame = iFrame; if ( !p->pPars->fSolveAll ) { + abctime clk = Abc_Clock(); Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p); + p->tAbs += Abc_Clock() - clk; if ( pCex == NULL ) { assert( p->pPars->fUseAbs ); Pdr_QueueClean( p ); pCube = NULL; + fRefined = 1; break; // keep solving } p->pAig->pSeqModel = pCex; @@ -1058,7 +1061,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) } if ( p->pPars->fVerbose ) - Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart ); // open a new timeframe p->nQueLim = p->pPars->nRestLimit; assert( pCube == NULL ); diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index 2ee4ae09..a6d249e8 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -96,6 +96,8 @@ struct Pdr_Man_t_ Vec_Int_t * vAbsFlops; // flops currently used Vec_Int_t * vMapFf2Ppi; Vec_Int_t * vMapPpi2Ff; + int nCexes; + int nCexesTotal; // terminary simulation Txs_Man_t * pTxs; // internal use @@ -142,6 +144,7 @@ struct Pdr_Man_t_ abctime tTsim; abctime tContain; abctime tCnf; + abctime tAbs; abctime tTotal; }; diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 7a8a66d6..e3233a3a 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -80,8 +80,10 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) } for ( i = ThisSize; i < 70; i++ ) Abc_Print( 1, " " ); - Abc_Print( 1, "%6d", p->nQueMax ); - Abc_Print( 1, "%6d", p->nAbsFlops ); + Abc_Print( 1, "%5d", p->nQueMax ); + Abc_Print( 1, "%5d", p->vAbsFlops ? Vec_IntCountPositive(p->vAbsFlops) : p->nAbsFlops ); + if ( p->pPars->fUseAbs ) + Abc_Print( 1, "%5d", p->nCexes ); Abc_Print( 1, "%10.2f sec", 1.0*Time/CLOCKS_PER_SEC ); if ( p->pPars->fSolveAll ) Abc_Print( 1, " CEX =%4d", p->pPars->nFailOuts ); @@ -89,7 +91,7 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) Abc_Print( 1, " T/O =%3d", p->pPars->nDropOuts ); Abc_Print( 1, "%s", fClose ? "\n":"\r" ); if ( fClose ) - p->nQueMax = 0; + p->nQueMax = 0, p->nCexes = 0; fflush( stdout ); } diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index e2807c92..c19041ee 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -324,8 +324,8 @@ void Pdr_ManStop( Pdr_Man_t * p ) Aig_ManCleanMarkAB( p->pAig ); if ( p->pPars->fVerbose ) { - Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Start =%4d\n", - p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nStarts ); + Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Cex =%4d Start =%4d\n", + p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nCexesTotal, p->nStarts ); ABC_PRTP( "SAT solving", p->tSat, p->tTotal ); ABC_PRTP( " unsat ", p->tSatUnsat, p->tTotal ); ABC_PRTP( " sat ", p->tSatSat, p->tTotal ); @@ -334,6 +334,7 @@ void Pdr_ManStop( Pdr_Man_t * p ) ABC_PRTP( "Ternary sim", p->tTsim, p->tTotal ); ABC_PRTP( "Containment", p->tContain, p->tTotal ); ABC_PRTP( "CNF compute", p->tCnf, p->tTotal ); + ABC_PRTP( "Refinement ", p->tAbs, p->tTotal ); ABC_PRTP( "TOTAL ", p->tTotal, p->tTotal ); fflush( stdout ); } @@ -503,7 +504,7 @@ Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) assert( f == nFrames ); // perform CEX minimization pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi ); - pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 1, 1 ); + pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 ); Gia_ManStop( pAbs ); assert( pCexCare->nPis == pCex->nPis ); Abc_CexFree( pCex ); @@ -520,7 +521,9 @@ Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) Abc_CexFree( pCexCare ); if ( nFfRefined == 0 ) // no refinement -- this is a real CEX return Pdr_ManDeriveCex(p); - printf( "CEX-based refinement refined %d flops.\n", nFfRefined ); + //printf( "CEX-based refinement refined %d flops.\n", nFfRefined ); + p->nCexesTotal++; + p->nCexes++; return NULL; } diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 1cff03c7..283a0e1d 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -476,7 +476,7 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); // move abstracted literals from flops to inputs if ( p->pPars->fUseAbs && p->vAbsFlops ) { - int i, iLit, k = 0, fAllNegs = 1; + int i, iLit, Used, k = 0, fAllNegs = 1; Vec_IntForEachEntry( vRes, iLit, i ) { if ( Vec_IntEntry(p->vAbsFlops, Abc_Lit2Var(iLit)) ) // used flop @@ -501,6 +501,21 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); break; } } + // add any flop that is not in the cone + if ( i == Vec_IntSize(vCiObjs) ) + { + Vec_IntForEachEntry( p->vAbsFlops, Used, i ) + { + if ( !Used ) + continue; + if ( Vec_IntFind( vRes, Abc_Var2Lit(i, 1) ) >= 0 ) + continue; + Vec_IntPush( vRes, Abc_Var2Lit(i, 0) ); + //Vec_IntPrint( vRes ); + break; + } + assert( i < Vec_IntSize(p->vAbsFlops) ); + } } } pRes = Pdr_SetCreate( vRes, vPiLits ); -- cgit v1.2.3 From 8333cb807fbe6773df8285591e75f35d519b6e81 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 10:55:34 -0800 Subject: Platform-independent double. --- src/sat/xsat/xsatDouble.h | 226 ++++++++++++++++++++++++++++++++++++++++++++++ src/sat/xsat/xsatFloat.h | 1 - 2 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 src/sat/xsat/xsatDouble.h (limited to 'src') diff --git a/src/sat/xsat/xsatDouble.h b/src/sat/xsat/xsatDouble.h new file mode 100644 index 00000000..d90e8c05 --- /dev/null +++ b/src/sat/xsat/xsatDouble.h @@ -0,0 +1,226 @@ +/**CFile**************************************************************** + + FileName [xdouble.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [] + + Synopsis [Double floating point number implementation.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - February 11, 2017.] + + Revision [] + +***********************************************************************/ + +#ifndef ABC__sat__Xdbl__Xdbl_h +#define ABC__sat__Xdbl__Xdbl_h + +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/* + The xdbl floating-point number is represented as a 64-bit unsigned int. + The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a + 48-bit mantissa. The decimal point is located between the MSB of Mnt, + which is always 1, and the remaining 15 digits of Mnt. + + Currently, only positive numbers are represented. + + The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] + that is, the smallest possible number is 1.0 and the largest possible + number is 2^(---16 ones---).(1.---47 ones---) + + Comparison of numbers can be done by comparing the underlying unsigned ints. + + Only addition, multiplication, and division by 2^n are currently implemented. +*/ + +static inline word Abc_Dbl2Word( double Dbl ) { union { word x; double y; } v; v.y = Dbl; return v.x; } +static inline double Abc_Word2Dbl( word Num ) { union { word x; double y; } v; v.x = Num; return v.y; } + + +typedef word xdbl; + +static inline word Xdbl_Exp( xdbl a ) { return a >> 48; } +static inline word Xdbl_Mnt( xdbl a ) { return (a << 16) >> 16; } + +static inline xdbl Xdbl_Create( word Exp, word Mnt ) { assert(!(Exp>>16) && (Mnt>>47)==(word)1); return (Exp<<48) | Mnt; } + +static inline xdbl Xdbl_Const1() { return Xdbl_Create( (word)0, (word)1 << 47 ); } +static inline xdbl Xdbl_Const2() { return Xdbl_Create( (word)1, (word)1 << 47 ); } +static inline xdbl Xdbl_Const3() { return Xdbl_Create( (word)1, (word)3 << 46 ); } +static inline xdbl Xdbl_Const12() { return Xdbl_Create( (word)3, (word)3 << 46 ); } +static inline xdbl Xdbl_Const1point5() { return Xdbl_Create( (word)0, (word)3 << 46 ); } +static inline xdbl Xdbl_Const2point5() { return Xdbl_Create( (word)1, (word)5 << 45 ); } +static inline xdbl Xdbl_Maximum() { return ~(word)0; } + +static inline double Xdbl_ToDouble( xdbl a ) { assert(Xdbl_Exp(a) < 1023); return Abc_Word2Dbl(((Xdbl_Exp(a) + 1023) << 52) | (((a<<17)>>17) << 5)); } +static inline xdbl Xdbl_FromDouble( double a ) { word A = Abc_Dbl2Word(a); assert(a >= 1.0); return Xdbl_Create((A >> 52)-1023, (((word)1) << 47) | ((A << 12) >> 17)); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Adding two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Add( xdbl a, xdbl b ) +{ + word Exp, Mnt; + if ( a < b ) a ^= b, b ^= a, a ^= b; + assert( a >= b ); + Mnt = Xdbl_Mnt(a) + (Xdbl_Mnt(b) >> (Xdbl_Exp(a) - Xdbl_Exp(b))); + Exp = Xdbl_Exp(a); + if ( Mnt >> 48 ) // new MSB is created + Exp++, Mnt >>= 1; + if ( Exp >> 16 ) // overflow + return Xdbl_Maximum(); + return Xdbl_Create( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Multiplying two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Mul( xdbl a, xdbl b ) +{ + word Exp, Mnt, MntA, MntB, MntAh, MntBh, MntAl, MntBl; + if ( a < b ) a ^= b, b ^= a, a ^= b; + assert( a >= b ); + MntA = Xdbl_Mnt(a); + MntB = Xdbl_Mnt(b); + MntAh = MntA>>32; + MntBh = MntB>>32; + MntAl = (MntA<<32)>>32; + MntBl = (MntB<<32)>>32; + Mnt = ((MntAh * MntBh) << 17) + ((MntAl * MntBl) >> 47) + ((MntAl * MntBh) >> 15) + ((MntAh * MntBl) >> 15); + Exp = Xdbl_Exp(a) + Xdbl_Exp(b); + if ( Mnt >> 48 ) // new MSB is created + Exp++, Mnt >>= 1; + if ( Exp >> 16 ) // overflow + return Xdbl_Maximum(); + return Xdbl_Create( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Dividing floating point number by a degree of 2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Div( xdbl a, unsigned Deg2 ) +{ + if ( Xdbl_Exp(a) >= (word)Deg2 ) + return Xdbl_Create( Xdbl_Exp(a) - Deg2, Xdbl_Mnt(a) ); + return Xdbl_Const1(); // underflow +} + +/**Function************************************************************* + + Synopsis [Testing procedure.] + + Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Xdbl_Test() +{ + xdbl c1 = Xdbl_Const1(); + xdbl c2 = Xdbl_Const2(); + xdbl c3 = Xdbl_Const3(); + xdbl c12 = Xdbl_Const12(); + xdbl c1p5 = Xdbl_Const1point5(); + xdbl c2p5 = Xdbl_Const2point5(); + + xdbl c1_ = Xdbl_FromDouble(1.0); + xdbl c2_ = Xdbl_FromDouble(2.0); + xdbl c3_ = Xdbl_FromDouble(3.0); + xdbl c12_ = Xdbl_FromDouble(12.0); + xdbl c1p5_ = Xdbl_FromDouble(1.5); + xdbl c2p5_ = Xdbl_FromDouble(2.5); + + xdbl sum1 = Xdbl_Add(c1, c1p5); + xdbl mul1 = Xdbl_Mul(c2, c1p5); + + xdbl sum2 = Xdbl_Add(c1p5, c2p5); + xdbl mul2 = Xdbl_Mul(c1p5, c2p5); + + xdbl a = Xdbl_FromDouble(1.2929725); + xdbl b = Xdbl_FromDouble(10.28828287); + xdbl ab = Xdbl_Mul(a, b); + + xdbl ten100 = Xdbl_FromDouble( 1e100 ); + xdbl ten100_ = ABC_CONST(0x014c924d692ca61b); + + assert( ten100 == ten100_ ); + +// float f1 = Xdbl_ToDouble(c1); +// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" ); +// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" ); + + printf( "1 = %lf\n", Xdbl_ToDouble(c1) ); + printf( "2 = %lf\n", Xdbl_ToDouble(c2) ); + printf( "3 = %lf\n", Xdbl_ToDouble(c3) ); + printf( "12 = %lf\n", Xdbl_ToDouble(c12) ); + printf( "1.5 = %lf\n", Xdbl_ToDouble(c1p5) ); + printf( "2.5 = %lf\n", Xdbl_ToDouble(c2p5) ); + + printf( "Converted 1 = %lf\n", Xdbl_ToDouble(c1_) ); + printf( "Converted 2 = %lf\n", Xdbl_ToDouble(c2_) ); + printf( "Converted 3 = %lf\n", Xdbl_ToDouble(c3_) ); + printf( "Converted 12 = %lf\n", Xdbl_ToDouble(c12_) ); + printf( "Converted 1.5 = %lf\n", Xdbl_ToDouble(c1p5_) ); + printf( "Converted 2.5 = %lf\n", Xdbl_ToDouble(c2p5_) ); + + printf( "1.0 + 1.5 = %lf\n", Xdbl_ToDouble(sum1) ); + printf( "2.0 * 1.5 = %lf\n", Xdbl_ToDouble(mul1) ); + + printf( "1.5 + 2.5 = %lf\n", Xdbl_ToDouble(sum2) ); + printf( "1.5 * 2.5 = %lf\n", Xdbl_ToDouble(mul2) ); + printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) ); + + printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) ); + + printf( "%.16lf * %.16lf = %.16lf (%.16lf)\n", Xdbl_ToDouble(a), Xdbl_ToDouble(b), Xdbl_ToDouble(ab), 1.2929725 * 10.28828287 ); + + assert( sum1 == c2p5 ); + assert( mul1 == c3 ); +} + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/xsat/xsatFloat.h b/src/sat/xsat/xsatFloat.h index 90149783..fb451a94 100644 --- a/src/sat/xsat/xsatFloat.h +++ b/src/sat/xsat/xsatFloat.h @@ -22,7 +22,6 @@ #define ABC__sat__xSAT__xsatFloat_h #include "misc/util/abc_global.h" -#include "misc/vec/vecInt.h" ABC_NAMESPACE_HEADER_START -- cgit v1.2.3 From ab2d3acac99620aef7d5b1c48eb59ee33bb2b584 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Sat, 11 Feb 2017 13:28:22 -0800 Subject: New implementation of a software floating point implementation (sdbl) for consistency across different platforms and compilers. Removing useless files and compile time options related to variable activity data type (it can only be sdbl). --- src/sat/satoko/act_clause.h | 36 ------ src/sat/satoko/act_var.h | 70 +--------- src/sat/satoko/satoko.h | 5 +- src/sat/satoko/solver.h | 2 +- src/sat/satoko/solver_api.c | 6 +- src/sat/satoko/types.h | 67 +++------- src/sat/satoko/utils/fixed.h | 67 ---------- src/sat/satoko/utils/heap.h | 2 +- src/sat/satoko/utils/sdbl.h | 133 +++++++++++++++++++ src/sat/satoko/utils/vec/vec_dble.h | 246 ----------------------------------- src/sat/satoko/utils/vec/vec_sdbl.h | 247 ++++++++++++++++++++++++++++++++++++ 11 files changed, 412 insertions(+), 469 deletions(-) delete mode 100644 src/sat/satoko/utils/fixed.h create mode 100644 src/sat/satoko/utils/sdbl.h delete mode 100755 src/sat/satoko/utils/vec/vec_dble.h create mode 100755 src/sat/satoko/utils/vec/vec_sdbl.h (limited to 'src') diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h index 1465e5ee..ade5e569 100644 --- a/src/sat/satoko/act_clause.h +++ b/src/sat/satoko/act_clause.h @@ -15,40 +15,6 @@ #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#ifdef SATOKO_ACT_CLAUSE_FLOAT - -/** Re-scale the activity value for all clauses. - */ -static inline void clause_act_rescale(solver_t *s) -{ - unsigned i, cref; - struct clause *clause; - - vec_uint_foreach(s->learnts, cref, i) { - clause = clause_read(s, cref); - clause->data[clause->size].act *= (float)1e-20; - } - s->clause_act_inc *= (float)1e-20; -} - -/** Increment the activity value of one clause ('clause') - */ -static inline void clause_act_bump(solver_t *s, struct clause *clause) -{ - clause->data[clause->size].act += s->clause_act_inc; - if (clause->data[clause->size].act > 1e20) - clause_act_rescale(s); -} - -/** Increment the value by which clauses activity values are incremented - */ -static inline void clause_act_decay(solver_t *s) -{ - s->clause_act_inc *= (1 / s->opts.clause_decay); -} - -#else /* SATOKO_ACT_CLAUSE_FLOAT */ - static inline void clause_act_rescale(solver_t *s) { unsigned i, cref; @@ -73,7 +39,5 @@ static inline void clause_act_decay(solver_t *s) s->clause_act_inc += (s->clause_act_inc >> 10); } -#endif /* SATOKO_ACT_CLAUSE_FLOAT */ - ABC_NAMESPACE_HEADER_END #endif /* satoko__act_clause_h */ diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h index b1fdb756..6b0ff98a 100644 --- a/src/sat/satoko/act_var.h +++ b/src/sat/satoko/act_var.h @@ -12,11 +12,11 @@ #include "solver.h" #include "types.h" #include "utils/heap.h" +#include "utils/sdbl.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#if defined SATOKO_ACT_VAR_DBLE /** Re-scale the activity value for all variables. */ static inline void var_act_rescale(solver_t *s) @@ -24,9 +24,9 @@ static inline void var_act_rescale(solver_t *s) unsigned i; act_t *activity = vec_act_data(s->activity); - for (i = 0; i < vec_act_size(s->activity); i++) - activity[i] *= s->opts.var_act_rescale; - s->var_act_inc *= s->opts.var_act_rescale; + for (i = 0; i < vec_sdbl_size(s->activity); i++) + activity[i] = sdbl_div(activity[i], s->opts.var_act_rescale); + s->var_act_inc = sdbl_div(s->var_act_inc, s->opts.var_act_rescale); } /** Increment the activity value of one variable ('var') @@ -35,7 +35,7 @@ static inline void var_act_bump(solver_t *s, unsigned var) { act_t *activity = vec_act_data(s->activity); - activity[var] += s->var_act_inc; + activity[var] = sdbl_add(activity[var], s->var_act_inc); if (activity[var] > s->opts.var_act_limit) var_act_rescale(s); if (heap_in_heap(s->var_order, var)) @@ -46,66 +46,8 @@ static inline void var_act_bump(solver_t *s, unsigned var) */ static inline void var_act_decay(solver_t *s) { - s->var_act_inc *= (1 / s->opts.var_decay); + s->var_act_inc = sdbl_mult(s->var_act_inc, double2sdbl(1 /s->opts.var_decay)); } -#elif defined(SATOKO_ACT_VAR_FIXED) - -static inline void var_act_rescale(solver_t *s) -{ - unsigned i; - act_t *activity = (act_t *)vec_act_data(s->activity); - - for (i = 0; i < vec_act_size(s->activity); i++) - activity[i] = fixed_mult(activity[i], VAR_ACT_RESCALE); - s->var_act_inc = fixed_mult(s->var_act_inc, VAR_ACT_RESCALE); -} - -static inline void var_act_bump(solver_t *s, unsigned var) -{ - act_t *activity = (act_t *)vec_act_data(s->activity); - - activity[var] = fixed_add(activity[var], s->var_act_inc); - if (activity[var] > VAR_ACT_LIMIT) - var_act_rescale(s); - if (heap_in_heap(s->var_order, var)) - heap_decrease(s->var_order, var); -} - -static inline void var_act_decay(solver_t *s) -{ - s->var_act_inc = fixed_mult(s->var_act_inc, dble2fixed(1 / s->opts.var_decay)); -} - -#else - -static inline void var_act_rescale(solver_t *s) -{ - unsigned i; - act_t *activity = vec_act_data(s->activity); - - for (i = 0; i < vec_act_size(s->activity); i++) - activity[i] >>= 19; - s->var_act_inc = stk_uint_max((s->var_act_inc >> 19), (1 << 5)); -} - -static inline void var_act_bump(solver_t *s, unsigned var) -{ - act_t *activity = vec_act_data(s->activity); - - activity[var] += s->var_act_inc; - if (activity[var] & 0xF0000000) - var_act_rescale(s); - if (heap_in_heap(s->var_order, var)) - heap_decrease(s->var_order, var); -} - -static inline void var_act_decay(solver_t *s) -{ - s->var_act_inc += (s->var_act_inc >> 4); -} - -#endif /* SATOKO_ACT_VAR_DBLE || SATOKO_ACT_VAR_FIXED */ - ABC_NAMESPACE_HEADER_END #endif /* satoko__act_var_h */ diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 363fe2fd..e3134b77 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -49,10 +49,11 @@ struct satoko_opts { float learnt_ratio; /* Percentage of learned clauses to remove */ /* VSIDS heuristic */ - float clause_decay; double var_decay; + float clause_decay; + unsigned var_act_rescale; act_t var_act_limit; - act_t var_act_rescale; + /* Binary resolution */ unsigned clause_max_sz_bin_resol; diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index a46b0c9d..849d738a 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -24,7 +24,7 @@ #include "utils/mem.h" #include "utils/misc.h" #include "utils/vec/vec_char.h" -#include "utils/vec/vec_dble.h" +#include "utils/vec/vec_sdbl.h" #include "utils/vec/vec_uint.h" #include "misc/util/abc_global.h" diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index ccab7685..f3f3d781 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -169,7 +169,7 @@ void satoko_default_opts(satoko_opts_t *opts) /* VSIDS heuristic */ opts->var_act_limit = VAR_ACT_LIMIT; opts->var_act_rescale = VAR_ACT_RESCALE; - opts->var_decay = VAR_ACT_DECAY; + opts->var_decay = 0.95; opts->clause_decay = (clause_act_t) 0.995; /* Binary resolution */ opts->clause_max_sz_bin_resol = 30; @@ -222,7 +222,9 @@ void satoko_add_variable(solver_t *s, char sign) vec_wl_push(s->bin_watches); vec_wl_push(s->watches); vec_wl_push(s->watches); - vec_act_push_back(s->activity, 0); + /* Variable activity are initialized with the lowest possible value + * which in satoko double implementation (SDBL) is the constant 1 */ + vec_act_push_back(s->activity, SDBL_CONST1); vec_uint_push_back(s->levels, 0); vec_char_push_back(s->assigns, VAR_UNASSING); vec_char_push_back(s->polarity, sign); diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index 5d5d4b98..d51aed4c 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -9,62 +9,29 @@ #ifndef satoko__types_h #define satoko__types_h -#include "utils/fixed.h" -#include "utils/vec/vec_dble.h" -#include "utils/vec/vec_uint.h" +#include "utils/sdbl.h" +#include "utils/vec/vec_sdbl.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START -#define SATOKO_ACT_VAR_DBLE -// #define SATOKO_ACT_VAR_FIXED -#define SATOKO_ACT_CLAUSE_FLOAT +/* In Satoko ABC version this file is useless */ -#ifdef SATOKO_ACT_VAR_DBLE - #define VAR_ACT_INIT_INC 1.0 - #define VAR_ACT_LIMIT (double)1e100 - #define VAR_ACT_RESCALE (double)1e-100 - #define VAR_ACT_DECAY (double)0.95 - typedef double act_t; - typedef vec_dble_t vec_act_t ; - #define vec_act_alloc(size) vec_dble_alloc(size) - #define vec_act_free(vec) vec_dble_free(vec) - #define vec_act_size(vec) vec_dble_size(vec) - #define vec_act_data(vec) vec_dble_data(vec) - #define vec_act_at(vec, idx) vec_dble_at(vec, idx) - #define vec_act_push_back(vec, value) vec_dble_push_back(vec, value) -#elif defined(SATOKO_ACT_VAR_FIXED) - #define VAR_ACT_INIT_INC FIXED_ONE - #define VAR_ACT_LIMIT (fixed_t)0xDFFFFFFF - #define VAR_ACT_RESCALE (fixed_t)0x00000012 - #define VAR_ACT_DECAY (double)0.96 - typedef fixed_t act_t; - typedef vec_uint_t vec_act_t; - #define vec_act_alloc(size) vec_uint_alloc(size) - #define vec_act_free(vec) vec_uint_free(vec) - #define vec_act_size(vec) vec_uint_size(vec) - #define vec_act_data(vec) vec_uint_data(vec) - #define vec_act_at(vec, idx) vec_uint_at(vec, idx) - #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) -#else - #define VAR_ACT_INIT_INC (1 << 5) - typedef unsigned act_t; - typedef vec_uint_t vec_act_t; - #define vec_act_alloc(size) vec_uint_alloc(size) - #define vec_act_free(vec) vec_uint_free(vec) - #define vec_act_size(vec) vec_uint_size(vec) - #define vec_act_data(vec) vec_uint_data(vec) - #define vec_act_at(vec, idx) vec_uint_at(vec, idx) - #define vec_act_push_back(vec, value) vec_uint_push_back(vec, value) -#endif /* SATOKO_ACT_VAR_DBLE */ +#define VAR_ACT_INIT_INC SDBL_CONST1 +#define VAR_ACT_LIMIT ABC_CONST(0x014c924d692ca61b) +#define VAR_ACT_RESCALE 200 +typedef sdbl_t act_t; +typedef vec_sdbl_t vec_act_t ; +#define vec_act_alloc(size) vec_sdbl_alloc(size) +#define vec_act_free(vec) vec_sdbl_free(vec) +#define vec_act_size(vec) vec_sdbl_size(vec) +#define vec_act_data(vec) vec_sdbl_data(vec) +#define vec_act_at(vec, idx) vec_sdbl_at(vec, idx) +#define vec_act_push_back(vec, value) vec_sdbl_push_back(vec, value) -#ifdef SATOKO_ACT_CLAUSE_FLOAT - #define CLAUSE_ACT_INIT_INC 1.0 - typedef float clause_act_t; -#else - #define CLAUSE_ACT_INIT_INC (1 << 11) - typedef unsigned clause_act_t; -#endif /* SATOKO_ACT_CLAUSE_FLOAT */ + +#define CLAUSE_ACT_INIT_INC (1 << 11) +typedef unsigned clause_act_t; ABC_NAMESPACE_HEADER_END #endif /* satoko__types_h */ diff --git a/src/sat/satoko/utils/fixed.h b/src/sat/satoko/utils/fixed.h deleted file mode 100644 index bddd1bb4..00000000 --- a/src/sat/satoko/utils/fixed.h +++ /dev/null @@ -1,67 +0,0 @@ -//===--- sort.h -------------------------------------------------------------=== -// -// satoko: Satisfiability solver -// -// This file is distributed under the BSD 2-Clause License. -// See LICENSE for details. -// -//===------------------------------------------------------------------------=== -#ifndef satoko__utils__fixed_h -#define satoko__utils__fixed_h - -#include "misc.h" - -#include "misc/util/abc_global.h" -ABC_NAMESPACE_HEADER_START - -typedef unsigned fixed_t; -static const int FIXED_W_BITS = 16; /* */ -static const int FIXED_F_BITS = 16;//32 - FIXED_W_BITS; -static const int FIXED_F_MASK = 0xFFFF; //(1 << FIXED_F_BITS) - 1; -static const fixed_t FIXED_MAX = 0xFFFFFFFF; -static const fixed_t FIXED_MIN = 0x00000000; -static const fixed_t FIXED_ONE = 0x10000;//(1 << FIXED_F_BITS); - -/* Conversion functions */ -static inline fixed_t uint2fixed(unsigned a) { return a * FIXED_ONE; } -static inline unsigned fixed2uint(fixed_t a) -{ - return (a + (FIXED_ONE >> 1)) / FIXED_ONE; -} - -static inline float fixed2float(fixed_t a) { return (float)a / FIXED_ONE; } -static inline fixed_t float2fixed(float a) -{ - float temp = a * FIXED_ONE; - temp += (temp >= 0) ? 0.5f : -0.5f; - return (fixed_t)temp; -} - -static inline double fixed2dble(fixed_t a) { return (double)a / FIXED_ONE; } -static inline fixed_t dble2fixed(double a) -{ - double temp = a * FIXED_ONE; - temp += (temp >= 0) ? 0.5f : -0.5f; - return (fixed_t)temp; -} - -static inline fixed_t fixed_add(fixed_t a, fixed_t b) { return (a + b); } -static inline fixed_t fixed_mult(fixed_t a, fixed_t b) -{ - unsigned hi_a = (a >> FIXED_F_BITS), lo_a = (a & FIXED_F_MASK); - unsigned hi_b = (b >> FIXED_F_BITS), lo_b = (b & FIXED_F_MASK); - unsigned lo_ab = lo_a * lo_b; - unsigned ab_ab = (hi_a * lo_b) + (lo_a * hi_b); - unsigned hi_ret = (hi_a * hi_b) + (ab_ab >> FIXED_F_BITS); - unsigned lo_ret = lo_ab + (ab_ab << FIXED_W_BITS); - - /* Carry */ - if (lo_ret < lo_ab) - hi_ret++; - - return (hi_ret << FIXED_F_BITS) | (lo_ret >> FIXED_W_BITS); -} - -ABC_NAMESPACE_HEADER_END - -#endif /* satoko__utils__fixed_h */ diff --git a/src/sat/satoko/utils/heap.h b/src/sat/satoko/utils/heap.h index e1611e95..8b1d8f4b 100644 --- a/src/sat/satoko/utils/heap.h +++ b/src/sat/satoko/utils/heap.h @@ -11,7 +11,7 @@ #include "mem.h" #include "../types.h" -#include "vec/vec_dble.h" +#include "vec/vec_sdbl.h" #include "vec/vec_int.h" #include "vec/vec_uint.h" diff --git a/src/sat/satoko/utils/sdbl.h b/src/sat/satoko/utils/sdbl.h new file mode 100644 index 00000000..9f90ba02 --- /dev/null +++ b/src/sat/satoko/utils/sdbl.h @@ -0,0 +1,133 @@ +//===--- sdbl.h -------------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +// by Alan Mishchenko +#ifndef satoko__utils__sdbl_h +#define satoko__utils__sdbl_h + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START +/* + The sdbl_t floating-point number is represented as a 64-bit unsigned int. + The number is (2^expt)*mnt, where expt is a 16-bit exponent and mnt is a + 48-bit mantissa. The decimal point is located between the MSB of mnt, + which is always 1, and the remaining 15 digits of mnt. + + Currently, only positive numbers are represented. + + The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] + that is, the smallest possible number is 1.0 and the largest possible + number is 2^(---16 ones---).(1.---47 ones---) + + Comparison of numbers can be done by comparing the underlying unsigned ints. + + Only addition, multiplication, and division by 2^n are currently implemented. +*/ + +typedef word sdbl_t; + +static sdbl_t SDBL_CONST1 = ABC_CONST(0x0000800000000000); +static sdbl_t SDBL_MAX = ~(sdbl_t)(0); + +union ui64_dbl { word ui64; double dbl; }; + +static inline word sdbl_exp(sdbl_t a) { return a >> 48; } +static inline word sdbl_mnt(sdbl_t a) { return (a << 16) >> 16; } + +static inline double sdbl2double(sdbl_t a) { + union ui64_dbl temp; + assert(sdbl_exp(a) < 1023); + temp.ui64 = ((sdbl_exp(a) + 1023) << 52) | (((a << 17) >> 17) << 5); + return temp.dbl; +} + +static inline sdbl_t double2sdbl(double value) +{ + union ui64_dbl temp; + sdbl_t expt, mnt; + assert(value >= 1.0); + temp.dbl = value; + expt = (temp.ui64 >> 52) - 1023; + mnt = SDBL_CONST1 | ((temp.ui64 << 12) >> 17); + return (expt << 48) + mnt; +} + +static inline sdbl_t sdbl_add(sdbl_t a, sdbl_t b) +{ + sdbl_t expt, mnt; + if (a < b) { + a ^= b; + b ^= a; + a ^= b; + } + assert(a >= b); + expt = sdbl_exp(a); + mnt = sdbl_mnt(a) + (sdbl_mnt(b) >> (sdbl_exp(a) - sdbl_exp(b))); + /* Check for carry */ + if (mnt >> 48) { + expt++; + mnt >>= 1; + } + if (expt >> 16) /* overflow */ + return SDBL_MAX; + return (expt << 48) + mnt; +} + +static inline sdbl_t sdbl_mult(sdbl_t a, sdbl_t b) +{ + sdbl_t expt, mnt; + sdbl_t a_mnt, a_mnt_hi, a_mnt_lo; + sdbl_t b_mnt, b_mnt_hi, b_mnt_lo; + if (a < b) { + a ^= b; + b ^= a; + a ^= b; + } + assert( a >= b ); + a_mnt = sdbl_mnt(a); + b_mnt = sdbl_mnt(b); + a_mnt_hi = a_mnt>>32; + b_mnt_hi = b_mnt>>32; + a_mnt_lo = (a_mnt<<32)>>32; + b_mnt_lo = (b_mnt<<32)>>32; + mnt = ((a_mnt_hi * b_mnt_hi) << 17) + + ((a_mnt_lo * b_mnt_lo) >> 47) + + ((a_mnt_lo * b_mnt_hi) >> 15) + + ((a_mnt_hi * b_mnt_lo) >> 15); + expt = sdbl_exp(a) + sdbl_exp(b); + /* Check for carry */ + if (mnt >> 48) { + expt++; + mnt >>= 1; + } + if (expt >> 16) /* overflow */ + return SDBL_MAX; + return (expt << 48) + mnt; +} + +static inline sdbl_t sdbl_div(sdbl_t a, unsigned deg2) +{ + if (sdbl_exp(a) >= (word)deg2) + return ((sdbl_exp(a) - deg2) << 48) + sdbl_mnt(a); + return SDBL_CONST1; +} + +static inline void sdbl_test() +{ + sdbl_t ten100_ = ABC_CONST(0x014c924d692ca61b); + printf("%f\n", sdbl2double(ten100_)); + printf("%016lX\n", double2sdbl(1 /0.95)); + printf("%016lX\n", SDBL_CONST1); + printf("%f\n", sdbl2double(SDBL_CONST1)); + printf("%f\n", sdbl2double(ABC_CONST(0x000086BCA1AF286B))); + +} + +ABC_NAMESPACE_HEADER_END + +#endif /* satoko__utils__sdbl_h */ diff --git a/src/sat/satoko/utils/vec/vec_dble.h b/src/sat/satoko/utils/vec/vec_dble.h deleted file mode 100755 index 50281c2a..00000000 --- a/src/sat/satoko/utils/vec/vec_dble.h +++ /dev/null @@ -1,246 +0,0 @@ -//===--- vec_int.h ----------------------------------------------------------=== -// -// satoko: Satisfiability solver -// -// This file is distributed under the BSD 2-Clause License. -// See LICENSE for details. -// -//===------------------------------------------------------------------------=== -#ifndef satoko__utils__vec__vec_dble_h -#define satoko__utils__vec__vec_dble_h - -#include -#include -#include - -#include "../mem.h" - -#include "misc/util/abc_global.h" -ABC_NAMESPACE_HEADER_START - -typedef struct vec_dble_t_ vec_dble_t; -struct vec_dble_t_ { - unsigned cap; - unsigned size; - double *data; -}; - -//===------------------------------------------------------------------------=== -// Vector Macros -//===------------------------------------------------------------------------=== -#define vec_dble_foreach(vec, entry, i) \ - for (i = 0; (i < vec->size) && (((entry) = vec_dble_at(vec, i)), 1); i++) - -#define vec_dble_foreach_start(vec, entry, i, start) \ - for (i = start; (i < vec_dble_size(vec)) && (((entry) = vec_dble_at(vec, i)), 1); i++) - -#define vec_dble_foreach_stop(vec, entry, i, stop) \ - for (i = 0; (i < stop) && (((entry) = vec_dble_at(vec, i)), 1); i++) - -//===------------------------------------------------------------------------=== -// Vector API -//===------------------------------------------------------------------------=== -static inline vec_dble_t *vec_dble_alloc(unsigned cap) -{ - vec_dble_t* p = satoko_alloc(vec_dble_t, 1); - - if (cap > 0 && cap < 16) - cap = 16; - p->size = 0; - p->cap = cap; - p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; - return p; -} - -static inline vec_dble_t *vec_dble_alloc_exact(unsigned cap) -{ - vec_dble_t* p = satoko_alloc(vec_dble_t, 1); - - p->size = 0; - p->cap = cap; - p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; - return p; -} - -static inline vec_dble_t *vec_dble_init(unsigned size, double value) -{ - vec_dble_t* p = satoko_alloc(vec_dble_t, 1); - - p->cap = size; - p->size = size; - p->data = p->cap ? satoko_alloc(double, p->cap) : NULL; - memset(p->data, value, sizeof(double) * p->size); - return p; -} - -static inline void vec_dble_free(vec_dble_t *p) -{ - if (p->data != NULL) - satoko_free(p->data); - satoko_free(p); -} - -static inline unsigned vec_dble_size(vec_dble_t *p) -{ - return p->size; -} - -static inline void vec_dble_resize(vec_dble_t *p, unsigned new_size) -{ - p->size = new_size; - if (p->cap >= new_size) - return; - p->data = satoko_realloc(double, p->data, new_size); - assert(p->data != NULL); - p->cap = new_size; -} - -static inline void vec_dble_reserve(vec_dble_t *p, unsigned new_cap) -{ - if (p->cap >= new_cap) - return; - p->data = satoko_realloc(double, p->data, new_cap); - assert(p->data != NULL); - p->cap = new_cap; -} - -static inline unsigned vec_dble_capacity(vec_dble_t *p) -{ - return p->cap; -} - -static inline int vec_dble_empty(vec_dble_t *p) -{ - return p->size ? 0 : 1; -} - -static inline void vec_dble_erase(vec_dble_t *p) -{ - satoko_free(p->data); - p->size = 0; - p->cap = 0; -} - -static inline double vec_dble_at(vec_dble_t *p, unsigned i) -{ - assert(i >= 0 && i < p->size); - return p->data[i]; -} - -static inline double *vec_dble_at_ptr(vec_dble_t *p, unsigned i) -{ - assert(i >= 0 && i < p->size); - return p->data + i; -} - -static inline double *vec_dble_data(vec_dble_t *p) -{ - assert(p); - return p->data; -} - -static inline void vec_dble_duplicate(vec_dble_t *dest, const vec_dble_t *src) -{ - assert(dest != NULL && src != NULL); - vec_dble_resize(dest, src->cap); - memcpy(dest->data, src->data, sizeof(double) * src->cap); - dest->size = src->size; -} - -static inline void vec_dble_copy(vec_dble_t *dest, const vec_dble_t *src) -{ - assert(dest != NULL && src != NULL); - vec_dble_resize(dest, src->size); - memcpy(dest->data, src->data, sizeof(double) * src->size); - dest->size = src->size; -} - -static inline void vec_dble_push_back(vec_dble_t *p, double value) -{ - if (p->size == p->cap) { - if (p->cap < 16) - vec_dble_reserve(p, 16); - else - vec_dble_reserve(p, 2 * p->cap); - } - p->data[p->size] = value; - p->size++; -} - -static inline void vec_dble_assign(vec_dble_t *p, unsigned i, double value) -{ - assert((i >= 0) && (i < vec_dble_size(p))); - p->data[i] = value; -} - -static inline void vec_dble_insert(vec_dble_t *p, unsigned i, double value) -{ - assert((i >= 0) && (i < vec_dble_size(p))); - vec_dble_push_back(p, 0); - memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(double)); - p->data[i] = value; -} - -static inline void vec_dble_drop(vec_dble_t *p, unsigned i) -{ - assert((i >= 0) && (i < vec_dble_size(p))); - memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(double)); - p->size -= 1; -} - -static inline void vec_dble_clear(vec_dble_t *p) -{ - p->size = 0; -} - -static inline int vec_dble_asc_compare(const void *p1, const void *p2) -{ - const double *pp1 = (const double *) p1; - const double *pp2 = (const double *) p2; - - if (*pp1 < *pp2) - return -1; - if (*pp1 > *pp2) - return 1; - return 0; -} - -static inline int vec_dble_desc_compare(const void* p1, const void* p2) -{ - const double *pp1 = (const double *) p1; - const double *pp2 = (const double *) p2; - - if (*pp1 > *pp2) - return -1; - if (*pp1 < *pp2) - return 1; - return 0; -} - -static inline void vec_dble_sort(vec_dble_t* p, int ascending) -{ - if (ascending) - qsort((void *) p->data, p->size, sizeof(double), - (int (*)(const void*, const void*)) vec_dble_asc_compare); - else - qsort((void *) p->data, p->size, sizeof(double), - (int (*)(const void*, const void*)) vec_dble_desc_compare); -} - -static inline long vec_dble_memory(vec_dble_t *p) -{ - return p == NULL ? 0 : sizeof(double) * p->cap + sizeof(vec_dble_t); -} - -static inline void vec_dble_print(vec_dble_t *p) -{ - unsigned i; - assert(p != NULL); - fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); - for (i = 0; i < p->size; i++) - fprintf(stdout, " %f", p->data[i]); - fprintf(stdout, " }\n"); -} - -ABC_NAMESPACE_HEADER_END -#endif /* satoko__utils__vec__vec_dble_h */ diff --git a/src/sat/satoko/utils/vec/vec_sdbl.h b/src/sat/satoko/utils/vec/vec_sdbl.h new file mode 100755 index 00000000..aefd687a --- /dev/null +++ b/src/sat/satoko/utils/vec/vec_sdbl.h @@ -0,0 +1,247 @@ +//===--- vec_int.h ----------------------------------------------------------=== +// +// satoko: Satisfiability solver +// +// This file is distributed under the BSD 2-Clause License. +// See LICENSE for details. +// +//===------------------------------------------------------------------------=== +#ifndef satoko__utils__vec__vec_sdbl_h +#define satoko__utils__vec__vec_sdbl_h + +#include +#include +#include + +#include "../mem.h" +#include "../sdbl.h" + +#include "misc/util/abc_global.h" +ABC_NAMESPACE_HEADER_START + +typedef struct vec_sdbl_t_ vec_sdbl_t; +struct vec_sdbl_t_ { + unsigned cap; + unsigned size; + sdbl_t *data; +}; + +//===------------------------------------------------------------------------=== +// Vector Macros +//===------------------------------------------------------------------------=== +#define vec_sdbl_foreach(vec, entry, i) \ + for (i = 0; (i < vec->size) && (((entry) = vec_sdbl_at(vec, i)), 1); i++) + +#define vec_sdbl_foreach_start(vec, entry, i, start) \ + for (i = start; (i < vec_sdbl_size(vec)) && (((entry) = vec_sdbl_at(vec, i)), 1); i++) + +#define vec_sdbl_foreach_stop(vec, entry, i, stop) \ + for (i = 0; (i < stop) && (((entry) = vec_sdbl_at(vec, i)), 1); i++) + +//===------------------------------------------------------------------------=== +// Vector API +//===------------------------------------------------------------------------=== +static inline vec_sdbl_t *vec_sdbl_alloc(unsigned cap) +{ + vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1); + + if (cap > 0 && cap < 16) + cap = 16; + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL; + return p; +} + +static inline vec_sdbl_t *vec_sdbl_alloc_exact(unsigned cap) +{ + vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1); + + p->size = 0; + p->cap = cap; + p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL; + return p; +} + +static inline vec_sdbl_t *vec_sdbl_init(unsigned size, sdbl_t value) +{ + vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1); + + p->cap = size; + p->size = size; + p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL; + memset(p->data, value, sizeof(sdbl_t) * p->size); + return p; +} + +static inline void vec_sdbl_free(vec_sdbl_t *p) +{ + if (p->data != NULL) + satoko_free(p->data); + satoko_free(p); +} + +static inline unsigned vec_sdbl_size(vec_sdbl_t *p) +{ + return p->size; +} + +static inline void vec_sdbl_resize(vec_sdbl_t *p, unsigned new_size) +{ + p->size = new_size; + if (p->cap >= new_size) + return; + p->data = satoko_realloc(sdbl_t, p->data, new_size); + assert(p->data != NULL); + p->cap = new_size; +} + +static inline void vec_sdbl_reserve(vec_sdbl_t *p, unsigned new_cap) +{ + if (p->cap >= new_cap) + return; + p->data = satoko_realloc(sdbl_t, p->data, new_cap); + assert(p->data != NULL); + p->cap = new_cap; +} + +static inline unsigned vec_sdbl_capacity(vec_sdbl_t *p) +{ + return p->cap; +} + +static inline int vec_sdbl_empty(vec_sdbl_t *p) +{ + return p->size ? 0 : 1; +} + +static inline void vec_sdbl_erase(vec_sdbl_t *p) +{ + satoko_free(p->data); + p->size = 0; + p->cap = 0; +} + +static inline sdbl_t vec_sdbl_at(vec_sdbl_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data[i]; +} + +static inline sdbl_t *vec_sdbl_at_ptr(vec_sdbl_t *p, unsigned i) +{ + assert(i >= 0 && i < p->size); + return p->data + i; +} + +static inline sdbl_t *vec_sdbl_data(vec_sdbl_t *p) +{ + assert(p); + return p->data; +} + +static inline void vec_sdbl_duplicate(vec_sdbl_t *dest, const vec_sdbl_t *src) +{ + assert(dest != NULL && src != NULL); + vec_sdbl_resize(dest, src->cap); + memcpy(dest->data, src->data, sizeof(sdbl_t) * src->cap); + dest->size = src->size; +} + +static inline void vec_sdbl_copy(vec_sdbl_t *dest, const vec_sdbl_t *src) +{ + assert(dest != NULL && src != NULL); + vec_sdbl_resize(dest, src->size); + memcpy(dest->data, src->data, sizeof(sdbl_t) * src->size); + dest->size = src->size; +} + +static inline void vec_sdbl_push_back(vec_sdbl_t *p, sdbl_t value) +{ + if (p->size == p->cap) { + if (p->cap < 16) + vec_sdbl_reserve(p, 16); + else + vec_sdbl_reserve(p, 2 * p->cap); + } + p->data[p->size] = value; + p->size++; +} + +static inline void vec_sdbl_assign(vec_sdbl_t *p, unsigned i, sdbl_t value) +{ + assert((i >= 0) && (i < vec_sdbl_size(p))); + p->data[i] = value; +} + +static inline void vec_sdbl_insert(vec_sdbl_t *p, unsigned i, sdbl_t value) +{ + assert((i >= 0) && (i < vec_sdbl_size(p))); + vec_sdbl_push_back(p, 0); + memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(sdbl_t)); + p->data[i] = value; +} + +static inline void vec_sdbl_drop(vec_sdbl_t *p, unsigned i) +{ + assert((i >= 0) && (i < vec_sdbl_size(p))); + memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(sdbl_t)); + p->size -= 1; +} + +static inline void vec_sdbl_clear(vec_sdbl_t *p) +{ + p->size = 0; +} + +static inline int vec_sdbl_asc_compare(const void *p1, const void *p2) +{ + const sdbl_t *pp1 = (const sdbl_t *) p1; + const sdbl_t *pp2 = (const sdbl_t *) p2; + + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + return 0; +} + +static inline int vec_sdbl_desc_compare(const void* p1, const void* p2) +{ + const sdbl_t *pp1 = (const sdbl_t *) p1; + const sdbl_t *pp2 = (const sdbl_t *) p2; + + if (*pp1 > *pp2) + return -1; + if (*pp1 < *pp2) + return 1; + return 0; +} + +static inline void vec_sdbl_sort(vec_sdbl_t* p, int ascending) +{ + if (ascending) + qsort((void *) p->data, p->size, sizeof(sdbl_t), + (int (*)(const void*, const void*)) vec_sdbl_asc_compare); + else + qsort((void *) p->data, p->size, sizeof(sdbl_t), + (int (*)(const void*, const void*)) vec_sdbl_desc_compare); +} + +static inline long vec_sdbl_memory(vec_sdbl_t *p) +{ + return p == NULL ? 0 : sizeof(sdbl_t) * p->cap + sizeof(vec_sdbl_t); +} + +static inline void vec_sdbl_print(vec_sdbl_t *p) +{ + unsigned i; + assert(p != NULL); + fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap); + for (i = 0; i < p->size; i++) + fprintf(stdout, " %f", sdbl2double(p->data[i])); + fprintf(stdout, " }\n"); +} + +ABC_NAMESPACE_HEADER_END +#endif /* satoko__utils__vec__vec_sdbl_h */ -- cgit v1.2.3 From 45f4d6c7e8678e140b363f3114b5393ed1f29681 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 13:55:41 -0800 Subject: Movinng custom floating-point implementations, etc. --- src/misc/util/abc_global.h | 2 + src/misc/util/utilDouble.h | 222 ++++++++++++++++++++++++++++++++++++++++++++ src/misc/util/utilFloat.h | 226 ++++++++++++++++++++++++++++++++++++++++++++ src/sat/bsat/satSolver.h | 3 +- src/sat/xsat/xsatDouble.h | 226 -------------------------------------------- src/sat/xsat/xsatFloat.h | 227 --------------------------------------------- 6 files changed, 452 insertions(+), 454 deletions(-) create mode 100644 src/misc/util/utilDouble.h create mode 100644 src/misc/util/utilFloat.h delete mode 100644 src/sat/xsat/xsatDouble.h delete mode 100644 src/sat/xsat/xsatFloat.h (limited to 'src') diff --git a/src/misc/util/abc_global.h b/src/misc/util/abc_global.h index 00d5d514..9e906816 100644 --- a/src/misc/util/abc_global.h +++ b/src/misc/util/abc_global.h @@ -225,6 +225,8 @@ static inline double Abc_MinDouble( double a, double b ) { return a < b ? static inline int Abc_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; } static inline float Abc_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; } +static inline word Abc_Dbl2Word( double Dbl ) { union { word x; double y; } v; v.y = Dbl; return v.x; } +static inline double Abc_Word2Dbl( word Num ) { union { word x; double y; } v; v.x = Num; return v.y; } static inline int Abc_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ) {}; return r; } static inline int Abc_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ) {}; return r; } static inline int Abc_Base16Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 16, r++ ) {}; return r; } diff --git a/src/misc/util/utilDouble.h b/src/misc/util/utilDouble.h new file mode 100644 index 00000000..0d023781 --- /dev/null +++ b/src/misc/util/utilDouble.h @@ -0,0 +1,222 @@ +/**CFile**************************************************************** + + FileName [utilDouble.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [] + + Synopsis [Double floating point number implementation.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - February 11, 2017.] + + Revision [] + +***********************************************************************/ + +#ifndef ABC__sat__Xdbl__Xdbl_h +#define ABC__sat__Xdbl__Xdbl_h + +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/* + The xdbl floating-point number is represented as a 64-bit unsigned int. + The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a + 48-bit mantissa. The decimal point is located between the MSB of Mnt, + which is always 1, and the remaining 15 digits of Mnt. + + Currently, only positive numbers are represented. + + The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] + that is, the smallest possible number is 1.0 and the largest possible + number is 2^(---16 ones---).(1.---47 ones---) + + Comparison of numbers can be done by comparing the underlying unsigned ints. + + Only addition, multiplication, and division by 2^n are currently implemented. +*/ + +typedef word xdbl; + +static inline word Xdbl_Exp( xdbl a ) { return a >> 48; } +static inline word Xdbl_Mnt( xdbl a ) { return (a << 16) >> 16; } + +static inline xdbl Xdbl_Create( word Exp, word Mnt ) { assert(!(Exp>>16) && (Mnt>>47)==(word)1); return (Exp<<48) | Mnt; } + +static inline xdbl Xdbl_Const1() { return Xdbl_Create( (word)0, (word)1 << 47 ); } +static inline xdbl Xdbl_Const2() { return Xdbl_Create( (word)1, (word)1 << 47 ); } +static inline xdbl Xdbl_Const3() { return Xdbl_Create( (word)1, (word)3 << 46 ); } +static inline xdbl Xdbl_Const12() { return Xdbl_Create( (word)3, (word)3 << 46 ); } +static inline xdbl Xdbl_Const1point5() { return Xdbl_Create( (word)0, (word)3 << 46 ); } +static inline xdbl Xdbl_Const2point5() { return Xdbl_Create( (word)1, (word)5 << 45 ); } +static inline xdbl Xdbl_Maximum() { return ~(word)0; } + +static inline double Xdbl_ToDouble( xdbl a ) { assert(Xdbl_Exp(a) < 1023); return Abc_Word2Dbl(((Xdbl_Exp(a) + 1023) << 52) | (((a<<17)>>17) << 5)); } +static inline xdbl Xdbl_FromDouble( double a ) { word A = Abc_Dbl2Word(a); assert(a >= 1.0); return Xdbl_Create((A >> 52)-1023, (((word)1) << 47) | ((A << 12) >> 17)); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Adding two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Add( xdbl a, xdbl b ) +{ + word Exp, Mnt; + if ( a < b ) a ^= b, b ^= a, a ^= b; + assert( a >= b ); + Mnt = Xdbl_Mnt(a) + (Xdbl_Mnt(b) >> (Xdbl_Exp(a) - Xdbl_Exp(b))); + Exp = Xdbl_Exp(a); + if ( Mnt >> 48 ) // new MSB is created + Exp++, Mnt >>= 1; + if ( Exp >> 16 ) // overflow + return Xdbl_Maximum(); + return Xdbl_Create( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Multiplying two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Mul( xdbl a, xdbl b ) +{ + word Exp, Mnt, MntA, MntB, MntAh, MntBh, MntAl, MntBl; + if ( a < b ) a ^= b, b ^= a, a ^= b; + assert( a >= b ); + MntA = Xdbl_Mnt(a); + MntB = Xdbl_Mnt(b); + MntAh = MntA>>32; + MntBh = MntB>>32; + MntAl = (MntA<<32)>>32; + MntBl = (MntB<<32)>>32; + Mnt = ((MntAh * MntBh) << 17) + ((MntAl * MntBl) >> 47) + ((MntAl * MntBh) >> 15) + ((MntAh * MntBl) >> 15); + Exp = Xdbl_Exp(a) + Xdbl_Exp(b); + if ( Mnt >> 48 ) // new MSB is created + Exp++, Mnt >>= 1; + if ( Exp >> 16 ) // overflow + return Xdbl_Maximum(); + return Xdbl_Create( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Dividing floating point number by a degree of 2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xdbl Xdbl_Div( xdbl a, unsigned Deg2 ) +{ + if ( Xdbl_Exp(a) >= (word)Deg2 ) + return Xdbl_Create( Xdbl_Exp(a) - Deg2, Xdbl_Mnt(a) ); + return Xdbl_Const1(); // underflow +} + +/**Function************************************************************* + + Synopsis [Testing procedure.] + + Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Xdbl_Test() +{ + xdbl c1 = Xdbl_Const1(); + xdbl c2 = Xdbl_Const2(); + xdbl c3 = Xdbl_Const3(); + xdbl c12 = Xdbl_Const12(); + xdbl c1p5 = Xdbl_Const1point5(); + xdbl c2p5 = Xdbl_Const2point5(); + + xdbl c1_ = Xdbl_FromDouble(1.0); + xdbl c2_ = Xdbl_FromDouble(2.0); + xdbl c3_ = Xdbl_FromDouble(3.0); + xdbl c12_ = Xdbl_FromDouble(12.0); + xdbl c1p5_ = Xdbl_FromDouble(1.5); + xdbl c2p5_ = Xdbl_FromDouble(2.5); + + xdbl sum1 = Xdbl_Add(c1, c1p5); + xdbl mul1 = Xdbl_Mul(c2, c1p5); + + xdbl sum2 = Xdbl_Add(c1p5, c2p5); + xdbl mul2 = Xdbl_Mul(c1p5, c2p5); + + xdbl a = Xdbl_FromDouble(1.2929725); + xdbl b = Xdbl_FromDouble(10.28828287); + xdbl ab = Xdbl_Mul(a, b); + + xdbl ten100 = Xdbl_FromDouble( 1e100 ); + xdbl ten100_ = ABC_CONST(0x014c924d692ca61b); + + assert( ten100 == ten100_ ); + +// float f1 = Xdbl_ToDouble(c1); +// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" ); +// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" ); + + printf( "1 = %lf\n", Xdbl_ToDouble(c1) ); + printf( "2 = %lf\n", Xdbl_ToDouble(c2) ); + printf( "3 = %lf\n", Xdbl_ToDouble(c3) ); + printf( "12 = %lf\n", Xdbl_ToDouble(c12) ); + printf( "1.5 = %lf\n", Xdbl_ToDouble(c1p5) ); + printf( "2.5 = %lf\n", Xdbl_ToDouble(c2p5) ); + + printf( "Converted 1 = %lf\n", Xdbl_ToDouble(c1_) ); + printf( "Converted 2 = %lf\n", Xdbl_ToDouble(c2_) ); + printf( "Converted 3 = %lf\n", Xdbl_ToDouble(c3_) ); + printf( "Converted 12 = %lf\n", Xdbl_ToDouble(c12_) ); + printf( "Converted 1.5 = %lf\n", Xdbl_ToDouble(c1p5_) ); + printf( "Converted 2.5 = %lf\n", Xdbl_ToDouble(c2p5_) ); + + printf( "1.0 + 1.5 = %lf\n", Xdbl_ToDouble(sum1) ); + printf( "2.0 * 1.5 = %lf\n", Xdbl_ToDouble(mul1) ); + + printf( "1.5 + 2.5 = %lf\n", Xdbl_ToDouble(sum2) ); + printf( "1.5 * 2.5 = %lf\n", Xdbl_ToDouble(mul2) ); + printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) ); + + printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) ); + + printf( "%.16lf * %.16lf = %.16lf (%.16lf)\n", Xdbl_ToDouble(a), Xdbl_ToDouble(b), Xdbl_ToDouble(ab), 1.2929725 * 10.28828287 ); + + assert( sum1 == c2p5 ); + assert( mul1 == c3 ); +} + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/misc/util/utilFloat.h b/src/misc/util/utilFloat.h new file mode 100644 index 00000000..f0739a92 --- /dev/null +++ b/src/misc/util/utilFloat.h @@ -0,0 +1,226 @@ +/**CFile**************************************************************** + + FileName [utilFloat.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [] + + Synopsis [Floating point number implementation.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley / UFRGS] + + Date [Ver. 1.0. Started - January 28, 2017.] + + Revision [] + +***********************************************************************/ +#ifndef ABC__sat__xSAT__xsatFloat_h +#define ABC__sat__xSAT__xsatFloat_h + +#include "misc/util/abc_global.h" + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/* + The xFloat_t floating-point number is represented as a 32-bit unsigned int. + The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a + 16-bit mantissa. The decimal point is located between the MSB of Mnt, + which is always 1, and the remaining 15 digits of Mnt. + + Currently, only positive numbers are represented. + + The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] + that is, the smallest possible number is 1.0 and the largest possible + number is 2^(---16 ones---).(1.---15 ones---) + + Comparison of numbers can be done by comparing the underlying unsigned ints. + + Only addition, multiplication, and division by 2^n are currently implemented. +*/ + +typedef struct xFloat_t_ xFloat_t; +struct xFloat_t_ +{ + unsigned Mnt : 16; + unsigned Exp : 16; +}; + +static inline unsigned xSat_Float2Uint( xFloat_t f ) { union { xFloat_t f; unsigned u; } temp; temp.f = f; return temp.u; } +static inline xFloat_t xSat_Uint2Float( unsigned u ) { union { xFloat_t f; unsigned u; } temp; temp.u = u; return temp.f; } +static inline int xSat_LessThan( xFloat_t a, xFloat_t b ) { return a.Exp < b.Exp || (a.Exp == b.Exp && a.Mnt < b.Mnt); } +static inline int xSat_Equal( xFloat_t a, xFloat_t b ) { return a.Exp == b.Exp && a.Mnt == b.Mnt; } + +static inline xFloat_t xSat_FloatCreate( unsigned Exp, unsigned Mnt ) { xFloat_t res; res.Exp = Exp; res.Mnt = Mnt; return res; } + +static inline xFloat_t xSat_FloatCreateConst1() { return xSat_FloatCreate( 0, 1 << 15 ); } +static inline xFloat_t xSat_FloatCreateConst2() { return xSat_FloatCreate( 1, 1 << 15 ); } +static inline xFloat_t xSat_FloatCreateConst3() { return xSat_FloatCreate( 1, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst12() { return xSat_FloatCreate( 3, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst1point5() { return xSat_FloatCreate( 0, 3 << 14 ); } +static inline xFloat_t xSat_FloatCreateConst2point5() { return xSat_FloatCreate( 1, 5 << 13 ); } +static inline xFloat_t xSat_FloatCreateMaximum() { return xSat_Uint2Float( 0xFFFFFFFF ); } + +static inline float xSat_Float2Float( xFloat_t a ) { assert(a.Exp < 127); return Abc_Int2Float(((a.Exp + 127) << 23) | ((a.Mnt & 0x7FFF) << 8)); } +static inline xFloat_t xSat_FloatFromFloat( float a ) { int A = Abc_Float2Int(a); assert(a >= 1.0); return xSat_FloatCreate((A >> 23)-127, 0x8000 | ((A >> 8) & 0x7FFF)); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Adding two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatAdd( xFloat_t a, xFloat_t b ) +{ + unsigned Exp, Mnt; + if ( a.Exp < b.Exp ) + return xSat_FloatAdd(b, a); + assert( a.Exp >= b.Exp ); + // compute new mantissa + Mnt = a.Mnt + (b.Mnt >> (a.Exp - b.Exp)); + // compute new exponent + Exp = a.Exp; + // update exponent and mantissa if new MSB is created + if ( Mnt & 0xFFFF0000 ) // new MSB bit is created + Exp++, Mnt >>= 1; + // check overflow + if ( Exp & 0xFFFF0000 ) // overflow + return xSat_Uint2Float( 0xFFFFFFFF ); + assert( (Exp & 0xFFFF0000) == 0 ); + assert( (Mnt & 0xFFFF0000) == 0 ); + assert( Mnt & 0x00008000 ); + return xSat_FloatCreate( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Multiplying two floating-point numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatMul( xFloat_t a, xFloat_t b ) +{ + unsigned Exp, Mnt; + if ( a.Exp < b.Exp ) + return xSat_FloatMul(b, a); + assert( a.Exp >= b.Exp ); + // compute new mantissa + Mnt = (a.Mnt * b.Mnt) >> 15; + // compute new exponent + Exp = a.Exp + b.Exp; + // update exponent and mantissa if new MSB is created + if ( Mnt & 0xFFFF0000 ) // new MSB bit is created + Exp++, Mnt >>= 1; + // check overflow + if ( Exp & 0xFFFF0000 ) // overflow + return xSat_Uint2Float( 0xFFFFFFFF ); + assert( (Exp & 0xFFFF0000) == 0 ); + assert( (Mnt & 0xFFFF0000) == 0 ); + assert( Mnt & 0x00008000 ); + return xSat_FloatCreate( Exp, Mnt ); +} + +/**Function************************************************************* + + Synopsis [Dividing floating point number by a degree of 2.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline xFloat_t xSat_FloatDiv( xFloat_t a, unsigned Deg2 ) +{ + assert( Deg2 < 0xFFFF ); + if ( a.Exp >= Deg2 ) + return xSat_FloatCreate( a.Exp - Deg2, a.Mnt ); + return xSat_FloatCreateConst1(); // underflow +} + +/**Function************************************************************* + + Synopsis [Testing procedure.] + + Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void xSat_FloatTest() +{ + xFloat_t c1 = xSat_FloatCreateConst1(); + xFloat_t c2 = xSat_FloatCreateConst2(); + xFloat_t c3 = xSat_FloatCreateConst3(); + xFloat_t c12 = xSat_FloatCreateConst12(); + xFloat_t c1p5 = xSat_FloatCreateConst1point5(); + xFloat_t c2p5 = xSat_FloatCreateConst2point5(); + + xFloat_t c1_ = xSat_FloatFromFloat(1.0); + xFloat_t c2_ = xSat_FloatFromFloat(2.0); + xFloat_t c3_ = xSat_FloatFromFloat(3.0); + xFloat_t c12_ = xSat_FloatFromFloat(12.0); + xFloat_t c1p5_ = xSat_FloatFromFloat(1.5); + xFloat_t c2p5_ = xSat_FloatFromFloat(2.5); + + xFloat_t sum1 = xSat_FloatAdd(c1, c1p5); + xFloat_t mul1 = xSat_FloatMul(c2, c1p5); + + xFloat_t sum2 = xSat_FloatAdd(c1p5, c2p5); + xFloat_t mul2 = xSat_FloatMul(c1p5, c2p5); + +// float f1 = xSat_Float2Float(c1); +// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" ); +// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" ); + + printf( "1 = %f\n", xSat_Float2Float(c1) ); + printf( "2 = %f\n", xSat_Float2Float(c2) ); + printf( "3 = %f\n", xSat_Float2Float(c3) ); + printf( "12 = %f\n", xSat_Float2Float(c12) ); + printf( "1.5 = %f\n", xSat_Float2Float(c1p5) ); + printf( "2.5 = %f\n", xSat_Float2Float(c2p5) ); + + printf( "Converted 1 = %f\n", xSat_Float2Float(c1_) ); + printf( "Converted 2 = %f\n", xSat_Float2Float(c2_) ); + printf( "Converted 3 = %f\n", xSat_Float2Float(c3_) ); + printf( "Converted 12 = %f\n", xSat_Float2Float(c12_) ); + printf( "Converted 1.5 = %f\n", xSat_Float2Float(c1p5_) ); + printf( "Converted 2.5 = %f\n", xSat_Float2Float(c2p5_) ); + + printf( "1.0 + 1.5 = %f\n", xSat_Float2Float(sum1) ); + printf( "2.0 * 1.5 = %f\n", xSat_Float2Float(mul1) ); + + printf( "1.5 + 2.5 = %f\n", xSat_Float2Float(sum2) ); + printf( "1.5 * 2.5 = %f\n", xSat_Float2Float(mul2) ); + printf( "12 / 2^2 = %f\n", xSat_Float2Float(xSat_FloatDiv(c12, 2)) ); + + assert( xSat_Equal(sum1, c2p5) ); + assert( xSat_Equal(mul1, c3) ); +} + +ABC_NAMESPACE_HEADER_END + +#endif diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 226d8c7a..21f24fcb 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -30,7 +30,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "satVec.h" #include "satClause.h" -#include "sat/xsat/xsatFloat.h" +#include "misc/util/utilFloat.h" +#include "misc/util/utilDouble.h" ABC_NAMESPACE_HEADER_START diff --git a/src/sat/xsat/xsatDouble.h b/src/sat/xsat/xsatDouble.h deleted file mode 100644 index d90e8c05..00000000 --- a/src/sat/xsat/xsatDouble.h +++ /dev/null @@ -1,226 +0,0 @@ -/**CFile**************************************************************** - - FileName [xdouble.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [] - - Synopsis [Double floating point number implementation.] - - Author [Alan Mishchenko, Bruno Schmitt] - - Affiliation [UC Berkeley / UFRGS] - - Date [Ver. 1.0. Started - February 11, 2017.] - - Revision [] - -***********************************************************************/ - -#ifndef ABC__sat__Xdbl__Xdbl_h -#define ABC__sat__Xdbl__Xdbl_h - -#include "misc/util/abc_global.h" - -ABC_NAMESPACE_HEADER_START - -//////////////////////////////////////////////////////////////////////// -/// STRUCTURE DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/* - The xdbl floating-point number is represented as a 64-bit unsigned int. - The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a - 48-bit mantissa. The decimal point is located between the MSB of Mnt, - which is always 1, and the remaining 15 digits of Mnt. - - Currently, only positive numbers are represented. - - The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] - that is, the smallest possible number is 1.0 and the largest possible - number is 2^(---16 ones---).(1.---47 ones---) - - Comparison of numbers can be done by comparing the underlying unsigned ints. - - Only addition, multiplication, and division by 2^n are currently implemented. -*/ - -static inline word Abc_Dbl2Word( double Dbl ) { union { word x; double y; } v; v.y = Dbl; return v.x; } -static inline double Abc_Word2Dbl( word Num ) { union { word x; double y; } v; v.x = Num; return v.y; } - - -typedef word xdbl; - -static inline word Xdbl_Exp( xdbl a ) { return a >> 48; } -static inline word Xdbl_Mnt( xdbl a ) { return (a << 16) >> 16; } - -static inline xdbl Xdbl_Create( word Exp, word Mnt ) { assert(!(Exp>>16) && (Mnt>>47)==(word)1); return (Exp<<48) | Mnt; } - -static inline xdbl Xdbl_Const1() { return Xdbl_Create( (word)0, (word)1 << 47 ); } -static inline xdbl Xdbl_Const2() { return Xdbl_Create( (word)1, (word)1 << 47 ); } -static inline xdbl Xdbl_Const3() { return Xdbl_Create( (word)1, (word)3 << 46 ); } -static inline xdbl Xdbl_Const12() { return Xdbl_Create( (word)3, (word)3 << 46 ); } -static inline xdbl Xdbl_Const1point5() { return Xdbl_Create( (word)0, (word)3 << 46 ); } -static inline xdbl Xdbl_Const2point5() { return Xdbl_Create( (word)1, (word)5 << 45 ); } -static inline xdbl Xdbl_Maximum() { return ~(word)0; } - -static inline double Xdbl_ToDouble( xdbl a ) { assert(Xdbl_Exp(a) < 1023); return Abc_Word2Dbl(((Xdbl_Exp(a) + 1023) << 52) | (((a<<17)>>17) << 5)); } -static inline xdbl Xdbl_FromDouble( double a ) { word A = Abc_Dbl2Word(a); assert(a >= 1.0); return Xdbl_Create((A >> 52)-1023, (((word)1) << 47) | ((A << 12) >> 17)); } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Adding two floating-point numbers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline xdbl Xdbl_Add( xdbl a, xdbl b ) -{ - word Exp, Mnt; - if ( a < b ) a ^= b, b ^= a, a ^= b; - assert( a >= b ); - Mnt = Xdbl_Mnt(a) + (Xdbl_Mnt(b) >> (Xdbl_Exp(a) - Xdbl_Exp(b))); - Exp = Xdbl_Exp(a); - if ( Mnt >> 48 ) // new MSB is created - Exp++, Mnt >>= 1; - if ( Exp >> 16 ) // overflow - return Xdbl_Maximum(); - return Xdbl_Create( Exp, Mnt ); -} - -/**Function************************************************************* - - Synopsis [Multiplying two floating-point numbers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline xdbl Xdbl_Mul( xdbl a, xdbl b ) -{ - word Exp, Mnt, MntA, MntB, MntAh, MntBh, MntAl, MntBl; - if ( a < b ) a ^= b, b ^= a, a ^= b; - assert( a >= b ); - MntA = Xdbl_Mnt(a); - MntB = Xdbl_Mnt(b); - MntAh = MntA>>32; - MntBh = MntB>>32; - MntAl = (MntA<<32)>>32; - MntBl = (MntB<<32)>>32; - Mnt = ((MntAh * MntBh) << 17) + ((MntAl * MntBl) >> 47) + ((MntAl * MntBh) >> 15) + ((MntAh * MntBl) >> 15); - Exp = Xdbl_Exp(a) + Xdbl_Exp(b); - if ( Mnt >> 48 ) // new MSB is created - Exp++, Mnt >>= 1; - if ( Exp >> 16 ) // overflow - return Xdbl_Maximum(); - return Xdbl_Create( Exp, Mnt ); -} - -/**Function************************************************************* - - Synopsis [Dividing floating point number by a degree of 2.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline xdbl Xdbl_Div( xdbl a, unsigned Deg2 ) -{ - if ( Xdbl_Exp(a) >= (word)Deg2 ) - return Xdbl_Create( Xdbl_Exp(a) - Deg2, Xdbl_Mnt(a) ); - return Xdbl_Const1(); // underflow -} - -/**Function************************************************************* - - Synopsis [Testing procedure.] - - Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Xdbl_Test() -{ - xdbl c1 = Xdbl_Const1(); - xdbl c2 = Xdbl_Const2(); - xdbl c3 = Xdbl_Const3(); - xdbl c12 = Xdbl_Const12(); - xdbl c1p5 = Xdbl_Const1point5(); - xdbl c2p5 = Xdbl_Const2point5(); - - xdbl c1_ = Xdbl_FromDouble(1.0); - xdbl c2_ = Xdbl_FromDouble(2.0); - xdbl c3_ = Xdbl_FromDouble(3.0); - xdbl c12_ = Xdbl_FromDouble(12.0); - xdbl c1p5_ = Xdbl_FromDouble(1.5); - xdbl c2p5_ = Xdbl_FromDouble(2.5); - - xdbl sum1 = Xdbl_Add(c1, c1p5); - xdbl mul1 = Xdbl_Mul(c2, c1p5); - - xdbl sum2 = Xdbl_Add(c1p5, c2p5); - xdbl mul2 = Xdbl_Mul(c1p5, c2p5); - - xdbl a = Xdbl_FromDouble(1.2929725); - xdbl b = Xdbl_FromDouble(10.28828287); - xdbl ab = Xdbl_Mul(a, b); - - xdbl ten100 = Xdbl_FromDouble( 1e100 ); - xdbl ten100_ = ABC_CONST(0x014c924d692ca61b); - - assert( ten100 == ten100_ ); - -// float f1 = Xdbl_ToDouble(c1); -// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" ); -// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" ); - - printf( "1 = %lf\n", Xdbl_ToDouble(c1) ); - printf( "2 = %lf\n", Xdbl_ToDouble(c2) ); - printf( "3 = %lf\n", Xdbl_ToDouble(c3) ); - printf( "12 = %lf\n", Xdbl_ToDouble(c12) ); - printf( "1.5 = %lf\n", Xdbl_ToDouble(c1p5) ); - printf( "2.5 = %lf\n", Xdbl_ToDouble(c2p5) ); - - printf( "Converted 1 = %lf\n", Xdbl_ToDouble(c1_) ); - printf( "Converted 2 = %lf\n", Xdbl_ToDouble(c2_) ); - printf( "Converted 3 = %lf\n", Xdbl_ToDouble(c3_) ); - printf( "Converted 12 = %lf\n", Xdbl_ToDouble(c12_) ); - printf( "Converted 1.5 = %lf\n", Xdbl_ToDouble(c1p5_) ); - printf( "Converted 2.5 = %lf\n", Xdbl_ToDouble(c2p5_) ); - - printf( "1.0 + 1.5 = %lf\n", Xdbl_ToDouble(sum1) ); - printf( "2.0 * 1.5 = %lf\n", Xdbl_ToDouble(mul1) ); - - printf( "1.5 + 2.5 = %lf\n", Xdbl_ToDouble(sum2) ); - printf( "1.5 * 2.5 = %lf\n", Xdbl_ToDouble(mul2) ); - printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) ); - - printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) ); - - printf( "%.16lf * %.16lf = %.16lf (%.16lf)\n", Xdbl_ToDouble(a), Xdbl_ToDouble(b), Xdbl_ToDouble(ab), 1.2929725 * 10.28828287 ); - - assert( sum1 == c2p5 ); - assert( mul1 == c3 ); -} - -ABC_NAMESPACE_HEADER_END - -#endif diff --git a/src/sat/xsat/xsatFloat.h b/src/sat/xsat/xsatFloat.h deleted file mode 100644 index fb451a94..00000000 --- a/src/sat/xsat/xsatFloat.h +++ /dev/null @@ -1,227 +0,0 @@ -/**CFile**************************************************************** - - FileName [xsatFloat.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [xSAT - A SAT solver written in C. - Read the license file for more info.] - - Synopsis [Floating point number implementation.] - - Author [Alan Mishchenko, Bruno Schmitt] - - Affiliation [UC Berkeley / UFRGS] - - Date [Ver. 1.0. Started - January 28, 2017.] - - Revision [] - -***********************************************************************/ -#ifndef ABC__sat__xSAT__xsatFloat_h -#define ABC__sat__xSAT__xsatFloat_h - -#include "misc/util/abc_global.h" - -ABC_NAMESPACE_HEADER_START - -//////////////////////////////////////////////////////////////////////// -/// STRUCTURE DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/* - The xFloat_t floating-point number is represented as a 32-bit unsigned int. - The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a - 16-bit mantissa. The decimal point is located between the MSB of Mnt, - which is always 1, and the remaining 15 digits of Mnt. - - Currently, only positive numbers are represented. - - The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111] - that is, the smallest possible number is 1.0 and the largest possible - number is 2^(---16 ones---).(1.---15 ones---) - - Comparison of numbers can be done by comparing the underlying unsigned ints. - - Only addition, multiplication, and division by 2^n are currently implemented. -*/ - -typedef struct xFloat_t_ xFloat_t; -struct xFloat_t_ -{ - unsigned Mnt : 16; - unsigned Exp : 16; -}; - -static inline unsigned xSat_Float2Uint( xFloat_t f ) { union { xFloat_t f; unsigned u; } temp; temp.f = f; return temp.u; } -static inline xFloat_t xSat_Uint2Float( unsigned u ) { union { xFloat_t f; unsigned u; } temp; temp.u = u; return temp.f; } -static inline int xSat_LessThan( xFloat_t a, xFloat_t b ) { return a.Exp < b.Exp || (a.Exp == b.Exp && a.Mnt < b.Mnt); } -static inline int xSat_Equal( xFloat_t a, xFloat_t b ) { return a.Exp == b.Exp && a.Mnt == b.Mnt; } - -static inline xFloat_t xSat_FloatCreate( unsigned Exp, unsigned Mnt ) { xFloat_t res; res.Exp = Exp; res.Mnt = Mnt; return res; } - -static inline xFloat_t xSat_FloatCreateConst1() { return xSat_FloatCreate( 0, 1 << 15 ); } -static inline xFloat_t xSat_FloatCreateConst2() { return xSat_FloatCreate( 1, 1 << 15 ); } -static inline xFloat_t xSat_FloatCreateConst3() { return xSat_FloatCreate( 1, 3 << 14 ); } -static inline xFloat_t xSat_FloatCreateConst12() { return xSat_FloatCreate( 3, 3 << 14 ); } -static inline xFloat_t xSat_FloatCreateConst1point5() { return xSat_FloatCreate( 0, 3 << 14 ); } -static inline xFloat_t xSat_FloatCreateConst2point5() { return xSat_FloatCreate( 1, 5 << 13 ); } -static inline xFloat_t xSat_FloatCreateMaximum() { return xSat_Uint2Float( 0xFFFFFFFF ); } - -static inline float xSat_Float2Float( xFloat_t a ) { assert(a.Exp < 127); return Abc_Int2Float(((a.Exp + 127) << 23) | ((a.Mnt & 0x7FFF) << 8)); } -static inline xFloat_t xSat_FloatFromFloat( float a ) { int A = Abc_Float2Int(a); assert(a >= 1.0); return xSat_FloatCreate((A >> 23)-127, 0x8000 | ((A >> 8) & 0x7FFF)); } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Adding two floating-point numbers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline xFloat_t xSat_FloatAdd( xFloat_t a, xFloat_t b ) -{ - unsigned Exp, Mnt; - if ( a.Exp < b.Exp ) - return xSat_FloatAdd(b, a); - assert( a.Exp >= b.Exp ); - // compute new mantissa - Mnt = a.Mnt + (b.Mnt >> (a.Exp - b.Exp)); - // compute new exponent - Exp = a.Exp; - // update exponent and mantissa if new MSB is created - if ( Mnt & 0xFFFF0000 ) // new MSB bit is created - Exp++, Mnt >>= 1; - // check overflow - if ( Exp & 0xFFFF0000 ) // overflow - return xSat_Uint2Float( 0xFFFFFFFF ); - assert( (Exp & 0xFFFF0000) == 0 ); - assert( (Mnt & 0xFFFF0000) == 0 ); - assert( Mnt & 0x00008000 ); - return xSat_FloatCreate( Exp, Mnt ); -} - -/**Function************************************************************* - - Synopsis [Multiplying two floating-point numbers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline xFloat_t xSat_FloatMul( xFloat_t a, xFloat_t b ) -{ - unsigned Exp, Mnt; - if ( a.Exp < b.Exp ) - return xSat_FloatMul(b, a); - assert( a.Exp >= b.Exp ); - // compute new mantissa - Mnt = (a.Mnt * b.Mnt) >> 15; - // compute new exponent - Exp = a.Exp + b.Exp; - // update exponent and mantissa if new MSB is created - if ( Mnt & 0xFFFF0000 ) // new MSB bit is created - Exp++, Mnt >>= 1; - // check overflow - if ( Exp & 0xFFFF0000 ) // overflow - return xSat_Uint2Float( 0xFFFFFFFF ); - assert( (Exp & 0xFFFF0000) == 0 ); - assert( (Mnt & 0xFFFF0000) == 0 ); - assert( Mnt & 0x00008000 ); - return xSat_FloatCreate( Exp, Mnt ); -} - -/**Function************************************************************* - - Synopsis [Dividing floating point number by a degree of 2.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline xFloat_t xSat_FloatDiv( xFloat_t a, unsigned Deg2 ) -{ - assert( Deg2 < 0xFFFF ); - if ( a.Exp >= Deg2 ) - return xSat_FloatCreate( a.Exp - Deg2, a.Mnt ); - return xSat_FloatCreateConst1(); // underflow -} - -/**Function************************************************************* - - Synopsis [Testing procedure.] - - Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void xSat_FloatTest() -{ - xFloat_t c1 = xSat_FloatCreateConst1(); - xFloat_t c2 = xSat_FloatCreateConst2(); - xFloat_t c3 = xSat_FloatCreateConst3(); - xFloat_t c12 = xSat_FloatCreateConst12(); - xFloat_t c1p5 = xSat_FloatCreateConst1point5(); - xFloat_t c2p5 = xSat_FloatCreateConst2point5(); - - xFloat_t c1_ = xSat_FloatFromFloat(1.0); - xFloat_t c2_ = xSat_FloatFromFloat(2.0); - xFloat_t c3_ = xSat_FloatFromFloat(3.0); - xFloat_t c12_ = xSat_FloatFromFloat(12.0); - xFloat_t c1p5_ = xSat_FloatFromFloat(1.5); - xFloat_t c2p5_ = xSat_FloatFromFloat(2.5); - - xFloat_t sum1 = xSat_FloatAdd(c1, c1p5); - xFloat_t mul1 = xSat_FloatMul(c2, c1p5); - - xFloat_t sum2 = xSat_FloatAdd(c1p5, c2p5); - xFloat_t mul2 = xSat_FloatMul(c1p5, c2p5); - -// float f1 = xSat_Float2Float(c1); -// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" ); -// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" ); - - printf( "1 = %f\n", xSat_Float2Float(c1) ); - printf( "2 = %f\n", xSat_Float2Float(c2) ); - printf( "3 = %f\n", xSat_Float2Float(c3) ); - printf( "12 = %f\n", xSat_Float2Float(c12) ); - printf( "1.5 = %f\n", xSat_Float2Float(c1p5) ); - printf( "2.5 = %f\n", xSat_Float2Float(c2p5) ); - - printf( "Converted 1 = %f\n", xSat_Float2Float(c1_) ); - printf( "Converted 2 = %f\n", xSat_Float2Float(c2_) ); - printf( "Converted 3 = %f\n", xSat_Float2Float(c3_) ); - printf( "Converted 12 = %f\n", xSat_Float2Float(c12_) ); - printf( "Converted 1.5 = %f\n", xSat_Float2Float(c1p5_) ); - printf( "Converted 2.5 = %f\n", xSat_Float2Float(c2p5_) ); - - printf( "1.0 + 1.5 = %f\n", xSat_Float2Float(sum1) ); - printf( "2.0 * 1.5 = %f\n", xSat_Float2Float(mul1) ); - - printf( "1.5 + 2.5 = %f\n", xSat_Float2Float(sum2) ); - printf( "1.5 * 2.5 = %f\n", xSat_Float2Float(mul2) ); - printf( "12 / 2^2 = %f\n", xSat_Float2Float(xSat_FloatDiv(c12, 2)) ); - - assert( xSat_Equal(sum1, c2p5) ); - assert( xSat_Equal(mul1, c3) ); -} - -ABC_NAMESPACE_HEADER_END - -#endif -- cgit v1.2.3 From f6193c0d45406e863e7efe3e092e0284d86adb9b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 15:38:50 -0800 Subject: Updates to variable activity in the SAT solver. --- src/sat/bsat/satSolver.c | 479 +++++++++++++++++++---------------------------- src/sat/bsat/satSolver.h | 87 +++------ 2 files changed, 224 insertions(+), 342 deletions(-) (limited to 'src') diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 1a2a393d..efe8efa6 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -145,21 +145,12 @@ static inline void order_update(sat_solver* s, int v) // updateorder assert(s->orderpos[v] != -1); -#ifdef USE_FLOAT_ACTIVITY_NEW - while (i != 0 && xSat_LessThan(s->activity[heap[parent]], s->activity[x]) ){ - heap[i] = heap[parent]; - orderpos[heap[i]] = i; - i = parent; - parent = (i - 1) / 2; - } -#else while (i != 0 && s->activity[x] > s->activity[heap[parent]]){ heap[i] = heap[parent]; orderpos[heap[i]] = i; i = parent; parent = (i - 1) / 2; } -#endif heap[i] = x; orderpos[x] = i; @@ -203,19 +194,11 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv int child = 1; while (child < size){ -#ifdef USE_FLOAT_ACTIVITY_NEW - if (child+1 < size && xSat_LessThan(s->activity[heap[child]], s->activity[heap[child+1]]) ) - child++; - assert(child < size); - if ( !xSat_LessThan(s->activity[x], s->activity[heap[child]]) ) - break; -#else if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]]) child++; assert(child < size); if (s->activity[x] >= s->activity[heap[child]]) break; -#endif heap[i] = heap[child]; orderpos[heap[i]] = i; @@ -233,161 +216,181 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars) { -#ifndef USE_FLOAT_ACTIVITY_NEW int i; + assert( s->VarActType == 1 ); for (i = 0; i < s->size; i++) s->activity[i] = 0; - s->var_inc = 1; + s->var_inc = Abc_Dbl2Word(1); for ( i = 0; i < nVars; i++ ) { int iVar = pVars ? pVars[i] : i; - s->activity[iVar] = nVars-i; + s->activity[iVar] = Abc_Dbl2Word(nVars-i); order_update( s, iVar ); } -#endif } //================================================================================================= -// Activity functions: - -#ifdef USE_FLOAT_ACTIVITY +// variable activities -#ifdef USE_FLOAT_ACTIVITY_NEW +static inline void solver_init_activities(sat_solver* s) +{ + // variable activities + s->VarActType = 0; + if ( s->VarActType == 0 ) + { + s->var_inc = (1 << 5); + s->var_decay = -1; + } + else if ( s->VarActType == 1 ) + { + s->var_inc = Abc_Dbl2Word(1.0); + s->var_decay = Abc_Dbl2Word(1.0 / 0.95); + } + else if ( s->VarActType == 2 ) + { + s->var_inc = Xdbl_FromDouble(1.0); + s->var_decay = Xdbl_FromDouble(1.0 / 0.950); + } + else assert(0); -static inline void act_var_rescale(sat_solver* s) { - xFloat_t * activity = s->activity; - int i; - for (i = 0; i < s->size; i++) - activity[i] = xSat_FloatDiv( activity[i], 1<<10 ); // activity[i] / 2^1024 - s->var_inc = xSat_FloatDiv( s->var_inc, 1<<10 ); -} -static inline void act_clause_rescale(sat_solver* s) { - xFloat_t* activity = (xFloat_t *)veci_begin(&s->act_clas); - int i; - for (i = 0; i < veci_size(&s->act_clas); i++) - activity[i] = xSat_FloatDiv( activity[i], 1<<10 ); // activity[i] / 2^1024 - s->cla_inc = xSat_FloatDiv( s->cla_inc, 1<<10 ); -} -static inline void act_var_bump(sat_solver* s, int v) { - s->activity[v] = xSat_FloatAdd( s->activity[v], s->var_inc ); - if ( xSat_LessThan(xSat_FloatCreate(1 << 12, 1 << 15), s->activity[v]) ) // 2^4096 < s->activity[v] - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); -} -static inline void act_var_bump_global(sat_solver* s, int v) { - assert(0); -} -static inline void act_var_bump_factor(sat_solver* s, int v) { - assert(0); -} -static inline void act_clause_bump(sat_solver* s, clause *c) { - xFloat_t* act = (xFloat_t *)veci_begin(&s->act_clas) + c->lits[c->size]; - *act = xSat_FloatAdd( *act, s->cla_inc ); - if ( xSat_LessThan(xSat_FloatCreate(1 << 12, 1 << 15), *act) ) // 2^4096 < *act - act_clause_rescale(s); + // clause activities + s->ClaActType = 0; + if ( s->ClaActType == 0 ) + { + s->cla_inc = (1 << 11); + s->cla_decay = -1; + } + else + { + s->cla_inc = 1; + s->cla_decay = (float)(1 / 0.999); + } } -static inline void act_var_decay(sat_solver* s) { s->var_inc = xSat_FloatMul(s->var_inc, s->var_decay); } -static inline void act_clause_decay(sat_solver* s) { s->cla_inc = xSat_FloatMul(s->cla_inc, s->cla_decay); } - -#else -static inline void act_var_rescale(sat_solver* s) { - double* activity = s->activity; - int i; - for (i = 0; i < s->size; i++) - activity[i] *= 1e-100; - s->var_inc *= 1e-100; +static inline void act_var_rescale(sat_solver* s) +{ + if ( s->VarActType == 0 ) + { + word* activity = s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] >>= 19; + s->var_inc >>= 19; + s->var_inc = Abc_MaxInt( (unsigned)s->var_inc, (1<<4) ); + } + else if ( s->VarActType == 1 ) + { + double* activity = (double*)s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] *= 1e-100; + s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * 1e-100 ); + //printf( "Rescaling var activity...\n" ); + } + else if ( s->VarActType == 2 ) + { + xdbl * activity = s->activity; + int i; + for (i = 0; i < s->size; i++) + activity[i] = Xdbl_Div( activity[i], 200 ); // activity[i] / 2^200 + s->var_inc = Xdbl_Div( s->var_inc, 200 ); + } + else assert(0); } -static inline void act_clause_rescale(sat_solver* s) { - float* activity = (float *)veci_begin(&s->act_clas); - int i; - for (i = 0; i < veci_size(&s->act_clas); i++) - activity[i] *= (float)1e-20; - s->cla_inc *= (float)1e-20; -} -static inline void act_var_bump(sat_solver* s, int v) { - s->activity[v] += s->var_inc; - if (s->activity[v] > 1e100) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); +static inline void act_var_bump(sat_solver* s, int v) +{ + if ( s->VarActType == 0 ) + { + s->activity[v] += s->var_inc; + if ((unsigned)s->activity[v] & 0x80000000) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 1 ) + { + double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc); + s->activity[v] = Abc_Dbl2Word(act); + if (act > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 2 ) + { + s->activity[v] = Xdbl_Add( s->activity[v], s->var_inc ); + if (s->activity[v] > ABC_CONST(0x014c924d692ca61b)) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else assert(0); } -static inline void act_var_bump_global(sat_solver* s, int v) { +static inline void act_var_bump_global(sat_solver* s, int v) +{ assert(0); } -static inline void act_var_bump_factor(sat_solver* s, int v) { +static inline void act_var_bump_factor(sat_solver* s, int v) +{ assert(0); } -static inline void act_clause_bump(sat_solver* s, clause *c) { - float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size]; - *act += s->cla_inc; - if (*act > 1e20) - act_clause_rescale(s); +static inline void act_var_decay(sat_solver* s) +{ + if ( s->VarActType == 0 ) + s->var_inc += (s->var_inc >> 4); + else if ( s->VarActType == 1 ) + s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * Abc_Word2Dbl(s->var_decay) ); + else if ( s->VarActType == 2 ) + s->var_inc = Xdbl_Mul(s->var_inc, s->var_decay); + else assert(0); } -static inline void act_var_decay(sat_solver* s) { s->var_inc *= s->var_decay; } -static inline void act_clause_decay(sat_solver* s) { s->cla_inc *= s->cla_decay; } - -#endif -#else - -static inline void act_var_rescale(sat_solver* s) { - unsigned* activity = s->activity; - int i; - for (i = 0; i < s->size; i++) - activity[i] >>= 19; - s->var_inc >>= 19; - s->var_inc = Abc_MaxInt( s->var_inc, (1<<4) ); -} - -static inline void act_clause_rescale(sat_solver* s) { - unsigned* activity = (unsigned *)veci_begin(&s->act_clas); - int i; - for (i = 0; i < veci_size(&s->act_clas); i++) - activity[i] >>= 14; - s->cla_inc >>= 14; - s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) ); -} - -static inline void act_var_bump(sat_solver* s, int v) { - s->activity[v] += s->var_inc; - if (s->activity[v] & 0x80000000) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); -} -static inline void act_var_bump_global(sat_solver* s, int v) { - if ( !s->pGlobalVars ) - return; - s->activity[v] += (int)(s->var_inc * 3 * s->pGlobalVars[v]); - if (s->activity[v] & 0x80000000) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); +// clause activities +static inline void act_clause_rescale(sat_solver* s) +{ + if ( s->ClaActType == 0 ) + { + unsigned* activity = (unsigned *)veci_begin(&s->act_clas); + int i; + for (i = 0; i < veci_size(&s->act_clas); i++) + activity[i] >>= 14; + s->cla_inc >>= 14; + s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) ); + } + else + { + float* activity = (float *)veci_begin(&s->act_clas); + int i; + for (i = 0; i < veci_size(&s->act_clas); i++) + activity[i] *= (float)1e-20; + s->cla_inc *= (float)1e-20; + } } -static inline void act_var_bump_factor(sat_solver* s, int v) { - if ( !s->factors ) - return; - s->activity[v] += (int)(s->var_inc * s->factors[v]); - if (s->activity[v] & 0x80000000) - act_var_rescale(s); - if (s->orderpos[v] != -1) - order_update(s,v); +static inline void act_clause_bump(sat_solver* s, clause *c) +{ + if ( s->ClaActType == 0 ) + { + unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size]; + *act += s->cla_inc; + if ( *act & 0x80000000 ) + act_clause_rescale(s); + } + else + { + float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size]; + *act += s->cla_inc; + if (*act > 1e20) + act_clause_rescale(s); + } } - -static inline void act_clause_bump(sat_solver* s, clause*c) { - unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size]; - *act += s->cla_inc; - if ( *act & 0x80000000 ) - act_clause_rescale(s); +static inline void act_clause_decay(sat_solver* s) +{ + if ( s->ClaActType == 0 ) + s->cla_inc += (s->cla_inc >> 10); + else + s->cla_inc *= s->cla_decay; } -static inline void act_var_decay(sat_solver* s) { s->var_inc += (s->var_inc >> 4); } -static inline void act_clause_decay(sat_solver* s) { s->cla_inc += (s->cla_inc >> 10); } - -#endif - //================================================================================================= // Sorting functions (sigh): @@ -488,15 +491,10 @@ int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt) assert( clause_id(c) == veci_size(&s->act_clas) ); // veci_push(&s->learned, h); // act_clause_bump(s,clause_read(s, h)); -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - veci_push(&s->act_clas, xSat_Float2Uint(xSat_FloatCreateConst1())); -#else - veci_push(&s->act_clas, s->cla_inc); -#endif -#else - veci_push(&s->act_clas, (1<<10)); -#endif + if ( s->ClaActType == 0 ) + veci_push(&s->act_clas, (1<<10)); + else + veci_push(&s->act_clas, s->cla_inc); s->stats.learnts++; s->stats.learnts_literals += size; } @@ -1086,7 +1084,6 @@ sat_solver* sat_solver_new(void) veci_new(&s->act_clas); veci_new(&s->stack); // veci_new(&s->model); - veci_new(&s->act_vars); veci_new(&s->unit_lits); veci_new(&s->temp_clause); veci_new(&s->conf_final); @@ -1103,22 +1100,10 @@ sat_solver* sat_solver_new(void) s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + solver_init_activities(s); + veci_new(&s->act_vars); + s->root_level = 0; // s->simpdb_assigns = 0; // s->simpdb_props = 0; @@ -1164,7 +1149,6 @@ sat_solver* zsat_solver_new_seed(double seed) veci_new(&s->act_clas); veci_new(&s->stack); // veci_new(&s->model); - veci_new(&s->act_vars); veci_new(&s->unit_lits); veci_new(&s->temp_clause); veci_new(&s->conf_final); @@ -1181,22 +1165,10 @@ sat_solver* zsat_solver_new_seed(double seed) s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + solver_init_activities(s); + veci_new(&s->act_vars); + s->root_level = 0; // s->simpdb_assigns = 0; // s->simpdb_props = 0; @@ -1236,16 +1208,8 @@ void sat_solver_setnvars(sat_solver* s,int n) s->polarity = ABC_REALLOC(char, s->polarity, s->cap); s->tags = ABC_REALLOC(char, s->tags, s->cap); s->loads = ABC_REALLOC(char, s->loads, s->cap); -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->activity = ABC_REALLOC(xFloat_t, s->activity, s->cap); -#else - s->activity = ABC_REALLOC(double, s->activity, s->cap); -#endif -#else - s->activity = ABC_REALLOC(unsigned, s->activity, s->cap); - s->activity2 = ABC_REALLOC(unsigned, s->activity2,s->cap); -#endif + s->activity = ABC_REALLOC(word, s->activity, s->cap); + s->activity2 = ABC_REALLOC(word, s->activity2,s->cap); s->pFreqs = ABC_REALLOC(char, s->pFreqs, s->cap); if ( s->factors ) @@ -1264,15 +1228,15 @@ void sat_solver_setnvars(sat_solver* s,int n) veci_new(&s->wlists[2*var]); if ( s->wlists[2*var+1].ptr == NULL ) veci_new(&s->wlists[2*var+1]); -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->activity[var] = xSat_FloatCreateConst1(); -#else - s->activity[var] = 0; -#endif -#else - s->activity[var] = (1<<10); -#endif + + if ( s->VarActType == 0 ) + s->activity[var] = (1<<10); + else if ( s->VarActType == 1 ) + s->activity[var] = 0; + else if ( s->VarActType == 2 ) + s->activity[var] = Xdbl_Const1(); + else assert(0); + s->pFreqs[var] = 0; if ( s->factors ) s->factors [var] = 0; @@ -1349,7 +1313,6 @@ void sat_solver_restart( sat_solver* s ) s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 ); s->binary = clause_read( s, s->hBinary ); - veci_resize(&s->act_clas, 0); veci_resize(&s->trail_lim, 0); veci_resize(&s->order, 0); for ( i = 0; i < s->size*2; i++ ) @@ -1362,22 +1325,13 @@ void sat_solver_restart( sat_solver* s ) // s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + + // variable activities + solver_init_activities(s); + veci_resize(&s->act_clas, 0); + + s->root_level = 0; // s->simpdb_assigns = 0; // s->simpdb_props = 0; @@ -1405,7 +1359,6 @@ void zsat_solver_restart_seed( sat_solver* s, double seed ) s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 ); s->binary = clause_read( s, s->hBinary ); - veci_resize(&s->act_clas, 0); veci_resize(&s->trail_lim, 0); veci_resize(&s->order, 0); for ( i = 0; i < s->size*2; i++ ) @@ -1418,22 +1371,10 @@ void zsat_solver_restart_seed( sat_solver* s, double seed ) // s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + solver_init_activities(s); + veci_resize(&s->act_clas, 0); + s->root_level = 0; // s->simpdb_assigns = 0; // s->simpdb_props = 0; @@ -1466,17 +1407,9 @@ double sat_solver_memory( sat_solver* s ) Mem += s->cap * sizeof(char); // ABC_FREE(s->polarity ); Mem += s->cap * sizeof(char); // ABC_FREE(s->tags ); Mem += s->cap * sizeof(char); // ABC_FREE(s->loads ); -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - Mem += s->cap * sizeof(xFloat_t); // ABC_FREE(s->activity ); -#else - Mem += s->cap * sizeof(double); // ABC_FREE(s->activity ); -#endif -#else - Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity ); + Mem += s->cap * sizeof(word); // ABC_FREE(s->activity ); if ( s->activity2 ) - Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity2); -#endif + Mem += s->cap * sizeof(word); // ABC_FREE(s->activity ); if ( s->factors ) Mem += s->cap * sizeof(double); // ABC_FREE(s->factors ); Mem += s->cap * sizeof(int); // ABC_FREE(s->orderpos ); @@ -1523,7 +1456,7 @@ void sat_solver_reducedb(sat_solver* s) s->nDBreduces++; -// printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax ); + printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax ); s->nLearntMax = s->nLearntStart + s->nLearntDelta * s->nDBreduces; // return; @@ -1533,15 +1466,10 @@ void sat_solver_reducedb(sat_solver* s) { Id = clause_id(c); // pSortValues[Id] = act[Id]; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); -#else - pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4); -#endif -#else - pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); -#endif + if ( s->ClaActType == 0 ) + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4); + else + pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4); assert( pSortValues[Id] >= 0 ); } @@ -1647,15 +1575,7 @@ void sat_solver_rollback( sat_solver* s ) if ( s->activity2 ) { s->var_inc = s->var_inc2; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - memcpy( s->activity, s->activity2, sizeof(xFloat_t) * s->iVarPivot ); -#else - memcpy( s->activity, s->activity2, sizeof(double) * s->iVarPivot ); -#endif -#else - memcpy( s->activity, s->activity2, sizeof(unsigned) * s->iVarPivot ); -#endif + memcpy( s->activity, s->activity2, sizeof(word) * s->iVarPivot ); } veci_resize(&s->order, 0); for ( i = 0; i < s->iVarPivot; i++ ) @@ -1704,22 +1624,9 @@ void sat_solver_rollback( sat_solver* s ) // s->cap = 0; s->qhead = 0; s->qtail = 0; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - s->var_inc = xSat_FloatCreateConst1(); - s->cla_inc = xSat_FloatCreateConst1(); - s->var_decay = xSat_FloatFromFloat( (float)(1 / 0.95) ); - s->cla_decay = xSat_FloatFromFloat( (float)(1 / 0.999) ); -#else - s->var_inc = 1; - s->cla_inc = 1; - s->var_decay = (float)(1 / 0.95 ); - s->cla_decay = (float)(1 / 0.999); -#endif -#else - s->var_inc = (1 << 5); - s->cla_inc = (1 << 11); -#endif + + solver_init_activities(s); + s->root_level = 0; s->random_seed = 91648253; s->progress_estimate = 0; diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h index 21f24fcb..5a8483c1 100644 --- a/src/sat/bsat/satSolver.h +++ b/src/sat/bsat/satSolver.h @@ -30,14 +30,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "satVec.h" #include "satClause.h" -#include "misc/util/utilFloat.h" #include "misc/util/utilDouble.h" ABC_NAMESPACE_HEADER_START -//#define USE_FLOAT_ACTIVITY -//#define USE_FLOAT_ACTIVITY_NEW - //================================================================================================= // Public interface: @@ -111,7 +107,6 @@ struct sat_solver_t int hBinary; // the special binary clause clause * binary; veci* wlists; // watcher lists - veci act_clas; // contain clause activities // rollback int iVarPivot; // the pivot for variables @@ -119,31 +114,17 @@ struct sat_solver_t int hProofPivot; // the pivot for proof records // activities -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - xFloat_t var_inc; // Amount to bump next variable with. - xFloat_t var_inc2; // Amount to bump next variable with. - xFloat_t var_decay; // INVERSE decay factor for variable activity: stores 1/decay. - xFloat_t cla_inc; // Amount to bump next clause with. - xFloat_t cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. - xFloat_t* activity; // A heuristic measurement of the activity of a variable. - xFloat_t* activity2; // backup variable activity -#else - double var_inc; // Amount to bump next variable with. - double var_inc2; // Amount to bump next variable with. - double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. - float cla_inc; // Amount to bump next clause with. - float cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. - double* activity; // A heuristic measurement of the activity of a variable. - double* activity2; // A heuristic measurement of the activity of a variable. -#endif -#else - int var_inc; // Amount to bump next variable with. - int var_inc2; // Amount to bump next variable with. - int cla_inc; // Amount to bump next clause with. - unsigned* activity; // A heuristic measurement of the activity of a variable. - unsigned* activity2; // backup variable activity -#endif + int VarActType; + int ClaActType; + word var_inc; // Amount to bump next variable with. + word var_inc2; // Amount to bump next variable with. + word var_decay; // INVERSE decay factor for variable activity: stores 1/decay. + word* activity; // A heuristic measurement of the activity of a variable. + word* activity2; // backup variable activity + unsigned cla_inc; // Amount to bump next clause with. + unsigned cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. + veci act_clas; // contain clause activities + char * pFreqs; // how many times this variable was assigned a value int nVarUsed; @@ -233,21 +214,25 @@ static int sat_solver_var_literal( sat_solver* s, int v ) static void sat_solver_act_var_clear(sat_solver* s) { int i; -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW - for (i = 0; i < s->size; i++) - s->activity[i] = xSat_FloatCreateConst1(); - s->var_inc = xSat_FloatCreateConst1(); -#else - for (i = 0; i < s->size; i++) - s->activity[i] = 0; - s->var_inc = 1; -#endif -#else - for (i = 0; i < s->size; i++) - s->activity[i] = 0; - s->var_inc = (1 << 5); -#endif + if ( s->VarActType == 0 ) + { + for (i = 0; i < s->size; i++) + s->activity[i] = (1 << 10); + s->var_inc = (1 << 5); + } + else if ( s->VarActType == 1 ) + { + for (i = 0; i < s->size; i++) + s->activity[i] = 0; + s->var_inc = 1; + } + else if ( s->VarActType == 2 ) + { + for (i = 0; i < s->size; i++) + s->activity[i] = Xdbl_Const1(); + s->var_inc = Xdbl_Const1(); + } + else assert(0); } static void sat_solver_compress(sat_solver* s) { @@ -313,18 +298,8 @@ static inline void sat_solver_bookmark(sat_solver* s) Sat_MemBookMark( &s->Mem ); if ( s->activity2 ) { -#ifdef USE_FLOAT_ACTIVITY -#ifdef USE_FLOAT_ACTIVITY_NEW s->var_inc2 = s->var_inc; - memcpy( s->activity2, s->activity, sizeof(xFloat_t) * s->iVarPivot ); -#else - s->var_inc2 = s->var_inc; - memcpy( s->activity2, s->activity, sizeof(double) * s->iVarPivot ); -#endif -#else - s->var_inc2 = s->var_inc; - memcpy( s->activity2, s->activity, sizeof(unsigned) * s->iVarPivot ); -#endif + memcpy( s->activity2, s->activity, sizeof(word) * s->iVarPivot ); } } static inline void sat_solver_set_pivot_variables( sat_solver* s, int * pPivots, int nPivots ) -- cgit v1.2.3 From 7b7ebf91e458271b5979a3464b25faae5a5e4a6a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 15:40:53 -0800 Subject: Compiler warning. --- src/aig/ivy/ivyFraig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/aig/ivy/ivyFraig.c b/src/aig/ivy/ivyFraig.c index 059f4c0e..d9887d74 100644 --- a/src/aig/ivy/ivyFraig.c +++ b/src/aig/ivy/ivyFraig.c @@ -2081,7 +2081,7 @@ void Ivy_FraigPrintActivity( Ivy_FraigMan_t * p ) { int i; for ( i = 0; i < p->nSatVars; i++ ) - printf( "%d %d ", i, p->pSat->activity[i] ); + printf( "%d %d ", i, (int)p->pSat->activity[i] ); printf( "\n" ); } -- cgit v1.2.3 From 2a5fa67d36393ab3ddb14e5bf542b0f29c8634e1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 17:28:37 -0800 Subject: Adding APIs to mark cones. Creating test-bench for incremental solving &satoko -i. --- src/aig/gia/giaSatoko.c | 133 ++++++++++++++++++++++++++++++++++---------- src/base/abci/abc.c | 14 +++-- src/base/cmd/cmdAuto.c | 6 +- src/sat/satoko/satoko.h | 2 + src/sat/satoko/solver.c | 16 +++++- src/sat/satoko/solver.h | 23 ++++++++ src/sat/satoko/solver_api.c | 27 ++++++++- 7 files changed, 181 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index db81bd85..7cbc4184 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -45,39 +45,93 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -satoko_t * Gia_ManCreateSatoko( Gia_Man_t * p ) +void Gia_ManCollectVars_rec( int Var, Vec_Int_t * vMapping, Vec_Int_t * vRes, Vec_Bit_t * vVisit ) +{ + int * pCut, i; + if ( Vec_BitEntry(vVisit, Var) ) + return; + Vec_BitWriteEntry(vVisit, Var, 1); + if ( Vec_IntEntry(vMapping, Var) ) // primary input or constant 0 + { + pCut = Vec_IntEntryP( vMapping, Vec_IntEntry(vMapping, Var) ); + for ( i = 1; i <= pCut[0]; i++ ) + Gia_ManCollectVars_rec( pCut[i], vMapping, vRes, vVisit ); + } + Vec_IntPush( vRes, Var ); +} +Vec_Int_t * Gia_ManCollectVars( int Root, Vec_Int_t * vMapping, int nVars ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Vec_Bit_t * vVisit = Vec_BitStart( nVars ); + assert( Vec_IntEntry(vMapping, Root) ); + Gia_ManCollectVars_rec( Root, vMapping, vRes, vVisit ); + Vec_BitFree( vVisit ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +satoko_t * Gia_ManSatokoInit( Cnf_Dat_t * pCnf, satoko_opts_t * opts ) { satoko_t * pSat = satoko_create(); - Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 1, 0, 0 ); - int i, status; + int i; //sat_solver_setnvars( pSat, p->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) { if ( !satoko_add_clause( pSat, (unsigned *)pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) { - Cnf_DataFree( pCnf ); satoko_destroy( pSat ); return NULL; } } + satoko_configure(pSat, opts); + return pSat; +} +void Gia_ManSatokoReport( int iOutput, int status, abctime clk ) +{ + if ( iOutput >= 0 ) + Abc_Print( 1, "Output %6d : ", iOutput ); + else + Abc_Print( 1, "Total: " ); + + if ( status == SATOKO_UNDEC ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == SATOKO_SAT ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", clk ); +} +satoko_t * Gia_ManSatokoCreate( Gia_Man_t * p, satoko_opts_t * opts ) +{ + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 1, 0, 0 ); + satoko_t * pSat = Gia_ManSatokoInit( pCnf, opts ); + int status = pSat ? satoko_simplify(pSat) : SATOKO_OK; Cnf_DataFree( pCnf ); - status = satoko_simplify(pSat); if ( status == SATOKO_OK ) return pSat; satoko_destroy( pSat ); return NULL; } -int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) +int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) { abctime clk = Abc_Clock(); satoko_t * pSat; int status, Cost = 0; - - pSat = Gia_ManCreateSatoko( p ); + pSat = Gia_ManSatokoCreate( p, opts ); if ( pSat ) { - satoko_configure(pSat, opts); status = satoko_solve( pSat ); Cost = (unsigned)pSat->stats.n_conflicts; satoko_destroy( pSat ); @@ -85,37 +139,60 @@ int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ) else status = SATOKO_UNSAT; - if ( iOutput >= 0 ) - Abc_Print( 1, "Output %6d : ", iOutput ); - else - Abc_Print( 1, "Total: " ); - - if ( status == SATOKO_UNDEC ) - Abc_Print( 1, "UNDECIDED " ); - else if ( status == SATOKO_SAT ) - Abc_Print( 1, "SATISFIABLE " ); - else - Abc_Print( 1, "UNSATISFIABLE " ); - - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Gia_ManSatokoReport( iOutput, status, Abc_Clock() - clk ); return Cost; } -void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ) +void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem ) { + int fUseCone = 1; + Gia_Man_t * pOne; + Gia_Obj_t * pRoot; + Vec_Int_t * vCone; + int i, iLit, status; + if ( fIncrem ) + { + abctime clk = Abc_Clock(); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, fUseCone, 0 ); + satoko_t * pSat = Gia_ManSatokoInit( pCnf, opts ); + Gia_ManForEachCo( p, pRoot, i ) + { + abctime clk = Abc_Clock(); + iLit = Abc_Var2Lit( i+1, 0 ); + satoko_assump_push( pSat, iLit ); + if ( fUseCone ) + { + vCone = Gia_ManCollectVars( i+1, pCnf->vMapping, pCnf->nVars ); + satoko_mark_cone( pSat, Vec_IntArray(vCone), Vec_IntSize(vCone) ); + printf( "Cone has %6d vars (out of %6d). ", Vec_IntSize(vCone), pCnf->nVars ); + status = satoko_solve( pSat ); + satoko_unmark_cone( pSat, Vec_IntArray(vCone), Vec_IntSize(vCone) ); + Vec_IntFree( vCone ); + } + else + { + status = satoko_solve( pSat ); + } + satoko_assump_pop( pSat ); + Gia_ManSatokoReport( i, status, Abc_Clock() - clk ); + } + Cnf_DataFree( pCnf ); + satoko_destroy( pSat ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); + return; + } if ( fSplit ) { - Gia_Man_t * pOne; - Gia_Obj_t * pRoot; - int i; + abctime clk = Abc_Clock(); Gia_ManForEachCo( p, pRoot, i ) { pOne = Gia_ManDupDfsCone( p, pRoot ); - Gia_ManCallSatokoOne( pOne, opts, i ); + Gia_ManSatokoCallOne( pOne, opts, i ); Gia_ManStop( pOne ); } + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); return; } - Gia_ManCallSatokoOne( p, opts, -1 ); + Gia_ManSatokoCallOne( p, opts, -1 ); } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f10be02b..bb0b8c8d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23410,13 +23410,13 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ); - int c, fSplit = 0; + extern void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem ); + int c, fSplit = 0, fIncrem = 0; satoko_opts_t opts; satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Csvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Csivh" ) ) != EOF ) { switch ( c ) { @@ -23434,6 +23434,9 @@ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) case 's': fSplit ^= 1; break; + case 'i': + fIncrem ^= 1; + break; case 'v': opts.verbose ^= 1; break; @@ -23449,13 +23452,14 @@ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" ); return 1; } - Gia_ManCallSatoko( pAbc->pGia, &opts, fSplit ); + Gia_ManSatokoCall( pAbc->pGia, &opts, fSplit, fIncrem ); return 0; usage: - Abc_Print( -2, "usage: &satoko [-C num] [-svh]\n" ); + Abc_Print( -2, "usage: &satoko [-C num] [-sivh]\n" ); Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); Abc_Print( -2, "\t-s : split multi-output miter into individual outputs [default = %s]\n", fSplit? "yes": "no" ); + Abc_Print( -2, "\t-i : split multi-output miter and solve incrementally [default = %s]\n", fIncrem? "yes": "no" ); Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index e279b19d..8151c2e5 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -47,7 +47,7 @@ ABC_NAMESPACE_IMPL_START #define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string #define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call -extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); +extern int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -92,7 +92,7 @@ int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts ) //printf( "Tuning with options: " ); //Cmd_RunAutoTunerPrintOptions( pOpts ); Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) - TotalCost += Gia_ManCallSatokoOne( pGia, pOpts, -1 ); + TotalCost += Gia_ManSatokoCallOne( pGia, pOpts, -1 ); return TotalCost; } @@ -142,7 +142,7 @@ void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) assert( 0 ); return NULL; } - pThData->Result = Gia_ManCallSatokoOne( pThData->pGia, pThData->pOpts, -1 ); + pThData->Result = Gia_ManSatokoCallOne( pThData->pGia, pThData->pOpts, -1 ); pThData->fWorking = 0; } assert( 0 ); diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index e3134b77..8d55a81c 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -89,6 +89,8 @@ extern void satoko_assump_push(satoko_t *s, unsigned); extern void satoko_assump_pop(satoko_t *s); extern int satoko_simplify(satoko_t *); extern int satoko_solve(satoko_t *); +extern void satoko_mark_cone(satoko_t *s, int * pvars, int nvars); +extern void satoko_unmark_cone(satoko_t *s, int * pvars, int nvars); /* If problem is unsatisfiable under assumptions, this function is used to * obtain the final conflict clause expressed in the assumptions. diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index cdd3141e..2abc9833 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -190,14 +190,18 @@ static inline unsigned solver_decide(solver_t *s) if (heap_size(s->var_order) == 0) { next_var = UNDEF; return UNDEF; - } else - next_var = heap_remove_min(s->var_order); + } + next_var = heap_remove_min(s->var_order); + if (solver_has_marks(s) && !var_mark(s, next_var)) + next_var = UNDEF; } return var2lit(next_var, vec_char_at(s->polarity, next_var)); } static inline void solver_new_decision(solver_t *s, unsigned lit) { + if (solver_has_marks(s) && !var_mark(s, lit2var(lit))) + return; assert(var_value(s, lit2var(lit)) == VAR_UNASSING); vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail)); solver_enqueue(s, lit, UNDEF); @@ -538,6 +542,8 @@ unsigned solver_propagate(solver_t *s) n_propagations++; watch_list_foreach(s->bin_watches, i, p) { + if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) + continue; if (var_value(s, lit2var(i->blocker)) == VAR_UNASSING) solver_enqueue(s, i->blocker, i->cref); else if (lit_value(s, i->blocker) == LIT_FALSE) @@ -551,6 +557,12 @@ unsigned solver_propagate(solver_t *s) struct clause *clause; struct watcher w; + if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) + { + *j++ = *i++; + continue; + } + if (lit_value(s, i->blocker) == LIT_TRUE) { *j++ = *i++; continue; diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 849d738a..01912a6e 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -93,6 +93,9 @@ struct solver_t_ { vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and * clauses minimization with binary resolution */ + /* Temporary data used for solving cones */ + vec_char_t *marks; + struct satoko_stats stats; struct satoko_opts opts; }; @@ -133,6 +136,18 @@ static inline unsigned var_reason(solver_t *s, unsigned var) { return vec_uint_at(s->reasons, var); } +static inline int var_mark(solver_t *s, unsigned var) +{ + return (int)vec_char_at(s->marks, var); +} +static inline void var_set_mark(solver_t *s, unsigned var) +{ + vec_char_assign(s->marks, var, 1); +} +static inline void var_clean_mark(solver_t *s, unsigned var) +{ + vec_char_assign(s->marks, var, 0); +} //===------------------------------------------------------------------------=== // Inline lit functions //===------------------------------------------------------------------------=== @@ -185,6 +200,14 @@ static inline int solver_enqueue(solver_t *s, unsigned lit, unsigned reason) vec_uint_push_back(s->trail, lit); return SATOKO_OK; } +static inline int solver_varnum(solver_t *s) +{ + return vec_char_size(s->assigns); +} +static inline int solver_has_marks(solver_t *s) +{ + return (int)(s->marks != NULL); +} //===------------------------------------------------------------------------=== // Inline clause functions diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index f3f3d781..b446fb05 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -145,11 +145,13 @@ void satoko_destroy(solver_t *s) vec_uint_free(s->stack); vec_uint_free(s->last_dlevel); vec_uint_free(s->stamps); + if (s->marks) vec_char_free(s->marks); satoko_free(s); } void satoko_default_opts(satoko_opts_t *opts) { + memset(opts, 0, sizeof(satoko_opts_t)); opts->verbose = 0; /* Limits */ opts->conf_limit = 0; @@ -232,6 +234,7 @@ void satoko_add_variable(solver_t *s, char sign) vec_uint_push_back(s->stamps, 0); vec_char_push_back(s->seen, 0); heap_insert(s->var_order, var); + if (s->marks) vec_char_push_back(s->marks, 0); } int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) @@ -287,8 +290,8 @@ int satoko_solve(solver_t *s) char status = SATOKO_UNDEC; assert(s); - if (s->opts.verbose) - print_opts(s); + //if (s->opts.verbose) + // print_opts(s); while (status == SATOKO_UNDEC) { status = solver_search(s); @@ -317,4 +320,24 @@ satoko_stats_t satoko_stats(satoko_t *s) return s->stats; } +void satoko_mark_cone(satoko_t *s, int * pvars, int nvars) +{ + int i; + if (!solver_has_marks(s)) + s->marks = vec_char_init(solver_varnum(s), 0); + for (i = 0; i < nvars; i++) + { + var_set_mark(s, pvars[i]); + if (!heap_in_heap(s->var_order, pvars[i])) + heap_insert(s->var_order, pvars[i]); + } +} +void satoko_unmark_cone(satoko_t *s, int * pvars, int nvars) +{ + int i; + assert(solver_has_marks(s)); + for (i = 0; i < nvars; i++) + var_clean_mark(s, pvars[i]); +} + ABC_NAMESPACE_IMPL_END -- cgit v1.2.3 From ae521b66019623fd6ed51d89bef8244650227876 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 21:00:37 -0800 Subject: Adding PDR with abstraction. --- src/proof/pdr/pdrCore.c | 11 +++++++---- src/proof/pdr/pdrInv.c | 4 ++-- src/proof/pdr/pdrTsim.c | 37 ++----------------------------------- 3 files changed, 11 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 5aa689f5..f77bc05f 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -706,7 +706,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ) { Counter++; pThis = Pdr_QueueHead( p ); - if ( pThis->iFrame == 0 ) + if ( pThis->iFrame == 0 || (p->pPars->fUseAbs && Pdr_SetIsInit(pThis->pState, -1)) ) return 0; // SAT if ( pThis->iFrame > kMax ) // finished this level return 1; @@ -862,7 +862,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) while ( 1 ) { int fRefined = 0; - if ( p->pPars->fUseAbs && iFrame == 3 ) + if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 2 ) { int i, Prio; assert( p->vAbsFlops == NULL ); @@ -995,7 +995,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); Pdr_ManPrintClauses( p, 0 ); } - if ( p->pPars->fVerbose ) + if ( p->pPars->fVerbose && !p->pPars->fUseAbs ) Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart ); p->pPars->iFrame = iFrame; if ( !p->pPars->fSolveAll ) @@ -1043,6 +1043,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart ); } } + if ( fRefined ) + break; if ( p->pTime4Outs ) { abctime timeSince = Abc_Clock() - clkOne; @@ -1059,9 +1061,10 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) p->timeToStopOne = 0; } } - if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart ); + if ( fRefined ) + continue; // open a new timeframe p->nQueLim = p->pPars->nRestLimit; assert( pCube == NULL ); diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index e3233a3a..554add9b 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -470,8 +470,8 @@ void Pdr_ManReportInvariant( Pdr_Man_t * p ) Vec_Ptr_t * vCubes; int kStart = Pdr_ManFindInvariantStart( p ); vCubes = Pdr_ManCollectCubes( p, kStart ); - Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (%.2f)\n", - kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), 1.0*p->nXsimLits/p->nXsimRuns ); + Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (cex = %d, ave = %.2f)\n", + kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), p->nCexesTotal, 1.0*p->nXsimLits/p->nXsimRuns ); // Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n", // kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) ); Vec_PtrFree( vCubes ); diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c index 283a0e1d..acbf70f5 100644 --- a/src/proof/pdr/pdrTsim.c +++ b/src/proof/pdr/pdrTsim.c @@ -473,54 +473,21 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem ); Pdr_ManDeriveResult( p->pAig, vCiObjs, vCiVals, vCi2Rem, vRes, vPiLits ); assert( Vec_IntSize(vRes) > 0 ); //p->tTsim += Abc_Clock() - clk; + // move abstracted literals from flops to inputs if ( p->pPars->fUseAbs && p->vAbsFlops ) { - int i, iLit, Used, k = 0, fAllNegs = 1; + int i, iLit, k = 0; Vec_IntForEachEntry( vRes, iLit, i ) { if ( Vec_IntEntry(p->vAbsFlops, Abc_Lit2Var(iLit)) ) // used flop - { Vec_IntWriteEntry( vRes, k++, iLit ); - fAllNegs &= Abc_LitIsCompl(iLit); - } else Vec_IntPush( vPiLits, 2*Saig_ManPiNum(p->pAig) + iLit ); } Vec_IntShrink( vRes, k ); - if ( fAllNegs ) // insert any positive literal - { - Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i ) - { - if ( !Saig_ObjIsLo( p->pAig, pObj ) ) - continue; - if ( Vec_IntEntry(vCiVals, i) ) - { - Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig); - Vec_IntPush( vRes, Abc_Var2Lit(Entry, 0) ); - break; - } - } - // add any flop that is not in the cone - if ( i == Vec_IntSize(vCiObjs) ) - { - Vec_IntForEachEntry( p->vAbsFlops, Used, i ) - { - if ( !Used ) - continue; - if ( Vec_IntFind( vRes, Abc_Var2Lit(i, 1) ) >= 0 ) - continue; - Vec_IntPush( vRes, Abc_Var2Lit(i, 0) ); - //Vec_IntPrint( vRes ); - break; - } - assert( i < Vec_IntSize(p->vAbsFlops) ); - } - } } pRes = Pdr_SetCreate( vRes, vPiLits ); - assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); - //ZH: Disabled assertion because this invariant doesn't hold with down //because of the join operation which can bring in initial states //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) ); -- cgit v1.2.3 From 4abb1ce8a45d115567a125c6b2b00d48f6776aff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 21:11:45 -0800 Subject: Commenting out uncommented message. --- src/sat/bsat/satSolver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index efe8efa6..37e0ea94 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -1456,7 +1456,7 @@ void sat_solver_reducedb(sat_solver* s) s->nDBreduces++; - printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax ); + //printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax ); s->nLearntMax = s->nLearntStart + s->nLearntDelta * s->nDBreduces; // return; -- cgit v1.2.3 From 3fb058a35562ceeafb2967f0991215ad47a23b0f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 22:48:20 -0800 Subject: Adding PDR with abstraction. --- src/proof/pdr/pdrCore.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index f77bc05f..568f7642 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -874,7 +874,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); } //if ( p->pPars->fUseAbs && p->vAbsFlops ) - // printf( "Starting frame %d with %d flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops) ); + // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); p->nFrames = iFrame; assert( iFrame == Vec_PtrSize(p->vSolvers)-1 ); p->iUseFrame = Abc_MaxInt(iFrame, 1); @@ -1061,10 +1061,19 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) p->timeToStopOne = 0; } } + if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined ) + { + int i, Used; + Vec_IntForEachEntry( p->vAbsFlops, Used, i ) + if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 ) + Vec_IntWriteEntry( p->vAbsFlops, i, 0 ); + } if ( p->pPars->fVerbose ) Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart ); if ( fRefined ) continue; + //if ( p->pPars->fUseAbs && p->vAbsFlops ) + // printf( "Finished frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); // open a new timeframe p->nQueLim = p->pPars->nRestLimit; assert( pCube == NULL ); -- cgit v1.2.3 From f4853496d7bc96ef134fb300f70f480307fa133b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 13 Feb 2017 01:02:03 -0800 Subject: Adding PDR with abstraction. --- src/proof/pdr/pdrCore.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 568f7642..45dbfc9f 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -862,16 +862,16 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) while ( 1 ) { int fRefined = 0; - if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 2 ) + if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 1 ) { - int i, Prio; +// int i, Prio; assert( p->vAbsFlops == NULL ); p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) ); p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) ); p->vMapPpi2Ff = Vec_IntAlloc( 100 ); - Vec_IntForEachEntry( p->vPrio, Prio, i ) - if ( Prio >> p->nPrioShift ) - Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); +// Vec_IntForEachEntry( p->vPrio, Prio, i ) +// if ( Prio >> p->nPrioShift ) +// Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); } //if ( p->pPars->fUseAbs && p->vAbsFlops ) // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); -- cgit v1.2.3 From 30037e06533b1c7291e32025ebb7c9a2e875e079 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Tue, 14 Feb 2017 14:43:44 -0800 Subject: - Small bug fix in var activity (improve performance) - New implementation of watcher lists. --- src/sat/satoko/solver.c | 14 +++++------- src/sat/satoko/solver.h | 20 +++++------------ src/sat/satoko/solver_api.c | 23 ++++++++----------- src/sat/satoko/watch_list.h | 54 ++++++++++++++++++++++++++++++--------------- 4 files changed, 55 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 2abc9833..d2bf1b5e 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -114,7 +114,7 @@ static inline void clause_bin_resolution(solver_t *s, vec_uint_t *clause_lits) vec_uint_assign(s->stamps, lit2var(lit), s->cur_stamp); counter = 0; - watch_list_foreach(s->bin_watches, w, neg_lit) { + watch_list_foreach_bin(s->watches, w, neg_lit) { unsigned imp_lit = w->blocker; if (vec_uint_at(s->stamps, lit2var(imp_lit)) == s->cur_stamp && lit_value(s, imp_lit) == LIT_TRUE) { @@ -400,8 +400,6 @@ static inline void solver_garbage_collect(solver_t *s) struct watcher *w; watch_list_foreach(s->watches, w, i) clause_realloc(new_cdb, s->all_clauses, &(w->cref)); - watch_list_foreach(s->bin_watches, w, i) - clause_realloc(new_cdb, s->all_clauses, &(w->cref)); } for (i = 0; i < vec_uint_size(s->trail); i++) @@ -541,7 +539,7 @@ unsigned solver_propagate(solver_t *s) struct watcher *i, *j; n_propagations++; - watch_list_foreach(s->bin_watches, i, p) { + watch_list_foreach_bin(s->watches, i, p) { if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) continue; if (var_value(s, lit2var(i->blocker)) == VAR_UNASSING) @@ -553,16 +551,14 @@ unsigned solver_propagate(solver_t *s) ws = vec_wl_at(s->watches, p); begin = watch_list_array(ws); end = begin + watch_list_size(ws); - for (i = j = begin; i < end;) { + for (i = j = begin + ws->n_bin; i < end;) { struct clause *clause; struct watcher w; - if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) - { + if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) { *j++ = *i++; continue; } - if (lit_value(s, i->blocker) == LIT_TRUE) { *j++ = *i++; continue; @@ -590,7 +586,7 @@ unsigned solver_propagate(solver_t *s) if (lit_value(s, lits[k]) != LIT_FALSE) { lits[1] = lits[k]; lits[k] = neg_lit; - watch_list_push(vec_wl_at(s->watches, lit_neg(lits[1])), w); + watch_list_push(vec_wl_at(s->watches, lit_neg(lits[1])), w, 0); goto next; } } diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 01912a6e..84c25689 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -49,7 +49,6 @@ struct solver_t_ { vec_uint_t *learnts; vec_uint_t *originals; vec_wl_t *watches; - vec_wl_t *bin_watches; /* Activity heuristic */ act_t var_act_inc; /* Amount to bump next variable with. */ @@ -200,6 +199,7 @@ static inline int solver_enqueue(solver_t *s, unsigned lit, unsigned reason) vec_uint_push_back(s->trail, lit); return SATOKO_OK; } + static inline int solver_varnum(solver_t *s) { return vec_char_size(s->assigns); @@ -227,25 +227,15 @@ static inline void clause_watch(solver_t *s, unsigned cref) w2.cref = cref; w1.blocker = clause->data[1].lit; w2.blocker = clause->data[0].lit; - if (clause->size == 2) { - watch_list_push(vec_wl_at(s->bin_watches, lit_neg(clause->data[0].lit)), w1); - watch_list_push(vec_wl_at(s->bin_watches, lit_neg(clause->data[1].lit)), w2); - } else { - watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), w1); - watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), w2); - } + watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), w1, (clause->size == 2)); + watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), w2, (clause->size == 2)); } static inline void clause_unwatch(solver_t *s, unsigned cref) { struct clause *clause = cdb_handler(s->all_clauses, cref); - if (clause->size == 2) { - watch_list_remove(vec_wl_at(s->bin_watches, lit_neg(clause->data[0].lit)), cref); - watch_list_remove(vec_wl_at(s->bin_watches, lit_neg(clause->data[1].lit)), cref); - } else { - watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), cref); - watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), cref); - } + watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), cref, (clause->size == 2)); + watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), cref, (clause->size == 2)); } ABC_NAMESPACE_HEADER_END diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index b446fb05..65fab837 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -89,7 +89,6 @@ solver_t * satoko_create() s->originals = vec_uint_alloc(0); s->learnts = vec_uint_alloc(0); s->watches = vec_wl_alloc(0); - s->bin_watches = vec_wl_alloc(0); /* Activity heuristic */ s->var_act_inc = VAR_ACT_INIT_INC; s->clause_act_inc = CLAUSE_ACT_INIT_INC; @@ -128,7 +127,6 @@ void satoko_destroy(solver_t *s) vec_uint_free(s->originals); vec_uint_free(s->learnts); vec_wl_free(s->watches); - vec_wl_free(s->bin_watches); vec_act_free(s->activity); heap_free(s->var_order); vec_uint_free(s->levels); @@ -145,7 +143,8 @@ void satoko_destroy(solver_t *s) vec_uint_free(s->stack); vec_uint_free(s->last_dlevel); vec_uint_free(s->stamps); - if (s->marks) vec_char_free(s->marks); + if (s->marks) + vec_char_free(s->marks); satoko_free(s); } @@ -220,13 +219,9 @@ int satoko_simplify(solver_t * s) void satoko_add_variable(solver_t *s, char sign) { unsigned var = vec_act_size(s->activity); - vec_wl_push(s->bin_watches); - vec_wl_push(s->bin_watches); vec_wl_push(s->watches); vec_wl_push(s->watches); - /* Variable activity are initialized with the lowest possible value - * which in satoko double implementation (SDBL) is the constant 1 */ - vec_act_push_back(s->activity, SDBL_CONST1); + vec_act_push_back(s->activity, 0); vec_uint_push_back(s->levels, 0); vec_char_push_back(s->assigns, VAR_UNASSING); vec_char_push_back(s->polarity, sign); @@ -320,23 +315,23 @@ satoko_stats_t satoko_stats(satoko_t *s) return s->stats; } -void satoko_mark_cone(satoko_t *s, int * pvars, int nvars) +void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars) { int i; if (!solver_has_marks(s)) - s->marks = vec_char_init(solver_varnum(s), 0); - for (i = 0; i < nvars; i++) - { + s->marks = vec_char_init(solver_varnum(s), 0); + for (i = 0; i < n_vars; i++) { var_set_mark(s, pvars[i]); if (!heap_in_heap(s->var_order, pvars[i])) heap_insert(s->var_order, pvars[i]); } } -void satoko_unmark_cone(satoko_t *s, int * pvars, int nvars) + +void satoko_unmark_cone(satoko_t *s, int *pvars, int n_vars) { int i; assert(solver_has_marks(s)); - for (i = 0; i < nvars; i++) + for (i = 0; i < n_vars; i++) var_clean_mark(s, pvars[i]); } diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index ef1c1a07..96399a83 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -10,6 +10,7 @@ #define satoko__watch_list_h #include "utils/mem.h" +#include "utils/misc.h" #include "misc/util/abc_global.h" ABC_NAMESPACE_HEADER_START @@ -22,6 +23,7 @@ struct watcher { struct watch_list { unsigned cap; unsigned size; + unsigned n_bin; struct watcher *watchers; }; @@ -40,6 +42,10 @@ struct vec_wl_t_ { watch < watch_list_array(vec_wl_at(vec, lit)) + watch_list_size(vec_wl_at(vec, lit)); \ watch++) +#define watch_list_foreach_bin(vec, watch, lit) \ + for (watch = watch_list_array(vec_wl_at(vec, lit)); \ + watch < watch_list_array(vec_wl_at(vec, lit)) + vec_wl_at(vec, lit)->n_bin; \ + watch++) //===------------------------------------------------------------------------=== // Watch list API //===------------------------------------------------------------------------=== @@ -60,25 +66,33 @@ static inline void watch_list_shrink(struct watch_list *wl, unsigned size) wl->size = size; } -static inline void watch_list_push(struct watch_list *wl, struct watcher w) +static inline void watch_list_grow(struct watch_list *wl) { - assert(wl); - if (wl->size == wl->cap) { - unsigned new_size = (wl->cap < 4) ? 4 : (wl->cap / 2) * 3; - struct watcher *watchers = - satoko_realloc(struct watcher, wl->watchers, new_size); - if (watchers == NULL) { - printf("Failed to realloc memory from %.1f MB to %.1f " - "MB.\n", - 1.0 * wl->cap / (1 << 20), - 1.0 * new_size / (1 << 20)); - fflush(stdout); - return; - } - wl->watchers = watchers; - wl->cap = new_size; + unsigned new_size = (wl->cap < 4) ? 4 : (wl->cap / 2) * 3; + struct watcher *watchers = + satoko_realloc(struct watcher, wl->watchers, new_size); + if (watchers == NULL) { + printf("Failed to realloc memory from %.1f MB to %.1f " + "MB.\n", + 1.0 * wl->cap / (1 << 20), + 1.0 * new_size / (1 << 20)); + fflush(stdout); + return; } + wl->watchers = watchers; + wl->cap = new_size; +} + +static inline void watch_list_push(struct watch_list *wl, struct watcher w, unsigned is_bin) +{ + assert(wl); + if (wl->size == wl->cap) + watch_list_grow(wl); wl->watchers[wl->size++] = w; + if (is_bin && wl->size > wl->n_bin) { + stk_swap(struct watcher, wl->watchers[wl->n_bin], wl->watchers[wl->size - 1]); + wl->n_bin++; + } } static inline struct watcher *watch_list_array(struct watch_list *wl) @@ -86,11 +100,15 @@ static inline struct watcher *watch_list_array(struct watch_list *wl) return wl->watchers; } -static inline void watch_list_remove(struct watch_list *wl, unsigned cref) +static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin) { struct watcher *watchers = watch_list_array(wl); unsigned i; - for (i = 0; watchers[i].cref != cref; i++); + if (is_bin) { + for (i = 0; watchers[i].cref != cref; i++); + wl->n_bin--; + } else + for (i = wl->n_bin; watchers[i].cref != cref; i++); assert(i < watch_list_size(wl)); memmove((wl->watchers + i), (wl->watchers + i + 1), (wl->size - i - 1) * sizeof(struct watcher)); -- cgit v1.2.3 From cb1ab7030fcd6964d4feb7441bf594829583d5ba Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 14 Feb 2017 20:26:43 -0800 Subject: Experiments with simulation. --- src/proof/cec/cecSimBack.c | 194 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/proof/cec/cecSimBack.c (limited to 'src') diff --git a/src/proof/cec/cecSimBack.c b/src/proof/cec/cecSimBack.c new file mode 100644 index 00000000..c3d09ff5 --- /dev/null +++ b/src/proof/cec/cecSimBack.c @@ -0,0 +1,194 @@ +/**CFile**************************************************************** + + FileName [cecSimBack.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Backward simulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSimBack.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" +#include "aig/gia/giaAig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ObjSatVerify( Gia_Man_t * p, Gia_Obj_t * pRoot, int Value ) +{ + Gia_Obj_t * pObj; + int i, RetValue = 1; + printf( "Obj = %4d Value = %d ", Gia_ObjId(p, pRoot), Value ); + Gia_ObjTerSimSet0( Gia_ManConst0(p) ); + Gia_ManForEachCi( p, pObj, i ) + if ( !Gia_ObjIsTravIdCurrent(p, pObj) ) + Gia_ObjTerSimSetX( pObj ), printf( "x" ); + else if ( pObj->fMark0 ) + Gia_ObjTerSimSet1( pObj ), printf( "1" ); + else + Gia_ObjTerSimSet0( pObj ), printf( "0" ); + printf( " " ); + Gia_ManForEachAnd( p, pObj, i ) + Gia_ObjTerSimAnd( pObj ); + if ( Value ? Gia_ObjTerSimGet1(pRoot) : Gia_ObjTerSimGet0(pRoot) ) + printf( "Verification successful.\n" ); + else + printf( "Verification failed.\n" ), RetValue = 0; + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Return 1 if pObj can have Value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Cec_ManCheckSat2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, word Value, Vec_Wrd_t * vValues ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return Value == (int)pObj->fMark0; + Gia_ObjSetTravIdCurrent(p, pObj); + pObj->fMark0 = Value; + if ( !Gia_ObjIsAnd(pObj) ) + return 1; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( Value ) + { + return Cec_ManCheckSat2_rec( p, pFan0, !Gia_ObjFaninC0(pObj), vValues ) && + Cec_ManCheckSat2_rec( p, pFan1, !Gia_ObjFaninC1(pObj), vValues ); + } + if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) // already assigned + { + if ( Gia_ObjFaninC0(pObj) == (int)pFan0->fMark0 ) // justified + return 1; + return Cec_ManCheckSat2_rec( p, pFan1, Gia_ObjFaninC1(pObj), vValues ); + } + if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) // already assigned + { + if ( Gia_ObjFaninC1(pObj) == (int)pFan1->fMark0 ) // justified + return 1; + return Cec_ManCheckSat2_rec( p, pFan0, Gia_ObjFaninC0(pObj), vValues ); + } + return Cec_ManCheckSat2_rec( p, pFan0, Gia_ObjFaninC0(pObj), vValues ); +} +word Cec_ManCheckSat2( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Wrd_t * vValues ) +{ + return 0; +} + +/**Function************************************************************* + + Synopsis [Return 1 if pObj can have Value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec_ManCheckSat_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value ) +{ + Gia_Obj_t * pFan0, * pFan1; + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return Value == (int)pObj->fMark0; + Gia_ObjSetTravIdCurrent(p, pObj); + pObj->fMark0 = Value; + if ( !Gia_ObjIsAnd(pObj) ) + return 1; + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( Value ) + { + return Cec_ManCheckSat_rec( p, pFan0, !Gia_ObjFaninC0(pObj) ) && + Cec_ManCheckSat_rec( p, pFan1, !Gia_ObjFaninC1(pObj) ); + } + if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) // already assigned + { + if ( Gia_ObjFaninC0(pObj) == (int)pFan0->fMark0 ) // justified + return 1; + return Cec_ManCheckSat_rec( p, pFan1, Gia_ObjFaninC1(pObj) ); + } + if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) // already assigned + { + if ( Gia_ObjFaninC1(pObj) == (int)pFan1->fMark0 ) // justified + return 1; + return Cec_ManCheckSat_rec( p, pFan0, Gia_ObjFaninC0(pObj) ); + } + return Cec_ManCheckSat_rec( p, pFan0, Gia_ObjFaninC0(pObj) ); +} +void Cec_ManSimBack( Gia_Man_t * p ) +{ + abctime clk = Abc_Clock(); + Vec_Wrd_t * vValues = Vec_WrdStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj; + int i, Count = 0; + word Res; + Gia_ManSetPhase( p ); + //Gia_ManForEachAnd( p, pObj, i ) + // printf( "%d", pObj->fPhase ); + //printf( "\n" ); + //return; + + Gia_ManForEachAnd( p, pObj, i ) + { + Gia_ManIncrementTravId(p); + //Gia_ManCleanMark0( p ); + Res = Cec_ManCheckSat_rec( p, pObj, !pObj->fPhase ); + //if ( Res ) + // Cec_ObjSatVerify( p, pObj, !pObj->fPhase ); + + //Res = Cec_ManCheckSat2_rec( p, pObj, !pObj->fPhase ? ~(word)0 : 0, vValues ); + //if ( Res ) + // Cec_ObjSatVerify2( p, pObj, !pObj->fPhase, Res ); + + Count += (int)(Res > 0); + } + Vec_WrdFree( vValues ); + printf( "Obj = %6d. SAT = %6d. ", Gia_ManAndNum(p), Count ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3 From 088aabc1023e6745bedeb16f9f8f01515c38e4b7 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Wed, 15 Feb 2017 17:02:32 -0800 Subject: - Small changes to the watch lists behavior. - Implementation of bookmark, unbookmark and rollback procedures. - Minor changes. --- src/sat/satoko/satoko.h | 7 +++-- src/sat/satoko/solver.c | 5 ++-- src/sat/satoko/solver.h | 6 ++++ src/sat/satoko/solver_api.c | 56 ++++++++++++++++++++++++++++++++++++- src/sat/satoko/types.h | 1 + src/sat/satoko/utils/vec/vec_sdbl.h | 6 ++++ src/sat/satoko/watch_list.h | 22 +++++++++++++++ 7 files changed, 98 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 8d55a81c..88070eac 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -89,9 +89,12 @@ extern void satoko_assump_push(satoko_t *s, unsigned); extern void satoko_assump_pop(satoko_t *s); extern int satoko_simplify(satoko_t *); extern int satoko_solve(satoko_t *); -extern void satoko_mark_cone(satoko_t *s, int * pvars, int nvars); -extern void satoko_unmark_cone(satoko_t *s, int * pvars, int nvars); +extern void satoko_mark_cone(satoko_t *, int *, int); +extern void satoko_unmark_cone(satoko_t *, int *, int); +extern void satoko_rollback(satoko_t *); +extern void satoko_bookmark(satoko_t *); +extern void satoko_unbookmark(satoko_t *); /* If problem is unsatisfiable under assumptions, this function is used to * obtain the final conflict clause expressed in the assumptions. * diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index d2bf1b5e..21a4860d 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -402,6 +402,7 @@ static inline void solver_garbage_collect(solver_t *s) clause_realloc(new_cdb, s->all_clauses, &(w->cref)); } + /* Update CREFS */ for (i = 0; i < vec_uint_size(s->trail); i++) if (lit_reason(s, vec_uint_at(s->trail, i)) != UNDEF) clause_realloc(new_cdb, s->all_clauses, &(vec_uint_data(s->reasons)[lit2var(vec_uint_at(s->trail, i))])); @@ -427,7 +428,7 @@ static inline void solver_reduce_cdb(solver_t *s) struct clause **learnts_cls; learnts_cls = satoko_alloc(struct clause *, n_learnts); - vec_uint_foreach(s->learnts, cref, i) + vec_uint_foreach_start(s->learnts, cref, i, s->book_cl_lrnt) learnts_cls[i] = clause_read(s, cref); limit = (unsigned)(n_learnts * s->opts.learnt_ratio); @@ -504,7 +505,7 @@ unsigned solver_clause_create(solver_t *s, vec_uint_t *lits, unsigned f_learnt) return cref; } -void solver_cancel_until(solver_t * s, unsigned level) +void solver_cancel_until(solver_t *s, unsigned level) { int i; diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 84c25689..68cc97dc 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -92,6 +92,12 @@ struct solver_t_ { vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and * clauses minimization with binary resolution */ + /* Bookmark */ + unsigned book_cl_orig; /* Bookmark for orignal problem clauses vector */ + unsigned book_cl_lrnt; /* Bookmark for learnt clauses vector */ + unsigned book_vars; /* Bookmark number of variables */ + unsigned book_trail; /* Bookmark trail size */ + /* Temporary data used for solving cones */ vec_char_t *marks; diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 65fab837..9cad0a14 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -229,7 +229,8 @@ void satoko_add_variable(solver_t *s, char sign) vec_uint_push_back(s->stamps, 0); vec_char_push_back(s->seen, 0); heap_insert(s->var_order, var); - if (s->marks) vec_char_push_back(s->marks, 0); + if (s->marks) + vec_char_push_back(s->marks, 0); } int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) @@ -315,6 +316,59 @@ satoko_stats_t satoko_stats(satoko_t *s) return s->stats; } +void satoko_bookmark(satoko_t *s) +{ + assert(solver_dlevel(s) == 0); + s->book_cl_orig = vec_uint_size(s->originals); + s->book_cl_lrnt = vec_uint_size(s->learnts); + s->book_vars = vec_char_size(s->assigns); + s->book_trail = vec_uint_size(s->trail); +} + +void satoko_unbookmark(satoko_t *s) +{ + s->book_cl_orig = 0; + s->book_cl_lrnt = 0; + s->book_vars = 0; + s->book_trail = 0; +} + +void satoko_rollback(satoko_t *s) +{ + unsigned i, cref; + unsigned n_originals = vec_uint_size(s->originals) - s->book_cl_orig; + unsigned n_learnts = vec_uint_size(s->learnts) - s->book_cl_lrnt; + struct clause **cl_to_remove; + + assert(solver_dlevel(s) == 0); + cl_to_remove = satoko_alloc(struct clause *, n_originals + n_learnts); + /* Mark clauses */ + vec_uint_foreach_start(s->originals, cref, i, s->book_cl_orig) + cl_to_remove[i] = clause_read(s, cref); + vec_uint_foreach_start(s->learnts, cref, i, s->book_cl_lrnt) + cl_to_remove[n_originals + i] = clause_read(s, cref); + for (i = 0; i < n_originals + n_learnts; i++) { + clause_unwatch(s, cdb_cref(s->all_clauses, (unsigned *)cl_to_remove[i])); + cl_to_remove[i]->f_mark = 1; + } + vec_uint_shrink(s->originals, s->book_cl_orig); + vec_uint_shrink(s->learnts, s->book_cl_lrnt); + /* Shrink variable related vectors */ + vec_act_shrink(s->activity, s->book_vars); + vec_uint_shrink(s->levels, s->book_vars); + vec_uint_shrink(s->reasons, s->book_vars); + vec_char_shrink(s->assigns, s->book_vars); + vec_char_shrink(s->polarity, s->book_vars); + solver_rebuild_order(s); + /* Rewind solver and cancel level 0 assignments to the trail */ + solver_cancel_until(s, 0); + vec_uint_shrink(s->trail, s->book_trail); + s->book_cl_orig = 0; + s->book_cl_lrnt = 0; + s->book_vars = 0; + s->book_trail = 0; +} + void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars) { int i; diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index d51aed4c..9c47ca7c 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -26,6 +26,7 @@ typedef vec_sdbl_t vec_act_t ; #define vec_act_free(vec) vec_sdbl_free(vec) #define vec_act_size(vec) vec_sdbl_size(vec) #define vec_act_data(vec) vec_sdbl_data(vec) +#define vec_act_shrink(vec, size) vec_sdbl_shrink(vec, size) #define vec_act_at(vec, idx) vec_sdbl_at(vec, idx) #define vec_act_push_back(vec, value) vec_sdbl_push_back(vec, value) diff --git a/src/sat/satoko/utils/vec/vec_sdbl.h b/src/sat/satoko/utils/vec/vec_sdbl.h index aefd687a..ec1c731c 100755 --- a/src/sat/satoko/utils/vec/vec_sdbl.h +++ b/src/sat/satoko/utils/vec/vec_sdbl.h @@ -86,6 +86,12 @@ static inline unsigned vec_sdbl_size(vec_sdbl_t *p) return p->size; } +static inline void vec_sdbl_shrink(vec_sdbl_t *p, unsigned new_size) +{ + assert(new_size <= p->cap); + p->size = new_size; +} + static inline void vec_sdbl_resize(vec_sdbl_t *p, unsigned new_size) { p->size = new_size; diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index 96399a83..49f419f2 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -100,6 +100,27 @@ static inline struct watcher *watch_list_array(struct watch_list *wl) return wl->watchers; } +/* TODO: I still have mixed feelings if this change should be done, keeping the + * old code commented after it. */ +static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin) +{ + struct watcher *watchers = watch_list_array(wl); + unsigned i; + if (is_bin) { + for (i = 0; watchers[i].cref != cref; i++); + assert(i < watch_list_size(wl)); + wl->n_bin--; + memmove((wl->watchers + i), (wl->watchers + i + 1), + (wl->size - i - 1) * sizeof(struct watcher)); + } else { + for (i = wl->n_bin; watchers[i].cref != cref; i++); + assert(i < watch_list_size(wl)); + stk_swap(struct watcher, wl->watchers[i], wl->watchers[wl->size - 1]); + } + wl->size -= 1; +} + +/* static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin) { struct watcher *watchers = watch_list_array(wl); @@ -114,6 +135,7 @@ static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsig (wl->size - i - 1) * sizeof(struct watcher)); wl->size -= 1; } +*/ static inline vec_wl_t *vec_wl_alloc(unsigned cap) { -- cgit v1.2.3 From ab387953ab3a50200384f5619cf999e3f729f28f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 15 Feb 2017 17:16:19 -0800 Subject: Word-level abstraction engine. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaDup.c | 37 ++++ src/base/abci/abc.c | 10 +- src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 25 ++- src/base/wlc/wlcAbs.c | 484 +++++++++++++++++++++++++++++------------------ src/base/wlc/wlcAbs2.c | 298 +++++++++++++++++++++++++---- src/base/wlc/wlcBlast.c | 2 +- src/base/wlc/wlcCom.c | 143 +++++++++++++- src/base/wlc/wlcNtk.c | 91 ++++++++- src/base/wlc/wlcUif.c | 290 ++++++++++++++++++++++++++++ src/proof/pdr/pdrInv.c | 13 +- src/proof/pdr/pdrMan.c | 2 +- 13 files changed, 1151 insertions(+), 246 deletions(-) create mode 100644 src/base/wlc/wlcUif.c (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 6677e0ad..c183432a 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1229,6 +1229,7 @@ extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int f extern Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 ); extern Gia_Man_t * Gia_ManDupWithNewPo( Gia_Man_t * p1, Gia_Man_t * p2 ); extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits ); +extern Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int nExtra ); extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ); extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int nInsDup, int fDualOut, int fSeq, int fImplic, int fVerbose ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 56d1d29d..ee709df4 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -2169,6 +2169,43 @@ Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits return pNew; } +/**Function************************************************************* + + Synopsis [Permute inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int nExtra ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < Gia_ManPiNum(p) - nPpis - nExtra; i++ ) // regular PIs + Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew ); + for ( i = Gia_ManPiNum(p) - nExtra; i < Gia_ManPiNum(p); i++ ) // extra PIs due to DC values + Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew ); + for ( i = Gia_ManPiNum(p) - nPpis - nExtra; i < Gia_ManPiNum(p) - nExtra; i++ ) // pseudo-PIs + Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew ); + for ( i = Gia_ManPiNum(p); i < Gia_ManCiNum(p); i++ ) // flop outputs + Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew ); + assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} + /**Function************************************************************* Synopsis [Duplicates AIG in the DFS order.] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index bb0b8c8d..af5d0ccf 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26219,10 +26219,10 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nConfGenLimit < 0 ) goto usage; break; - case 'R': + case 'Q': if ( globalUtilOptind >= argc ) { - Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); + Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); goto usage; } pPars->nRestLimit = atoi(argv[globalUtilOptind]); @@ -26366,7 +26366,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26374,7 +26374,7 @@ usage: Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); - Abc_Print( -2, "\t-R num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); + Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index 3485bd4d..c4330264 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -10,5 +10,6 @@ SRC += src/base/wlc/wlcAbs.c \ src/base/wlc/wlcSim.c \ src/base/wlc/wlcShow.c \ src/base/wlc/wlcStdin.c \ + src/base/wlc/wlcUif.c \ src/base/wlc/wlcWin.c \ src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 21ba73a3..91dc0573 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -158,6 +158,7 @@ struct Wlc_Ntk_t_ Vec_Int_t vCopies; // object first bits Vec_Int_t vBits; // object mapping into AIG nodes Vec_Int_t vLevels; // object levels + Vec_Int_t vRefs; // object reference counters }; typedef struct Wlc_Par_t_ Wlc_Par_t; @@ -167,7 +168,10 @@ struct Wlc_Par_t_ int nBitsMul; // multiplier bit-widht int nBitsMux; // MUX bit-width int nBitsFlop; // flop bit-width - int fVerbose; // verbose output` + int nIterMax; // the max number of iterations + int fXorOutput; // XOR outputs of word-level miter + int fVerbose; // verbose output + int fPdrVerbose; // verbose output }; static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } @@ -272,19 +276,15 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) //////////////////////////////////////////////////////////////////////// /*=== wlcAbs.c ========================================================*/ -extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ); -extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); -extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); -extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); -extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); +extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ -extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); -extern Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth ); /*=== wlcCom.c ========================================================*/ extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ +extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); @@ -311,6 +311,9 @@ extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); +extern int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p ); +extern void Wlc_NtkSetRefs( Wlc_Ntk_t * p ); +extern int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree ); @@ -321,6 +324,12 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p ); extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd ); /*=== wlcReadVer.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ); +/*=== wlcUif.c ========================================================*/ +extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ); +extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); +extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); +extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); +extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); /*=== wlcWin.c =============================================================*/ extern void Wlc_WinProfileArith( Wlc_Ntk_t * p ); /*=== wlcWriteVer.c ========================================================*/ diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index ce6b8de9..318df4dd 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [wlcAbs.c] + FileName [wlcAbs1.c] SystemName [ABC: Logic synthesis and verification system.] @@ -14,11 +14,14 @@ Date [Ver. 1.0. Started - August 22, 2014.] - Revision [$Id: wlcAbs.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + Revision [$Id: wlcAbs1.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] ***********************************************************************/ #include "wlc.h" +#include "proof/pdr/pdr.h" +#include "aig/gia/giaAig.h" +#include "sat/bmc/bmc.h" ABC_NAMESPACE_IMPL_START @@ -32,253 +35,370 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* - Synopsis [Check if two objects have the same input/output signatures.] + Synopsis [Mark operators that meet the abstraction criteria.] - Description [] + Description [This procedure returns the array of objects (vLeaves) that + should be abstracted because of their high bit-width. It uses input array (vUnmark) + to not abstract those objects that have been refined in the previous rounds.] SideEffects [] SeeAlso [] ***********************************************************************/ -int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { - Wlc_Obj_t * pFanin, * pFanin2; int k; - if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) ) - return 0; - if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) ) - return 0; - if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) ) - return 0; - for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ ) + Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + Wlc_Obj_t * pObj; int i, Count[4] = {0}; + Wlc_NtkForEachObj( p, pObj, i ) { - pFanin = Wlc_ObjFanin(p, pObj, k); - pFanin2 = Wlc_ObjFanin(p, pObj2, k); - if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) ) - return 0; - if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) ) - return 0; + if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away + continue; + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++; + continue; + } + if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++; + continue; + } + if ( pObj->Type == WLC_OBJ_MUX ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++; + continue; + } + if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++; + continue; + } } - return 1; + if ( fVerbose ) + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); + return vLeaves; } /**Function************************************************************* - Synopsis [Collect IDs of the multipliers.] + Synopsis [Marks nodes to be included in the abstracted network.] - Description [] + Description [Marks all objects that will be included in the abstracted model. + Stops at the objects (vLeaves) that are abstracted away. Returns three arrays: + a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the + set of flops present as flops in the abstracted network.] SideEffects [] SeeAlso [] ***********************************************************************/ -Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ) +static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) + { + assert( !Wlc_ObjIsPi(pObj) ); + Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); + return; + } + if ( Wlc_ObjIsCi(pObj) ) + { + if ( Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) ); + else + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); +} +static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { - Wlc_Obj_t * pObj; int i; - Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 ); + Wlc_Obj_t * pObj; + int i, Count = 0; + Wlc_NtkCleanMarks( p ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); Wlc_NtkForEachObj( p, pObj, i ) - if ( pObj->Type == WLC_OBJ_ARI_MULTI ) - Vec_IntPush( vBoxIds, i ); - if ( Vec_IntSize( vBoxIds ) > 0 ) - return vBoxIds; - Vec_IntFree( vBoxIds ); - return NULL; + Count += pObj->Mark; +// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n", +// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops), +// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) ); + Vec_IntSort( vPisOld, 0 ); + Vec_IntSort( vPisNew, 0 ); + Vec_IntSort( vFlops, 0 ); + Wlc_NtkCleanMarks( p ); } /**Function************************************************************* - Synopsis [Returns all pairs of uifable multipliers.] + Synopsis [Derive word-level abstracted model based on the parameter values.] - Description [] + Description [Retuns the word-level abstracted network and the set of pseudo-PIs + (vPisNew), which were created during abstraction. If the abstraction is + satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs + and their MFFC cones will be listed in the array (vUnmark), which will + force the abstraction to not stop at these pseudo-PIs in the future.] SideEffects [] SeeAlso [] ***********************************************************************/ -Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { - Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p ); - Vec_Int_t * vPairs = Vec_IntAlloc( 2 ); - Wlc_Obj_t * pObj, * pObj2; int i, k; - // iterate through unique pairs - Wlc_NtkForEachObjVec( vMultis, p, pObj, i ) - Wlc_NtkForEachObjVec( vMultis, p, pObj2, k ) - { - if ( k == i ) - break; - if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) ) - { - Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) ); - Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) ); - } - } - Vec_IntFree( vMultis ); - if ( Vec_IntSize( vPairs ) > 0 ) - return vPairs; - Vec_IntFree( vPairs ); - return NULL; + Wlc_Ntk_t * pNtkNew = NULL; + Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); + Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); + Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose ); + Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); + Vec_BitFree( vLeaves ); + pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); + Vec_IntFree( vPisOld ); + Vec_IntFree( vFlops ); + if ( pvPisNew ) + *pvPisNew = vPisNew; + else + Vec_IntFree( vPisNew ); + return pNtkNew; } +/**Function************************************************************* + + Synopsis [Find what objects need to be un-abstracted.] + Description [Returns a subset of pseudo-PIs (vPisNew), which will be + prevented from being abstracted in the future rounds of abstraction. + The AIG manager (pGia) is a bit-level view of the abstracted model. + The counter-example (pCex) is used to find waht PPIs to refine.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew ) +{ + Vec_Int_t * vRefine = Vec_IntAlloc( 100 ); + Abc_Cex_t * pCexCare; + Wlc_Obj_t * pObj; + // count the number of bit-level PPIs and map them into word-level objects they were derived from + int f, i, b, nRealPis, nPpiBits = 0; + Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis ); + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) ); + // since PPIs are ordered last, the previous bits are real PIs + nRealPis = pCex->nPis - nPpiBits; + // find the care-set + pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 ); + assert( pCexCare->nPis == pCex->nPis ); + // detect care PPIs + for ( f = 0; f <= pCexCare->iFrame; f++ ) + for ( i = nRealPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) ); + Abc_CexFree( pCexCare ); + Vec_IntFree( vMap ); + if ( Vec_IntSize(vRefine) == 0 )// real CEX + Vec_IntFreeP( &vRefine ); + return vRefine; +} /**Function************************************************************* - Synopsis [Abstracts nodes by replacing their outputs with new PIs.] + Synopsis [Mark MFFC cones of the un-abstracted objects.] - Description [If array is NULL, abstract all multipliers.] + Description [The MFFC cones of the objects in vRefine are traversed + and all their nodes are marked in vUnmark.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) +static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) { - Vec_Int_t * vNodes = vNodesInit; - Wlc_Ntk_t * pNew; - Wlc_Obj_t * pObj; - int i, k, iObj, iFanin; - // get multipliers if not given - if ( vNodes == NULL ) - vNodes = Wlc_NtkCollectMultipliers( p ); - if ( vNodes == NULL ) - return NULL; - // mark nodes - Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) - pObj->Mark = 1; - // iterate through the nodes in the DFS order - Wlc_NtkCleanCopy( p ); - Wlc_NtkForEachObj( p, pObj, i ) + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + Wlc_ObjForEachFanin( pNode, Fanin, i ) { - if ( i == Vec_IntSize(&p->vCopies) ) - break; - if ( pObj->Mark ) { - // clean - pObj->Mark = 0; - // add fresh PI with the same number of bits - iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ); - } - else { - // update fanins - Wlc_ObjForEachFanin( pObj, iFanin, k ) - Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin); - // node to remain - iObj = i; - } - Wlc_ObjSetCopy( p, i, iObj ); + Vec_IntAddToEntry( &p->vRefs, Fanin, -1 ); + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark ); + } + return Counter; +} +static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Wlc_ObjForEachFanin( pNode, Fanin, i ) + { + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) ); + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); } - // POs do not change in this procedure - if ( vNodes != vNodesInit ) - Vec_IntFree( vNodes ); - // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); - return pNew; + return Counter; +} +static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int Count1, Count2; + // if this is a flop output, compute MFFC of the corresponding flop input + while ( Wlc_ObjIsCi(pNode) ) + { + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + pNode = Wlc_ObjFo2Fi(p, pNode); + } + assert( !Wlc_ObjIsCi(pNode) ); + // dereference the node (and set the bits in vUnmark) + Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark ); + // reference it back + Count2 = Wlc_NtkNodeRef_rec( p, pNode ); + assert( Count1 == Count2 ); + return Count1; +} +static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark ) +{ + Wlc_Obj_t * pObj; int i, nNodes = 0; + if ( Vec_IntSize(&p->vRefs) == 0 ) + Wlc_NtkSetRefs( p ); + Wlc_NtkForEachObjVec( vRefine, p, pObj, i ) + nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark ); + return nNodes; } /**Function************************************************************* - Synopsis [Adds UIF constraints to node pairs and updates POs.] + Synopsis [Performs abstraction.] - Description [] + Description [Derives initial abstraction based on user-specified + parameter values, which tell what is the smallest bit-width of a + primitive that is being abstracted away. Currently only add/sub, + mul/div, mux, and flop are supported with individual parameters. + The second step is to refine the initial abstraction until the + point when the property is proved.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) +int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { - Vec_Int_t * vPairs = vPairsInit; - Wlc_Ntk_t * pNew; - Wlc_Obj_t * pObj, * pObj2; - Vec_Int_t * vUifConstrs, * vCompares, * vFanins; - int i, k, iObj, iObj2, iObjNew, iObjNew2; - int iFanin, iFanin2, iFaninNew; - // get multiplier pairs if not given - if ( vPairs == NULL ) - vPairs = Wlc_NtkFindUifableMultiplierPairs( p ); - if ( vPairs == NULL ) - return NULL; - // sanity checks - assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 ); - // iterate through node pairs - vFanins = Vec_IntAlloc( 100 ); - vCompares = Vec_IntAlloc( 100 ); - vUifConstrs = Vec_IntAlloc( 100 ); - Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i ) + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this + pPdrPars->fVerbose = pPars->fPdrVerbose; + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) { - // get two nodes - pObj = Wlc_NtkObj( p, iObj ); - pObj2 = Wlc_NtkObj( p, iObj2 ); - assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) ); - // create fanin comparator nodes - Vec_IntClear( vCompares ); - Wlc_ObjForEachFanin( pObj, iFanin, k ) + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present { - iFanin2 = Wlc_ObjFaninId( pObj2, k ); - Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 ); - iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins ); - Vec_IntPush( vCompares, iFaninNew ); - // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to - // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... - pObj = Wlc_NtkObj( p, iObj ); + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); } - // concatenate fanin comparators - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares ); - // create reduction-OR node - Vec_IntFill( vFanins, 1, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins ); - // craete output comparator node - Vec_IntFillTwo( vFanins, 2, iObj, iObj2 ); - iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins ); - // create implication node (iObjNew is already complemented above) - Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins ); - // save the constraint - Vec_IntPush( vUifConstrs, iObjNew ); - } - // derive the AND of the UIF contraints - assert( Vec_IntSize(vUifConstrs) > 0 ); - if ( Vec_IntSize(vUifConstrs) == 1 ) - iObjNew = Vec_IntEntry( vUifConstrs, 0 ); - else - { - // concatenate - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs ); - // create reduction-AND node - Vec_IntFill( vFanins, 1, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins ); - } - // update each PO to point to the new node - Wlc_NtkForEachPo( p, pObj, i ) - { - iObj = Wlc_ObjId(p, pObj); - Vec_IntFillTwo( vFanins, 2, iObj, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins ); - // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to - // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... - pObj = Wlc_NtkObj( p, iObj ); - // update PO/CO arrays - assert( Vec_IntEntry(&p->vPos, i) == iObj ); - assert( Vec_IntEntry(&p->vCos, i) == iObj ); - Vec_IntWriteEntry( &p->vPos, i, iObjNew ); - Vec_IntWriteEntry( &p->vCos, i, iObjNew ); - // transfer the PO attribute - Wlc_NtkObj(p, iObjNew)->fIsPo = 1; - assert( pObj->fIsPo ); - pObj->fIsPo = 0; + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); } - // cleanup - Vec_IntFree( vUifConstrs ); - Vec_IntFree( vCompares ); - Vec_IntFree( vFanins ); - if ( vPairs != vPairsInit ) - Vec_IntFree( vPairs ); - // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); - return pNew; + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c index f5a7b46d..9bccdf62 100644 --- a/src/base/wlc/wlcAbs2.c +++ b/src/base/wlc/wlcAbs2.c @@ -19,6 +19,9 @@ ***********************************************************************/ #include "wlc.h" +#include "proof/pdr/pdr.h" +#include "aig/gia/giaAig.h" +#include "sat/bmc/bmc.h" ABC_NAMESPACE_IMPL_START @@ -26,56 +29,31 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct Wabs_Par_t_ Wabs_Par_t; -struct Wabs_Par_t_ -{ - Wlc_Ntk_t * pNtk; - Wlc_Par_t * pPars; - Vec_Bit_t * vLeaves; -}; - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) -{ - memset( pPars, 0, sizeof(Wlc_Par_t) ); - pPars->nBitsAdd = ABC_INFINITY; // adder bit-width - pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht - pPars->nBitsMux = ABC_INFINITY; // MUX bit-width - pPars->nBitsFlop = ABC_INFINITY; // flop bit-width - pPars->fVerbose = 0; // verbose output` -} - -/**Function************************************************************* - - Synopsis [Mark operators that meet the criteria.] + Synopsis [Mark operators that meet the abstraction criteria.] - Description [] + Description [This procedure returns the array of objects (vLeaves) that + should be abstracted because of their high bit-width. It uses input array (vUnmark) + to not abstract those objects that have been refined in the previous rounds.] SideEffects [] SeeAlso [] ***********************************************************************/ -Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; Wlc_NtkForEachObj( p, pObj, i ) { + if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away + continue; if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) @@ -101,7 +79,8 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) continue; } } - printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); + if ( fVerbose ) + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); return vLeaves; } @@ -109,14 +88,17 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Synopsis [Marks nodes to be included in the abstracted network.] - Description [] + Description [Marks all objects that will be included in the abstracted model. + Stops at the objects (vLeaves) that are abstracted away. Returns three arrays: + a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the + set of flops present as flops in the abstracted network.] SideEffects [] SeeAlso [] ***********************************************************************/ -void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { int i, iFanin; if ( pObj->Mark ) @@ -139,8 +121,7 @@ void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeav Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); } - -void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { Wlc_Obj_t * pObj; int i, Count = 0; @@ -162,31 +143,264 @@ void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOl /**Function************************************************************* - Synopsis [Derive abstraction based on the parameter values.] + Synopsis [Derive word-level abstracted model based on the parameter values.] - Description [] + Description [Retuns the word-level abstracted network and the set of pseudo-PIs + (vPisNew), which were created during abstraction. If the abstraction is + satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs + and their MFFC cones will be listed in the array (vUnmark), which will + force the abstraction to not stop at these pseudo-PIs in the future.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); - Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose ); Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); Vec_BitFree( vLeaves ); pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); Vec_IntFree( vPisOld ); - Vec_IntFree( vPisNew ); Vec_IntFree( vFlops ); + if ( pvPisNew ) + *pvPisNew = vPisNew; + else + Vec_IntFree( vPisNew ); return pNtkNew; } +/**Function************************************************************* + + Synopsis [Find what objects need to be un-abstracted.] + + Description [Returns a subset of pseudo-PIs (vPisNew), which will be + prevented from being abstracted in the future rounds of abstraction. + The AIG manager (pGia) is a bit-level view of the abstracted model. + The counter-example (pCex) is used to find waht PPIs to refine.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew ) +{ + Vec_Int_t * vRefine = Vec_IntAlloc( 100 ); + Abc_Cex_t * pCexCare; + Wlc_Obj_t * pObj; + // count the number of bit-level PPIs and map them into word-level objects they were derived from + int f, i, b, nRealPis, nPpiBits = 0; + Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis ); + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) ); + // since PPIs are ordered last, the previous bits are real PIs + nRealPis = pCex->nPis - nPpiBits; + // find the care-set + pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 ); + assert( pCexCare->nPis == pCex->nPis ); + // detect care PPIs + for ( f = 0; f <= pCexCare->iFrame; f++ ) + for ( i = nRealPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) ); + Abc_CexFree( pCexCare ); + Vec_IntFree( vMap ); + if ( Vec_IntSize(vRefine) == 0 )// real CEX + Vec_IntFreeP( &vRefine ); + return vRefine; +} + +/**Function************************************************************* + + Synopsis [Mark MFFC cones of the un-abstracted objects.] + + Description [The MFFC cones of the objects in vRefine are traversed + and all their nodes are marked in vUnmark.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + Wlc_ObjForEachFanin( pNode, Fanin, i ) + { + Vec_IntAddToEntry( &p->vRefs, Fanin, -1 ); + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark ); + } + return Counter; +} +static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Wlc_ObjForEachFanin( pNode, Fanin, i ) + { + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) ); + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); + } + return Counter; +} +static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int Count1, Count2; + // if this is a flop output, compute MFFC of the corresponding flop input + while ( Wlc_ObjIsCi(pNode) ) + { + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + pNode = Wlc_ObjFo2Fi(p, pNode); + } + assert( !Wlc_ObjIsCi(pNode) ); + // dereference the node (and set the bits in vUnmark) + Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark ); + // reference it back + Count2 = Wlc_NtkNodeRef_rec( p, pNode ); + assert( Count1 == Count2 ); + return Count1; +} +static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark ) +{ + Wlc_Obj_t * pObj; int i, nNodes = 0; + if ( Vec_IntSize(&p->vRefs) == 0 ) + Wlc_NtkSetRefs( p ); + Wlc_NtkForEachObjVec( vRefine, p, pObj, i ) + nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark ); + return nNodes; +} + +/**Function************************************************************* + + Synopsis [Performs abstraction.] + + Description [Derives initial abstraction based on user-specified + parameter values, which tell what is the smallest bit-width of a + primitive that is being abstracted away. Currently only add/sub, + mul/div, mux, and flop are supported with individual parameters. + The second step is to refine the initial abstraction until the + point when the property is proved.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this + pPdrPars->fVerbose = pPars->fPdrVerbose; + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) + { + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present + { + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); + } + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); + } + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 67d7c902..f4de8ee6 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1418,7 +1418,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in } else { - pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 1 ); + pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 0 ); Gia_ManDupRemapLiterals( vBits, pTemp ); Gia_ManStop( pTemp ); } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 346a9076..97717b09 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -33,6 +33,7 @@ static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -74,6 +75,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); @@ -458,7 +460,7 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Wlc_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) { switch ( c ) { @@ -506,9 +508,26 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBitsFlop < 0 ) goto usage; break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; case 'h': goto usage; default: @@ -520,17 +539,133 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - pNtk = Wlc_NtkAbs( pNtk, pPars ); - Wlc_AbcUpdateNtk( pAbc, pNtk ); + Wlc_NtkAbsCore( pNtk, pPars ); + return 0; +usage: + Abc_Print( -2, "usage: %%abs [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandAbs2( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + Wlc_NtkAbsCore2( pNtk, pPars ); return 0; usage: - Abc_Print( -2, "usage: %%abs [-AMXF num] [-vh]\n" ); + Abc_Print( -2, "usage: %%abs2 [-AMXFI num] [-xvwh]\n" ); Abc_Print( -2, "\t abstraction for word-level networks\n" ); Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 86b0c17e..e6ab0739 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -94,6 +94,30 @@ char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Wlc_Par_t) ); + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->nIterMax = 1000; // the max number of iterations + pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fVerbose = 0; // verbose output` + pPars->fPdrVerbose = 0; // show verbose PDR output +} + /**Function************************************************************* Synopsis [Working with models.] @@ -227,6 +251,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vCopies.pArray ); ABC_FREE( p->vBits.pArray ); ABC_FREE( p->vLevels.pArray ); + ABC_FREE( p->vRefs.pArray ); ABC_FREE( p->pInits ); ABC_FREE( p->pObjs ); ABC_FREE( p->pName ); @@ -912,7 +937,7 @@ Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vP if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Wlc_NtkTransferNames( pNew, p ); + //Wlc_NtkTransferNames( pNew, p ); return pNew; } @@ -1129,6 +1154,70 @@ void Wlc_NtkShortNames( Wlc_Ntk_t * p ) } } +/**Function************************************************************* + + Synopsis [Count the number of flops initialized to DC value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p ) +{ + int i, nFlops, Count = 0; + if ( p->pInits == NULL ) + return 0; + nFlops = strlen(p->pInits); + for ( i = 0; i < nFlops; i++ ) + Count += (p->pInits[i] == 'x' || p->pInits[i] == 'X'); + return Count; +} + +/**Function************************************************************* + + Synopsis [Create references.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkSetRefs( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; int i, k, Fanin; + Vec_IntFill( &p->vRefs, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObj( p, pObj, i ) + Wlc_ObjForEachFanin( pObj, Fanin, k ) + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); + Wlc_NtkForEachCo( p, pObj, i ) + Vec_IntAddToEntry( &p->vRefs, Wlc_ObjId(p, pObj), 1 ); +} + +/**Function************************************************************* + + Synopsis [This procedure simply count the number of PPI bits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew ) +{ + Wlc_Obj_t * pObj; + int i, Count = 0; + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + Count += Wlc_ObjRange(pObj); + return Count; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcUif.c b/src/base/wlc/wlcUif.c new file mode 100644 index 00000000..78451c17 --- /dev/null +++ b/src/base/wlc/wlcUif.c @@ -0,0 +1,290 @@ +/**CFile**************************************************************** + + FileName [wlcUif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Abstraction for word-level networks.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcUif.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Check if two objects have the same input/output signatures.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ) +{ + Wlc_Obj_t * pFanin, * pFanin2; int k; + if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) ) + return 0; + if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) ) + return 0; + if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) ) + return 0; + for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ ) + { + pFanin = Wlc_ObjFanin(p, pObj, k); + pFanin2 = Wlc_ObjFanin(p, pObj2, k); + if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) ) + return 0; + if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Collect IDs of the multipliers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; int i; + Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 ); + Wlc_NtkForEachObj( p, pObj, i ) + if ( pObj->Type == WLC_OBJ_ARI_MULTI ) + Vec_IntPush( vBoxIds, i ); + if ( Vec_IntSize( vBoxIds ) > 0 ) + return vBoxIds; + Vec_IntFree( vBoxIds ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Returns all pairs of uifable multipliers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ) +{ + Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p ); + Vec_Int_t * vPairs = Vec_IntAlloc( 2 ); + Wlc_Obj_t * pObj, * pObj2; int i, k; + // iterate through unique pairs + Wlc_NtkForEachObjVec( vMultis, p, pObj, i ) + Wlc_NtkForEachObjVec( vMultis, p, pObj2, k ) + { + if ( k == i ) + break; + if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) ) + { + Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) ); + Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) ); + } + } + Vec_IntFree( vMultis ); + if ( Vec_IntSize( vPairs ) > 0 ) + return vPairs; + Vec_IntFree( vPairs ); + return NULL; +} + + + +/**Function************************************************************* + + Synopsis [Abstracts nodes by replacing their outputs with new PIs.] + + Description [If array is NULL, abstract all multipliers.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) +{ + Vec_Int_t * vNodes = vNodesInit; + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + int i, k, iObj, iFanin; + // get multipliers if not given + if ( vNodes == NULL ) + vNodes = Wlc_NtkCollectMultipliers( p ); + if ( vNodes == NULL ) + return NULL; + // mark nodes + Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) + pObj->Mark = 1; + // iterate through the nodes in the DFS order + Wlc_NtkCleanCopy( p ); + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( i == Vec_IntSize(&p->vCopies) ) + break; + if ( pObj->Mark ) { + // clean + pObj->Mark = 0; + // add fresh PI with the same number of bits + iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ); + } + else { + // update fanins + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin); + // node to remain + iObj = i; + } + Wlc_ObjSetCopy( p, i, iObj ); + } + // POs do not change in this procedure + if ( vNodes != vNodesInit ) + Vec_IntFree( vNodes ); + // reconstruct topological order + pNew = Wlc_NtkDupDfs( p, 0, 1 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Adds UIF constraints to node pairs and updates POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) +{ + Vec_Int_t * vPairs = vPairsInit; + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj, * pObj2; + Vec_Int_t * vUifConstrs, * vCompares, * vFanins; + int i, k, iObj, iObj2, iObjNew, iObjNew2; + int iFanin, iFanin2, iFaninNew; + // get multiplier pairs if not given + if ( vPairs == NULL ) + vPairs = Wlc_NtkFindUifableMultiplierPairs( p ); + if ( vPairs == NULL ) + return NULL; + // sanity checks + assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 ); + // iterate through node pairs + vFanins = Vec_IntAlloc( 100 ); + vCompares = Vec_IntAlloc( 100 ); + vUifConstrs = Vec_IntAlloc( 100 ); + Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i ) + { + // get two nodes + pObj = Wlc_NtkObj( p, iObj ); + pObj2 = Wlc_NtkObj( p, iObj2 ); + assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) ); + // create fanin comparator nodes + Vec_IntClear( vCompares ); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + { + iFanin2 = Wlc_ObjFaninId( pObj2, k ); + Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 ); + iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins ); + Vec_IntPush( vCompares, iFaninNew ); + // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to + // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... + pObj = Wlc_NtkObj( p, iObj ); + } + // concatenate fanin comparators + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares ); + // create reduction-OR node + Vec_IntFill( vFanins, 1, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins ); + // craete output comparator node + Vec_IntFillTwo( vFanins, 2, iObj, iObj2 ); + iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins ); + // create implication node (iObjNew is already complemented above) + Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins ); + // save the constraint + Vec_IntPush( vUifConstrs, iObjNew ); + } + // derive the AND of the UIF contraints + assert( Vec_IntSize(vUifConstrs) > 0 ); + if ( Vec_IntSize(vUifConstrs) == 1 ) + iObjNew = Vec_IntEntry( vUifConstrs, 0 ); + else + { + // concatenate + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs ); + // create reduction-AND node + Vec_IntFill( vFanins, 1, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins ); + } + // update each PO to point to the new node + Wlc_NtkForEachPo( p, pObj, i ) + { + iObj = Wlc_ObjId(p, pObj); + Vec_IntFillTwo( vFanins, 2, iObj, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins ); + // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to + // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... + pObj = Wlc_NtkObj( p, iObj ); + // update PO/CO arrays + assert( Vec_IntEntry(&p->vPos, i) == iObj ); + assert( Vec_IntEntry(&p->vCos, i) == iObj ); + Vec_IntWriteEntry( &p->vPos, i, iObjNew ); + Vec_IntWriteEntry( &p->vCos, i, iObjNew ); + // transfer the PO attribute + Wlc_NtkObj(p, iObjNew)->fIsPo = 1; + assert( pObj->fIsPo ); + pObj->fIsPo = 0; + } + // cleanup + Vec_IntFree( vUifConstrs ); + Vec_IntFree( vCompares ); + Vec_IntFree( vFanins ); + if ( vPairs != vPairsInit ) + Vec_IntFree( vPairs ); + // reconstruct topological order + pNew = Wlc_NtkDupDfs( p, 0, 1 ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c index 554add9b..baade033 100644 --- a/src/proof/pdr/pdrInv.c +++ b/src/proof/pdr/pdrInv.c @@ -50,7 +50,16 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) Vec_Ptr_t * vVec; int i, ThisSize, Length, LengthStart; if ( Vec_PtrSize(p->vSolvers) < 2 ) + { + printf( "Frame " ); + printf( "Clauses " ); + printf( "Max Queue " ); + printf( "Flops " ); + printf( "Cex " ); + printf( "Time" ); + printf( "\n" ); return; + } if ( Abc_FrameIsBatchMode() && !fClose ) return; // count the total length of the printout @@ -81,9 +90,9 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time ) for ( i = ThisSize; i < 70; i++ ) Abc_Print( 1, " " ); Abc_Print( 1, "%5d", p->nQueMax ); - Abc_Print( 1, "%5d", p->vAbsFlops ? Vec_IntCountPositive(p->vAbsFlops) : p->nAbsFlops ); + Abc_Print( 1, "%6d", p->vAbsFlops ? Vec_IntCountPositive(p->vAbsFlops) : p->nAbsFlops ); if ( p->pPars->fUseAbs ) - Abc_Print( 1, "%5d", p->nCexes ); + Abc_Print( 1, "%4d", p->nCexes ); Abc_Print( 1, "%10.2f sec", 1.0*Time/CLOCKS_PER_SEC ); if ( p->pPars->fSolveAll ) Abc_Print( 1, " CEX =%4d", p->pPars->nFailOuts ); diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index c19041ee..abe8c0a8 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -455,7 +455,7 @@ Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) int i, f, Lit, Flop, nFrames = 0; int nPis = Saig_ManPiNum(p->pAig); int nFfRefined = 0; - if ( !p->pPars->fUseAbs ) + if ( !p->pPars->fUseAbs || !p->vMapPpi2Ff ) return Pdr_ManDeriveCex(p); // restore previous map Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i ) -- cgit v1.2.3 From bcc6d2686ffe6c0edce08d1470801f2f8e642bff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 15 Feb 2017 19:12:47 -0800 Subject: Fixing missing sat_solver APIs in 'iprove'. --- src/sat/bsat/satSolver.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index 37e0ea94..f753e0a5 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -328,12 +328,49 @@ static inline void act_var_bump(sat_solver* s, int v) } static inline void act_var_bump_global(sat_solver* s, int v) { - assert(0); + if ( !s->pGlobalVars ) + return; + if ( s->VarActType == 0 ) + { + s->activity[v] += (int)((unsigned)s->var_inc * 3 * s->pGlobalVars[v]); + if (s->activity[v] & 0x80000000) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 1 ) + { + s->activity[v] += (unsigned)(Abc_Word2Dbl(s->var_inc) * 3.0 * s->pGlobalVars[v]); + if (Abc_Word2Dbl(s->activity[v]) > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else assert( 0 ); } static inline void act_var_bump_factor(sat_solver* s, int v) { - assert(0); + if ( !s->factors ) + return; + if ( s->VarActType == 0 ) + { + s->activity[v] += (int)((unsigned)s->var_inc * (float)s->factors[v]); + if (s->activity[v] & 0x80000000) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 1 ) + { + s->activity[v] += (unsigned)(Abc_Word2Dbl(s->var_inc) * s->factors[v]); + if (Abc_Word2Dbl(s->activity[v]) > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else assert( 0 ); } + static inline void act_var_decay(sat_solver* s) { if ( s->VarActType == 0 ) @@ -1234,7 +1271,7 @@ void sat_solver_setnvars(sat_solver* s,int n) else if ( s->VarActType == 1 ) s->activity[var] = 0; else if ( s->VarActType == 2 ) - s->activity[var] = Xdbl_Const1(); + s->activity[var] = 0; else assert(0); s->pFreqs[var] = 0; -- cgit v1.2.3 From c7b68c5e3f547679b524ec5e0dcb85cc3735deef Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 10:03:34 -0800 Subject: Promising modification of the generalization procedure in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 37 ++++++++++++++++++++++++------------- src/proof/pdr/pdrInt.h | 2 +- src/proof/pdr/pdrSat.c | 4 ++-- 5 files changed, 34 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index af5d0ccf..44e4bc16 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26313,6 +26313,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'g': pPars->fSkipGeneral ^= 1; break; + case 'j': + pPars->fSimpleGeneral ^= 1; + break; case 'o': pPars->fUsePropOut ^= 1; break; @@ -26366,7 +26369,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26392,6 +26395,7 @@ usage: Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); + Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 33397588..534e8e4b 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -60,6 +60,7 @@ struct Pdr_Par_t_ int fShortest; // forces bug traces to be shortest int fShiftStart; // allows clause pushing to start from an intermediate frame int fReuseProofOblig; // reuses proof-obligationgs in the last timeframe + int fSimpleGeneral; // simplified generalization int fSkipGeneral; // skips expensive generalization step int fSkipDown; // skips the application of down int fCtgs; // handle CTGs in down diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 45dbfc9f..58735f28 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -125,7 +125,7 @@ Pdr_Set_t * Pdr_ManReduceClause( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ) // make sure the cube works { int RetValue; - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0, 1 ); assert( RetValue ); } */ @@ -172,7 +172,7 @@ int Pdr_ManPushClauses( Pdr_Man_t * p ) } // check if the clause can be moved to the next frame - RetValue2 = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0 ); + RetValue2 = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0, 1 ); if ( RetValue2 == -1 ) return -1; if ( !RetValue2 ) @@ -336,7 +336,7 @@ int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube ) continue; // try removing this literal Lit = (*ppCube)->Lits[i]; (*ppCube)->Lits[i] = -1; - RetValue = Pdr_ManCheckCube( p, k, *ppCube, NULL, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, k, *ppCube, NULL, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == -1 ) return -1; (*ppCube)->Lits[i] = Lit; @@ -392,7 +392,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, *added = 1; } ctgAttempts++; - CtgRetValue = Pdr_ManCheckCube ( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0 ); + CtgRetValue = Pdr_ManCheckCube ( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0, 1 ); if ( CtgRetValue != 1 ) { Pdr_SetDeref( pCtg ); @@ -403,7 +403,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, pCubeMin = Pdr_SetDup ( pCtg ); for ( l = k; l < kMax; l++ ) - if ( !Pdr_ManCheckCube( p, l, pCubeMin, NULL, 0, 0 ) ) + if ( !Pdr_ManCheckCube( p, l, pCubeMin, NULL, 0, 0, 1 ) ) break; micResult = ZPdr_ManSimpleMic( p, l-1, &pCubeMin ); assert ( micResult != -1 ); @@ -430,7 +430,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, // add clause for ( i = 1; i <= l; i++ ) Pdr_ManSolverAddClause( p, i, pCubeMin ); - RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); assert( RetValue >= 0 ); Pdr_SetDeref( pCtg ); if ( RetValue == 1 ) @@ -464,7 +464,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, printf ("Failed initiation\n"); return 0; } - RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == -1 ) return -1; if ( RetValue == 1 ) @@ -530,7 +530,7 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP *ppCubeMin = NULL; if ( p->pPars->fFlopOrder ) Vec_IntSelectSortCostReverseLit( pCube->Lits, pCube->nLits, p->vPrio ); - RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0, 1 ); if ( p->pPars->fFlopOrder ) Vec_IntSelectSort( pCube->Lits, pCube->nLits ); if ( RetValue == -1 ) @@ -552,6 +552,16 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP // perform generalization if ( !p->pPars->fSkipGeneral ) { + // assume the unminimized cube + if ( p->pPars->fSimpleGeneral ) + { + sat_solver * pSat = Pdr_ManFetchSolver( p, k ); + Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCubeMin, 1, 0 ); + int RetValue1 = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntArray(vLits1) + Vec_IntSize(vLits1) ); + assert( RetValue1 == 1 ); + sat_solver_compress( pSat ); + } + // sort literals by their occurences pOrder = Pdr_ManSortByPriority( p, pCubeMin ); // try removing literals @@ -571,12 +581,13 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP // check init state if ( Pdr_SetIsInit(pCubeMin, i) ) continue; + // try removing this literal Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; if ( p->pPars->fSkipDown ) - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1, !p->pPars->fSimpleGeneral ); else - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1, !p->pPars->fSimpleGeneral ); if ( RetValue == -1 ) { Pdr_SetDeref( pCubeMin ); @@ -641,7 +652,7 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP continue; // try removing this literal Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1; - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == -1 ) { Pdr_SetDeref( pCubeMin ); @@ -759,7 +770,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ) assert( pPred == NULL ); for ( k = pThis->iFrame; k < kMax; k++ ) { - RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0 ); + RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0, 1 ); if ( RetValue == -1 ) { Pdr_OblDeref( pThis ); @@ -940,7 +951,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p ) p->pPars->iFrame = iFrame; return -1; } - RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0 ); + RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == 1 ) break; if ( RetValue == -1 ) diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h index a6d249e8..e5b04339 100644 --- a/src/proof/pdr/pdrInt.h +++ b/src/proof/pdr/pdrInt.h @@ -199,7 +199,7 @@ extern Vec_Int_t * Pdr_ManLitsToCube( Pdr_Man_t * p, int k, int * pArray, in extern void Pdr_ManSolverAddClause( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); extern void Pdr_ManCollectValues( Pdr_Man_t * p, int k, Vec_Int_t * vObjIds, Vec_Int_t * vValues ); extern int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); -extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf ); +extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf, int fUseLit ); /*=== pdrTsim.c ==========================================================*/ extern Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ); /*=== pdrTsim2.c ==========================================================*/ diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c index b9403e6f..ab582d9e 100644 --- a/src/proof/pdr/pdrSat.c +++ b/src/proof/pdr/pdrSat.c @@ -287,9 +287,9 @@ int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCube ) SeeAlso [] ***********************************************************************/ -int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf ) +int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf, int fUseLit ) { - int fUseLit = 1; + //int fUseLit = 0; int fLitUsed = 0; sat_solver * pSat; Vec_Int_t * vLits; -- cgit v1.2.3 From 408ce468152257ddbcbce697f26e5246618fd38b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 10:28:39 -0800 Subject: Fixing memory leak in 'pdr'. --- src/proof/pdr/pdrCore.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 58735f28..40e86727 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -378,7 +378,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, ctgAttempts = 0; while ( p->pPars->fCtgs && RetValue == 0 && k > 1 && ctgAttempts < 3 ) { - pCtg = Pdr_SetDup ( pPred ); + pCtg = Pdr_SetDup( pPred ); //Check CTG for inductiveness if ( Pdr_SetIsInit( pCtg, -1 ) ) { @@ -392,7 +392,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, *added = 1; } ctgAttempts++; - CtgRetValue = Pdr_ManCheckCube ( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0, 1 ); + CtgRetValue = Pdr_ManCheckCube( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0, 1 ); if ( CtgRetValue != 1 ) { Pdr_SetDeref( pCtg ); @@ -430,7 +430,8 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, // add clause for ( i = 1; i <= l; i++ ) Pdr_ManSolverAddClause( p, i, pCubeMin ); - RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); + Pdr_SetDeref( pPred ); + RetValue = Pdr_ManCheckCube( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); assert( RetValue >= 0 ); Pdr_SetDeref( pCtg ); if ( RetValue == 1 ) @@ -464,7 +465,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, printf ("Failed initiation\n"); return 0; } - RetValue = Pdr_ManCheckCube ( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); + RetValue = Pdr_ManCheckCube( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 ); if ( RetValue == -1 ) return -1; if ( RetValue == 1 ) @@ -598,8 +599,8 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP { if ( p->pPars->fSkipDown ) continue; - pCubeCpy = Pdr_SetCreateFrom ( pCubeMin, i ); - RetValue = ZPdr_ManDown ( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); + pCubeCpy = Pdr_SetCreateFrom( pCubeMin, i ); + RetValue = ZPdr_ManDown( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added ); if ( p->pPars->fCtgs ) //CTG handling code messes up with the internal order array pOrder = Pdr_ManSortByPriority( p, pCubeMin ); -- cgit v1.2.3 From 61b665ac8d3f107eb8ddf01f4cb816ddc3df21b0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 11:38:06 -0800 Subject: Experiment with graph constuction using ZDDs. --- src/bdd/extrab/extraBddMisc.c | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src') diff --git a/src/bdd/extrab/extraBddMisc.c b/src/bdd/extrab/extraBddMisc.c index a2ba4036..44170102 100644 --- a/src/bdd/extrab/extraBddMisc.c +++ b/src/bdd/extrab/extraBddMisc.c @@ -2333,6 +2333,52 @@ void Extra_zddDumpPla( DdManager * dd, DdNode * F, int nVars, char * pFileName ) ABC_FREE( pCube ); } +/**Function************************************************************* + + Synopsis [Constructing ZDD of a graph.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Extra_GraphExperiment() +{ + int Edges[5][5] = { + {1, 3, 4}, + {1, 5}, + {2, 3, 5}, + {2, 4} + }; + int e, n; + + DdManager * dd = Cudd_Init( 0, 6, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + + // create the edges + DdNode * zGraph, * zEdge, * zVar, * zTemp; + zGraph = DD_ZERO(dd); Cudd_Ref( zGraph ); + for ( e = 0; Edges[e][0]; e++ ) + { + zEdge = DD_ONE(dd); Cudd_Ref( zEdge ); + for ( n = 0; Edges[e][n]; n++ ) + { + zVar = cuddZddGetNode( dd, Edges[e][n], DD_ONE(dd), DD_ZERO(dd) ); Cudd_Ref( zVar ); + zEdge = Cudd_zddUnateProduct( dd, zTemp = zEdge, zVar ); Cudd_Ref( zEdge ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zVar ); + } + zGraph = Cudd_zddUnion( dd, zTemp = zGraph, zEdge ); Cudd_Ref( zGraph ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zEdge ); + } + + Cudd_zddPrintMinterm( dd, zGraph ); + + Cudd_RecursiveDerefZdd( dd, zGraph ); + Cudd_Quit(dd); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 632ca7ed11be3bd57ac1a730a9775658c17d9b53 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 13:37:46 -0800 Subject: Promising alternative of CEX minimization in 'pdr'. --- src/base/abci/abc.c | 8 +++-- src/proof/pdr/pdr.h | 1 + src/proof/pdr/pdrCore.c | 6 ++-- src/proof/pdr/pdrMan.c | 79 ++++++++++++++++++++++++++++--------------------- 4 files changed, 57 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 44e4bc16..52684f8c 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) { switch ( c ) { @@ -26328,6 +26328,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 't': pPars->fUseAbs ^= 1; break; + case 'k': + pPars->fUseSimpleRef ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26369,7 +26372,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26400,6 +26403,7 @@ usage: Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); + Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h index 534e8e4b..51b04606 100644 --- a/src/proof/pdr/pdr.h +++ b/src/proof/pdr/pdr.h @@ -65,6 +65,7 @@ struct Pdr_Par_t_ int fSkipDown; // skips the application of down int fCtgs; // handle CTGs in down int fUseAbs; // use abstraction + int fUseSimpleRef; // simplified CEX refinement int fVerbose; // verbose output` int fVeryVerbose; // very verbose output int fNotVerbose; // not printing line by line progress diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index 40e86727..efb4154f 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -60,8 +60,6 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->nRestLimit = 0; // limit on the number of proof-obligations pPars->nRandomSeed = 91648253; // value to seed the SAT solver with pPars->fTwoRounds = 0; // use two rounds for generalization - pPars->fSkipDown = 1; // apply down in generalization - pPars->fCtgs = 0; // handle CTGs in down pPars->fMonoCnf = 0; // monolythic CNF pPars->fNewXSim = 0; // updated X-valued simulation pPars->fFlopPrio = 0; // use structural flop priorities @@ -70,6 +68,10 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars ) pPars->fUseSupp = 1; // using support variables in the invariant pPars->fShortest = 0; // forces bug traces to be shortest pPars->fUsePropOut = 1; // use property output + pPars->fSkipDown = 1; // apply down in generalization + pPars->fCtgs = 0; // handle CTGs in down + pPars->fUseAbs = 0; // use abstraction + pPars->fUseSimpleRef = 0; // simplified CEX refinement pPars->fVerbose = 0; // verbose output pPars->fVeryVerbose = 0; // very verbose output pPars->fNotVerbose = 0; // not printing line-by-line progress diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c index abe8c0a8..a076223b 100644 --- a/src/proof/pdr/pdrMan.c +++ b/src/proof/pdr/pdrMan.c @@ -482,45 +482,58 @@ Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p ) } if ( Vec_IntSize(p->vMapPpi2Ff) == 0 ) // no PPIs -- this is a real CEX return Pdr_ManDeriveCex(p); - // create the counter-example - pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames ); - pCex->iPo = p->iOutCur; - pCex->iFrame = nFrames-1; - for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) - for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ ) + if ( p->pPars->fUseSimpleRef ) + { + // rely on ternary simulation to perform refinement + Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i ) { - Lit = pObl->pState->Lits[i]; - if ( lit_sign(Lit) ) - continue; - if ( lit_var(Lit) < nPis ) // PI literal - Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) ); - else - { - int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis); - assert( iPPI < pCex->nPis ); - Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI ); - } + assert( Vec_IntEntry(p->vAbsFlops, Flop) == 0 ); + Vec_IntWriteEntry( p->vAbsFlops, Flop, 1 ); + nFfRefined++; } - assert( f == nFrames ); - // perform CEX minimization - pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi ); - pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 ); - Gia_ManStop( pAbs ); - assert( pCexCare->nPis == pCex->nPis ); - Abc_CexFree( pCex ); - // detect care PPIs - for ( f = 0; f < nFrames; f++ ) + } + else { - for ( i = nPis; i < pCexCare->nPis; i++ ) - if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + // create the counter-example + pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames ); + pCex->iPo = p->iOutCur; + pCex->iFrame = nFrames-1; + for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ ) + for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ ) { - if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted - Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++; + Lit = pObl->pState->Lits[i]; + if ( lit_sign(Lit) ) + continue; + if ( lit_var(Lit) < nPis ) // PI literal + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) ); + else + { + int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis); + assert( iPPI < pCex->nPis ); + Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI ); + } } + assert( f == nFrames ); + // perform CEX minimization + pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi ); + pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 ); + Gia_ManStop( pAbs ); + assert( pCexCare->nPis == pCex->nPis ); + Abc_CexFree( pCex ); + // detect care PPIs + for ( f = 0; f < nFrames; f++ ) + { + for ( i = nPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + { + if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted + Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++; + } + } + Abc_CexFree( pCexCare ); + if ( nFfRefined == 0 ) // no refinement -- this is a real CEX + return Pdr_ManDeriveCex(p); } - Abc_CexFree( pCexCare ); - if ( nFfRefined == 0 ) // no refinement -- this is a real CEX - return Pdr_ManDeriveCex(p); //printf( "CEX-based refinement refined %d flops.\n", nFfRefined ); p->nCexesTotal++; p->nCexes++; -- cgit v1.2.3 From 6d6bf8740d246b1478b636a1d300ede371bffabe Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 13:57:36 -0800 Subject: Fixing missing sat_solver APIs in 'iprove'. --- src/sat/bsat/satSolver.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c index f753e0a5..df9ada8e 100644 --- a/src/sat/bsat/satSolver.c +++ b/src/sat/bsat/satSolver.c @@ -328,11 +328,11 @@ static inline void act_var_bump(sat_solver* s, int v) } static inline void act_var_bump_global(sat_solver* s, int v) { - if ( !s->pGlobalVars ) + if ( !s->pGlobalVars || !s->pGlobalVars[v] ) return; if ( s->VarActType == 0 ) { - s->activity[v] += (int)((unsigned)s->var_inc * 3 * s->pGlobalVars[v]); + s->activity[v] += (int)((unsigned)s->var_inc * 3); if (s->activity[v] & 0x80000000) act_var_rescale(s); if (s->orderpos[v] != -1) @@ -340,8 +340,17 @@ static inline void act_var_bump_global(sat_solver* s, int v) } else if ( s->VarActType == 1 ) { - s->activity[v] += (unsigned)(Abc_Word2Dbl(s->var_inc) * 3.0 * s->pGlobalVars[v]); - if (Abc_Word2Dbl(s->activity[v]) > 1e100) + double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * 3.0; + s->activity[v] = Abc_Dbl2Word(act); + if ( act > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 2 ) + { + s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(3.0)) ); + if (s->activity[v] > ABC_CONST(0x014c924d692ca61b)) act_var_rescale(s); if (s->orderpos[v] != -1) order_update(s,v); @@ -362,8 +371,17 @@ static inline void act_var_bump_factor(sat_solver* s, int v) } else if ( s->VarActType == 1 ) { - s->activity[v] += (unsigned)(Abc_Word2Dbl(s->var_inc) * s->factors[v]); - if (Abc_Word2Dbl(s->activity[v]) > 1e100) + double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * s->factors[v]; + s->activity[v] = Abc_Dbl2Word(act); + if ( act > 1e100) + act_var_rescale(s); + if (s->orderpos[v] != -1) + order_update(s,v); + } + else if ( s->VarActType == 2 ) + { + s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(s->factors[v])) ); + if (s->activity[v] > ABC_CONST(0x014c924d692ca61b)) act_var_rescale(s); if (s->orderpos[v] != -1) order_update(s,v); -- cgit v1.2.3 From 378af9d94fc32232f638c784fb9cb9095f410bee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 17 Feb 2017 14:09:58 -0800 Subject: Experiment with graph constuction using ZDDs. --- src/bdd/extrab/extraBddMisc.c | 203 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) (limited to 'src') diff --git a/src/bdd/extrab/extraBddMisc.c b/src/bdd/extrab/extraBddMisc.c index 44170102..bc4d8a7a 100644 --- a/src/bdd/extrab/extraBddMisc.c +++ b/src/bdd/extrab/extraBddMisc.c @@ -2379,6 +2379,209 @@ void Extra_GraphExperiment() Cudd_RecursiveDerefZdd( dd, zGraph ); Cudd_Quit(dd); } + + + + +/**Function******************************************************************** + + Synopsis [Performs the reordering-sensitive step of Extra_zddCombination().] + + Description [Generates in a bottom-up fashion ZDD for one combination + whose var values are given in the array VarValues. If necessary, + creates new variables on the fly.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * extraZddCombination( + DdManager* dd, + int* VarValues, + int nVars ) +{ + int lev, index; + DdNode *zRes, *zTemp; + + /* transform the combination from the array VarValues into a ZDD cube. */ + zRes = dd->one; + cuddRef(zRes); + + /* go through levels starting bottom-up and create nodes + * if these variables are present in the comb + */ + for (lev = nVars - 1; lev >= 0; lev--) + { + index = (lev >= dd->sizeZ) ? lev : dd->invpermZ[lev]; + if (VarValues[index] == 1) + { + /* compose zRes with ZERO for the given ZDD variable */ + zRes = cuddZddGetNode( dd, index, zTemp = zRes, dd->zero ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes ); + cuddDeref( zTemp ); + } + } + cuddDeref( zRes ); + return zRes; + +} /* end of extraZddCombination */ + +/**Function******************************************************************** + + Synopsis [Creates ZDD of the combination containing given variables.] + + Description [Creates ZDD of the combination containing given variables. + VarValues contains 1 for a variable that belongs to the + combination and 0 for a varible that does not belong. + nVars is number of ZDD variables in the array.] + + SideEffects [New ZDD variables are created if indices of the variables + present in the combination are larger than the currently + allocated number of ZDD variables.] + + SeeAlso [] + +******************************************************************************/ +DdNode * Extra_zddCombination( + DdManager *dd, + int* VarValues, + int nVars ) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddCombination(dd, VarValues, nVars); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddCombination */ + +/**Function******************************************************************** + + Synopsis [Generates a random set of combinations.] + + Description [Given a set of n elements, each of which is encoded using one + ZDD variable, this function generates a random set of k subsets + (combinations of elements) with density d. Assumes that k and n + are positive integers. Returns NULL if density is less than 0.0 + or more than 1.0.] + + SideEffects [Allocates new ZDD variables if their current number is less than n.] + + SeeAlso [] + +******************************************************************************/ +DdNode* Extra_zddRandomSet( + DdManager * dd, /* the DD manager */ + int n, /* the number of elements */ + int k, /* the number of combinations (subsets) */ + double d) /* average density of elements in combinations */ +{ + DdNode *Result, *TempComb, *Aux; + int c, v, Limit, *VarValues; + + /* sanity check the parameters */ + if ( n <= 0 || k <= 0 || d < 0.0 || d > 1.0 ) + return NULL; + + /* allocate temporary storage for variable values */ + VarValues = ABC_ALLOC( int, n ); + if (VarValues == NULL) + { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + + /* start the new set */ + Result = dd->zero; + Cudd_Ref( Result ); + + /* seed random number generator */ + Cudd_Srandom( time(NULL) ); +// Cudd_Srandom( 4 ); + /* determine the limit below which var belongs to the combination */ + Limit = (int)(d * 2147483561.0); + + /* add combinations one by one */ + for ( c = 0; c < k; c++ ) + { + for ( v = 0; v < n; v++ ) + if ( Cudd_Random() <= Limit ) + VarValues[v] = 1; + else + VarValues[v] = 0; + + TempComb = Extra_zddCombination( dd, VarValues, n ); + Cudd_Ref( TempComb ); + + /* make sure that this combination is not already in the set */ + if ( c ) + { /* at least one combination is already included */ + + Aux = Cudd_zddDiff( dd, Result, TempComb ); + Cudd_Ref( Aux ); + if ( Aux != Result ) + { + Cudd_RecursiveDerefZdd( dd, Aux ); + Cudd_RecursiveDerefZdd( dd, TempComb ); + c--; + continue; + } + else + { /* Aux is the same node as Result */ + Cudd_Deref( Aux ); + } + } + + Result = Cudd_zddUnion( dd, Aux = Result, TempComb ); + Cudd_Ref( Result ); + Cudd_RecursiveDerefZdd( dd, Aux ); + Cudd_RecursiveDerefZdd( dd, TempComb ); + } + + ABC_FREE( VarValues ); + Cudd_Deref( Result ); + return Result; + +} /* end of Extra_zddRandomSet */ + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Extra_ZddTest() +{ + int N = 64; + int K0 = 1000; + int i, Size; + DdManager * dd = Cudd_Init( 0, 32, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + for ( i = 1; i <= 10; i++ ) + { + int K = K0 * i; + DdNode * zRandSet = Extra_zddRandomSet( dd, N, K, 0.5 ); Cudd_Ref(zRandSet); + Size = Cudd_zddDagSize(zRandSet); + //Cudd_zddPrintMinterm( dd, zRandSet ); + printf( "N = %5d K = %5d BddSize = %6d MemBdd = %8.3f MB MemBit = %8.3f MB Ratio = %8.3f %%\n", + N, K, Size, 20.0*Size/(1<<20), 0.125 * N * K /(1<<20), 100.0*(0.125 * N * K)/(20.0*Size) ); + Cudd_RecursiveDerefZdd( dd, zRandSet ); + } + Cudd_Quit(dd); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From bc010af4be920199d7f1e0bfe4a6d70dcbca042b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 17 Feb 2017 14:10:32 -0800 Subject: Promising modification of the generalization procedure in 'pdr'. --- src/proof/pdr/pdrCore.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c index efb4154f..501f9be6 100644 --- a/src/proof/pdr/pdrCore.c +++ b/src/proof/pdr/pdrCore.c @@ -637,6 +637,16 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP Pdr_SetDeref( pCubeTmp ); assert( pCubeMin->nLits > 0 ); + // assume the minimized cube + if ( p->pPars->fSimpleGeneral ) + { + sat_solver * pSat = Pdr_ManFetchSolver( p, k ); + Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCubeMin, 1, 0 ); + int RetValue1 = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntArray(vLits1) + Vec_IntSize(vLits1) ); + assert( RetValue1 == 1 ); + sat_solver_compress( pSat ); + } + // get the ordering by decreasing priority pOrder = Pdr_ManSortByPriority( p, pCubeMin ); j--; -- cgit v1.2.3 From 1d3ff5338a0c98f2319578b25f9695c3a326dd9d Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Fri, 17 Feb 2017 18:55:00 -0800 Subject: added ipdr --- src/base/abci/abc.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 52684f8c..af79a66d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -333,6 +333,7 @@ static int Abc_CommandBm2 ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSaucy ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTestCex ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandIPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); #ifdef ABC_USE_CUDD static int Abc_CommandReconcile ( Abc_Frame_t * pAbc, int argc, char ** argv ); #endif @@ -983,6 +984,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); Cmd_CommandAdd( pAbc, "Verification", "testcex", Abc_CommandTestCex, 0 ); Cmd_CommandAdd( pAbc, "Verification", "pdr", Abc_CommandPdr, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "ipdr", Abc_CommandIPdr, 0 ); #ifdef ABC_USE_CUDD Cmd_CommandAdd( pAbc, "Verification", "reconcile", Abc_CommandReconcile, 1 ); #endif @@ -26415,6 +26417,272 @@ usage: + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + Pdr_Par_t Pars, * pPars = &Pars; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + int c; + Pdr_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) + { + switch ( c ) + { + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRecycle = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRecycle < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nFrameMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nFrameMax < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nConfLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nConfLimit < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nConfGenLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nConfGenLimit < 0 ) + goto usage; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRestLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRestLimit < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOut = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOut < 0 ) + goto usage; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOutOne = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOutOne < 0 ) + goto usage; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOutGap = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOutGap < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRandomSeed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRandomSeed < 0 ) + goto usage; + break; + case 'a': + pPars->fSolveAll ^= 1; + break; + case 'x': + pPars->fStoreCex ^= 1; + break; + case 'r': + pPars->fTwoRounds ^= 1; + break; + case 'm': + pPars->fMonoCnf ^= 1; + break; + case 'u': + pPars->fNewXSim ^= 1; + break; + case 'y': + pPars->fFlopPrio ^= 1; + break; + case 'f': + pPars->fFlopOrder ^= 1; + break; + case 's': + pPars->fShortest ^= 1; + break; + case 'i': + pPars->fShiftStart ^= 1; + break; + case 'p': + pPars->fReuseProofOblig ^= 1; + break; + case 'd': + pPars->fDumpInv ^= 1; + break; + case 'e': + pPars->fUseSupp ^= 1; + break; + case 'g': + pPars->fSkipGeneral ^= 1; + break; + case 'j': + pPars->fSimpleGeneral ^= 1; + break; + case 'o': + pPars->fUsePropOut ^= 1; + break; + case 'n': + pPars->fSkipDown ^= 1; + break; + case 'c': + pPars->fCtgs ^= 1; + break; + case 't': + pPars->fUseAbs ^= 1; + break; + case 'k': + pPars->fUseSimpleRef ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fVeryVerbose ^= 1; + break; + case 'z': + pPars->fNotVerbose ^= 1; + break; + case 'h': + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( -2, "There is no current network.\n"); + return 0; + } + if ( Abc_NtkLatchNum(pNtk) == 0 ) + { + Abc_Print( 0, "The current network is combinational.\n"); + return 0; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + Abc_Print( -2, "The current network is not an AIG (run \"strash\").\n"); + return 0; + } + // run the procedure + pPars->fUseBridge = pAbc->fBridgeMode; + pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); + pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; + Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); + if ( pNtk->vSeqModelVec ) + Abc_FrameReplaceCexVec( pAbc, &pNtk->vSeqModelVec ); + else + Abc_FrameReplaceCex( pAbc, &pNtk->pSeqModel ); + return 0; + +usage: + Abc_Print( -2, "usage: ipdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); + Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); + Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); + Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); + Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); + Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); + Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); + Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); + Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); + Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); + Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); + Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); + Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); + Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); + Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); + Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); + Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); + Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); + Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); + Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); + Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); + Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); + Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); + Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); + Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n\n"); + Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); + Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); + Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); + Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); + + + return 1; } -- cgit v1.2.3 From 196b3591830e9fbe0877411b8053233c11d0f4ce Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 09:51:54 -0800 Subject: started pdrIncr.c --- src/base/abci/abc.c | 2 ++ src/proof/pdr/module.make | 3 ++- src/proof/pdr/pdrIncr.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/proof/pdr/pdrIncr.c (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index af79a66d..0e3a1d3a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26434,6 +26434,7 @@ usage: int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + extern int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); Pdr_Par_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c; @@ -26629,6 +26630,7 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // run the procedure + IPdr_ManSolve( pNtk, pPars ); pPars->fUseBridge = pAbc->fBridgeMode; pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; diff --git a/src/proof/pdr/module.make b/src/proof/pdr/module.make index 2967aeb8..4c177a21 100644 --- a/src/proof/pdr/module.make +++ b/src/proof/pdr/module.make @@ -5,4 +5,5 @@ SRC += src/proof/pdr/pdrCnf.c \ src/proof/pdr/pdrSat.c \ src/proof/pdr/pdrTsim.c \ src/proof/pdr/pdrTsim2.c \ - src/proof/pdr/pdrUtil.c + src/proof/pdr/pdrUtil.c \ + src/proof/pdr/pdrIncr.c diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c new file mode 100644 index 00000000..a2329870 --- /dev/null +++ b/src/proof/pdr/pdrIncr.c @@ -0,0 +1,56 @@ +/**CFile**************************************************************** + + FileName [pdrIncr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Property driven reachability.] + + Synopsis [PDR with incremental solving.] + + Author [Yen-Sheng Ho, Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - Feb. 17, 2017.] + + Revision [$Id: pdrIncr.c$] + +***********************************************************************/ + +#include "pdrInt.h" +#include "base/main/main.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ) +{ + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END -- cgit v1.2.3 From 91a0a0fc3b5dfd5aa71122106dbdacf6268e51fb Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 10:28:16 -0800 Subject: copied pdr_mansolve --- src/base/abci/abc.c | 3 +-- src/proof/pdr/pdrIncr.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0e3a1d3a..f12e3727 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26630,9 +26630,8 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // run the procedure - IPdr_ManSolve( pNtk, pPars ); pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); + pAbc->Status = IPdr_ManSolve( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); if ( pNtk->vSeqModelVec ) diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index a2329870..2276384c 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -27,6 +27,7 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -45,7 +46,45 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ) { - return 0; + int RetValue = -1; + abctime clk = Abc_Clock(); + Aig_Man_t * pMan; + pMan = Abc_NtkToDar( pNtk, 0, 1 ); + + RetValue = Pdr_ManSolve( pMan, pPars ); + + if ( RetValue == 1 ) + Abc_Print( 1, "Property proved. " ); + else + { + if ( RetValue == 0 ) + { + if ( pMan->pSeqModel == NULL ) + Abc_Print( 1, "Counter-example is not available.\n" ); + else + { + Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", pMan->pSeqModel->iPo, pNtk->pName, pMan->pSeqModel->iFrame ); + if ( !Saig_ManVerifyCex( pMan, pMan->pSeqModel ) ) + Abc_Print( 1, "Counter-example verification has FAILED.\n" ); + } + } + else if ( RetValue == -1 ) + Abc_Print( 1, "Property UNDECIDED. " ); + else + assert( 0 ); + } + ABC_PRT( "Time", Abc_Clock() - clk ); + + + ABC_FREE( pNtk->pSeqModel ); + pNtk->pSeqModel = pMan->pSeqModel; + pMan->pSeqModel = NULL; + if ( pNtk->vSeqModelVec ) + Vec_PtrFreeFree( pNtk->vSeqModelVec ); + pNtk->vSeqModelVec = pMan->vSeqModelVec; + pMan->vSeqModelVec = NULL; + Aig_ManStop( pMan ); + return RetValue; } //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From b93a80512941e5039e48a7b74e625d7d6f9f720a Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 12:43:03 -0800 Subject: copied some functions from pdr --- src/base/abci/abc.c | 4 +- src/proof/pdr/pdrIncr.c | 429 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 429 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f12e3727..0645c6e3 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26434,7 +26434,7 @@ usage: int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - extern int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + extern int Abc_NtkDarIPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); Pdr_Par_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c; @@ -26631,7 +26631,7 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) } // run the procedure pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = IPdr_ManSolve( pNtk, pPars ); + pAbc->Status = Abc_NtkDarIPdr( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); if ( pNtk->vSeqModelVec ) diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 2276384c..d33b45ac 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -28,6 +28,11 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); +extern int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube ); +extern int Pdr_ManPushClauses( Pdr_Man_t * p ); +extern int Gia_ManToBridgeAbort( FILE * pFile, int Size, unsigned char * pBuffer ); +extern int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex, int iPoProved ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -44,14 +49,434 @@ extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); SeeAlso [] ***********************************************************************/ -int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ) +int IPdr_ManSolveInt( Pdr_Man_t * p ) +{ + int fPrintClauses = 0; + Pdr_Set_t * pCube = NULL; + Aig_Obj_t * pObj; + Abc_Cex_t * pCexNew; + int iFrame, RetValue = -1; + int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) ); + abctime clkStart = Abc_Clock(), clkOne = 0; + p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0; + assert( Vec_PtrSize(p->vSolvers) == 0 ); + // in the multi-output mode, mark trivial POs (those fed by const0) as solved + if ( p->pPars->fSolveAll ) + Saig_ManForEachPo( p->pAig, pObj, iFrame ) + if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) ) + { + Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat + p->pPars->nProveOuts++; + if ( p->pPars->fUseBridge ) + Gia_ManToBridgeResult( stdout, 1, NULL, iFrame ); + } + // create the first timeframe + p->pPars->timeLastSolved = Abc_Clock(); + Pdr_ManCreateSolver( p, (iFrame = 0) ); + while ( 1 ) + { + int fRefined = 0; + if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 1 ) + { +// int i, Prio; + assert( p->vAbsFlops == NULL ); + p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) ); + p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) ); + p->vMapPpi2Ff = Vec_IntAlloc( 100 ); +// Vec_IntForEachEntry( p->vPrio, Prio, i ) +// if ( Prio >> p->nPrioShift ) +// Vec_IntWriteEntry( p->vAbsFlops, i, 1 ); + } + //if ( p->pPars->fUseAbs && p->vAbsFlops ) + // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); + p->nFrames = iFrame; + assert( iFrame == Vec_PtrSize(p->vSolvers)-1 ); + p->iUseFrame = Abc_MaxInt(iFrame, 1); + Saig_ManForEachPo( p->pAig, pObj, p->iOutCur ) + { + // skip disproved outputs + if ( p->vCexes && Vec_PtrEntry(p->vCexes, p->iOutCur) ) + continue; + // skip output whose time has run out + if ( p->pTime4Outs && p->pTime4Outs[p->iOutCur] == 0 ) + continue; + // check if the output is trivially solved + if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) ) + continue; + // check if the output is trivially solved + if ( Aig_ObjChild0(pObj) == Aig_ManConst1(p->pAig) ) + { + if ( !p->pPars->fSolveAll ) + { + pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ); + p->pAig->pSeqModel = pCexNew; + return 0; // SAT + } + pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1; + p->pPars->nFailOuts++; + if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 ); + if ( !p->pPars->fNotVerbose ) + Abc_Print( 1, "Output %*d was trivially asserted in frame %2d (solved %*d out of %*d outputs).\n", + nOutDigits, p->iOutCur, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); + assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ); + if ( p->pPars->fUseBridge ) + Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo ); + Vec_PtrWriteEntry( p->vCexes, p->iOutCur, pCexNew ); + if ( p->pPars->pFuncOnFail && p->pPars->pFuncOnFail(p->iOutCur, p->pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, p->iOutCur) : NULL) ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( p->pPars->nFailOuts + p->pPars->nDropOuts == Saig_ManPoNum(p->pAig) ) + return p->pPars->nFailOuts ? 0 : -1; // SAT or UNDEC + p->pPars->timeLastSolved = Abc_Clock(); + continue; + } + // try to solve this output + if ( p->pTime4Outs ) + { + assert( p->pTime4Outs[p->iOutCur] > 0 ); + clkOne = Abc_Clock(); + p->timeToStopOne = p->pTime4Outs[p->iOutCur] + Abc_Clock(); + } + while ( 1 ) + { + if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0, 1 ); + if ( RetValue == 1 ) + break; + if ( RetValue == -1 ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( p->timeToStop && Abc_Clock() > p->timeToStop ) + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne ) + { + Pdr_QueueClean( p ); + pCube = NULL; + break; // keep solving + } + else if ( p->pPars->nConfLimit ) + Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame ); + else if ( p->pPars->fVerbose ) + Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( RetValue == 0 ) + { + RetValue = Pdr_ManBlockCube( p, pCube ); + if ( RetValue == -1 ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( p->timeToStop && Abc_Clock() > p->timeToStop ) + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne ) + { + Pdr_QueueClean( p ); + pCube = NULL; + break; // keep solving + } + else if ( p->pPars->nConfLimit ) + Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame ); + else if ( p->pPars->fVerbose ) + Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( RetValue == 0 ) + { + if ( fPrintClauses ) + { + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); + Pdr_ManPrintClauses( p, 0 ); + } + if ( p->pPars->fVerbose && !p->pPars->fUseAbs ) + Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart ); + p->pPars->iFrame = iFrame; + if ( !p->pPars->fSolveAll ) + { + abctime clk = Abc_Clock(); + Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p); + p->tAbs += Abc_Clock() - clk; + if ( pCex == NULL ) + { + assert( p->pPars->fUseAbs ); + Pdr_QueueClean( p ); + pCube = NULL; + fRefined = 1; + break; // keep solving + } + p->pAig->pSeqModel = pCex; + return 0; // SAT + } + p->pPars->nFailOuts++; + pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Pdr_ManDeriveCex(p) : (Abc_Cex_t *)(ABC_PTRINT_T)1; + if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 ); + assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ); + if ( p->pPars->fUseBridge ) + Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo ); + Vec_PtrWriteEntry( p->vCexes, p->iOutCur, pCexNew ); + if ( p->pPars->pFuncOnFail && p->pPars->pFuncOnFail(p->iOutCur, p->pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, p->iOutCur) : NULL) ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( !p->pPars->fNotVerbose ) + Abc_Print( 1, "Output %*d was asserted in frame %2d (%2d) (solved %*d out of %*d outputs).\n", + nOutDigits, p->iOutCur, iFrame, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) ); + if ( p->pPars->nFailOuts == Saig_ManPoNum(p->pAig) ) + return 0; // all SAT + Pdr_QueueClean( p ); + pCube = NULL; + break; // keep solving + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart ); + } + } + if ( fRefined ) + break; + if ( p->pTime4Outs ) + { + abctime timeSince = Abc_Clock() - clkOne; + assert( p->pTime4Outs[p->iOutCur] > 0 ); + p->pTime4Outs[p->iOutCur] = (p->pTime4Outs[p->iOutCur] > timeSince) ? p->pTime4Outs[p->iOutCur] - timeSince : 0; + if ( p->pTime4Outs[p->iOutCur] == 0 && Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ) // undecided + { + p->pPars->nDropOuts++; + if ( p->pPars->vOutMap ) + Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, -1 ); + if ( !p->pPars->fNotVerbose ) + Abc_Print( 1, "Timing out on output %*d in frame %d.\n", nOutDigits, p->iOutCur, iFrame ); + } + p->timeToStopOne = 0; + } + } + if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined ) + { + int i, Used; + Vec_IntForEachEntry( p->vAbsFlops, Used, i ) + if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 ) + Vec_IntWriteEntry( p->vAbsFlops, i, 0 ); + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart ); + if ( fRefined ) + continue; + //if ( p->pPars->fUseAbs && p->vAbsFlops ) + // printf( "Finished frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) ); + // open a new timeframe + p->nQueLim = p->pPars->nRestLimit; + assert( pCube == NULL ); + Pdr_ManSetPropertyOutput( p, iFrame ); + Pdr_ManCreateSolver( p, ++iFrame ); + if ( fPrintClauses ) + { + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); + Pdr_ManPrintClauses( p, 0 ); + } + // push clauses into this timeframe + RetValue = Pdr_ManPushClauses( p ); + if ( RetValue == -1 ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + { + if ( p->timeToStop && Abc_Clock() > p->timeToStop ) + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + else + Abc_Print( 1, "Reached conflict limit (%d) in frame.\n", p->pPars->nConfLimit, iFrame ); + } + p->pPars->iFrame = iFrame; + return -1; + } + if ( RetValue ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Pdr_ManReportInvariant( p ); + if ( !p->pPars->fSilent ) + Pdr_ManVerifyInvariant( p ); + p->pPars->iFrame = iFrame; + // count the number of UNSAT outputs + p->pPars->nProveOuts = Saig_ManPoNum(p->pAig) - p->pPars->nFailOuts - p->pPars->nDropOuts; + // convert previously 'unknown' into 'unsat' + if ( p->pPars->vOutMap ) + for ( iFrame = 0; iFrame < Saig_ManPoNum(p->pAig); iFrame++ ) + if ( Vec_IntEntry(p->pPars->vOutMap, iFrame) == -2 ) // unknown + { + Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat + if ( p->pPars->fUseBridge ) + Gia_ManToBridgeResult( stdout, 1, NULL, iFrame ); + } + if ( p->pPars->nProveOuts == Saig_ManPoNum(p->pAig) ) + return 1; // UNSAT + if ( p->pPars->nFailOuts > 0 ) + return 0; // SAT + return -1; + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart ); + + // check termination + if ( p->pPars->pFuncStop && p->pPars->pFuncStop(p->pPars->RunId) ) + { + p->pPars->iFrame = iFrame; + return -1; + } + if ( p->timeToStop && Abc_Clock() > p->timeToStop ) + { + if ( fPrintClauses ) + { + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); + Pdr_ManPrintClauses( p, 0 ); + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC ) + { + if ( fPrintClauses ) + { + Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame ); + Pdr_ManPrintClauses( p, 0 ); + } + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame ); + p->pPars->iFrame = iFrame; + return -1; + } + if ( p->pPars->nFrameMax && iFrame >= p->pPars->nFrameMax ) + { + if ( p->pPars->fVerbose ) + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + if ( !p->pPars->fSilent ) + Abc_Print( 1, "Reached limit on the number of timeframes (%d).\n", p->pPars->nFrameMax ); + p->pPars->iFrame = iFrame; + return -1; + } + } + assert( 0 ); + return -1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) +{ + Pdr_Man_t * p; + int k, RetValue; + abctime clk = Abc_Clock(); + if ( pPars->nTimeOutOne && !pPars->fSolveAll ) + pPars->nTimeOutOne = 0; + if ( pPars->nTimeOutOne && pPars->nTimeOut == 0 ) + pPars->nTimeOut = pPars->nTimeOutOne * Saig_ManPoNum(pAig) / 1000 + (int)((pPars->nTimeOutOne * Saig_ManPoNum(pAig) % 1000) > 0); + if ( pPars->fVerbose ) + { +// Abc_Print( 1, "Running PDR by Niklas Een (aka IC3 by Aaron Bradley) with these parameters:\n" ); + Abc_Print( 1, "VarMax = %d. FrameMax = %d. QueMax = %d. TimeMax = %d. ", + pPars->nRecycle, + pPars->nFrameMax, + pPars->nRestLimit, + pPars->nTimeOut ); + Abc_Print( 1, "MonoCNF = %s. SkipGen = %s. SolveAll = %s.\n", + pPars->fMonoCnf ? "yes" : "no", + pPars->fSkipGeneral ? "yes" : "no", + pPars->fSolveAll ? "yes" : "no" ); + } + ABC_FREE( pAig->pSeqModel ); + p = Pdr_ManStart( pAig, pPars, NULL ); + RetValue = IPdr_ManSolveInt( p ); + if ( RetValue == 0 ) + assert( pAig->pSeqModel != NULL || p->vCexes != NULL ); + if ( p->vCexes ) + { + assert( p->pAig->vSeqModelVec == NULL ); + p->pAig->vSeqModelVec = p->vCexes; + p->vCexes = NULL; + } + if ( p->pPars->fDumpInv ) + { + char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); + Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); + } + else if ( RetValue == 1 ) + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); + p->tTotal += Abc_Clock() - clk; + Pdr_ManStop( p ); + pPars->iFrame--; + // convert all -2 (unknown) entries into -1 (undec) + if ( pPars->vOutMap ) + for ( k = 0; k < Saig_ManPoNum(pAig); k++ ) + if ( Vec_IntEntry(pPars->vOutMap, k) == -2 ) // unknown + Vec_IntWriteEntry( pPars->vOutMap, k, -1 ); // undec + if ( pPars->fUseBridge ) + Gia_ManToBridgeAbort( stdout, 7, (unsigned char *)"timeout" ); + return RetValue; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkDarIPdr ( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ) { int RetValue = -1; abctime clk = Abc_Clock(); Aig_Man_t * pMan; pMan = Abc_NtkToDar( pNtk, 0, 1 ); - RetValue = Pdr_ManSolve( pMan, pPars ); + RetValue = IPdr_ManSolve( pMan, pPars ); if ( RetValue == 1 ) Abc_Print( 1, "Property proved. " ); -- cgit v1.2.3 From 429f52ce15d1c10e71d98d8c1388b93809a425e1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 14:20:10 -0800 Subject: Experiments with SAT sweeping. --- src/aig/gia/gia.h | 14 +- src/aig/gia/giaEquiv.c | 2 +- src/aig/gia/giaUtil.c | 19 + src/base/wlc/wlcSim.c | 22 +- src/misc/util/utilTruth.h | 16 + src/proof/cec/cecSat.c | 862 ++++++++++++++++++++++++++++++++++++++++++++ src/proof/cec/module.make | 1 + src/sat/bmc/bmcGen.c | 18 +- src/sat/satoko/satoko.h | 2 +- src/sat/satoko/solver_api.c | 4 +- 10 files changed, 932 insertions(+), 28 deletions(-) create mode 100644 src/proof/cec/cecSat.c (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index c183432a..10804850 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -194,6 +194,7 @@ struct Gia_Man_t_ int MappedDelay; // delay after mapping // bit-parallel simulation int iPatsPi; + int nSimWords; Vec_Wrd_t * vSims; Vec_Wrd_t * vSimsPi; Vec_Int_t * vClassOld; @@ -982,24 +983,26 @@ static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p static inline int Gia_ObjIsConst( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == 0; } static inline int Gia_ObjIsHead( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0; } -static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; } -static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; } +static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) <= 0; } +static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) <= 0; } static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; } static inline int Gia_ObjHasSameRepr( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjRepr(p, i) == Gia_ObjRepr(p, k) && Gia_ObjRepr(p, i) != GIA_VOID) : Gia_ObjRepr(p, k) == 0; } static inline int Gia_ObjIsFailedPair( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjFailed(p, i) || Gia_ObjFailed(p, k)) : Gia_ObjFailed(p, k); } -static inline int Gia_ClassIsPair( Gia_Man_t * p, int i ) { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) == 0; } +static inline int Gia_ClassIsPair( Gia_Man_t * p, int i ) { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) <= 0; } static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { assert( Gia_ClassIsPair(p,i) ); Gia_ObjSetRepr(p, Gia_ObjNext(p, i), GIA_VOID); Gia_ObjSetNext(p, i, 0); } #define Gia_ManForEachConst( p, i ) \ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else #define Gia_ManForEachClass( p, i ) \ for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else +#define Gia_ManForEachClass0( p, i ) \ + for ( i = 0; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else #define Gia_ManForEachClassReverse( p, i ) \ for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else #define Gia_ClassForEachObj( p, i, iObj ) \ - for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) ) + for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) ) #define Gia_ClassForEachObj1( p, i, iObj ) \ - for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) ) + for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) static inline int Gia_ObjFoffsetId( Gia_Man_t * p, int Id ) { return Vec_IntEntry( p->vFanout, Id ); } @@ -1585,6 +1588,7 @@ extern void Gia_ManSwapPos( Gia_Man_t * p, int i ); extern Vec_Int_t * Gia_ManSaveValue( Gia_Man_t * p ); extern void Gia_ManLoadValue( Gia_Man_t * p, Vec_Int_t * vValues ); extern Vec_Int_t * Gia_ManFirstFanouts( Gia_Man_t * p ); +extern void Gia_ManDetectMuxes( Gia_Man_t * p ); /*=== giaCTas.c ===========================================================*/ typedef struct Tas_Man_t_ Tas_Man_t; diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 1b0bce07..f41db898 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -485,7 +485,7 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ) if ( fVerbose ) { // int Ent; - Abc_Print( 1, "Const0 = " ); + Abc_Print( 1, "Const0 (%d) = ", Counter0 ); Gia_ManForEachConst( p, i ) Abc_Print( 1, "%d ", i ); Abc_Print( 1, "\n" ); diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index c7af642e..d64c53fa 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2050,6 +2050,25 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName ) Vec_WrdFree( vTruths ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDetectMuxes( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pNodeT, * pNodeE; int i; + Gia_ManForEachObj( p, pObj, i ); + if ( Gia_ObjIsAnd(pObj) && Gia_ObjRecognizeMux(pObj, &pNodeT, &pNodeE) ) + pObj->fMark0 = 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcSim.c b/src/base/wlc/wlcSim.c index 20ac8c61..e2fcd1f8 100644 --- a/src/base/wlc/wlcSim.c +++ b/src/base/wlc/wlcSim.c @@ -43,13 +43,13 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj ) { - return Vec_WrdEntryP( p->vSims, p->iPatsPi * iObj ); + return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); } static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj ) { int w; word * pSim = Wlc_ObjSim( p, iObj ); - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = Gia_ManRandomW( 0 ); } static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj ) @@ -57,7 +57,7 @@ static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj ) int w; word * pSimRo = Wlc_ObjSim( p, iObj ); word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimRo[w] = pSimRi[w]; } static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj ) @@ -67,10 +67,10 @@ static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj ) word * pSimCo = Wlc_ObjSim( p, iObj ); word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); if ( Gia_ObjFaninC0(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimCo[w] = ~pSimDri[w]; else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimCo[w] = pSimDri[w]; } static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj ) @@ -81,16 +81,16 @@ static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj ) word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = ~pSim0[w] & ~pSim1[w]; else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = ~pSim0[w] & pSim1[w]; else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = pSim0[w] & ~pSim1[w]; else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = pSim0[w] & pSim1[w]; } @@ -135,7 +135,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int // allocate simulation info for one timeframe Vec_WrdFreeP( &pGia->vSims ); pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords ); - pGia->iPatsPi = nWords; + pGia->nSimWords = nWords; // allocate resulting simulation info vRes = Vec_PtrAlloc( Vec_IntSize(vNodes) ); Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i ) @@ -188,7 +188,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int printf( "Replaced %d dangling internal bits with constant 0.\n", Counter ); } Vec_WrdFreeP( &pGia->vSims ); - pGia->iPatsPi = 0; + pGia->nSimWords = 0; Gia_ManStop( pGia ); return vRes; } diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index d77ed64d..e04ffbc9 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -1631,6 +1631,14 @@ static inline int Abc_TtFindFirstBit( word * pIn, int nVars ) return 64*w + Abc_Tt6FirstBit(pIn[w]); return -1; } +static inline int Abc_TtFindFirstBit2( word * pIn, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( pIn[w] ) + return 64*w + Abc_Tt6FirstBit(pIn[w]); + return -1; +} static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars ) { int w, nWords = Abc_TtWordNum(nVars); @@ -1639,6 +1647,14 @@ static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars ) return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]); return -1; } +static inline int Abc_TtFindFirstDiffBit2( word * pIn1, word * pIn2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( pIn1[w] ^ pIn2[w] ) + return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]); + return -1; +} static inline int Abc_TtFindFirstZero( word * pIn, int nVars ) { int w, nWords = Abc_TtWordNum(nVars); diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c new file mode 100644 index 00000000..9e85e49d --- /dev/null +++ b/src/proof/cec/cecSat.c @@ -0,0 +1,862 @@ +/**CFile**************************************************************** + + FileName [cecSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Detection of structural isomorphism.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig/gia/gia.h" +#include "misc/util/utilTruth.h" +#include "sat/satoko/satoko.h" +#include "sat/satoko/solver.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// sweeping manager +typedef struct Cec2_Par_t_ Cec2_Par_t; +struct Cec2_Par_t_ +{ + int nSimWords; // simulation words + int nSimRounds; // simulation rounds + int nConfLimit; // SAT solver conflict limit + int fIsMiter; // this is a miter + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + +// SAT solving manager +typedef struct Cec2_Man_t_ Cec2_Man_t; +struct Cec2_Man_t_ +{ + Cec2_Par_t * pPars; // parameters + Gia_Man_t * pAig; // user's AIG + Gia_Man_t * pNew; // internal AIG + // SAT solving + satoko_t * pSat; // SAT solver + Vec_Ptr_t * vFrontier; // CNF construction + Vec_Ptr_t * vFanins; // CNF construction + Vec_Wrd_t * vSims; // CI simulation info + Vec_Int_t * vNodesNew; // nodes + Vec_Int_t * vObjSatPairs; // nodes +}; + +static inline int Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); } +static inline int Cec2_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec2_ObjSatId(p, pObj) == -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), Num); return Num; } +static inline void Cec2_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Cec2_ObjSatId(p, pObj) != -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), -1); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets parameter defaults.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_SetDefaultParams( Cec2_Par_t * p ) +{ + memset( p, 0, sizeof(Cec2_Par_t) ); + p->nSimWords = 8; // simulation words + p->nSimRounds = 4; // simulation rounds + p->nConfLimit = 1000; // conflict limit at a node + p->fIsMiter = 0; // this is a miter + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 1; // verbose stats +} + +/**Function************************************************************* + + Synopsis [Adds clauses to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, satoko_t * pSat ) +{ + int fPolarFlip = 0; + Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; + int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; + + assert( !Gia_IsComplement( pNode ) ); + assert( pNode->fMark0 ); + // get nodes (I = if, T = then, E = else) + pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); + // get the variable numbers + VarF = Cec2_ObjSatId(p, pNode); + VarI = Cec2_ObjSatId(p, pNodeI); + VarT = Cec2_ObjSatId(p, Gia_Regular(pNodeT)); + VarE = Cec2_ObjSatId(p, Gia_Regular(pNodeE)); + // get the complementation flags + fCompT = Gia_IsComplement(pNodeT); + fCompE = Gia_IsComplement(pNodeE); + + // f = ITE(i, t, e) + + // i' + t' + f + // i' + t + f' + // i + e' + f + // i + e + f' + + // create four clauses + pLits[0] = Abc_Var2Lit(VarI, 1); + pLits[1] = Abc_Var2Lit(VarT, 1^fCompT); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 1); + pLits[1] = Abc_Var2Lit(VarT, 0^fCompT); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 0); + pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 0); + pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + + // two additional clauses + // t' & e' -> f' + // t & e -> f + + // t + e + f' + // t' + e' + f + + if ( VarT == VarE ) + { +// assert( fCompT == !fCompE ); + return; + } + + pLits[0] = Abc_Var2Lit(VarT, 0^fCompT); + pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarT, 1^fCompT); + pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = satoko_add_clause( pSat, pLits, 3 ); + assert( RetValue ); +} +void Cec2_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, satoko_t * pSat ) +{ + int fPolarFlip = 0; + Gia_Obj_t * pFanin; + int * pLits, nLits, RetValue, i; + assert( !Gia_IsComplement(pNode) ); + assert( Gia_ObjIsAnd( pNode ) ); + // create storage for literals + nLits = Vec_PtrSize(vSuper) + 1; + pLits = ABC_ALLOC( int, nLits ); + // suppose AND-gate is A & B = C + // add !A => !C or A + !C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[0] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin)); + pLits[1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 1); + if ( fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( pNode->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + } + RetValue = satoko_add_clause( pSat, pLits, 2 ); + assert( RetValue ); + } + // add A & B => C or !A + !B + C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[i] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); + if ( fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = Abc_LitNot( pLits[i] ); + } + } + pLits[nLits-1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 0); + if ( fPolarFlip ) + { + if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] ); + } + RetValue = satoko_add_clause( pSat, pLits, nLits ); + assert( RetValue ); + ABC_FREE( pLits ); +} + +/**Function************************************************************* + + Synopsis [Adds clauses and returns CNF variable of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) || + (!fFirst && Gia_ObjValue(pObj) > 1) || + (fUseMuxes && pObj->fMark0) ) + { + Vec_PtrPushUnique( vSuper, pObj ); + return; + } + // go through the branches + Cec2_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes ); + Cec2_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes ); +} +void Cec2_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsCi(pObj) ); + Vec_PtrClear( vSuper ); + Cec2_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes ); +} +void Cec2_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, satoko_t * pSat ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsConst0(pObj) ); + if ( Cec2_ObjSatId(p, pObj) >= 0 ) + return; + assert( Cec2_ObjSatId(p, pObj) == -1 ); + Cec2_ObjSetSatId( p, pObj, satoko_add_variable(pSat, 0) ); + if ( Gia_ObjIsAnd(pObj) ) + Vec_PtrPush( vFrontier, pObj ); +} +int Cec2_ObjGetCnfVar( Cec2_Man_t * p, int iObj ) +{ + Gia_Obj_t * pNode, * pFanin; + Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj); + int i, k, fUseMuxes = 1; + // quit if CNF is ready + if ( Cec2_ObjSatId(p->pNew,pObj) >= 0 ) + return Cec2_ObjSatId(p->pNew,pObj); + assert( iObj > 0 ); + if ( Gia_ObjIsCi(pObj) ) + return Cec2_ObjSetSatId( p->pNew, pObj, satoko_add_variable(p->pSat, 0) ); + assert( Gia_ObjIsAnd(pObj) ); + // start the frontier + Vec_PtrClear( p->vFrontier ); + Cec2_ObjAddToFrontier( p->pNew, pObj, p->vFrontier, p->pSat ); + // explore nodes in the frontier + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i ) + { + // create the supergate + assert( Cec2_ObjSatId(p->pNew,pNode) >= 0 ); + if ( fUseMuxes && pNode->fMark0 ) + { + Vec_PtrClear( p->vFanins ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); + Cec2_AddClausesMux( p->pNew, pNode, p->pSat ); + } + else + { + Cec2_CollectSuper( pNode, fUseMuxes, p->vFanins ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); + Cec2_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat ); + } + assert( Vec_PtrSize(p->vFanins) > 1 ); + } + return Cec2_ObjSatId(p->pNew,pObj); +} + + + +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word * Cec2_ObjSim( Gia_Man_t * p, int iObj ) +{ + return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); +} +static inline void Cec2_ObjSimSetPiBit( Gia_Man_t * p, int iObj, int Bit ) +{ + word * pSim = Cec2_ObjSim( p, iObj ); + p->iPatsPi = (p->iPatsPi == 64 * p->nSimWords - 1) ? 1 : p->iPatsPi + 1; + assert( p->iPatsPi > 0 && p->iPatsPi < 64 * p->nSimWords ); + if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit ) + Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi ); +} +static inline void Cec2_ObjSimRo( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSimRo = Cec2_ObjSim( p, iObj ); + word * pSimRi = Cec2_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); + for ( w = 0; w < p->nSimWords; w++ ) + pSimRo[w] = pSimRi[w]; +} +static inline void Cec2_ObjSimCo( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSimCo = Cec2_ObjSim( p, iObj ); + word * pSimDri = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = ~pSimDri[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = pSimDri[w]; +} +static inline void Cec2_ObjSimAnd( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSim = Cec2_ObjSim( p, iObj ); + word * pSim0 = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + word * pSim1 = Cec2_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = ~pSim0[w] & ~pSim1[w]; + else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = ~pSim0[w] & pSim1[w]; + else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = pSim0[w] & ~pSim1[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = pSim0[w] & pSim1[w]; +} +static inline int Cec2_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 ) +{ + int w; + word * pSim0 = Cec2_ObjSim( p, iObj0 ); + word * pSim1 = Cec2_ObjSim( p, iObj1 ); + if ( (pSim0[0] & 1) == (pSim1[0] & 1) ) + { + for ( w = 0; w < p->nSimWords; w++ ) + if ( pSim0[w] != pSim1[w] ) + return 0; + return 1; + } + else + { + for ( w = 0; w < p->nSimWords; w++ ) + if ( pSim0[w] != ~pSim1[w] ) + return 0; + return 1; + } +} +static inline void Cec2_ObjSimPi( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSim = Cec2_ObjSim( p, iObj ); + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = Gia_ManRandomW( 0 ); + pSim[0] <<= 1; +} +void Cec2_ManSimulateCis( Gia_Man_t * p ) +{ + int i, Id; + Gia_ManForEachCiId( p, Id, i ) + Cec2_ObjSimPi( p, Id ); + p->iPatsPi = 1; +} +Abc_Cex_t * Cec2_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat ) +{ + Abc_Cex_t * pCex; + int i, Id; + pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 ); + pCex->iPo = iOut; + if ( iPat == -1 ) + return pCex; + Gia_ManForEachCiId( p, Id, i ) + if ( Abc_InfoHasBit((unsigned *)Cec2_ObjSim(p, Id), iPat) ) + Abc_InfoSetBit( pCex->pData, i ); + return pCex; +} +int Cec2_ManSimulateCos( Gia_Man_t * p ) +{ + int i, Id; + // check outputs and generate CEX if they fail + Gia_ManForEachCoId( p, Id, i ) + { + Cec2_ObjSimCo( p, Id ); + if ( Cec2_ObjSimEqual(p, Id, 0) ) + continue; + p->pCexSeq = Cec2_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec2_ObjSim(p, Id), p->nSimWords) ); + return 0; + } + return 1; +} +void Cec2_ManSaveCis( Gia_Man_t * p ) +{ + int w, i, Id; + assert( p->vSimsPi != NULL ); + for ( w = 0; w < p->nSimWords; w++ ) + Gia_ManForEachCiId( p, Id, i ) + Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] ); +} +void Cec2_ManSimulate( Gia_Man_t * p ) +{ + extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ); + Gia_Obj_t * pObj; int i; + Cec2_ManSaveCis( p ); + Gia_ManForEachAnd( p, pObj, i ) + Cec2_ObjSimAnd( p, i ); + if ( p->pReprs == NULL ) + return; + Gia_ManForEachClass0( p, i ) + Cec2_ManSimClassRefineOne( p, i ); +} +void Cec2_ManSimAlloc( Gia_Man_t * p, int nWords ) +{ + Vec_WrdFreeP( &p->vSims ); + Vec_WrdFreeP( &p->vSimsPi ); + p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); + p->vSimsPi = Vec_WrdAlloc( Gia_ManCiNum(p) * nWords * 4 ); // storage for CI patterns + p->nSimWords = nWords; +} + + +/**Function************************************************************* + + Synopsis [Computes hash key of the simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec2_ManSimHashKey( word * pSim, int nSims, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned uHash = 0, * pSimU = (unsigned *)pSim; + int i, nSimsU = 2 * nSims; + if ( pSimU[0] & 1 ) + for ( i = 0; i < nSimsU; i++ ) + uHash ^= ~pSimU[i] * s_Primes[i & 0xf]; + else + for ( i = 0; i < nSimsU; i++ ) + uHash ^= pSimU[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + + Synopsis [Creating initial equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ) +{ + int iObj, iPrev = iRepr, iPrev2, iRepr2; + Gia_ClassForEachObj1( p, iRepr, iRepr2 ) + if ( Cec2_ObjSimEqual(p, iRepr, iRepr2) ) + iPrev = iRepr2; + else + break; + if ( iRepr2 <= 0 ) // no refinement + return; + // relink remaining nodes of the class + // nodes that are equal to iRepr, remain in the class of iRepr + // nodes that are not equal to iRepr, move to the class of iRepr2 + Gia_ObjSetRepr( p, iRepr2, GIA_VOID ); + iPrev2 = iRepr2; + for ( iObj = Gia_ObjNext(p, iRepr2); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) + { + if ( Cec2_ObjSimEqual(p, iRepr, iObj) ) // remains with iRepr + { + Gia_ObjSetNext( p, iPrev, iObj ); + iPrev = iObj; + } + else // moves to iRepr2 + { + Gia_ObjSetRepr( p, iObj, iRepr2 ); + Gia_ObjSetNext( p, iPrev2, iObj ); + iPrev2 = iObj; + } + } + Gia_ObjSetNext( p, iPrev, -1 ); + Gia_ObjSetNext( p, iPrev2, -1 ); +} +void Cec2_ManCreateClasses( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int nWords = p->nSimWords; + int * pTable, nTableSize, i, Key; + // allocate representation + assert( p->pReprs == NULL ); + p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) ); + // hash each node by its simulation info + nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) ); + pTable = ABC_FALLOC( int, nTableSize ); + Gia_ManForEachObj( p, pObj, i ) + { + p->pReprs[i].iRepr = GIA_VOID; + if ( Gia_ObjIsCo(pObj) ) + continue; + Key = Cec2_ManSimHashKey( Cec2_ObjSim(p, i), nWords, nTableSize ); + assert( Key >= 0 && Key < nTableSize ); + if ( pTable[Key] == -1 ) + pTable[Key] = i; + else + Gia_ObjSetRepr( p, i, pTable[Key] ); + } + // create classes + for ( i = Gia_ManObjNum(p) - 1; i >= 0; i-- ) + { + int iRepr = Gia_ObjRepr(p, i); + if ( iRepr == GIA_VOID ) + continue; + Gia_ObjSetNext( p, i, Gia_ObjNext(p, iRepr) ); + Gia_ObjSetNext( p, iRepr, i ); + } + ABC_FREE( pTable ); + Gia_ManForEachClass0( p, i ) + Cec2_ManSimClassRefineOne( p, i ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) +{ + Cec2_Man_t * p; + Gia_Obj_t * pObj; int i; + assert( Gia_ManRegNum(pAig) == 0 ); + p = ABC_CALLOC( Cec2_Man_t, 1 ); + memset( p, 0, sizeof(Cec2_Man_t) ); + p->pPars = pPars; + p->pAig = pAig; + // create new manager + p->pNew = Gia_ManStart( Gia_ManObjNum(pAig) ); + Gia_ManFillValue( pAig ); + Gia_ManConst0(pAig)->Value = 0; + Gia_ManForEachCi( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi( p->pNew ); + Gia_ManHashAlloc( p->pNew ); + Vec_IntFill( &p->pNew->vCopies, Gia_ManObjNum(p->pNew), -1 ); + // SAT solving + p->pSat = satoko_create(); + p->vFrontier = Vec_PtrAlloc( 1000 ); + p->vFanins = Vec_PtrAlloc( 100 ); + p->vNodesNew = Vec_IntAlloc( 100 ); + p->vObjSatPairs = Vec_IntAlloc( 100 ); + // remember pointer to the solver in the AIG manager + pAig->pData = p->pSat; + return p; +} +void Cec2_ManDestroy( Cec2_Man_t * p ) +{ + Vec_WrdFreeP( &p->pAig->vSims ); + //Vec_WrdFreeP( &p->pAig->vSimsPi ); + Gia_ManCleanMark01( p->pAig ); + satoko_destroy( p->pSat ); + Gia_ManStopP( &p->pNew ); + Vec_PtrFreeP( &p->vFrontier ); + Vec_PtrFreeP( &p->vFanins ); + Vec_IntFreeP( &p->vNodesNew ); + Vec_IntFreeP( &p->vObjSatPairs ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec2_ManCollect_rec( Cec2_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjIsTravIdCurrentId(p->pNew, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p->pNew, iObj); + pObj = Gia_ManObj( p->pNew, iObj ); + if ( Cec2_ObjSatId(p->pNew, pObj) >= 0 ) + Vec_IntPush( p->vNodesNew, iObj ); + if ( !iObj ) + return; + if ( Gia_ObjIsAnd(pObj) ) + { + Cec2_ManCollect_rec( p, Gia_ObjFaninId0(pObj, iObj) ); + Cec2_ManCollect_rec( p, Gia_ObjFaninId1(pObj, iObj) ); + } + else + { + assert( Cec2_ObjSatId(p->pNew, pObj) >= 0 ); + Vec_IntPushTwo( p->vObjSatPairs, Gia_ManCiIdToId(p->pAig, Gia_ObjCioId(pObj)), Cec2_ObjSatId(p->pNew, pObj) ); // SAT var + } +} +int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) +{ + Gia_Obj_t * pObj; + int status, i, iVar0, iVar1; + if (iObj1 < iObj0) + iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0; + assert( iObj0 < iObj1 ); + assert( solver_varnum(p->pSat) == 0 ); + if ( !iObj0 ) + Cec2_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), satoko_add_variable(p->pSat, 0) ); + iVar0 = Cec2_ObjGetCnfVar( p, iObj0 ); + iVar1 = Cec2_ObjGetCnfVar( p, iObj1 ); + // collect inputs and internal nodes + Vec_IntClear( p->vNodesNew ); + Vec_IntClear( p->vObjSatPairs ); + Gia_ManIncrementTravId( p->pNew ); + Cec2_ManCollect_rec( p, iObj0 ); + Cec2_ManCollect_rec( p, iObj1 ); + // solve direct + satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) ); + satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) ); + status = satoko_solve( p->pSat ); + satoko_assump_pop( p->pSat ); + satoko_assump_pop( p->pSat ); + if ( status == SATOKO_UNSAT && iObj0 > 0 ) + { + // solve reverse + satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 0) ); + satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, !fPhase) ); + status = satoko_solve( p->pSat ); + satoko_assump_pop( p->pSat ); + satoko_assump_pop( p->pSat ); + } + Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i ) + Cec2_ObjCleanSatId( p->pNew, pObj ); + return status; +} +int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) +{ + int i, IdAig, IdSat, status, RetValue = 1; + Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj ); + Gia_Obj_t * pRepr = Gia_ObjReprObj( p->pAig, iObj ); + int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase; + status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); + if ( status == SATOKO_SAT ) + { + Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i ) + Cec2_ObjSimSetPiBit( p->pAig, IdAig, var_value(p->pSat, IdSat) == LIT_TRUE ); + RetValue = 0; + } + else if ( status == SATOKO_UNSAT ) + { + pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl ); + Gia_ObjSetProved( p->pAig, iObj ); + } + else + { + assert( status == SATOKO_UNDEC ); + Gia_ObjSetFailed( p->pAig, iObj ); + assert( 0 ); + } + satoko_rollback( p->pSat ); + return RetValue; +} +int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) +{ + Cec2_Man_t * pMan; + Gia_Obj_t * pObj, * pRepr, * pObjNew; + int i, fDisproved = 1; + + // check if any output trivially fails under all-0 pattern + Gia_ManSetPhase( p ); + if ( pPars->fIsMiter ) + { + Gia_ManForEachCo( p, pObj, i ) + if ( pObj->fPhase ) + { + p->pCexSeq = Cec2_ManDeriveCex( p, i, -1 ); + return 0; + } + } + // simulate one round and create classes + Cec2_ManSimAlloc( p, pPars->nSimWords ); + Cec2_ManSimulateCis( p ); + Cec2_ManSimulate( p ); + if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected + return 0; + Cec2_ManCreateClasses( p ); + if ( pPars->fVerbose ) + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + + // perform additinal simulation + for ( i = 0; i < pPars->nSimRounds; i++ ) + { + Cec2_ManSimulateCis( p ); + Cec2_ManSimulate( p ); + if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected + return 0; + if ( pPars->fVerbose ) + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + } + // perform sweeping + pMan = Cec2_ManCreate( p, pPars ); + while ( fDisproved ) + { + fDisproved = 0; + Cec2_ManSimulateCis( p ); + Gia_ManForEachAnd( p, pObj, i ) + { + pObj->fMark1 = 0; + if ( ~pObj->Value ) // skip swept nodes + continue; + assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) ); + pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 || Gia_ObjFanin1(pObj)->fMark1; + if ( pObj->fMark1 ) // skip nodes in the TFO of a disproved one + continue; + // duplicate the node + pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( Vec_IntSize(&pMan->pNew->vCopies) == Abc_Lit2Var(pObj->Value) ) + { + pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) ); + pObjNew->fMark0 = Gia_ObjIsMuxType( pObjNew ); + Vec_IntPush( &pMan->pNew->vCopies, -1 ); + } + assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) ); + pRepr = Gia_ObjReprObj( p, i ); + if ( pRepr == NULL || pRepr->fMark1 ) + continue; + //if ( Gia_ObjIsConst0(pRepr) ) + // continue; + if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) + { + assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) ); + Gia_ObjSetProved( p, i ); + continue; + } + if ( Cec2_ManSweepNode(pMan, i) ) + continue; + // mark nodes as disproved + pRepr->fMark1 = pObj->fMark1 = 1; + fDisproved = 1; + } + if ( fDisproved ) + { + Cec2_ManSimulate( p ); + if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected + break; + } + if ( pPars->fVerbose ) + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + } + Cec2_ManDestroy( pMan ); + return p->pCexSeq ? 0 : 1; +} +void Cec2_ManSimulateTest( Gia_Man_t * p ) +{ + abctime clk = Abc_Clock(); + Cec2_Par_t Pars, * pPars = &Pars; + Cec2_SetDefaultParams( pPars ); + Cec2_ManPerformSweeping( p, pPars ); + Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make index 82e0de74..38106e5e 100644 --- a/src/proof/cec/module.make +++ b/src/proof/cec/module.make @@ -6,6 +6,7 @@ SRC += src/proof/cec/cecCec.c \ src/proof/cec/cecIso.c \ src/proof/cec/cecMan.c \ src/proof/cec/cecPat.c \ + src/proof/cec/cecSat.c \ src/proof/cec/cecSeq.c \ src/proof/cec/cecSolve.c \ src/proof/cec/cecSplit.c \ diff --git a/src/sat/bmc/bmcGen.c b/src/sat/bmc/bmcGen.c index 5d84ce87..460c9fec 100644 --- a/src/sat/bmc/bmcGen.c +++ b/src/sat/bmc/bmcGen.c @@ -46,13 +46,13 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ static inline word * Gia_ManMoObj( Gia_Man_t * p, int iObj ) { - return Vec_WrdEntryP( p->vSims, iObj * p->iPatsPi ); + return Vec_WrdEntryP( p->vSims, iObj * p->nSimWords ); } static inline void Gia_ManMoSetCi( Gia_Man_t * p, int iObj ) { int w; word * pSims = Gia_ManMoObj( p, iObj ); - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = Gia_ManRandomW( 0 ); } static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj ) @@ -65,19 +65,19 @@ static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj ) if ( Gia_ObjFaninC0(pObj) ) { if ( Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = ~(pSims0[w] | pSims1[w]); else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = ~pSims0[w] & pSims1[w]; } else { if ( Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = pSims0[w] & ~pSims1[w]; else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = pSims0[w] & pSims1[w]; } } @@ -89,12 +89,12 @@ static inline void Gia_ManMoSetCo( Gia_Man_t * p, int iObj ) word * pSims0 = Gia_ManMoObj( p, Gia_ObjFaninId0(pObj, iObj) ); if ( Gia_ObjFaninC0(pObj) ) { - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = ~pSims0[w]; } else { - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSims[w] = pSims0[w]; } } @@ -102,7 +102,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords ) { int i, iObj; Gia_ManRandomW( 1 ); - p->iPatsPi = nWords; + p->nSimWords = nWords; if ( p->vSims ) Vec_WrdFill( p->vSims, nWords * Gia_ManObjNum(p), 0 ); else diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 88070eac..7c2f3720 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -83,7 +83,7 @@ extern void satoko_destroy(satoko_t *); extern void satoko_default_opts(satoko_opts_t *); extern void satoko_configure(satoko_t *, satoko_opts_t *); extern int satoko_parse_dimacs(char *, satoko_t **); -extern void satoko_add_variable(satoko_t *, char); +extern int satoko_add_variable(satoko_t *, char); extern int satoko_add_clause(satoko_t *, unsigned *, unsigned); extern void satoko_assump_push(satoko_t *s, unsigned); extern void satoko_assump_pop(satoko_t *s); diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 9cad0a14..e03cc084 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -216,7 +216,7 @@ int satoko_simplify(solver_t * s) return SATOKO_OK; } -void satoko_add_variable(solver_t *s, char sign) +int satoko_add_variable(solver_t *s, char sign) { unsigned var = vec_act_size(s->activity); vec_wl_push(s->watches); @@ -231,6 +231,7 @@ void satoko_add_variable(solver_t *s, char sign) heap_insert(s->var_order, var); if (s->marks) vec_char_push_back(s->marks, 0); + return var; } int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) @@ -351,6 +352,7 @@ void satoko_rollback(satoko_t *s) clause_unwatch(s, cdb_cref(s->all_clauses, (unsigned *)cl_to_remove[i])); cl_to_remove[i]->f_mark = 1; } + satoko_free(cl_to_remove); vec_uint_shrink(s->originals, s->book_cl_orig); vec_uint_shrink(s->learnts, s->book_cl_lrnt); /* Shrink variable related vectors */ -- cgit v1.2.3 From 316238d484c867c1114bd015c025dd0d1ce2bb1a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 14:26:31 -0800 Subject: Compiler warnings. --- src/aig/gia/giaUtil.c | 2 +- src/sat/satoko/satoko.h | 4 ++-- src/sat/satoko/solver_api.c | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index d64c53fa..d100b6c1 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2063,7 +2063,7 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName ) ***********************************************************************/ void Gia_ManDetectMuxes( Gia_Man_t * p ) { - Gia_Obj_t * pObj, * pNodeT, * pNodeE; int i; + Gia_Obj_t * pObj = NULL, * pNodeT, * pNodeE; int i; Gia_ManForEachObj( p, pObj, i ); if ( Gia_ObjIsAnd(pObj) && Gia_ObjRecognizeMux(pObj, &pNodeT, &pNodeE) ) pObj->fMark0 = 1; diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 7c2f3720..2d3e056e 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -84,8 +84,8 @@ extern void satoko_default_opts(satoko_opts_t *); extern void satoko_configure(satoko_t *, satoko_opts_t *); extern int satoko_parse_dimacs(char *, satoko_t **); extern int satoko_add_variable(satoko_t *, char); -extern int satoko_add_clause(satoko_t *, unsigned *, unsigned); -extern void satoko_assump_push(satoko_t *s, unsigned); +extern int satoko_add_clause(satoko_t *, int *, int); +extern void satoko_assump_push(satoko_t *s, int); extern void satoko_assump_pop(satoko_t *s); extern int satoko_simplify(satoko_t *); extern int satoko_solve(satoko_t *); diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index e03cc084..e4fd88b7 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -234,7 +234,7 @@ int satoko_add_variable(solver_t *s, char sign) return var; } -int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) +int satoko_add_clause(solver_t *s, int *lits, int size) { unsigned i, j; unsigned prev_lit; @@ -249,10 +249,10 @@ int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) vec_uint_clear(s->temp_lits); j = 0; prev_lit = UNDEF; - for (i = 0; i < size; i++) { - if (lits[i] == lit_neg(prev_lit) || lit_value(s, lits[i]) == LIT_TRUE) + for (i = 0; i < (unsigned)size; i++) { + if ((unsigned)lits[i] == lit_neg(prev_lit) || lit_value(s, lits[i]) == LIT_TRUE) return SATOKO_OK; - else if (lits[i] != prev_lit && var_value(s, lit2var(lits[i])) == VAR_UNASSING) { + else if ((unsigned)lits[i] != prev_lit && var_value(s, lit2var(lits[i])) == VAR_UNASSING) { prev_lit = lits[i]; vec_uint_push_back(s->temp_lits, lits[i]); } @@ -270,7 +270,7 @@ int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) return SATOKO_OK; } -void satoko_assump_push(solver_t *s, unsigned lit) +void satoko_assump_push(solver_t *s, int lit) { vec_uint_push_back(s->assumptions, lit); } -- cgit v1.2.3 From 131c1613a4ca77c063cd677d0086a3b426868b3b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 14:29:04 -0800 Subject: Compiler warnings. --- src/aig/gia/giaSatoko.c | 2 +- src/sat/satoko/cnf_reader.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/aig/gia/giaSatoko.c b/src/aig/gia/giaSatoko.c index 7cbc4184..5e04502d 100644 --- a/src/aig/gia/giaSatoko.c +++ b/src/aig/gia/giaSatoko.c @@ -87,7 +87,7 @@ satoko_t * Gia_ManSatokoInit( Cnf_Dat_t * pCnf, satoko_opts_t * opts ) //sat_solver_setnvars( pSat, p->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) { - if ( !satoko_add_clause( pSat, (unsigned *)pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) + if ( !satoko_add_clause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) { satoko_destroy( pSat ); return NULL; diff --git a/src/sat/satoko/cnf_reader.c b/src/sat/satoko/cnf_reader.c index 9fbbda65..adb9a47b 100644 --- a/src/sat/satoko/cnf_reader.c +++ b/src/sat/satoko/cnf_reader.c @@ -141,7 +141,7 @@ int satoko_parse_dimacs(char *fname, satoko_t **solver) return -1; } read_clause(&token, lits); - if (!satoko_add_clause(p, vec_uint_data(lits), vec_uint_size(lits))) { + if (!satoko_add_clause(p, (int*)vec_uint_data(lits), vec_uint_size(lits))) { vec_uint_print(lits); return 0; } -- cgit v1.2.3 From fdc0b471e5b9a20d4bf5f603f58369aba17326c3 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 14:38:08 -0800 Subject: working on incremental pdr --- src/proof/pdr/pdrIncr.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index d33b45ac..c4f384f5 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -38,6 +38,121 @@ extern int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex, in /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs ) +{ + Vec_Ptr_t * vArrayK; + Pdr_Set_t * pCube; + int i, k, Counter = 0; + Vec_VecForEachLevelStart( vClauses, vArrayK, k, kStart ) + { + Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare ); + Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, i ) + { + Abc_Print( 1, "C=%4d. F=%4d ", Counter++, k ); + Pdr_SetPrint( stdout, pCube, nRegs, NULL ); + Abc_Print( 1, "\n" ); + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p ) +{ + int i, k; + Vec_Vec_t * vClausesSaved; + Pdr_Set_t * pCla; + + // Note that the last frame is empty + vClausesSaved = Vec_VecStart(Vec_VecSize(p->vClauses)-1); + Vec_VecForEachEntryStartStop( Pdr_Set_t *, p->vClauses, pCla, i, k, 0, Vec_VecSize(vClausesSaved) ) + Vec_VecPush(vClausesSaved, i, Pdr_SetDup(pCla)); + + return vClausesSaved; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k ) +{ + sat_solver * pSat; + Vec_Ptr_t * vArrayK; + Pdr_Set_t * pCube; + int i, j; + + assert( Vec_PtrSize(p->vSolvers) == k ); + assert( Vec_IntSize(p->vActVars) == k ); + + pSat = zsat_solver_new_seed(p->pPars->nRandomSeed); + pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) ); + Vec_PtrPush( p->vSolvers, pSat ); + Vec_IntPush( p->vActVars, 0 ); + + // set the property output + Pdr_ManSetPropertyOutput( p, k ); + // add the clauses + Vec_VecForEachLevelStart( p->vClauses, vArrayK, i, k ) + Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, j ) + Pdr_ManSolverAddClause( p, k, pCube ); + return pSat; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) +{ + int i; + + assert(vClauses); + + Vec_VecFree(p->vClauses); + p->vClauses = vClauses; + + for ( i = 0; i < Vec_VecSize(p->vClauses); ++i ) + IPdr_ManSetSolver(p, i); + + return 0; +} + /**Function************************************************************* Synopsis [] @@ -59,7 +174,7 @@ int IPdr_ManSolveInt( Pdr_Man_t * p ) int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) ); abctime clkStart = Abc_Clock(), clkOne = 0; p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0; - assert( Vec_PtrSize(p->vSolvers) == 0 ); + // assert( Vec_PtrSize(p->vSolvers) == 0 ); // in the multi-output mode, mark trivial POs (those fed by const0) as solved if ( p->pPars->fSolveAll ) Saig_ManForEachPo( p->pAig, pObj, iFrame ) @@ -72,7 +187,13 @@ int IPdr_ManSolveInt( Pdr_Man_t * p ) } // create the first timeframe p->pPars->timeLastSolved = Abc_Clock(); - Pdr_ManCreateSolver( p, (iFrame = 0) ); + + if ( Vec_VecSize(p->vClauses) == 0 ) + Pdr_ManCreateSolver( p, (iFrame = 0) ); + else { + iFrame = Vec_VecSize(p->vClauses); + Pdr_ManCreateSolver( p, iFrame ); + } while ( 1 ) { int fRefined = 0; @@ -406,6 +527,9 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) { Pdr_Man_t * p; int k, RetValue; + int i, nRegs; + Vec_Vec_t * vClausesSaved; + abctime clk = Abc_Clock(); if ( pPars->nTimeOutOne && !pPars->fSolveAll ) pPars->nTimeOutOne = 0; @@ -444,6 +568,26 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) else if ( RetValue == 1 ) Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); p->tTotal += Abc_Clock() - clk; + + if (pPars->iFrame == pPars->nFrameMax) + { + vClausesSaved = IPdr_ManSaveClauses(p); + nRegs = Aig_ManRegNum(p->pAig); + + Pdr_ManStop( p ); + + printf("PDR reached the max frame: %d\n", pPars->iFrame); + IPdr_ManPrintClauses(vClausesSaved, 0, nRegs); + + p = Pdr_ManStart( pAig, pPars, NULL ); + IPdr_ManRestore( p, vClausesSaved ); + + // Solve again + pPars->nFrameMax = pPars->nFrameMax + 1; + RetValue = IPdr_ManSolveInt(p); + IPdr_ManPrintClauses(p->vClauses, 0, nRegs); + } + Pdr_ManStop( p ); pPars->iFrame--; // convert all -2 (unknown) entries into -1 (undec) @@ -457,7 +601,6 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) } - /**Function************************************************************* Synopsis [] -- cgit v1.2.3 From ac409b3152bf0bb6fd49c243ae635ca288d92b06 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Sat, 18 Feb 2017 15:24:56 -0800 Subject: Bug fix in analyze_final method. --- src/sat/satoko/solver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 21a4860d..6554f653 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -362,13 +362,13 @@ static inline void solver_handle_conflict(solver_t *s, unsigned confl_cref) static inline void solver_analyze_final(solver_t *s, unsigned lit) { - unsigned i; + int i; vec_uint_push_back(s->final_conflict, lit); if (solver_dlevel(s) == 0) return; vec_char_assign(s->seen, lit2var(lit), 1); - for (i = vec_uint_size(s->trail) - 1; i <= vec_uint_at(s->trail_lim, 0); i--) { + for (i = (int) vec_uint_size(s->trail) - 1; i >= (int) vec_uint_at(s->trail_lim, 0); i--) { unsigned var = lit2var(vec_uint_at(s->trail, i)); if (vec_char_at(s->seen, var)) { -- cgit v1.2.3 From 3f0cb6318b14e286cd9054a0f771183d15ef3db6 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Sat, 18 Feb 2017 17:08:54 -0800 Subject: New function to retrieve polarity value of a variable. --- src/sat/satoko/solver.c | 2 +- src/sat/satoko/solver.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 6554f653..3e5fc8ee 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -195,7 +195,7 @@ static inline unsigned solver_decide(solver_t *s) if (solver_has_marks(s) && !var_mark(s, next_var)) next_var = UNDEF; } - return var2lit(next_var, vec_char_at(s->polarity, next_var)); + return var2lit(next_var, var_polarity(s, next_var)); } static inline void solver_new_decision(solver_t *s, unsigned lit) diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index 68cc97dc..dcae8f6e 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -132,6 +132,11 @@ static inline char var_value(solver_t *s, unsigned var) return vec_char_at(s->assigns, var); } +static inline char var_polarity(solver_t *s, unsigned var) +{ + return vec_char_at(s->polarity, var); +} + static inline unsigned var_dlevel(solver_t *s, unsigned var) { return vec_uint_at(s->levels, var); -- cgit v1.2.3 From 27caed8dc812db321730ee9451a2a0788ad0ab28 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 20:20:50 -0800 Subject: Experiments with SAT sweeping. --- src/base/abci/abc.c | 2 +- src/proof/cec/cecSat.c | 119 +++++++++++++++++++++++++++++++++++--------- src/sat/satoko/solver.c | 1 + src/sat/satoko/solver_api.c | 9 ++++ src/sat/satoko/watch_list.h | 2 +- 5 files changed, 108 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 52684f8c..4c37242d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43019,7 +43019,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); - +Cec2_ManSimulateTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; usage: diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c index 9e85e49d..aba53318 100644 --- a/src/proof/cec/cecSat.c +++ b/src/proof/cec/cecSat.c @@ -55,6 +55,7 @@ struct Cec2_Man_t_ Vec_Wrd_t * vSims; // CI simulation info Vec_Int_t * vNodesNew; // nodes Vec_Int_t * vObjSatPairs; // nodes + Vec_Int_t * vCexTriples; // nodes }; static inline int Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); } @@ -352,11 +353,9 @@ static inline word * Cec2_ObjSim( Gia_Man_t * p, int iObj ) { return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); } -static inline void Cec2_ObjSimSetPiBit( Gia_Man_t * p, int iObj, int Bit ) +static inline void Cec2_ObjSimSetInputBit( Gia_Man_t * p, int iObj, int Bit ) { word * pSim = Cec2_ObjSim( p, iObj ); - p->iPatsPi = (p->iPatsPi == 64 * p->nSimWords - 1) ? 1 : p->iPatsPi + 1; - assert( p->iPatsPi > 0 && p->iPatsPi < 64 * p->nSimWords ); if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit ) Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi ); } @@ -421,7 +420,7 @@ static inline int Cec2_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 ) return 1; } } -static inline void Cec2_ObjSimPi( Gia_Man_t * p, int iObj ) +static inline void Cec2_ObjSimCi( Gia_Man_t * p, int iObj ) { int w; word * pSim = Cec2_ObjSim( p, iObj ); @@ -433,7 +432,7 @@ void Cec2_ManSimulateCis( Gia_Man_t * p ) { int i, Id; Gia_ManForEachCiId( p, Id, i ) - Cec2_ObjSimPi( p, Id ); + Cec2_ObjSimCi( p, Id ); p->iPatsPi = 1; } Abc_Cex_t * Cec2_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat ) @@ -471,15 +470,28 @@ void Cec2_ManSaveCis( Gia_Man_t * p ) Gia_ManForEachCiId( p, Id, i ) Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] ); } -void Cec2_ManSimulate( Gia_Man_t * p ) +void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples ) { extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ); - Gia_Obj_t * pObj; int i; - Cec2_ManSaveCis( p ); + Gia_Obj_t * pObj; + int i, iRepr, iObj, Entry; + //Cec2_ManSaveCis( p ); Gia_ManForEachAnd( p, pObj, i ) Cec2_ObjSimAnd( p, i ); if ( p->pReprs == NULL ) return; + if ( vTriples ) + { + Vec_IntForEachEntryTriple( vTriples, iRepr, iObj, Entry, i ) + { + word * pSim0 = Cec2_ObjSim( p, iRepr ); + word * pSim1 = Cec2_ObjSim( p, iObj ); + int iPat = Abc_Lit2Var(Entry); + int fPhase = Abc_LitIsCompl(Entry); + if ( (fPhase ^ Abc_InfoHasBit((unsigned *)pSim0, iPat)) == Abc_InfoHasBit((unsigned *)pSim1, iPat) ) + printf( "ERROR: Pattern %d did not disprove pair %d and %d.\n", iPat, iRepr, iObj ); + } + } Gia_ManForEachClass0( p, i ) Cec2_ManSimClassRefineOne( p, i ); } @@ -570,7 +582,8 @@ void Cec2_ManCreateClasses( Gia_Man_t * p ) int nWords = p->nSimWords; int * pTable, nTableSize, i, Key; // allocate representation - assert( p->pReprs == NULL ); + ABC_FREE( p->pReprs ); + ABC_FREE( p->pNexts ); p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) ); // hash each node by its simulation info @@ -618,7 +631,7 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) { Cec2_Man_t * p; Gia_Obj_t * pObj; int i; - assert( Gia_ManRegNum(pAig) == 0 ); + //assert( Gia_ManRegNum(pAig) == 0 ); p = ABC_CALLOC( Cec2_Man_t, 1 ); memset( p, 0, sizeof(Cec2_Man_t) ); p->pPars = pPars; @@ -637,6 +650,7 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) p->vFanins = Vec_PtrAlloc( 100 ); p->vNodesNew = Vec_IntAlloc( 100 ); p->vObjSatPairs = Vec_IntAlloc( 100 ); + p->vCexTriples = Vec_IntAlloc( 100 ); // remember pointer to the solver in the AIG manager pAig->pData = p->pSat; return p; @@ -652,10 +666,51 @@ void Cec2_ManDestroy( Cec2_Man_t * p ) Vec_PtrFreeP( &p->vFanins ); Vec_IntFreeP( &p->vNodesNew ); Vec_IntFreeP( &p->vObjSatPairs ); + Vec_IntFreeP( &p->vCexTriples ); ABC_FREE( p ); } +/**Function************************************************************* + + Synopsis [Verify counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec2_ManVerify_rec( Gia_Man_t * p, int iObj, satoko_t * pSat ) +{ + int Value0, Value1; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( iObj == 0 ) return 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return pObj->fMark1; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return pObj->fMark1 = var_polarity(pSat, Cec2_ObjSatId(p, pObj)) == LIT_TRUE; + assert( Gia_ObjIsAnd(pObj) ); + Value0 = Cec2_ManVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), pSat ) ^ Gia_ObjFaninC0(pObj); + Value1 = Cec2_ManVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), pSat ) ^ Gia_ObjFaninC1(pObj); + return pObj->fMark1 = Value0 & Value1; +} +void Cec2_ManVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase, satoko_t * pSat ) +{ +// int val0 = var_polarity(pSat, Cec2_ObjSatId(p, Gia_ManObj(p, iObj0))) == LIT_TRUE; +// int val1 = var_polarity(pSat, Cec2_ObjSatId(p, Gia_ManObj(p, iObj1))) == LIT_TRUE; + int Value0, Value1; + Gia_ManIncrementTravId( p ); + Value0 = Cec2_ManVerify_rec( p, iObj0, pSat ); + Value1 = Cec2_ManVerify_rec( p, iObj1, pSat ); + if ( (Value0 ^ Value1) == fPhase ) + printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 ); +// else +// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );; +} + /**Function************************************************************* Synopsis [Internal simulation APIs.] @@ -707,6 +762,7 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) Gia_ManIncrementTravId( p->pNew ); Cec2_ManCollect_rec( p, iObj0 ); Cec2_ManCollect_rec( p, iObj1 ); +//printf( "%d ", Vec_IntSize(p->vNodesNew) ); // solve direct satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) ); satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) ); @@ -722,6 +778,8 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) satoko_assump_pop( p->pSat ); satoko_assump_pop( p->pSat ); } + //if ( status == SATOKO_SAT ) + // Cec2_ManVerify( p->pNew, iObj0, iObj1, fPhase, p->pSat ); Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i ) Cec2_ObjCleanSatId( p->pNew, pObj ); return status; @@ -735,8 +793,10 @@ int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); if ( status == SATOKO_SAT ) { + p->pAig->iPatsPi = (p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 1) ? 1 : p->pAig->iPatsPi + 1; + assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords ); Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i ) - Cec2_ObjSimSetPiBit( p->pAig, IdAig, var_value(p->pSat, IdSat) == LIT_TRUE ); + Cec2_ObjSimSetInputBit( p->pAig, IdAig, var_polarity(p->pSat, IdSat) == LIT_TRUE ); RetValue = 0; } else if ( status == SATOKO_UNSAT ) @@ -751,13 +811,14 @@ int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) assert( 0 ); } satoko_rollback( p->pSat ); + p->pSat->stats.n_conflicts = 0; return RetValue; } int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) { Cec2_Man_t * pMan; Gia_Obj_t * pObj, * pRepr, * pObjNew; - int i, fDisproved = 1; + int i, Iter, fDisproved = 1; // check if any output trivially fails under all-0 pattern Gia_ManSetPhase( p ); @@ -770,10 +831,11 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) return 0; } } + // simulate one round and create classes Cec2_ManSimAlloc( p, pPars->nSimWords ); Cec2_ManSimulateCis( p ); - Cec2_ManSimulate( p ); + Cec2_ManSimulate( p, NULL ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected return 0; Cec2_ManCreateClasses( p ); @@ -784,7 +846,7 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) for ( i = 0; i < pPars->nSimRounds; i++ ) { Cec2_ManSimulateCis( p ); - Cec2_ManSimulate( p ); + Cec2_ManSimulate( p, NULL ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected return 0; if ( pPars->fVerbose ) @@ -792,33 +854,34 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) } // perform sweeping pMan = Cec2_ManCreate( p, pPars ); - while ( fDisproved ) + for ( Iter = 0; fDisproved; Iter++ ) { fDisproved = 0; Cec2_ManSimulateCis( p ); + Vec_IntClear( pMan->vCexTriples ); Gia_ManForEachAnd( p, pObj, i ) { - pObj->fMark1 = 0; - if ( ~pObj->Value ) // skip swept nodes - continue; - assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) ); pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 || Gia_ObjFanin1(pObj)->fMark1; if ( pObj->fMark1 ) // skip nodes in the TFO of a disproved one continue; + if ( ~pObj->Value ) // skip swept nodes + continue; + if ( !~Gia_ObjFanin0(pObj)->Value || !~Gia_ObjFanin1(pObj)->Value ) // skip fanouts of non-swept nodes + continue; + assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) ); // duplicate the node pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); if ( Vec_IntSize(&pMan->pNew->vCopies) == Abc_Lit2Var(pObj->Value) ) { pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) ); pObjNew->fMark0 = Gia_ObjIsMuxType( pObjNew ); + Gia_ObjSetPhase( pMan->pNew, pObjNew ); Vec_IntPush( &pMan->pNew->vCopies, -1 ); } assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) ); pRepr = Gia_ObjReprObj( p, i ); if ( pRepr == NULL || pRepr->fMark1 ) continue; - //if ( Gia_ObjIsConst0(pRepr) ) - // continue; if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) { assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) ); @@ -827,13 +890,20 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) } if ( Cec2_ManSweepNode(pMan, i) ) continue; + pObj->Value = ~0; + //Vec_IntPushThree( pMan->vCexTriples, Gia_ObjId(p, pRepr), i, Abc_Var2Lit(p->iPatsPi, pObj->fPhase ^ pRepr->fPhase) ); // mark nodes as disproved - pRepr->fMark1 = pObj->fMark1 = 1; fDisproved = 1; + if ( Iter > 5 ) + continue; + if ( Gia_ObjIsAnd(pRepr) ) + pRepr->fMark1 = 1; + pObj->fMark1 = 1; } if ( fDisproved ) { - Cec2_ManSimulate( p ); + //printf( "The number of pattern = %d.\n", p->iPatsPi ); + Cec2_ManSimulate( p, pMan->vCexTriples ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected break; } @@ -841,6 +911,7 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); } Cec2_ManDestroy( pMan ); + //Gia_ManEquivPrintClasses( p, 1, 0 ); return p->pCexSeq ? 0 : 1; } void Cec2_ManSimulateTest( Gia_Man_t * p ) @@ -848,6 +919,8 @@ void Cec2_ManSimulateTest( Gia_Man_t * p ) abctime clk = Abc_Clock(); Cec2_Par_t Pars, * pPars = &Pars; Cec2_SetDefaultParams( pPars ); +// Gia_ManComputeGiaEquivs( p, 100000, 0 ); +// Gia_ManEquivPrintClasses( p, 1, 0 ); Cec2_ManPerformSweeping( p, pPars ); Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); } diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 3e5fc8ee..3738129b 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -364,6 +364,7 @@ static inline void solver_analyze_final(solver_t *s, unsigned lit) { int i; + vec_uint_clear(s->final_conflict); vec_uint_push_back(s->final_conflict, lit); if (solver_dlevel(s) == 0) return; diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index e4fd88b7..f758a1ef 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -356,10 +356,15 @@ void satoko_rollback(satoko_t *s) vec_uint_shrink(s->originals, s->book_cl_orig); vec_uint_shrink(s->learnts, s->book_cl_lrnt); /* Shrink variable related vectors */ + for (i = s->book_vars; i < 2 * vec_char_size(s->assigns); i++) + vec_wl_at(s->watches, i)->size = 0; + s->watches->size = s->book_vars; vec_act_shrink(s->activity, s->book_vars); vec_uint_shrink(s->levels, s->book_vars); vec_uint_shrink(s->reasons, s->book_vars); + vec_uint_shrink(s->stamps, s->book_vars); vec_char_shrink(s->assigns, s->book_vars); + vec_char_shrink(s->seen, s->book_vars); vec_char_shrink(s->polarity, s->book_vars); solver_rebuild_order(s); /* Rewind solver and cancel level 0 assignments to the trail */ @@ -369,6 +374,10 @@ void satoko_rollback(satoko_t *s) s->book_cl_lrnt = 0; s->book_vars = 0; s->book_trail = 0; + if (!s->book_vars) { + s->all_clauses->size = 0; + s->all_clauses->wasted = 0; + } } void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars) diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index 49f419f2..a36ab2bb 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -154,7 +154,7 @@ static inline vec_wl_t *vec_wl_alloc(unsigned cap) static inline void vec_wl_free(vec_wl_t *vec_wl) { unsigned i; - for (i = 0; i < vec_wl->size; i++) + for (i = 0; i < vec_wl->cap; i++) watch_list_free(vec_wl->watch_lists + i); satoko_free(vec_wl->watch_lists); satoko_free(vec_wl); -- cgit v1.2.3 From fc0f3b8d0dbd15b57f2159a1119b1dcf5db0aa68 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 21:22:26 -0800 Subject: working on incremental pdr --- src/proof/pdr/pdrIncr.c | 70 +++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index c4f384f5..aa07b668 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -527,7 +527,6 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) { Pdr_Man_t * p; int k, RetValue; - int i, nRegs; Vec_Vec_t * vClausesSaved; abctime clk = Abc_Clock(); @@ -549,46 +548,49 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) pPars->fSolveAll ? "yes" : "no" ); } ABC_FREE( pAig->pSeqModel ); + + p = Pdr_ManStart( pAig, pPars, NULL ); - RetValue = IPdr_ManSolveInt( p ); - if ( RetValue == 0 ) - assert( pAig->pSeqModel != NULL || p->vCexes != NULL ); - if ( p->vCexes ) - { - assert( p->pAig->vSeqModelVec == NULL ); - p->pAig->vSeqModelVec = p->vCexes; - p->vCexes = NULL; - } - if ( p->pPars->fDumpInv ) - { - char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); - Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); - Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); - } - else if ( RetValue == 1 ) - Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); - p->tTotal += Abc_Clock() - clk; + while ( 1 ) { + RetValue = IPdr_ManSolveInt( p ); - if (pPars->iFrame == pPars->nFrameMax) - { - vClausesSaved = IPdr_ManSaveClauses(p); - nRegs = Aig_ManRegNum(p->pAig); + if ( RetValue == -1 && pPars->iFrame == pPars->nFrameMax) { + vClausesSaved = IPdr_ManSaveClauses( p ); - Pdr_ManStop( p ); + Pdr_ManStop( p ); - printf("PDR reached the max frame: %d\n", pPars->iFrame); - IPdr_ManPrintClauses(vClausesSaved, 0, nRegs); + p = Pdr_ManStart( pAig, pPars, NULL ); + IPdr_ManRestore( p, vClausesSaved ); - p = Pdr_ManStart( pAig, pPars, NULL ); - IPdr_ManRestore( p, vClausesSaved ); + pPars->nFrameMax = pPars->nFrameMax << 1; - // Solve again - pPars->nFrameMax = pPars->nFrameMax + 1; - RetValue = IPdr_ManSolveInt(p); - IPdr_ManPrintClauses(p->vClauses, 0, nRegs); - } + continue; + } + + if ( RetValue == 0 ) + assert( pAig->pSeqModel != NULL || p->vCexes != NULL ); + if ( p->vCexes ) + { + assert( p->pAig->vSeqModelVec == NULL ); + p->pAig->vSeqModelVec = p->vCexes; + p->vCexes = NULL; + } + if ( p->pPars->fDumpInv ) + { + char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla"); + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); + Pdr_ManDumpClauses( p, pFileName, RetValue==1 ); + } + else if ( RetValue == 1 ) + Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) ); - Pdr_ManStop( p ); + p->tTotal += Abc_Clock() - clk; + Pdr_ManStop( p ); + + break; + } + + pPars->iFrame--; // convert all -2 (unknown) entries into -1 (undec) if ( pPars->vOutMap ) -- cgit v1.2.3 From 24fdcecb2d034af4d7f7c26ec083f6baf1434018 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 09:20:44 -0800 Subject: started %pdra --- src/base/wlc/wlcCom.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) (limited to 'src') diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 97717b09..6b542b94 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -33,6 +33,7 @@ static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPdrAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -75,6 +76,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%pdra", Abc_CommandPdrAbs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); @@ -442,6 +444,121 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + Wlc_NtkAbsCore( pNtk, pPars ); + return 0; +usage: + Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + /**Function******************************************************************** Synopsis [] -- cgit v1.2.3 From 6cf289dadd41354eb03ef1fa0a4d366ab5f62f8c Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 09:55:58 -0800 Subject: working on pdr with wla --- src/base/wlc/wlc.h | 1 + src/base/wlc/wlcAbs.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcCom.c | 2 +- src/proof/pdr/pdrIncr.c | 11 +++-- 4 files changed, 120 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 91dc0573..9ca56917 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -277,6 +277,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 318df4dd..cfd1155d 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -283,6 +283,117 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec return nNodes; } +/**Function************************************************************* + + Synopsis [Performs PDR with word-level abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fVerbose = pPars->fPdrVerbose; + + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) + { + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present + { + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); + } + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); + } + + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; +} + /**Function************************************************************* Synopsis [Performs abstraction.] diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 6b542b94..e980752b 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -541,7 +541,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - Wlc_NtkAbsCore( pNtk, pPars ); + Wlc_NtkPdrAbs( pNtk, pPars ); return 0; usage: Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index aa07b668..2a718577 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -77,14 +77,17 @@ void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs ) SeeAlso [] ***********************************************************************/ -Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p ) +Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ) { int i, k; Vec_Vec_t * vClausesSaved; Pdr_Set_t * pCla; - // Note that the last frame is empty - vClausesSaved = Vec_VecStart(Vec_VecSize(p->vClauses)-1); + if ( fDropLast ) + vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses)-1 ); + else + vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses) ); + Vec_VecForEachEntryStartStop( Pdr_Set_t *, p->vClauses, pCla, i, k, 0, Vec_VecSize(vClausesSaved) ) Vec_VecPush(vClausesSaved, i, Pdr_SetDup(pCla)); @@ -555,7 +558,7 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) RetValue = IPdr_ManSolveInt( p ); if ( RetValue == -1 && pPars->iFrame == pPars->nFrameMax) { - vClausesSaved = IPdr_ManSaveClauses( p ); + vClausesSaved = IPdr_ManSaveClauses( p, 1 ); Pdr_ManStop( p ); -- cgit v1.2.3 From 840f5d1ca8d8d51fa28c2ac3cd7bc9dd2e245f29 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 10:22:15 -0800 Subject: working on pdr with wla --- src/base/wlc/wlcAbs.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index cfd1155d..b6571e53 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -20,6 +20,7 @@ #include "wlc.h" #include "proof/pdr/pdr.h" +#include "proof/pdr/pdrInt.h" #include "aig/gia/giaAig.h" #include "sat/bmc/bmc.h" @@ -29,6 +30,10 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); +extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); +extern int IPdr_ManSolveInt( Pdr_Man_t * p ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -297,6 +302,8 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); + Pdr_Man_t * pPdr; + Vec_Vec_t * vClauses = NULL; int nIters, nNodes, nDcFlops, RetValue = -1; // start the bitmap to mark objects that cannot be abstracted because of refinement // currently, this bitmap is empty because abstraction begins without refinement @@ -347,9 +354,14 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // try to prove abstracted GIA by converting it to AIG and calling PDR pAig = Gia_ManToAigSimple( pGia ); - RetValue = Pdr_ManSolve( pAig, pPdrPars ); + + pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + if (vClauses) + IPdr_ManRestore(pPdr, vClauses); + + RetValue = IPdr_ManSolveInt( pPdr ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; - Aig_ManStop( pAig ); // consider outcomes if ( pCex == NULL ) @@ -357,6 +369,8 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) assert( RetValue ); // proved or undecided Gia_ManStop( pGia ); Vec_IntFree( vPisNew ); + Pdr_ManStop( pPdr ); + Aig_ManStop( pAig ); break; } @@ -367,15 +381,22 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) if ( vRefine == NULL ) // real CEX { Abc_CexFree( pCex ); // return CEX in the future + Pdr_ManStop( pPdr ); + Aig_ManStop( pAig ); break; } + // spurious CEX, continue solving + vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + Pdr_ManStop( pPdr ); + // update the set of objects to be un-abstracted nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); if ( pPars->fVerbose ) printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); Vec_IntFree( vRefine ); Abc_CexFree( pCex ); + Aig_ManStop( pAig ); } Vec_BitFree( vUnmark ); -- cgit v1.2.3 From 2732cbc1ee3b82fa7f609ef4c7156132058612dc Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 12:31:28 -0800 Subject: working on pdr with wla --- src/base/wlc/wlcAbs.c | 30 +++++++++++++++++++++++++----- src/proof/pdr/pdrIncr.c | 3 +++ 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index b6571e53..342d667f 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -133,6 +133,17 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * Wlc_NtkCleanMarks( p ); Wlc_NtkForEachCo( p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + + + Vec_IntClear(vFlops); + Wlc_NtkForEachCi( p, pObj, i ) { + if ( !Wlc_ObjIsPi(pObj) ) { + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); + pObj->Mark = 1; + } + } + + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); Wlc_NtkForEachObj( p, pObj, i ) @@ -312,6 +323,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); pPdrPars->fVerbose = pPars->fPdrVerbose; + pPdrPars->fVeryVerbose = 1; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) @@ -356,8 +368,15 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); - if (vClauses) - IPdr_ManRestore(pPdr, vClauses); + if ( vClauses ) { + if ( Vec_VecSize( vClauses) == 1 ) { + Vec_VecFree( vClauses ); + vClauses = NULL; + } else { + assert( Vec_VecSize( vClauses) >= 2 ); + IPdr_ManRestore(pPdr, vClauses); + } + } RetValue = IPdr_ManSolveInt( pPdr ); @@ -441,11 +460,12 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // set up parameters to run PDR Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); - pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) - pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) - pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + //pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + //pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this pPdrPars->fVerbose = pPars->fPdrVerbose; + pPdrPars->fVeryVerbose = 1; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) { diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 2a718577..b1f126f4 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -147,6 +147,9 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) assert(vClauses); + printf( "IPdr restore:\n" ); + IPdr_ManPrintClauses( vClauses, 0, Aig_ManRegNum( p->pAig ) ); + Vec_VecFree(p->vClauses); p->vClauses = vClauses; -- cgit v1.2.3 From 99fe7dfe2906cafad8fafc104b23e6ec8416ce4e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 19 Feb 2017 12:51:38 -0800 Subject: Experiments with SAT sweeping. --- src/proof/cec/cecSat.c | 89 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c index aba53318..88397550 100644 --- a/src/proof/cec/cecSat.c +++ b/src/proof/cec/cecSat.c @@ -56,6 +56,17 @@ struct Cec2_Man_t_ Vec_Int_t * vNodesNew; // nodes Vec_Int_t * vObjSatPairs; // nodes Vec_Int_t * vCexTriples; // nodes + // statistics + int nSatSat; + int nSatUnsat; + int nSatUndec; + abctime timeSatSat; + abctime timeSatUnsat; + abctime timeSatUndec; + abctime timeSim; + abctime timeRefine; + abctime timeExtra; + abctime timeStart; }; static inline int Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); } @@ -470,14 +481,16 @@ void Cec2_ManSaveCis( Gia_Man_t * p ) Gia_ManForEachCiId( p, Id, i ) Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] ); } -void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples ) +void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples, Cec2_Man_t * pMan ) { extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ); + abctime clk = Abc_Clock(); Gia_Obj_t * pObj; int i, iRepr, iObj, Entry; //Cec2_ManSaveCis( p ); Gia_ManForEachAnd( p, pObj, i ) Cec2_ObjSimAnd( p, i ); + pMan->timeSim += Abc_Clock() - clk; if ( p->pReprs == NULL ) return; if ( vTriples ) @@ -492,8 +505,10 @@ void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples ) printf( "ERROR: Pattern %d did not disprove pair %d and %d.\n", iPat, iRepr, iObj ); } } + clk = Abc_Clock(); Gia_ManForEachClass0( p, i ) Cec2_ManSimClassRefineOne( p, i ); + pMan->timeRefine += Abc_Clock() - clk; } void Cec2_ManSimAlloc( Gia_Man_t * p, int nWords ) { @@ -576,8 +591,9 @@ void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ) Gia_ObjSetNext( p, iPrev, -1 ); Gia_ObjSetNext( p, iPrev2, -1 ); } -void Cec2_ManCreateClasses( Gia_Man_t * p ) +void Cec2_ManCreateClasses( Gia_Man_t * p, Cec2_Man_t * pMan ) { + abctime clk; Gia_Obj_t * pObj; int nWords = p->nSimWords; int * pTable, nTableSize, i, Key; @@ -611,8 +627,10 @@ void Cec2_ManCreateClasses( Gia_Man_t * p ) Gia_ObjSetNext( p, iRepr, i ); } ABC_FREE( pTable ); + clk = Abc_Clock(); Gia_ManForEachClass0( p, i ) Cec2_ManSimClassRefineOne( p, i ); + pMan->timeRefine += Abc_Clock() - clk; } @@ -634,6 +652,7 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) //assert( Gia_ManRegNum(pAig) == 0 ); p = ABC_CALLOC( Cec2_Man_t, 1 ); memset( p, 0, sizeof(Cec2_Man_t) ); + p->timeStart = Abc_Clock(); p->pPars = pPars; p->pAig = pAig; // create new manager @@ -657,6 +676,24 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) } void Cec2_ManDestroy( Cec2_Man_t * p ) { + if ( p->pPars->fVerbose ) + { + abctime timeTotal = Abc_Clock() - p->timeStart; + abctime timeSat = p->timeSatSat + p->timeSatUnsat + p->timeSatUndec; + abctime timeOther = timeTotal - timeSat - p->timeSim - p->timeRefine - p->timeExtra; +// Abc_Print( 1, "%d\n", p->Num ); + ABC_PRTP( "SAT solving", timeSat, timeTotal ); + ABC_PRTP( " sat ", p->timeSatSat, timeTotal ); + ABC_PRTP( " unsat ", p->timeSatUnsat, timeTotal ); + ABC_PRTP( " fail ", p->timeSatUndec, timeTotal ); + ABC_PRTP( "Simulation ", p->timeSim, timeTotal ); + ABC_PRTP( "Refinement ", p->timeRefine, timeTotal ); + ABC_PRTP( "Rollback ", p->timeExtra, timeTotal ); + ABC_PRTP( "Other ", timeOther, timeTotal ); + ABC_PRTP( "TOTAL ", timeTotal, timeTotal ); + fflush( stdout ); + } + Vec_WrdFreeP( &p->pAig->vSims ); //Vec_WrdFreeP( &p->pAig->vSimsPi ); Gia_ManCleanMark01( p->pAig ); @@ -784,8 +821,10 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) Cec2_ObjCleanSatId( p->pNew, pObj ); return status; } + int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) { + abctime clk = Abc_Clock(); int i, IdAig, IdSat, status, RetValue = 1; Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj ); Gia_Obj_t * pRepr = Gia_ObjReprObj( p->pAig, iObj ); @@ -793,30 +832,47 @@ int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); if ( status == SATOKO_SAT ) { + p->nSatSat++; p->pAig->iPatsPi = (p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 1) ? 1 : p->pAig->iPatsPi + 1; assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords ); Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i ) Cec2_ObjSimSetInputBit( p->pAig, IdAig, var_polarity(p->pSat, IdSat) == LIT_TRUE ); RetValue = 0; + p->timeSatSat += Abc_Clock() - clk; } else if ( status == SATOKO_UNSAT ) { + p->nSatUnsat++; pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl ); Gia_ObjSetProved( p->pAig, iObj ); + p->timeSatUnsat += Abc_Clock() - clk; } else { + p->nSatUndec++; assert( status == SATOKO_UNDEC ); Gia_ObjSetFailed( p->pAig, iObj ); assert( 0 ); + p->timeSatUndec += Abc_Clock() - clk; } + clk = Abc_Clock(); satoko_rollback( p->pSat ); + p->timeExtra += Abc_Clock() - clk; p->pSat->stats.n_conflicts = 0; return RetValue; } +void Cec2_ManPrintStats( Gia_Man_t * p, Cec2_Par_t * pPars, Cec2_Man_t * pMan ) +{ + if ( !pPars->fVerbose ) + return; + printf( "S =%5d ", pMan ? pMan->nSatSat : 0 ); + printf( "U =%5d ", pMan ? pMan->nSatUnsat : 0 ); + printf( "F =%5d ", pMan ? pMan->nSatUndec : 0 ); + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); +} int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) { - Cec2_Man_t * pMan; + Cec2_Man_t * pMan = Cec2_ManCreate( p, pPars ); Gia_Obj_t * pObj, * pRepr, * pObjNew; int i, Iter, fDisproved = 1; @@ -835,25 +891,23 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) // simulate one round and create classes Cec2_ManSimAlloc( p, pPars->nSimWords ); Cec2_ManSimulateCis( p ); - Cec2_ManSimulate( p, NULL ); + Cec2_ManSimulate( p, NULL, pMan ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected return 0; - Cec2_ManCreateClasses( p ); - if ( pPars->fVerbose ) - Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + Cec2_ManCreateClasses( p, pMan ); + Cec2_ManPrintStats( p, pPars, pMan ); // perform additinal simulation for ( i = 0; i < pPars->nSimRounds; i++ ) { Cec2_ManSimulateCis( p ); - Cec2_ManSimulate( p, NULL ); + Cec2_ManSimulate( p, NULL, pMan ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected return 0; - if ( pPars->fVerbose ) - Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + Cec2_ManPrintStats( p, pPars, pMan ); } // perform sweeping - pMan = Cec2_ManCreate( p, pPars ); + //pMan = Cec2_ManCreate( p, pPars ); for ( Iter = 0; fDisproved; Iter++ ) { fDisproved = 0; @@ -880,7 +934,7 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) } assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) ); pRepr = Gia_ObjReprObj( p, i ); - if ( pRepr == NULL || pRepr->fMark1 ) + if ( pRepr == NULL || pRepr->fMark1 || !~pRepr->Value ) continue; if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) { @@ -894,7 +948,7 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) //Vec_IntPushThree( pMan->vCexTriples, Gia_ObjId(p, pRepr), i, Abc_Var2Lit(p->iPatsPi, pObj->fPhase ^ pRepr->fPhase) ); // mark nodes as disproved fDisproved = 1; - if ( Iter > 5 ) + //if ( Iter > 5 ) continue; if ( Gia_ObjIsAnd(pRepr) ) pRepr->fMark1 = 1; @@ -903,12 +957,11 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) if ( fDisproved ) { //printf( "The number of pattern = %d.\n", p->iPatsPi ); - Cec2_ManSimulate( p, pMan->vCexTriples ); + Cec2_ManSimulate( p, pMan->vCexTriples, pMan ); if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected break; } - if ( pPars->fVerbose ) - Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + Cec2_ManPrintStats( p, pPars, pMan ); } Cec2_ManDestroy( pMan ); //Gia_ManEquivPrintClasses( p, 1, 0 ); @@ -916,13 +969,13 @@ int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) } void Cec2_ManSimulateTest( Gia_Man_t * p ) { - abctime clk = Abc_Clock(); + //abctime clk = Abc_Clock(); Cec2_Par_t Pars, * pPars = &Pars; Cec2_SetDefaultParams( pPars ); // Gia_ManComputeGiaEquivs( p, 100000, 0 ); // Gia_ManEquivPrintClasses( p, 1, 0 ); Cec2_ManPerformSweeping( p, pPars ); - Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); + //Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); } -- cgit v1.2.3 From 68dd7806355a423af3ea400ab7c605bd3bf566d3 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Sun, 19 Feb 2017 15:34:21 -0800 Subject: Adding new command to reset Satoko. Small fixes in watching list data structure. --- src/sat/satoko/cdb.h | 6 ++++++ src/sat/satoko/satoko.h | 2 ++ src/sat/satoko/solver_api.c | 48 ++++++++++++++++++++++++++++++++++++++++----- src/sat/satoko/types.h | 1 + src/sat/satoko/utils/heap.h | 5 +---- src/sat/satoko/watch_list.h | 10 ++++++++++ 6 files changed, 63 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/sat/satoko/cdb.h b/src/sat/satoko/cdb.h index 28686ff2..32b0bf93 100644 --- a/src/sat/satoko/cdb.h +++ b/src/sat/satoko/cdb.h @@ -81,6 +81,12 @@ static inline void cdb_remove(struct cdb *p, struct clause *clause) p->wasted += clause->size; } +static inline void cdb_clear(struct cdb *p) +{ + p->wasted = 0; + p->size = 0; +} + static inline unsigned cdb_capacity(struct cdb *p) { return p->cap; diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 2d3e056e..a0c4d216 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -80,6 +80,8 @@ struct satoko_stats { //===------------------------------------------------------------------------=== extern satoko_t *satoko_create(void); extern void satoko_destroy(satoko_t *); +extern void satoko_reset(satoko_t *); + extern void satoko_default_opts(satoko_opts_t *); extern void satoko_configure(satoko_t *, satoko_opts_t *); extern int satoko_parse_dimacs(char *, satoko_t **); diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index f758a1ef..90d04cfd 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -334,6 +334,41 @@ void satoko_unbookmark(satoko_t *s) s->book_trail = 0; } +void satoko_reset(satoko_t *s) +{ + vec_uint_clear(s->assumptions); + vec_uint_clear(s->final_conflict); + cdb_clear(s->all_clauses); + vec_uint_clear(s->originals); + vec_uint_clear(s->learnts); + vec_wl_clean(s->watches); + vec_act_clear(s->activity); + heap_clear(s->var_order); + vec_uint_clear(s->levels); + vec_uint_clear(s->reasons); + vec_char_clear(s->assigns); + vec_char_clear(s->polarity); + vec_uint_clear(s->trail); + vec_uint_clear(s->trail_lim); + b_queue_clean(s->bq_lbd); + b_queue_clean(s->bq_trail); + vec_uint_clear(s->temp_lits); + vec_char_clear(s->seen); + vec_uint_clear(s->tagged); + vec_uint_clear(s->stack); + vec_uint_clear(s->last_dlevel); + vec_uint_clear(s->stamps); + s->var_act_inc = VAR_ACT_INIT_INC; + s->clause_act_inc = CLAUSE_ACT_INIT_INC; + s->n_confl_bfr_reduce = s->opts.n_conf_fst_reduce; + s->RC1 = 1; + s->RC2 = s->opts.n_conf_fst_reduce; + s->book_cl_orig = 0; + s->book_cl_lrnt = 0; + s->book_vars = 0; + s->book_trail = 0; +} + void satoko_rollback(satoko_t *s) { unsigned i, cref; @@ -342,6 +377,11 @@ void satoko_rollback(satoko_t *s) struct clause **cl_to_remove; assert(solver_dlevel(s) == 0); + if (!s->book_vars) { + satoko_reset(s); + return; + } + cl_to_remove = satoko_alloc(struct clause *, n_originals + n_learnts); /* Mark clauses */ vec_uint_foreach_start(s->originals, cref, i, s->book_cl_orig) @@ -356,8 +396,10 @@ void satoko_rollback(satoko_t *s) vec_uint_shrink(s->originals, s->book_cl_orig); vec_uint_shrink(s->learnts, s->book_cl_lrnt); /* Shrink variable related vectors */ - for (i = s->book_vars; i < 2 * vec_char_size(s->assigns); i++) + for (i = s->book_vars; i < 2 * vec_char_size(s->assigns); i++) { vec_wl_at(s->watches, i)->size = 0; + vec_wl_at(s->watches, i)->n_bin = 0; + } s->watches->size = s->book_vars; vec_act_shrink(s->activity, s->book_vars); vec_uint_shrink(s->levels, s->book_vars); @@ -374,10 +416,6 @@ void satoko_rollback(satoko_t *s) s->book_cl_lrnt = 0; s->book_vars = 0; s->book_trail = 0; - if (!s->book_vars) { - s->all_clauses->size = 0; - s->all_clauses->wasted = 0; - } } void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars) diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h index 9c47ca7c..06c190ab 100644 --- a/src/sat/satoko/types.h +++ b/src/sat/satoko/types.h @@ -26,6 +26,7 @@ typedef vec_sdbl_t vec_act_t ; #define vec_act_free(vec) vec_sdbl_free(vec) #define vec_act_size(vec) vec_sdbl_size(vec) #define vec_act_data(vec) vec_sdbl_data(vec) +#define vec_act_clear(vec) vec_sdbl_clear(vec) #define vec_act_shrink(vec, size) vec_sdbl_shrink(vec, size) #define vec_act_at(vec, idx) vec_sdbl_at(vec, idx) #define vec_act_push_back(vec, value) vec_sdbl_push_back(vec, value) diff --git a/src/sat/satoko/utils/heap.h b/src/sat/satoko/utils/heap.h index 8b1d8f4b..391b8a7e 100644 --- a/src/sat/satoko/utils/heap.h +++ b/src/sat/satoko/utils/heap.h @@ -158,10 +158,7 @@ static inline void heap_build(heap_t *p, vec_uint_t *entries) static inline void heap_clear(heap_t *p) { - unsigned i; - int entry; - vec_int_foreach(p->indices, entry, i) - vec_int_assign(p->indices, i, -1); + vec_int_clear(p->indices); vec_uint_clear(p->data); } diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h index a36ab2bb..1bcbf3b4 100644 --- a/src/sat/satoko/watch_list.h +++ b/src/sat/satoko/watch_list.h @@ -160,6 +160,16 @@ static inline void vec_wl_free(vec_wl_t *vec_wl) satoko_free(vec_wl); } +static inline void vec_wl_clean(vec_wl_t *vec_wl) +{ + unsigned i; + for (i = 0; i < vec_wl->size; i++) { + vec_wl->watch_lists[i].size = 0; + vec_wl->watch_lists[i].n_bin = 0; + } + vec_wl->size = 0; +} + static inline void vec_wl_push(vec_wl_t *vec_wl) { if (vec_wl->size == vec_wl->cap) { -- cgit v1.2.3 From 2d1792040a8c09a12d70413ceb99bd11bb145c2b Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 15:57:13 -0800 Subject: working on pdr with wla --- src/base/wlc/wlcAbs.c | 16 ++++++---------- src/proof/pdr/pdrIncr.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 342d667f..8cc79722 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -323,7 +323,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); pPdrPars->fVerbose = pPars->fPdrVerbose; - pPdrPars->fVeryVerbose = 1; + pPdrPars->fVeryVerbose = 0; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) @@ -368,14 +368,10 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + if ( vClauses ) { - if ( Vec_VecSize( vClauses) == 1 ) { - Vec_VecFree( vClauses ); - vClauses = NULL; - } else { - assert( Vec_VecSize( vClauses) >= 2 ); - IPdr_ManRestore(pPdr, vClauses); - } + assert( Vec_VecSize( vClauses) >= 2 ); + IPdr_ManRestore( pPdr, vClauses ); } RetValue = IPdr_ManSolveInt( pPdr ); @@ -406,7 +402,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } // spurious CEX, continue solving - vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + vClauses = IPdr_ManSaveClauses( pPdr, 1 ); Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted @@ -465,7 +461,7 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) //pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this pPdrPars->fVerbose = pPars->fPdrVerbose; - pPdrPars->fVeryVerbose = 1; + pPdrPars->fVeryVerbose = 0; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) { diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index b1f126f4..4f66eeb4 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -66,6 +66,41 @@ void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs ) } } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IPdr_ManCheckClauses( Pdr_Man_t * p ) +{ + Pdr_Set_t * pCubeK; + Vec_Ptr_t * vArrayK; + int j, k, RetValue, kMax = Vec_PtrSize(p->vSolvers)-1; + int iStartFrame = 1; + + Vec_VecForEachLevelStartStop( p->vClauses, vArrayK, k, iStartFrame, kMax ) + { + Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j ) + { + RetValue = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0, 1 ); + + if ( !RetValue ) { + printf( "Cube[%d][%d] not inductive!\n", k, j ); + } + + assert( RetValue == 1 ); + } + } + + return 1; +} + /**Function************************************************************* Synopsis [] @@ -83,6 +118,11 @@ Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ) Vec_Vec_t * vClausesSaved; Pdr_Set_t * pCla; + if ( Vec_VecSize( p->vClauses ) == 1 ) + return NULL; + if ( Vec_VecSize( p->vClauses ) == 2 && fDropLast ) + return NULL; + if ( fDropLast ) vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses)-1 ); else @@ -147,9 +187,6 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) assert(vClauses); - printf( "IPdr restore:\n" ); - IPdr_ManPrintClauses( vClauses, 0, Aig_ManRegNum( p->pAig ) ); - Vec_VecFree(p->vClauses); p->vClauses = vClauses; @@ -197,8 +234,8 @@ int IPdr_ManSolveInt( Pdr_Man_t * p ) if ( Vec_VecSize(p->vClauses) == 0 ) Pdr_ManCreateSolver( p, (iFrame = 0) ); else { - iFrame = Vec_VecSize(p->vClauses); - Pdr_ManCreateSolver( p, iFrame ); + iFrame = Vec_VecSize(p->vClauses) - 1; + IPdr_ManCheckClauses( p ); } while ( 1 ) { -- cgit v1.2.3 From 1a66a5823a37123c099e63cb94bba1fd844487d1 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 16:09:59 -0800 Subject: working on pdr with wla --- src/base/wlc/wlcAbs.c | 2 +- src/proof/pdr/pdrIncr.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8cc79722..47bd9a3f 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -402,7 +402,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } // spurious CEX, continue solving - vClauses = IPdr_ManSaveClauses( pPdr, 1 ); + vClauses = IPdr_ManSaveClauses( pPdr, 0 ); Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 4f66eeb4..9f7dfd90 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -81,14 +81,16 @@ int IPdr_ManCheckClauses( Pdr_Man_t * p ) { Pdr_Set_t * pCubeK; Vec_Ptr_t * vArrayK; - int j, k, RetValue, kMax = Vec_PtrSize(p->vSolvers)-1; + int j, k, RetValue, kMax = Vec_PtrSize(p->vSolvers); int iStartFrame = 1; + int counter = 0; Vec_VecForEachLevelStartStop( p->vClauses, vArrayK, k, iStartFrame, kMax ) { Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j ) { - RetValue = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0, 1 ); + ++counter; + RetValue = Pdr_ManCheckCube( p, k - 1, pCubeK, NULL, 0, 0, 1 ); if ( !RetValue ) { printf( "Cube[%d][%d] not inductive!\n", k, j ); @@ -97,6 +99,7 @@ int IPdr_ManCheckClauses( Pdr_Man_t * p ) assert( RetValue == 1 ); } } + printf( "XXX: Pass check clauses! %d frames and %d clauses checked\n", k, counter ); return 1; } -- cgit v1.2.3 From 25ecc3d42973cd832d78b00cbed188171892325d Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 19:57:44 -0800 Subject: fixed a tricky bug: property should not be assumed true in the last frame --- src/proof/pdr/pdrIncr.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 9f7dfd90..09a06a27 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -99,7 +99,6 @@ int IPdr_ManCheckClauses( Pdr_Man_t * p ) assert( RetValue == 1 ); } } - printf( "XXX: Pass check clauses! %d frames and %d clauses checked\n", k, counter ); return 1; } @@ -149,7 +148,7 @@ Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ) SeeAlso [] ***********************************************************************/ -sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k ) +sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k, int nTotal ) { sat_solver * pSat; Vec_Ptr_t * vArrayK; @@ -165,7 +164,12 @@ sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k ) Vec_IntPush( p->vActVars, 0 ); // set the property output - Pdr_ManSetPropertyOutput( p, k ); + if ( k < nTotal - 1 ) + Pdr_ManSetPropertyOutput( p, k ); + + if (k == 0) + return pSat; + // add the clauses Vec_VecForEachLevelStart( p->vClauses, vArrayK, i, k ) Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, j ) @@ -194,7 +198,7 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) p->vClauses = vClauses; for ( i = 0; i < Vec_VecSize(p->vClauses); ++i ) - IPdr_ManSetSolver(p, i); + IPdr_ManSetSolver( p, i, Vec_VecSize( p->vClauses ) ); return 0; } -- cgit v1.2.3 From 222b3741a40af2913132ef385936b955bbc19b4d Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 10:13:18 -0800 Subject: fixed time profiling in pdr --- src/base/wlc/wlcAbs.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 47bd9a3f..902c060d 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -313,6 +313,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); + abctime pdrClk; Pdr_Man_t * pPdr; Vec_Vec_t * vClauses = NULL; int nIters, nNodes, nDcFlops, RetValue = -1; @@ -368,6 +369,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + pdrClk = Abc_Clock(); if ( vClauses ) { assert( Vec_VecSize( vClauses) >= 2 ); @@ -375,6 +377,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } RetValue = IPdr_ManSolveInt( pPdr ); + pPdr->tTotal += Abc_Clock() - pdrClk; pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; @@ -403,6 +406,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // spurious CEX, continue solving vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted -- cgit v1.2.3 From 19510bd38e46fd913bf6dc29393938e50fd717ee Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 11:07:12 -0800 Subject: added datastructure for %pdra options --- src/base/wlc/wlc.h | 18 +++++++++++++++++- src/base/wlc/wlcAbs.c | 27 ++++++++++++++++++++++++++- src/base/wlc/wlcCom.c | 4 ++-- 3 files changed, 45 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 9ca56917..cf8bdab4 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -174,6 +174,21 @@ struct Wlc_Par_t_ int fPdrVerbose; // verbose output }; + +typedef struct WlcPdr_Par_t_ WlcPdr_Par_t; +struct WlcPdr_Par_t_ +{ + int nBitsAdd; // adder bit-width + int nBitsMul; // multiplier bit-widht + int nBitsMux; // MUX bit-width + int nBitsFlop; // flop bit-width + int nIterMax; // the max number of iterations + int fXorOutput; // XOR outputs of word-level miter + int fVerbose; // verbose output + int fPdrVerbose; // verbose output +}; + + static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -277,7 +292,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); -extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ @@ -286,6 +301,7 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); +extern void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 902c060d..8fde7f56 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -38,6 +38,31 @@ extern int IPdr_ManSolveInt( Pdr_Man_t * p ); /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(WlcPdr_Par_t) ); + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-width + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->nIterMax = 1000; // the max number of iterations + pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fVerbose = 0; // verbose output + pPars->fPdrVerbose = 0; // show verbose PDR output +} + /**Function************************************************************* Synopsis [Mark operators that meet the abstraction criteria.] @@ -310,7 +335,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec SeeAlso [] ***********************************************************************/ -int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) { abctime clk = Abc_Clock(); abctime pdrClk; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index e980752b..d30b376e 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -458,9 +458,9 @@ usage: int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - Wlc_Par_t Pars, * pPars = &Pars; + WlcPdr_Par_t Pars, * pPars = &Pars; int c; - Wlc_ManSetDefaultParams( pPars ); + WlcPdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) { -- cgit v1.2.3 From ac1eb60db9129110e7795614ad82d85cb74d854e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 20 Feb 2017 12:32:32 -0800 Subject: Experiments with SAT sweeping. --- src/base/abci/abc.c | 2 +- src/proof/cec/cecSat.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 4c37242d..466af66a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43019,7 +43019,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); -Cec2_ManSimulateTest( pAbc->pGia ); +//Cec2_ManSimulateTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; usage: diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c index 88397550..97bbb7d3 100644 --- a/src/proof/cec/cecSat.c +++ b/src/proof/cec/cecSat.c @@ -37,6 +37,7 @@ struct Cec2_Par_t_ int nSimRounds; // simulation rounds int nConfLimit; // SAT solver conflict limit int fIsMiter; // this is a miter + int fUseCones; // use logic cones int fVeryVerbose; // verbose stats int fVerbose; // verbose stats }; @@ -54,6 +55,7 @@ struct Cec2_Man_t_ Vec_Ptr_t * vFanins; // CNF construction Vec_Wrd_t * vSims; // CI simulation info Vec_Int_t * vNodesNew; // nodes + Vec_Int_t * vSatVars; // nodes Vec_Int_t * vObjSatPairs; // nodes Vec_Int_t * vCexTriples; // nodes // statistics @@ -95,6 +97,7 @@ void Cec2_SetDefaultParams( Cec2_Par_t * p ) p->nSimRounds = 4; // simulation rounds p->nConfLimit = 1000; // conflict limit at a node p->fIsMiter = 0; // this is a miter + p->fUseCones = 1; // use logic cones p->fVeryVerbose = 0; // verbose stats p->fVerbose = 1; // verbose stats } @@ -668,6 +671,7 @@ Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) p->vFrontier = Vec_PtrAlloc( 1000 ); p->vFanins = Vec_PtrAlloc( 100 ); p->vNodesNew = Vec_IntAlloc( 100 ); + p->vSatVars = Vec_IntAlloc( 100 ); p->vObjSatPairs = Vec_IntAlloc( 100 ); p->vCexTriples = Vec_IntAlloc( 100 ); // remember pointer to the solver in the AIG manager @@ -702,6 +706,7 @@ void Cec2_ManDestroy( Cec2_Man_t * p ) Vec_PtrFreeP( &p->vFrontier ); Vec_PtrFreeP( &p->vFanins ); Vec_IntFreeP( &p->vNodesNew ); + Vec_IntFreeP( &p->vSatVars ); Vec_IntFreeP( &p->vObjSatPairs ); Vec_IntFreeP( &p->vCexTriples ); ABC_FREE( p ); @@ -767,7 +772,10 @@ void Cec2_ManCollect_rec( Cec2_Man_t * p, int iObj ) Gia_ObjSetTravIdCurrentId(p->pNew, iObj); pObj = Gia_ManObj( p->pNew, iObj ); if ( Cec2_ObjSatId(p->pNew, pObj) >= 0 ) + { Vec_IntPush( p->vNodesNew, iObj ); + Vec_IntPush( p->vSatVars, Cec2_ObjSatId(p->pNew, pObj) ); + } if ( !iObj ) return; if ( Gia_ObjIsAnd(pObj) ) @@ -788,19 +796,21 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) if (iObj1 < iObj0) iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0; assert( iObj0 < iObj1 ); - assert( solver_varnum(p->pSat) == 0 ); - if ( !iObj0 ) + assert( p->pPars->fUseCones || solver_varnum(p->pSat) == 0 ); + if ( !iObj0 && Cec2_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 ) Cec2_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), satoko_add_variable(p->pSat, 0) ); iVar0 = Cec2_ObjGetCnfVar( p, iObj0 ); iVar1 = Cec2_ObjGetCnfVar( p, iObj1 ); // collect inputs and internal nodes Vec_IntClear( p->vNodesNew ); + Vec_IntClear( p->vSatVars ); Vec_IntClear( p->vObjSatPairs ); Gia_ManIncrementTravId( p->pNew ); Cec2_ManCollect_rec( p, iObj0 ); Cec2_ManCollect_rec( p, iObj1 ); //printf( "%d ", Vec_IntSize(p->vNodesNew) ); // solve direct + if ( p->pPars->fUseCones ) satoko_mark_cone( p->pSat, Vec_IntArray(p->vSatVars), Vec_IntSize(p->vSatVars) ); satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) ); satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) ); status = satoko_solve( p->pSat ); @@ -815,8 +825,11 @@ int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) satoko_assump_pop( p->pSat ); satoko_assump_pop( p->pSat ); } + if ( p->pPars->fUseCones ) satoko_unmark_cone( p->pSat, Vec_IntArray(p->vSatVars), Vec_IntSize(p->vSatVars) ); //if ( status == SATOKO_SAT ) // Cec2_ManVerify( p->pNew, iObj0, iObj1, fPhase, p->pSat ); + if ( p->pPars->fUseCones ) + return status; Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i ) Cec2_ObjCleanSatId( p->pNew, pObj ); return status; @@ -855,6 +868,8 @@ int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) assert( 0 ); p->timeSatUndec += Abc_Clock() - clk; } + if ( p->pPars->fUseCones ) + return RetValue; clk = Abc_Clock(); satoko_rollback( p->pSat ); p->timeExtra += Abc_Clock() - clk; -- cgit v1.2.3 From 9f43c84501cf8c5a8ae74cc5bebea63dafc3a714 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 12:51:04 -0800 Subject: added options of checking and pushing to %pdra --- src/base/wlc/wlc.h | 2 ++ src/base/wlc/wlcAbs.c | 10 ++++++---- src/base/wlc/wlcCom.c | 12 ++++++++++-- src/proof/pdr/pdrIncr.c | 37 +++++++++++++++++++++++++++++++++---- 4 files changed, 51 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index cf8bdab4..9cb34bf3 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -184,6 +184,8 @@ struct WlcPdr_Par_t_ int nBitsFlop; // flop bit-width int nIterMax; // the max number of iterations int fXorOutput; // XOR outputs of word-level miter + int fCheckClauses; // Check clauses in the reloaded trace + int fPushClauses; // Push clauses in the reloaded trace int fVerbose; // verbose output int fPdrVerbose; // verbose output }; diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8fde7f56..fbaa1b8a 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -32,7 +32,7 @@ ABC_NAMESPACE_IMPL_START extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); -extern int IPdr_ManSolveInt( Pdr_Man_t * p ); +extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -59,6 +59,8 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) pPars->nBitsFlop = ABC_INFINITY; // flop bit-width pPars->nIterMax = 1000; // the max number of iterations pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fCheckClauses = 1; // Check clauses in the reloaded trace + pPars->fPushClauses = 0; // Push clauses in the reloaded trace pPars->fVerbose = 0; // verbose output pPars->fPdrVerbose = 0; // show verbose PDR output } @@ -76,7 +78,7 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; @@ -197,7 +199,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -401,7 +403,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) IPdr_ManRestore( pPdr, vClauses ); } - RetValue = IPdr_ManSolveInt( pPdr ); + RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses ); pPdr->tTotal += Abc_Clock() - pdrClk; pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index d30b376e..7801abc6 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -462,7 +462,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; WlcPdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF ) { switch ( c ) { @@ -524,6 +524,12 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'x': pPars->fXorOutput ^= 1; break; + case 'c': + pPars->fCheckClauses ^= 1; + break; + case 'p': + pPars->fPushClauses ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -544,7 +550,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Wlc_NtkPdrAbs( pNtk, pPars ); return 0; usage: - Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-cpxvwh]\n" ); Abc_Print( -2, "\t abstraction for word-level networks\n" ); Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); @@ -552,6 +558,8 @@ usage: Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle checking clauses in the reloaded trace [default = %s]\n", pPars->fCheckClauses? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle pushing clauses in the reloaded trace [default = %s]\n", pPars->fPushClauses? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 09a06a27..85403a7d 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -68,7 +68,9 @@ void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs ) /**Function************************************************************* - Synopsis [] + Synopsis [ Check if each cube c_k in frame k satisfies the query + R_{k-1} && T && !c_k && c_k' (must be UNSAT). + Return True if all cubes pass the check. ] Description [] @@ -214,7 +216,7 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) SeeAlso [] ***********************************************************************/ -int IPdr_ManSolveInt( Pdr_Man_t * p ) +int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ) { int fPrintClauses = 0; Pdr_Set_t * pCube = NULL; @@ -242,7 +244,34 @@ int IPdr_ManSolveInt( Pdr_Man_t * p ) Pdr_ManCreateSolver( p, (iFrame = 0) ); else { iFrame = Vec_VecSize(p->vClauses) - 1; - IPdr_ManCheckClauses( p ); + + if ( fCheckClauses ) + { + if ( p->pPars->fVerbose ) + Abc_Print( 1, "IPDR: Checking the reloaded length-%d trace...", iFrame + 1 ) ; + IPdr_ManCheckClauses( p ); + if ( p->pPars->fVerbose ) + Abc_Print( 1, " Passed!\n" ) ; + } + + if ( fPushClauses ) + { + p->iUseFrame = Abc_MaxInt(iFrame, 1); + + if ( p->pPars->fVerbose ) + { + Abc_Print( 1, "IPDR: Pushing the reloaded clauses. Before:\n" ); + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + } + + RetValue = Pdr_ManPushClauses( p ); + + if ( p->pPars->fVerbose ) + { + Abc_Print( 1, "IPDR: Finished pushing. After:\n" ); + Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); + } + } } while ( 1 ) { @@ -602,7 +631,7 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) p = Pdr_ManStart( pAig, pPars, NULL ); while ( 1 ) { - RetValue = IPdr_ManSolveInt( p ); + RetValue = IPdr_ManSolveInt( p, 1, 0 ); if ( RetValue == -1 && pPars->iFrame == pPars->nFrameMax) { vClausesSaved = IPdr_ManSaveClauses( p, 1 ); -- cgit v1.2.3 From c5e9506f5d5a5303b9df453fce7f313147799276 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 12:58:20 -0800 Subject: small tweaks in %pdra -p --- src/proof/pdr/pdrIncr.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 85403a7d..6de86c18 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -271,6 +271,13 @@ int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ) Abc_Print( 1, "IPDR: Finished pushing. After:\n" ); Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart ); } + + if ( RetValue ) + { + Pdr_ManReportInvariant( p ); + Pdr_ManVerifyInvariant( p ); + return 1; + } } } while ( 1 ) -- cgit v1.2.3 From 9d46d84b278acac3ca5983ddb7fbd41a9a4b926b Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Tue, 21 Feb 2017 18:37:06 -0300 Subject: Small tweak to rollback behavior. --- src/sat/satoko/solver.c | 3 +++ src/sat/satoko/solver.h | 1 + src/sat/satoko/solver_api.c | 4 ++++ 3 files changed, 8 insertions(+) (limited to 'src') diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c index 3738129b..af3dcffb 100644 --- a/src/sat/satoko/solver.c +++ b/src/sat/satoko/solver.c @@ -397,6 +397,9 @@ static inline void solver_garbage_collect(solver_t *s) unsigned *array; struct cdb *new_cdb = cdb_alloc(cdb_capacity(s->all_clauses) - cdb_wasted(s->all_clauses)); + if (s->book_cdb) + s->book_cdb = 0; + for (i = 0; i < 2 * vec_char_size(s->assigns); i++) { struct watcher *w; watch_list_foreach(s->watches, w, i) diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h index dcae8f6e..33f8ce88 100644 --- a/src/sat/satoko/solver.h +++ b/src/sat/satoko/solver.h @@ -95,6 +95,7 @@ struct solver_t_ { /* Bookmark */ unsigned book_cl_orig; /* Bookmark for orignal problem clauses vector */ unsigned book_cl_lrnt; /* Bookmark for learnt clauses vector */ + unsigned book_cdb; /* Bookmark clause database size */ unsigned book_vars; /* Bookmark number of variables */ unsigned book_trail; /* Bookmark trail size */ diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 90d04cfd..3cb9f3d3 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -330,6 +330,7 @@ void satoko_unbookmark(satoko_t *s) { s->book_cl_orig = 0; s->book_cl_lrnt = 0; + s->book_cdb = 0; s->book_vars = 0; s->book_trail = 0; } @@ -365,6 +366,7 @@ void satoko_reset(satoko_t *s) s->RC2 = s->opts.n_conf_fst_reduce; s->book_cl_orig = 0; s->book_cl_lrnt = 0; + s->book_cdb = 0; s->book_vars = 0; s->book_trail = 0; } @@ -412,6 +414,8 @@ void satoko_rollback(satoko_t *s) /* Rewind solver and cancel level 0 assignments to the trail */ solver_cancel_until(s, 0); vec_uint_shrink(s->trail, s->book_trail); + if (s->book_cdb) + s->all_clauses->size = s->book_cdb; s->book_cl_orig = 0; s->book_cl_lrnt = 0; s->book_vars = 0; -- cgit v1.2.3 From 01e6beea8e617eb5ef4f9b621b009eded9498a1f Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Tue, 21 Feb 2017 20:06:13 -0800 Subject: clean up --- src/base/wlc/wlc.h | 18 +----------------- src/base/wlc/wlcAbs.c | 33 +++------------------------------ src/base/wlc/wlcCom.c | 4 ++-- src/base/wlc/wlcNtk.c | 2 ++ 4 files changed, 8 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 9cb34bf3..686d9f00 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -163,20 +163,6 @@ struct Wlc_Ntk_t_ typedef struct Wlc_Par_t_ Wlc_Par_t; struct Wlc_Par_t_ -{ - int nBitsAdd; // adder bit-width - int nBitsMul; // multiplier bit-widht - int nBitsMux; // MUX bit-width - int nBitsFlop; // flop bit-width - int nIterMax; // the max number of iterations - int fXorOutput; // XOR outputs of word-level miter - int fVerbose; // verbose output - int fPdrVerbose; // verbose output -}; - - -typedef struct WlcPdr_Par_t_ WlcPdr_Par_t; -struct WlcPdr_Par_t_ { int nBitsAdd; // adder bit-width int nBitsMul; // multiplier bit-widht @@ -190,7 +176,6 @@ struct WlcPdr_Par_t_ int fPdrVerbose; // verbose output }; - static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -294,7 +279,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); -extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ @@ -303,7 +288,6 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); -extern void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index fbaa1b8a..1e5df918 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -38,33 +38,6 @@ extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPu /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) -{ - memset( pPars, 0, sizeof(WlcPdr_Par_t) ); - pPars->nBitsAdd = ABC_INFINITY; // adder bit-width - pPars->nBitsMul = ABC_INFINITY; // multiplier bit-width - pPars->nBitsMux = ABC_INFINITY; // MUX bit-width - pPars->nBitsFlop = ABC_INFINITY; // flop bit-width - pPars->nIterMax = 1000; // the max number of iterations - pPars->fXorOutput = 1; // XOR outputs of word-level miter - pPars->fCheckClauses = 1; // Check clauses in the reloaded trace - pPars->fPushClauses = 0; // Push clauses in the reloaded trace - pPars->fVerbose = 0; // verbose output - pPars->fPdrVerbose = 0; // show verbose PDR output -} - /**Function************************************************************* Synopsis [Mark operators that meet the abstraction criteria.] @@ -78,7 +51,7 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; @@ -199,7 +172,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -337,7 +310,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec SeeAlso [] ***********************************************************************/ -int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); abctime pdrClk; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 7801abc6..df736e70 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -458,9 +458,9 @@ usage: int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - WlcPdr_Par_t Pars, * pPars = &Pars; + Wlc_Par_t Pars, * pPars = &Pars; int c; - WlcPdr_ManSetDefaultParams( pPars ); + Wlc_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF ) { diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index e6ab0739..c8fc15a7 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -114,6 +114,8 @@ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) pPars->nBitsFlop = ABC_INFINITY; // flop bit-width pPars->nIterMax = 1000; // the max number of iterations pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fCheckClauses = 1; // Check clauses in the reloaded trace + pPars->fPushClauses = 0; // Push clauses in the reloaded trace pPars->fVerbose = 0; // verbose output` pPars->fPdrVerbose = 0; // show verbose PDR output } -- cgit v1.2.3 From fb2fbd70bd31eb08dd50c66788d5165697ca6925 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Tue, 21 Feb 2017 20:10:11 -0800 Subject: clean up --- src/base/abci/abc.c | 269 ---------------------------------------------------- 1 file changed, 269 deletions(-) (limited to 'src') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0645c6e3..52684f8c 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -333,7 +333,6 @@ static int Abc_CommandBm2 ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSaucy ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTestCex ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandIPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); #ifdef ABC_USE_CUDD static int Abc_CommandReconcile ( Abc_Frame_t * pAbc, int argc, char ** argv ); #endif @@ -984,7 +983,6 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); Cmd_CommandAdd( pAbc, "Verification", "testcex", Abc_CommandTestCex, 0 ); Cmd_CommandAdd( pAbc, "Verification", "pdr", Abc_CommandPdr, 0 ); - Cmd_CommandAdd( pAbc, "Verification", "ipdr", Abc_CommandIPdr, 0 ); #ifdef ABC_USE_CUDD Cmd_CommandAdd( pAbc, "Verification", "reconcile", Abc_CommandReconcile, 1 ); #endif @@ -26417,273 +26415,6 @@ usage: - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - extern int Abc_NtkDarIPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - Pdr_Par_t Pars, * pPars = &Pars; - Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); - int c; - Pdr_ManSetDefaultParams( pPars ); - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) - { - switch ( c ) - { - case 'M': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRecycle = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRecycle < 0 ) - goto usage; - break; - case 'F': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nFrameMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nFrameMax < 0 ) - goto usage; - break; - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfLimit < 0 ) - goto usage; - break; - case 'D': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfGenLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfGenLimit < 0 ) - goto usage; - break; - case 'Q': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRestLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRestLimit < 0 ) - goto usage; - break; - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOut = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOut < 0 ) - goto usage; - break; - case 'H': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOutOne = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOutOne < 0 ) - goto usage; - break; - case 'G': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOutGap = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOutGap < 0 ) - goto usage; - break; - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRandomSeed = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRandomSeed < 0 ) - goto usage; - break; - case 'a': - pPars->fSolveAll ^= 1; - break; - case 'x': - pPars->fStoreCex ^= 1; - break; - case 'r': - pPars->fTwoRounds ^= 1; - break; - case 'm': - pPars->fMonoCnf ^= 1; - break; - case 'u': - pPars->fNewXSim ^= 1; - break; - case 'y': - pPars->fFlopPrio ^= 1; - break; - case 'f': - pPars->fFlopOrder ^= 1; - break; - case 's': - pPars->fShortest ^= 1; - break; - case 'i': - pPars->fShiftStart ^= 1; - break; - case 'p': - pPars->fReuseProofOblig ^= 1; - break; - case 'd': - pPars->fDumpInv ^= 1; - break; - case 'e': - pPars->fUseSupp ^= 1; - break; - case 'g': - pPars->fSkipGeneral ^= 1; - break; - case 'j': - pPars->fSimpleGeneral ^= 1; - break; - case 'o': - pPars->fUsePropOut ^= 1; - break; - case 'n': - pPars->fSkipDown ^= 1; - break; - case 'c': - pPars->fCtgs ^= 1; - break; - case 't': - pPars->fUseAbs ^= 1; - break; - case 'k': - pPars->fUseSimpleRef ^= 1; - break; - case 'v': - pPars->fVerbose ^= 1; - break; - case 'w': - pPars->fVeryVerbose ^= 1; - break; - case 'z': - pPars->fNotVerbose ^= 1; - break; - case 'h': - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - Abc_Print( -2, "There is no current network.\n"); - return 0; - } - if ( Abc_NtkLatchNum(pNtk) == 0 ) - { - Abc_Print( 0, "The current network is combinational.\n"); - return 0; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - Abc_Print( -2, "The current network is not an AIG (run \"strash\").\n"); - return 0; - } - // run the procedure - pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = Abc_NtkDarIPdr( pNtk, pPars ); - pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; - Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); - if ( pNtk->vSeqModelVec ) - Abc_FrameReplaceCexVec( pAbc, &pNtk->vSeqModelVec ); - else - Abc_FrameReplaceCex( pAbc, &pNtk->pSeqModel ); - return 0; - -usage: - Abc_Print( -2, "usage: ipdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); - Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); - Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); - Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); - Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); - Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); - Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); - Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); - Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); - Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); - Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); - Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); - Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); - Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); - Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); - Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); - Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); - Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); - Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); - Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); - Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); - Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); - Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); - Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); - Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); - Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); - Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); - Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); - Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); - Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); - Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); - Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n\n"); - Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); - Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); - Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); - Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); - - - return 1; } -- cgit v1.2.3 From 96ccd24e6e5e2489d165bc14ac81136255a7b1f8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Feb 2017 20:39:52 -0800 Subject: Changes to Visual Studio project file to support 'pdra'. --- src/proof/pdr/module.make | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/proof/pdr/module.make b/src/proof/pdr/module.make index 4c177a21..1dee93aa 100644 --- a/src/proof/pdr/module.make +++ b/src/proof/pdr/module.make @@ -1,9 +1,9 @@ SRC += src/proof/pdr/pdrCnf.c \ src/proof/pdr/pdrCore.c \ + src/proof/pdr/pdrIncr.c \ src/proof/pdr/pdrInv.c \ src/proof/pdr/pdrMan.c \ src/proof/pdr/pdrSat.c \ src/proof/pdr/pdrTsim.c \ src/proof/pdr/pdrTsim2.c \ - src/proof/pdr/pdrUtil.c \ - src/proof/pdr/pdrIncr.c + src/proof/pdr/pdrUtil.c -- cgit v1.2.3 From 53b1d46b8d19e491679d9374c9758b09e2becf59 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Feb 2017 22:20:03 -0800 Subject: Remapping flops in '%pdra. --- src/base/wlc/wlcAbs.c | 95 ++++++++++++++++++++++++++++++++++++++++++------- src/proof/pdr/pdrIncr.c | 13 +++++-- 2 files changed, 94 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 1e5df918..e33424f7 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [wlcAbs1.c] + FileName [wlcAbs.c] SystemName [ABC: Logic synthesis and verification system.] @@ -8,13 +8,13 @@ Synopsis [Abstraction for word-level networks.] - Author [Alan Mishchenko] + Author [Yen-Sheng Ho, Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - August 22, 2014.] - Revision [$Id: wlcAbs1.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + Revision [$Id: wlcAbs.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -31,7 +31,7 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); -extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); +extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap ); extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ); //////////////////////////////////////////////////////////////////////// @@ -134,7 +134,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * Wlc_NtkForEachCo( p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); - +/* Vec_IntClear(vFlops); Wlc_NtkForEachCi( p, pObj, i ) { if ( !Wlc_ObjIsPi(pObj) ) { @@ -142,7 +142,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * pObj->Mark = 1; } } - +*/ Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); @@ -172,7 +172,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, Vec_Int_t ** pvFlops, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -183,7 +183,10 @@ static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUn Vec_BitFree( vLeaves ); pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); Vec_IntFree( vPisOld ); - Vec_IntFree( vFlops ); + if ( pvFlops ) + *pvFlops = vFlops; + else + Vec_IntFree( vFlops ); if ( pvPisNew ) *pvPisNew = vPisNew; else @@ -299,6 +302,55 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec return nNodes; } +/**Function************************************************************* + + Synopsis [Computes the map for remapping flop IDs used in the clauses.] + + Description [Takes the original network (Wlc_Ntk_t) and the array of word-level + flops used in the old abstraction (vFfOld) and those used in the new abstraction + (vFfNew). Returns the integer map, which remaps every binary flop found + in the old abstraction into a binary flop found in the new abstraction.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkFlopsRemap( Wlc_Ntk_t * p, Vec_Int_t * vFfOld, Vec_Int_t * vFfNew ) +{ + Vec_Int_t * vMap = Vec_IntAlloc( 1000 ); // the resulting map + Vec_Int_t * vMapFfNew2Bit1 = Vec_IntAlloc( 1000 ); // first binary bit of each new word-level flop + int i, b, iFfOld, iFfNew, iBit1New, nBits = 0; + // map object IDs of old flops into their flop indexes + Vec_Int_t * vMapFfObj2FfId = Vec_IntStartFull( Wlc_NtkObjNumMax(p) ); + Vec_IntForEachEntry( vFfNew, iFfNew, i ) + Vec_IntWriteEntry( vMapFfObj2FfId, iFfNew, i ); + // map each new flop index into its first bit + Vec_IntForEachEntry( vFfNew, iFfNew, i ) + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfNew ); + int nRange = Wlc_ObjRange( pObj ); + Vec_IntPush( vMapFfNew2Bit1, nBits ); + nBits += nRange; + } + assert( Vec_IntSize(vMapFfNew2Bit1) == Vec_IntSize(vFfNew) ); + // remap old binary flops into new binary flops + Vec_IntForEachEntry( vFfOld, iFfOld, i ) + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfOld ); + int nRange = Wlc_ObjRange( pObj ); + iFfNew = Vec_IntEntry( vMapFfObj2FfId, iFfOld ); + assert( iFfNew >= 0 ); // every old flop should be present in the new abstraction + // find the first bit of this new flop + iBit1New = Vec_IntEntry( vMapFfNew2Bit1, iFfNew ); + for ( b = 0; b < nRange; b++ ) + Vec_IntPush( vMap, iBit1New + b ); + } + Vec_IntFree( vMapFfNew2Bit1 ); + Vec_IntFree( vMapFfObj2FfId ); + return vMap; +} + /**Function************************************************************* Synopsis [Performs PDR with word-level abstraction.] @@ -316,7 +368,8 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) abctime pdrClk; Pdr_Man_t * pPdr; Vec_Vec_t * vClauses = NULL; - int nIters, nNodes, nDcFlops, RetValue = -1; + Vec_Int_t * vFfOld = NULL, * vFfNew = NULL, * vMap = NULL; + int nIters, nNodes, nDcFlops, RetValue = -1, nGiaFfNumOld = -1; // start the bitmap to mark objects that cannot be abstracted because of refinement // currently, this bitmap is empty because abstraction begins without refinement Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); @@ -339,9 +392,25 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) printf( "\nIteration %d:\n", nIters ); // get abstracted GIA and the set of pseudo-PIs (vPisNew) - pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, &vFfNew, pPars->fVerbose ); pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + // map old flops into new flops + if ( vFfOld ) + { + assert( nGiaFfNumOld >= 0 ); + vMap = Wlc_NtkFlopsRemap( p, vFfOld, vFfNew ); + //Vec_IntPrint( vMap ); + // if reset flop was added in the previous iteration, it will be added again in this iteration + // remap the last flop (reset flop) into the last flop (reset flop) of the current AIG + if ( Vec_IntSize(vMap) + 1 == nGiaFfNumOld ) + Vec_IntPush( vMap, Gia_ManRegNum(pGia)-1 ); + assert( Vec_IntSize(vMap) == nGiaFfNumOld ); + Vec_IntFreeP( &vFfOld ); + } + ABC_SWAP( Vec_Int_t *, vFfOld, vFfNew ); + nGiaFfNumOld = Gia_ManRegNum(pGia); + // if the abstraction has flops with DC-init state, // new PIs were introduced by bit-blasting at the end of the PI list // here we move these variables to be *before* PPIs, because @@ -373,8 +442,9 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) if ( vClauses ) { assert( Vec_VecSize( vClauses) >= 2 ); - IPdr_ManRestore( pPdr, vClauses ); + IPdr_ManRestore( pPdr, vClauses, vMap ); } + Vec_IntFreeP( &vMap ); RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses ); pPdr->tTotal += Abc_Clock() - pdrClk; @@ -418,6 +488,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Aig_ManStop( pAig ); } + Vec_IntFreeP( &vFfOld ); Vec_BitFree( vUnmark ); // report the result if ( pPars->fVerbose ) @@ -479,7 +550,7 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) printf( "\nIteration %d:\n", nIters ); // get abstracted GIA and the set of pseudo-PIs (vPisNew) - pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, NULL, pPars->fVerbose ); pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); // if the abstraction has flops with DC-init state, diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c index 6de86c18..3fcd3d31 100644 --- a/src/proof/pdr/pdrIncr.c +++ b/src/proof/pdr/pdrIncr.c @@ -190,7 +190,7 @@ sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k, int nTotal ) SeeAlso [] ***********************************************************************/ -int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) +int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap ) { int i; @@ -199,6 +199,15 @@ int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ) Vec_VecFree(p->vClauses); p->vClauses = vClauses; + // remap clause literals using mapping (old flop -> new flop) found in array vMap + if ( vMap ) + { + Pdr_Set_t * pSet; int j, k; + Vec_VecForEachEntry( Pdr_Set_t *, vClauses, pSet, i, j ) + for ( k = 0; k < pSet->nLits; k++ ) + pSet->Lits[k] = Abc_Lit2LitV( Vec_IntArray(vMap), pSet->Lits[k] ); + } + for ( i = 0; i < Vec_VecSize(p->vClauses); ++i ) IPdr_ManSetSolver( p, i, Vec_VecSize( p->vClauses ) ); @@ -646,7 +655,7 @@ int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars ) Pdr_ManStop( p ); p = Pdr_ManStart( pAig, pPars, NULL ); - IPdr_ManRestore( p, vClausesSaved ); + IPdr_ManRestore( p, vClausesSaved, NULL ); pPars->nFrameMax = pPars->nFrameMax << 1; -- cgit v1.2.3 From dd8cc7e9a27e2bd962d612911c6fd9508c6c1e0d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 22 Feb 2017 13:03:53 -0800 Subject: Removing unused procedure. --- src/aig/gia/gia.h | 1 - src/aig/gia/giaUtil.c | 19 ------------------- 2 files changed, 20 deletions(-) (limited to 'src') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 10804850..5ad87008 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1588,7 +1588,6 @@ extern void Gia_ManSwapPos( Gia_Man_t * p, int i ); extern Vec_Int_t * Gia_ManSaveValue( Gia_Man_t * p ); extern void Gia_ManLoadValue( Gia_Man_t * p, Vec_Int_t * vValues ); extern Vec_Int_t * Gia_ManFirstFanouts( Gia_Man_t * p ); -extern void Gia_ManDetectMuxes( Gia_Man_t * p ); /*=== giaCTas.c ===========================================================*/ typedef struct Tas_Man_t_ Tas_Man_t; diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index d100b6c1..c7af642e 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2050,25 +2050,6 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName ) Vec_WrdFree( vTruths ); } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManDetectMuxes( Gia_Man_t * p ) -{ - Gia_Obj_t * pObj = NULL, * pNodeT, * pNodeE; int i; - Gia_ManForEachObj( p, pObj, i ); - if ( Gia_ObjIsAnd(pObj) && Gia_ObjRecognizeMux(pObj, &pNodeT, &pNodeE) ) - pObj->fMark0 = 1; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3