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
98cf5698
Commit
98cf5698
authored
May 05, 2013
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New fast extract.
parent
7a78e303
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
71 additions
and
17 deletions
+71
-17
src/base/abci/abcFx.c
+71
-17
No files found.
src/base/abci/abcFx.c
View file @
98cf5698
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
PackageName [Network and node package.]
PackageName [Network and node package.]
Synopsis [I
nterface with the fast_extract package
.]
Synopsis [I
mplementation of traditional "fast_extract" algorithm
.]
Author [Alan Mishchenko]
Author [Alan Mishchenko]
...
@@ -29,6 +29,59 @@ ABC_NAMESPACE_IMPL_START
...
@@ -29,6 +29,59 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/*
The code in this file implements the traditional "fast_extract" algorithm,
which extracts two-cube divisors concurrently with single-cube two-literal divisors,
as proposed in the TCAD'92 paper by J. Rajski and J. Vasudevamurthi.
Integration notes:
It is assumed that each object (primary input or internal node) in the original network
is associated with a unique integer number, called object identifier (ObjId, for short).
The user's input data given to 'fast_extract" is an array of cubes (pMan->vCubes).
Each cube is an array of integers, in which the first entry contains ObjId of the node,
to which this cube belongs in the original network. The following entries of a cube are
SOP literals of this cube. Each literal is represtned as 2*FaninId + ComplAttr, where FaninId
is ObjId of the fanin node and ComplAttr is 1 if literal is complemented, and 0 otherwise.
The user's output data produced by 'fast_extract' is also an array of cubes (pMan->vCubes).
If no divisors have been extracted, the output array is the same as the input array.
If some divisors have been extracted, the output array contains updated old cubes and new cubes
representing the extracted divisors. The new divisors have their ObjId starting from the
largest ObjId used in the cubes. To give the user more flexibility, which may be needed when some
ObjIds are already used for primary output nodes, which do not participate in fast_extract,
the parameter ObjIdMax is passed to procedure Fx_FastExtract(). The new divisors will receive
their ObjId starting from ObjIdMax onward, as divisor extaction proceeds.
The following two requirements are imposed on the input and output array of cubes:
(1) The array of cubes should be sorted by the first entry in each cube (that is, cubes belonging
to the same node should form a contiguous range).
(2) Literals in a cube should be sorted in the increasing order of the integer numbers.
To integrate this code into a calling application, such as ABC, the input cube array should
be generated (below this is done by the procedure Abc_NtkFxRetrieve) and the output cube array
should be incorporated into the current network (below this is done by the procedure Abc_NtkFxInsert).
In essence, the latter procedure performs the following:
- removes the current fanins and SOPs of each node in the network
- adds new nodes for each new divisor introduced by "fast_extract"
- populates fanins and SOPs of each node, both old and new, as indicaded by the resulting cube array.
Implementation notes:
The implementation is optimized for simplicity and speed of computation.
(1) Main input/output data-structure (pMan->vCubes) is the array of cubes which is dynamically updated by the algorithm.
(2) Auxiliary data-structure (pMan->vLits) is the array of arrays. The i-th array contains IDs of cubes which have literal i.
It may be convenient to think about the first (second) array as rows (columns) of a sparse matrix,
although the sparse matrix data-structure is not used in the proposed implementation.
(3) Hash table (pMan->pHash) hashes the normalized divisors (represented as integer arrays) into integer numbers.
(4) Array of divisor weights (pMan->vWeights), that is, the number of SOP literals to be saved by extacting each divisor.
(5) Priority queue (pMan->vPrio), which sorts divisor (integer numbers) by their weight
(6) Integer array (pMan->vVarCube), which maps each ObjId into the first cube of this object,
or -1, if there is no cubes as in the case of a primary input.
*/
typedef
struct
Fx_Man_t_
Fx_Man_t
;
typedef
struct
Fx_Man_t_
Fx_Man_t
;
struct
Fx_Man_t_
struct
Fx_Man_t_
{
{
...
@@ -36,22 +89,23 @@ struct Fx_Man_t_
...
@@ -36,22 +89,23 @@ struct Fx_Man_t_
Vec_Wec_t
*
vCubes
;
// cube -> lit
Vec_Wec_t
*
vCubes
;
// cube -> lit
// internal data
// internal data
Vec_Wec_t
*
vLits
;
// lit -> cube
Vec_Wec_t
*
vLits
;
// lit -> cube
Vec_Int_t
*
vCounts
;
// literal counts (currently
un
used)
Vec_Int_t
*
vCounts
;
// literal counts (currently
not
used)
Hsh_VecMan_t
*
pHash
;
// hash table
of
divisors
Hsh_VecMan_t
*
pHash
;
// hash table
for normalized
divisors
Vec_Flt_t
*
vWeights
;
// divisor weights
Vec_Flt_t
*
vWeights
;
// divisor weights
Vec_Que_t
*
vPrio
;
// priority queue
Vec_Que_t
*
vPrio
;
// priority queue
for divisors by weight
Vec_Int_t
*
vVarCube
;
// mapping
var
into its first cube
Vec_Int_t
*
vVarCube
;
// mapping
ObjId
into its first cube
// temporary
arrays used for updating data-structure after one extraction
// temporary
data to update the data-structure when a divisor is extracted
Vec_Int_t
*
vCubesS
;
// single cubes for the given divisor
Vec_Int_t
*
vCubesS
;
// single cubes for the given divisor
Vec_Int_t
*
vCubesD
;
// cube pairs for the given divisor
Vec_Int_t
*
vCubesD
;
// cube pairs for the given divisor
Vec_Int_t
*
vCompls
;
// complement
s of cube pairs
Vec_Int_t
*
vCompls
;
// complement
ed attribute of each cube pair
Vec_Int_t
*
vCubeFree
;
// cube-free divisor
Vec_Int_t
*
vCubeFree
;
// cube-free divisor
Vec_Int_t
*
vDiv
;
// divisor
Vec_Int_t
*
vDiv
;
//
selected
divisor
// statistics
// statistics
clock_t
timeStart
;
// starting time
clock_t
timeStart
;
// starting time
int
nVars
;
// original problem variables
int
nVars
;
// original problem variables
int
nLits
;
// the number of SOP literals
int
nLits
;
// the number of SOP literals
int
nDivs
;
// the number of extracted divisors
int
nDivs
;
// the number of extracted divisors
int
nCompls
;
// the number of complements
int
nPairsS
;
// number of lit pairs
int
nPairsS
;
// number of lit pairs
int
nPairsD
;
// number of cube pairs
int
nPairsD
;
// number of cube pairs
int
nDivsS
;
// single cube divisors
int
nDivsS
;
// single cube divisors
...
@@ -63,8 +117,6 @@ static inline int Fx_ManGetFirstVarCube( Fx_Man_t * p, Vec_Int_t * vCube ) { ret
...
@@ -63,8 +117,6 @@ static inline int Fx_ManGetFirstVarCube( Fx_Man_t * p, Vec_Int_t * vCube ) { ret
#define Fx_ManForEachCubeVec( vVec, vCubes, vCube, i ) \
#define Fx_ManForEachCubeVec( vVec, vCubes, vCube, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && ((vCube) = Vec_WecEntry(vCubes, Vec_IntEntry(vVec, i))); i++ )
for ( i = 0; (i < Vec_IntSize(vVec)) && ((vCube) = Vec_WecEntry(vCubes, Vec_IntEntry(vVec, i))); i++ )
static
int
Fx_FastExtract
(
Vec_Wec_t
*
vCubes
,
int
nVars
,
int
fVerbose
);
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
@@ -248,6 +300,7 @@ int Abc_NtkFxCheck( Abc_Ntk_t * pNtk )
...
@@ -248,6 +300,7 @@ int Abc_NtkFxCheck( Abc_Ntk_t * pNtk )
***********************************************************************/
***********************************************************************/
int
Abc_NtkFxPerform
(
Abc_Ntk_t
*
pNtk
,
int
fVerbose
)
int
Abc_NtkFxPerform
(
Abc_Ntk_t
*
pNtk
,
int
fVerbose
)
{
{
extern
int
Fx_FastExtract
(
Vec_Wec_t
*
vCubes
,
int
ObjIdMax
,
int
fVerbose
);
Vec_Wec_t
*
vCubes
;
Vec_Wec_t
*
vCubes
;
assert
(
Abc_NtkIsSopLogic
(
pNtk
)
);
assert
(
Abc_NtkIsSopLogic
(
pNtk
)
);
// check unique fanins
// check unique fanins
...
@@ -372,8 +425,9 @@ static inline void Fx_PrintDiv( Fx_Man_t * p, int iDiv )
...
@@ -372,8 +425,9 @@ static inline void Fx_PrintDiv( Fx_Man_t * p, int iDiv )
printf
(
"%4d : "
,
p
->
nDivs
);
printf
(
"%4d : "
,
p
->
nDivs
);
printf
(
"Div %7d : "
,
iDiv
);
printf
(
"Div %7d : "
,
iDiv
);
printf
(
"Weight %5d "
,
(
int
)
Vec_FltEntry
(
p
->
vWeights
,
iDiv
)
);
printf
(
"Weight %5d "
,
(
int
)
Vec_FltEntry
(
p
->
vWeights
,
iDiv
)
);
// printf( "Compl %4d ", p->nCompls );
Fx_PrintDivOne
(
Hsh_VecReadEntry
(
p
->
pHash
,
iDiv
)
);
Fx_PrintDivOne
(
Hsh_VecReadEntry
(
p
->
pHash
,
iDiv
)
);
for
(
i
=
Vec_IntSize
(
Hsh_VecReadEntry
(
p
->
pHash
,
iDiv
))
+
3
;
i
<
20
;
i
++
)
for
(
i
=
Vec_IntSize
(
Hsh_VecReadEntry
(
p
->
pHash
,
iDiv
))
+
3
;
i
<
16
;
i
++
)
printf
(
" "
);
printf
(
" "
);
printf
(
"Lits =%7d "
,
p
->
nLits
);
printf
(
"Lits =%7d "
,
p
->
nLits
);
printf
(
"Divs =%8d "
,
Hsh_VecSize
(
p
->
pHash
)
);
printf
(
"Divs =%8d "
,
Hsh_VecSize
(
p
->
pHash
)
);
...
@@ -873,7 +927,7 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
...
@@ -873,7 +927,7 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
Vec_Int_t
*
vCube
,
*
vCube2
,
*
vLitP
,
*
vLitN
;
Vec_Int_t
*
vCube
,
*
vCube2
,
*
vLitP
,
*
vLitN
;
Vec_Int_t
*
vDiv
=
p
->
vDiv
;
Vec_Int_t
*
vDiv
=
p
->
vDiv
;
int
nLitsNew
=
p
->
nLits
-
(
int
)
Vec_FltEntry
(
p
->
vWeights
,
iDiv
);
int
nLitsNew
=
p
->
nLits
-
(
int
)
Vec_FltEntry
(
p
->
vWeights
,
iDiv
);
int
i
,
k
,
Lit0
,
Lit1
,
iVarNew
,
fComplAny
,
RetValue
;
int
i
,
k
,
Lit0
,
Lit1
,
iVarNew
,
RetValue
;
// get the divisor and select pivot variables
// get the divisor and select pivot variables
p
->
nDivs
++
;
p
->
nDivs
++
;
...
@@ -952,13 +1006,13 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
...
@@ -952,13 +1006,13 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
}
}
// create updated double-cube divisor cube pairs
// create updated double-cube divisor cube pairs
k
=
0
;
k
=
0
;
fComplAny
=
0
;
p
->
nCompls
=
0
;
assert
(
Vec_IntSize
(
p
->
vCubesD
)
%
2
==
0
);
assert
(
Vec_IntSize
(
p
->
vCubesD
)
%
2
==
0
);
assert
(
Vec_IntSize
(
p
->
vCubesD
)
==
2
*
Vec_IntSize
(
p
->
vCompls
)
);
assert
(
Vec_IntSize
(
p
->
vCubesD
)
==
2
*
Vec_IntSize
(
p
->
vCompls
)
);
for
(
i
=
0
;
i
<
Vec_IntSize
(
p
->
vCubesD
);
i
+=
2
)
for
(
i
=
0
;
i
<
Vec_IntSize
(
p
->
vCubesD
);
i
+=
2
)
{
{
int
fCompl
=
Vec_IntEntry
(
p
->
vCompls
,
i
/
2
);
int
fCompl
=
Vec_IntEntry
(
p
->
vCompls
,
i
/
2
);
fComplAny
|
=
fCompl
;
p
->
nCompls
+
=
fCompl
;
vCube
=
Vec_WecEntry
(
p
->
vCubes
,
Vec_IntEntry
(
p
->
vCubesD
,
i
)
);
vCube
=
Vec_WecEntry
(
p
->
vCubes
,
Vec_IntEntry
(
p
->
vCubesD
,
i
)
);
vCube2
=
Vec_WecEntry
(
p
->
vCubes
,
Vec_IntEntry
(
p
->
vCubesD
,
i
+
1
)
);
vCube2
=
Vec_WecEntry
(
p
->
vCubes
,
Vec_IntEntry
(
p
->
vCubesD
,
i
+
1
)
);
RetValue
=
Fx_ManDivRemoveLits
(
vCube
,
vDiv
,
fCompl
);
// cube 2*i
RetValue
=
Fx_ManDivRemoveLits
(
vCube
,
vDiv
,
fCompl
);
// cube 2*i
...
@@ -1020,7 +1074,7 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
...
@@ -1020,7 +1074,7 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
Vec_IntForEachEntry
(
vDiv
,
Lit0
,
i
)
Vec_IntForEachEntry
(
vDiv
,
Lit0
,
i
)
{
{
Vec_IntTwoRemove
(
Vec_WecEntry
(
p
->
vLits
,
Abc_Lit2Var
(
Lit0
)),
p
->
vCubesD
);
Vec_IntTwoRemove
(
Vec_WecEntry
(
p
->
vLits
,
Abc_Lit2Var
(
Lit0
)),
p
->
vCubesD
);
if
(
fComplAny
&&
i
>
1
)
// the last two lits are possibly complemented
if
(
p
->
nCompls
&&
i
>
1
)
// the last two lits are possibly complemented
Vec_IntTwoRemove
(
Vec_WecEntry
(
p
->
vLits
,
Abc_LitNot
(
Abc_Lit2Var
(
Lit0
))),
p
->
vCubesD
);
Vec_IntTwoRemove
(
Vec_WecEntry
(
p
->
vLits
,
Abc_LitNot
(
Abc_Lit2Var
(
Lit0
))),
p
->
vCubesD
);
}
}
...
@@ -1041,14 +1095,14 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
...
@@ -1041,14 +1095,14 @@ void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
int
Fx_FastExtract
(
Vec_Wec_t
*
vCubes
,
int
nVars
,
int
fVerbose
)
int
Fx_FastExtract
(
Vec_Wec_t
*
vCubes
,
int
ObjIdMax
,
int
fVerbose
)
{
{
int
fVeryVerbose
=
0
;
int
fVeryVerbose
=
0
;
Fx_Man_t
*
p
;
Fx_Man_t
*
p
;
clock_t
clk
=
clock
();
clock_t
clk
=
clock
();
// initialize the data-structure
// initialize the data-structure
p
=
Fx_ManStart
(
vCubes
);
p
=
Fx_ManStart
(
vCubes
);
Fx_ManCreateLiterals
(
p
,
nVars
);
Fx_ManCreateLiterals
(
p
,
ObjIdMax
);
Fx_ManCreateDivisors
(
p
);
Fx_ManCreateDivisors
(
p
);
if
(
fVeryVerbose
)
if
(
fVeryVerbose
)
Fx_PrintMatrix
(
p
);
Fx_PrintMatrix
(
p
);
...
...
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