Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
abc
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
abc
Commits
b2470dd3
Commit
b2470dd3
authored
Sep 01, 2007
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Version abc70901
parent
9f5ef0d6
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
791 additions
and
417 deletions
+791
-417
abc.dsp
+3
-3
src/aig/aig/aig.h
+3
-3
src/aig/aig/aigPart.c
+81
-68
src/aig/fra/fraPart.c
+2
-2
src/base/abc/abc.h
+1
-0
src/base/abc/abcNtk.c
+54
-1
src/base/abci/abc.c
+3
-0
src/base/abci/abcFraig.c
+48
-67
src/base/abci/abcMiter.c
+1
-1
src/base/abci/abcPart.c
+513
-199
src/base/abci/abcVerify.c
+19
-11
src/base/main/main.h
+2
-2
src/base/main/mainFrame.c
+5
-4
src/base/main/mainInt.h
+1
-2
src/opt/lpk/lpkAbcDec.c
+13
-13
src/opt/lpk/lpkAbcDsd.c
+3
-3
src/opt/lpk/lpkAbcMux.c
+3
-3
src/opt/lpk/lpkAbcUtil.c
+2
-2
src/opt/lpk/lpkCore.c
+1
-1
src/opt/lpk/lpkInt.h
+29
-32
src/opt/lpk/module.make
+4
-0
No files found.
abc.dsp
View file @
b2470dd3
...
...
@@ -1542,7 +1542,7 @@ SOURCE=.\src\opt\lpk\lpk.h
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkAbc
Core
.c
SOURCE=.\src\opt\lpk\lpkAbc
Dec
.c
# End Source File
# Begin Source File
...
...
@@ -1550,11 +1550,11 @@ SOURCE=.\src\opt\lpk\lpkAbcDsd.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkAbc
Fun
.c
SOURCE=.\src\opt\lpk\lpkAbc
Mux
.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkAbc
Mux
.c
SOURCE=.\src\opt\lpk\lpkAbc
Util
.c
# End Source File
# Begin Source File
...
...
src/aig/aig/aig.h
View file @
b2470dd3
...
...
@@ -425,9 +425,9 @@ extern void Aig_ObjOrderInsert( Aig_Man_t * p, int ObjId );
extern
void
Aig_ObjOrderRemove
(
Aig_Man_t
*
p
,
int
ObjId
);
extern
void
Aig_ObjOrderAdvance
(
Aig_Man_t
*
p
);
/*=== aigPart.c =========================================================*/
extern
Vec_
Vec
_t
*
Aig_ManSupports
(
Aig_Man_t
*
pMan
);
extern
Vec_
Vec_t
*
Aig_ManPartitionSmart
(
Aig_Man_t
*
p
,
int
nPartSizeLimit
,
int
fVerbose
,
Vec_Vec
_t
**
pvPartSupps
);
extern
Vec_
Vec
_t
*
Aig_ManPartitionNaive
(
Aig_Man_t
*
p
,
int
nPartSize
);
extern
Vec_
Ptr
_t
*
Aig_ManSupports
(
Aig_Man_t
*
pMan
);
extern
Vec_
Ptr_t
*
Aig_ManPartitionSmart
(
Aig_Man_t
*
p
,
int
nPartSizeLimit
,
int
fVerbose
,
Vec_Ptr
_t
**
pvPartSupps
);
extern
Vec_
Ptr
_t
*
Aig_ManPartitionNaive
(
Aig_Man_t
*
p
,
int
nPartSize
);
/*=== aigRepr.c =========================================================*/
extern
void
Aig_ManReprStart
(
Aig_Man_t
*
p
,
int
nIdMax
);
extern
void
Aig_ManReprStop
(
Aig_Man_t
*
p
);
...
...
src/aig/aig/aigPart.c
View file @
b2470dd3
...
...
@@ -264,18 +264,23 @@ Vec_Int_t * Part_ManTransferEntry( Part_One_t * p )
SeeAlso []
***********************************************************************/
Vec_
Vec
_t
*
Aig_ManSupports
(
Aig_Man_t
*
pMan
)
Vec_
Ptr
_t
*
Aig_ManSupports
(
Aig_Man_t
*
pMan
)
{
Vec_
Vec_t
*
vSupp
s
;
Vec_
Ptr_t
*
vSupport
s
;
Vec_Int_t
*
vSupp
;
Part_Man_t
*
p
;
Part_One_t
*
pPart0
,
*
pPart1
;
Aig_Obj_t
*
pObj
;
int
i
,
iIns
=
0
,
iOut
=
0
;
int
i
;
// set the number of PIs/POs
Aig_ManForEachPi
(
pMan
,
pObj
,
i
)
pObj
->
pNext
=
(
Aig_Obj_t
*
)
i
;
Aig_ManForEachPo
(
pMan
,
pObj
,
i
)
pObj
->
pNext
=
(
Aig_Obj_t
*
)
i
;
// start the support computation manager
p
=
Part_ManStart
(
1
<<
20
,
1
<<
6
);
// consider objects in the topological order
vSupp
s
=
Vec_Vec
Alloc
(
Aig_ManPoNum
(
pMan
)
);
vSupp
orts
=
Vec_Ptr
Alloc
(
Aig_ManPoNum
(
pMan
)
);
Aig_ManCleanData
(
pMan
);
Aig_ManForEachObj
(
pMan
,
pObj
,
i
)
{
...
...
@@ -296,8 +301,8 @@ Vec_Vec_t * Aig_ManSupports( Aig_Man_t * pMan )
{
pPart0
=
Aig_ObjFanin0
(
pObj
)
->
pData
;
vSupp
=
Part_ManTransferEntry
(
pPart0
);
Vec_IntPush
(
vSupp
,
iOut
++
);
Vec_PtrPush
(
(
Vec_Ptr_t
*
)
vSupp
s
,
vSupp
);
Vec_IntPush
(
vSupp
,
(
int
)
pObj
->
pNext
);
Vec_PtrPush
(
vSupport
s
,
vSupp
);
assert
(
pPart0
->
nRefs
>
0
);
if
(
--
pPart0
->
nRefs
==
0
)
Part_ManRecycleEntry
(
p
,
pPart0
);
...
...
@@ -308,7 +313,7 @@ Vec_Vec_t * Aig_ManSupports( Aig_Man_t * pMan )
if
(
pObj
->
nRefs
)
{
pPart0
=
Part_ManFetchEntry
(
p
,
1
,
pObj
->
nRefs
);
pPart0
->
pOuts
[
pPart0
->
nOuts
++
]
=
iIns
++
;
pPart0
->
pOuts
[
pPart0
->
nOuts
++
]
=
(
int
)
pObj
->
pNext
;
pObj
->
pData
=
pPart0
;
}
continue
;
...
...
@@ -324,13 +329,18 @@ Vec_Vec_t * Aig_ManSupports( Aig_Man_t * pMan )
//printf( "Memory usage = %d Mb.\n", Vec_PtrSize(p->vMemory) * p->nChunkSize / (1<<20) );
Part_ManStop
(
p
);
// sort supports by size
Vec_VecSort
(
vSupps
,
1
);
Vec_VecSort
(
(
Vec_Vec_t
*
)
vSupports
,
1
);
// clear the number of PIs/POs
Aig_ManForEachPi
(
pMan
,
pObj
,
i
)
pObj
->
pNext
=
NULL
;
Aig_ManForEachPo
(
pMan
,
pObj
,
i
)
pObj
->
pNext
=
NULL
;
/*
Aig_ManForEachPo( pMan, pObj, i )
printf( "%d ", Vec_IntSize( (Vec_Int_t *)Vec_VecEntry(vSupps, i) ) );
printf( "%d ", Vec_IntSize( (Vec_Int_t *)Vec_VecEntry(vSupp
ort
s, i) ) );
printf( "\n" );
*/
return
vSupps
;
return
vSupp
ort
s
;
}
/**Function*************************************************************
...
...
@@ -344,16 +354,17 @@ Vec_Vec_t * Aig_ManSupports( Aig_Man_t * pMan )
SeeAlso []
***********************************************************************/
char
*
Aig_ManSuppCharStart
(
Vec_Int_t
*
vOne
,
int
nPis
)
unsigned
*
Aig_ManSuppCharStart
(
Vec_Int_t
*
vOne
,
int
nPis
)
{
char
*
pBuffer
;
unsigned
*
pBuffer
;
int
i
,
Entry
;
pBuffer
=
ALLOC
(
char
,
nPis
);
memset
(
pBuffer
,
0
,
sizeof
(
char
)
*
nPis
);
int
nWords
=
Aig_BitWordNum
(
nPis
);
pBuffer
=
ALLOC
(
unsigned
,
nWords
);
memset
(
pBuffer
,
0
,
sizeof
(
unsigned
)
*
nWords
);
Vec_IntForEachEntry
(
vOne
,
Entry
,
i
)
{
assert
(
Entry
<
nPis
);
pBuffer
[
Entry
]
=
1
;
Aig_InfoSetBit
(
pBuffer
,
Entry
)
;
}
return
pBuffer
;
}
...
...
@@ -369,13 +380,13 @@ char * Aig_ManSuppCharStart( Vec_Int_t * vOne, int nPis )
SeeAlso []
***********************************************************************/
void
Aig_ManSuppCharAdd
(
char
*
pBuffer
,
Vec_Int_t
*
vOne
,
int
nPis
)
void
Aig_ManSuppCharAdd
(
unsigned
*
pBuffer
,
Vec_Int_t
*
vOne
,
int
nPis
)
{
int
i
,
Entry
;
Vec_IntForEachEntry
(
vOne
,
Entry
,
i
)
{
assert
(
Entry
<
nPis
);
pBuffer
[
Entry
]
=
1
;
Aig_InfoSetBit
(
pBuffer
,
Entry
)
;
}
}
...
...
@@ -390,11 +401,11 @@ void Aig_ManSuppCharAdd( char * pBuffer, Vec_Int_t * vOne, int nPis )
SeeAlso []
***********************************************************************/
int
Aig_ManSuppCharCommon
(
char
*
pBuffer
,
Vec_Int_t
*
vOne
)
int
Aig_ManSuppCharCommon
(
unsigned
*
pBuffer
,
Vec_Int_t
*
vOne
)
{
int
i
,
Entry
,
nCommon
=
0
;
Vec_IntForEachEntry
(
vOne
,
Entry
,
i
)
nCommon
+=
pBuffer
[
Entry
]
;
nCommon
+=
Aig_InfoHasBit
(
pBuffer
,
Entry
)
;
return
nCommon
;
}
...
...
@@ -409,24 +420,27 @@ int Aig_ManSuppCharCommon( char * pBuffer, Vec_Int_t * vOne )
SeeAlso []
***********************************************************************/
int
Aig_ManPartitionSmartFindPart
(
Vec_Ptr_t
*
vPartSuppsAll
,
Vec_Ptr_t
*
vPartsAll
,
Vec_Ptr_t
*
vPartSupps
Char
,
int
nPart
SizeLimit
,
Vec_Int_t
*
vOne
)
int
Aig_ManPartitionSmartFindPart
(
Vec_Ptr_t
*
vPartSuppsAll
,
Vec_Ptr_t
*
vPartsAll
,
Vec_Ptr_t
*
vPartSupps
Bit
,
int
nSupp
SizeLimit
,
Vec_Int_t
*
vOne
)
{
Vec_Int_t
*
vPartSupp
,
*
vPart
;
Vec_Int_t
*
vPartSupp
;
//
, * vPart;
int
Attract
,
Repulse
,
Value
,
ValueBest
;
int
i
,
nCommon
,
iBest
;
iBest
=
-
1
;
ValueBest
=
0
;
Vec_PtrForEachEntry
(
vPartSuppsAll
,
vPartSupp
,
i
)
{
vPart
=
Vec_PtrEntry
(
vPartsAll
,
i
);
if
(
nPartSizeLimit
>
0
&&
Vec_IntSize
(
vPart
)
>=
nPart
SizeLimit
)
continue
;
//
vPart = Vec_PtrEntry( vPartsAll, i );
// if ( nSuppSizeLimit > 0 && Vec_IntSize(vPart) >= nSupp
SizeLimit )
//
continue;
// nCommon = Vec_IntTwoCountCommon( vPartSupp, vOne );
nCommon
=
Aig_ManSuppCharCommon
(
Vec_PtrEntry
(
vPartSupps
Char
,
i
),
vOne
);
nCommon
=
Aig_ManSuppCharCommon
(
Vec_PtrEntry
(
vPartSupps
Bit
,
i
),
vOne
);
if
(
nCommon
==
0
)
continue
;
if
(
nCommon
==
Vec_IntSize
(
vOne
)
)
return
i
;
// skip partitions whose size exceeds the limit
if
(
nSuppSizeLimit
>
0
&&
Vec_IntSize
(
vPartSupp
)
>=
2
*
nSuppSizeLimit
)
continue
;
Attract
=
1000
*
nCommon
/
Vec_IntSize
(
vOne
);
if
(
Vec_IntSize
(
vPartSupp
)
<
100
)
Repulse
=
1
;
...
...
@@ -484,20 +498,20 @@ void Aig_ManPartitionPrint( Aig_Man_t * p, Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vP
SeeAlso []
***********************************************************************/
void
Aig_ManPartitionCompact
(
Vec_Ptr_t
*
vPartsAll
,
Vec_Ptr_t
*
vPartSuppsAll
,
int
n
Part
SizeLimit
)
void
Aig_ManPartitionCompact
(
Vec_Ptr_t
*
vPartsAll
,
Vec_Ptr_t
*
vPartSuppsAll
,
int
n
Supp
SizeLimit
)
{
Vec_Int_t
*
vOne
,
*
vPart
,
*
vPartSupp
,
*
vTemp
;
int
i
,
iPart
;
if
(
n
Part
SizeLimit
==
0
)
n
Part
SizeLimit
=
200
;
if
(
n
Supp
SizeLimit
==
0
)
n
Supp
SizeLimit
=
200
;
// pack smaller partitions into larger blocks
iPart
=
0
;
vPart
=
vPartSupp
=
NULL
;
Vec_PtrForEachEntry
(
vPartSuppsAll
,
vOne
,
i
)
{
if
(
Vec_IntSize
(
vOne
)
<
n
Part
SizeLimit
)
if
(
Vec_IntSize
(
vOne
)
<
n
Supp
SizeLimit
)
{
if
(
vPartSupp
==
NULL
)
{
...
...
@@ -513,7 +527,7 @@ void Aig_ManPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll,
Vec_IntFree
(
vTemp
);
Vec_IntFree
(
Vec_PtrEntry
(
vPartsAll
,
i
)
);
}
if
(
Vec_IntSize
(
vPartSupp
)
<
n
Part
SizeLimit
)
if
(
Vec_IntSize
(
vPartSupp
)
<
n
Supp
SizeLimit
)
continue
;
}
else
...
...
@@ -556,34 +570,33 @@ void Aig_ManPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll,
SeeAlso []
***********************************************************************/
Vec_
Vec_t
*
Aig_ManPartitionSmart
(
Aig_Man_t
*
p
,
int
nPartSizeLimit
,
int
fVerbose
,
Vec_Vec
_t
**
pvPartSupps
)
Vec_
Ptr_t
*
Aig_ManPartitionSmart
(
Aig_Man_t
*
p
,
int
nSuppSizeLimit
,
int
fVerbose
,
Vec_Ptr
_t
**
pvPartSupps
)
{
Vec_Ptr_t
*
vPartSupps
Char
;
Vec_Ptr_t
*
vSupps
,
*
vPartsAll
,
*
vPartsAll2
,
*
vPartSuppsAll
;
//, * vPartPtr;
Vec_Ptr_t
*
vPartSupps
Bit
;
Vec_Ptr_t
*
vSupp
ort
s
,
*
vPartsAll
,
*
vPartsAll2
,
*
vPartSuppsAll
;
//, * vPartPtr;
Vec_Int_t
*
vOne
,
*
vPart
,
*
vPartSupp
,
*
vTemp
;
int
i
,
iPart
,
iOut
,
clk
;
// compute the supports for all outputs
clk
=
clock
();
vSupp
s
=
(
Vec_Ptr_t
*
)
Aig_ManSupports
(
p
);
vSupp
orts
=
Aig_ManSupports
(
p
);
if
(
fVerbose
)
{
PRT
(
"Supps"
,
clock
()
-
clk
);
}
// start char-based support representation
vPartSupps
Char
=
Vec_PtrAlloc
(
1000
);
vPartSupps
Bit
=
Vec_PtrAlloc
(
1000
);
// create partitions
clk
=
clock
();
vPartsAll
=
Vec_PtrAlloc
(
256
);
vPartSuppsAll
=
Vec_PtrAlloc
(
256
);
Vec_PtrForEachEntry
(
vSupps
,
vOne
,
i
)
Vec_PtrForEachEntry
(
vSupp
ort
s
,
vOne
,
i
)
{
// get the output number
iOut
=
Vec_IntPop
(
vOne
);
// find closely matching part
iPart
=
Aig_ManPartitionSmartFindPart
(
vPartSuppsAll
,
vPartsAll
,
vPartSuppsChar
,
nPartSizeLimit
,
vOne
);
//printf( "%4d->%4d ", i, iPart );
iPart
=
Aig_ManPartitionSmartFindPart
(
vPartSuppsAll
,
vPartsAll
,
vPartSuppsBit
,
nSuppSizeLimit
,
vOne
);
if
(
iPart
==
-
1
)
{
// create new partition
...
...
@@ -595,7 +608,7 @@ clk = clock();
Vec_PtrPush
(
vPartsAll
,
vPart
);
Vec_PtrPush
(
vPartSuppsAll
,
vPartSupp
);
Vec_PtrPush
(
vPartSupps
Char
,
Aig_ManSuppCharStart
(
vOne
,
Aig_ManPiNum
(
p
))
);
Vec_PtrPush
(
vPartSupps
Bit
,
Aig_ManSuppCharStart
(
vOne
,
Aig_ManPiNum
(
p
))
);
}
else
{
...
...
@@ -609,14 +622,14 @@ clk = clock();
// reinsert new support
Vec_PtrWriteEntry
(
vPartSuppsAll
,
iPart
,
vPartSupp
);
Aig_ManSuppCharAdd
(
Vec_PtrEntry
(
vPartSupps
Char
,
iPart
),
vOne
,
Aig_ManPiNum
(
p
)
);
Aig_ManSuppCharAdd
(
Vec_PtrEntry
(
vPartSupps
Bit
,
iPart
),
vOne
,
Aig_ManPiNum
(
p
)
);
}
}
// stop char-based support representation
Vec_PtrForEachEntry
(
vPartSupps
Char
,
vTemp
,
i
)
Vec_PtrForEachEntry
(
vPartSupps
Bit
,
vTemp
,
i
)
free
(
vTemp
);
Vec_PtrFree
(
vPartSupps
Char
);
Vec_PtrFree
(
vPartSupps
Bit
);
//printf( "\n" );
if
(
fVerbose
)
...
...
@@ -640,7 +653,7 @@ clk = clock();
// compact small partitions
// Aig_ManPartitionPrint( p, vPartsAll, vPartSuppsAll );
Aig_ManPartitionCompact
(
vPartsAll
,
vPartSuppsAll
,
n
Part
SizeLimit
);
Aig_ManPartitionCompact
(
vPartsAll
,
vPartSuppsAll
,
n
Supp
SizeLimit
);
if
(
fVerbose
)
// Aig_ManPartitionPrint( p, vPartsAll, vPartSuppsAll );
printf
(
"Created %d partitions.
\n
"
,
Vec_PtrSize
(
vPartsAll
)
);
...
...
@@ -651,11 +664,11 @@ if ( fVerbose )
}
// cleanup
Vec_VecFree
(
(
Vec_Vec_t
*
)
vSupps
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vSupp
ort
s
);
if
(
pvPartSupps
==
NULL
)
Vec_VecFree
(
(
Vec_Vec_t
*
)
vPartSuppsAll
);
else
*
pvPartSupps
=
(
Vec_Vec_t
*
)
vPartSuppsAll
;
*
pvPartSupps
=
vPartSuppsAll
;
/*
// converts from intergers to nodes
Vec_PtrForEachEntry( vPartsAll, vPart, iPart )
...
...
@@ -667,7 +680,7 @@ if ( fVerbose )
Vec_PtrWriteEntry( vPartsAll, iPart, vPartPtr );
}
*/
return
(
Vec_Vec_t
*
)
vPartsAll
;
return
vPartsAll
;
}
/**Function*************************************************************
...
...
@@ -681,15 +694,15 @@ if ( fVerbose )
SeeAlso []
***********************************************************************/
Vec_
Vec
_t
*
Aig_ManPartitionNaive
(
Aig_Man_t
*
p
,
int
nPartSize
)
Vec_
Ptr
_t
*
Aig_ManPartitionNaive
(
Aig_Man_t
*
p
,
int
nPartSize
)
{
Vec_
Vec
_t
*
vParts
;
Vec_
Ptr
_t
*
vParts
;
Aig_Obj_t
*
pObj
;
int
nParts
,
i
;
nParts
=
(
Aig_ManPoNum
(
p
)
/
nPartSize
)
+
((
Aig_ManPoNum
(
p
)
%
nPartSize
)
>
0
);
vParts
=
Vec_VecStart
(
nParts
);
vParts
=
(
Vec_Ptr_t
*
)
Vec_VecStart
(
nParts
);
Aig_ManForEachPo
(
p
,
pObj
,
i
)
Vec_
VecPush
(
vParts
,
i
/
nPartSize
,
pObj
);
Vec_
IntPush
(
Vec_PtrEntry
(
vParts
,
i
/
nPartSize
),
i
);
return
vParts
;
}
...
...
@@ -787,18 +800,18 @@ Vec_Ptr_t * Aig_ManMiterPartitioned( Aig_Man_t * p1, Aig_Man_t * p2, int nPartSi
Aig_Man_t
*
pNew
;
Aig_Obj_t
*
pMiter
;
Vec_Ptr_t
*
vMiters
,
*
vNodes1
,
*
vNodes2
;
Vec_
Vec
_t
*
vParts
,
*
vPartSupps
;
Vec_
Ptr
_t
*
vParts
,
*
vPartSupps
;
Vec_Int_t
*
vPart
,
*
vPartSupp
;
int
i
,
k
;
// partition the first manager
vParts
=
Aig_ManPartitionSmart
(
p1
,
nPartSize
,
0
,
&
vPartSupps
);
// derive miters
vMiters
=
Vec_PtrAlloc
(
Vec_
Vec
Size
(
vParts
)
);
for
(
i
=
0
;
i
<
Vec_
Vec
Size
(
vParts
);
i
++
)
vMiters
=
Vec_PtrAlloc
(
Vec_
Ptr
Size
(
vParts
)
);
for
(
i
=
0
;
i
<
Vec_
Ptr
Size
(
vParts
);
i
++
)
{
// get partitions and their support
vPart
=
Vec_PtrEntry
(
(
Vec_Ptr_t
*
)
vParts
,
i
);
vPartSupp
=
Vec_PtrEntry
(
(
Vec_Ptr_t
*
)
vPartSupps
,
i
);
vPart
=
Vec_PtrEntry
(
vParts
,
i
);
vPartSupp
=
Vec_PtrEntry
(
vPartSupps
,
i
);
// create the new miter
pNew
=
Aig_ManStart
(
1000
);
// create the PIs
...
...
@@ -815,8 +828,8 @@ Vec_Ptr_t * Aig_ManMiterPartitioned( Aig_Man_t * p1, Aig_Man_t * p2, int nPartSi
Aig_ManCleanup
(
pNew
);
Vec_PtrPush
(
vMiters
,
pNew
);
}
Vec_VecFree
(
vParts
);
Vec_VecFree
(
vPartSupps
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vParts
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vPartSupps
);
return
vMiters
;
}
...
...
@@ -837,7 +850,7 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize )
Aig_Man_t
*
pChoice
,
*
pNew
,
*
pAig
,
*
p
;
Aig_Obj_t
*
pObj
;
Vec_Ptr_t
*
vMiters
,
*
vNodes
;
Vec_
Vec
_t
*
vParts
,
*
vPartSupps
;
Vec_
Ptr
_t
*
vParts
,
*
vPartSupps
;
Vec_Int_t
*
vPart
,
*
vPartSupp
;
int
i
,
k
,
m
;
...
...
@@ -847,12 +860,12 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize )
vParts
=
Aig_ManPartitionSmart
(
pAig
,
nPartSize
,
0
,
&
vPartSupps
);
// derive the AIG partitions
vMiters
=
Vec_PtrAlloc
(
Vec_
Vec
Size
(
vParts
)
);
for
(
i
=
0
;
i
<
Vec_
Vec
Size
(
vParts
);
i
++
)
vMiters
=
Vec_PtrAlloc
(
Vec_
Ptr
Size
(
vParts
)
);
for
(
i
=
0
;
i
<
Vec_
Ptr
Size
(
vParts
);
i
++
)
{
// get partitions and their support
vPart
=
Vec_PtrEntry
(
(
Vec_Ptr_t
*
)
vParts
,
i
);
vPartSupp
=
Vec_PtrEntry
(
(
Vec_Ptr_t
*
)
vPartSupps
,
i
);
vPart
=
Vec_PtrEntry
(
vParts
,
i
);
vPartSupp
=
Vec_PtrEntry
(
vPartSupps
,
i
);
// create the new miter
pNew
=
Aig_ManStart
(
1000
);
// create the PIs
...
...
@@ -884,13 +897,13 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize )
Vec_PtrForEachEntry
(
vMiters
,
p
,
i
)
{
// get partitions and their support
vPart
=
Vec_PtrEntry
(
(
Vec_Ptr_t
*
)
vParts
,
i
);
vPartSupp
=
Vec_PtrEntry
(
(
Vec_Ptr_t
*
)
vPartSupps
,
i
);
vPart
=
Vec_PtrEntry
(
vParts
,
i
);
vPartSupp
=
Vec_PtrEntry
(
vPartSupps
,
i
);
// copy the component
vNodes
=
Aig_ManDupPart
(
pNew
,
p
,
vPart
,
vPartSupp
,
1
);
assert
(
Vec_PtrSize
(
vNodes
)
==
Vec_
Vec
Size
(
vParts
)
*
Vec_PtrSize
(
vAigs
)
);
assert
(
Vec_PtrSize
(
vNodes
)
==
Vec_
Ptr
Size
(
vParts
)
*
Vec_PtrSize
(
vAigs
)
);
// create choice node
for
(
k
=
0
;
k
<
Vec_
Vec
Size
(
vParts
);
k
++
)
for
(
k
=
0
;
k
<
Vec_
Ptr
Size
(
vParts
);
k
++
)
{
for
(
m
=
0
;
m
<
Vec_PtrSize
(
vAigs
);
m
++
)
{
...
...
@@ -901,8 +914,8 @@ Aig_Man_t * Aig_ManChoicePartitioned( Vec_Ptr_t * vAigs, int nPartSize )
}
Vec_PtrFree
(
vNodes
);
}
Vec_VecFree
(
vParts
);
Vec_VecFree
(
vPartSupps
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vParts
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vPartSupps
);
// trasfer representatives
Aig_ManReprStart
(
pNew
,
Aig_ManObjIdMax
(
pNew
)
+
1
);
...
...
src/aig/fra/fraPart.c
View file @
b2470dd3
...
...
@@ -58,7 +58,7 @@ void Fra_ManPartitionTest( Aig_Man_t * p, int nComLim )
// compute supports
clk
=
clock
();
vSupps
=
Aig_ManSupports
(
p
);
vSupps
=
(
Vec_Vec_t
*
)
Aig_ManSupports
(
p
);
PRT
(
"Supports"
,
clock
()
-
clk
);
// remove last entry
Aig_ManForEachPo
(
p
,
pObj
,
i
)
...
...
@@ -192,7 +192,7 @@ void Fra_ManPartitionTest2( Aig_Man_t * p )
// compute supports
clk
=
clock
();
vSupps
=
Aig_ManSupports
(
p
);
vSupps
=
(
Vec_Vec_t
*
)
Aig_ManSupports
(
p
);
PRT
(
"Supports"
,
clock
()
-
clk
);
// remove last entry
Aig_ManForEachPo
(
p
,
pObj
,
i
)
...
...
src/base/abc/abc.h
View file @
b2470dd3
...
...
@@ -729,6 +729,7 @@ extern void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk );
extern
Abc_Ntk_t
*
Abc_NtkDup
(
Abc_Ntk_t
*
pNtk
);
extern
Abc_Ntk_t
*
Abc_NtkCreateCone
(
Abc_Ntk_t
*
pNtk
,
Abc_Obj_t
*
pNode
,
char
*
pNodeName
,
int
fUseAllCis
);
extern
Abc_Ntk_t
*
Abc_NtkCreateConeArray
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vRoots
,
int
fUseAllCis
);
extern
void
Abc_NtkAppendToCone
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vRoots
);
extern
Abc_Ntk_t
*
Abc_NtkCreateMffc
(
Abc_Ntk_t
*
pNtk
,
Abc_Obj_t
*
pNode
,
char
*
pNodeName
);
extern
Abc_Ntk_t
*
Abc_NtkCreateTarget
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vRoots
,
Vec_Int_t
*
vValues
);
extern
Abc_Ntk_t
*
Abc_NtkCreateFromNode
(
Abc_Ntk_t
*
pNtk
,
Abc_Obj_t
*
pNode
);
...
...
src/base/abc/abcNtk.c
View file @
b2470dd3
...
...
@@ -623,7 +623,7 @@ Abc_Ntk_t * Abc_NtkCreateConeArray( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, int fU
}
Vec_PtrFree
(
vNodes
);
// add the PO
corresponding to the
nodes
// add the PO
s corresponding to the root
nodes
Vec_PtrForEachEntry
(
vRoots
,
pObj
,
i
)
{
// create the PO node
...
...
@@ -644,6 +644,59 @@ Abc_Ntk_t * Abc_NtkCreateConeArray( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, int fU
/**Function*************************************************************
Synopsis [Adds new nodes to the cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkAppendToCone
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vRoots
)
{
Vec_Ptr_t
*
vNodes
;
Abc_Obj_t
*
pObj
;
int
i
,
iNodeId
;
assert
(
Abc_NtkIsStrash
(
pNtkNew
)
);
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
// collect the nodes in the TFI of the output (mark the TFI)
vNodes
=
Abc_NtkDfsNodes
(
pNtk
,
(
Abc_Obj_t
**
)
Vec_PtrArray
(
vRoots
),
Vec_PtrSize
(
vRoots
)
);
// establish connection between the constant nodes
Abc_AigConst1
(
pNtk
)
->
pCopy
=
Abc_AigConst1
(
pNtkNew
);
// create the PIs
Abc_NtkForEachCi
(
pNtk
,
pObj
,
i
)
{
// skip CIs that are not used
if
(
!
Abc_NodeIsTravIdCurrent
(
pObj
)
)
continue
;
// find the corresponding CI in the new network
iNodeId
=
Nm_ManFindIdByNameTwoTypes
(
pNtkNew
->
pManName
,
Abc_ObjName
(
pObj
),
ABC_OBJ_PI
,
ABC_OBJ_BO
);
if
(
iNodeId
==
-
1
)
{
pObj
->
pCopy
=
Abc_NtkCreatePi
(
pNtkNew
);
Abc_ObjAssignName
(
pObj
->
pCopy
,
Abc_ObjName
(
pObj
),
NULL
);
}
else
pObj
->
pCopy
=
Abc_NtkObj
(
pNtkNew
,
iNodeId
);
}
// copy the nodes
Vec_PtrForEachEntry
(
vNodes
,
pObj
,
i
)
pObj
->
pCopy
=
Abc_AigAnd
(
pNtkNew
->
pManFunc
,
Abc_ObjChild0Copy
(
pObj
),
Abc_ObjChild1Copy
(
pObj
)
);
Vec_PtrFree
(
vNodes
);
// do not add the COs
if
(
!
Abc_NtkCheck
(
pNtkNew
)
)
fprintf
(
stdout
,
"Abc_NtkAppendToCone(): Network check has failed.
\n
"
);
}
/**Function*************************************************************
Synopsis [Creates the network composed of MFFC of one node.]
Description []
...
...
src/base/abci/abc.c
View file @
b2470dd3
...
...
@@ -2977,6 +2977,9 @@ int Abc_CommandLutpack( Abc_Frame_t * pAbc, int argc, char ** argv )
pOut
=
Abc_FrameReadOut
(
pAbc
);
pErr
=
Abc_FrameReadErr
(
pAbc
);
printf
(
"This command will be available soon
\n
"
);
return
0
;
// set defaults
memset
(
pPars
,
0
,
sizeof
(
Lpk_Par_t
)
);
pPars
->
nLutsMax
=
4
;
// (N) the maximum number of LUTs in the structure
...
...
src/base/abci/abcFraig.c
View file @
b2470dd3
...
...
@@ -648,46 +648,32 @@ Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
int
Abc_NtkFraigStore
(
Abc_Ntk_t
*
pNtk
)
int
Abc_NtkFraigStore
(
Abc_Ntk_t
*
pNtk
Add
)
{
Abc_Ntk_t
*
pStore
;
int
nAndsOld
;
if
(
!
Abc_NtkIsLogic
(
pNtk
)
&&
!
Abc_NtkIsStrash
(
pNtk
)
)
Vec_Ptr_t
*
vStore
;
Abc_Ntk_t
*
pNtk
;
// create the network to be stored
pNtk
=
Abc_NtkStrash
(
pNtkAdd
,
0
,
0
,
0
);
if
(
pNtk
==
NULL
)
{
printf
(
"
The netlist need to be converted into a logic network before adding it to storage
.
\n
"
);
printf
(
"
Abc_NtkFraigStore: Initial strashing has failed
.
\n
"
);
return
0
;
}
// get the network currently stored
pStore
=
Abc_FrameReadNtk
Store
();
if
(
pStore
==
NULL
)
vStore
=
Abc_FrameRead
Store
();
if
(
Vec_PtrSize
(
vStore
)
>
0
)
{
//
start the stored network
pStore
=
Abc_NtkStrash
(
pNtk
,
0
,
0
,
0
);
if
(
pStore
==
NULL
)
//
check that the networks have the same PIs
// reorder PIs of pNtk2 according to pNtk1
if
(
!
Abc_NtkCompareSignals
(
pNtk
,
Vec_PtrEntry
(
vStore
,
0
),
1
,
1
)
)
{
printf
(
"Abc_NtkFraigStore: Initial strashing has failed.
\n
"
);
return
0
;
printf
(
"Trying to store the network with different primary inputs.
\n
"
);
printf
(
"The previously stored networks are deleted and this one is added.
\n
"
);
Abc_NtkFraigStoreClean
();
}
// save the parameters
Abc_FrameSetNtkStore
(
pStore
);
Abc_FrameSetNtkStoreSize
(
1
);
nAndsOld
=
0
;
}
else
{
// add the new network to storage
nAndsOld
=
Abc_NtkNodeNum
(
pStore
);
if
(
!
Abc_NtkAppend
(
pStore
,
pNtk
,
0
)
)
{
printf
(
"The current network cannot be appended to the stored network.
\n
"
);
return
0
;
}
// set the number of networks stored
Abc_FrameSetNtkStoreSize
(
Abc_FrameReadNtkStoreSize
()
+
1
);
}
printf
(
"The number of AIG nodes added to storage = %5d.
\n
"
,
Abc_NtkNodeNum
(
pStore
)
-
nAndsOld
);
Vec_PtrPush
(
vStore
,
pNtk
);
printf
(
"The number of AIG nodes added to storage = %5d.
\n
"
,
Abc_NtkNodeNum
(
pNtk
)
);
return
1
;
}
...
...
@@ -704,54 +690,48 @@ int Abc_NtkFraigStore( Abc_Ntk_t * pNtk )
***********************************************************************/
Abc_Ntk_t
*
Abc_NtkFraigRestore
()
{
extern
Abc_Ntk_t
*
Abc_NtkFraigPartitioned
(
Abc_Ntk_t
*
pNtk
,
void
*
pParams
);
extern
Abc_Ntk_t
*
Abc_NtkFraigPartitioned
(
Vec_Ptr_t
*
vStore
,
void
*
pParams
);
Fraig_Params_t
Params
;
Abc_Ntk_t
*
pStore
,
*
pFraig
;
Vec_Ptr_t
*
vStore
;
Abc_Ntk_t
*
pNtk
,
*
pFraig
;
int
nWords1
,
nWords2
,
nWordsMin
;
int
clk
=
clock
();
// get the stored network
pStore
=
Abc_FrameReadNtkStore
();
Abc_FrameSetNtkStore
(
NULL
);
if
(
pStore
==
NULL
)
vStore
=
Abc_FrameReadStore
();
if
(
Vec_PtrSize
(
vStore
)
==
0
)
{
printf
(
"There are no network currently in storage.
\n
"
);
return
NULL
;
}
printf
(
"Currently stored %d networks wi
th %d nodes will be fraiged.
\n
"
,
Abc_FrameReadNtkStoreSize
(),
Abc_NtkNodeNum
(
pStore
)
);
printf
(
"Currently stored %d networks wi
ll be fraiged.
\n
"
,
Vec_PtrSize
(
vStore
)
);
pNtk
=
Vec_PtrEntry
(
vStore
,
0
);
// to determine the number of simulation patterns
// use the following strategy
// at least 64 words (32 words random and 32 words dynamic)
// no more than 256M for one circuit (128M + 128M)
nWords1
=
32
;
nWords2
=
(
1
<<
27
)
/
(
Abc_NtkNodeNum
(
p
Store
)
+
Abc_NtkCiNum
(
pStore
));
nWords2
=
(
1
<<
27
)
/
(
Abc_NtkNodeNum
(
p
Ntk
)
+
Abc_NtkCiNum
(
pNtk
));
nWordsMin
=
ABC_MIN
(
nWords1
,
nWords2
);
// set parameters for fraiging
Fraig_ParamsSetDefault
(
&
Params
);
Params
.
nPatsRand
=
nWordsMin
*
32
;
// the number of words of random simulation info
Params
.
nPatsDyna
=
nWordsMin
*
32
;
// the number of words of dynamic simulation info
Params
.
nBTLimit
=
999999
;
// the max number of backtracks to perform
Params
.
fFuncRed
=
1
;
// performs only one level hashing
Params
.
fFeedBack
=
1
;
// enables solver feedback
Params
.
fDist1Pats
=
1
;
// enables distance-1 patterns
Params
.
fDoSparse
=
1
;
// performs equiv tests for sparse functions
Params
.
fChoicing
=
1
;
// enables recording structural choices
Params
.
fTryProve
=
0
;
// tries to solve the final miter
Params
.
fVerbose
=
0
;
// the verbosiness flag
// Fraig_ManReportChoices( p );
// transform it into FRAIG
// pFraig = Abc_NtkFraig( pStore, &Params, 1, 0 );
pFraig
=
Abc_NtkFraigPartitioned
(
pStore
,
&
Params
);
PRT
(
"Total fraiging time"
,
clock
()
-
clk
);
if
(
pFraig
==
NULL
)
return
NULL
;
Abc_NtkDelete
(
pStore
);
Params
.
nPatsRand
=
nWordsMin
*
32
;
// the number of words of random simulation info
Params
.
nPatsDyna
=
nWordsMin
*
32
;
// the number of words of dynamic simulation info
Params
.
nBTLimit
=
1000
;
// the max number of backtracks to perform
Params
.
fFuncRed
=
1
;
// performs only one level hashing
Params
.
fFeedBack
=
1
;
// enables solver feedback
Params
.
fDist1Pats
=
1
;
// enables distance-1 patterns
Params
.
fDoSparse
=
1
;
// performs equiv tests for sparse functions
Params
.
fChoicing
=
1
;
// enables recording structural choices
Params
.
fTryProve
=
0
;
// tries to solve the final miter
Params
.
fVerbose
=
0
;
// the verbosiness flag
// perform partitioned computation of structural choices
pFraig
=
Abc_NtkFraigPartitioned
(
vStore
,
&
Params
);
Abc_NtkFraigStoreClean
();
PRT
(
"Total choicing time"
,
clock
()
-
clk
);
return
pFraig
;
}
...
...
@@ -768,12 +748,13 @@ PRT( "Total fraiging time", clock() - clk );
***********************************************************************/
void
Abc_NtkFraigStoreClean
()
{
Abc_Ntk_t
*
pStore
;
// get the stored network
pStore
=
Abc_FrameReadNtkStore
();
if
(
pStore
)
Abc_NtkDelete
(
pStore
);
Abc_FrameSetNtkStore
(
NULL
);
Vec_Ptr_t
*
vStore
;
Abc_Ntk_t
*
pNtk
;
int
i
;
vStore
=
Abc_FrameReadStore
();
Vec_PtrForEachEntry
(
vStore
,
pNtk
,
i
)
Abc_NtkDelete
(
pNtk
);
Vec_PtrClear
(
vStore
);
}
/**Function*************************************************************
...
...
@@ -794,7 +775,7 @@ void Abc_NtkFraigStoreCheck( Abc_Ntk_t * pFraig )
int
i
,
k
;
// check that the PO functions are correct
nPoFinal
=
Abc_NtkPoNum
(
pFraig
);
nStored
=
Abc_FrameRead
Ntk
StoreSize
();
nStored
=
Abc_FrameReadStoreSize
();
assert
(
nPoFinal
%
nStored
==
0
);
nPoOrig
=
nPoFinal
/
nStored
;
for
(
i
=
0
;
i
<
nPoOrig
;
i
++
)
...
...
src/base/abci/abcMiter.c
View file @
b2470dd3
...
...
@@ -314,7 +314,7 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt
Abc_ObjAddFanin
(
pNode
,
pMiter
);
// assign the name to the node
if
(
nPartSize
==
1
)
sprintf
(
Buffer
,
"%s"
,
Abc_ObjName
(
Abc_Ntk
P
o
(
pNtk1
,
i
))
);
sprintf
(
Buffer
,
"%s"
,
Abc_ObjName
(
Abc_Ntk
C
o
(
pNtk1
,
i
))
);
else
sprintf
(
Buffer
,
"%d"
,
i
);
Abc_ObjAssignName
(
pNode
,
"miter_"
,
Buffer
);
...
...
src/base/abci/abcPart.c
View file @
b2470dd3
...
...
@@ -24,13 +24,238 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef
struct
Supp_Man_t_
Supp_Man_t
;
struct
Supp_Man_t_
{
int
nChunkSize
;
// the size of one chunk of memory (~1 Mb)
int
nStepSize
;
// the step size in saving memory (~64 bytes)
char
*
pFreeBuf
;
// the pointer to free memory
int
nFreeSize
;
// the size of remaining free memory
Vec_Ptr_t
*
vMemory
;
// the memory allocated
Vec_Ptr_t
*
vFree
;
// the vector of free pieces of memory
};
typedef
struct
Supp_One_t_
Supp_One_t
;
struct
Supp_One_t_
{
int
nRefs
;
// the number of references
int
nOuts
;
// the number of outputs
int
nOutsAlloc
;
// the array size
int
pOuts
[
0
];
// the array of outputs
};
static
inline
int
Supp_SizeType
(
int
nSize
,
int
nStepSize
)
{
return
nSize
/
nStepSize
+
((
nSize
%
nStepSize
)
>
0
);
}
static
inline
char
*
Supp_OneNext
(
char
*
pPart
)
{
return
*
((
char
**
)
pPart
);
}
static
inline
void
Supp_OneSetNext
(
char
*
pPart
,
char
*
pNext
)
{
*
((
char
**
)
pPart
)
=
pNext
;
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Prepare supports.]
Synopsis [Start the memory manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Supp_Man_t
*
Supp_ManStart
(
int
nChunkSize
,
int
nStepSize
)
{
Supp_Man_t
*
p
;
p
=
ALLOC
(
Supp_Man_t
,
1
);
memset
(
p
,
0
,
sizeof
(
Supp_Man_t
)
);
p
->
nChunkSize
=
nChunkSize
;
p
->
nStepSize
=
nStepSize
;
p
->
vMemory
=
Vec_PtrAlloc
(
1000
);
p
->
vFree
=
Vec_PtrAlloc
(
1000
);
return
p
;
}
/**Function*************************************************************
Synopsis [Stops the memory manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Supp_ManStop
(
Supp_Man_t
*
p
)
{
void
*
pMemory
;
int
i
;
Vec_PtrForEachEntry
(
p
->
vMemory
,
pMemory
,
i
)
free
(
pMemory
);
Vec_PtrFree
(
p
->
vMemory
);
Vec_PtrFree
(
p
->
vFree
);
free
(
p
);
}
/**Function*************************************************************
Synopsis [Fetches the memory entry of the given size.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char
*
Supp_ManFetch
(
Supp_Man_t
*
p
,
int
nSize
)
{
int
Type
,
nSizeReal
;
char
*
pMemory
;
assert
(
nSize
>
0
);
Type
=
Supp_SizeType
(
nSize
,
p
->
nStepSize
);
Vec_PtrFillExtra
(
p
->
vFree
,
Type
+
1
,
NULL
);
if
(
pMemory
=
Vec_PtrEntry
(
p
->
vFree
,
Type
)
)
{
Vec_PtrWriteEntry
(
p
->
vFree
,
Type
,
Supp_OneNext
(
pMemory
)
);
return
pMemory
;
}
nSizeReal
=
p
->
nStepSize
*
Type
;
if
(
p
->
nFreeSize
<
nSizeReal
)
{
p
->
pFreeBuf
=
ALLOC
(
char
,
p
->
nChunkSize
);
p
->
nFreeSize
=
p
->
nChunkSize
;
Vec_PtrPush
(
p
->
vMemory
,
p
->
pFreeBuf
);
}
assert
(
p
->
nFreeSize
>=
nSizeReal
);
pMemory
=
p
->
pFreeBuf
;
p
->
pFreeBuf
+=
nSizeReal
;
p
->
nFreeSize
-=
nSizeReal
;
return
pMemory
;
}
/**Function*************************************************************
Synopsis [Recycles the memory entry of the given size.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Supp_ManRecycle
(
Supp_Man_t
*
p
,
char
*
pMemory
,
int
nSize
)
{
int
Type
;
Type
=
Supp_SizeType
(
nSize
,
p
->
nStepSize
);
Vec_PtrFillExtra
(
p
->
vFree
,
Type
+
1
,
NULL
);
Supp_OneSetNext
(
pMemory
,
Vec_PtrEntry
(
p
->
vFree
,
Type
)
);
Vec_PtrWriteEntry
(
p
->
vFree
,
Type
,
pMemory
);
}
/**Function*************************************************************
Synopsis [Fetches the memory entry of the given size.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
Supp_One_t
*
Supp_ManFetchEntry
(
Supp_Man_t
*
p
,
int
nWords
,
int
nRefs
)
{
Supp_One_t
*
pPart
;
pPart
=
(
Supp_One_t
*
)
Supp_ManFetch
(
p
,
sizeof
(
Supp_One_t
)
+
sizeof
(
int
)
*
nWords
);
pPart
->
nRefs
=
nRefs
;
pPart
->
nOuts
=
0
;
pPart
->
nOutsAlloc
=
nWords
;
return
pPart
;
}
/**Function*************************************************************
Synopsis [Recycles the memory entry of the given size.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
void
Supp_ManRecycleEntry
(
Supp_Man_t
*
p
,
Supp_One_t
*
pEntry
)
{
assert
(
pEntry
->
nOuts
<=
pEntry
->
nOutsAlloc
);
assert
(
pEntry
->
nOuts
>=
pEntry
->
nOutsAlloc
/
2
);
Supp_ManRecycle
(
p
,
(
char
*
)
pEntry
,
sizeof
(
Supp_One_t
)
+
sizeof
(
int
)
*
pEntry
->
nOutsAlloc
);
}
/**Function*************************************************************
Synopsis [Merges two entries.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Supp_One_t
*
Supp_ManMergeEntry
(
Supp_Man_t
*
pMan
,
Supp_One_t
*
p1
,
Supp_One_t
*
p2
,
int
nRefs
)
{
Supp_One_t
*
p
=
Supp_ManFetchEntry
(
pMan
,
p1
->
nOuts
+
p2
->
nOuts
,
nRefs
);
int
*
pBeg1
=
p1
->
pOuts
;
int
*
pBeg2
=
p2
->
pOuts
;
int
*
pBeg
=
p
->
pOuts
;
int
*
pEnd1
=
p1
->
pOuts
+
p1
->
nOuts
;
int
*
pEnd2
=
p2
->
pOuts
+
p2
->
nOuts
;
while
(
pBeg1
<
pEnd1
&&
pBeg2
<
pEnd2
)
{
if
(
*
pBeg1
==
*
pBeg2
)
*
pBeg
++
=
*
pBeg1
++
,
pBeg2
++
;
else
if
(
*
pBeg1
<
*
pBeg2
)
*
pBeg
++
=
*
pBeg1
++
;
else
*
pBeg
++
=
*
pBeg2
++
;
}
while
(
pBeg1
<
pEnd1
)
*
pBeg
++
=
*
pBeg1
++
;
while
(
pBeg2
<
pEnd2
)
*
pBeg
++
=
*
pBeg2
++
;
p
->
nOuts
=
pBeg
-
p
->
pOuts
;
assert
(
p
->
nOuts
<=
p
->
nOutsAlloc
);
assert
(
p
->
nOuts
>=
p1
->
nOuts
);
assert
(
p
->
nOuts
>=
p2
->
nOuts
);
return
p
;
}
/**Function*************************************************************
Synopsis [Tranfers the entry.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t
*
Supp_ManTransferEntry
(
Supp_One_t
*
p
)
{
Vec_Int_t
*
vSupp
;
int
i
;
vSupp
=
Vec_IntAlloc
(
p
->
nOuts
);
for
(
i
=
0
;
i
<
p
->
nOuts
;
i
++
)
Vec_IntPush
(
vSupp
,
p
->
pOuts
[
i
]
);
return
vSupp
;
}
/**Function*************************************************************
Synopsis [Computes supports of the POs in the multi-output AIG.]
Description []
...
...
@@ -39,7 +264,152 @@
SeeAlso []
***********************************************************************/
Vec_Ptr_t
*
Abc_NtkPartitionCollectSupps
(
Abc_Ntk_t
*
pNtk
)
Vec_Ptr_t
*
Abc_NtkDfsNatural
(
Abc_Ntk_t
*
pNtk
)
{
Vec_Ptr_t
*
vNodes
;
Abc_Obj_t
*
pObj
,
*
pNext
;
int
i
,
k
;
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
vNodes
=
Vec_PtrAlloc
(
Abc_NtkObjNum
(
pNtk
)
);
Abc_NtkIncrementTravId
(
pNtk
);
// add the constant-1 nodes
pObj
=
Abc_AigConst1
(
pNtk
);
Abc_NodeSetTravIdCurrent
(
pObj
);
Vec_PtrPush
(
vNodes
,
pObj
);
// add the CIs/nodes/COs in the topological order
Abc_NtkForEachNode
(
pNtk
,
pObj
,
i
)
{
// check the fanins and add CIs
Abc_ObjForEachFanin
(
pObj
,
pNext
,
k
)
if
(
Abc_ObjIsCi
(
pNext
)
&&
!
Abc_NodeIsTravIdCurrent
(
pNext
)
)
{
Abc_NodeSetTravIdCurrent
(
pNext
);
Vec_PtrPush
(
vNodes
,
pNext
);
}
// add the node
Vec_PtrPush
(
vNodes
,
pObj
);
// check the fanouts and add COs
Abc_ObjForEachFanout
(
pObj
,
pNext
,
k
)
if
(
Abc_ObjIsCo
(
pNext
)
&&
!
Abc_NodeIsTravIdCurrent
(
pNext
)
)
{
Abc_NodeSetTravIdCurrent
(
pNext
);
Vec_PtrPush
(
vNodes
,
pNext
);
}
}
return
vNodes
;
}
/**Function*************************************************************
Synopsis [Computes supports of the POs.]
Description [Returns the ptr-vector of int-vectors.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t
*
Abc_NtkComputeSupportsSmart
(
Abc_Ntk_t
*
pNtk
)
{
Vec_Ptr_t
*
vSupports
;
Vec_Ptr_t
*
vNodes
;
Vec_Int_t
*
vSupp
;
Supp_Man_t
*
p
;
Supp_One_t
*
pPart0
,
*
pPart1
;
Abc_Obj_t
*
pObj
;
int
i
;
// set the number of PIs/POs
Abc_NtkForEachCi
(
pNtk
,
pObj
,
i
)
pObj
->
pNext
=
(
Abc_Obj_t
*
)
i
;
Abc_NtkForEachCo
(
pNtk
,
pObj
,
i
)
pObj
->
pNext
=
(
Abc_Obj_t
*
)
i
;
// start the support computation manager
p
=
Supp_ManStart
(
1
<<
20
,
1
<<
6
);
// consider objects in the topological order
vSupports
=
Vec_PtrAlloc
(
Abc_NtkCoNum
(
pNtk
)
);
Abc_NtkCleanCopy
(
pNtk
);
// order the nodes so that the PIs and POs follow naturally
vNodes
=
Abc_NtkDfsNatural
(
pNtk
);
Vec_PtrForEachEntry
(
vNodes
,
pObj
,
i
)
{
if
(
Abc_ObjIsNode
(
pObj
)
)
{
pPart0
=
(
Supp_One_t
*
)
Abc_ObjFanin0
(
pObj
)
->
pCopy
;
pPart1
=
(
Supp_One_t
*
)
Abc_ObjFanin1
(
pObj
)
->
pCopy
;
pObj
->
pCopy
=
(
Abc_Obj_t
*
)
Supp_ManMergeEntry
(
p
,
pPart0
,
pPart1
,
Abc_ObjFanoutNum
(
pObj
)
);
assert
(
pPart0
->
nRefs
>
0
);
if
(
--
pPart0
->
nRefs
==
0
)
Supp_ManRecycleEntry
(
p
,
pPart0
);
assert
(
pPart1
->
nRefs
>
0
);
if
(
--
pPart1
->
nRefs
==
0
)
Supp_ManRecycleEntry
(
p
,
pPart1
);
continue
;
}
if
(
Abc_ObjIsCo
(
pObj
)
)
{
pPart0
=
(
Supp_One_t
*
)
Abc_ObjFanin0
(
pObj
)
->
pCopy
;
// only save the CO if it is non-trivial
if
(
Abc_ObjIsNode
(
Abc_ObjFanin0
(
pObj
))
)
{
vSupp
=
Supp_ManTransferEntry
(
pPart0
);
Vec_IntPush
(
vSupp
,
(
int
)
pObj
->
pNext
);
Vec_PtrPush
(
vSupports
,
vSupp
);
}
assert
(
pPart0
->
nRefs
>
0
);
if
(
--
pPart0
->
nRefs
==
0
)
Supp_ManRecycleEntry
(
p
,
pPart0
);
continue
;
}
if
(
Abc_ObjIsCi
(
pObj
)
)
{
if
(
Abc_ObjFanoutNum
(
pObj
)
)
{
pPart0
=
(
Supp_One_t
*
)
Supp_ManFetchEntry
(
p
,
1
,
Abc_ObjFanoutNum
(
pObj
)
);
pPart0
->
pOuts
[
pPart0
->
nOuts
++
]
=
(
int
)
pObj
->
pNext
;
pObj
->
pCopy
=
(
Abc_Obj_t
*
)
pPart0
;
}
continue
;
}
if
(
pObj
==
Abc_AigConst1
(
pNtk
)
)
{
if
(
Abc_ObjFanoutNum
(
pObj
)
)
pObj
->
pCopy
=
(
Abc_Obj_t
*
)
Supp_ManFetchEntry
(
p
,
0
,
Abc_ObjFanoutNum
(
pObj
)
);
continue
;
}
assert
(
0
);
}
Vec_PtrFree
(
vNodes
);
//printf( "Memory usage = %d Mb.\n", Vec_PtrSize(p->vMemory) * p->nChunkSize / (1<<20) );
Supp_ManStop
(
p
);
// sort supports by size
Vec_VecSort
(
(
Vec_Vec_t
*
)
vSupports
,
1
);
// clear the number of PIs/POs
Abc_NtkForEachCi
(
pNtk
,
pObj
,
i
)
pObj
->
pNext
=
NULL
;
Abc_NtkForEachCo
(
pNtk
,
pObj
,
i
)
pObj
->
pNext
=
NULL
;
/*
Vec_PtrForEachEntry( vSupports, vSupp, i )
printf( "%d ", Vec_IntSize(vSupp) );
printf( "\n" );
*/
return
vSupports
;
}
/**Function*************************************************************
Synopsis [Computes supports of the POs using naive method.]
Description [Returns the ptr-vector of int-vectors.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t
*
Abc_NtkComputeSupportsNaive
(
Abc_Ntk_t
*
pNtk
)
{
Vec_Ptr_t
*
vSupp
,
*
vSupports
;
Vec_Int_t
*
vSuppI
;
...
...
@@ -47,29 +417,39 @@ Vec_Ptr_t * Abc_NtkPartitionCollectSupps( Abc_Ntk_t * pNtk )
int
i
,
k
;
// set the PI numbers
Abc_NtkForEachCi
(
pNtk
,
pObj
,
i
)
pObj
->
p
Copy
=
(
void
*
)
i
;
// save
ht
e CI numbers
pObj
->
p
Next
=
(
void
*
)
i
;
// save
th
e CI numbers
vSupports
=
Vec_PtrAlloc
(
Abc_NtkCoNum
(
pNtk
)
);
Abc_NtkForEachCo
(
pNtk
,
pObj
,
i
)
{
if
(
!
Abc_ObjIsNode
(
Abc_ObjFanin0
(
pObj
))
)
continue
;
vSupp
=
Abc_NtkNodeSupport
(
pNtk
,
&
pObj
,
1
);
vSuppI
=
(
Vec_Int_t
*
)
vSupp
;
Vec_PtrForEachEntry
(
vSupp
,
pTemp
,
k
)
Vec_IntWriteEntry
(
vSuppI
,
k
,
(
int
)
pTemp
->
p
Copy
);
Vec_IntWriteEntry
(
vSuppI
,
k
,
(
int
)
pTemp
->
p
Next
);
Vec_IntSort
(
vSuppI
,
0
);
// append the number of this output
Vec_IntPush
(
vSuppI
,
i
);
// save the support in the vector
Vec_PtrPush
(
vSupports
,
vSuppI
);
}
// clean the CI numbers
Abc_NtkForEachCi
(
pNtk
,
pObj
,
i
)
pObj
->
pNext
=
NULL
;
// sort supports by size
Vec_VecSort
(
(
Vec_Vec_t
*
)
vSupports
,
1
);
/*
Vec_PtrForEachEntry( vSupports, vSuppI, i )
printf( "%d ", Vec_IntSize(vSuppI) );
printf( "\n" );
*/
return
vSupports
;
}
/**Function*************************************************************
Synopsis [Start
char-bases
support representation.]
Synopsis [Start
bitwise
support representation.]
Description []
...
...
@@ -78,23 +458,24 @@ Vec_Ptr_t * Abc_NtkPartitionCollectSupps( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
char
*
Abc_NtkSuppCharStart
(
Vec_Int_t
*
vOne
,
int
nPis
)
unsigned
*
Abc_NtkSuppCharStart
(
Vec_Int_t
*
vOne
,
int
nPis
)
{
char
*
pBuffer
;
unsigned
*
pBuffer
;
int
i
,
Entry
;
pBuffer
=
ALLOC
(
char
,
nPis
);
memset
(
pBuffer
,
0
,
sizeof
(
char
)
*
nPis
);
int
nWords
=
Abc_BitWordNum
(
nPis
);
pBuffer
=
ALLOC
(
unsigned
,
nWords
);
memset
(
pBuffer
,
0
,
sizeof
(
unsigned
)
*
nWords
);
Vec_IntForEachEntry
(
vOne
,
Entry
,
i
)
{
assert
(
Entry
<
nPis
);
pBuffer
[
Entry
]
=
1
;
Abc_InfoSetBit
(
pBuffer
,
Entry
)
;
}
return
pBuffer
;
}
/**Function*************************************************************
Synopsis [Add to
char-bases
support representation.]
Synopsis [Add to
bitwise
support representation.]
Description []
...
...
@@ -103,19 +484,19 @@ char * Abc_NtkSuppCharStart( Vec_Int_t * vOne, int nPis )
SeeAlso []
***********************************************************************/
void
Abc_NtkSuppCharAdd
(
char
*
pBuffer
,
Vec_Int_t
*
vOne
,
int
nPis
)
void
Abc_NtkSuppCharAdd
(
unsigned
*
pBuffer
,
Vec_Int_t
*
vOne
,
int
nPis
)
{
int
i
,
Entry
;
Vec_IntForEachEntry
(
vOne
,
Entry
,
i
)
{
assert
(
Entry
<
nPis
);
pBuffer
[
Entry
]
=
1
;
Abc_InfoSetBit
(
pBuffer
,
Entry
)
;
}
}
/**Function*************************************************************
Synopsis [Find the common variables using
char-bases
support representation.]
Synopsis [Find the common variables using
bitwise
support representation.]
Description []
...
...
@@ -124,11 +505,11 @@ void Abc_NtkSuppCharAdd( char * pBuffer, Vec_Int_t * vOne, int nPis )
SeeAlso []
***********************************************************************/
int
Abc_NtkSuppCharCommon
(
char
*
pBuffer
,
Vec_Int_t
*
vOne
)
int
Abc_NtkSuppCharCommon
(
unsigned
*
pBuffer
,
Vec_Int_t
*
vOne
)
{
int
i
,
Entry
,
nCommon
=
0
;
Vec_IntForEachEntry
(
vOne
,
Entry
,
i
)
nCommon
+=
pBuffer
[
Entry
]
;
nCommon
+=
Abc_InfoHasBit
(
pBuffer
,
Entry
)
;
return
nCommon
;
}
...
...
@@ -143,7 +524,7 @@ int Abc_NtkSuppCharCommon( char * pBuffer, Vec_Int_t * vOne )
SeeAlso []
***********************************************************************/
int
Abc_NtkPartitionSmartFindPart
(
Vec_Ptr_t
*
vPartSuppsAll
,
Vec_Ptr_t
*
vPartsAll
,
Vec_Ptr_t
*
vPartSuppsChar
,
int
n
Part
SizeLimit
,
Vec_Int_t
*
vOne
)
int
Abc_NtkPartitionSmartFindPart
(
Vec_Ptr_t
*
vPartSuppsAll
,
Vec_Ptr_t
*
vPartsAll
,
Vec_Ptr_t
*
vPartSuppsChar
,
int
n
Supp
SizeLimit
,
Vec_Int_t
*
vOne
)
{
/*
Vec_Int_t * vPartSupp, * vPart;
...
...
@@ -178,7 +559,7 @@ int Abc_NtkPartitionSmartFindPart( Vec_Ptr_t * vPartSuppsAll, Vec_Ptr_t * vParts
return iBest;
*/
Vec_Int_t
*
vPartSupp
,
*
vPart
;
Vec_Int_t
*
vPartSupp
;
//
, * vPart;
int
Attract
,
Repulse
,
Value
,
ValueBest
;
int
i
,
nCommon
,
iBest
;
// int nCommon2;
...
...
@@ -186,16 +567,24 @@ int Abc_NtkPartitionSmartFindPart( Vec_Ptr_t * vPartSuppsAll, Vec_Ptr_t * vParts
ValueBest
=
0
;
Vec_PtrForEachEntry
(
vPartSuppsAll
,
vPartSupp
,
i
)
{
vPart
=
Vec_PtrEntry
(
vPartsAll
,
i
);
if
(
nPartSizeLimit
>
0
&&
Vec_IntSize
(
vPart
)
>=
nPartSizeLimit
)
continue
;
// skip partitions with too many outputs
// vPart = Vec_PtrEntry( vPartsAll, i );
// if ( nSuppSizeLimit > 0 && Vec_IntSize(vPart) >= nSuppSizeLimit )
// continue;
// find the number of common variables between this output and the partitions
// nCommon2 = Vec_IntTwoCountCommon( vPartSupp, vOne );
nCommon
=
Abc_NtkSuppCharCommon
(
Vec_PtrEntry
(
vPartSuppsChar
,
i
),
vOne
);
// assert( nCommon2 == nCommon );
// if no common variables, continue searching
if
(
nCommon
==
0
)
continue
;
// if all variables are common, the best partition if found
if
(
nCommon
==
Vec_IntSize
(
vOne
)
)
return
i
;
// skip partitions whose size exceeds the limit
if
(
nSuppSizeLimit
>
0
&&
Vec_IntSize
(
vPartSupp
)
>=
2
*
nSuppSizeLimit
)
continue
;
// figure out might be the good partition for this one
Attract
=
1000
*
nCommon
/
Vec_IntSize
(
vOne
);
if
(
Vec_IntSize
(
vPartSupp
)
<
100
)
Repulse
=
1
;
...
...
@@ -238,7 +627,7 @@ void Abc_NtkPartitionPrint( Abc_Ntk_t * pNtk, Vec_Ptr_t * vPartsAll, Vec_Ptr_t *
if
(
i
==
Vec_PtrSize
(
vPartsAll
)
-
1
)
break
;
}
assert
(
Counter
==
Abc_NtkCoNum
(
pNtk
)
);
//
assert( Counter == Abc_NtkCoNum(pNtk) );
printf
(
"
\n
Total = %d. Outputs = %d.
\n
"
,
Counter
,
Abc_NtkCoNum
(
pNtk
)
);
}
...
...
@@ -253,20 +642,20 @@ void Abc_NtkPartitionPrint( Abc_Ntk_t * pNtk, Vec_Ptr_t * vPartsAll, Vec_Ptr_t *
SeeAlso []
***********************************************************************/
void
Abc_NtkPartitionCompact
(
Vec_Ptr_t
*
vPartsAll
,
Vec_Ptr_t
*
vPartSuppsAll
,
int
n
Part
SizeLimit
)
void
Abc_NtkPartitionCompact
(
Vec_Ptr_t
*
vPartsAll
,
Vec_Ptr_t
*
vPartSuppsAll
,
int
n
Supp
SizeLimit
)
{
Vec_Int_t
*
vOne
,
*
vPart
,
*
vPartSupp
,
*
vTemp
;
int
i
,
iPart
;
if
(
n
Part
SizeLimit
==
0
)
n
Part
SizeLimit
=
200
;
if
(
n
Supp
SizeLimit
==
0
)
n
Supp
SizeLimit
=
200
;
// pack smaller partitions into larger blocks
iPart
=
0
;
vPart
=
vPartSupp
=
NULL
;
Vec_PtrForEachEntry
(
vPartSuppsAll
,
vOne
,
i
)
{
if
(
Vec_IntSize
(
vOne
)
<
n
Part
SizeLimit
)
if
(
Vec_IntSize
(
vOne
)
<
n
Supp
SizeLimit
)
{
if
(
vPartSupp
==
NULL
)
{
...
...
@@ -282,7 +671,7 @@ void Abc_NtkPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll,
Vec_IntFree
(
vTemp
);
Vec_IntFree
(
Vec_PtrEntry
(
vPartsAll
,
i
)
);
}
if
(
Vec_IntSize
(
vPartSupp
)
<
n
Part
SizeLimit
)
if
(
Vec_IntSize
(
vPartSupp
)
<
n
Supp
SizeLimit
)
continue
;
}
else
...
...
@@ -318,23 +707,25 @@ void Abc_NtkPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll,
Synopsis [Perform the smart partitioning.]
Description []
Description [
Returns the ptr-vector of int-vectors.
]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_
Vec_t
*
Abc_NtkPartitionSmart
(
Abc_Ntk_t
*
pNtk
,
int
nPart
SizeLimit
,
int
fVerbose
)
Vec_
Ptr_t
*
Abc_NtkPartitionSmart
(
Abc_Ntk_t
*
pNtk
,
int
nSupp
SizeLimit
,
int
fVerbose
)
{
ProgressBar
*
pProgress
;
Vec_Ptr_t
*
vPartSuppsChar
;
Vec_Ptr_t
*
vSupps
,
*
vPartsAll
,
*
vPartsAll2
,
*
vPartSuppsAll
,
*
vPartPtr
;
Vec_Ptr_t
*
vSupps
,
*
vPartsAll
,
*
vPartsAll2
,
*
vPartSuppsAll
;
Vec_Int_t
*
vOne
,
*
vPart
,
*
vPartSupp
,
*
vTemp
;
int
i
,
iPart
,
iOut
,
clk
,
clk2
,
timeFind
=
0
;
// compute the supports for all outputs
clk
=
clock
();
vSupps
=
Abc_NtkPartitionCollectSupps
(
pNtk
);
// vSupps = Abc_NtkComputeSupportsNaive( pNtk );
vSupps
=
Abc_NtkComputeSupportsSmart
(
pNtk
);
if
(
fVerbose
)
{
PRT
(
"Supps"
,
clock
()
-
clk
);
...
...
@@ -346,15 +737,19 @@ PRT( "Supps", clock() - clk );
clk
=
clock
();
vPartsAll
=
Vec_PtrAlloc
(
256
);
vPartSuppsAll
=
Vec_PtrAlloc
(
256
);
pProgress
=
Extra_ProgressBarStart
(
stdout
,
Vec_PtrSize
(
vSupps
)
);
Vec_PtrForEachEntry
(
vSupps
,
vOne
,
i
)
{
Extra_ProgressBarUpdate
(
pProgress
,
i
,
NULL
);
// if ( i % 1000 == 0 )
// printf( "CIs = %6d. COs = %6d. Processed = %6d (out of %6d). Parts = %6d.\r",
// Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), i, Vec_PtrSize(vSupps), Vec_PtrSize(vPartsAll) );
// get the output number
iOut
=
Vec_IntPop
(
vOne
);
// find closely matching part
clk2
=
clock
();
iPart
=
Abc_NtkPartitionSmartFindPart
(
vPartSuppsAll
,
vPartsAll
,
vPartSuppsChar
,
n
Part
SizeLimit
,
vOne
);
iPart
=
Abc_NtkPartitionSmartFindPart
(
vPartSuppsAll
,
vPartsAll
,
vPartSuppsChar
,
n
Supp
SizeLimit
,
vOne
);
timeFind
+=
clock
()
-
clk2
;
//printf( "%4d->%4d ", i, iPart );
if
(
iPart
==
-
1
)
{
// create new partition
...
...
@@ -383,6 +778,7 @@ timeFind += clock() - clk2;
Abc_NtkSuppCharAdd
(
Vec_PtrEntry
(
vPartSuppsChar
,
iPart
),
vOne
,
Abc_NtkCiNum
(
pNtk
)
);
}
}
Extra_ProgressBarStop
(
pProgress
);
// stop char-based support representation
Vec_PtrForEachEntry
(
vPartSuppsChar
,
vTemp
,
i
)
...
...
@@ -411,20 +807,20 @@ clk = clock();
// compact small partitions
// Abc_NtkPartitionPrint( pNtk, vPartsAll, vPartSuppsAll );
Abc_NtkPartitionCompact
(
vPartsAll
,
vPartSuppsAll
,
nPartSizeLimit
);
if
(
fVerbose
)
// Abc_NtkPartitionPrint( pNtk, vPartsAll, vPartSuppsAll );
printf
(
"Created %d partitions.
\n
"
,
Vec_PtrSize
(
vPartsAll
)
);
Abc_NtkPartitionCompact
(
vPartsAll
,
vPartSuppsAll
,
nSuppSizeLimit
);
if
(
fVerbose
)
{
PRT
(
"Comps"
,
clock
()
-
clk
);
}
if
(
fVerbose
)
printf
(
"Created %d partitions.
\n
"
,
Vec_PtrSize
(
vPartsAll
)
);
// Abc_NtkPartitionPrint( pNtk, vPartsAll, vPartSuppsAll );
// cleanup
Vec_VecFree
(
(
Vec_Vec_t
*
)
vSupps
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vPartSuppsAll
);
/*
// converts from intergers to nodes
Vec_PtrForEachEntry( vPartsAll, vPart, iPart )
{
...
...
@@ -434,34 +830,54 @@ PRT( "Comps", clock() - clk );
Vec_IntFree( vPart );
Vec_PtrWriteEntry( vPartsAll, iPart, vPartPtr );
}
return
(
Vec_Vec_t
*
)
vPartsAll
;
*/
return
vPartsAll
;
}
/**Function*************************************************************
Synopsis [Perform the naive partitioning.]
Description []
Description [
Returns the ptr-vector of int-vectors.
]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_
Vec
_t
*
Abc_NtkPartitionNaive
(
Abc_Ntk_t
*
pNtk
,
int
nPartSize
)
Vec_
Ptr
_t
*
Abc_NtkPartitionNaive
(
Abc_Ntk_t
*
pNtk
,
int
nPartSize
)
{
Vec_
Vec
_t
*
vParts
;
Vec_
Ptr
_t
*
vParts
;
Abc_Obj_t
*
pObj
;
int
nParts
,
i
;
nParts
=
(
Abc_NtkCoNum
(
pNtk
)
/
nPartSize
)
+
((
Abc_NtkCoNum
(
pNtk
)
%
nPartSize
)
>
0
);
vParts
=
Vec_VecStart
(
nParts
);
vParts
=
(
Vec_Ptr_t
*
)
Vec_VecStart
(
nParts
);
Abc_NtkForEachCo
(
pNtk
,
pObj
,
i
)
Vec_
VecPush
(
vParts
,
i
/
nPartSize
,
pObj
);
Vec_
IntPush
(
Vec_PtrEntry
(
vParts
,
i
/
nPartSize
),
i
);
return
vParts
;
}
/**Function*************************************************************
Synopsis [Converts from intergers to pointers for the given network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkConvertCos
(
Abc_Ntk_t
*
pNtk
,
Vec_Int_t
*
vOuts
,
Vec_Ptr_t
*
vOutsPtr
)
{
int
Out
,
i
;
Vec_PtrClear
(
vOutsPtr
);
Vec_IntForEachEntry
(
vOuts
,
Out
,
i
)
Vec_PtrPush
(
vOutsPtr
,
Abc_NtkCo
(
pNtk
,
Out
)
);
}
/**Function*************************************************************
Synopsis [Returns representative of the given node.]
Description []
...
...
@@ -506,134 +922,6 @@ static inline Abc_Obj_t * Abc_NtkPartStitchCopy1( Vec_Ptr_t * vEquiv, Abc_Obj_t
/**Function*************************************************************
Synopsis [Stitches together several networks with choice nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t
*
Abc_NtkPartStitchChoices_old
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vParts
)
{
Vec_Ptr_t
*
vNodes
,
*
vEquiv
;
Abc_Ntk_t
*
pNtkNew
,
*
pNtkNew2
,
*
pNtkTemp
;
Abc_Obj_t
*
pObj
,
*
pFanin
,
*
pRepr0
,
*
pRepr1
,
*
pRepr
;
int
i
,
k
,
iNodeId
;
// start a new network similar to the original one
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_STRASH
,
ABC_FUNC_AIG
);
// duplicate the name and the spec
pNtkNew
->
pName
=
Extra_UtilStrsav
(
pNtk
->
pName
);
pNtkNew
->
pSpec
=
Extra_UtilStrsav
(
pNtk
->
pSpec
);
// annotate parts to point to the new network
vEquiv
=
Vec_PtrStart
(
Abc_NtkObjNumMax
(
pNtk
)
+
1
);
Vec_PtrForEachEntry
(
vParts
,
pNtkTemp
,
i
)
{
assert
(
Abc_NtkIsStrash
(
pNtkTemp
)
);
Abc_NtkCleanCopy
(
pNtkTemp
);
// map the CI nodes
Abc_AigConst1
(
pNtkTemp
)
->
pCopy
=
Abc_AigConst1
(
pNtkNew
);
Abc_NtkForEachCi
(
pNtkTemp
,
pObj
,
k
)
{
iNodeId
=
Nm_ManFindIdByNameTwoTypes
(
pNtkNew
->
pManName
,
Abc_ObjName
(
pObj
),
ABC_OBJ_PI
,
ABC_OBJ_BO
);
if
(
iNodeId
==
-
1
)
{
printf
(
"Cannot find CI node %s in the original network.
\n
"
,
Abc_ObjName
(
pObj
)
);
return
NULL
;
}
pObj
->
pCopy
=
Abc_NtkObj
(
pNtkNew
,
iNodeId
);
}
// add the internal nodes while saving representatives
vNodes
=
Abc_AigDfs
(
pNtkTemp
,
1
,
0
);
Vec_PtrForEachEntry
(
vNodes
,
pObj
,
k
)
{
pObj
->
pCopy
=
Abc_AigAnd
(
pNtkNew
->
pManFunc
,
Abc_ObjChild0Copy
(
pObj
),
Abc_ObjChild1Copy
(
pObj
)
);
assert
(
!
Abc_ObjIsComplement
(
pObj
->
pCopy
)
);
if
(
!
Abc_AigNodeIsChoice
(
pObj
)
)
continue
;
// find the earliest representative of the choice node
pRepr0
=
NULL
;
for
(
pFanin
=
pObj
;
pFanin
;
pFanin
=
pFanin
->
pData
)
{
pRepr1
=
Abc_NtkPartStitchFindRepr_rec
(
vEquiv
,
pFanin
->
pCopy
);
if
(
pRepr0
==
NULL
||
pRepr0
->
Id
>
pRepr1
->
Id
)
pRepr0
=
pRepr1
;
}
// set this representative for the representives of all choices
for
(
pFanin
=
pObj
;
pFanin
;
pFanin
=
pFanin
->
pData
)
{
pRepr1
=
Abc_NtkPartStitchFindRepr_rec
(
vEquiv
,
pFanin
->
pCopy
);
Vec_PtrWriteEntry
(
vEquiv
,
pRepr1
->
Id
,
pRepr0
);
}
}
Vec_PtrFree
(
vNodes
);
// map the CO nodes
Abc_NtkForEachCo
(
pNtkTemp
,
pObj
,
k
)
{
iNodeId
=
Nm_ManFindIdByNameTwoTypes
(
pNtkNew
->
pManName
,
Abc_ObjName
(
pObj
),
ABC_OBJ_PO
,
ABC_OBJ_BI
);
if
(
iNodeId
==
-
1
)
{
printf
(
"Cannot find CO node %s in the original network.
\n
"
,
Abc_ObjName
(
pObj
)
);
return
NULL
;
}
pObj
->
pCopy
=
Abc_NtkObj
(
pNtkNew
,
iNodeId
);
Abc_ObjAddFanin
(
pObj
->
pCopy
,
Abc_ObjChild0Copy
(
pObj
)
);
}
}
// reconstruct the AIG
pNtkNew2
=
Abc_NtkStartFrom
(
pNtkNew
,
ABC_NTK_STRASH
,
ABC_FUNC_AIG
);
// duplicate the name and the spec
pNtkNew2
->
pName
=
Extra_UtilStrsav
(
pNtkNew
->
pName
);
pNtkNew2
->
pSpec
=
Extra_UtilStrsav
(
pNtkNew
->
pSpec
);
// duplicate internal nodes
Abc_AigForEachAnd
(
pNtkNew
,
pObj
,
i
)
{
pRepr0
=
Abc_NtkPartStitchCopy0
(
vEquiv
,
pObj
);
pRepr1
=
Abc_NtkPartStitchCopy1
(
vEquiv
,
pObj
);
pObj
->
pCopy
=
Abc_AigAnd
(
pNtkNew2
->
pManFunc
,
pRepr0
,
pRepr1
);
assert
(
!
Abc_ObjIsComplement
(
pObj
->
pCopy
)
);
// add the choice if applicable
pRepr
=
Abc_NtkPartStitchFindRepr_rec
(
vEquiv
,
pObj
);
if
(
pObj
!=
pRepr
)
{
assert
(
pObj
->
Id
>
pRepr
->
Id
);
if
(
pObj
->
pCopy
!=
pRepr
->
pCopy
)
{
assert
(
pObj
->
pCopy
->
Id
>
pRepr
->
pCopy
->
Id
);
pObj
->
pCopy
->
pData
=
pRepr
->
pCopy
->
pData
;
pRepr
->
pCopy
->
pData
=
pObj
->
pCopy
;
}
}
}
// connect the COs
Abc_NtkForEachCo
(
pNtkNew
,
pObj
,
k
)
Abc_ObjAddFanin
(
pObj
->
pCopy
,
Abc_NtkPartStitchCopy0
(
vEquiv
,
pObj
)
);
// replace the network
Abc_NtkDelete
(
pNtkNew
);
pNtkNew
=
pNtkNew2
;
// check correctness of the new network
Vec_PtrFree
(
vEquiv
);
if
(
!
Abc_NtkCheck
(
pNtkNew
)
)
{
printf
(
"Abc_NtkPartStitchChoices: The network check has failed.
\n
"
);
Abc_NtkDelete
(
pNtkNew
);
return
NULL
;
}
return
pNtkNew
;
}
/**Function*************************************************************
Synopsis []
Description []
...
...
@@ -762,6 +1050,20 @@ Abc_Ntk_t * Abc_NtkPartStitchChoices( Abc_Ntk_t * pNtk, Vec_Ptr_t * vParts )
}
}
// connect the remaining POs
/*
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy = Abc_NtkCi( pNtkNew, i );
Abc_NtkForEachCo( pNtk, pObj, i )
pObj->pCopy = Abc_NtkCo( pNtkNew, i );
*/
Abc_NtkForEachCo
(
pNtk
,
pObj
,
i
)
{
if
(
Abc_ObjFaninNum
(
pObj
->
pCopy
)
==
0
)
Abc_ObjAddFanin
(
pObj
->
pCopy
,
Abc_ObjChild0Copy
(
pObj
)
);
}
// transform into the HOP manager
pMan
=
Abc_NtkPartStartHop
(
pNtkNew
);
pNtkNew
=
Abc_NtkHopRemoveLoops
(
pNtkTemp
=
pNtkNew
,
pMan
);
...
...
@@ -788,47 +1090,57 @@ Abc_Ntk_t * Abc_NtkPartStitchChoices( Abc_Ntk_t * pNtk, Vec_Ptr_t * vParts )
SeeAlso []
***********************************************************************/
Abc_Ntk_t
*
Abc_NtkFraigPartitioned
(
Abc_Ntk_t
*
pNtk
,
void
*
pParams
)
Abc_Ntk_t
*
Abc_NtkFraigPartitioned
(
Vec_Ptr_t
*
vStore
,
void
*
pParams
)
{
extern
int
Cmd_CommandExecute
(
void
*
pAbc
,
char
*
sCommand
);
extern
void
*
Abc_FrameGetGlobalFrame
();
Vec_
Vec_t
*
vParts
;
Vec_
Ptr_t
*
vFraigs
,
*
vOne
;
Abc_Ntk_t
*
pNtkAig
,
*
pNtkFraig
;
int
i
;
Vec_
Ptr_t
*
vParts
,
*
vFraigs
,
*
vOnePtr
;
Vec_
Int_t
*
vOne
;
Abc_Ntk_t
*
pNtk
,
*
pNtk2
,
*
pNtk
Aig
,
*
pNtkFraig
;
int
i
,
k
;
// perform partitioning
pNtk
=
Vec_PtrEntry
(
vStore
,
0
);
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
// vParts = Abc_NtkPartitionNaive( pNtk, 20 );
vParts
=
Abc_NtkPartitionSmart
(
pNtk
,
0
,
0
);
vParts
=
Abc_NtkPartitionSmart
(
pNtk
,
30
0
,
0
);
Cmd_CommandExecute
(
Abc_FrameGetGlobalFrame
(),
"unset progressbar"
);
// fraig each partition
vFraigs
=
Vec_PtrAlloc
(
Vec_VecSize
(
vParts
)
);
Vec_VecForEachLevel
(
vParts
,
vOne
,
i
)
vOnePtr
=
Vec_PtrAlloc
(
1000
);
vFraigs
=
Vec_PtrAlloc
(
Vec_PtrSize
(
vParts
)
);
Vec_PtrForEachEntry
(
vParts
,
vOne
,
i
)
{
pNtkAig
=
Abc_NtkCreateConeArray
(
pNtk
,
vOne
,
0
);
pNtkFraig
=
Abc_NtkFraig
(
pNtkAig
,
pParams
,
0
,
0
);
// start the partition
Abc_NtkConvertCos
(
pNtk
,
vOne
,
vOnePtr
);
pNtkAig
=
Abc_NtkCreateConeArray
(
pNtk
,
vOnePtr
,
0
);
// add nodes to the partition
Vec_PtrForEachEntryStart
(
vStore
,
pNtk2
,
k
,
1
)
{
Abc_NtkConvertCos
(
pNtk2
,
vOne
,
vOnePtr
);
Abc_NtkAppendToCone
(
pNtkAig
,
pNtk2
,
vOnePtr
);
}
printf
(
"Fraiging part %4d (out of %4d) PI = %5d. PO = %5d. And = %6d. Lev = %4d.
\r
"
,
i
+
1
,
Vec_PtrSize
(
vParts
),
Abc_NtkPiNum
(
pNtkAig
),
Abc_NtkPoNum
(
pNtkAig
),
Abc_NtkNodeNum
(
pNtkAig
),
Abc_AigLevel
(
pNtkAig
)
);
// fraig the partition
pNtkFraig
=
Abc_NtkFraig
(
pNtkAig
,
pParams
,
1
,
0
);
Vec_PtrPush
(
vFraigs
,
pNtkFraig
);
Abc_NtkDelete
(
pNtkAig
);
printf
(
"Finished part %d (out of %d)
\r
"
,
i
+
1
,
Vec_VecSize
(
vParts
)
);
}
Vec_VecFree
(
vParts
);
printf
(
"
\r
"
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vParts
);
Cmd_CommandExecute
(
Abc_FrameGetGlobalFrame
(),
"set progressbar"
);
// derive the final network
pNtkFraig
=
Abc_NtkPartStitchChoices
(
pNtk
,
vFraigs
);
Vec_PtrForEachEntry
(
vFraigs
,
pNtkAig
,
i
)
{
// Abc_NtkPrintStats( stdout, pNtkAig, 0 );
Abc_NtkDelete
(
pNtkAig
);
}
Vec_PtrFree
(
vFraigs
);
Vec_PtrFree
(
vOnePtr
);
return
pNtkFraig
;
}
...
...
@@ -848,8 +1160,8 @@ void Abc_NtkFraigPartitionedTime( Abc_Ntk_t * pNtk, void * pParams )
extern
int
Cmd_CommandExecute
(
void
*
pAbc
,
char
*
sCommand
);
extern
void
*
Abc_FrameGetGlobalFrame
();
Vec_
Vec_t
*
vParts
;
Vec_
Ptr_t
*
vFraigs
,
*
vOne
;
Vec_
Ptr_t
*
vParts
,
*
vFraigs
,
*
vOnePtr
;
Vec_
Int_t
*
vOne
;
Abc_Ntk_t
*
pNtkAig
,
*
pNtkFraig
;
int
i
;
int
clk
=
clock
();
...
...
@@ -857,22 +1169,24 @@ void Abc_NtkFraigPartitionedTime( Abc_Ntk_t * pNtk, void * pParams )
// perform partitioning
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
// vParts = Abc_NtkPartitionNaive( pNtk, 20 );
vParts
=
Abc_NtkPartitionSmart
(
pNtk
,
0
,
0
);
vParts
=
Abc_NtkPartitionSmart
(
pNtk
,
30
0
,
0
);
Cmd_CommandExecute
(
Abc_FrameGetGlobalFrame
(),
"unset progressbar"
);
// fraig each partition
vFraigs
=
Vec_PtrAlloc
(
Vec_VecSize
(
vParts
)
);
Vec_VecForEachLevel
(
vParts
,
vOne
,
i
)
vOnePtr
=
Vec_PtrAlloc
(
1000
);
vFraigs
=
Vec_PtrAlloc
(
Vec_PtrSize
(
vParts
)
);
Vec_PtrForEachEntry
(
vParts
,
vOne
,
i
)
{
pNtkAig
=
Abc_NtkCreateConeArray
(
pNtk
,
vOne
,
0
);
Abc_NtkConvertCos
(
pNtk
,
vOne
,
vOnePtr
);
pNtkAig
=
Abc_NtkCreateConeArray
(
pNtk
,
vOnePtr
,
0
);
pNtkFraig
=
Abc_NtkFraig
(
pNtkAig
,
pParams
,
0
,
0
);
Vec_PtrPush
(
vFraigs
,
pNtkFraig
);
Abc_NtkDelete
(
pNtkAig
);
printf
(
"Finished part %
d (out of %d)
\r
"
,
i
+
1
,
Vec_Vec
Size
(
vParts
)
);
printf
(
"Finished part %
5d (out of %5d)
\r
"
,
i
+
1
,
Vec_Ptr
Size
(
vParts
)
);
}
Vec_VecFree
(
vParts
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vParts
);
Cmd_CommandExecute
(
Abc_FrameGetGlobalFrame
(),
"set progressbar"
);
...
...
@@ -880,7 +1194,7 @@ void Abc_NtkFraigPartitionedTime( Abc_Ntk_t * pNtk, void * pParams )
Vec_PtrForEachEntry
(
vFraigs
,
pNtkAig
,
i
)
Abc_NtkDelete
(
pNtkAig
);
Vec_PtrFree
(
vFraigs
);
Vec_PtrFree
(
vOnePtr
);
PRT
(
"Partitioned fraiging time"
,
clock
()
-
clk
);
}
...
...
src/base/abci/abcVerify.c
View file @
b2470dd3
...
...
@@ -293,7 +293,7 @@ void Abc_NtkCecFraigPart( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, in
}
else
{
printf
(
"Finished part %
d (out of %
d)
\r
"
,
i
+
1
,
Abc_NtkPoNum
(
pMiter
)
);
printf
(
"Finished part %
5d (out of %5
d)
\r
"
,
i
+
1
,
Abc_NtkPoNum
(
pMiter
)
);
nOutputs
+=
nPartSize
;
}
// if ( pMiter->pModel )
...
...
@@ -301,7 +301,7 @@ void Abc_NtkCecFraigPart( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, in
if
(
pMiterPart
)
Abc_NtkDelete
(
pMiterPart
);
}
Cmd_CommandExecute
(
Abc_FrameGetGlobalFrame
(),
"set progressbar"
);
if
(
Status
==
1
)
...
...
@@ -325,12 +325,13 @@ void Abc_NtkCecFraigPart( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, in
void
Abc_NtkCecFraigPartAuto
(
Abc_Ntk_t
*
pNtk1
,
Abc_Ntk_t
*
pNtk2
,
int
nSeconds
,
int
fVerbose
)
{
extern
int
Abc_NtkCombinePos
(
Abc_Ntk_t
*
pNtk
,
int
fAnd
);
extern
Vec_Vec_t
*
Abc_NtkPartitionSmart
(
Abc_Ntk_t
*
pNtk
,
int
nPartSizeLimit
,
int
fVerbose
);
extern
Vec_Ptr_t
*
Abc_NtkPartitionSmart
(
Abc_Ntk_t
*
pNtk
,
int
nPartSizeLimit
,
int
fVerbose
);
extern
void
Abc_NtkConvertCos
(
Abc_Ntk_t
*
pNtk
,
Vec_Int_t
*
vOuts
,
Vec_Ptr_t
*
vOnePtr
);
extern
int
Cmd_CommandExecute
(
void
*
pAbc
,
char
*
sCommand
);
extern
void
*
Abc_FrameGetGlobalFrame
();
Vec_
Vec_t
*
vParts
;
Vec_
Ptr
_t
*
vOne
;
Vec_
Ptr_t
*
vParts
,
*
vOnePtr
;
Vec_
Int
_t
*
vOne
;
Prove_Params_t
Params
,
*
pParams
=
&
Params
;
Abc_Ntk_t
*
pMiter
,
*
pMiterPart
;
int
i
,
RetValue
,
Status
,
nOutputs
;
...
...
@@ -368,15 +369,17 @@ void Abc_NtkCecFraigPartAuto( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds
Cmd_CommandExecute
(
Abc_FrameGetGlobalFrame
(),
"unset progressbar"
);
// partition the outputs
vParts
=
Abc_NtkPartitionSmart
(
pMiter
,
50
,
1
);
vParts
=
Abc_NtkPartitionSmart
(
pMiter
,
300
,
0
);
// fraig each partition
Status
=
1
;
nOutputs
=
0
;
Vec_VecForEachLevel
(
vParts
,
vOne
,
i
)
vOnePtr
=
Vec_PtrAlloc
(
1000
);
Vec_PtrForEachEntry
(
vParts
,
vOne
,
i
)
{
// get this part of the miter
pMiterPart
=
Abc_NtkCreateConeArray
(
pMiter
,
vOne
,
0
);
Abc_NtkConvertCos
(
pMiter
,
vOne
,
vOnePtr
);
pMiterPart
=
Abc_NtkCreateConeArray
(
pMiter
,
vOnePtr
,
0
);
Abc_NtkCombinePos
(
pMiterPart
,
0
);
// check the miter for being constant
RetValue
=
Abc_NtkMiterIsConstant
(
pMiterPart
);
...
...
@@ -391,6 +394,9 @@ void Abc_NtkCecFraigPartAuto( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds
Abc_NtkDelete
(
pMiterPart
);
continue
;
}
printf
(
"Verifying part %4d (out of %4d) PI = %5d. PO = %5d. And = %6d. Lev = %4d.
\r
"
,
i
+
1
,
Vec_PtrSize
(
vParts
),
Abc_NtkPiNum
(
pMiterPart
),
Abc_NtkPoNum
(
pMiterPart
),
Abc_NtkNodeNum
(
pMiterPart
),
Abc_AigLevel
(
pMiterPart
)
);
// solve the problem
RetValue
=
Abc_NtkIvyProve
(
&
pMiterPart
,
pParams
);
if
(
RetValue
==
-
1
)
...
...
@@ -412,12 +418,14 @@ void Abc_NtkCecFraigPartAuto( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds
}
else
{
printf
(
"Finished part %d (out of %d)
\r
"
,
i
+
1
,
Vec_Vec
Size
(
vParts
)
);
nOutputs
+=
Vec_
Ptr
Size
(
vOne
);
// printf( "Finished part %5d (out of %5d)\r", i+1, Vec_Ptr
Size(vParts) );
nOutputs
+=
Vec_
Int
Size
(
vOne
);
}
Abc_NtkDelete
(
pMiterPart
);
}
Vec_VecFree
(
vParts
);
printf
(
"
\r
"
);
Vec_VecFree
(
(
Vec_Vec_t
*
)
vParts
);
Vec_PtrFree
(
vOnePtr
);
Cmd_CommandExecute
(
Abc_FrameGetGlobalFrame
(),
"set progressbar"
);
...
...
src/base/main/main.h
View file @
b2470dd3
...
...
@@ -92,8 +92,8 @@ extern void Abc_FrameDeleteAllNetworks( Abc_Frame_t * p );
extern
void
Abc_FrameSetGlobalFrame
(
Abc_Frame_t
*
p
);
extern
Abc_Frame_t
*
Abc_FrameGetGlobalFrame
();
extern
Abc_Ntk_t
*
Abc_FrameReadNtk
Store
();
extern
int
Abc_FrameRead
Ntk
StoreSize
();
extern
Vec_Ptr_t
*
Abc_FrameRead
Store
();
extern
int
Abc_FrameReadStoreSize
();
extern
void
*
Abc_FrameReadLibLut
();
extern
void
*
Abc_FrameReadLibGen
();
extern
void
*
Abc_FrameReadLibSuper
();
...
...
src/base/main/mainFrame.c
View file @
b2470dd3
...
...
@@ -43,8 +43,8 @@ static Abc_Frame_t * s_GlobalFrame = NULL;
SeeAlso []
***********************************************************************/
Abc_Ntk_t
*
Abc_FrameReadNtkStore
()
{
return
s_GlobalFrame
->
pStored
;
}
int
Abc_FrameRead
NtkStoreSize
()
{
return
s_GlobalFrame
->
nStored
;
}
Vec_Ptr_t
*
Abc_FrameReadStore
()
{
return
s_GlobalFrame
->
vStore
;
}
int
Abc_FrameRead
StoreSize
()
{
return
Vec_PtrSize
(
s_GlobalFrame
->
vStore
);
}
void
*
Abc_FrameReadLibLut
()
{
return
s_GlobalFrame
->
pLibLut
;
}
void
*
Abc_FrameReadLibGen
()
{
return
s_GlobalFrame
->
pLibGen
;
}
void
*
Abc_FrameReadLibSuper
()
{
return
s_GlobalFrame
->
pLibSuper
;
}
...
...
@@ -53,8 +53,6 @@ void * Abc_FrameReadManDd() { if ( s_GlobalFrame->dd ==
void
*
Abc_FrameReadManDec
()
{
if
(
s_GlobalFrame
->
pManDec
==
NULL
)
s_GlobalFrame
->
pManDec
=
Dec_ManStart
();
return
s_GlobalFrame
->
pManDec
;
}
char
*
Abc_FrameReadFlag
(
char
*
pFlag
)
{
return
Cmd_FlagReadByName
(
s_GlobalFrame
,
pFlag
);
}
void
Abc_FrameSetNtkStore
(
Abc_Ntk_t
*
pNtk
)
{
s_GlobalFrame
->
pStored
=
pNtk
;
}
void
Abc_FrameSetNtkStoreSize
(
int
nStored
)
{
s_GlobalFrame
->
nStored
=
nStored
;
}
void
Abc_FrameSetLibLut
(
void
*
pLib
)
{
s_GlobalFrame
->
pLibLut
=
pLib
;
}
void
Abc_FrameSetLibGen
(
void
*
pLib
)
{
s_GlobalFrame
->
pLibGen
=
pLib
;
}
void
Abc_FrameSetLibSuper
(
void
*
pLib
)
{
s_GlobalFrame
->
pLibSuper
=
pLib
;
}
...
...
@@ -113,6 +111,8 @@ Abc_Frame_t * Abc_FrameAllocate()
// set the starting step
p
->
nSteps
=
1
;
p
->
fBatchMode
=
0
;
// networks to be used by choice
p
->
vStore
=
Vec_PtrAlloc
(
16
);
// initialize decomposition manager
define_cube_size
(
20
);
set_espresso_flags
();
...
...
@@ -145,6 +145,7 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
if
(
p
->
pLibVer
)
Abc_LibFree
(
p
->
pLibVer
,
NULL
);
if
(
p
->
pManDec
)
Dec_ManStop
(
p
->
pManDec
);
if
(
p
->
dd
)
Extra_StopManager
(
p
->
dd
);
if
(
p
->
vStore
)
Vec_PtrFree
(
p
->
vStore
);
Abc_FrameDeleteAllNetworks
(
p
);
free
(
p
);
s_GlobalFrame
=
NULL
;
...
...
src/base/main/mainInt.h
View file @
b2470dd3
...
...
@@ -63,8 +63,7 @@ struct Abc_Frame_t_
int
TimeCommand
;
// the runtime of the last command
int
TimeTotal
;
// the total runtime of all commands
// temporary storage for structural choices
Abc_Ntk_t
*
pStored
;
// the stored networks
int
nStored
;
// the number of stored networks
Vec_Ptr_t
*
vStore
;
// networks to be used by choice
// decomposition package
void
*
pManDec
;
// decomposition manager
DdManager
*
dd
;
// temporary BDD package
...
...
src/opt/lpk/lpkAbc
Core
.c
→
src/opt/lpk/lpkAbc
Dec
.c
View file @
b2470dd3
/**CFile****************************************************************
FileName [lpkAbc
Core
.c]
FileName [lpkAbc
Dec
.c]
SystemName [ABC: Logic synthesis and verification system.]
...
...
@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkAbc
Core
.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
Revision [$Id: lpkAbc
Dec
.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
...
...
@@ -39,7 +39,7 @@
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Lpk_
FunImplement
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
Lpk_Fun_t
*
p
)
Abc_Obj_t
*
Lpk_
ImplementFun
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
Lpk_Fun_t
*
p
)
{
Abc_Obj_t
*
pObjNew
;
int
i
;
...
...
@@ -73,7 +73,7 @@ Abc_Obj_t * Lpk_FunImplement( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Lpk_Fun_t *
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Lpk_
Lpt
Implement
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
int
nLeavesOld
)
Abc_Obj_t
*
Lpk_Implement
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
int
nLeavesOld
)
{
Lpk_Fun_t
*
pFun
;
Abc_Obj_t
*
pRes
;
...
...
@@ -81,7 +81,7 @@ Abc_Obj_t * Lpk_LptImplement( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, int nLeaves
for
(
i
=
Vec_PtrSize
(
vLeaves
)
-
1
;
i
>=
nLeavesOld
;
i
--
)
{
pFun
=
Vec_PtrEntry
(
vLeaves
,
i
);
pRes
=
Lpk_
FunImplement
(
pNtk
,
vLeaves
,
pFun
);
pRes
=
Lpk_
ImplementFun
(
pNtk
,
vLeaves
,
pFun
);
Vec_PtrWriteEntry
(
vLeaves
,
i
,
pRes
);
Lpk_FunFree
(
pFun
);
}
...
...
@@ -99,7 +99,7 @@ Abc_Obj_t * Lpk_LptImplement( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, int nLeaves
SeeAlso []
***********************************************************************/
int
Lpk_
Lpk
Decompose_rec
(
Lpk_Fun_t
*
p
)
int
Lpk_Decompose_rec
(
Lpk_Fun_t
*
p
)
{
Lpk_Fun_t
*
p2
;
int
VarPol
;
...
...
@@ -107,14 +107,14 @@ int Lpk_LpkDecompose_rec( Lpk_Fun_t * p )
if
(
p
->
nVars
<=
p
->
nLutK
)
return
1
;
// check if decomposition exists
VarPol
=
Lpk_
FunAnalizeMux
(
p
);
VarPol
=
Lpk_
MuxAnalize
(
p
);
if
(
VarPol
==
-
1
)
return
0
;
// split and call recursively
p2
=
Lpk_
FunSplitMux
(
p
,
VarPol
);
if
(
!
Lpk_
Lpk
Decompose_rec
(
p2
)
)
p2
=
Lpk_
MuxSplit
(
p
,
VarPol
);
if
(
!
Lpk_Decompose_rec
(
p2
)
)
return
0
;
return
Lpk_
Lpk
Decompose_rec
(
p
);
return
Lpk_Decompose_rec
(
p
);
}
...
...
@@ -129,7 +129,7 @@ int Lpk_LpkDecompose_rec( Lpk_Fun_t * p )
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Lpk_
Lpk
Decompose
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
unsigned
*
pTruth
,
int
nLutK
,
int
AreaLim
,
int
DelayLim
)
Abc_Obj_t
*
Lpk_Decompose
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
unsigned
*
pTruth
,
int
nLutK
,
int
AreaLim
,
int
DelayLim
)
{
Lpk_Fun_t
*
p
;
Abc_Obj_t
*
pObjNew
=
NULL
;
...
...
@@ -139,8 +139,8 @@ Abc_Obj_t * Lpk_LpkDecompose( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned *
p
=
Lpk_FunCreate
(
pNtk
,
vLeaves
,
pTruth
,
nLutK
,
AreaLim
,
DelayLim
);
Lpk_FunSuppMinimize
(
p
);
// decompose the function
if
(
Lpk_
Lpk
Decompose_rec
(
p
)
)
pObjNew
=
Lpk_
Lpt
Implement
(
pNtk
,
vLeaves
,
nLeaves
);
if
(
Lpk_Decompose_rec
(
p
)
)
pObjNew
=
Lpk_Implement
(
pNtk
,
vLeaves
,
nLeaves
);
else
{
for
(
i
=
Vec_PtrSize
(
vLeaves
)
-
1
;
i
>=
nLeaves
;
i
--
)
...
...
src/opt/lpk/lpkAbcDsd.c
View file @
b2470dd3
...
...
@@ -6,7 +6,7 @@
PackageName [Fast Boolean matching for LUT structures.]
Synopsis []
Synopsis [
LUT-decomposition based on recursive DSD.
]
Author [Alan Mishchenko]
...
...
@@ -266,7 +266,7 @@ void Lpk_FunFreeTruthTables( Lpk_Fun_t * p, int nCofDepth, unsigned * ppTruths[5
SeeAlso []
***********************************************************************/
Lpk_Res_t
*
Lpk_
FunAnalizeDsd
(
Lpk_Fun_t
*
p
,
int
nCofDepth
)
Lpk_Res_t
*
Lpk_
DsdAnalize
(
Lpk_Fun_t
*
p
,
int
nCofDepth
)
{
static
Lpk_Res_t
Res
,
*
pRes
=
&
Res
;
unsigned
*
ppTruths
[
5
][
16
];
...
...
@@ -330,7 +330,7 @@ Lpk_Res_t * Lpk_FunAnalizeDsd( Lpk_Fun_t * p, int nCofDepth )
SeeAlso []
***********************************************************************/
Lpk_Fun_t
*
Lpk_
FunSplitDsd
(
Lpk_Fun_t
*
p
,
char
*
pCofVars
,
int
nCofVars
,
unsigned
uBoundSet
)
Lpk_Fun_t
*
Lpk_
DsdSplit
(
Lpk_Fun_t
*
p
,
char
*
pCofVars
,
int
nCofVars
,
unsigned
uBoundSet
)
{
Kit_DsdMan_t
*
pDsdMan
;
Kit_DsdNtk_t
*
pNtkDec
,
*
pTemp
;
...
...
src/opt/lpk/lpkAbcMux.c
View file @
b2470dd3
...
...
@@ -6,7 +6,7 @@
PackageName [Fast Boolean matching for LUT structures.]
Synopsis [
Iterat
ive MUX decomposition.]
Synopsis [
LUT-decomposition based on recurs
ive MUX decomposition.]
Author [Alan Mishchenko]
...
...
@@ -85,7 +85,7 @@ void Lpk_FunComputeCofSupps( Lpk_Fun_t * p, unsigned * puSupps )
SeeAlso []
***********************************************************************/
int
Lpk_
FunAnalizeMux
(
Lpk_Fun_t
*
p
)
int
Lpk_
MuxAnalize
(
Lpk_Fun_t
*
p
)
{
unsigned
puSupps
[
32
]
=
{
0
};
int
nSuppSize0
,
nSuppSize1
,
Delay
,
Delay0
,
Delay1
,
DelayA
,
DelayB
;
...
...
@@ -193,7 +193,7 @@ int Lpk_FunAnalizeMux( Lpk_Fun_t * p )
SeeAlso []
***********************************************************************/
Lpk_Fun_t
*
Lpk_
FunSplitMux
(
Lpk_Fun_t
*
p
,
int
VarPol
)
Lpk_Fun_t
*
Lpk_
MuxSplit
(
Lpk_Fun_t
*
p
,
int
VarPol
)
{
Lpk_Fun_t
*
pNew
;
unsigned
*
pTruth
=
Lpk_FunTruth
(
p
,
0
);
...
...
src/opt/lpk/lpkAbc
Fun
.c
→
src/opt/lpk/lpkAbc
Util
.c
View file @
b2470dd3
/**CFile****************************************************************
FileName [lpkAbc
Fun
.c]
FileName [lpkAbc
Util
.c]
SystemName [ABC: Logic synthesis and verification system.]
...
...
@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkAbc
Fun
.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
Revision [$Id: lpkAbc
Util
.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
...
...
src/opt/lpk/lpkCore.c
View file @
b2470dd3
...
...
@@ -378,7 +378,7 @@ p->timeTruth += clock() - clk;
// update the network
clk
=
clock
();
pObjNew
=
Lpk_
Lpk
Decompose
(
p
->
pNtk
,
vLeaves
,
pTruth
,
p
->
pPars
->
nLutSize
,
pObjNew
=
Lpk_Decompose
(
p
->
pNtk
,
vLeaves
,
pTruth
,
p
->
pPars
->
nLutSize
,
(
int
)
pCut
->
nNodes
-
(
int
)
pCut
->
nNodesDup
-
1
,
Abc_ObjRequiredLevel
(
p
->
pObj
)
);
p
->
timeEval
+=
clock
()
-
clk
;
...
...
src/opt/lpk/lpkInt.h
View file @
b2470dd3
...
...
@@ -118,21 +118,7 @@ struct Lpk_Man_t_
};
// preliminary decomposition result
typedef
struct
Lpk_Res_t_
Lpk_Res_t
;
struct
Lpk_Res_t_
{
int
nBSVars
;
unsigned
BSVars
;
int
nCofVars
;
char
pCofVars
[
4
];
int
nSuppSizeS
;
int
nSuppSizeL
;
int
DelayEst
;
int
AreaEst
;
};
// function to be decomposed
// internal representation of the function to be decomposed
typedef
struct
Lpk_Fun_t_
Lpk_Fun_t
;
struct
Lpk_Fun_t_
{
...
...
@@ -148,15 +134,23 @@ struct Lpk_Fun_t_
unsigned
pTruth
[
0
];
// the truth table (contains room for three truth tables)
};
#define Lpk_SuppForEachVar( Supp, Var )\
for ( Var = 0; Var < 16; Var++ )\
if ( !(Supp & (1<<Var)) ) {} else
static
inline
int
Lpk_LutNumVars
(
int
nLutsLim
,
int
nLutK
)
{
return
nLutsLim
*
(
nLutK
-
1
)
+
1
;
}
static
inline
int
Lpk_LutNumLuts
(
int
nVarsMax
,
int
nLutK
)
{
return
(
nVarsMax
-
1
)
/
(
nLutK
-
1
)
+
(
int
)((
nVarsMax
-
1
)
%
(
nLutK
-
1
)
>
0
);
}
static
inline
unsigned
*
Lpk_FunTruth
(
Lpk_Fun_t
*
p
,
int
Num
)
{
assert
(
Num
<
3
);
return
p
->
pTruth
+
Kit_TruthWordNum
(
p
->
nVars
)
*
Num
;
}
// preliminary decomposition result
typedef
struct
Lpk_Res_t_
Lpk_Res_t
;
struct
Lpk_Res_t_
{
int
nBSVars
;
// the number of bound set variables
unsigned
BSVars
;
// the bound set
int
nCofVars
;
// the number of cofactoring variables
char
pCofVars
[
4
];
// the cofactoring variables
int
nSuppSizeS
;
// support size of the smaller (decomposed) function
int
nSuppSizeL
;
// support size of the larger (composition) function
int
DelayEst
;
// estimated delay of the decomposition
int
AreaEst
;
// estimated area of the decomposition
};
static
inline
int
Lpk_LutNumVars
(
int
nLutsLim
,
int
nLutK
)
{
return
nLutsLim
*
(
nLutK
-
1
)
+
1
;
}
static
inline
int
Lpk_LutNumLuts
(
int
nVarsMax
,
int
nLutK
)
{
return
(
nVarsMax
-
1
)
/
(
nLutK
-
1
)
+
(
int
)((
nVarsMax
-
1
)
%
(
nLutK
-
1
)
>
0
);
}
static
inline
unsigned
*
Lpk_FunTruth
(
Lpk_Fun_t
*
p
,
int
Num
)
{
assert
(
Num
<
3
);
return
p
->
pTruth
+
Kit_TruthWordNum
(
p
->
nVars
)
*
Num
;
}
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
...
...
@@ -172,14 +166,23 @@ static inline unsigned * Lpk_FunTruth( Lpk_Fun_t * p, int Num ) { assert( Num <
for ( i = 0; (i < (int)(pCut)->nNodes) && (((pObj) = Abc_NtkObj(pNtk, (pCut)->pNodes[i])), 1); i++ )
#define Lpk_CutForEachNodeReverse( pNtk, pCut, pObj, i ) \
for ( i = (int)(pCut)->nNodes - 1; (i >= 0) && (((pObj) = Abc_NtkObj(pNtk, (pCut)->pNodes[i])), 1); i-- )
#define Lpk_SuppForEachVar( Supp, Var )\
for ( Var = 0; Var < 16; Var++ )\
if ( !(Supp & (1<<Var)) ) {} else
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== lpkAbcCore.c ============================================================*/
extern
Abc_Obj_t
*
Lpk_LpkDecompose
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
unsigned
*
pTruth
,
int
nLutK
,
int
AreaLim
,
int
DelayLim
);
/*=== lpkAbcFun.c ============================================================*/
/*=== lpkAbcDec.c ============================================================*/
extern
Abc_Obj_t
*
Lpk_Decompose
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
unsigned
*
pTruth
,
int
nLutK
,
int
AreaLim
,
int
DelayLim
);
/*=== lpkAbcDsd.c ============================================================*/
extern
Lpk_Res_t
*
Lpk_DsdAnalize
(
Lpk_Fun_t
*
p
,
int
nCofDepth
);
extern
Lpk_Fun_t
*
Lpk_DsdSplit
(
Lpk_Fun_t
*
p
,
char
*
pCofVars
,
int
nCofVars
,
unsigned
uBoundSet
);
/*=== lpkAbcMux.c ============================================================*/
extern
int
Lpk_MuxAnalize
(
Lpk_Fun_t
*
p
);
extern
Lpk_Fun_t
*
Lpk_MuxSplit
(
Lpk_Fun_t
*
p
,
int
VarPol
);
/*=== lpkAbcUtil.c ============================================================*/
extern
Lpk_Fun_t
*
Lpk_FunAlloc
(
int
nVars
);
extern
void
Lpk_FunFree
(
Lpk_Fun_t
*
p
);
extern
Lpk_Fun_t
*
Lpk_FunCreate
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vLeaves
,
unsigned
*
pTruth
,
int
nLutK
,
int
AreaLim
,
int
DelayLim
);
...
...
@@ -187,12 +190,6 @@ extern Lpk_Fun_t * Lpk_FunDup( Lpk_Fun_t * p, unsigned * pTruth );
extern
void
Lpk_FunSuppMinimize
(
Lpk_Fun_t
*
p
);
extern
int
Lpk_SuppDelay
(
unsigned
uSupp
,
char
*
pDelays
);
extern
int
Lpk_SuppToVars
(
unsigned
uBoundSet
,
char
*
pVars
);
/*=== lpkAbcDsd.c ============================================================*/
extern
Lpk_Res_t
*
Lpk_FunAnalizeDsd
(
Lpk_Fun_t
*
p
,
int
nCofDepth
);
extern
Lpk_Fun_t
*
Lpk_FunSplitDsd
(
Lpk_Fun_t
*
p
,
char
*
pCofVars
,
int
nCofVars
,
unsigned
uBoundSet
);
/*=== lpkAbcMux.c ============================================================*/
extern
int
Lpk_FunAnalizeMux
(
Lpk_Fun_t
*
p
);
extern
Lpk_Fun_t
*
Lpk_FunSplitMux
(
Lpk_Fun_t
*
p
,
int
VarPol
);
/*=== lpkCut.c =========================================================*/
...
...
src/opt/lpk/module.make
View file @
b2470dd3
SRC
+=
src/opt/lpk/lpkCore.c
\
src/opt/lpk/lpkAbcDec.c
\
src/opt/lpk/lpkAbcMux.c
\
src/opt/lpk/lpkAbcDsd.c
\
src/opt/lpk/lpkAbcUtil.c
\
src/opt/lpk/lpkCut.c
\
src/opt/lpk/lpkMan.c
\
src/opt/lpk/lpkMap.c
\
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment