mirror of https://github.com/YosysHQ/abc.git
Merge pull request #534 from zxxr1113/scorr2-upstream
new command &scorr2 extended from &scorr
This commit is contained in:
commit
4e1b34d744
|
|
@ -6685,6 +6685,14 @@ SOURCE=.\src\proof\cec\cecCorr.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\proof\cec\cecCorr2.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\proof\cec\cecCorrCert.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\src\proof\cec\cecCorrDyn.c
|
SOURCE=.\src\proof\cec\cecCorrDyn.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
|
||||||
|
|
@ -1836,6 +1836,9 @@ extern Vec_Int_t * Tas_ReadModel( Tas_Man_t * p );
|
||||||
extern void Tas_ManSatPrintStats( Tas_Man_t * p );
|
extern void Tas_ManSatPrintStats( Tas_Man_t * p );
|
||||||
extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
|
extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
|
||||||
extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs );
|
extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs );
|
||||||
|
extern void Tas_ManSetConflictNum( Tas_Man_t * p, int Num );
|
||||||
|
extern void Tas_ManSyncCore( Tas_Man_t * p );
|
||||||
|
extern Vec_Int_t * Tas_ManSolveRoots( Tas_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose );
|
||||||
|
|
||||||
/*=== giaDecGraph.c ===========================================================*/
|
/*=== giaDecGraph.c ===========================================================*/
|
||||||
extern Gia_Man_t* Gia_ManDecGraph( Gia_Man_t* p );
|
extern Gia_Man_t* Gia_ManDecGraph( Gia_Man_t* p );
|
||||||
|
|
@ -1884,4 +1887,3 @@ ABC_NAMESPACE_HEADER_END
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// END OF FILE ///
|
/// END OF FILE ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ struct Tas_Man_t_
|
||||||
{
|
{
|
||||||
Tas_Par_t Pars; // parameters
|
Tas_Par_t Pars; // parameters
|
||||||
Gia_Man_t * pAig; // AIG manager
|
Gia_Man_t * pAig; // AIG manager
|
||||||
|
int nSyncedObjs; // pAig objects already prepped (Value/marks/refs) for resident reuse
|
||||||
Tas_Que_t pProp; // propagation queue
|
Tas_Que_t pProp; // propagation queue
|
||||||
Tas_Que_t pJust; // justification queue
|
Tas_Que_t pJust; // justification queue
|
||||||
Tas_Que_t pClauses; // clause queue
|
Tas_Que_t pClauses; // clause queue
|
||||||
|
|
@ -90,6 +91,9 @@ struct Tas_Man_t_
|
||||||
Vec_Int_t * vLevReas; // levels and decisions
|
Vec_Int_t * vLevReas; // levels and decisions
|
||||||
Vec_Int_t * vModel; // satisfying assignment
|
Vec_Int_t * vModel; // satisfying assignment
|
||||||
Vec_Ptr_t * vTemp; // temporary storage
|
Vec_Ptr_t * vTemp; // temporary storage
|
||||||
|
Vec_Int_t * vOutLits; // optional endpoint literals to sample before cancel
|
||||||
|
Vec_Int_t * vOutVals; // optional endpoint values by output
|
||||||
|
int iOutVal; // current output whose endpoints are sampled
|
||||||
// watched clauses
|
// watched clauses
|
||||||
Tas_Sto_t pStore; // storage for watched clauses
|
Tas_Sto_t pStore; // storage for watched clauses
|
||||||
int * pWatches; // watched lists for each literal
|
int * pWatches; // watched lists for each literal
|
||||||
|
|
@ -308,6 +312,29 @@ static inline void Tas_ManSaveModel( Tas_Man_t * p, Vec_Int_t * vCex )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int Tas_ManLitValue( Tas_Man_t * p, int iLit )
|
||||||
|
{
|
||||||
|
Gia_Obj_t * pObj;
|
||||||
|
if ( iLit < 0 )
|
||||||
|
return -1;
|
||||||
|
if ( Abc_Lit2Var(iLit) == 0 )
|
||||||
|
return Abc_LitIsCompl(iLit);
|
||||||
|
pObj = Gia_ManObj( p->pAig, Abc_Lit2Var(iLit) );
|
||||||
|
if ( !Tas_VarIsAssigned(pObj) )
|
||||||
|
return -1;
|
||||||
|
return Tas_VarValue(pObj) ^ Abc_LitIsCompl(iLit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Tas_ManSaveOutVals( Tas_Man_t * p, Vec_Int_t * vOutLits, Vec_Int_t * vOutVals, int Out )
|
||||||
|
{
|
||||||
|
if ( vOutLits == NULL || vOutVals == NULL )
|
||||||
|
return;
|
||||||
|
if ( 2*Out + 1 >= Vec_IntSize(vOutLits) )
|
||||||
|
return;
|
||||||
|
Vec_IntWriteEntry( vOutVals, 2*Out, Tas_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out) ) );
|
||||||
|
Vec_IntWriteEntry( vOutVals, 2*Out + 1, Tas_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out + 1) ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis []
|
Synopsis []
|
||||||
|
|
@ -1380,7 +1407,10 @@ int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 )
|
||||||
if ( pObj2 && !Tas_VarIsAssigned(Gia_Regular(pObj2)) )
|
if ( pObj2 && !Tas_VarIsAssigned(Gia_Regular(pObj2)) )
|
||||||
Tas_ManAssign( p, pObj2, 0, NULL, NULL );
|
Tas_ManAssign( p, pObj2, 0, NULL, NULL );
|
||||||
if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) )
|
if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) )
|
||||||
|
{
|
||||||
Tas_ManSaveModel( p, p->vModel );
|
Tas_ManSaveModel( p, p->vModel );
|
||||||
|
Tas_ManSaveOutVals( p, p->vOutLits, p->vOutVals, p->iOutVal );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
RetValue = 1;
|
RetValue = 1;
|
||||||
Tas_ManCancelUntil( p, 0 );
|
Tas_ManCancelUntil( p, 0 );
|
||||||
|
|
@ -1514,12 +1544,12 @@ void Tas_ManSatPrintStats( Tas_Man_t * p )
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
|
Vec_Int_t * Tas_ManSolveMiterNcOutVals( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals )
|
||||||
{
|
{
|
||||||
extern void Gia_ManCollectTest( Gia_Man_t * pAig );
|
extern void Gia_ManCollectTest( Gia_Man_t * pAig );
|
||||||
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
|
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
|
||||||
Tas_Man_t * p;
|
Tas_Man_t * p;
|
||||||
Vec_Int_t * vCex, * vVisit, * vCexStore;
|
Vec_Int_t * vCex, * vVisit, * vCexStore, * vOutVals = NULL;
|
||||||
Vec_Str_t * vStatus;
|
Vec_Str_t * vStatus;
|
||||||
Gia_Obj_t * pRoot;//, * pRootCopy;
|
Gia_Obj_t * pRoot;//, * pRootCopy;
|
||||||
// Gia_Man_t * pAigCopy = Gia_ManDup( pAig ), * pAigTemp;
|
// Gia_Man_t * pAigCopy = Gia_ManDup( pAig ), * pAigTemp;
|
||||||
|
|
@ -1540,6 +1570,12 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
||||||
// create resulting data-structures
|
// create resulting data-structures
|
||||||
vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
|
vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
|
||||||
vCexStore = Vec_IntAlloc( 10000 );
|
vCexStore = Vec_IntAlloc( 10000 );
|
||||||
|
if ( pvOutVals )
|
||||||
|
{
|
||||||
|
*pvOutVals = NULL;
|
||||||
|
if ( vOutLits )
|
||||||
|
vOutVals = Vec_IntStartFull( 2 * Gia_ManPoNum(pAig) );
|
||||||
|
}
|
||||||
vVisit = Vec_IntAlloc( 100 );
|
vVisit = Vec_IntAlloc( 100 );
|
||||||
vCex = Tas_ReadModel( p );
|
vCex = Tas_ReadModel( p );
|
||||||
// solve for each output
|
// solve for each output
|
||||||
|
|
@ -1567,7 +1603,13 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
||||||
// p->Pars.fUseActive = 1;
|
// p->Pars.fUseActive = 1;
|
||||||
p->Pars.fUseHighest = 1;
|
p->Pars.fUseHighest = 1;
|
||||||
p->Pars.fUseLowest = 0;
|
p->Pars.fUseLowest = 0;
|
||||||
|
p->vOutLits = vOutLits;
|
||||||
|
p->vOutVals = vOutVals;
|
||||||
|
p->iOutVal = i;
|
||||||
status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL );
|
status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL );
|
||||||
|
p->vOutLits = NULL;
|
||||||
|
p->vOutVals = NULL;
|
||||||
|
p->iOutVal = -1;
|
||||||
// printf( "\n" );
|
// printf( "\n" );
|
||||||
/*
|
/*
|
||||||
if ( status == -1 )
|
if ( status == -1 )
|
||||||
|
|
@ -1621,6 +1663,10 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
||||||
// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro );
|
// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro );
|
||||||
Tas_ManStop( p );
|
Tas_ManStop( p );
|
||||||
*pvStatus = vStatus;
|
*pvStatus = vStatus;
|
||||||
|
if ( pvOutVals )
|
||||||
|
*pvOutVals = vOutVals;
|
||||||
|
else
|
||||||
|
Vec_IntFreeP( &vOutVals );
|
||||||
|
|
||||||
// printf( "Total number of cex literals = %d. (Ave = %d)\n",
|
// printf( "Total number of cex literals = %d. (Ave = %d)\n",
|
||||||
// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,
|
// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,
|
||||||
|
|
@ -1628,6 +1674,11 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
||||||
return vCexStore;
|
return vCexStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
|
||||||
|
{
|
||||||
|
return Tas_ManSolveMiterNcOutVals( pAig, nConfs, pvStatus, fVerbose, NULL, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Packs patterns into array of simulation info.]
|
Synopsis [Packs patterns into array of simulation info.]
|
||||||
|
|
@ -1782,10 +1833,144 @@ void Tas_ManSolveMiterNc2( Gia_Man_t * pAig, int nConfs, Gia_Man_t * pAigOld, Ve
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Sets the conflict limit.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Tas_ManSetConflictNum( Tas_Man_t * p, int Num )
|
||||||
|
{
|
||||||
|
p->Pars.nBTLimit = Num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Syncs newly appended pAig objects for resident reuse.]
|
||||||
|
|
||||||
|
Description [Prepares objects appended since the last sync so the
|
||||||
|
persistent solver can reuse the same manager across rounds. Mirrors
|
||||||
|
Cbs_ManSyncCore but also resizes the TAS-specific watched-literal and
|
||||||
|
activity arrays.]
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Tas_ManSyncCore( Tas_Man_t * p )
|
||||||
|
{
|
||||||
|
Gia_Man_t * pAig = p->pAig;
|
||||||
|
Gia_Obj_t * pObj;
|
||||||
|
int i, nObjs = Gia_ManObjNum( pAig );
|
||||||
|
assert( p->nSyncedObjs <= nObjs );
|
||||||
|
if ( p->nSyncedObjs == nObjs )
|
||||||
|
return;
|
||||||
|
pAig->pRefs = ABC_REALLOC( int, pAig->pRefs, nObjs );
|
||||||
|
memset( pAig->pRefs + p->nSyncedObjs, 0, sizeof(int) * (nObjs - p->nSyncedObjs) );
|
||||||
|
p->pWatches = ABC_REALLOC( int, p->pWatches, 2 * nObjs );
|
||||||
|
memset( p->pWatches + 2 * p->nSyncedObjs, 0, sizeof(int) * 2 * (nObjs - p->nSyncedObjs) );
|
||||||
|
p->pActivity = ABC_REALLOC( float, p->pActivity, nObjs );
|
||||||
|
memset( p->pActivity + p->nSyncedObjs, 0, sizeof(float) * (nObjs - p->nSyncedObjs) );
|
||||||
|
for ( i = p->nSyncedObjs; i < nObjs; i++ )
|
||||||
|
{
|
||||||
|
pObj = Gia_ManObj( pAig, i );
|
||||||
|
pObj->fMark0 = pObj->fMark1 = 0;
|
||||||
|
pObj->Value = ~0;
|
||||||
|
pObj->fPhase = 0;
|
||||||
|
if ( Gia_ObjIsAnd(pObj) )
|
||||||
|
{
|
||||||
|
pAig->pRefs[Gia_ObjFaninId0(pObj, i)]++;
|
||||||
|
pAig->pRefs[Gia_ObjFaninId1(pObj, i)]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->nSyncedObjs = nObjs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Solves a set of root literals directly on a persistent AIG.]
|
||||||
|
|
||||||
|
Description [Same prover as Tas_ManSolveMiterNc, but each problem is a root
|
||||||
|
literal of p->pAig (no CO needed) instead of a CO of a freshly built view, and
|
||||||
|
the manager is resident: it is allocated once on the persistent COless pCore
|
||||||
|
and reused across rounds, only Tas_ManSyncCore-ing the objects appended since
|
||||||
|
the last call. Output index i corresponds to vRootLits[i]; vCexStore / vStatus
|
||||||
|
format matches Tas_ManSolveMiterNc. CEX is saved by CioId, which on pCore
|
||||||
|
equals the view's CI numbering.]
|
||||||
|
|
||||||
|
SideEffects [Prepares newly appended objects via Tas_ManSyncCore.]
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
Vec_Int_t * Tas_ManSolveRoots( Tas_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose )
|
||||||
|
{
|
||||||
|
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
|
||||||
|
Gia_Man_t * pAig = p->pAig;
|
||||||
|
Vec_Int_t * vCex, * vCexStore;
|
||||||
|
Vec_Str_t * vStatus;
|
||||||
|
int i, iLit, status;
|
||||||
|
abctime clk, clkTotal = Abc_Clock();
|
||||||
|
assert( Gia_ManRegNum(pAig) == 0 );
|
||||||
|
Tas_ManSyncCore( p ); // prep only objects appended since the last solve
|
||||||
|
vStatus = Vec_StrAlloc( Vec_IntSize(vRootLits) );
|
||||||
|
vCexStore = Vec_IntAlloc( 10000 );
|
||||||
|
vCex = Tas_ReadModel( p );
|
||||||
|
Vec_IntForEachEntry( vRootLits, iLit, i )
|
||||||
|
{
|
||||||
|
Vec_IntClear( vCex );
|
||||||
|
if ( Abc_Lit2Var(iLit) == 0 ) // structural constant root
|
||||||
|
{
|
||||||
|
if ( Abc_LitIsCompl(iLit) ) // const 1: trivial counter-example
|
||||||
|
{
|
||||||
|
Cec_ManSatAddToStore( vCexStore, vCex, i );
|
||||||
|
Vec_StrPush( vStatus, 0 );
|
||||||
|
}
|
||||||
|
else // const 0: proved
|
||||||
|
Vec_StrPush( vStatus, 1 );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
clk = Abc_Clock();
|
||||||
|
p->Pars.fUseHighest = 1;
|
||||||
|
p->Pars.fUseLowest = 0;
|
||||||
|
status = Tas_ManSolve( p, Gia_ObjFromLit(pAig, iLit), NULL );
|
||||||
|
Vec_StrPush( vStatus, (char)status );
|
||||||
|
if ( status == -1 )
|
||||||
|
{
|
||||||
|
p->nSatUndec++;
|
||||||
|
p->nConfUndec += p->Pars.nBTThis;
|
||||||
|
Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
|
||||||
|
p->timeSatUndec += Abc_Clock() - clk;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( status == 0 )
|
||||||
|
{
|
||||||
|
p->nSatSat++;
|
||||||
|
p->nConfSat += p->Pars.nBTThis;
|
||||||
|
Cec_ManSatAddToStore( vCexStore, vCex, i );
|
||||||
|
p->timeSatSat += Abc_Clock() - clk;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert( status == 1 );
|
||||||
|
p->nSatUnsat++;
|
||||||
|
p->nConfUnsat += p->Pars.nBTThis;
|
||||||
|
p->timeSatUnsat += Abc_Clock() - clk;
|
||||||
|
}
|
||||||
|
p->nSatTotal += Vec_IntSize(vRootLits);
|
||||||
|
p->timeTotal += Abc_Clock() - clkTotal;
|
||||||
|
*pvStatus = vStatus;
|
||||||
|
return vCexStore;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// END OF FILE ///
|
/// END OF FILE ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,7 @@ static int Abc_CommandAbc9Append ( Abc_Frame_t * pAbc, int argc, cha
|
||||||
static int Abc_CommandAbc9Scl ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandAbc9Scl ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandAbc9Lcorr ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandAbc9Lcorr ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandAbc9Scorr ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandAbc9Scorr ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
static int Abc_CommandAbc9Scorr2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandAbc9Choice ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandAbc9Choice ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandAbc9Sat ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandAbc9Sat ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandAbc9SatEnum ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandAbc9SatEnum ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
|
@ -1346,6 +1347,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
||||||
Cmd_CommandAdd( pAbc, "ABC9", "&scl", Abc_CommandAbc9Scl, 0 );
|
Cmd_CommandAdd( pAbc, "ABC9", "&scl", Abc_CommandAbc9Scl, 0 );
|
||||||
Cmd_CommandAdd( pAbc, "ABC9", "&lcorr", Abc_CommandAbc9Lcorr, 0 );
|
Cmd_CommandAdd( pAbc, "ABC9", "&lcorr", Abc_CommandAbc9Lcorr, 0 );
|
||||||
Cmd_CommandAdd( pAbc, "ABC9", "&scorr", Abc_CommandAbc9Scorr, 0 );
|
Cmd_CommandAdd( pAbc, "ABC9", "&scorr", Abc_CommandAbc9Scorr, 0 );
|
||||||
|
Cmd_CommandAdd( pAbc, "ABC9", "&scorr2", Abc_CommandAbc9Scorr2, 0 );
|
||||||
Cmd_CommandAdd( pAbc, "ABC9", "&choice", Abc_CommandAbc9Choice, 0 );
|
Cmd_CommandAdd( pAbc, "ABC9", "&choice", Abc_CommandAbc9Choice, 0 );
|
||||||
Cmd_CommandAdd( pAbc, "ABC9", "&sat", Abc_CommandAbc9Sat, 0 );
|
Cmd_CommandAdd( pAbc, "ABC9", "&sat", Abc_CommandAbc9Sat, 0 );
|
||||||
Cmd_CommandAdd( pAbc, "ABC9", "&satenum", Abc_CommandAbc9SatEnum, 0 );
|
Cmd_CommandAdd( pAbc, "ABC9", "&satenum", Abc_CommandAbc9SatEnum, 0 );
|
||||||
|
|
@ -41820,7 +41822,230 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
Cec_ManCorSetDefaultParams( pPars );
|
Cec_ManCorSetDefaultParams( pPars );
|
||||||
pPars->nProcs = 1;
|
pPars->nProcs = 1;
|
||||||
Extra_UtilGetoptReset();
|
Extra_UtilGetoptReset();
|
||||||
while ( ( c = Extra_UtilGetopt( argc, argv, "FCGXPSZpkrecqiowvh" ) ) != EOF )
|
while ( ( c = Extra_UtilGetopt( argc, argv, "FCGXPSZpkrecqowvh" ) ) != EOF )
|
||||||
|
{
|
||||||
|
switch ( c )
|
||||||
|
{
|
||||||
|
case 'F':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
pPars->nFrames = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( pPars->nFrames < 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->nBTLimit = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( pPars->nBTLimit < 0 )
|
||||||
|
goto usage;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
pPars->nPrefix = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( pPars->nPrefix < 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->nLimitMax = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( pPars->nLimitMax < 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->nProcs = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( pPars->nProcs < 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->nPartSize = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( pPars->nPartSize < 0 )
|
||||||
|
goto usage;
|
||||||
|
break;
|
||||||
|
case 'Z':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-Z\" should be followed by an integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
nFlopIncFreq = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( nFlopIncFreq < 0 )
|
||||||
|
goto usage;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
fPartition ^= 1;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
pPars->fConstCorr ^= 1;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
pPars->fUseRings ^= 1;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
pPars->fMakeChoices ^= 1;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
pPars->fUseCSat ^= 1;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
pPars->fStopWhenGone ^= 1;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
fUseOld ^= 1;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
pPars->fVerboseFlops ^= 1;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
pPars->fVerbose ^= 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( pAbc->pGia == NULL )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Abc_CommandAbc9Scorr(): There is no AIG.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( Gia_ManBoxNum(pAbc->pGia) && Gia_ManRegBoxNum(pAbc->pGia) )
|
||||||
|
{
|
||||||
|
if ( pAbc->pGia->pAigExtra == NULL )
|
||||||
|
{
|
||||||
|
printf( "Timing manager is given but there is no GIA of boxes.\n" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pTemp = Gia_ManSweepWithBoxes( pAbc->pGia, NULL, pPars, 0, 0, pPars->fVerbose, pPars->fVerboseFlops );
|
||||||
|
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( Gia_ManRegNum(pAbc->pGia) == 0 )
|
||||||
|
{
|
||||||
|
Abc_Print( 0, "The network is combinational.\n" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( nFlopIncFreq )
|
||||||
|
{
|
||||||
|
extern Gia_Man_t * Gia_ManDupStopsAdd( Gia_Man_t * p, Vec_Int_t * vStops );
|
||||||
|
extern Gia_Man_t * Gia_ManDupStopsRem( Gia_Man_t * p, Vec_Int_t * vStops );
|
||||||
|
extern Vec_Int_t * Gia_ManFindStopFlops( Gia_Man_t * p, int nFlopIncFreq, int fVerbose );
|
||||||
|
Vec_Int_t * vStops = Gia_ManFindStopFlops( pAbc->pGia, nFlopIncFreq, pPars->fVerbose );
|
||||||
|
if ( vStops )
|
||||||
|
{
|
||||||
|
extern void Gia_ManTransferEquivs2( Gia_Man_t * p, Gia_Man_t * pNew );
|
||||||
|
Gia_Man_t * pUsed = Gia_ManDupStopsAdd( pAbc->pGia, vStops );
|
||||||
|
if ( pPars->nPartSize > 0 )
|
||||||
|
pTemp = Gia_SignalCorrespondencePart( pUsed, pPars );
|
||||||
|
else if ( fUseOld )
|
||||||
|
pTemp = Cec_ManScorrCorrespondence( pUsed, pPars );
|
||||||
|
else if ( fPartition )
|
||||||
|
pTemp = Gia_ManScorrDivideTest( pUsed, pPars );
|
||||||
|
else
|
||||||
|
pTemp = Cec_ManLSCorrespondence( pUsed, pPars );
|
||||||
|
Gia_ManTransferEquivs2( pUsed, pAbc->pGia );
|
||||||
|
Gia_ManStop( pUsed );
|
||||||
|
pTemp = Gia_ManDupStopsRem( pUsed = pTemp, vStops );
|
||||||
|
Gia_ManStop( pUsed );
|
||||||
|
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||||
|
Vec_IntFree( vStops );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( pPars->nPartSize > 0 )
|
||||||
|
pTemp = Gia_SignalCorrespondencePart( pAbc->pGia, pPars );
|
||||||
|
else if ( fUseOld )
|
||||||
|
pTemp = Cec_ManScorrCorrespondence( pAbc->pGia, pPars );
|
||||||
|
else if ( fPartition )
|
||||||
|
pTemp = Gia_ManScorrDivideTest( pAbc->pGia, pPars );
|
||||||
|
else
|
||||||
|
pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars );
|
||||||
|
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
Abc_Print( -2, "usage: &scorr [-FCGXPSZ num] [-pkrecqowvh]\n" );
|
||||||
|
Abc_Print( -2, "\t performs signal correpondence computation\n" );
|
||||||
|
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
|
||||||
|
Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames );
|
||||||
|
Abc_Print( -2, "\t-G num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix );
|
||||||
|
Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax );
|
||||||
|
Abc_Print( -2, "\t-P num : the number of concurrent processes [default = %d]\n", pPars->nProcs );
|
||||||
|
Abc_Print( -2, "\t-S num : the number of flops in one partition [default = %d]\n", pPars->nPartSize );
|
||||||
|
Abc_Print( -2, "\t-Z num : the average flop include frequency [default = %d]\n", nFlopIncFreq );
|
||||||
|
Abc_Print( -2, "\t-p : toggle using partitioning for the input AIG [default = %s]\n", fPartition? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-k : toggle using constant correspondence [default = %s]\n", pPars->fConstCorr? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-e : toggle using equivalences as choices [default = %s]\n", pPars->fMakeChoices? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-q : toggle quitting when PO is not a constant candidate [default = %s]\n", pPars->fStopWhenGone? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-o : toggle calling old engine [default = %s]\n", fUseOld? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-w : toggle printing verbose info about equivalent flops [default = %s]\n", pPars->fVerboseFlops? "yes": "no" );
|
||||||
|
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 []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_CommandAbc9Scorr2( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
|
{
|
||||||
|
extern Gia_Man_t * Cec_ManScorrCorrespondence( Gia_Man_t * p, Cec_ParCor_t * pPars );
|
||||||
|
extern Gia_Man_t * Cec_ManLSCorrespondence2( Gia_Man_t * p, Cec_ParCor_t * pPars );
|
||||||
|
extern Gia_Man_t * Gia_ManScorrDivideTest( Gia_Man_t * p, Cec_ParCor_t * pPars );
|
||||||
|
extern Gia_Man_t * Gia_SignalCorrespondencePart( Gia_Man_t * p, Cec_ParCor_t * pPars );
|
||||||
|
Cec_ParCor_t Pars, * pPars = &Pars;
|
||||||
|
Gia_Man_t * pTemp;
|
||||||
|
int fPartition = 0;
|
||||||
|
int nFlopIncFreq = 0;
|
||||||
|
int fUseOld = 0, c;
|
||||||
|
Cec_ManCorSetDefaultParams( pPars );
|
||||||
|
pPars->nProcs = 1;
|
||||||
|
pPars->fIncremental = 1;
|
||||||
|
pPars->fDynSrm = 1;
|
||||||
|
pPars->fIncrSim = 1;
|
||||||
|
pPars->fSkipFailResim = 1;
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
while ( ( c = Extra_UtilGetopt( argc, argv, "FCGXPSZKYDpkrecqiIosvh" ) ) != EOF )
|
||||||
{
|
{
|
||||||
switch ( c )
|
switch ( c )
|
||||||
{
|
{
|
||||||
|
|
@ -41922,12 +42147,24 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
case 'i':
|
case 'i':
|
||||||
pPars->fIncremental ^= 1;
|
pPars->fIncremental ^= 1;
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
pPars->fDynSrm ^= 1;
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
pPars->fIncrSim ^= 1;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
pPars->fSkipFailResim ^= 1;
|
||||||
|
break;
|
||||||
|
case 'Y':
|
||||||
|
pPars->fBmcTasAdaptive ^= 1;
|
||||||
|
break;
|
||||||
|
case 'K':
|
||||||
|
pPars->fKissatCert ^= 1;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
fUseOld ^= 1;
|
fUseOld ^= 1;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
|
||||||
pPars->fVerboseFlops ^= 1;
|
|
||||||
break;
|
|
||||||
case 'v':
|
case 'v':
|
||||||
pPars->fVerbose ^= 1;
|
pPars->fVerbose ^= 1;
|
||||||
break;
|
break;
|
||||||
|
|
@ -41935,16 +42172,26 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( pPars->fIncremental )
|
if ( pPars->fDynSrm && !pPars->fIncremental )
|
||||||
{
|
{
|
||||||
//preserve for incremental mode, maybe should be a separate command
|
Abc_Print( -1, "The dynamic SRM manager (-D) requires -i.\n" );
|
||||||
pPars->fDynSrm = 1; //dynamic SRM
|
return 1;
|
||||||
pPars->fIncrSim = 1; //incremental simulation
|
}
|
||||||
pPars->fSkipFailResim = 1; //skip resimulation of failed flops
|
if ( pPars->fBmcTasAdaptive && !pPars->fDynSrm )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "The adaptive BMC solver policy (-Y) requires -D.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( pPars->fKissatCert &&
|
||||||
|
(fUseOld || fPartition || pPars->nPartSize > 0 ||
|
||||||
|
nFlopIncFreq > 0 || pPars->nPrefix > 0) )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "The strict fixed-point oracle (-K) supports the direct engine with -G 0 only.\n" );
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
if ( pAbc->pGia == NULL )
|
if ( pAbc->pGia == NULL )
|
||||||
{
|
{
|
||||||
Abc_Print( -1, "Abc_CommandAbc9Scorr(): There is no AIG.\n" );
|
Abc_Print( -1, "&scorr2: There is no AIG.\n" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ( Gia_ManBoxNum(pAbc->pGia) && Gia_ManRegBoxNum(pAbc->pGia) )
|
if ( Gia_ManBoxNum(pAbc->pGia) && Gia_ManRegBoxNum(pAbc->pGia) )
|
||||||
|
|
@ -41980,7 +42227,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
else if ( fPartition )
|
else if ( fPartition )
|
||||||
pTemp = Gia_ManScorrDivideTest( pUsed, pPars );
|
pTemp = Gia_ManScorrDivideTest( pUsed, pPars );
|
||||||
else
|
else
|
||||||
pTemp = Cec_ManLSCorrespondence( pUsed, pPars );
|
pTemp = Cec_ManLSCorrespondence2( pUsed, pPars );
|
||||||
Gia_ManTransferEquivs2( pUsed, pAbc->pGia );
|
Gia_ManTransferEquivs2( pUsed, pAbc->pGia );
|
||||||
Gia_ManStop( pUsed );
|
Gia_ManStop( pUsed );
|
||||||
pTemp = Gia_ManDupStopsRem( pUsed = pTemp, vStops );
|
pTemp = Gia_ManDupStopsRem( pUsed = pTemp, vStops );
|
||||||
|
|
@ -41997,13 +42244,13 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
else if ( fPartition )
|
else if ( fPartition )
|
||||||
pTemp = Gia_ManScorrDivideTest( pAbc->pGia, pPars );
|
pTemp = Gia_ManScorrDivideTest( pAbc->pGia, pPars );
|
||||||
else
|
else
|
||||||
pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars );
|
pTemp = Cec_ManLSCorrespondence2( pAbc->pGia, pPars );
|
||||||
Abc_FrameUpdateGia( pAbc, pTemp );
|
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
Abc_Print( -2, "usage: &scorr [-FCGXPSZ num] [-pkrecqiowvh]\n" );
|
Abc_Print( -2, "usage: &scorr2 [-FCGXPSZ num] [-pkrecqiDIsYKovh]\n" );
|
||||||
Abc_Print( -2, "\t performs signal correpondence computation\n" );
|
Abc_Print( -2, "\t performs signal correpondence computation using the incremental scorr2 engine\n" );
|
||||||
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
|
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
|
||||||
Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames );
|
Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames );
|
||||||
Abc_Print( -2, "\t-G num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix );
|
Abc_Print( -2, "\t-G num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix );
|
||||||
|
|
@ -42017,11 +42264,16 @@ usage:
|
||||||
Abc_Print( -2, "\t-e : toggle using equivalences as choices [default = %s]\n", pPars->fMakeChoices? "yes": "no" );
|
Abc_Print( -2, "\t-e : toggle using equivalences as choices [default = %s]\n", pPars->fMakeChoices? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" );
|
Abc_Print( -2, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-q : toggle quitting when PO is not a constant candidate [default = %s]\n", pPars->fStopWhenGone? "yes": "no" );
|
Abc_Print( -2, "\t-q : toggle quitting when PO is not a constant candidate [default = %s]\n", pPars->fStopWhenGone? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-i : toggle integrated incremental SRM/re-proof/resimulation [default = %s]\n", pPars->fIncremental? "yes": "no" );
|
Abc_Print( -2, "\t-i : toggle incremental TFO-triggered re-proof [default = %s]\n", pPars->fIncremental? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-D : toggle persistent dynamic SRM construction [default = %s]\n", pPars->fDynSrm? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-I : toggle persistent event-driven resimulation [default = %s]\n", pPars->fIncrSim? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-s : toggle skipping resimulation without a real CEX [default = %s]\n", pPars->fSkipFailResim? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-Y : toggle guarded CBS-first/TAS-rescue BMC policy [default = %s]\n", pPars->fBmcTasAdaptive? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-K : toggle strict final fixed-point Kissat audit [default = %s]\n", pPars->fKissatCert? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-o : toggle calling old engine [default = %s]\n", fUseOld? "yes": "no" );
|
Abc_Print( -2, "\t-o : toggle calling old engine [default = %s]\n", fUseOld? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-w : toggle printing verbose info about equivalent flops [default = %s]\n", pPars->fVerboseFlops? "yes": "no" );
|
|
||||||
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
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");
|
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||||
|
Abc_Print( -2, "\t This command was contributed by Xiran Zhao from University of Chinese Academy of Sciences (UCAS).\n" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -351,6 +351,19 @@ static inline abctime Abc_Clock()
|
||||||
return (abctime) clock();
|
return (abctime) clock();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
// Returns monotonic wall-clock time in nanoseconds. The dynamic SRM
|
||||||
|
// heuristics use this to compare rebuild and reuse costs.
|
||||||
|
static inline abctime Abc_ClockHr()
|
||||||
|
{
|
||||||
|
#if defined(CLOCK_MONOTONIC)
|
||||||
|
struct timespec ts;
|
||||||
|
if ( clock_gettime( CLOCK_MONOTONIC, &ts ) < 0 )
|
||||||
|
return (abctime)-1;
|
||||||
|
return ((abctime) ts.tv_sec) * 1000000000 + (abctime) ts.tv_nsec;
|
||||||
|
#else
|
||||||
|
return (abctime)( (double)Abc_Clock() * 1.0e9 / CLOCKS_PER_SEC );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
// counting thread time
|
// counting thread time
|
||||||
static inline abctime Abc_ThreadClock()
|
static inline abctime Abc_ThreadClock()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,9 @@ struct Cec_ParCor_t_
|
||||||
int nLevelMax; // (scorr only) the max number of levels
|
int nLevelMax; // (scorr only) the max number of levels
|
||||||
int nStepsMax; // (scorr only) the max number of induction steps
|
int nStepsMax; // (scorr only) the max number of induction steps
|
||||||
int nLimitMax; // (scorr only) stop after this many iterations if little or no improvement
|
int nLimitMax; // (scorr only) stop after this many iterations if little or no improvement
|
||||||
|
int nIncrFallbackPct; // (-i) fall back to full SRM when active pairs exceed this percent
|
||||||
|
int nDynSrmRebuildPct; // (-D) cold-rebuild when active pairs exceed this percent
|
||||||
|
int nDynSrmCompactMult; // (-D) cold-compact when core exceeds this multiple of reset size
|
||||||
int fLatchCorr; // consider only latch outputs
|
int fLatchCorr; // consider only latch outputs
|
||||||
int fConstCorr; // consider only constants
|
int fConstCorr; // consider only constants
|
||||||
int fUseRings; // use rings
|
int fUseRings; // use rings
|
||||||
|
|
@ -167,10 +170,16 @@ struct Cec_ParCor_t_
|
||||||
// int fFirstStop; // stop on the first sat output
|
// int fFirstStop; // stop on the first sat output
|
||||||
int fUseSmartCnf; // use smart CNF computation
|
int fUseSmartCnf; // use smart CNF computation
|
||||||
int fStopWhenGone; // quit when PO is not a candidate constant
|
int fStopWhenGone; // quit when PO is not a candidate constant
|
||||||
int fIncremental; // integrated incremental mode for &scorr
|
int fIncremental; // active-list/TFO-triggered reproof in main loop
|
||||||
|
int fIncrOracle; // internal unbounded shadow SAT for pairs skipped by -i
|
||||||
int fIncrSim; // persistent CEX-TFO-only resimulation after SAT
|
int fIncrSim; // persistent CEX-TFO-only resimulation after SAT
|
||||||
int fDynSrm; // persistent dynamic SRM and true-unroll resimulation
|
int fDynSrm; // persistent dynamic SRM and true-unroll resimulation
|
||||||
|
int fDynSrmNoAdapt;// disable adaptive cold-rebuilds in DynSRM
|
||||||
|
int fUseTas; // use TAS (vs CBS) for persistent solving (-D)
|
||||||
|
int fBmcTasAdaptive;// use guarded CBS-first/TAS-rescue policy in BMC
|
||||||
|
int fKissatCert; // strictly audit final base+step obligations with Kissat
|
||||||
int fSkipFailResim;// skip resim in rounds with no real CEX (only timeout/fail)
|
int fSkipFailResim;// skip resim in rounds with no real CEX (only timeout/fail)
|
||||||
|
int fVerifyResim; // internal oracle: check incremental resim values vs full sweep
|
||||||
int fVerboseFlops; // verbose stats
|
int fVerboseFlops; // verbose stats
|
||||||
int fVeryVerbose; // verbose stats
|
int fVeryVerbose; // verbose stats
|
||||||
int fVerbose; // verbose stats
|
int fVerbose; // verbose stats
|
||||||
|
|
|
||||||
|
|
@ -192,10 +192,18 @@ void Cec_ManCorSetDefaultParams( Cec_ParCor_t * p )
|
||||||
p->nBTLimit = 100; // conflict limit at a node
|
p->nBTLimit = 100; // conflict limit at a node
|
||||||
p->nLevelMax = -1; // (scorr only) the max number of levels
|
p->nLevelMax = -1; // (scorr only) the max number of levels
|
||||||
p->nStepsMax = -1; // (scorr only) the max number of induction steps
|
p->nStepsMax = -1; // (scorr only) the max number of induction steps
|
||||||
|
p->nIncrFallbackPct = 100; // (-i) fall back to full SRM when active pairs exceed this percent
|
||||||
|
p->nDynSrmRebuildPct = 20; // (-D) cold-rebuild when active pairs exceed this percent
|
||||||
|
p->nDynSrmCompactMult = 4; // (-D) cold-compact when core exceeds this multiple of reset size
|
||||||
p->fLatchCorr = 0; // consider only latch outputs
|
p->fLatchCorr = 0; // consider only latch outputs
|
||||||
p->fConstCorr = 0; // consider only constants
|
p->fConstCorr = 0; // consider only constants
|
||||||
p->fUseRings = 1; // combine classes into rings
|
p->fUseRings = 1; // combine classes into rings
|
||||||
|
p->fIncrOracle = 0; // internal unbounded shadow SAT for pairs skipped by -i
|
||||||
p->fSkipFailResim = 0; // skip resim when a round has no real CEX (only timeout/fail)
|
p->fSkipFailResim = 0; // skip resim when a round has no real CEX (only timeout/fail)
|
||||||
|
p->fDynSrmNoAdapt = 1; // timing-guided DynSRM rebuild heuristic is opt-in
|
||||||
|
p->fUseTas = 0; // use CBS by default for persistent solving
|
||||||
|
p->fBmcTasAdaptive = 0; // guarded BMC TAS rescue is opt-in (-Y)
|
||||||
|
p->fKissatCert = 0; // strict final base+step Kissat audit is opt-in
|
||||||
p->fUseCSat = 1; // use circuit-based solver
|
p->fUseCSat = 1; // use circuit-based solver
|
||||||
// p->fFirstStop = 0; // stop on the first sat output
|
// p->fFirstStop = 0; // stop on the first sat output
|
||||||
p->fUseSmartCnf = 0; // use smart CNF computation
|
p->fUseSmartCnf = 0; // use smart CNF computation
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,7 @@ static inline int Cec_ParCorShouldStop( Cec_ParCor_t * pPars )
|
||||||
/// DECLARATIONS ///
|
/// DECLARATIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Shared with cecCorrIncr.c (declared in cecInt.h).
|
static void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
|
||||||
extern void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
|
|
||||||
extern int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// FUNCTION DEFINITIONS ///
|
/// FUNCTION DEFINITIONS ///
|
||||||
|
|
@ -53,7 +51,7 @@ extern int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pO
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix )
|
static inline int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix )
|
||||||
{
|
{
|
||||||
if ( Gia_ObjIsAnd(pObj) )
|
if ( Gia_ObjIsAnd(pObj) )
|
||||||
{
|
{
|
||||||
|
|
@ -499,53 +497,6 @@ int Cec_ManLoadCounterExamples( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iS
|
||||||
return iStart;
|
return iStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
|
||||||
|
|
||||||
Synopsis [Performs bitpacking of counter-examples and records bit lanes.]
|
|
||||||
|
|
||||||
Description []
|
|
||||||
|
|
||||||
SideEffects []
|
|
||||||
|
|
||||||
SeeAlso []
|
|
||||||
|
|
||||||
***********************************************************************/
|
|
||||||
int Cec_ManLoadCounterExamplesMapped( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart, Vec_Int_t * vOutBits )
|
|
||||||
{
|
|
||||||
Vec_Int_t * vPat;
|
|
||||||
Vec_Ptr_t * vPres;
|
|
||||||
int nWords = Vec_PtrReadWordsSimInfo(vInfo);
|
|
||||||
int nBits = 32 * nWords;
|
|
||||||
int k, nSize, Out;
|
|
||||||
Vec_IntClear( vOutBits );
|
|
||||||
vPat = Vec_IntAlloc( 100 );
|
|
||||||
vPres = Vec_PtrAllocSimInfo( Vec_PtrSize(vInfo), nWords );
|
|
||||||
Vec_PtrCleanSimInfo( vPres, 0, nWords );
|
|
||||||
while ( iStart < Vec_IntSize(vCexStore) )
|
|
||||||
{
|
|
||||||
Out = Vec_IntEntry( vCexStore, iStart++ );
|
|
||||||
nSize = Vec_IntEntry( vCexStore, iStart++ );
|
|
||||||
if ( nSize <= 0 )
|
|
||||||
continue;
|
|
||||||
Vec_IntClear( vPat );
|
|
||||||
for ( k = 0; k < nSize; k++ )
|
|
||||||
Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) );
|
|
||||||
for ( k = 1; k < nBits; k++ )
|
|
||||||
if ( Cec_ManLoadCounterExamplesTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) )
|
|
||||||
break;
|
|
||||||
if ( k < nBits )
|
|
||||||
{
|
|
||||||
Vec_IntPush( vOutBits, Out );
|
|
||||||
Vec_IntPush( vOutBits, k );
|
|
||||||
}
|
|
||||||
if ( k == nBits-1 )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Vec_PtrFree( vPres );
|
|
||||||
Vec_IntFree( vPat );
|
|
||||||
return iStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Performs bitpacking of counter-examples.]
|
Synopsis [Performs bitpacking of counter-examples.]
|
||||||
|
|
@ -587,53 +538,6 @@ int Cec_ManLoadCounterExamples2( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int i
|
||||||
return iStart;
|
return iStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
|
||||||
|
|
||||||
Synopsis [Classifies vCexStore entries by SAT outcome.]
|
|
||||||
|
|
||||||
Description [Each entry is (Out, nLits[, lit0, ..., lit{nLits-1}]).
|
|
||||||
nLits > 0 -> real SAT CEX with usable literals;
|
|
||||||
nLits == 0 -> trivial SAT (e.g. SRM PO became const 1);
|
|
||||||
nLits == -1 -> timeout/fail, no CEX.
|
|
||||||
Counts are written via the out-pointers (any may be NULL).
|
|
||||||
Returns 1 iff there is at least one entry usable for resim
|
|
||||||
(real or trivial), preserving the prior skip-failed-resim
|
|
||||||
semantics where only timeout-only stores get skipped.]
|
|
||||||
|
|
||||||
SideEffects []
|
|
||||||
|
|
||||||
SeeAlso []
|
|
||||||
|
|
||||||
***********************************************************************/
|
|
||||||
static int Cec_ManCexStoreClassify( Vec_Int_t * vCexStore, int * pnReal, int * pnTriv, int * pnFail )
|
|
||||||
{
|
|
||||||
int iStart = 0, nSize, nReal = 0, nTriv = 0, nFail = 0;
|
|
||||||
while ( iStart < Vec_IntSize(vCexStore) )
|
|
||||||
{
|
|
||||||
iStart++; // output number
|
|
||||||
assert( iStart < Vec_IntSize(vCexStore) );
|
|
||||||
nSize = Vec_IntEntry( vCexStore, iStart++ );
|
|
||||||
if ( nSize > 0 )
|
|
||||||
{
|
|
||||||
nReal++;
|
|
||||||
iStart += nSize;
|
|
||||||
}
|
|
||||||
else if ( nSize == 0 )
|
|
||||||
{
|
|
||||||
nTriv++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert( nSize == -1 );
|
|
||||||
nFail++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( pnReal ) *pnReal = nReal;
|
|
||||||
if ( pnTriv ) *pnTriv = nTriv;
|
|
||||||
if ( pnFail ) *pnFail = nFail;
|
|
||||||
return (nReal + nTriv) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Resimulates counter-examples derived by the SAT solver.]
|
Synopsis [Resimulates counter-examples derived by the SAT solver.]
|
||||||
|
|
@ -645,104 +549,33 @@ static int Cec_ManCexStoreClassify( Vec_Int_t * vCexStore, int * pnReal, int * p
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
static int Cec_ManResimulateCounterExamplesSeed( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore, int nFrames, Cec_SeedSim_t * pSeed, Vec_Int_t * vOutputs )
|
int Cec_ManResimulateCounterExamples( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore, int nFrames )
|
||||||
{
|
{
|
||||||
Vec_Int_t * vPairs = NULL;
|
Vec_Int_t * vPairs;
|
||||||
Vec_Int_t * vOutBits = NULL;
|
Vec_Ptr_t * vSimInfo;
|
||||||
Vec_Ptr_t * vSimInfo = NULL;
|
int RetValue = 0, iStart = 0;
|
||||||
int RetValue = 0, iStart = 0, fValueRefs = 0;
|
vPairs = Gia_ManCorrCreateRemapping( pSim->pAig );
|
||||||
if ( pSeed )
|
Gia_ManCreateValueRefs( pSim->pAig );
|
||||||
Cec_SeedSimBeginCall( pSeed ); // reset per-call local/full/maxdirty counters
|
|
||||||
// pSim->pPars->nWords = 63;
|
// pSim->pPars->nWords = 63;
|
||||||
pSim->pPars->nFrames = nFrames;
|
pSim->pPars->nFrames = nFrames;
|
||||||
if ( pSeed )
|
vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pSim->pAig) + Gia_ManPiNum(pSim->pAig) * nFrames, pSim->pPars->nWords );
|
||||||
{
|
|
||||||
Cec_SeedSimEnsurePersistent( pSeed, pSim );
|
|
||||||
// Defer the (possibly full-unroll-sized) class cone: it is built lazily
|
|
||||||
// inside Cec_SeedSimTryBatch() only once a batch passes the density gate,
|
|
||||||
// so rounds that fall back to full resim never pay for it.
|
|
||||||
pSeed->fUseCone = 0;
|
|
||||||
vSimInfo = pSeed->vSimInfo;
|
|
||||||
vOutBits = Vec_IntAlloc( 1000 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Gia_ManCreateValueRefs( pSim->pAig );
|
|
||||||
fValueRefs = 1;
|
|
||||||
vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pSim->pAig) + Gia_ManPiNum(pSim->pAig) * nFrames, pSim->pPars->nWords );
|
|
||||||
}
|
|
||||||
vPairs = Gia_ManCorrCreateRemapping( pSim->pAig );
|
|
||||||
while ( iStart < Vec_IntSize(vCexStore) )
|
while ( iStart < Vec_IntSize(vCexStore) )
|
||||||
{
|
{
|
||||||
if ( pSeed )
|
Cec_ManStartSimInfo( vSimInfo, Gia_ManRegNum(pSim->pAig) );
|
||||||
{
|
iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart );
|
||||||
int LocalStatus;
|
// iStart = Cec_ManLoadCounterExamples2( vSimInfo, vCexStore, iStart );
|
||||||
iStart = Cec_SeedSimLoadPersistentBatch(
|
// Gia_ManCorrRemapSimInfo( pSim->pAig, vSimInfo );
|
||||||
pSeed, vCexStore, iStart, vPairs, vOutBits );
|
Gia_ManCorrPerformRemapping( vPairs, vSimInfo );
|
||||||
if ( pSeed->nFallbackCooldown > 0 )
|
RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo );
|
||||||
{
|
|
||||||
Cec_SeedSimBypassBatch( pSeed, Vec_IntSize(vOutBits) / 2 );
|
|
||||||
pSeed->nFallbackCooldown--;
|
|
||||||
}
|
|
||||||
else if ( (LocalStatus = Cec_SeedSimTryBatch(
|
|
||||||
pSeed, pSim, vSimInfo, vOutputs, vOutBits, nFrames )) ==
|
|
||||||
CEC_SEEDSIM_RESULT_LOCAL )
|
|
||||||
{
|
|
||||||
pSeed->nFallbackStreak = 0;
|
|
||||||
pSeed->nFallbackCooldown = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if ( LocalStatus == CEC_SEEDSIM_RESULT_FULL_WIDE )
|
|
||||||
{
|
|
||||||
int Shift;
|
|
||||||
pSeed->nFallbackStreak++;
|
|
||||||
Shift = Abc_MinInt( pSeed->nFallbackStreak - 1, 3 );
|
|
||||||
pSeed->nFallbackCooldown =
|
|
||||||
Abc_MinInt( (1 << Shift) - 1,
|
|
||||||
CEC_SEEDSIM_MAX_FALLBACK_BACKOFF );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pSeed->nFallbackStreak = 0;
|
|
||||||
pSeed->nFallbackCooldown = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Cec_ManStartSimInfo( vSimInfo, Gia_ManRegNum(pSim->pAig) );
|
|
||||||
iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart );
|
|
||||||
Gia_ManCorrPerformRemapping( vPairs, vSimInfo );
|
|
||||||
}
|
|
||||||
// The local path returned above. Reaching here means standard full
|
|
||||||
// resimulation, either outside incremental mode or as a fallback.
|
|
||||||
if ( pSeed )
|
|
||||||
{
|
|
||||||
if ( !fValueRefs )
|
|
||||||
{
|
|
||||||
Gia_ManCreateValueRefs( pSim->pAig );
|
|
||||||
fValueRefs = 1;
|
|
||||||
}
|
|
||||||
RetValue |= Cec_ManSeqResimulateSeed( pSim, vSimInfo, pSeed );
|
|
||||||
Cec_SeedSimRestorePersistentInputs( pSeed );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo );
|
|
||||||
// Cec_ManSeqResimulateInfo( pSim->pAig, vSimInfo, NULL );
|
// Cec_ManSeqResimulateInfo( pSim->pAig, vSimInfo, NULL );
|
||||||
}
|
}
|
||||||
//Gia_ManEquivPrintOne( pSim->pAig, 85, 0 );
|
//Gia_ManEquivPrintOne( pSim->pAig, 85, 0 );
|
||||||
assert( iStart == Vec_IntSize(vCexStore) );
|
assert( iStart == Vec_IntSize(vCexStore) );
|
||||||
Vec_IntFreeP( &vOutBits );
|
Vec_PtrFree( vSimInfo );
|
||||||
if ( !pSeed )
|
Vec_IntFree( vPairs );
|
||||||
Vec_PtrFree( vSimInfo );
|
|
||||||
Vec_IntFreeP( &vPairs );
|
|
||||||
return RetValue;
|
return RetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Cec_ManResimulateCounterExamples( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore, int nFrames )
|
|
||||||
{
|
|
||||||
return Cec_ManResimulateCounterExamplesSeed( pSim, vCexStore, nFrames, NULL, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Resimulates counter-examples derived by the SAT solver.]
|
Synopsis [Resimulates counter-examples derived by the SAT solver.]
|
||||||
|
|
@ -772,101 +605,11 @@ int Cec_ManResimulateCounterExamplesComb( Cec_ManSim_t * pSim, Vec_Int_t * vCexS
|
||||||
return RetValue;
|
return RetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
|
||||||
|
|
||||||
Synopsis [Checks whether two endpoints are still in the same class.]
|
|
||||||
|
|
||||||
Description [Ring mode needs special handling for the closing edge
|
|
||||||
tail -> head because Gia_ObjHasSameRepr() compares raw
|
|
||||||
representatives and the head stores GIA_VOID.]
|
|
||||||
|
|
||||||
SideEffects []
|
|
||||||
|
|
||||||
SeeAlso []
|
|
||||||
|
|
||||||
***********************************************************************/
|
|
||||||
static int Cec_ManObjsStillMerged( Gia_Man_t * p, int iRepr, int iObj, int fRings )
|
|
||||||
{
|
|
||||||
int iReprRoot, iObjRoot;
|
|
||||||
if ( !fRings )
|
|
||||||
return Gia_ObjHasSameRepr( p, iRepr, iObj );
|
|
||||||
if ( iRepr == 0 )
|
|
||||||
return Gia_ObjIsConst( p, iObj );
|
|
||||||
if ( iObj == 0 )
|
|
||||||
return Gia_ObjIsConst( p, iRepr );
|
|
||||||
if ( !Gia_ObjIsClass( p, iRepr ) || !Gia_ObjIsClass( p, iObj ) )
|
|
||||||
return 0;
|
|
||||||
iReprRoot = Gia_ObjIsHead( p, iRepr ) ? iRepr : Gia_ObjRepr( p, iRepr );
|
|
||||||
iObjRoot = Gia_ObjIsHead( p, iObj ) ? iObj : Gia_ObjRepr( p, iObj );
|
|
||||||
return iReprRoot == iObjRoot && iReprRoot != GIA_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int Cec_ManObjToSplit( Gia_Man_t * p, int iRepr, int iObj, int fRings )
|
|
||||||
{
|
|
||||||
// For the ring closing edge (tail, head), split the tail. Splitting the
|
|
||||||
// head is also correct, but it changes the representative of the whole
|
|
||||||
// remaining class and creates a much larger incremental seed set.
|
|
||||||
if ( fRings && iObj > 0 && Gia_ObjIsHead( p, iObj ) && Gia_ObjIsClass( p, iRepr ) )
|
|
||||||
return iRepr;
|
|
||||||
return iObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Function*************************************************************
|
|
||||||
|
|
||||||
Synopsis [Directly splits pairs whose SAT result was trivial (nLits==0).]
|
|
||||||
|
|
||||||
Description [A trivial SAT (e.g. SRM PO became const 1) is a real
|
|
||||||
disproval but carries no CEX literals, so Cec_ManResimulateCounterExamples
|
|
||||||
cannot break the pair -- only random filler can, and usually does not.
|
|
||||||
Splitting these pairs directly is sound (SAT proved disequivalence) and
|
|
||||||
recovers work that the standard resim path leaves on the table.
|
|
||||||
|
|
||||||
Only nLits==0 entries are touched; nLits>0 entries are left for resim to
|
|
||||||
refine, matching the established behaviour in Gia_ManCheckRefinements
|
|
||||||
that avoids force-splitting CEX-bearing SAT pairs (token_ring regression).
|
|
||||||
|
|
||||||
Returns the number of pairs actually split this call.]
|
|
||||||
|
|
||||||
SideEffects []
|
|
||||||
|
|
||||||
SeeAlso []
|
|
||||||
|
|
||||||
***********************************************************************/
|
|
||||||
static int Cec_ManTrivialSatSplit( Gia_Man_t * pAig, Cec_ManSim_t * pSim,
|
|
||||||
Vec_Int_t * vCexStore, Vec_Str_t * vStatus, Vec_Int_t * vOutputs, int fRings )
|
|
||||||
{
|
|
||||||
int iStart = 0, Out, nSize, iRepr, iObj, iSplit, Count = 0;
|
|
||||||
while ( iStart < Vec_IntSize(vCexStore) )
|
|
||||||
{
|
|
||||||
Out = Vec_IntEntry( vCexStore, iStart++ );
|
|
||||||
assert( iStart < Vec_IntSize(vCexStore) );
|
|
||||||
nSize = Vec_IntEntry( vCexStore, iStart++ );
|
|
||||||
if ( nSize > 0 )
|
|
||||||
{
|
|
||||||
iStart += nSize;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( nSize < 0 )
|
|
||||||
continue;
|
|
||||||
// nSize == 0 -> trivial SAT, no CEX literals.
|
|
||||||
assert( Out < Vec_StrSize(vStatus) );
|
|
||||||
assert( Vec_StrEntry(vStatus, Out) == 0 );
|
|
||||||
iRepr = Vec_IntEntry( vOutputs, 2*Out );
|
|
||||||
iObj = Vec_IntEntry( vOutputs, 2*Out + 1 );
|
|
||||||
if ( !Cec_ManObjsStillMerged( pAig, iRepr, iObj, fRings ) )
|
|
||||||
continue;
|
|
||||||
iSplit = Cec_ManObjToSplit( pAig, iRepr, iObj, fRings );
|
|
||||||
if ( Cec_ManSimClassRemoveOne( pSim, iSplit ) )
|
|
||||||
Count++;
|
|
||||||
}
|
|
||||||
return Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Updates equivalence classes by marking those that timed out.]
|
Synopsis [Updates equivalence classes by marking those that timed out.]
|
||||||
|
|
||||||
Description [Returns 1 if all nodes are proved.]
|
Description [Returns 1 if all ndoes are proved.]
|
||||||
|
|
||||||
SideEffects []
|
SideEffects []
|
||||||
|
|
||||||
|
|
@ -1057,16 +800,7 @@ void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPr
|
||||||
Vec_Int_t * vCexStore;
|
Vec_Int_t * vCexStore;
|
||||||
Cec_ManSim_t * pSim;
|
Cec_ManSim_t * pSim;
|
||||||
Gia_Man_t * pSrm;
|
Gia_Man_t * pSrm;
|
||||||
int fChanges, i;
|
int fChanges, RetValue, i;
|
||||||
int nBmcResimFrames = pPars->nFrames + 1 + nPrefs;
|
|
||||||
int fBmcPersist = 0;
|
|
||||||
// BMC SRM is keyed only on pReprs (Gia_ManCorrSpecReduceInit ignores
|
|
||||||
// its fRings flag). So the incremental filter only needs pReprs-based
|
|
||||||
// seeds; pNexts changes cannot affect this SRM and there are no ring
|
|
||||||
// closing edges to reprove -- BMC is structurally simpler than the
|
|
||||||
// main inductive loop.
|
|
||||||
Cec_IncrMgr_t * pBmcMgr = NULL;
|
|
||||||
Cec_DynSrm_t * pBmcDynSrm = NULL;
|
|
||||||
// prepare simulation manager
|
// prepare simulation manager
|
||||||
Cec_ManSimSetDefaultParams( pParsSim );
|
Cec_ManSimSetDefaultParams( pParsSim );
|
||||||
pParsSim->nWords = pPars->nWords;
|
pParsSim->nWords = pPars->nWords;
|
||||||
|
|
@ -1079,102 +813,29 @@ void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPr
|
||||||
Cec_ManSatSetDefaultParams( pParsSat );
|
Cec_ManSatSetDefaultParams( pParsSat );
|
||||||
pParsSat->nBTLimit = pPars->nBTLimit;
|
pParsSat->nBTLimit = pPars->nBTLimit;
|
||||||
pParsSat->fVerbose = pPars->fVerbose;
|
pParsSat->fVerbose = pPars->fVerbose;
|
||||||
if ( pPars->fIncremental )
|
|
||||||
{
|
|
||||||
pBmcMgr = Cec_IncrMgrAlloc( pAig, pPars->nFrames + nPrefs );
|
|
||||||
Cec_IncrMgrSnapshotClasses( pBmcMgr );
|
|
||||||
}
|
|
||||||
if ( pPars->fDynSrm && pBmcMgr )
|
|
||||||
pBmcDynSrm = Cec_DynSrmAlloc( pAig, pBmcMgr );
|
|
||||||
fBmcPersist = ( pBmcDynSrm != NULL && pPars->fUseCSat );
|
|
||||||
fChanges = 1;
|
fChanges = 1;
|
||||||
for ( i = 0; fChanges && (!pPars->nLimitMax || i < pPars->nLimitMax); i++ )
|
for ( i = 0; fChanges && (!pPars->nLimitMax || i < pPars->nLimitMax); i++ )
|
||||||
{
|
{
|
||||||
int * pTfoMask = NULL;
|
|
||||||
int nReprSeeds = 0, nTotalPairs = 0, nActivePairs = 0;
|
|
||||||
int nBmcPos = 0;
|
|
||||||
if ( Cec_ParCorShouldStop( pPars ) )
|
if ( Cec_ParCorShouldStop( pPars ) )
|
||||||
break;
|
break;
|
||||||
abctime clkBmc = Abc_Clock();
|
abctime clkBmc = Abc_Clock();
|
||||||
fChanges = 0;
|
fChanges = 0;
|
||||||
// BMC SRM is non-ring (Gia_ManCorrSpecReduceInit ignores fRings);
|
pSrm = Gia_ManCorrSpecReduceInit( pAig, pPars->nFrames, nPrefs, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings );
|
||||||
// the incremental mask filters on pReprs-derived endpoints only.
|
if ( Gia_ManPoNum(pSrm) == 0 )
|
||||||
if ( pBmcMgr && i > 0 )
|
|
||||||
{
|
{
|
||||||
nReprSeeds = Cec_IncrMgrComputeSeeds( pBmcMgr );
|
Gia_ManStop( pSrm );
|
||||||
if ( nReprSeeds == 0 )
|
|
||||||
{
|
|
||||||
// No pReprs change. BMC SRM topology is unchanged.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Cec_IncrMgrComputeTfo( pBmcMgr );
|
|
||||||
// BMC SRM is non-ring; pass fRings=0 so we count (head, member)
|
|
||||||
// pairs only and skip any ring-edge bookkeeping.
|
|
||||||
if ( pBmcDynSrm )
|
|
||||||
Cec_DynSrmCountActivePairs( pBmcDynSrm, 0, pBmcMgr->pTfoMark, &nTotalPairs, &nActivePairs );
|
|
||||||
else
|
|
||||||
Cec_IncrMgrCountActivePairs( pBmcMgr, 0, pBmcMgr->pTfoMark, &nTotalPairs, &nActivePairs );
|
|
||||||
if ( nActivePairs == 0 )
|
|
||||||
break;
|
|
||||||
// Same fallback heuristic as the main loop: above ~70% active,
|
|
||||||
// the mask plus emission filter costs more than just rebuilding
|
|
||||||
// the full SRM.
|
|
||||||
if ( !( nTotalPairs > 0 && (ABC_INT64_T)10 * nActivePairs > (ABC_INT64_T)7 * nTotalPairs ) )
|
|
||||||
pTfoMask = pBmcMgr->pTfoMark;
|
|
||||||
}
|
|
||||||
pSrm = NULL;
|
|
||||||
if ( fBmcPersist )
|
|
||||||
Cec_DynSrmBuildCoreInit( pBmcDynSrm, pPars->nFrames, nPrefs, !pPars->fLatchCorr, &vOutputs, pTfoMask, pTfoMask ? CEC_EMIT_ACTIVE : CEC_EMIT_ALL );
|
|
||||||
else if ( pBmcDynSrm )
|
|
||||||
pSrm = Cec_DynSrmBuildInit( pBmcDynSrm, pPars->nFrames, nPrefs, !pPars->fLatchCorr, &vOutputs, pTfoMask, pTfoMask ? CEC_EMIT_ACTIVE : CEC_EMIT_ALL );
|
|
||||||
else if ( pTfoMask )
|
|
||||||
pSrm = Gia_ManCorrSpecReduceInit_Active( pAig, pPars->nFrames, nPrefs, !pPars->fLatchCorr, &vOutputs, pTfoMask );
|
|
||||||
else
|
|
||||||
pSrm = Gia_ManCorrSpecReduceInit( pAig, pPars->nFrames, nPrefs, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings );
|
|
||||||
nBmcPos = fBmcPersist ? Vec_IntSize(Cec_DynSrmOutLits(pBmcDynSrm)) : Gia_ManCoNum(pSrm);
|
|
||||||
if ( pTfoMask && pPars->fVeryVerbose )
|
|
||||||
Abc_Print( 1, " [bmc-incr i=%d repr=%d active=%d/%d POs=%d]\n",
|
|
||||||
i, nReprSeeds, nActivePairs, nTotalPairs, nBmcPos );
|
|
||||||
// Snapshot after SRM construction, before SAT/refine: this is the
|
|
||||||
// class state whose pairs were just emitted. The next iteration's
|
|
||||||
// diff vs this snapshot tells us which pairs are stale.
|
|
||||||
if ( pBmcMgr )
|
|
||||||
Cec_IncrMgrSnapshotClasses( pBmcMgr );
|
|
||||||
if ( nBmcPos == 0 )
|
|
||||||
{
|
|
||||||
if ( pSrm )
|
|
||||||
Gia_ManStop( pSrm );
|
|
||||||
Vec_IntFree( vOutputs );
|
Vec_IntFree( vOutputs );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pParsSat->nBTLimit *= 10;
|
pParsSat->nBTLimit *= 10;
|
||||||
if ( fBmcPersist )
|
if ( pPars->fUseCSat )
|
||||||
vCexStore = Cec_DynSrmSolve( pBmcDynSrm, pPars->nBTLimit, &vStatus );
|
|
||||||
else if ( pPars->fUseCSat )
|
|
||||||
vCexStore = Tas_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
|
vCexStore = Tas_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0 );
|
||||||
else
|
else
|
||||||
vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
|
vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
|
||||||
// refine classes with these counter-examples
|
// refine classes with these counter-examples
|
||||||
if ( Vec_IntSize(vCexStore) )
|
if ( Vec_IntSize(vCexStore) )
|
||||||
{
|
{
|
||||||
int nCexReal = 0, nCexTriv = 0;
|
RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nPrefs );
|
||||||
// classify CEX entries: real (nLits>0) / trivial (==0) / fail (==-1)
|
|
||||||
Cec_ManCexStoreClassify( vCexStore, &nCexReal, &nCexTriv, NULL );
|
|
||||||
// only invoke resim when there is a real CEX (nLits>0). Trivial
|
|
||||||
// (nLits==0) and fail (==-1) entries carry no literals; trivial
|
|
||||||
// pairs are handled by direct split below, fail pairs by chk.
|
|
||||||
if ( nCexReal > 0 || !pPars->fSkipFailResim )
|
|
||||||
{
|
|
||||||
// Keep BMC/init CEX resimulation on the canonical full path even
|
|
||||||
// in incremental mode. BMC counterexamples are partial models
|
|
||||||
// of frame/prefix-specific SAT obligations; retaining them as a
|
|
||||||
// persistent simulation background over-refines classes and can
|
|
||||||
// significantly hurt gate QoR. The main correspondence loop
|
|
||||||
// below still uses event resim for ordinary refinement batches.
|
|
||||||
Cec_ManResimulateCounterExamples( pSim, vCexStore, nBmcResimFrames );
|
|
||||||
}
|
|
||||||
if ( nCexTriv > 0 )
|
|
||||||
Cec_ManTrivialSatSplit( pAig, pSim, vCexStore, vStatus, vOutputs, pPars->fUseRings );
|
|
||||||
Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
|
Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
|
||||||
fChanges = 1;
|
fChanges = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1183,14 +844,11 @@ void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPr
|
||||||
// recycle
|
// recycle
|
||||||
Vec_IntFree( vCexStore );
|
Vec_IntFree( vCexStore );
|
||||||
Vec_StrFree( vStatus );
|
Vec_StrFree( vStatus );
|
||||||
if ( pSrm )
|
Gia_ManStop( pSrm );
|
||||||
Gia_ManStop( pSrm );
|
|
||||||
Vec_IntFree( vOutputs );
|
Vec_IntFree( vOutputs );
|
||||||
if ( Cec_ParCorShouldStop( pPars ) )
|
if ( Cec_ParCorShouldStop( pPars ) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Cec_DynSrmFree( pBmcDynSrm );
|
|
||||||
Cec_IncrMgrFree( pBmcMgr );
|
|
||||||
Cec_ManSimStop( pSim );
|
Cec_ManSimStop( pSim );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1287,19 +945,10 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
||||||
Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
|
Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
|
||||||
Cec_ManSim_t * pSim;
|
Cec_ManSim_t * pSim;
|
||||||
Gia_Man_t * pSrm;
|
Gia_Man_t * pSrm;
|
||||||
int r, nPrev[4] = {0};
|
int r, RetValue, nPrev[4] = {0};
|
||||||
abctime clkTotal = Abc_Clock();
|
abctime clkTotal = Abc_Clock();
|
||||||
abctime clkSat = 0, clkSim = 0, clkSrm = 0;
|
abctime clkSat = 0, clkSim = 0, clkSrm = 0;
|
||||||
abctime clk2, clk = Abc_Clock();
|
abctime clk2, clk = Abc_Clock();
|
||||||
// Incremental active-list manager (NULL if -i not set)
|
|
||||||
Cec_IncrMgr_t * pMgr = NULL;
|
|
||||||
// Persistent dynamic SRM construction manager (NULL outside incremental mode).
|
|
||||||
Cec_DynSrm_t * pDynSrm = NULL;
|
|
||||||
int fPersist = 0; // incremental + circuit-SAT: solve persistent pCore directly
|
|
||||||
// Unified CEX event-resimulation manager (NULL outside incremental mode).
|
|
||||||
Cec_SeedSim_t * pSeedSim = NULL;
|
|
||||||
abctime clkIncr = 0;
|
|
||||||
int nIncrSkipped = 0, nIncrFallback = 0;
|
|
||||||
if ( Gia_ManRegNum(pAig) == 0 )
|
if ( Gia_ManRegNum(pAig) == 0 )
|
||||||
{
|
{
|
||||||
Abc_Print( 1, "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" );
|
Abc_Print( 1, "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" );
|
||||||
|
|
@ -1330,9 +979,9 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
||||||
pParsSat->nBTLimit = Abc_MinInt( pParsSat->nBTLimit, 1000 );
|
pParsSat->nBTLimit = Abc_MinInt( pParsSat->nBTLimit, 1000 );
|
||||||
if ( pPars->fVerbose )
|
if ( pPars->fVerbose )
|
||||||
{
|
{
|
||||||
Abc_Print( 1, "Obj = %7d. And = %7d. Conf = %5d. Fr = %d. Lcorr = %d. Ring = %d. CSat = %d. Incr = %d. Dyn = %d.\n",
|
Abc_Print( 1, "Obj = %7d. And = %7d. Conf = %5d. Fr = %d. Lcorr = %d. Ring = %d. CSat = %d.\n",
|
||||||
Gia_ManObjNum(pAig), Gia_ManAndNum(pAig),
|
Gia_ManObjNum(pAig), Gia_ManAndNum(pAig),
|
||||||
pPars->nBTLimit, pPars->nFrames, pPars->fLatchCorr, pPars->fUseRings, pPars->fUseCSat, pPars->fIncremental, pPars->fDynSrm );
|
pPars->nBTLimit, pPars->nFrames, pPars->fLatchCorr, pPars->fUseRings, pPars->fUseCSat );
|
||||||
Cec_ManRefinedClassPrintStats( pAig, NULL, 0, Abc_Clock() - clk );
|
Cec_ManRefinedClassPrintStats( pAig, NULL, 0, Abc_Clock() - clk );
|
||||||
}
|
}
|
||||||
// check the base case
|
// check the base case
|
||||||
|
|
@ -1350,136 +999,41 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
||||||
Cec_ManSimStop( pSim );
|
Cec_ManSimStop( pSim );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ( pPars->fIncremental )
|
|
||||||
{
|
|
||||||
pMgr = Cec_IncrMgrAlloc( pAig, pPars->nFrames );
|
|
||||||
Cec_IncrMgrSnapshotClasses( pMgr );
|
|
||||||
}
|
|
||||||
if ( pPars->fDynSrm && pMgr )
|
|
||||||
pDynSrm = Cec_DynSrmAlloc( pAig, pMgr );
|
|
||||||
// Incremental persistence path: solve the persistent COless pCore directly (circuit
|
|
||||||
// SAT only), skipping the per-round throwaway view that BuildView copies.
|
|
||||||
fPersist = ( pDynSrm != NULL && pPars->fUseCSat );
|
|
||||||
// Resident local-sim manager sized for the main-loop resim depth.
|
|
||||||
if ( pPars->fIncrSim )
|
|
||||||
pSeedSim = Cec_SeedSimAlloc( pAig, pPars->nFrames + 1 + nAddFrames, pPars->nFrames, pParsSim->nWords );
|
|
||||||
// perform refinement of equivalence classes
|
// perform refinement of equivalence classes
|
||||||
for ( r = 0; r < nIterMax; r++ )
|
for ( r = 0; r < nIterMax; r++ )
|
||||||
{
|
{
|
||||||
if ( Cec_ParCorShouldStop( pPars ) )
|
if ( Cec_ParCorShouldStop( pPars ) )
|
||||||
{
|
{
|
||||||
Cec_ManSimStop( pSim );
|
Cec_ManSimStop( pSim );
|
||||||
Cec_DynSrmFree( pDynSrm );
|
|
||||||
Cec_IncrMgrFree( pMgr );
|
|
||||||
Cec_SeedSimFree( pSeedSim );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ( pPars->nStepsMax == r )
|
if ( pPars->nStepsMax == r )
|
||||||
{
|
{
|
||||||
Cec_ManSimStop( pSim );
|
Cec_ManSimStop( pSim );
|
||||||
Cec_DynSrmFree( pDynSrm );
|
|
||||||
Cec_IncrMgrFree( pMgr );
|
|
||||||
Cec_SeedSimFree( pSeedSim );
|
|
||||||
Abc_Print( 1, "Stopped signal correspondence after %d refiment iterations.\n", r );
|
Abc_Print( 1, "Stopped signal correspondence after %d refiment iterations.\n", r );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
clk = Abc_Clock();
|
clk = Abc_Clock();
|
||||||
// perform speculative reduction (with optional active-list filter)
|
// perform speculative reduction
|
||||||
clk2 = Abc_Clock();
|
clk2 = Abc_Clock();
|
||||||
{
|
pSrm = Gia_ManCorrSpecReduce( pAig, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings );
|
||||||
int * pTfoMask = NULL;
|
assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == Gia_ManRegNum(pAig)+(pPars->nFrames+!pPars->fLatchCorr)*Gia_ManPiNum(pAig) );
|
||||||
int nReprSeeds = 0, nNextChanges = 0;
|
|
||||||
int nTotalPairs = 0, nActivePairs = 0;
|
|
||||||
// Decide whether to apply incremental TFO mask this iteration.
|
|
||||||
// Skip on r==0 because the first full SRM establishes the cache.
|
|
||||||
if ( pMgr && r > 0 )
|
|
||||||
{
|
|
||||||
abctime clkI = Abc_Clock();
|
|
||||||
nReprSeeds = Cec_IncrMgrComputeSeeds( pMgr );
|
|
||||||
nNextChanges = pPars->fUseRings ? Cec_IncrMgrCountNextChanges( pMgr ) : 0;
|
|
||||||
if ( nReprSeeds == 0 && nNextChanges == 0 )
|
|
||||||
{
|
|
||||||
// No class-state change since the full/active SRM just
|
|
||||||
// proved these pairs; this is true convergence.
|
|
||||||
clkIncr += Abc_Clock() - clkI;
|
|
||||||
clkSrm += Abc_Clock() - clk2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Cec_IncrMgrComputeTfo( pMgr );
|
|
||||||
if ( pDynSrm )
|
|
||||||
Cec_DynSrmCountActivePairs( pDynSrm, pPars->fUseRings, pMgr->pTfoMark, &nTotalPairs, &nActivePairs );
|
|
||||||
else
|
|
||||||
Cec_IncrMgrCountActivePairs( pMgr, pPars->fUseRings, pMgr->pTfoMark, &nTotalPairs, &nActivePairs );
|
|
||||||
if ( nActivePairs == 0 )
|
|
||||||
{
|
|
||||||
// Classes changed, but no remaining candidate pair
|
|
||||||
// depends on the changes and no new ring edge exists.
|
|
||||||
clkIncr += Abc_Clock() - clkI;
|
|
||||||
clkSrm += Abc_Clock() - clk2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Fallback is based on emitted candidate pairs, not seed count.
|
|
||||||
// Above ~70% active pairs, full SRM is usually cheaper.
|
|
||||||
else if ( nTotalPairs > 0 && (ABC_INT64_T)10 * nActivePairs > (ABC_INT64_T)7 * nTotalPairs )
|
|
||||||
{
|
|
||||||
nIncrFallback++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pTfoMask = pMgr->pTfoMark;
|
|
||||||
nIncrSkipped += nTotalPairs - nActivePairs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clkIncr += Abc_Clock() - clkI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incremental persistence under circuit-SAT: build the COless pCore and solve
|
|
||||||
// its root literals directly below; skip the per-round throwaway view.
|
|
||||||
if ( fPersist )
|
|
||||||
{
|
|
||||||
Cec_DynSrmBuildCore( pDynSrm, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings, pTfoMask, pTfoMask ? CEC_EMIT_ACTIVE : CEC_EMIT_ALL );
|
|
||||||
pSrm = NULL;
|
|
||||||
}
|
|
||||||
else if ( pDynSrm )
|
|
||||||
pSrm = Cec_DynSrmBuild( pDynSrm, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings, pTfoMask, pTfoMask ? CEC_EMIT_ACTIVE : CEC_EMIT_ALL );
|
|
||||||
else if ( pTfoMask )
|
|
||||||
pSrm = Gia_ManCorrSpecReduce_Emit( pAig, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings, pTfoMask, pMgr, CEC_EMIT_ACTIVE, NULL );
|
|
||||||
else
|
|
||||||
pSrm = Gia_ManCorrSpecReduce( pAig, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings );
|
|
||||||
if ( pTfoMask && pPars->fVeryVerbose )
|
|
||||||
Abc_Print( 1, " [incr r=%d repr=%d next=%d tfo=%d active=%d/%d POs=%d]\n",
|
|
||||||
r, nReprSeeds, nNextChanges,
|
|
||||||
Vec_IntSize(pMgr->vTfoNodes), nActivePairs, nTotalPairs,
|
|
||||||
fPersist ? Vec_IntSize(Cec_DynSrmOutLits(pDynSrm)) : Gia_ManCoNum(pSrm) );
|
|
||||||
// Snapshot after SRM construction: the active builder still needs
|
|
||||||
// the old pNexts snapshot to recognize newly-created ring edges.
|
|
||||||
// SAT/sim refinement below is what creates the next iteration's diff.
|
|
||||||
if ( pMgr )
|
|
||||||
Cec_IncrMgrSnapshotClasses( pMgr );
|
|
||||||
}
|
|
||||||
assert( fPersist || (Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == Gia_ManRegNum(pAig)+(pPars->nFrames+!pPars->fLatchCorr)*Gia_ManPiNum(pAig)) );
|
|
||||||
clkSrm += Abc_Clock() - clk2;
|
clkSrm += Abc_Clock() - clk2;
|
||||||
if ( (fPersist ? Vec_IntSize(Cec_DynSrmOutLits(pDynSrm)) : Gia_ManCoNum(pSrm)) == 0 )
|
if ( Gia_ManCoNum(pSrm) == 0 )
|
||||||
{
|
{
|
||||||
Vec_IntFree( vOutputs );
|
Vec_IntFree( vOutputs );
|
||||||
if ( pSrm )
|
Gia_ManStop( pSrm );
|
||||||
Gia_ManStop( pSrm );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//Gia_DumpAiger( pSrm, "corrsrm", r, 2 );
|
//Gia_DumpAiger( pSrm, "corrsrm", r, 2 );
|
||||||
// found counter-examples to speculation
|
// found counter-examples to speculation
|
||||||
clk2 = Abc_Clock();
|
clk2 = Abc_Clock();
|
||||||
if ( fPersist )
|
if ( pPars->fUseCSat )
|
||||||
vCexStore = Cec_DynSrmSolve( pDynSrm, pPars->nBTLimit, &vStatus );
|
|
||||||
else if ( pPars->fUseCSat )
|
|
||||||
vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0, 0 );
|
vCexStore = Cbs_ManSolveMiterNc( pSrm, pPars->nBTLimit, &vStatus, 0, 0 );
|
||||||
else
|
else
|
||||||
vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
|
vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus );
|
||||||
if ( pSrm )
|
Gia_ManStop( pSrm );
|
||||||
Gia_ManStop( pSrm );
|
|
||||||
clkSat += Abc_Clock() - clk2;
|
clkSat += Abc_Clock() - clk2;
|
||||||
if ( Vec_IntSize(vCexStore) == 0 )
|
if ( Vec_IntSize(vCexStore) == 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -1492,21 +1046,10 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
||||||
|
|
||||||
// refine classes with these counter-examples
|
// refine classes with these counter-examples
|
||||||
clk2 = Abc_Clock();
|
clk2 = Abc_Clock();
|
||||||
{
|
RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nAddFrames );
|
||||||
int nCexReal = 0, nCexTriv = 0;
|
Vec_IntFree( vCexStore );
|
||||||
Cec_ManCexStoreClassify( vCexStore, &nCexReal, &nCexTriv, NULL );
|
clkSim += Abc_Clock() - clk2;
|
||||||
if ( nCexReal > 0 || !pPars->fSkipFailResim )
|
Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
|
||||||
{
|
|
||||||
Cec_ManResimulateCounterExamplesSeed( pSim,
|
|
||||||
vCexStore, pPars->nFrames + 1 + nAddFrames,
|
|
||||||
pSeedSim, vOutputs );
|
|
||||||
}
|
|
||||||
if ( nCexTriv > 0 )
|
|
||||||
Cec_ManTrivialSatSplit( pAig, pSim, vCexStore, vStatus, vOutputs, pPars->fUseRings );
|
|
||||||
Vec_IntFree( vCexStore );
|
|
||||||
clkSim += Abc_Clock() - clk2;
|
|
||||||
Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings );
|
|
||||||
}
|
|
||||||
if ( pPars->fVerbose )
|
if ( pPars->fVerbose )
|
||||||
Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, Abc_Clock() - clk );
|
Cec_ManRefinedClassPrintStats( pAig, vStatus, r+1, Abc_Clock() - clk );
|
||||||
Vec_StrFree( vStatus );
|
Vec_StrFree( vStatus );
|
||||||
|
|
@ -1515,9 +1058,6 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
||||||
if ( Cec_ParCorShouldStop( pPars ) )
|
if ( Cec_ParCorShouldStop( pPars ) )
|
||||||
{
|
{
|
||||||
Cec_ManSimStop( pSim );
|
Cec_ManSimStop( pSim );
|
||||||
Cec_DynSrmFree( pDynSrm );
|
|
||||||
Cec_IncrMgrFree( pMgr );
|
|
||||||
Cec_SeedSimFree( pSeedSim );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// quit if const is no longer there
|
// quit if const is no longer there
|
||||||
|
|
@ -1527,9 +1067,6 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
||||||
printf( "because the property output is no longer a candidate constant.\n" );
|
printf( "because the property output is no longer a candidate constant.\n" );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
Cec_ManSimStop( pSim );
|
Cec_ManSimStop( pSim );
|
||||||
Cec_DynSrmFree( pDynSrm );
|
|
||||||
Cec_IncrMgrFree( pMgr );
|
|
||||||
Cec_SeedSimFree( pSeedSim );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( pPars->nLimitMax )
|
if ( pPars->nLimitMax )
|
||||||
|
|
@ -1541,9 +1078,6 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
||||||
printf( "because refinement does not proceed quickly.\n" );
|
printf( "because refinement does not proceed quickly.\n" );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
Cec_ManSimStop( pSim );
|
Cec_ManSimStop( pSim );
|
||||||
Cec_DynSrmFree( pDynSrm );
|
|
||||||
Cec_IncrMgrFree( pMgr );
|
|
||||||
Cec_SeedSimFree( pSeedSim );
|
|
||||||
ABC_FREE( pAig->pReprs );
|
ABC_FREE( pAig->pReprs );
|
||||||
ABC_FREE( pAig->pNexts );
|
ABC_FREE( pAig->pNexts );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1571,19 +1105,9 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
||||||
ABC_PRTP( "Sat ", clkSat, clkTotal );
|
ABC_PRTP( "Sat ", clkSat, clkTotal );
|
||||||
ABC_PRTP( "Sim ", clkSim, clkTotal );
|
ABC_PRTP( "Sim ", clkSim, clkTotal );
|
||||||
ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal );
|
ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal );
|
||||||
if ( pMgr )
|
|
||||||
{
|
|
||||||
ABC_PRTP( "Incr ", clkIncr, clkTotal );
|
|
||||||
Abc_Print( 1, "Incr: fallback rounds = %d, skipped candidate pairs = %d\n", nIncrFallback, nIncrSkipped );
|
|
||||||
}
|
|
||||||
if ( pDynSrm )
|
|
||||||
Cec_DynSrmPrintStats( pDynSrm );
|
|
||||||
Abc_PrintTime( 1, "TOTAL", clkTotal );
|
Abc_PrintTime( 1, "TOTAL", clkTotal );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
}
|
}
|
||||||
Cec_IncrMgrFree( pMgr );
|
|
||||||
Cec_DynSrmFree( pDynSrm );
|
|
||||||
Cec_SeedSimFree( pSeedSim );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,155 @@
|
||||||
|
/**CFile****************************************************************
|
||||||
|
|
||||||
|
FileName [cecCorrCert.c]
|
||||||
|
|
||||||
|
SystemName [ABC: Logic synthesis and verification system.]
|
||||||
|
|
||||||
|
PackageName [Combinational equivalence checking.]
|
||||||
|
|
||||||
|
Synopsis [Kissat certificate for the final &scorr2 fixed point.]
|
||||||
|
|
||||||
|
Author [Xiran Zhao]
|
||||||
|
|
||||||
|
Affiliation [University of Chinese Academy of Sciences (UCAS)]
|
||||||
|
|
||||||
|
Date [Ver. 1.0. Started - Jun 2026.]
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "cecInt.h"
|
||||||
|
#include "sat/cnf/cnf.h"
|
||||||
|
#include "sat/kissat/kissatSolver.h"
|
||||||
|
|
||||||
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
||||||
|
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Certifies all SRM mismatch outputs in one Kissat call.]
|
||||||
|
|
||||||
|
Description [The generated CNF contains one OR clause over all SRM
|
||||||
|
outputs. UNSAT therefore proves every candidate pair simultaneously.
|
||||||
|
On SAT, one full CI assignment and one violated output are returned in
|
||||||
|
the same format used by the ordinary correspondence refinement loop.
|
||||||
|
|
||||||
|
Return values are 1 (all outputs UNSAT), 0 (SAT counterexample), and
|
||||||
|
-1 (UNKNOWN or an inconsistent model/API result).]
|
||||||
|
|
||||||
|
SideEffects [None on pSrm or the host correspondence classes.]
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Cec_ManCorrKissatCertify( Gia_Man_t * pSrm, Vec_Int_t * vOutputs,
|
||||||
|
Vec_Int_t ** pvCexStore, Vec_Str_t ** pvStatus, int * piOut, int fVerbose )
|
||||||
|
{
|
||||||
|
Cnf_Dat_t * pCnf;
|
||||||
|
kissat_solver * pSat;
|
||||||
|
Vec_Int_t * vCexStore = Vec_IntAlloc( 16 );
|
||||||
|
Vec_Str_t * vStatus = Vec_StrAlloc( Gia_ManCoNum(pSrm) );
|
||||||
|
Gia_Obj_t * pObj;
|
||||||
|
unsigned char * pValues = NULL;
|
||||||
|
abctime clk = Abc_Clock();
|
||||||
|
int i, iVar, * pBeg, * pEnd, Status = -1, iOut = -1;
|
||||||
|
|
||||||
|
assert( Vec_IntSize(vOutputs) == 2 * Gia_ManCoNum(pSrm) );
|
||||||
|
*pvCexStore = NULL;
|
||||||
|
*pvStatus = NULL;
|
||||||
|
*piOut = -1;
|
||||||
|
for ( i = 0; i < Gia_ManCoNum(pSrm); i++ )
|
||||||
|
Vec_StrPush( vStatus, 1 );
|
||||||
|
if ( Gia_ManCoNum(pSrm) == 0 )
|
||||||
|
{
|
||||||
|
if ( fVerbose )
|
||||||
|
Abc_Print( 1, "[scorr2-audit] result=pass pairs=0 reason=structural time_sec=0.00\n" );
|
||||||
|
*pvCexStore = vCexStore;
|
||||||
|
*pvStatus = vStatus;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fAddOrCla=1 asserts that at least one mismatch output is true.
|
||||||
|
pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pSrm, 8, 0, 1, 0, 0 );
|
||||||
|
pSat = kissat_solver_new();
|
||||||
|
kissat_solver_setnvars( pSat, pCnf->nVars );
|
||||||
|
Cnf_CnfForClause( pCnf, pBeg, pEnd, i )
|
||||||
|
if ( !kissat_solver_addclause(pSat, pBeg, pEnd) )
|
||||||
|
{
|
||||||
|
// Contradiction during clause loading is already an UNSAT proof.
|
||||||
|
Status = -1;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
Status = kissat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
|
||||||
|
if ( Status == -1 )
|
||||||
|
goto finish;
|
||||||
|
if ( Status == 0 )
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
// Evaluate the GIA under the Kissat model to identify a violated pair.
|
||||||
|
pValues = ABC_CALLOC( unsigned char, Gia_ManObjNum(pSrm) );
|
||||||
|
Gia_ManForEachCi( pSrm, pObj, i )
|
||||||
|
{
|
||||||
|
iVar = pCnf->pVarNums[Gia_ObjId(pSrm, pObj)];
|
||||||
|
pValues[Gia_ObjId(pSrm, pObj)] = iVar >= 0 ? kissat_solver_get_var_value(pSat, iVar) : 0;
|
||||||
|
}
|
||||||
|
Gia_ManForEachAnd( pSrm, pObj, i )
|
||||||
|
pValues[Gia_ObjId(pSrm, pObj)] =
|
||||||
|
(pValues[Gia_ObjFaninId0p(pSrm, pObj)] ^ Gia_ObjFaninC0(pObj)) &
|
||||||
|
(pValues[Gia_ObjFaninId1p(pSrm, pObj)] ^ Gia_ObjFaninC1(pObj));
|
||||||
|
Gia_ManForEachCo( pSrm, pObj, i )
|
||||||
|
if ( pValues[Gia_ObjFaninId0p(pSrm, pObj)] ^ Gia_ObjFaninC0(pObj) )
|
||||||
|
{
|
||||||
|
iOut = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( iOut < 0 )
|
||||||
|
{
|
||||||
|
Status = 0;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Vec_Int_t * vCex = Vec_IntAlloc( Gia_ManCiNum(pSrm) );
|
||||||
|
Gia_ManForEachCi( pSrm, pObj, i )
|
||||||
|
Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjCioId(pObj), !pValues[Gia_ObjId(pSrm, pObj)]) );
|
||||||
|
Vec_StrWriteEntry( vStatus, iOut, 0 );
|
||||||
|
Cec_ManSatAddToStore( vCexStore, vCex, iOut );
|
||||||
|
Vec_IntFree( vCex );
|
||||||
|
}
|
||||||
|
|
||||||
|
finish:
|
||||||
|
if ( fVerbose )
|
||||||
|
{
|
||||||
|
if ( Status == -1 )
|
||||||
|
Abc_Print( 1, "[scorr2-audit] result=pass pairs=%d vars=%d clauses=%d ", Gia_ManCoNum(pSrm), pCnf->nVars, pCnf->nClauses );
|
||||||
|
else if ( Status == 1 && iOut >= 0 )
|
||||||
|
Abc_Print( 1, "[scorr2-audit] result=counterexample pair=%d/%d nodes=%d/%d ", iOut, Gia_ManCoNum(pSrm), Vec_IntEntry(vOutputs, 2*iOut), Vec_IntEntry(vOutputs, 2*iOut+1) );
|
||||||
|
else
|
||||||
|
Abc_Print( -1, "[scorr2-audit] result=unknown pairs=%d ", Gia_ManCoNum(pSrm) );
|
||||||
|
Abc_PrintTime( 1, "Kissat", Abc_Clock() - clk );
|
||||||
|
if ( Status == 1 && iOut >= 0 && pValues != NULL )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "[scorr2-audit] model" );
|
||||||
|
Gia_ManForEachCi( pSrm, pObj, i )
|
||||||
|
{
|
||||||
|
if ( i == 16 )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, " ..." );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Abc_Print( -1, " ci%d=%d", Gia_ObjCioId(pObj), pValues[Gia_ObjId(pSrm, pObj)] );
|
||||||
|
}
|
||||||
|
Abc_Print( -1, "\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ABC_FREE( pValues );
|
||||||
|
kissat_solver_delete( pSat );
|
||||||
|
Cnf_DataFree( pCnf );
|
||||||
|
*pvCexStore = vCexStore;
|
||||||
|
*pvStatus = vStatus;
|
||||||
|
*piOut = iOut;
|
||||||
|
if ( Status == -1 )
|
||||||
|
return 1;
|
||||||
|
if ( Status == 1 && iOut >= 0 )
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
@ -6,11 +6,11 @@
|
||||||
|
|
||||||
PackageName [Combinational equivalence checking.]
|
PackageName [Combinational equivalence checking.]
|
||||||
|
|
||||||
Synopsis [Dynamic SRM manager for &scorr.]
|
Synopsis [Dynamic SRM manager for &scorr2.]
|
||||||
|
|
||||||
Author [Xiran Zhao]
|
Author [Xiran Zhao]
|
||||||
|
|
||||||
Affiliation [University of Chinese Academy of Sciences]
|
Affiliation [University of Chinese Academy of Sciences (UCAS)]
|
||||||
|
|
||||||
Date [Ver. 1.0. Started - Jun 2026.]
|
Date [Ver. 1.0. Started - Jun 2026.]
|
||||||
|
|
||||||
|
|
@ -20,6 +20,13 @@
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_START
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
||||||
|
#define CEC_BMC_TAS_PROBE_ROOTS 8
|
||||||
|
#define CEC_BMC_TAS_PROBE_SUCCESS_PCT 75
|
||||||
|
#define CEC_BMC_TAS_CORE_NORM_MAX 25000
|
||||||
|
#define CEC_BMC_TAS_CORE_ABS_MAX 200000
|
||||||
|
#define CEC_BMC_TAS_RETRY_ROOTS_MAX 8192
|
||||||
|
#define CEC_BMC_TAS_STRUCT_WORK_MAX 64000000LL
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// DECLARATIONS ///
|
/// DECLARATIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -29,8 +36,12 @@ struct Cec_DynSrm_t_
|
||||||
Gia_Man_t * pAig; // host AIG; owned by caller
|
Gia_Man_t * pAig; // host AIG; owned by caller
|
||||||
Cec_IncrMgr_t * pIncr; // active-list manager; owned by caller
|
Cec_IncrMgr_t * pIncr; // active-list manager; owned by caller
|
||||||
Gia_Man_t * pCore; // persistent SRM core without COs
|
Gia_Man_t * pCore; // persistent SRM core without COs
|
||||||
Cbs_Man_t * pCbs; // resident circuit-SAT manager on pCore
|
Cbs_Man_t * pCbs; // resident circuit-SAT manager on pCore (-D direct solving)
|
||||||
|
Tas_Man_t * pTas; // resident TAS manager on pCore (-D direct solving)
|
||||||
int nCoreObjsAtReset; // real post-build pCore size after the last cold (re)build, for compaction (0 until that build finishes)
|
int nCoreObjsAtReset; // real post-build pCore size after the last cold (re)build, for compaction (0 until that build finishes)
|
||||||
|
int fUseAdaptive; // use timing-guided cold rebuilds in addition to the hard bloat guard
|
||||||
|
int nCompactMult;
|
||||||
|
int fForceRebuild;
|
||||||
Vec_Int_t * vSpecLits; // cached core literals, indexed by frame/object
|
Vec_Int_t * vSpecLits; // cached core literals, indexed by frame/object
|
||||||
Vec_Int_t * vOutLits; // core literals selected as current SAT outputs
|
Vec_Int_t * vOutLits; // core literals selected as current SAT outputs
|
||||||
Vec_Int_t * vCopyTouched; // core ANDs copied into the current view
|
Vec_Int_t * vCopyTouched; // core ANDs copied into the current view
|
||||||
|
|
@ -38,8 +49,6 @@ struct Cec_DynSrm_t_
|
||||||
Vec_Int_t * vRoMap; // host obj id -> RO index
|
Vec_Int_t * vRoMap; // host obj id -> RO index
|
||||||
// Phase-2 measurement (behavior-preserving): per-key stamp used to count the
|
// Phase-2 measurement (behavior-preserving): per-key stamp used to count the
|
||||||
// union of true-value (no repr substitution) cones of the active pairs.
|
// union of true-value (no repr substitution) cones of the active pairs.
|
||||||
int * pTrueMark; // size = nFramesTotal * nObjs; 0 = unvisited
|
|
||||||
int nTrueStamp; // current visit stamp
|
|
||||||
int nObjs;
|
int nObjs;
|
||||||
int nPis;
|
int nPis;
|
||||||
int nRegs;
|
int nRegs;
|
||||||
|
|
@ -47,8 +56,21 @@ struct Cec_DynSrm_t_
|
||||||
int nCoreCiNum;
|
int nCoreCiNum;
|
||||||
int nBuilds;
|
int nBuilds;
|
||||||
int nBuildsActive;
|
int nBuildsActive;
|
||||||
|
int nBuildsFull;
|
||||||
int nCoreResets;
|
int nCoreResets;
|
||||||
int nCoreCompactions;
|
int nCoreCompactions;
|
||||||
|
int nIncrFallbackResets;
|
||||||
|
int nDynActiveResets;
|
||||||
|
int nAdaptiveResets;
|
||||||
|
int nAdaptiveBurstResets;
|
||||||
|
int nAdaptiveBurstLeft;
|
||||||
|
int nBuildsSinceReset;
|
||||||
|
int nLastBuildReset;
|
||||||
|
int nLastResetReason;
|
||||||
|
int nForceResetReason;
|
||||||
|
int nLastResetSpan;
|
||||||
|
int nAdaptResetSamples;
|
||||||
|
int nAdaptReuseSamples;
|
||||||
int nCoreBuilds;
|
int nCoreBuilds;
|
||||||
int nViewBuilds;
|
int nViewBuilds;
|
||||||
int nCacheFullClears;
|
int nCacheFullClears;
|
||||||
|
|
@ -60,18 +82,66 @@ struct Cec_DynSrm_t_
|
||||||
int nCoreObjsMax;
|
int nCoreObjsMax;
|
||||||
int nViewObjsLast;
|
int nViewObjsLast;
|
||||||
int nViewObjsMax;
|
int nViewObjsMax;
|
||||||
|
int nCoreDeltaLast;
|
||||||
|
int nCoreDeltaMax;
|
||||||
|
int nCoreBloatLastPermil;
|
||||||
|
int nCoreBloatMaxPermil;
|
||||||
|
ABC_INT64_T nOutLitsActiveSum;
|
||||||
|
ABC_INT64_T nOutLitsFullSum;
|
||||||
|
ABC_INT64_T nCoreObjsActiveSum;
|
||||||
|
ABC_INT64_T nCoreObjsFullSum;
|
||||||
|
ABC_INT64_T nSolveIters;
|
||||||
|
ABC_INT64_T nSolveCalls;
|
||||||
|
ABC_INT64_T nSolveReal;
|
||||||
|
ABC_INT64_T nSolveTriv;
|
||||||
|
ABC_INT64_T nSolveFail;
|
||||||
|
ABC_INT64_T nSolveFailIters;
|
||||||
|
ABC_INT64_T nFailCoreObjSum;
|
||||||
|
ABC_INT64_T nFailOutLitSum;
|
||||||
|
int nFailCoreObjMax;
|
||||||
|
int nFailOutLitMax;
|
||||||
|
double dAdaptResetCost;
|
||||||
|
double dAdaptReuseCost;
|
||||||
|
double dAdaptLastCost;
|
||||||
|
abctime tBuildLast;
|
||||||
|
abctime tBuildEnsureLast;
|
||||||
|
abctime tBuildInvalidateLast;
|
||||||
|
abctime tBuildEmitLast;
|
||||||
|
abctime tBuildTotal;
|
||||||
|
abctime tBuildResetTotal;
|
||||||
|
abctime tBuildReuseTotal;
|
||||||
|
abctime tBuildEnsureTotal;
|
||||||
|
abctime tBuildInvalidateTotal;
|
||||||
|
abctime tBuildEmitTotal;
|
||||||
|
abctime tViewLast;
|
||||||
|
abctime tViewTotal;
|
||||||
|
abctime tSolveLast;
|
||||||
|
ABC_INT64_T nBmcAdaptiveRounds;
|
||||||
|
ABC_INT64_T nBmcCbsRoots;
|
||||||
|
ABC_INT64_T nBmcCbsUnknown;
|
||||||
|
ABC_INT64_T nBmcTasProbeRoots;
|
||||||
|
ABC_INT64_T nBmcTasRetryRoots;
|
||||||
|
ABC_INT64_T nBmcTasResolved;
|
||||||
|
ABC_INT64_T nBmcTasUnknown;
|
||||||
|
ABC_INT64_T nBmcTasEnabledRounds;
|
||||||
|
ABC_INT64_T nBmcTasSkippedLarge;
|
||||||
|
ABC_INT64_T nBmcTasSkippedWork;
|
||||||
|
ABC_INT64_T nBmcTasSkippedBudget;
|
||||||
|
ABC_INT64_T nBmcTasStructWork;
|
||||||
|
abctime tBmcCbs;
|
||||||
|
abctime tBmcTas;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// FUNCTION DEFINITIONS ///
|
/// FUNCTION DEFINITIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Active-pair selection mirrors incremental mode: a pair is active iff an endpoint is
|
// Active-pair selection mirrors -i exactly: a pair is active iff an endpoint is
|
||||||
// in the alias-aware TFO (or, in ring mode, the ring edge itself changed). The
|
// in the alias-aware TFO (or, in ring mode, the ring edge itself changed). The
|
||||||
// earlier "pending" set that force-re-emitted still-merged SAT pairs has been
|
// earlier "pending" set that force-re-emitted still-merged SAT pairs has been
|
||||||
// removed: per md/scorr_i_correctness_bug_report.md the alias-aware TFO is the
|
// removed: per md/scorr_i_correctness_bug_report.md the alias-aware TFO is the
|
||||||
// real fix, and the retry/pending protection was shown to be both unnecessary
|
// real fix, and the retry/pending protection was shown to be both unnecessary
|
||||||
// and incomplete.
|
// (alias-only passes -d) and incomplete. -d (incr-oracle) certifies soundness.
|
||||||
static int Cec_DynSrmActiveConst( Cec_DynSrm_t * p, int * pTfoMark, int ObjId )
|
static int Cec_DynSrmActiveConst( Cec_DynSrm_t * p, int * pTfoMark, int ObjId )
|
||||||
{
|
{
|
||||||
(void)p;
|
(void)p;
|
||||||
|
|
@ -134,6 +204,9 @@ static void Cec_DynSrmResetCore( Cec_DynSrm_t * p )
|
||||||
if ( p->pCbs ) // stop resident solver before its pCore is freed
|
if ( p->pCbs ) // stop resident solver before its pCore is freed
|
||||||
Cbs_ManStop( p->pCbs );
|
Cbs_ManStop( p->pCbs );
|
||||||
p->pCbs = NULL;
|
p->pCbs = NULL;
|
||||||
|
if ( p->pTas )
|
||||||
|
Tas_ManStop( p->pTas );
|
||||||
|
p->pTas = NULL;
|
||||||
if ( p->pCore )
|
if ( p->pCore )
|
||||||
Gia_ManStop( p->pCore );
|
Gia_ManStop( p->pCore );
|
||||||
p->pCore = NULL;
|
p->pCore = NULL;
|
||||||
|
|
@ -143,8 +216,6 @@ static void Cec_DynSrmResetCore( Cec_DynSrm_t * p )
|
||||||
Vec_IntFreeP( &p->vCopyTouched );
|
Vec_IntFreeP( &p->vCopyTouched );
|
||||||
Vec_IntFreeP( &p->vPiMap );
|
Vec_IntFreeP( &p->vPiMap );
|
||||||
Vec_IntFreeP( &p->vRoMap );
|
Vec_IntFreeP( &p->vRoMap );
|
||||||
ABC_FREE( p->pTrueMark );
|
|
||||||
p->nTrueStamp = 0;
|
|
||||||
p->nObjs = p->nPis = p->nRegs = p->nFramesTotal = p->nCoreCiNum = 0;
|
p->nObjs = p->nPis = p->nRegs = p->nFramesTotal = p->nCoreCiNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,30 +224,104 @@ static void Cec_DynSrmResetCore( Cec_DynSrm_t * p )
|
||||||
// solver's per-round sync/solve walks an ever-larger graph. At a quiescent
|
// solver's per-round sync/solve walks an ever-larger graph. At a quiescent
|
||||||
// point (start of a build) cold-rebuild once it exceeds a multiple of its
|
// point (start of a build) cold-rebuild once it exceeds a multiple of its
|
||||||
// post-build size; the rebuilt core re-materializes only the live active cones.
|
// post-build size; the rebuilt core re-materializes only the live active cones.
|
||||||
#define CEC_DYN_COMPACT_MULT 4
|
#define CEC_DYN_COMPACT_MULT 4
|
||||||
|
#define CEC_DYN_ADAPT_BLOAT_PERMIL 3000
|
||||||
|
#define CEC_DYN_ADAPT_WORSE_PERMIL 1500
|
||||||
|
#define CEC_DYN_ADAPT_RESET_BETTER_PERMIL 750
|
||||||
|
#define CEC_DYN_ADAPT_MIN_REUSE_SAMPLES 8
|
||||||
|
#define CEC_DYN_ADAPT_MIN_CALLS 16
|
||||||
|
#define CEC_DYN_ADAPT_MIN_BUILDS_SINCE_RESET 2
|
||||||
|
#define CEC_DYN_ADAPT_FAST_GROW_SPAN 4
|
||||||
|
#define CEC_DYN_ADAPT_BURST_ROUNDS 2
|
||||||
|
#define CEC_DYN_ADAPT_FAST_COMPACT_SPAN 2
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CEC_DYN_RESET_NONE = 0,
|
||||||
|
CEC_DYN_RESET_SHAPE = 1,
|
||||||
|
CEC_DYN_RESET_COMPACT = 2,
|
||||||
|
CEC_DYN_RESET_ADAPT = 3,
|
||||||
|
CEC_DYN_RESET_BURST = 4,
|
||||||
|
CEC_DYN_RESET_IFALLBACK = 5,
|
||||||
|
CEC_DYN_RESET_DACTIVE = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
static int Cec_DynSrmCurrentBloatPermil( Cec_DynSrm_t * p )
|
||||||
|
{
|
||||||
|
if ( p->nCoreObjsAtReset <= 0 || p->pCore == NULL )
|
||||||
|
return 1000;
|
||||||
|
return (int)((ABC_INT64_T)1000 * Gia_ManObjNum(p->pCore) / p->nCoreObjsAtReset);
|
||||||
|
}
|
||||||
|
|
||||||
static int Cec_DynSrmShouldCompact( Cec_DynSrm_t * p )
|
static int Cec_DynSrmShouldCompact( Cec_DynSrm_t * p )
|
||||||
{
|
{
|
||||||
// 64-bit multiply: nCoreObjsAtReset can reach tens of millions (the growth
|
// 64-bit multiply: nCoreObjsAtReset can reach tens of millions (the growth
|
||||||
// case this guards), so CEC_DYN_COMPACT_MULT * it must not overflow int.
|
// case this guards), so nCompactMult * it must not overflow int.
|
||||||
return p->nCoreObjsAtReset > 0 &&
|
return p->nCoreObjsAtReset > 0 &&
|
||||||
Gia_ManObjNum(p->pCore) > (ABC_INT64_T)CEC_DYN_COMPACT_MULT * p->nCoreObjsAtReset;
|
Gia_ManObjNum(p->pCore) > (ABC_INT64_T)p->nCompactMult * p->nCoreObjsAtReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Cec_DynSrmShouldAdaptiveReset( Cec_DynSrm_t * p )
|
||||||
|
{
|
||||||
|
int nBloat;
|
||||||
|
if ( !p->fUseAdaptive )
|
||||||
|
return CEC_DYN_RESET_NONE;
|
||||||
|
if ( p->nAdaptiveBurstLeft > 0 )
|
||||||
|
{
|
||||||
|
p->nAdaptiveBurstLeft--;
|
||||||
|
p->nAdaptiveBurstResets++;
|
||||||
|
return CEC_DYN_RESET_BURST;
|
||||||
|
}
|
||||||
|
if ( p->nBuildsSinceReset < CEC_DYN_ADAPT_MIN_BUILDS_SINCE_RESET )
|
||||||
|
return CEC_DYN_RESET_NONE;
|
||||||
|
if ( p->nBuildsSinceReset > CEC_DYN_ADAPT_FAST_GROW_SPAN )
|
||||||
|
return CEC_DYN_RESET_NONE;
|
||||||
|
if ( p->nAdaptResetSamples == 0 || p->nAdaptReuseSamples < CEC_DYN_ADAPT_MIN_REUSE_SAMPLES )
|
||||||
|
return CEC_DYN_RESET_NONE;
|
||||||
|
nBloat = Cec_DynSrmCurrentBloatPermil( p );
|
||||||
|
if ( nBloat < CEC_DYN_ADAPT_BLOAT_PERMIL )
|
||||||
|
return CEC_DYN_RESET_NONE;
|
||||||
|
if ( 1000.0 * p->dAdaptReuseCost > (double)CEC_DYN_ADAPT_WORSE_PERMIL * p->dAdaptResetCost )
|
||||||
|
return CEC_DYN_RESET_ADAPT;
|
||||||
|
return CEC_DYN_RESET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Cec_DynSrmEnsureCore( Cec_DynSrm_t * p, int nFrames, int fScorr )
|
static void Cec_DynSrmEnsureCore( Cec_DynSrm_t * p, int nFrames, int fScorr )
|
||||||
{
|
{
|
||||||
Gia_Obj_t * pObj;
|
Gia_Obj_t * pObj;
|
||||||
int f, i, nFramesTotal = nFrames + fScorr;
|
int f, i, nFramesTotal = nFrames + fScorr;
|
||||||
|
int ResetReason = CEC_DYN_RESET_NONE;
|
||||||
int fSameShape = ( p->pCore != NULL &&
|
int fSameShape = ( p->pCore != NULL &&
|
||||||
p->nObjs == Gia_ManObjNum(p->pAig) &&
|
p->nObjs == Gia_ManObjNum(p->pAig) &&
|
||||||
p->nPis == Gia_ManPiNum(p->pAig) &&
|
p->nPis == Gia_ManPiNum(p->pAig) &&
|
||||||
p->nRegs == Gia_ManRegNum(p->pAig) &&
|
p->nRegs == Gia_ManRegNum(p->pAig) &&
|
||||||
p->nFramesTotal == nFramesTotal );
|
p->nFramesTotal == nFramesTotal );
|
||||||
if ( fSameShape && !Cec_DynSrmShouldCompact(p) )
|
p->nLastBuildReset = 0;
|
||||||
|
p->nLastResetReason = CEC_DYN_RESET_NONE;
|
||||||
|
if ( !fSameShape )
|
||||||
|
ResetReason = CEC_DYN_RESET_SHAPE;
|
||||||
|
else if ( p->fForceRebuild )
|
||||||
|
ResetReason = p->nForceResetReason;
|
||||||
|
else if ( Cec_DynSrmShouldCompact(p) )
|
||||||
|
ResetReason = CEC_DYN_RESET_COMPACT;
|
||||||
|
else
|
||||||
|
ResetReason = Cec_DynSrmShouldAdaptiveReset( p );
|
||||||
|
if ( fSameShape && ResetReason == CEC_DYN_RESET_NONE )
|
||||||
return;
|
return;
|
||||||
if ( fSameShape ) // reusable shape but bloated: cold-rebuild
|
p->fForceRebuild = 0;
|
||||||
|
p->nForceResetReason = CEC_DYN_RESET_NONE;
|
||||||
|
if ( ResetReason == CEC_DYN_RESET_COMPACT ) // reusable shape but bloated: cold-rebuild
|
||||||
p->nCoreCompactions++;
|
p->nCoreCompactions++;
|
||||||
|
if ( ResetReason == CEC_DYN_RESET_IFALLBACK )
|
||||||
|
p->nIncrFallbackResets++;
|
||||||
|
if ( ResetReason == CEC_DYN_RESET_DACTIVE )
|
||||||
|
p->nDynActiveResets++;
|
||||||
|
if ( ResetReason == CEC_DYN_RESET_ADAPT )
|
||||||
|
p->nAdaptiveResets++;
|
||||||
|
p->nLastResetSpan = p->nBuildsSinceReset;
|
||||||
Cec_DynSrmResetCore( p );
|
Cec_DynSrmResetCore( p );
|
||||||
|
p->nLastBuildReset = 1;
|
||||||
|
p->nLastResetReason = ResetReason;
|
||||||
|
p->nBuildsSinceReset = 0;
|
||||||
p->nObjs = Gia_ManObjNum( p->pAig );
|
p->nObjs = Gia_ManObjNum( p->pAig );
|
||||||
p->nPis = Gia_ManPiNum( p->pAig );
|
p->nPis = Gia_ManPiNum( p->pAig );
|
||||||
p->nRegs = Gia_ManRegNum( p->pAig );
|
p->nRegs = Gia_ManRegNum( p->pAig );
|
||||||
|
|
@ -186,8 +331,6 @@ static void Cec_DynSrmEnsureCore( Cec_DynSrm_t * p, int nFrames, int fScorr )
|
||||||
p->vCopyTouched = Vec_IntAlloc( 1000 );
|
p->vCopyTouched = Vec_IntAlloc( 1000 );
|
||||||
p->vPiMap = Vec_IntStartFull( p->nObjs );
|
p->vPiMap = Vec_IntStartFull( p->nObjs );
|
||||||
p->vRoMap = Vec_IntStartFull( p->nObjs );
|
p->vRoMap = Vec_IntStartFull( p->nObjs );
|
||||||
p->pTrueMark = ABC_CALLOC( int, p->nFramesTotal * p->nObjs );
|
|
||||||
p->nTrueStamp = 0;
|
|
||||||
p->pCore = Gia_ManStart( Abc_MaxInt( p->nFramesTotal * p->nObjs, 1000 ) );
|
p->pCore = Gia_ManStart( Abc_MaxInt( p->nFramesTotal * p->nObjs, 1000 ) );
|
||||||
p->pCore->pName = Abc_UtilStrsav( p->pAig->pName );
|
p->pCore->pName = Abc_UtilStrsav( p->pAig->pName );
|
||||||
p->pCore->pSpec = Abc_UtilStrsav( p->pAig->pSpec );
|
p->pCore->pSpec = Abc_UtilStrsav( p->pAig->pSpec );
|
||||||
|
|
@ -411,14 +554,77 @@ static Gia_Man_t * Cec_DynSrmBuildView( Cec_DynSrm_t * p )
|
||||||
return pView;
|
return pView;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cec_DynSrm_t * Cec_DynSrmAlloc( Gia_Man_t * pAig, Cec_IncrMgr_t * pIncr )
|
static void Cec_DynSrmRecordBuildStats( Cec_DynSrm_t * p,
|
||||||
|
Cec_IncrEmitMode_t Mode, int nCoreObjsBefore, int nCoreResetsBefore,
|
||||||
|
abctime tBuild, abctime tEnsure, abctime tInvalidate, abctime tEmit )
|
||||||
|
{
|
||||||
|
int fReset = p->nCoreResets > nCoreResetsBefore;
|
||||||
|
p->nBuildsSinceReset++;
|
||||||
|
if ( Mode == CEC_EMIT_ACTIVE )
|
||||||
|
{
|
||||||
|
p->nOutLitsActiveSum += p->nOutLitsLast;
|
||||||
|
p->nCoreObjsActiveSum += p->nCoreObjsLast;
|
||||||
|
}
|
||||||
|
else if ( Mode == CEC_EMIT_ALL )
|
||||||
|
{
|
||||||
|
p->nBuildsFull++;
|
||||||
|
p->nOutLitsFullSum += p->nOutLitsLast;
|
||||||
|
p->nCoreObjsFullSum += p->nCoreObjsLast;
|
||||||
|
}
|
||||||
|
p->nCoreDeltaLast = Abc_MaxInt( 0, p->nCoreObjsLast - nCoreObjsBefore );
|
||||||
|
p->nCoreDeltaMax = Abc_MaxInt( p->nCoreDeltaMax, p->nCoreDeltaLast );
|
||||||
|
if ( p->nCoreObjsAtReset > 0 )
|
||||||
|
{
|
||||||
|
p->nCoreBloatLastPermil =
|
||||||
|
(int)((ABC_INT64_T)1000 * p->nCoreObjsLast / p->nCoreObjsAtReset);
|
||||||
|
p->nCoreBloatMaxPermil =
|
||||||
|
Abc_MaxInt( p->nCoreBloatMaxPermil, p->nCoreBloatLastPermil );
|
||||||
|
}
|
||||||
|
if ( tBuild )
|
||||||
|
{
|
||||||
|
p->tBuildLast = tBuild;
|
||||||
|
p->tBuildEnsureLast = tEnsure;
|
||||||
|
p->tBuildInvalidateLast = tInvalidate;
|
||||||
|
p->tBuildEmitLast = tEmit;
|
||||||
|
p->tBuildTotal += tBuild;
|
||||||
|
if ( fReset )
|
||||||
|
p->tBuildResetTotal += tBuild;
|
||||||
|
else
|
||||||
|
p->tBuildReuseTotal += tBuild;
|
||||||
|
p->tBuildEnsureTotal += tEnsure;
|
||||||
|
p->tBuildInvalidateTotal += tInvalidate;
|
||||||
|
p->tBuildEmitTotal += tEmit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cec_DynSrm_t * Cec_DynSrmAlloc( Gia_Man_t * pAig, Cec_IncrMgr_t * pIncr, int fUseAdaptive )
|
||||||
{
|
{
|
||||||
Cec_DynSrm_t * p = ABC_CALLOC( Cec_DynSrm_t, 1 );
|
Cec_DynSrm_t * p = ABC_CALLOC( Cec_DynSrm_t, 1 );
|
||||||
p->pAig = pAig;
|
p->pAig = pAig;
|
||||||
p->pIncr = pIncr;
|
p->pIncr = pIncr;
|
||||||
|
p->fUseAdaptive = fUseAdaptive;
|
||||||
|
p->nCompactMult = CEC_DYN_COMPACT_MULT;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cec_DynSrmSetParams( Cec_DynSrm_t * p, Cec_ParCor_t * pPars )
|
||||||
|
{
|
||||||
|
if ( p == NULL || pPars == NULL )
|
||||||
|
return;
|
||||||
|
p->nCompactMult = Abc_MaxInt( 1, pPars->nDynSrmCompactMult );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cec_DynSrmForceRebuild( Cec_DynSrm_t * p, int fIncrFallback )
|
||||||
|
{
|
||||||
|
if ( p == NULL )
|
||||||
|
return;
|
||||||
|
p->fForceRebuild = 1;
|
||||||
|
if ( fIncrFallback )
|
||||||
|
p->nForceResetReason = CEC_DYN_RESET_IFALLBACK;
|
||||||
|
else if ( p->nForceResetReason != CEC_DYN_RESET_IFALLBACK )
|
||||||
|
p->nForceResetReason = CEC_DYN_RESET_DACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
void Cec_DynSrmFree( Cec_DynSrm_t * p )
|
void Cec_DynSrmFree( Cec_DynSrm_t * p )
|
||||||
{
|
{
|
||||||
if ( p == NULL )
|
if ( p == NULL )
|
||||||
|
|
@ -427,19 +633,57 @@ void Cec_DynSrmFree( Cec_DynSrm_t * p )
|
||||||
ABC_FREE( p );
|
ABC_FREE( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cec_DynSrmPrintStats( Cec_DynSrm_t * p )
|
static void Cec_DynSrmUpdateAdaptCost( double * pCost, int * pSamples, double Value )
|
||||||
{
|
{
|
||||||
|
if ( *pSamples == 0 )
|
||||||
|
*pCost = Value;
|
||||||
|
else
|
||||||
|
*pCost = 0.75 * *pCost + 0.25 * Value;
|
||||||
|
(*pSamples)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cec_DynSrmRecordSolveStats( Cec_DynSrm_t * p,
|
||||||
|
int nCalls, int nReal, int nTriv, int nFail, abctime tSat )
|
||||||
|
{
|
||||||
|
int nDen;
|
||||||
|
double dCost;
|
||||||
if ( p == NULL )
|
if ( p == NULL )
|
||||||
return;
|
return;
|
||||||
Abc_Print( 1, "DynSRM: builds = %d, active_builds = %d\n",
|
p->nSolveIters++;
|
||||||
p->nBuilds, p->nBuildsActive );
|
p->nSolveCalls += nCalls;
|
||||||
Abc_Print( 1, "DynSRM: core_resets = %d, compactions = %d, core_builds = %d, view_builds = %d, out_lits_last/max = %d/%d, core_objs_last/max = %d/%d, view_objs_last/max = %d/%d\n",
|
p->nSolveReal += nReal;
|
||||||
p->nCoreResets, p->nCoreCompactions, p->nCoreBuilds, p->nViewBuilds,
|
p->nSolveTriv += nTriv;
|
||||||
p->nOutLitsLast, p->nOutLitsMax,
|
p->nSolveFail += nFail;
|
||||||
p->nCoreObjsLast, p->nCoreObjsMax,
|
if ( nFail > 0 )
|
||||||
p->nViewObjsLast, p->nViewObjsMax );
|
{
|
||||||
Abc_Print( 1, "DynSRM: cache_full_clears = %d, cache_local_clears = %d, cache_local_entries = %d\n",
|
p->nSolveFailIters++;
|
||||||
p->nCacheFullClears, p->nCacheLocalClears, p->nCacheLocalEntries );
|
p->nFailCoreObjSum += (ABC_INT64_T)nFail * p->nCoreObjsLast;
|
||||||
|
p->nFailOutLitSum += (ABC_INT64_T)nFail * p->nOutLitsLast;
|
||||||
|
p->nFailCoreObjMax = Abc_MaxInt( p->nFailCoreObjMax, p->nCoreObjsLast );
|
||||||
|
p->nFailOutLitMax = Abc_MaxInt( p->nFailOutLitMax, p->nOutLitsLast );
|
||||||
|
}
|
||||||
|
p->tSolveLast = tSat;
|
||||||
|
if ( !p->fUseAdaptive || p->tBuildLast == 0 )
|
||||||
|
return;
|
||||||
|
nDen = nCalls > 0 ? nCalls : p->nOutLitsLast;
|
||||||
|
if ( nDen < CEC_DYN_ADAPT_MIN_CALLS )
|
||||||
|
return;
|
||||||
|
dCost = (double)(p->tBuildLast + tSat) / (double)nDen;
|
||||||
|
p->dAdaptLastCost = dCost;
|
||||||
|
if ( p->nLastBuildReset )
|
||||||
|
{
|
||||||
|
if ( p->nLastResetReason != CEC_DYN_RESET_SHAPE )
|
||||||
|
{
|
||||||
|
Cec_DynSrmUpdateAdaptCost( &p->dAdaptResetCost, &p->nAdaptResetSamples, dCost );
|
||||||
|
if ( p->nAdaptReuseSamples >= CEC_DYN_ADAPT_MIN_REUSE_SAMPLES &&
|
||||||
|
p->nLastResetReason == CEC_DYN_RESET_COMPACT &&
|
||||||
|
p->nLastResetSpan <= CEC_DYN_ADAPT_FAST_COMPACT_SPAN &&
|
||||||
|
1000.0 * dCost < (double)CEC_DYN_ADAPT_RESET_BETTER_PERMIL * p->dAdaptReuseCost )
|
||||||
|
p->nAdaptiveBurstLeft = CEC_DYN_ADAPT_BURST_ROUNDS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Cec_DynSrmUpdateAdaptCost( &p->dAdaptReuseCost, &p->nAdaptReuseSamples, dCost );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cec_DynSrmCountActivePairs( Cec_DynSrm_t * p, int fRings, int * pTfoMark,
|
void Cec_DynSrmCountActivePairs( Cec_DynSrm_t * p, int fRings, int * pTfoMark,
|
||||||
|
|
@ -493,12 +737,16 @@ void Cec_DynSrmCountActivePairs( Cec_DynSrm_t * p, int fRings, int * pTfoMark,
|
||||||
|
|
||||||
// Builds (or extends) the persistent COless pCore and selects this round's
|
// Builds (or extends) the persistent COless pCore and selects this round's
|
||||||
// active-pair root literals into p->vOutLits / *pvOutputs. Shared by the view
|
// active-pair root literals into p->vOutLits / *pvOutputs. Shared by the view
|
||||||
// path (Cec_DynSrmBuild) and the persistent path (solve pCore directly).
|
// path (Cec_DynSrmBuild) and the -D persistence path (solve pCore directly).
|
||||||
void Cec_DynSrmBuildCore( Cec_DynSrm_t * p, int nFrames, int fScorr,
|
void Cec_DynSrmBuildCore( Cec_DynSrm_t * p, int nFrames, int fScorr,
|
||||||
Vec_Int_t ** pvOutputs, int fRings, int * pTfoMask, Cec_IncrEmitMode_t Mode )
|
Vec_Int_t ** pvOutputs, int fRings, int * pTfoMask, Cec_IncrEmitMode_t Mode )
|
||||||
{
|
{
|
||||||
Gia_Obj_t * pObj, * pRepr;
|
Gia_Obj_t * pObj, * pRepr;
|
||||||
int i, iPrev, iObj, iPrevNew, iObjNew, iPrevRaw, iObjRaw;
|
int i, iPrev, iObj, iPrevNew, iObjNew, iPrevRaw, iObjRaw;
|
||||||
|
int nCoreResetsBefore, nCoreObjsBefore;
|
||||||
|
int fMeasure = p->fUseAdaptive;
|
||||||
|
abctime tBuild = fMeasure ? Abc_ClockHr() : 0;
|
||||||
|
abctime tStep, tEnsure = 0, tInvalidate = 0, tEmit = 0;
|
||||||
assert( p != NULL );
|
assert( p != NULL );
|
||||||
assert( nFrames > 0 );
|
assert( nFrames > 0 );
|
||||||
assert( Gia_ManRegNum(p->pAig) > 0 );
|
assert( Gia_ManRegNum(p->pAig) > 0 );
|
||||||
|
|
@ -507,8 +755,15 @@ void Cec_DynSrmBuildCore( Cec_DynSrm_t * p, int nFrames, int fScorr,
|
||||||
p->nBuilds++;
|
p->nBuilds++;
|
||||||
if ( Mode == CEC_EMIT_ACTIVE )
|
if ( Mode == CEC_EMIT_ACTIVE )
|
||||||
p->nBuildsActive++;
|
p->nBuildsActive++;
|
||||||
|
nCoreResetsBefore = p->nCoreResets;
|
||||||
|
tStep = fMeasure ? Abc_ClockHr() : 0;
|
||||||
Cec_DynSrmEnsureCore( p, nFrames, fScorr );
|
Cec_DynSrmEnsureCore( p, nFrames, fScorr );
|
||||||
|
if ( fMeasure ) tEnsure = Abc_ClockHr() - tStep;
|
||||||
|
nCoreObjsBefore = Gia_ManObjNum( p->pCore );
|
||||||
|
tStep = fMeasure ? Abc_ClockHr() : 0;
|
||||||
Cec_DynSrmInvalidateCache( p, Mode == CEC_EMIT_SKIPPED ? NULL : pTfoMask );
|
Cec_DynSrmInvalidateCache( p, Mode == CEC_EMIT_SKIPPED ? NULL : pTfoMask );
|
||||||
|
if ( fMeasure ) tInvalidate = Abc_ClockHr() - tStep;
|
||||||
|
tStep = fMeasure ? Abc_ClockHr() : 0;
|
||||||
Gia_ManSetPhase( p->pAig );
|
Gia_ManSetPhase( p->pAig );
|
||||||
*pvOutputs = Vec_IntAlloc( 1000 );
|
*pvOutputs = Vec_IntAlloc( 1000 );
|
||||||
Vec_IntClear( p->vOutLits );
|
Vec_IntClear( p->vOutLits );
|
||||||
|
|
@ -603,6 +858,10 @@ void Cec_DynSrmBuildCore( Cec_DynSrm_t * p, int nFrames, int fScorr,
|
||||||
if ( p->nCoreObjsAtReset == 0 ) // first build after a cold (re)set: record the
|
if ( p->nCoreObjsAtReset == 0 ) // first build after a cold (re)set: record the
|
||||||
p->nCoreObjsAtReset = p->nCoreObjsLast; // real post-build size as the compaction baseline
|
p->nCoreObjsAtReset = p->nCoreObjsLast; // real post-build size as the compaction baseline
|
||||||
p->nCoreObjsMax = Abc_MaxInt( p->nCoreObjsMax, p->nCoreObjsLast );
|
p->nCoreObjsMax = Abc_MaxInt( p->nCoreObjsMax, p->nCoreObjsLast );
|
||||||
|
if ( fMeasure ) tEmit = Abc_ClockHr() - tStep;
|
||||||
|
if ( fMeasure ) tBuild = Abc_ClockHr() - tBuild;
|
||||||
|
Cec_DynSrmRecordBuildStats( p, Mode, nCoreObjsBefore, nCoreResetsBefore,
|
||||||
|
tBuild, tEnsure, tInvalidate, tEmit );
|
||||||
}
|
}
|
||||||
|
|
||||||
Gia_Man_t * Cec_DynSrmBuild( Cec_DynSrm_t * p, int nFrames, int fScorr,
|
Gia_Man_t * Cec_DynSrmBuild( Cec_DynSrm_t * p, int nFrames, int fScorr,
|
||||||
|
|
@ -621,6 +880,10 @@ void Cec_DynSrmBuildCoreInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fS
|
||||||
{
|
{
|
||||||
Gia_Obj_t * pObj, * pRepr;
|
Gia_Obj_t * pObj, * pRepr;
|
||||||
int f, i, iPrevNew, iObjNew;
|
int f, i, iPrevNew, iObjNew;
|
||||||
|
int nCoreResetsBefore, nCoreObjsBefore;
|
||||||
|
int fMeasure = p->fUseAdaptive;
|
||||||
|
abctime tBuild = fMeasure ? Abc_ClockHr() : 0;
|
||||||
|
abctime tStep, tEnsure = 0, tInvalidate = 0, tEmit = 0;
|
||||||
assert( p != NULL );
|
assert( p != NULL );
|
||||||
assert( (!fScorr && nFrames > 1) || (fScorr && nFrames > 0) || nPrefix );
|
assert( (!fScorr && nFrames > 1) || (fScorr && nFrames > 0) || nPrefix );
|
||||||
assert( Gia_ManRegNum(p->pAig) > 0 );
|
assert( Gia_ManRegNum(p->pAig) > 0 );
|
||||||
|
|
@ -629,8 +892,15 @@ void Cec_DynSrmBuildCoreInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fS
|
||||||
p->nBuilds++;
|
p->nBuilds++;
|
||||||
if ( Mode == CEC_EMIT_ACTIVE )
|
if ( Mode == CEC_EMIT_ACTIVE )
|
||||||
p->nBuildsActive++;
|
p->nBuildsActive++;
|
||||||
|
nCoreResetsBefore = p->nCoreResets;
|
||||||
|
tStep = fMeasure ? Abc_ClockHr() : 0;
|
||||||
Cec_DynSrmEnsureCore( p, nFrames + nPrefix, fScorr );
|
Cec_DynSrmEnsureCore( p, nFrames + nPrefix, fScorr );
|
||||||
|
if ( fMeasure ) tEnsure = Abc_ClockHr() - tStep;
|
||||||
|
nCoreObjsBefore = Gia_ManObjNum( p->pCore );
|
||||||
|
tStep = fMeasure ? Abc_ClockHr() : 0;
|
||||||
Cec_DynSrmInvalidateCache( p, Mode == CEC_EMIT_SKIPPED ? NULL : pTfoMask );
|
Cec_DynSrmInvalidateCache( p, Mode == CEC_EMIT_SKIPPED ? NULL : pTfoMask );
|
||||||
|
if ( fMeasure ) tInvalidate = Abc_ClockHr() - tStep;
|
||||||
|
tStep = fMeasure ? Abc_ClockHr() : 0;
|
||||||
Gia_ManSetPhase( p->pAig );
|
Gia_ManSetPhase( p->pAig );
|
||||||
*pvOutputs = Vec_IntAlloc( 1000 );
|
*pvOutputs = Vec_IntAlloc( 1000 );
|
||||||
Vec_IntClear( p->vOutLits );
|
Vec_IntClear( p->vOutLits );
|
||||||
|
|
@ -665,6 +935,13 @@ void Cec_DynSrmBuildCoreInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fS
|
||||||
if ( p->nCoreObjsAtReset == 0 )
|
if ( p->nCoreObjsAtReset == 0 )
|
||||||
p->nCoreObjsAtReset = p->nCoreObjsLast;
|
p->nCoreObjsAtReset = p->nCoreObjsLast;
|
||||||
p->nCoreObjsMax = Abc_MaxInt( p->nCoreObjsMax, p->nCoreObjsLast );
|
p->nCoreObjsMax = Abc_MaxInt( p->nCoreObjsMax, p->nCoreObjsLast );
|
||||||
|
if ( fMeasure )
|
||||||
|
{
|
||||||
|
tEmit = Abc_ClockHr() - tStep;
|
||||||
|
tBuild = Abc_ClockHr() - tBuild;
|
||||||
|
}
|
||||||
|
Cec_DynSrmRecordBuildStats( p, Mode, nCoreObjsBefore, nCoreResetsBefore,
|
||||||
|
tBuild, tEnsure, tInvalidate, tEmit );
|
||||||
}
|
}
|
||||||
|
|
||||||
Gia_Man_t * Cec_DynSrmBuildInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fScorr,
|
Gia_Man_t * Cec_DynSrmBuildInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fScorr,
|
||||||
|
|
@ -681,16 +958,254 @@ Vec_Int_t * Cec_DynSrmOutLits( Cec_DynSrm_t * p ) { return p->vOutLits; }
|
||||||
// circuit-SAT manager (allocated lazily; re-created after a core reset/compaction
|
// circuit-SAT manager (allocated lazily; re-created after a core reset/compaction
|
||||||
// since its pAig is freed there). The CI-layout assert guards the CEX CioId ->
|
// since its pAig is freed there). The CI-layout assert guards the CEX CioId ->
|
||||||
// resim-input contract that the discarded view used to enforce in the main loop.
|
// resim-input contract that the discarded view used to enforce in the main loop.
|
||||||
Vec_Int_t * Cec_DynSrmSolve( Cec_DynSrm_t * p, int nConfs, Vec_Str_t ** pvStatus )
|
Vec_Int_t * Cec_DynSrmSolve( Cec_DynSrm_t * p, int nConfs, Vec_Str_t ** pvStatus, int fUseTas )
|
||||||
{
|
{
|
||||||
assert( Gia_ManRegNum(p->pCore) == 0 );
|
assert( Gia_ManRegNum(p->pCore) == 0 );
|
||||||
assert( Gia_ManCiNum(p->pCore) == p->nRegs + p->nFramesTotal * p->nPis );
|
assert( Gia_ManCiNum(p->pCore) == p->nRegs + p->nFramesTotal * p->nPis );
|
||||||
|
if ( fUseTas )
|
||||||
|
{
|
||||||
|
if ( p->pTas == NULL )
|
||||||
|
p->pTas = Tas_ManAlloc( p->pCore, nConfs );
|
||||||
|
Tas_ManSetConflictNum( p->pTas, nConfs );
|
||||||
|
return Tas_ManSolveRoots( p->pTas, p->vOutLits, pvStatus, 0 );
|
||||||
|
}
|
||||||
if ( p->pCbs == NULL )
|
if ( p->pCbs == NULL )
|
||||||
p->pCbs = Cbs_ManAlloc( p->pCore );
|
p->pCbs = Cbs_ManAlloc( p->pCore );
|
||||||
Cbs_ManSetConflictNum( p->pCbs, nConfs );
|
Cbs_ManSetConflictNum( p->pCbs, nConfs );
|
||||||
return Cbs_ManSolveRoots( p->pCbs, p->vOutLits, pvStatus, 0 );
|
return Cbs_ManSolveRoots( p->pCbs, p->vOutLits, pvStatus, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Cec_DynSrmStoreCopyEntry( Vec_Int_t * vDest, Vec_Int_t * vSrc, int iStart, int iOut )
|
||||||
|
{
|
||||||
|
int k, nLits = Vec_IntEntry( vSrc, iStart + 1 );
|
||||||
|
Vec_IntPush( vDest, iOut );
|
||||||
|
Vec_IntPush( vDest, nLits );
|
||||||
|
for ( k = 0; k < nLits; k++ )
|
||||||
|
Vec_IntPush( vDest, Vec_IntEntry(vSrc, iStart + 2 + k) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static Vec_Int_t * Cec_DynSrmStoreIndex( Vec_Int_t * vStore, int nRoots )
|
||||||
|
{
|
||||||
|
Vec_Int_t * vStarts = Vec_IntStartFull( nRoots );
|
||||||
|
int iStart = 0, iOut, nLits;
|
||||||
|
while ( iStart < Vec_IntSize(vStore) )
|
||||||
|
{
|
||||||
|
iOut = Vec_IntEntry( vStore, iStart );
|
||||||
|
nLits = Vec_IntEntry( vStore, iStart + 1 );
|
||||||
|
assert( iOut >= 0 && iOut < nRoots );
|
||||||
|
assert( nLits >= -1 );
|
||||||
|
Vec_IntWriteEntry( vStarts, iOut, iStart );
|
||||||
|
iStart += 2 + Abc_MaxInt( nLits, 0 );
|
||||||
|
}
|
||||||
|
assert( iStart == Vec_IntSize(vStore) );
|
||||||
|
return vStarts;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs TAS on a subset of roots and merges its local output indices into the
|
||||||
|
// original CBS status/store namespace. Returns the number of SAT/UNSAT roots.
|
||||||
|
static int Cec_DynSrmTasRetryBatch( Cec_DynSrm_t * p, int nConfs,
|
||||||
|
Vec_Int_t * vRoots, Vec_Int_t * vRootToOrig, Vec_Str_t * vFinalStatus,
|
||||||
|
Vec_Int_t * vTasStore, Vec_Int_t * vTasStarts )
|
||||||
|
{
|
||||||
|
Vec_Str_t * vStatus = NULL;
|
||||||
|
Vec_Int_t * vStore;
|
||||||
|
abctime clk = Abc_ClockHr();
|
||||||
|
int i, iStart = 0, iLocal, iOrig, nLits, Status, nResolved = 0;
|
||||||
|
assert( Vec_IntSize(vRoots) == Vec_IntSize(vRootToOrig) );
|
||||||
|
if ( p->pTas == NULL )
|
||||||
|
p->pTas = Tas_ManAlloc( p->pCore, nConfs );
|
||||||
|
Tas_ManSetConflictNum( p->pTas, nConfs );
|
||||||
|
vStore = Tas_ManSolveRoots( p->pTas, vRoots, &vStatus, 0 );
|
||||||
|
p->tBmcTas += Abc_ClockHr() - clk;
|
||||||
|
Vec_StrForEachEntry( vStatus, Status, i )
|
||||||
|
{
|
||||||
|
iOrig = Vec_IntEntry( vRootToOrig, i );
|
||||||
|
if ( Status != -1 )
|
||||||
|
{
|
||||||
|
Vec_StrWriteEntry( vFinalStatus, iOrig, (char)Status );
|
||||||
|
nResolved++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( iStart < Vec_IntSize(vStore) )
|
||||||
|
{
|
||||||
|
iLocal = Vec_IntEntry( vStore, iStart );
|
||||||
|
nLits = Vec_IntEntry( vStore, iStart + 1 );
|
||||||
|
assert( iLocal >= 0 && iLocal < Vec_IntSize(vRootToOrig) );
|
||||||
|
iOrig = Vec_IntEntry( vRootToOrig, iLocal );
|
||||||
|
Vec_IntWriteEntry( vTasStarts, iOrig, Vec_IntSize(vTasStore) );
|
||||||
|
Cec_DynSrmStoreCopyEntry( vTasStore, vStore, iStart, iOrig );
|
||||||
|
iStart += 2 + Abc_MaxInt( nLits, 0 );
|
||||||
|
}
|
||||||
|
assert( iStart == Vec_IntSize(vStore) );
|
||||||
|
Vec_IntFree( vStore );
|
||||||
|
Vec_StrFree( vStatus );
|
||||||
|
return nResolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [CBS-first BMC solving with guarded TAS rescue.]
|
||||||
|
|
||||||
|
Description [Forced -T remains TAS-only. The default path solves every
|
||||||
|
root with CBS, then considers only CBS UNKNOWN roots. Large cores are
|
||||||
|
rejected using both absolute and frame-normalized size. Otherwise TAS is
|
||||||
|
sampled on eight roots; only a 75% successful probe enables retrying the
|
||||||
|
remainder. A deterministic node-root work budget and a retry-root cap bound
|
||||||
|
TAS use without consulting machine-dependent wall time. The final status/CEX
|
||||||
|
arrays preserve original root indices.]
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
Vec_Int_t * Cec_DynSrmSolveBmcAdaptive( Cec_DynSrm_t * p, int nConfs,
|
||||||
|
Vec_Str_t ** pvStatus, int fUseTas )
|
||||||
|
{
|
||||||
|
Vec_Str_t * vStatus = NULL;
|
||||||
|
Vec_Int_t * vCbsStore, * vCbsStarts, * vUnknown;
|
||||||
|
Vec_Int_t * vProbeRoots, * vProbeMap, * vRetryRoots, * vRetryMap;
|
||||||
|
Vec_Int_t * vTasStore, * vTasStarts, * vFinalStore;
|
||||||
|
abctime clk;
|
||||||
|
int i, Status, nRoots = Vec_IntSize(p->vOutLits), nProbe, nProbeResolved;
|
||||||
|
int nFrames = Abc_MaxInt( 1, p->nFramesTotal );
|
||||||
|
int nCore = Gia_ManObjNum( p->pCore );
|
||||||
|
int nCoreNorm = (nCore + nFrames - 1) / nFrames;
|
||||||
|
int fCoreEligible;
|
||||||
|
|
||||||
|
if ( fUseTas )
|
||||||
|
return Cec_DynSrmSolve( p, nConfs, pvStatus, 1 );
|
||||||
|
p->nBmcAdaptiveRounds++;
|
||||||
|
p->nBmcCbsRoots += nRoots;
|
||||||
|
clk = Abc_ClockHr();
|
||||||
|
vCbsStore = Cec_DynSrmSolve( p, nConfs, &vStatus, 0 );
|
||||||
|
p->tBmcCbs += Abc_ClockHr() - clk;
|
||||||
|
vUnknown = Vec_IntAlloc( 64 );
|
||||||
|
Vec_StrForEachEntry( vStatus, Status, i )
|
||||||
|
if ( Status == -1 )
|
||||||
|
Vec_IntPush( vUnknown, i );
|
||||||
|
p->nBmcCbsUnknown += Vec_IntSize(vUnknown);
|
||||||
|
if ( Vec_IntSize(vUnknown) == 0 )
|
||||||
|
{
|
||||||
|
Vec_IntFree( vUnknown );
|
||||||
|
*pvStatus = vStatus;
|
||||||
|
return vCbsStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
fCoreEligible = nCore <= CEC_BMC_TAS_CORE_ABS_MAX &&
|
||||||
|
nCoreNorm <= CEC_BMC_TAS_CORE_NORM_MAX;
|
||||||
|
if ( !fCoreEligible )
|
||||||
|
{
|
||||||
|
p->nBmcTasSkippedLarge += Vec_IntSize(vUnknown);
|
||||||
|
Vec_IntFree( vUnknown );
|
||||||
|
*pvStatus = vStatus;
|
||||||
|
return vCbsStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
vCbsStarts = Cec_DynSrmStoreIndex( vCbsStore, nRoots );
|
||||||
|
vTasStore = Vec_IntAlloc( 64 );
|
||||||
|
vTasStarts = Vec_IntStartFull( nRoots );
|
||||||
|
nProbe = Abc_MinInt( CEC_BMC_TAS_PROBE_ROOTS, Vec_IntSize(vUnknown) );
|
||||||
|
if ( p->nBmcTasStructWork + (ABC_INT64_T)nCoreNorm * nProbe >
|
||||||
|
CEC_BMC_TAS_STRUCT_WORK_MAX )
|
||||||
|
{
|
||||||
|
p->nBmcTasSkippedWork += Vec_IntSize(vUnknown);
|
||||||
|
Vec_IntFree( vCbsStarts );
|
||||||
|
Vec_IntFree( vTasStore );
|
||||||
|
Vec_IntFree( vTasStarts );
|
||||||
|
Vec_IntFree( vUnknown );
|
||||||
|
*pvStatus = vStatus;
|
||||||
|
return vCbsStore;
|
||||||
|
}
|
||||||
|
vProbeRoots = Vec_IntAlloc( nProbe );
|
||||||
|
vProbeMap = Vec_IntAlloc( nProbe );
|
||||||
|
for ( i = 0; i < nProbe; i++ )
|
||||||
|
{
|
||||||
|
int iOrig = Vec_IntEntry( vUnknown, i );
|
||||||
|
Vec_IntPush( vProbeRoots, Vec_IntEntry(p->vOutLits, iOrig) );
|
||||||
|
Vec_IntPush( vProbeMap, iOrig );
|
||||||
|
}
|
||||||
|
p->nBmcTasProbeRoots += nProbe;
|
||||||
|
nProbeResolved = Cec_DynSrmTasRetryBatch( p, nConfs, vProbeRoots, vProbeMap,
|
||||||
|
vStatus, vTasStore, vTasStarts );
|
||||||
|
p->nBmcTasStructWork += (ABC_INT64_T)nCoreNorm * nProbe;
|
||||||
|
p->nBmcTasResolved += nProbeResolved;
|
||||||
|
p->nBmcTasUnknown += nProbe - nProbeResolved;
|
||||||
|
Vec_IntFree( vProbeRoots );
|
||||||
|
Vec_IntFree( vProbeMap );
|
||||||
|
|
||||||
|
if ( nProbeResolved * 100 >= CEC_BMC_TAS_PROBE_SUCCESS_PCT * nProbe &&
|
||||||
|
Vec_IntSize(vUnknown) > nProbe )
|
||||||
|
{
|
||||||
|
int nRetryAvail = Vec_IntSize(vUnknown) - nProbe;
|
||||||
|
int nRetryBudget = CEC_BMC_TAS_RETRY_ROOTS_MAX - (int)p->nBmcTasRetryRoots;
|
||||||
|
ABC_INT64_T nWorkLeft = CEC_BMC_TAS_STRUCT_WORK_MAX - p->nBmcTasStructWork;
|
||||||
|
int nRetryWork = nWorkLeft > 0 ? (int)(nWorkLeft / nCoreNorm) : 0;
|
||||||
|
int nRetry = Abc_MinInt( nRetryAvail,
|
||||||
|
Abc_MinInt( Abc_MaxInt(0, nRetryBudget), Abc_MaxInt(0, nRetryWork) ) );
|
||||||
|
if ( nRetryBudget <= 0 )
|
||||||
|
p->nBmcTasSkippedBudget += nRetryAvail;
|
||||||
|
else if ( nRetryWork <= 0 )
|
||||||
|
p->nBmcTasSkippedWork += nRetryAvail;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vRetryRoots = Vec_IntAlloc( nRetry );
|
||||||
|
vRetryMap = Vec_IntAlloc( nRetry );
|
||||||
|
for ( i = nProbe; i < nProbe + nRetry; i++ )
|
||||||
|
{
|
||||||
|
int iOrig = Vec_IntEntry( vUnknown, i );
|
||||||
|
Vec_IntPush( vRetryRoots, Vec_IntEntry(p->vOutLits, iOrig) );
|
||||||
|
Vec_IntPush( vRetryMap, iOrig );
|
||||||
|
}
|
||||||
|
p->nBmcTasEnabledRounds++;
|
||||||
|
p->nBmcTasRetryRoots += Vec_IntSize(vRetryRoots);
|
||||||
|
i = Cec_DynSrmTasRetryBatch( p, nConfs, vRetryRoots, vRetryMap,
|
||||||
|
vStatus, vTasStore, vTasStarts );
|
||||||
|
p->nBmcTasResolved += i;
|
||||||
|
p->nBmcTasUnknown += Vec_IntSize(vRetryRoots) - i;
|
||||||
|
p->nBmcTasStructWork += (ABC_INT64_T)nCoreNorm * nRetry;
|
||||||
|
if ( nRetry < nRetryAvail )
|
||||||
|
{
|
||||||
|
if ( nRetry == nRetryBudget )
|
||||||
|
p->nBmcTasSkippedBudget += nRetryAvail - nRetry;
|
||||||
|
else
|
||||||
|
p->nBmcTasSkippedWork += nRetryAvail - nRetry;
|
||||||
|
}
|
||||||
|
Vec_IntFree( vRetryRoots );
|
||||||
|
Vec_IntFree( vRetryMap );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild the CEX store once so a TAS answer cleanly replaces the CBS
|
||||||
|
// UNKNOWN entry instead of leaving both records for Gia_ManCheckRefinements.
|
||||||
|
vFinalStore = Vec_IntAlloc( Vec_IntSize(vCbsStore) + Vec_IntSize(vTasStore) );
|
||||||
|
Vec_StrForEachEntry( vStatus, Status, i )
|
||||||
|
{
|
||||||
|
int iStart;
|
||||||
|
if ( Status == 1 )
|
||||||
|
continue;
|
||||||
|
if ( Status == -1 )
|
||||||
|
{
|
||||||
|
Vec_IntPush( vFinalStore, i );
|
||||||
|
Vec_IntPush( vFinalStore, -1 );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
iStart = Vec_IntEntry( vCbsStarts, i );
|
||||||
|
if ( iStart >= 0 && Vec_StrEntry(vStatus, i) == 0 &&
|
||||||
|
Vec_IntEntry(vCbsStore, iStart + 1) >= 0 )
|
||||||
|
Cec_DynSrmStoreCopyEntry( vFinalStore, vCbsStore, iStart, i );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iStart = Vec_IntEntry( vTasStarts, i );
|
||||||
|
assert( iStart >= 0 );
|
||||||
|
Cec_DynSrmStoreCopyEntry( vFinalStore, vTasStore, iStart, i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Vec_IntFree( vCbsStore );
|
||||||
|
Vec_IntFree( vCbsStarts );
|
||||||
|
Vec_IntFree( vTasStore );
|
||||||
|
Vec_IntFree( vTasStarts );
|
||||||
|
Vec_IntFree( vUnknown );
|
||||||
|
*pvStatus = vStatus;
|
||||||
|
return vFinalStore;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// END OF FILE ///
|
/// END OF FILE ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@
|
||||||
|
|
||||||
PackageName [Combinational equivalence checking.]
|
PackageName [Combinational equivalence checking.]
|
||||||
|
|
||||||
Synopsis [Incremental active-list / TFO filter for &scorr.]
|
Synopsis [Incremental active-list / TFO filter for &scorr2.]
|
||||||
|
|
||||||
Author [Xiran Zhao]
|
Author [Xiran Zhao]
|
||||||
|
|
||||||
Affiliation [University of Chinese Academy of Sciences]
|
Affiliation [University of Chinese Academy of Sciences (UCAS)]
|
||||||
|
|
||||||
Date [Ver. 1.0. Started - May 2026.]
|
Date [Ver. 1.0. Started - May 2026.]
|
||||||
|
|
||||||
|
|
@ -477,7 +477,7 @@ Gia_Man_t * Gia_ManCorrSpecReduce_Emit( Gia_Man_t * p, int nFrames, int fScorr,
|
||||||
(Mode == CEC_EMIT_SKIPPED && !fActive);
|
(Mode == CEC_EMIT_SKIPPED && !fActive);
|
||||||
if ( !fEmit )
|
if ( !fEmit )
|
||||||
continue;
|
continue;
|
||||||
iObjRaw = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 );
|
iObjRaw = Gia_ManCorr2SpecReal( pNew, p, pObj, nFrames, 0 );
|
||||||
iObjNew = Abc_LitNotCond( iObjRaw, Gia_ObjPhase(pObj) );
|
iObjNew = Abc_LitNotCond( iObjRaw, Gia_ObjPhase(pObj) );
|
||||||
if ( iObjNew != 0 )
|
if ( iObjNew != 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -507,8 +507,8 @@ Gia_Man_t * Gia_ManCorrSpecReduce_Emit( Gia_Man_t * p, int nFrames, int fScorr,
|
||||||
(Mode == CEC_EMIT_SKIPPED && !fActive);
|
(Mode == CEC_EMIT_SKIPPED && !fActive);
|
||||||
if ( fEmit )
|
if ( fEmit )
|
||||||
{
|
{
|
||||||
iPrevRaw = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 );
|
iPrevRaw = Gia_ManCorr2SpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 );
|
||||||
iObjRaw = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 );
|
iObjRaw = Gia_ManCorr2SpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 );
|
||||||
iPrevNew = Abc_LitNotCond( iPrevRaw, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
|
iPrevNew = Abc_LitNotCond( iPrevRaw, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
|
||||||
iObjNew = Abc_LitNotCond( iObjRaw, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
|
iObjNew = Abc_LitNotCond( iObjRaw, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
|
||||||
if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
|
if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
|
||||||
|
|
@ -536,8 +536,8 @@ Gia_Man_t * Gia_ManCorrSpecReduce_Emit( Gia_Man_t * p, int nFrames, int fScorr,
|
||||||
(Mode == CEC_EMIT_SKIPPED && !fActive);
|
(Mode == CEC_EMIT_SKIPPED && !fActive);
|
||||||
if ( fEmit )
|
if ( fEmit )
|
||||||
{
|
{
|
||||||
iPrevRaw = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 );
|
iPrevRaw = Gia_ManCorr2SpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames, 0 );
|
||||||
iObjRaw = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 );
|
iObjRaw = Gia_ManCorr2SpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames, 0 );
|
||||||
iPrevNew = Abc_LitNotCond( iPrevRaw, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
|
iPrevNew = Abc_LitNotCond( iPrevRaw, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) );
|
||||||
iObjNew = Abc_LitNotCond( iObjRaw, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
|
iObjNew = Abc_LitNotCond( iObjRaw, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) );
|
||||||
if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
|
if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 )
|
||||||
|
|
@ -572,8 +572,8 @@ Gia_Man_t * Gia_ManCorrSpecReduce_Emit( Gia_Man_t * p, int nFrames, int fScorr,
|
||||||
if ( !fEmit )
|
if ( !fEmit )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
iPrevRaw = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, nFrames, 0 );
|
iPrevRaw = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorr2SpecReal( pNew, p, pRepr, nFrames, 0 );
|
||||||
iObjRaw = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames, 0 );
|
iObjRaw = Gia_ManCorr2SpecReal( pNew, p, pObj, nFrames, 0 );
|
||||||
iPrevNew = iPrevRaw;
|
iPrevNew = iPrevRaw;
|
||||||
iObjNew = Abc_LitNotCond( iObjRaw, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
|
iObjNew = Abc_LitNotCond( iObjRaw, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
|
||||||
if ( iPrevNew != iObjNew )
|
if ( iPrevNew != iObjNew )
|
||||||
|
|
@ -662,8 +662,8 @@ Gia_Man_t * Gia_ManCorrSpecReduceInit_Active( Gia_Man_t * p, int nFrames, int nP
|
||||||
if ( !pTfoMark[i] && !pTfoMark[idR] )
|
if ( !pTfoMark[i] && !pTfoMark[idR] )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, f, nPrefix );
|
iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorr2SpecReal( pNew, p, pRepr, f, nPrefix );
|
||||||
iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, f, nPrefix );
|
iObjNew = Gia_ManCorr2SpecReal( pNew, p, pObj, f, nPrefix );
|
||||||
iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
|
iObjNew = Abc_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) );
|
||||||
if ( iPrevNew != iObjNew )
|
if ( iPrevNew != iObjNew )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
PackageName [Combinational equivalence checking.]
|
PackageName [Combinational equivalence checking.]
|
||||||
|
|
||||||
Synopsis [Persistent event-driven incremental simulation for &scorr.]
|
Synopsis [Persistent event-driven incremental simulation for &scorr2.]
|
||||||
|
|
||||||
Description [Keeps packed CI patterns and host-AIG values across CEX batches.
|
Description [Keeps packed CI patterns and host-AIG values across CEX batches.
|
||||||
Only changed CI words are propagated through the frame-aware fanout graph.
|
Only changed CI words are propagated through the frame-aware fanout graph.
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
Author [Xiran Zhao]
|
Author [Xiran Zhao]
|
||||||
|
|
||||||
Affiliation [University of Chinese Academy of Sciences]
|
Affiliation [University of Chinese Academy of Sciences (UCAS)]
|
||||||
|
|
||||||
Date [Ver. 1.0. Started - Jun 2026.]
|
Date [Ver. 1.0. Started - Jun 2026.]
|
||||||
|
|
||||||
|
|
@ -389,6 +389,8 @@ void Cec_SeedSimFree( Cec_SeedSim_t * p )
|
||||||
ABC_FREE( p->pEventWords );
|
ABC_FREE( p->pEventWords );
|
||||||
ABC_FREE( p->pCone );
|
ABC_FREE( p->pCone );
|
||||||
ABC_FREE( p->pConeClose );
|
ABC_FREE( p->pConeClose );
|
||||||
|
ABC_FREE( p->pReprPre );
|
||||||
|
ABC_FREE( p->pNextPre );
|
||||||
ABC_FREE( p->pRootMark );
|
ABC_FREE( p->pRootMark );
|
||||||
ABC_FREE( p->pTxnMark );
|
ABC_FREE( p->pTxnMark );
|
||||||
ABC_FREE( p->pPackPres );
|
ABC_FREE( p->pPackPres );
|
||||||
|
|
@ -1327,6 +1329,149 @@ static void Cec_SeedSimBuildPersistentValues( Cec_SeedSim_t * p )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (-V) Oracle for incremental-resim correctness. The maintained pVal must equal
|
||||||
|
// the true value of every IN-CONE key under the current persistent inputs. We
|
||||||
|
// snapshot the under-test values, recompute the trusted values by a full sweep
|
||||||
|
// from vSimInfo (no class side effects), compare on cone keys, then restore the
|
||||||
|
// under-test values so the run trajectory is unchanged (purely observational).
|
||||||
|
// Out-of-cone keys are intentionally stale and are not checked.
|
||||||
|
int Cec_SeedSimVerifyValues( Cec_SeedSim_t * p )
|
||||||
|
{
|
||||||
|
size_t nKeys, nVals;
|
||||||
|
unsigned * pTest;
|
||||||
|
int Key, w, nBad = 0;
|
||||||
|
if ( p->pVal == NULL )
|
||||||
|
return 0;
|
||||||
|
nKeys = (size_t)p->nFrames * p->nObjs;
|
||||||
|
nVals = nKeys * (size_t)p->nWords;
|
||||||
|
pTest = ABC_ALLOC( unsigned, nVals );
|
||||||
|
memcpy( pTest, p->pVal, sizeof(unsigned) * nVals ); // maintained (under test)
|
||||||
|
Cec_SeedSimBuildPersistentValues( p ); // p->pVal := true values
|
||||||
|
for ( Key = 0; Key < (int)nKeys; Key++ )
|
||||||
|
{
|
||||||
|
if ( p->fUseCone && !Abc_InfoHasBit(p->pCone, Key) )
|
||||||
|
continue;
|
||||||
|
for ( w = 0; w < p->nWords; w++ )
|
||||||
|
{
|
||||||
|
size_t Flat = (size_t)Key * p->nWords + w;
|
||||||
|
if ( pTest[Flat] != p->pVal[Flat] )
|
||||||
|
{
|
||||||
|
if ( nBad < 20 )
|
||||||
|
Abc_Print( 1, " [resim-oracle] STALE key f=%d obj=%d w=%d "
|
||||||
|
"maintained=%08x true=%08x\n",
|
||||||
|
Key / p->nObjs, Key % p->nObjs, w,
|
||||||
|
pTest[Flat], p->pVal[Flat] );
|
||||||
|
nBad++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( nBad )
|
||||||
|
Abc_Print( 1, " [resim-oracle] %d in-cone keys STALE "
|
||||||
|
"(maintained != true under persistent inputs)\n", nBad );
|
||||||
|
memcpy( p->pVal, pTest, sizeof(unsigned) * nVals ); // restore: stay observational
|
||||||
|
ABC_FREE( pTest );
|
||||||
|
return nBad;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (-V) Capture the class partition (pReprs/pNexts) before a batch is resimulated.
|
||||||
|
// Cec_SeedSimVerifyRefine() replays the trusted full resim from this snapshot.
|
||||||
|
void Cec_SeedSimVerifySnapshot( Cec_SeedSim_t * p )
|
||||||
|
{
|
||||||
|
int nObjs = p->nObjs;
|
||||||
|
if ( p->pAig->pReprs == NULL || p->pAig->pNexts == NULL )
|
||||||
|
return;
|
||||||
|
if ( p->pReprPre == NULL )
|
||||||
|
{
|
||||||
|
p->pReprPre = ABC_ALLOC( int, nObjs );
|
||||||
|
p->pNextPre = ABC_ALLOC( int, nObjs );
|
||||||
|
}
|
||||||
|
memcpy( p->pReprPre, p->pAig->pReprs, sizeof(int) * nObjs );
|
||||||
|
memcpy( p->pNextPre, p->pAig->pNexts, sizeof(int) * nObjs );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int Cec_SeedSimSavedRoot( int * pReprs, int ObjId )
|
||||||
|
{
|
||||||
|
return pReprs[ObjId] == GIA_VOID ? ObjId : pReprs[ObjId];
|
||||||
|
}
|
||||||
|
|
||||||
|
// (-V) Oracle for class refinement (not just the value cache). The incremental
|
||||||
|
// resim has just committed its splits for this batch (P_incr). We re-run the
|
||||||
|
// TRUSTED full resim on the SAME packed CEX inputs starting from the pre-batch
|
||||||
|
// partition (P0), giving the reference partition P_full.
|
||||||
|
//
|
||||||
|
// Both directions matter:
|
||||||
|
// * P_incr merged, P_full split: missed split, a correctness risk.
|
||||||
|
// * P_incr split, P_full merged: extra split, a QoR regression.
|
||||||
|
//
|
||||||
|
// The check reuses the production refinement code (correct phase/const handling),
|
||||||
|
// then restores P_incr so the run stays observational. Returns #mismatches.
|
||||||
|
int Cec_SeedSimVerifyRefine( Cec_SeedSim_t * p, Cec_ManSim_t * pSim,
|
||||||
|
Vec_Ptr_t * vSimInfo, int nFrames )
|
||||||
|
{
|
||||||
|
Gia_Man_t * pAig = p->pAig;
|
||||||
|
int nObjs = p->nObjs;
|
||||||
|
int * pReprIncr, * pNextIncr;
|
||||||
|
int i, nMissed = 0, nExtra = 0;
|
||||||
|
if ( pAig->pReprs == NULL || p->pReprPre == NULL )
|
||||||
|
return 0;
|
||||||
|
pReprIncr = ABC_ALLOC( int, nObjs );
|
||||||
|
pNextIncr = ABC_ALLOC( int, nObjs );
|
||||||
|
memcpy( pReprIncr, pAig->pReprs, sizeof(int) * nObjs ); // P_incr (committed)
|
||||||
|
memcpy( pNextIncr, pAig->pNexts, sizeof(int) * nObjs );
|
||||||
|
// restore the pre-batch partition and run the trusted full resim
|
||||||
|
memcpy( pAig->pReprs, p->pReprPre, sizeof(int) * nObjs );
|
||||||
|
memcpy( pAig->pNexts, p->pNextPre, sizeof(int) * nObjs );
|
||||||
|
Gia_ManCreateValueRefs( pAig );
|
||||||
|
pSim->pPars->nFrames = nFrames;
|
||||||
|
Cec_ManSeqResimulate( pSim, vSimInfo ); // pAig now holds P_full
|
||||||
|
// a pair merged in P_incr but split in P_full is a missed (unsound) split
|
||||||
|
for ( i = 1; i < nObjs; i++ )
|
||||||
|
{
|
||||||
|
int rIncr = pReprIncr[i], ci, cr;
|
||||||
|
if ( rIncr == GIA_VOID )
|
||||||
|
continue; // i was a head/none in P_incr
|
||||||
|
ci = Gia_ObjRepr(pAig, i) == GIA_VOID ? i : Gia_ObjRepr(pAig, i);
|
||||||
|
cr = Gia_ObjRepr(pAig, rIncr) == GIA_VOID ? rIncr : Gia_ObjRepr(pAig, rIncr);
|
||||||
|
if ( ci != cr )
|
||||||
|
{
|
||||||
|
if ( nMissed < 20 )
|
||||||
|
Abc_Print( 1, " [resim-oracle] MISSED SPLIT obj=%d repr=%d "
|
||||||
|
"(merged by incremental, split by full resim)\n", i, rIncr );
|
||||||
|
nMissed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// a pair split in P_incr but merged in P_full is an extra split (QoR loss)
|
||||||
|
for ( i = 1; i < nObjs; i++ )
|
||||||
|
{
|
||||||
|
int rFull = Gia_ObjRepr(pAig, i), ci, cr;
|
||||||
|
if ( rFull == GIA_VOID )
|
||||||
|
continue; // i was a head/none in P_full
|
||||||
|
ci = Cec_SeedSimSavedRoot( pReprIncr, i );
|
||||||
|
cr = Cec_SeedSimSavedRoot( pReprIncr, rFull );
|
||||||
|
if ( ci != cr )
|
||||||
|
{
|
||||||
|
if ( nExtra < 20 )
|
||||||
|
Abc_Print( 1, " [resim-oracle] EXTRA SPLIT obj=%d repr=%d "
|
||||||
|
"(split by incremental roots %d/%d, merged by full resim)\n",
|
||||||
|
i, rFull, ci, cr );
|
||||||
|
nExtra++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// restore the committed (incremental) partition: stay observational
|
||||||
|
memcpy( pAig->pReprs, pReprIncr, sizeof(int) * nObjs );
|
||||||
|
memcpy( pAig->pNexts, pNextIncr, sizeof(int) * nObjs );
|
||||||
|
ABC_FREE( pReprIncr );
|
||||||
|
ABC_FREE( pNextIncr );
|
||||||
|
if ( nMissed )
|
||||||
|
Abc_Print( 1, " [resim-oracle] %d MISSED SPLITS this batch "
|
||||||
|
"(incremental coarser than full resim)\n", nMissed );
|
||||||
|
if ( nExtra )
|
||||||
|
Abc_Print( 1, " [resim-oracle] %d EXTRA SPLITS this batch "
|
||||||
|
"(incremental finer than full resim; QoR regression)\n", nExtra );
|
||||||
|
return nMissed + nExtra;
|
||||||
|
}
|
||||||
|
|
||||||
void Cec_SeedSimEnsurePersistent( Cec_SeedSim_t * p, Cec_ManSim_t * pSim )
|
void Cec_SeedSimEnsurePersistent( Cec_SeedSim_t * p, Cec_ManSim_t * pSim )
|
||||||
{
|
{
|
||||||
int nInputs = p->nRegs + p->nPis * p->nFrames;
|
int nInputs = p->nRegs + p->nPis * p->nFrames;
|
||||||
|
|
@ -1928,6 +2073,11 @@ int Cec_SeedSimTryBatch( Cec_SeedSim_t * p, Cec_ManSim_t * pSim,
|
||||||
Cec_SeedSimRecordBatch( p, Vec_IntSize(vOutBits) / 2 );
|
Cec_SeedSimRecordBatch( p, Vec_IntSize(vOutBits) / 2 );
|
||||||
p->nEventInputVarsMax = Abc_MaxInt( p->nEventInputVarsMax, nInputVars );
|
p->nEventInputVarsMax = Abc_MaxInt( p->nEventInputVarsMax, nInputVars );
|
||||||
p->nEventInputWordsMax = Abc_MaxInt( p->nEventInputWordsMax, nInputWords );
|
p->nEventInputWordsMax = Abc_MaxInt( p->nEventInputWordsMax, nInputWords );
|
||||||
|
// Up-front density gate. A batch whose changed-CI seed is a large fraction
|
||||||
|
// of all unrolled inputs will dirty a near-full closure, so event
|
||||||
|
// propagation cannot beat a bit-parallel full sweep. Reject it here before
|
||||||
|
// mutating any persistent value, instead of propagating until a mid-flight
|
||||||
|
// budget abort discards the work (and then still falling back to full).
|
||||||
if ( (ABC_INT64_T)nInputVars * CEC_EVENT_INPUT_FRAC_DEN >
|
if ( (ABC_INT64_T)nInputVars * CEC_EVENT_INPUT_FRAC_DEN >
|
||||||
(ABC_INT64_T)nTotalInputs * CEC_EVENT_INPUT_FRAC_NUM )
|
(ABC_INT64_T)nTotalInputs * CEC_EVENT_INPUT_FRAC_NUM )
|
||||||
{
|
{
|
||||||
|
|
@ -1935,6 +2085,17 @@ int Cec_SeedSimTryBatch( Cec_SeedSim_t * p, Cec_ManSim_t * pSim,
|
||||||
p->nBatchFull++;
|
p->nBatchFull++;
|
||||||
return CEC_SEEDSIM_RESULT_FULL_WIDE;
|
return CEC_SEEDSIM_RESULT_FULL_WIDE;
|
||||||
}
|
}
|
||||||
|
// No class-cone gate. Event propagation below follows the full forward TFO of
|
||||||
|
// this batch's changed CIs (bounded only by the deterministic nNodeLimit /
|
||||||
|
// nEdgeLimit work budget; exceeding it falls back to a full sweep without
|
||||||
|
// committing). This keeps the persistent pVal globally consistent with the
|
||||||
|
// committed inputs, so Cec_SeedSimEventRefine() never reads a stale value and
|
||||||
|
// never misses a split. pSeed->fUseCone stays 0 (reset in
|
||||||
|
// Cec_ManResimulateCounterExamples), so Cec_SeedSimConeHasKey() is always true.
|
||||||
|
// The old per-call active-pair cone was too narrow -> stale values across calls
|
||||||
|
// -> missed splits -> unsound merges; see md/I_resim_soundness_bug.md. The
|
||||||
|
// cone scaffolding (Cec_SeedSimBuildClassCone / pCone / ...) is retained, unused,
|
||||||
|
// for a future adaptive *full-candidate* cone on sparse-candidate designs.
|
||||||
(void)vOutputs;
|
(void)vOutputs;
|
||||||
Cec_SeedSimReset( p );
|
Cec_SeedSimReset( p );
|
||||||
Vec_IntClear( p->vValueUndo );
|
Vec_IntClear( p->vValueUndo );
|
||||||
|
|
@ -2023,7 +2184,8 @@ void Cec_SeedSimBeginCall( Cec_SeedSim_t * p )
|
||||||
p->nEventLocal = p->nEventFallback = 0;
|
p->nEventLocal = p->nEventFallback = 0;
|
||||||
p->nEventPopsMax = p->nEventEdgesMax = 0;
|
p->nEventPopsMax = p->nEventEdgesMax = 0;
|
||||||
p->nEventInputVarsMax = p->nEventInputWordsMax = 0;
|
p->nEventInputVarsMax = p->nEventInputWordsMax = 0;
|
||||||
p->nEventFallbackWork = 0;
|
p->nEventFallbackWork = p->nEventFallbackTime = 0;
|
||||||
|
p->nAdaptTrips = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cec_SeedSimBypassBatch( Cec_SeedSim_t * p, int nCex )
|
void Cec_SeedSimBypassBatch( Cec_SeedSim_t * p, int nCex )
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ typedef enum Cec_IncrEmitMode_t_
|
||||||
CEC_EMIT_SKIPPED
|
CEC_EMIT_SKIPPED
|
||||||
} Cec_IncrEmitMode_t;
|
} Cec_IncrEmitMode_t;
|
||||||
|
|
||||||
// Persistent event-driven simulation manager for &scorr incremental mode.
|
// Persistent event-driven simulation manager for &scorr2 -I.
|
||||||
// Packed input patterns and host-AIG values survive across CEX batches. A
|
// Packed input patterns and host-AIG values survive across CEX batches. A
|
||||||
// batch records only the input words it changes; real value deltas propagate
|
// batch records only the input words it changes; real value deltas propagate
|
||||||
// through the frame-aware fanout graph and dirty classes are fully regrouped.
|
// through the frame-aware fanout graph and dirty classes are fully regrouped.
|
||||||
|
|
@ -268,8 +268,14 @@ struct Cec_SeedSim_t_
|
||||||
Vec_Int_t * vConeQueue; // newly marked keys used to class-close pCone
|
Vec_Int_t * vConeQueue; // newly marked keys used to class-close pCone
|
||||||
int * pConeClose; // (frame,root) stamp: class already closed this build
|
int * pConeClose; // (frame,root) stamp: class already closed this build
|
||||||
int nConeCloseVer; // version for pConeClose
|
int nConeCloseVer; // version for pConeClose
|
||||||
|
int fVerify; // (-V) check maintained values vs full sweep each batch
|
||||||
|
int * pReprPre; // (-V) class-repr snapshot captured before a batch
|
||||||
|
int * pNextPre; // (-V) class-next snapshot captured before a batch
|
||||||
int nFallbackStreak; // persists across resimulation calls
|
int nFallbackStreak; // persists across resimulation calls
|
||||||
int nFallbackCooldown; // batches bypassed before next event probe
|
int nFallbackCooldown; // batches bypassed before next event probe
|
||||||
|
int nAdaptLocal; // decaying window: recent successful event batches
|
||||||
|
int nAdaptFail; // decaying window: recent event batches that fell back
|
||||||
|
int nAdaptTrips; // per-call adaptive cooldown activations
|
||||||
// Class-refinement scratch.
|
// Class-refinement scratch.
|
||||||
int * pRootMark; // per-objId "root already queued" stamp
|
int * pRootMark; // per-objId "root already queued" stamp
|
||||||
int nRootVersion;
|
int nRootVersion;
|
||||||
|
|
@ -288,7 +294,7 @@ struct Cec_SeedSim_t_
|
||||||
unsigned * pPhase0; // nWords of 0 (phase-0 vector, used by refine)
|
unsigned * pPhase0; // nWords of 0 (phase-0 vector, used by refine)
|
||||||
unsigned * pPhase1; // nWords of ~0 (phase-1 vector)
|
unsigned * pPhase1; // nWords of ~0 (phase-1 vector)
|
||||||
int fOwnsFanout; // 1 if we built static fanout (must free)
|
int fOwnsFanout; // 1 if we built static fanout (must free)
|
||||||
// Profile counters (reset per resim call)
|
// Per-call work state used by bounded fallback and adaptive control.
|
||||||
int nBatchLocal; // rounds handled by local TFO sim
|
int nBatchLocal; // rounds handled by local TFO sim
|
||||||
int nBatchFull; // rounds that fell back to full sweep
|
int nBatchFull; // rounds that fell back to full sweep
|
||||||
int nBatchTrunc; // local rounds that stopped optional TFO expansion
|
int nBatchTrunc; // local rounds that stopped optional TFO expansion
|
||||||
|
|
@ -313,10 +319,12 @@ struct Cec_SeedSim_t_
|
||||||
int nEventInputVarsMax; // largest changed-CI count in one batch
|
int nEventInputVarsMax; // largest changed-CI count in one batch
|
||||||
int nEventInputWordsMax; // largest changed-CI-word count in one batch
|
int nEventInputWordsMax; // largest changed-CI-word count in one batch
|
||||||
int nEventFallbackWork; // structural word-operation budget exceeded
|
int nEventFallbackWork; // structural word-operation budget exceeded
|
||||||
|
int nEventFallbackTime; // adaptive elapsed-time budget exceeded
|
||||||
};
|
};
|
||||||
|
|
||||||
// Dynamic SRM construction manager for &scorr incremental mode. It keeps the
|
// Dynamic SRM construction manager for &scorr2 -D. It keeps the speculative SRM
|
||||||
// speculative SRM core used by SAT.
|
// core used by SAT; counterexample resimulation is selected independently by
|
||||||
|
// -I and otherwise uses the original host-AIG path.
|
||||||
typedef struct Cec_DynSrm_t_ Cec_DynSrm_t;
|
typedef struct Cec_DynSrm_t_ Cec_DynSrm_t;
|
||||||
|
|
||||||
// Recursive diagnosis has a much higher constant factor than a linear sweep.
|
// Recursive diagnosis has a much higher constant factor than a linear sweep.
|
||||||
|
|
@ -337,6 +345,15 @@ typedef struct Cec_DynSrm_t_ Cec_DynSrm_t;
|
||||||
// Consecutive wide cones use bounded exponential backoff. A successful local
|
// Consecutive wide cones use bounded exponential backoff. A successful local
|
||||||
// batch clears both the streak and cooldown immediately.
|
// batch clears both the streak and cooldown immediately.
|
||||||
#define CEC_SEEDSIM_MAX_FALLBACK_BACKOFF 7
|
#define CEC_SEEDSIM_MAX_FALLBACK_BACKOFF 7
|
||||||
|
// Adaptive event-resim circuit breaker. Logs showed good cases are strongly
|
||||||
|
// local-heavy (400k: 161/0, fermat: 451/6) while bad cases are fallback-heavy
|
||||||
|
// (RAV: 122/1335). Use a small decaying window to probe again after cooldown
|
||||||
|
// without repeatedly paying the failed event propagation cost.
|
||||||
|
#define CEC_SEEDSIM_ADAPT_WINDOW 16
|
||||||
|
#define CEC_SEEDSIM_ADAPT_MIN_SAMPLES 8
|
||||||
|
#define CEC_SEEDSIM_ADAPT_FAIL_MUL 2
|
||||||
|
#define CEC_SEEDSIM_ADAPT_FAIL_EXTRA 4
|
||||||
|
#define CEC_SEEDSIM_ADAPT_MAX_COOLDOWN 31
|
||||||
#define CEC_EVENT_NODE_WORD_FRAC_NUM 1
|
#define CEC_EVENT_NODE_WORD_FRAC_NUM 1
|
||||||
#define CEC_EVENT_NODE_WORD_FRAC_DEN 10
|
#define CEC_EVENT_NODE_WORD_FRAC_DEN 10
|
||||||
#define CEC_EVENT_EDGE_WORD_FRAC_NUM 1
|
#define CEC_EVENT_EDGE_WORD_FRAC_NUM 1
|
||||||
|
|
@ -361,13 +378,13 @@ typedef struct Cec_DynSrm_t_ Cec_DynSrm_t;
|
||||||
|
|
||||||
/*=== cecCorr.c ============================================================*/
|
/*=== cecCorr.c ============================================================*/
|
||||||
extern void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, abctime Time );
|
extern void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, abctime Time );
|
||||||
extern void Cec_ManStartSimInfo( Vec_Ptr_t * vInfo, int nFlops );
|
/*=== cecCorr2.c ===========================================================*/
|
||||||
extern Vec_Int_t * Gia_ManCorrCreateRemapping( Gia_Man_t * p );
|
extern int Gia_ManCorr2SpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
|
||||||
extern void Gia_ManCorrPerformRemapping( Vec_Int_t * vPairs, Vec_Ptr_t * vInfo );
|
extern void Gia_ManCorr2SpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
|
||||||
extern int Cec_ManLoadCounterExamples( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart );
|
extern Gia_Man_t * Gia_ManCorr2SpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings, Vec_Int_t ** pvOutLits );
|
||||||
extern int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
|
extern Gia_Man_t * Cec_ManLSCorrespondence2( Gia_Man_t * pAig, Cec_ParCor_t * pPars );
|
||||||
extern void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f, int nPrefix );
|
/*=== cecCorrCert.c =========================================================*/
|
||||||
extern Gia_Man_t * Gia_ManCorrSpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings );
|
extern int Cec_ManCorrKissatCertify( Gia_Man_t * pSrm, Vec_Int_t * vOutputs, Vec_Int_t ** pvCexStore, Vec_Str_t ** pvStatus, int * piOut, int fVerbose );
|
||||||
/*=== cecCorrIncr.c ============================================================*/
|
/*=== cecCorrIncr.c ============================================================*/
|
||||||
extern Cec_IncrMgr_t * Cec_IncrMgrAlloc( Gia_Man_t * pAig, int nFrames );
|
extern Cec_IncrMgr_t * Cec_IncrMgrAlloc( Gia_Man_t * pAig, int nFrames );
|
||||||
extern void Cec_IncrMgrFree( Cec_IncrMgr_t * p );
|
extern void Cec_IncrMgrFree( Cec_IncrMgr_t * p );
|
||||||
|
|
@ -380,16 +397,19 @@ extern void Cec_IncrMgrComputeTfo( Cec_IncrMgr_t * p );
|
||||||
extern Gia_Man_t * Gia_ManCorrSpecReduce_Emit( Gia_Man_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings, int * pTfoMark, Cec_IncrMgr_t * pIncr, Cec_IncrEmitMode_t Mode, Vec_Int_t ** pvOutLits );
|
extern Gia_Man_t * Gia_ManCorrSpecReduce_Emit( Gia_Man_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings, int * pTfoMark, Cec_IncrMgr_t * pIncr, Cec_IncrEmitMode_t Mode, Vec_Int_t ** pvOutLits );
|
||||||
extern Gia_Man_t * Gia_ManCorrSpecReduceInit_Active( Gia_Man_t * p, int nFrames, int nPrefix, int fScorr, Vec_Int_t ** pvOutputs, int * pTfoMark );
|
extern Gia_Man_t * Gia_ManCorrSpecReduceInit_Active( Gia_Man_t * p, int nFrames, int nPrefix, int fScorr, Vec_Int_t ** pvOutputs, int * pTfoMark );
|
||||||
/*=== cecCorrDyn.c ============================================================*/
|
/*=== cecCorrDyn.c ============================================================*/
|
||||||
extern Cec_DynSrm_t * Cec_DynSrmAlloc( Gia_Man_t * pAig, Cec_IncrMgr_t * pIncr );
|
extern Cec_DynSrm_t * Cec_DynSrmAlloc( Gia_Man_t * pAig, Cec_IncrMgr_t * pIncr, int fUseAdaptive );
|
||||||
|
extern void Cec_DynSrmSetParams( Cec_DynSrm_t * p, Cec_ParCor_t * pPars );
|
||||||
|
extern void Cec_DynSrmForceRebuild( Cec_DynSrm_t * p, int fIncrFallback );
|
||||||
extern void Cec_DynSrmFree( Cec_DynSrm_t * p );
|
extern void Cec_DynSrmFree( Cec_DynSrm_t * p );
|
||||||
extern void Cec_DynSrmPrintStats( Cec_DynSrm_t * p );
|
extern void Cec_DynSrmRecordSolveStats( Cec_DynSrm_t * p, int nCalls, int nReal, int nTriv, int nFail, abctime tSat );
|
||||||
extern void Cec_DynSrmCountActivePairs( Cec_DynSrm_t * p, int fRings, int * pTfoMark, int * pnTotal, int * pnActive );
|
extern void Cec_DynSrmCountActivePairs( Cec_DynSrm_t * p, int fRings, int * pTfoMark, int * pnTotal, int * pnActive );
|
||||||
extern Gia_Man_t * Cec_DynSrmBuild( Cec_DynSrm_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings, int * pTfoMask, Cec_IncrEmitMode_t Mode );
|
extern Gia_Man_t * Cec_DynSrmBuild( Cec_DynSrm_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings, int * pTfoMask, Cec_IncrEmitMode_t Mode );
|
||||||
extern void Cec_DynSrmBuildCore( Cec_DynSrm_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings, int * pTfoMask, Cec_IncrEmitMode_t Mode );
|
extern void Cec_DynSrmBuildCore( Cec_DynSrm_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings, int * pTfoMask, Cec_IncrEmitMode_t Mode );
|
||||||
extern Gia_Man_t * Cec_DynSrmBuildInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fScorr, Vec_Int_t ** pvOutputs, int * pTfoMask, Cec_IncrEmitMode_t Mode );
|
extern Gia_Man_t * Cec_DynSrmBuildInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fScorr, Vec_Int_t ** pvOutputs, int * pTfoMask, Cec_IncrEmitMode_t Mode );
|
||||||
extern void Cec_DynSrmBuildCoreInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fScorr, Vec_Int_t ** pvOutputs, int * pTfoMask, Cec_IncrEmitMode_t Mode );
|
extern void Cec_DynSrmBuildCoreInit( Cec_DynSrm_t * p, int nFrames, int nPrefix, int fScorr, Vec_Int_t ** pvOutputs, int * pTfoMask, Cec_IncrEmitMode_t Mode );
|
||||||
extern Vec_Int_t * Cec_DynSrmOutLits( Cec_DynSrm_t * p );
|
extern Vec_Int_t * Cec_DynSrmOutLits( Cec_DynSrm_t * p );
|
||||||
extern Vec_Int_t * Cec_DynSrmSolve( Cec_DynSrm_t * p, int nConfs, Vec_Str_t ** pvStatus );
|
extern Vec_Int_t * Cec_DynSrmSolve( Cec_DynSrm_t * p, int nConfs, Vec_Str_t ** pvStatus, int fUseTas );
|
||||||
|
extern Vec_Int_t * Cec_DynSrmSolveBmcAdaptive( Cec_DynSrm_t * p, int nConfs, Vec_Str_t ** pvStatus, int fUseTas );
|
||||||
/*=== cecCorrIncrSim.c ============================================================*/
|
/*=== cecCorrIncrSim.c ============================================================*/
|
||||||
extern Cec_SeedSim_t * Cec_SeedSimAlloc( Gia_Man_t * pAig, int nFrames, int iSeedFrame, int nWords );
|
extern Cec_SeedSim_t * Cec_SeedSimAlloc( Gia_Man_t * pAig, int nFrames, int iSeedFrame, int nWords );
|
||||||
extern void Cec_SeedSimFree( Cec_SeedSim_t * p );
|
extern void Cec_SeedSimFree( Cec_SeedSim_t * p );
|
||||||
|
|
@ -401,6 +421,9 @@ extern void Cec_SeedSimBeginCall( Cec_SeedSim_t * p );
|
||||||
extern void Cec_SeedSimBypassBatch( Cec_SeedSim_t * p, int nCex );
|
extern void Cec_SeedSimBypassBatch( Cec_SeedSim_t * p, int nCex );
|
||||||
extern void Cec_SeedSimEnsurePersistent( Cec_SeedSim_t * p, Cec_ManSim_t * pSim );
|
extern void Cec_SeedSimEnsurePersistent( Cec_SeedSim_t * p, Cec_ManSim_t * pSim );
|
||||||
extern void Cec_SeedSimBuildClassCone( Cec_SeedSim_t * p, Vec_Int_t * vOutputs );
|
extern void Cec_SeedSimBuildClassCone( Cec_SeedSim_t * p, Vec_Int_t * vOutputs );
|
||||||
|
extern int Cec_SeedSimVerifyValues( Cec_SeedSim_t * p );
|
||||||
|
extern void Cec_SeedSimVerifySnapshot( Cec_SeedSim_t * p );
|
||||||
|
extern int Cec_SeedSimVerifyRefine( Cec_SeedSim_t * p, Cec_ManSim_t * pSim, Vec_Ptr_t * vSimInfo, int nFrames );
|
||||||
extern int Cec_SeedSimLoadPersistentBatch( Cec_SeedSim_t * p, Vec_Int_t * vCexStore, int iStart, Vec_Int_t * vPairs, Vec_Int_t * vOutBits );
|
extern int Cec_SeedSimLoadPersistentBatch( Cec_SeedSim_t * p, Vec_Int_t * vCexStore, int iStart, Vec_Int_t * vPairs, Vec_Int_t * vOutBits );
|
||||||
extern void Cec_SeedSimRestorePersistentInputs( Cec_SeedSim_t * p );
|
extern void Cec_SeedSimRestorePersistentInputs( Cec_SeedSim_t * p );
|
||||||
/*=== cecClass.c ============================================================*/
|
/*=== cecClass.c ============================================================*/
|
||||||
|
|
@ -466,4 +489,3 @@ ABC_NAMESPACE_HEADER_END
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// END OF FILE ///
|
/// END OF FILE ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ SRC += src/proof/cec/cecCec.c \
|
||||||
src/proof/cec/cecClass.c \
|
src/proof/cec/cecClass.c \
|
||||||
src/proof/cec/cecCore.c \
|
src/proof/cec/cecCore.c \
|
||||||
src/proof/cec/cecCorr.c \
|
src/proof/cec/cecCorr.c \
|
||||||
|
src/proof/cec/cecCorr2.c \
|
||||||
|
src/proof/cec/cecCorrCert.c \
|
||||||
src/proof/cec/cecCorrDyn.c \
|
src/proof/cec/cecCorrDyn.c \
|
||||||
src/proof/cec/cecCorrIncr.c \
|
src/proof/cec/cecCorrIncr.c \
|
||||||
src/proof/cec/cecCorrIncrSim.c \
|
src/proof/cec/cecCorrIncrSim.c \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue