Command rewire

This commit is contained in:
jiunhaochen
2025-03-01 23:44:55 +08:00
parent 75ef06017d
commit 083d3884dd
17 changed files with 2681 additions and 1 deletions

1
.gitignore vendored
View File

@@ -31,6 +31,7 @@ src/aig/ddb/
*.plg
*.zip
*.DS_Store
abcspaceext.dsw
abcext.dsp

View File

@@ -26,7 +26,7 @@ MODULES := \
src/misc/vec src/misc/hash src/misc/tim src/misc/bzlib src/misc/zlib \
src/misc/mem src/misc/bar src/misc/bbl src/misc/parse \
src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt src/opt/rar \
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \
src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose src/sat/glucose2 \
src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \

View File

@@ -295,6 +295,7 @@ static int Abc_CommandAttach ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandSuperChoice ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSuperChoiceLut ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTimeScale ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRewire ( Abc_Frame_t * pAbc, int argc, char ** argv );
//static int Abc_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
//static int Abc_CommandFpgaFast ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -523,6 +524,7 @@ static int Abc_CommandAbc9Ttopt ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9Transduction ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9TranStoch ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Rrr ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Rewire ( Abc_Frame_t * pAbc, int argc, char ** argv );
//#endif
static int Abc_CommandAbc9LNetMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Unmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -1099,6 +1101,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "SC mapping", "superc", Abc_CommandSuperChoice, 1 );
Cmd_CommandAdd( pAbc, "SC mapping", "supercl", Abc_CommandSuperChoiceLut, 1 );
Cmd_CommandAdd( pAbc, "SC mapping", "timescale", Abc_CommandTimeScale, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "rewire", Abc_CommandRewire, 1 );
// Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Abc_CommandFpga, 1 );
// Cmd_CommandAdd( pAbc, "FPGA mapping", "ffpga", Abc_CommandFpgaFast, 1 );
@@ -1328,6 +1331,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&transduction", Abc_CommandAbc9Transduction, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&transtoch" , Abc_CommandAbc9TranStoch, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&rrr", Abc_CommandAbc9Rrr, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&rewire" , Abc_CommandAbc9Rewire, 0 );
//#endif
Cmd_CommandAdd( pAbc, "ABC9", "&lnetmap", Abc_CommandAbc9LNetMap, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&unmap", Abc_CommandAbc9Unmap, 0 );
@@ -20402,6 +20406,162 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandRewire( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Abc_Ntk_t *Abc_ManRewire(Abc_Ntk_t *pNtk, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
Abc_Ntk_t *pNtk, *pTemp;
int c, nIters = 100000, nExpands = 128, nGrowth = 4, nDivs = -1, nFaninMax = 8, nSeed = 1, nTimeOut = 0, nVerbose = 1, nMode = 0, nDist = 0;
Extra_UtilGetoptReset();
// Cmd_CommandExecute
pNtk = Abc_FrameReadNtk(pAbc);
while ( ( c = Extra_UtilGetopt( argc, argv, "IEGDFSTMLVh" ) ) != EOF ) {
switch ( c ) {
case 'I':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-I\" should be followed by a positive integer.\n" );
goto usage;
}
nIters = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'E':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-E\" should be followed by a positive integer.\n" );
goto usage;
}
nExpands = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'G':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer.\n" );
goto usage;
}
nGrowth = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-D\" should be followed by a positive integer.\n" );
goto usage;
}
nDivs = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-F\" should be followed by a positive integer.\n" );
goto usage;
}
nFaninMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'S':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-S\" should be followed by a positive integer.\n" );
goto usage;
}
nSeed = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'T':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-S\" should be followed by a positive integer.\n" );
goto usage;
}
nTimeOut = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'M':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-M\" should be followed by a positive integer.\n" );
goto usage;
}
nMode = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'L':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-L\" should be followed by a positive integer.\n" );
goto usage;
}
nDist = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'V':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-V\" should be followed by a positive integer.\n" );
goto usage;
}
nVerbose = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'h':
default:
goto usage;
}
}
if ( argc > globalUtilOptind + 1 )
{
Abc_Print( -1, "Wrong number of auguments.\n" );
goto usage;
}
if ( pNtk == NULL )
{
Abc_Print( -1, "Empty network.\n" );
return 1;
}
if ( nMode == 1 && Abc_FrameReadLibGen2() == NULL )
{
Abc_Print( -1, "Library is not available.\n" );
return 1;
}
pTemp = Abc_ManRewire( pNtk, nIters, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nDist, nSeed, nVerbose );
Abc_FrameReplaceCurrentNetwork( pAbc, pTemp );
return 0;
usage:
Abc_Print( -2, "usage: rewrire [-IEGDFSTV <num>]\n" );
Abc_Print( -2, "\t performs AIG re-wiring\n" );
Abc_Print( -2, "\t-I <num> : the number of iterations [default = %d]\n", nIters );
Abc_Print( -2, "\t-E <num> : the number of fanins to add to all nodes [default = %d]\n", nExpands );
Abc_Print( -2, "\t-G <num> : the number of fanins to add to one node [default = %d]\n", nGrowth );
Abc_Print( -2, "\t-D <num> : the number of shared divisors to extract [default = %d]\n", nDivs );
Abc_Print( -2, "\t-F <num> : the limit on the fanin count at a node [default = %d]\n", nFaninMax);
Abc_Print( -2, "\t-L <num> : localization distances [default = %d]\n", nDist);
Abc_Print( -2, "\t-M <num> : optimization target [default = %s]\n", nMode ? "transistor" : "node" );
Abc_Print( -2, "\t-S <num> : the random seed [default = %d]\n", nSeed );
Abc_Print( -2, "\t-T <num> : the timeout in seconds [default = unused]\n" );
Abc_Print( -2, "\t-V <num> : the verbosity level [default = %d]\n", nVerbose );
Abc_Print( -2, "\t-h : prints the command usage\n" );
Abc_Print( -2, "\t\n" );
return 1;
}
/**Function*************************************************************
Synopsis []
@@ -45391,6 +45551,159 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc9Rewire( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Gia_Man_t *Gia_ManRewire(Gia_Man_t *pGia, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
Gia_Man_t *pTemp;
int c, nIters = 100000, nExpands = 128, nGrowth = 4, nDivs = -1, nFaninMax = 8, nSeed = 1, nTimeOut = 0, nVerbose = 1, nMode = 0, nDist = 0;
Extra_UtilGetoptReset();
// Cmd_CommandExecute
while ( ( c = Extra_UtilGetopt( argc, argv, "IEGDFSTMLVh" ) ) != EOF ) {
switch ( c ) {
case 'I':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-I\" should be followed by a positive integer.\n" );
goto usage;
}
nIters = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'E':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-E\" should be followed by a positive integer.\n" );
goto usage;
}
nExpands = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'G':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer.\n" );
goto usage;
}
nGrowth = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-D\" should be followed by a positive integer.\n" );
goto usage;
}
nDivs = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-F\" should be followed by a positive integer.\n" );
goto usage;
}
nFaninMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'S':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-S\" should be followed by a positive integer.\n" );
goto usage;
}
nSeed = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'T':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-S\" should be followed by a positive integer.\n" );
goto usage;
}
nTimeOut = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'M':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-M\" should be followed by a positive integer.\n" );
goto usage;
}
nMode = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'L':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-L\" should be followed by a positive integer.\n" );
goto usage;
}
nDist = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'V':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-V\" should be followed by a positive integer.\n" );
goto usage;
}
nVerbose = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'h':
default:
goto usage;
}
}
if ( argc > globalUtilOptind + 1 )
{
Abc_Print( -1, "Wrong number of auguments.\n" );
goto usage;
}
if ( pAbc->pGia == NULL )
{
Abc_Print( -1, "Empty GIA network.\n" );
return 1;
}
if ( nMode == 1 && Abc_FrameReadLibGen2() == NULL )
{
Abc_Print( -1, "Library is not available.\n" );
return 1;
}
pTemp = Gia_ManRewire( pAbc->pGia, nIters, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nDist, nSeed, nVerbose );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
Abc_Print( -2, "usage: &rewrire [-IEGDFSTV <num>]\n" );
Abc_Print( -2, "\t performs AIG re-wiring\n" );
Abc_Print( -2, "\t-I <num> : the number of iterations [default = %d]\n", nIters );
Abc_Print( -2, "\t-E <num> : the number of fanins to add to all nodes [default = %d]\n", nExpands );
Abc_Print( -2, "\t-G <num> : the number of fanins to add to one node [default = %d]\n", nGrowth );
Abc_Print( -2, "\t-D <num> : the number of shared divisors to extract [default = %d]\n", nDivs );
Abc_Print( -2, "\t-F <num> : the limit on the fanin count at a node [default = %d]\n", nFaninMax);
Abc_Print( -2, "\t-L <num> : localization distances [default = %d]\n", nDist);
Abc_Print( -2, "\t-M <num> : optimization target [default = %s]\n", nMode ? "transistor" : "node" );
Abc_Print( -2, "\t-S <num> : the random seed [default = %d]\n", nSeed );
Abc_Print( -2, "\t-T <num> : the timeout in seconds [default = unused]\n" );
Abc_Print( -2, "\t-V <num> : the verbosity level [default = %d]\n", nVerbose );
Abc_Print( -2, "\t-h : prints the command usage\n" );
Abc_Print( -2, "\t\n" );
return 1;
}
/**Function*************************************************************
Synopsis []

View File

@@ -884,6 +884,73 @@ Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
return vMapping;
}
/**Function*************************************************************
Synopsis [Build mapped network from the mini-mapped format.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromMiniMapping( int *pArray )
{
if ( !pArray ) {
printf("Mapping is not available.\n");
return NULL;
}
Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
if ( !pLib ) {
printf("Library is not available.\n");
return NULL;
}
Abc_Ntk_t *pNtkMapped = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_MAP, 1 );
pNtkMapped->pName = Extra_UtilStrsav( "mapped" );
int nCis, nCos, nNodes, nFlops;
int i, k, nLeaves, Pos = 4;
char * pBuffer, * pName;
Mio_Gate_t *pGate;
nCis = pArray[0];
nCos = pArray[1];
nNodes = pArray[2];
nFlops = pArray[3];
// create pi
for ( i = 0; i < nCis; i++ )
Abc_NtkCreatePi( pNtkMapped );
// create nodes
for ( i = 0; i < nNodes; i++ )
Abc_NtkCreateNode( pNtkMapped );
// create po
for ( i = 0; i < nCos; i++ )
Abc_NtkCreatePo( pNtkMapped );
// connect nodes
for ( i = 0; i < nNodes; i++ )
{
nLeaves = pArray[Pos++];
for ( k = 0; k < nLeaves; k++ )
Abc_ObjAddFanin( Abc_NtkObj( pNtkMapped, nCis + i + 1 ), Abc_NtkObj( pNtkMapped, pArray[Pos++] + 1 ) );
}
for ( i = 0; i < nCos; i++ )
Abc_ObjAddFanin( Abc_NtkCo( pNtkMapped, i ), Abc_NtkObj( pNtkMapped, pArray[Pos++] + 1 ) );
pBuffer = (char *)(pArray + Pos);
for ( i = 0; i < nNodes; i++ )
{
pName = pBuffer;
pBuffer += strlen(pName) + 1;
pGate = Mio_LibraryReadGateByName( pLib, pName, NULL );
Abc_NtkObj( pNtkMapped, nCis + i + 1 )->pData = pGate;
}
Abc_NtkAddDummyPiNames( pNtkMapped );
Abc_NtkAddDummyPoNames( pNtkMapped );
if ( !Abc_NtkCheck( pNtkMapped ) )
fprintf( stdout, "Abc_NtkFromMiniMapping(): Network check has failed.\n" );
return pNtkMapped;
}
/**Function*************************************************************
Synopsis [Prints mapped network represented in mini-mapped format.]
@@ -925,6 +992,26 @@ void Abc_NtkPrintMiniMapping( int * pArray )
}
}
/**Function*************************************************************
Synopsis [Procedures to update internal ABC network using mini-mapped network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkInputMiniMapping( Abc_Frame_t * pAbc, void *p )
{
Abc_Ntk_t * pNtk;
if ( pAbc == NULL )
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
pNtk = Abc_NtkFromMiniMapping( (int *)p );
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
}
/**Function*************************************************************
Synopsis [This procedure outputs an array representing mini-mapped network.]

View File

@@ -144,6 +144,22 @@ Mini_Aig_t * Abc_NtkToMiniAig( Abc_Ntk_t * pNtk )
Mini_AigSetRegNum( p, Abc_NtkLatchNum(pNtk) );
return p;
}
Mini_Aig_t * Abc_MiniAigFromNtk ( Abc_Ntk_t *pNtk )
{
Abc_Ntk_t *pNtkRes = NULL;
Mini_Aig_t *pAig;
if (Abc_NtkHasMapping(pNtk)) {
pNtk = pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 );
if ( pNtkRes == NULL )
{
printf("Strashing has failed.\n" );
return NULL;
}
}
pAig = Abc_NtkToMiniAig(pNtk);
if (pNtkRes) Abc_NtkDelete(pNtkRes);
return pAig;
}
/**Function*************************************************************

4
src/opt/rar/module.make Normal file
View File

@@ -0,0 +1,4 @@
SRC += src/opt/rar/rewire_rng.c \
src/opt/rar/rewire_map.c \
src/opt/rar/rewire_rar.c \
src/opt/rar/rewire_miaig.cpp

45
src/opt/rar/rewire_map.c Normal file
View File

@@ -0,0 +1,45 @@
#include "rewire_map.h"
ABC_NAMESPACE_IMPL_START
extern Abc_Ntk_t *Abc_NtkFromAigPhase(Aig_Man_t *pMan);
extern Abc_Ntk_t *Abc_NtkDarAmap(Abc_Ntk_t *pNtk, Amap_Par_t *pPars);
extern void *Abc_FrameReadLibGen2();
extern Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk );
extern void Abc_NtkPrintMiniMapping( int * pArray );
extern Abc_Ntk_t * Abc_NtkFromMiniMapping( int *vMapping );
extern Mini_Aig_t * Abc_MiniAigFromNtk ( Abc_Ntk_t *pNtk );
Abc_Ntk_t *Gia_ManRewirePut(Gia_Man_t *pGia) {
Aig_Man_t *pMan = Gia_ManToAig(pGia, 0);
Abc_Ntk_t *pNtk = Abc_NtkFromAigPhase(pMan);
Aig_ManStop(pMan);
return pNtk;
}
Abc_Ntk_t *Abc_ManRewireMap(Abc_Ntk_t *pNtk) {
Amap_Par_t Pars, *pPars = &Pars;
Amap_ManSetDefaultParams(pPars);
Abc_Ntk_t *pNtkMapped = Abc_NtkDarAmap(pNtk, pPars);
if (pNtkMapped == NULL) {
Abc_NtkDelete(pNtk);
Abc_Print(-1, "Mapping has failed.\n");
return NULL;
}
return pNtkMapped;
}
Vec_Int_t *Abc_ManRewireNtkWriteMiniMapping(Abc_Ntk_t *pNtk) {
return Abc_NtkWriteMiniMapping(pNtk);
}
Abc_Ntk_t *Abc_ManRewireNtkFromMiniMapping(int *vMapping) {
return Abc_NtkFromMiniMapping(vMapping);
}
Mini_Aig_t *Abc_ManRewireMiniAigFromNtk(Abc_Ntk_t *pNtk) {
return Abc_MiniAigFromNtk(pNtk);
}
ABC_NAMESPACE_IMPL_END

20
src/opt/rar/rewire_map.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef REWIRE_MAP_H
#define REWIRE_MAP_H
#include "base/abc/abc.h"
#include "aig/gia/giaAig.h"
#include "map/amap/amap.h"
#include "map/mio/mio.h"
#include "aig/miniaig/miniaig.h"
ABC_NAMESPACE_HEADER_START
Abc_Ntk_t *Gia_ManRewirePut(Gia_Man_t *pGia);
Abc_Ntk_t *Abc_ManRewireMap(Abc_Ntk_t *pNtk);
Vec_Int_t *Abc_ManRewireNtkWriteMiniMapping(Abc_Ntk_t *pNtk);
Abc_Ntk_t *Abc_ManRewireNtkFromMiniMapping(int *vMapping);
Mini_Aig_t *Abc_ManRewireMiniAigFromNtk(Abc_Ntk_t *pNtk);
ABC_NAMESPACE_HEADER_END
#endif // REWIRE_MAP_H

1159
src/opt/rar/rewire_miaig.cpp Normal file

File diff suppressed because it is too large Load Diff

473
src/opt/rar/rewire_miaig.h Normal file
View File

@@ -0,0 +1,473 @@
#ifndef REWIRE_MIAIG_H
#define REWIRE_MIAIG_H
#define RW_ABC
#ifdef RW_ABC
#include "base/abc/abc.h"
#include "aig/miniaig/miniaig.h"
#include "rewire_map.h"
#else
#ifdef _WIN32
typedef unsigned __int64 word; // 32-bit windows
#else
typedef long long unsigned word; // other platforms
#endif
#ifdef _WIN32
typedef __int64 iword; // 32-bit windows
#else
typedef long long iword; // other platforms
#endif
#endif // RW_ABC
#include "rewire_vec.h"
#include "rewire_tt.h"
#include "rewire_time.h"
#include <vector>
#include <algorithm>
#ifdef RW_ABC
ABC_NAMESPACE_CXX_HEADER_START
#endif // RW_ABC
namespace Rewire {
#if RW_THREADS
// exchange-add operation for atomic operations on reference counters
#if defined __riscv && !defined __riscv_atomic
// riscv target without A extension
static inline int RW_XADD(int *addr, int delta) {
int tmp = *addr;
*addr += delta;
return tmp;
}
#elif defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32)
// atomic increment on the linux version of the Intel(tm) compiler
#define RW_XADD(addr, delta) \
(int)_InterlockedExchangeAdd( \
const_cast<void *>(reinterpret_cast<volatile void *>(addr)), delta)
#elif defined __GNUC__
#if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__)
#ifdef __ATOMIC_ACQ_REL
#define RW_XADD(addr, delta) \
__c11_atomic_fetch_add((_Atomic(int) *)(addr), delta, __ATOMIC_ACQ_REL)
#else
#define RW_XADD(addr, delta) \
__atomic_fetch_add((_Atomic(int) *)(addr), delta, 4)
#endif
#else
#if defined __ATOMIC_ACQ_REL && !defined __clang__
// version for gcc >= 4.7
#define RW_XADD(addr, delta) \
(int)__atomic_fetch_add((unsigned *)(addr), (unsigned)(delta), \
__ATOMIC_ACQ_REL)
#else
#define RW_XADD(addr, delta) \
(int)__sync_fetch_and_add((unsigned *)(addr), (unsigned)(delta))
#endif
#endif
#elif defined _MSC_VER && !defined RC_INVOKED
#define RW_XADD(addr, delta) \
(int)_InterlockedExchangeAdd((long volatile *)addr, delta)
#else
// thread-unsafe branch
static inline int RW_XADD(int *addr, int delta) {
int tmp = *addr;
*addr += delta;
return tmp;
}
#endif
#else // RW_THREADS
static inline int RW_XADD(int *addr, int delta) {
int tmp = *addr;
*addr += delta;
return tmp;
}
#endif // RW_THREADS
#define Miaig_CustomForEachConstInput(p, i) for (i = 0; i <= p->nIns; i++)
#define Miaig_CustomForEachInput(p, i) for (i = 1; i <= p->nIns; i++)
#define Miaig_CustomForEachNode(p, i) for (i = 1 + p->nIns; i < p->nObjs - p->nOuts; i++)
#define Miaig_CustomForEachNodeReverse(p, i) for (i = p->nObjs - p->nOuts - 1; i > 1 + p->nIns; i--)
#define Miaig_CustomForEachInputNode(p, i) for (i = 1; i < p->nObjs - p->nOuts; i++)
#define Miaig_CustomForEachNodeStart(p, i, s) for (i = s; i < p->nObjs - p->nOuts; i++)
#define Miaig_CustomForEachOutput(p, i) for (i = p->nObjs - p->nOuts; i < p->nObjs; i++)
#define Miaig_CustomForEachNodeOutput(p, i) for (i = 1 + p->nIns; i < p->nObjs; i++)
#define Miaig_CustomForEachNodeOutputStart(p, i, s) for (i = s; i < p->nObjs; i++)
#define Miaig_CustomForEachObj(p, i) for (i = 0; i < p->nObjs; i++)
#define Miaig_CustomForEachObjFanin(p, i, iLit, k) Vi_ForEachEntry(&p->pvFans[i], iLit, k)
#define Miaig_ForEachConstInput(i) for (i = 0; i <= _data->nIns; i++)
#define Miaig_ForEachInput(i) for (i = 1; i <= _data->nIns; i++)
#define Miaig_ForEachNode(i) for (i = 1 + _data->nIns; i < _data->nObjs - _data->nOuts; i++)
#define Miaig_ForEachNodeReverse(i) for (i = _data->nObjs - p->nOuts - 1; i > 1 + _data->nIns; i--)
#define Miaig_ForEachInputNode(i) for (i = 1; i < _data->nObjs - _data->nOuts; i++)
#define Miaig_ForEachNodeStart(i, s) for (i = s; i < _data->nObjs - _data->nOuts; i++)
#define Miaig_ForEachOutput(i) for (i = _data->nObjs - _data->nOuts; i < _data->nObjs; i++)
#define Miaig_ForEachNodeOutput(i) for (i = 1 + _data->nIns; i < _data->nObjs; i++)
#define Miaig_ForEachNodeOutputStart(i, s) for (i = s; i < _data->nObjs; i++)
#define Miaig_ForEachObj(i) for (i = 0; i < _data->nObjs; i++)
#define Miaig_ForEachObjFanin(i, iLit, k) Vi_ForEachEntry(&_data->pvFans[i], iLit, k)
static inline int Rw_Lit2LitV(int *pMapV2V, int Lit) {
assert(Lit >= 0);
return Abc_Var2Lit(pMapV2V[Abc_Lit2Var(Lit)], Abc_LitIsCompl(Lit));
}
static inline int Rw_Lit2LitL(int *pMapV2L, int Lit) {
assert(Lit >= 0);
return Abc_LitNotCond(pMapV2L[Abc_Lit2Var(Lit)], Abc_LitIsCompl(Lit));
}
struct Miaig_Data {
int refcount; // Reference counter
int nIns; // primary inputs
int nOuts; // primary outputs
int nObjs; // all objects
int nObjsAlloc; // allocated space
int nWords; // the truth table size
int nTravIds; // traversal ID counter
int *pTravIds; // traversal IDs
int *pCopy; // temp copy
int *pRefs; // reference counters
int *pLevel; // levels
int *pDist; // distances
word *pTruths[3]; // truth tables
word *pCare; // careset
word *pProd; // product
vi *vOrder; // node order
vi *vOrderF; // fanin order
vi *vOrderF2; // fanin order
vi *vTfo; // transitive fanout cone
vi *pvFans; // the array of objects' fanins
int *pTable; // structural hashing table
int TableSize; // the size of the hash table
float nTransistor; // objective value
vi *pNtkMapped; // mapped network
};
class Miaig {
public:
Miaig(void);
~Miaig(void);
Miaig(const Miaig &m);
Miaig &operator=(const Miaig &m);
Miaig(int nIns, int nOuts, int nObjsAlloc);
#ifdef RW_ABC
Miaig(Gia_Man_t *pGia);
Miaig(Abc_Ntk_t *pNtk);
Miaig(Mini_Aig_t *pMiniAig);
#endif // RW_ABC
public:
void addref(void);
void release(void);
private:
void create(int nIns, int nOuts, int nObjsAlloc);
public:
int fromGia(Gia_Man_t *pGia);
int fromMiniAig(Mini_Aig_t *pMiniAig);
public:
int &nIns(void);
int &nOuts(void);
int &nObjs(void);
int &nObjsAlloc(void);
int objIsPi(int i);
int objIsPo(int i);
int objIsNode(int i);
void print(void);
int appendObj(void);
void appendFanin(int i, int iLit);
int objFaninNum(int i);
int objFanin0(int i);
int objFanin1(int i);
int &objLevel(int i);
int &objRef(int i);
int &objTravId(int i);
int &objCopy(int i);
int &objDist(int i);
int &nTravIds(void);
word *objTruth(int i, int n);
int objType(int i);
int nWords(void);
void refObj(int iObj);
void derefObj(int iObj);
void derefObj_rec(int iObj, int iLitSkip);
private:
int initializeLevels_rec(int iObj);
void initializeLevels(void);
void initializeRefs(void);
void verifyRefs(void);
void initializeTruth(void);
void initializeDists(void);
private:
void markDfs_rec(int iObj);
int markDfs(void);
void markDistanceN_rec(int iObj, int n, int limit);
void markDistanceN(int Obj, int n);
void topoCollect_rec(int iObj);
vi *topoCollect(void);
void reduceFanins(vi *v);
int *createStops(void);
void collectSuper_rec(int iLit, int *pStop, vi *vSuper);
int checkConst(int iObj, word *pCare, int fVerbose);
void truthSimNode(int i);
word *truthSimNodeSubset(int i, int m);
word *truthSimNodeSubset2(int i, vi *vFanins, int nFanins);
void truthUpdate(vi *vTfo);
int computeTfo_rec(int iObj);
vi *computeTfo(int iObj);
word *computeCareSet(int iObj);
vi *createRandomOrder(void);
void addPair(vi *vPair, int iFan1, int iFan2);
int findPair(vi *vPair);
int updateFanins(vi *vFans, int iFan1, int iFan2, int iLit);
void extractBest(vi *vPairs);
vi *findPairs(word *pSto, int nWords);
int findShared(int nNewNodesMax);
int hashTwo(int l0, int l1, int TableSize);
int *hashLookup(int *pTable, int l0, int l1, int TableSize);
public:
float countAnd2(int reset = 0);
float countTransistors(int reset = 0);
int countLevel(void);
private:
void dupDfs_rec(Miaig &pNew, int iObj);
int buildNodeBalance_rec(Miaig &pNew, vi *vFanins, int begin, int end, int fCprop, int fStrash);
private:
int buildNode(int l0, int l1, int fCprop, int fStrash);
int buildNodeBalance(Miaig &pNew, vi *vFanins, int fCprop, int fStrash);
int buildNodeCascade(Miaig &pNew, vi *vFanins, int fCprop, int fStrash);
private:
int expandOne(int iObj, int nAddedMax, int nDist, int fVerbose);
int reduceOne(int iObj, int fOnlyConst, int fOnlyBuffer, int fHeuristic, int fVerbose);
int expandThenReduceOne(int iNode, int nFaninAddLimit, int nDist, int fVerbose);
public:
Miaig dup(int fRemDangle, int fMapped = 0);
Miaig dupDfs(void);
Miaig dupStrash(int fCprop, int fStrash, int fCascade);
Miaig dupMulti(int nFaninMax_, int nGrowth);
Miaig expand(int nFaninAddLimitAll, int nDist, int nVerbose);
Miaig share(int nNewNodesMax);
Miaig reduce(int fVerbose);
Miaig expandThenReduce(int nFaninAddLimit, int nDist, int fVerbose);
Miaig expandShareReduce(int nFaninAddLimitAll, int nDivs, int nDist, int nVerbose);
Miaig rewire(int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nVerbose);
#ifdef RW_ABC
Gia_Man_t *toGia(void);
Abc_Ntk_t *toNtk(int fMapped = 0);
Mini_Aig_t *toMiniAig(void);
#endif // RW_ABC
private:
int *_refcount;
Miaig_Data *_data;
};
inline Miaig::Miaig(void)
: _refcount(nullptr), _data(nullptr) {
}
inline Miaig::Miaig(int nIns, int nOuts, int nObjsAlloc)
: Miaig() {
create(nIns, nOuts, nObjsAlloc);
}
#ifdef RW_ABC
inline Miaig::Miaig(Gia_Man_t *pGia) : Miaig() {
fromGia(pGia);
}
inline Miaig::Miaig(Abc_Ntk_t *pNtk) : Miaig() {
Mini_Aig_t *pMiniAig = Abc_ManRewireMiniAigFromNtk(pNtk);
fromMiniAig(pMiniAig);
Mini_AigStop(pMiniAig);
}
inline Miaig::Miaig(Mini_Aig_t *pMiniAig) : Miaig() {
fromMiniAig(pMiniAig);
}
#endif // RW_ABC
inline Miaig::~Miaig(void) {
release();
}
inline Miaig::Miaig(const Miaig &m)
: _refcount(m._refcount), _data(m._data) {
addref();
}
inline Miaig &Miaig::operator=(const Miaig &m) {
if (this == &m) {
return *this;
}
if (m._refcount) {
RW_XADD(m._refcount, 1);
}
release();
_refcount = m._refcount;
_data = m._data;
return *this;
}
inline void Miaig::addref(void) {
if (_refcount) {
RW_XADD(_refcount, 1);
}
}
inline void Miaig::release(void) {
if (_refcount && RW_XADD(_refcount, -1) == 1) {
if (_data) {
for (int i = 0; i < _data->nObjsAlloc; ++i)
if (_data->pvFans[i].ptr)
free(_data->pvFans[i].ptr);
free(_data->pvFans);
Vi_Free(_data->vOrder);
Vi_Free(_data->vOrderF);
Vi_Free(_data->vOrderF2);
Vi_Free(_data->vTfo);
free(_data->pTravIds);
free(_data->pCopy);
free(_data->pRefs);
free(_data->pTruths[0]);
if (_data->pCare) free(_data->pCare);
if (_data->pProd) free(_data->pProd);
if (_data->pLevel) free(_data->pLevel);
if (_data->pDist) free(_data->pDist);
if (_data->pTable) free(_data->pTable);
if (_data->pNtkMapped) Vi_Free(_data->pNtkMapped);
delete _data;
}
}
_data = nullptr;
_refcount = nullptr;
}
inline int &Miaig::nIns(void) {
return _data->nIns;
}
inline int &Miaig::nOuts(void) {
return _data->nOuts;
}
inline int &Miaig::nObjs(void) {
return _data->nObjs;
}
inline int &Miaig::nObjsAlloc(void) {
return _data->nObjsAlloc;
}
inline int Miaig::objIsPi(int i) {
return i > 0 && i <= _data->nIns;
}
inline int Miaig::objIsPo(int i) {
return i >= _data->nObjs - _data->nOuts;
}
inline int Miaig::objIsNode(int i) {
return i > _data->nIns && i < _data->nObjs - _data->nOuts;
}
inline int Miaig::appendObj(void) {
assert(_data->nObjs < _data->nObjsAlloc);
return _data->nObjs++;
}
inline void Miaig::appendFanin(int i, int iLit) {
Vi_PushOrder(_data->pvFans + i, iLit);
}
inline int Miaig::objFaninNum(int i) {
return Vi_Size(_data->pvFans + i);
}
inline int Miaig::objFanin0(int i) {
return Vi_Read(_data->pvFans + i, 0);
}
inline int Miaig::objFanin1(int i) {
assert(objFaninNum(i) == 2);
return Vi_Read(_data->pvFans + i, 1);
}
inline int &Miaig::objLevel(int i) {
return _data->pLevel[i];
}
inline int &Miaig::objRef(int i) {
return _data->pRefs[i];
}
inline int &Miaig::objTravId(int i) {
return _data->pTravIds[i];
}
inline int &Miaig::objCopy(int i) {
return _data->pCopy[i];
}
inline int &Miaig::objDist(int i) {
return _data->pDist[i];
}
inline int &Miaig::nTravIds(void) {
return _data->nTravIds;
}
inline int Miaig::nWords(void) {
return _data->nWords;
}
inline float Miaig::countAnd2(int reset) {
int i, Counter = 0;
Miaig_ForEachNode(i) {
Counter += objFaninNum(i) - 1;
}
return Counter;
}
inline int Miaig::countLevel(void) {
initializeLevels();
int i, Level = -1;
Miaig_ForEachOutput(i) {
Level = Abc_MaxInt(Level, objLevel(i));
}
return Level;
}
inline word *Miaig::objTruth(int i, int n) {
return _data->pTruths[n] + nWords() * i;
}
inline int Miaig::objType(int i) {
return objTravId(i) == nTravIds();
}
} // namespace Rewire
#ifdef RW_ABC
ABC_NAMESPACE_CXX_HEADER_END
#endif // RW_ABC
#endif // REWIRE_MIAIG_H

17
src/opt/rar/rewire_rar.c Normal file
View File

@@ -0,0 +1,17 @@
#include "rewire_rar.h"
ABC_NAMESPACE_IMPL_START
Gia_Man_t *Gia_ManRewire(Gia_Man_t *pGia, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose) {
return Gia_ManRewireInt(pGia, nIters, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nDist, nSeed, fVerbose);
}
Abc_Ntk_t *Abc_ManRewire(Abc_Ntk_t *pNtk, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose) {
return Abc_ManRewireInt(pNtk, nIters, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nDist, nSeed, fVerbose);
}
Mini_Aig_t *MiniAig_ManRewire(Mini_Aig_t *pAig, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose) {
return MiniAig_ManRewireInt(pAig, nIters, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nDist, nSeed, fVerbose);
}
ABC_NAMESPACE_IMPL_END

27
src/opt/rar/rewire_rar.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef RAR_H
#define RAR_H
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "base/abc/abc.h"
#include "aig/gia/gia.h"
#include "aig/miniaig/miniaig.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_HEADER_START
Gia_Man_t *Gia_ManRewire(Gia_Man_t *pGia, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
Gia_Man_t *Gia_ManRewireInt(Gia_Man_t *pGia, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
Abc_Ntk_t *Abc_ManRewire(Abc_Ntk_t *pNtk, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
Abc_Ntk_t *Abc_ManRewireInt(Abc_Ntk_t *pNtk, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
Mini_Aig_t *MiniAig_ManRewire(Mini_Aig_t *pAig, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
Mini_Aig_t *MiniAig_ManRewireInt(Mini_Aig_t *pAig, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
ABC_NAMESPACE_HEADER_END
#endif // RAR_H

33
src/opt/rar/rewire_rng.c Normal file
View File

@@ -0,0 +1,33 @@
#include "rewire_rng.h"
ABC_NAMESPACE_IMPL_START
unsigned Random_Int(int fReset) {
static unsigned int m_z = NUMBER1;
static unsigned int m_w = NUMBER2;
if (fReset) {
m_z = NUMBER1;
m_w = NUMBER2;
}
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w;
}
word Random_Word(int fReset) {
return ((word)Random_Int(fReset) << 32) | ((word)Random_Int(fReset) << 0);
}
// This procedure should be called once with Seed > 0 to initialize the generator.
// After initialization, the generator should be always called with Seed == 0.
unsigned Random_Num(int Seed) {
static unsigned RandMask = 0;
if (Seed == 0)
return RandMask ^ Random_Int(0);
RandMask = Random_Int(1);
for (int i = 0; i < Seed; i++)
RandMask = Random_Int(0);
return RandMask;
}
ABC_NAMESPACE_IMPL_END

28
src/opt/rar/rewire_rng.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef RAR_RNG_H
#define RAR_RNG_H
/*************************************************************
random number generation
**************************************************************/
#include "base/abc/abc.h"
// Creates a sequence of random numbers.
// http://www.codeproject.com/KB/recipes/SimpleRNG.aspx
ABC_NAMESPACE_HEADER_START
#define NUMBER1 3716960521u
#define NUMBER2 2174103536u
unsigned Random_Int(int fReset);
word Random_Word(int fReset);
// This procedure should be called once with Seed > 0 to initialize the generator.
// After initialization, the generator should be always called with Seed == 0.
unsigned Random_Num(int Seed);
ABC_NAMESPACE_HEADER_END
#endif // RAR_RNG_H

41
src/opt/rar/rewire_time.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef RAR_TIME_H
#define RAR_TIME_H
/*************************************************************
counting wall time
**************************************************************/
#include "base/abc/abc.h"
ABC_NAMESPACE_HEADER_START
static inline iword Time_Clock() {
#if defined(__APPLE__) && defined(__MACH__)
#define APPLE_MACH (__APPLE__ & __MACH__)
#else
#define APPLE_MACH 0
#endif
#if (defined(LIN) || defined(LIN64)) && !APPLE_MACH && !defined(__MINGW32__)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
return (iword)-1;
iword res = ((iword)ts.tv_sec) * CLOCKS_PER_SEC;
res += (((iword)ts.tv_nsec) * CLOCKS_PER_SEC) / 1000000000;
return res;
#else
return (iword)clock();
#endif
}
static inline void Time_Print(const char *pStr, iword time) {
printf("%s = %10.2f sec", pStr, (float)1.0 * ((double)(time)) / ((double)CLOCKS_PER_SEC));
}
static inline void Time_PrintEndl(const char *pStr, iword time) {
Time_Print(pStr, time);
printf("\n");
}
ABC_NAMESPACE_HEADER_END
#endif // RAR_TIME_H

210
src/opt/rar/rewire_tt.h Normal file
View File

@@ -0,0 +1,210 @@
#ifndef RAR_TT_H
#define RAR_TT_H
/*************************************************************
truth table manipulation
**************************************************************/
#include "base/abc/abc.h"
ABC_NAMESPACE_HEADER_START
// the bit count for the first 256 integer numbers
static int Tt_BitCount8[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
static inline int Tt_BitCount16(int i) {
return Tt_BitCount8[i & 0xFF] + Tt_BitCount8[i >> 8];
}
static word ss_Truths6[6] = {
ABC_CONST(0xAAAAAAAAAAAAAAAA),
ABC_CONST(0xCCCCCCCCCCCCCCCC),
ABC_CONST(0xF0F0F0F0F0F0F0F0),
ABC_CONST(0xFF00FF00FF00FF00),
ABC_CONST(0xFFFF0000FFFF0000),
ABC_CONST(0xFFFFFFFF00000000)};
static inline int Tt_HexDigitNum(int n) {
return n <= 2 ? 1 : 1 << (n - 2);
}
static inline void Tt_Print(word *p, int nWords) {
int k, Digit, nDigits = nWords * 16;
for (k = nDigits - 1; k >= 0; k--) {
Digit = (int)((p[k / 16] >> ((k % 16) * 4)) & 15);
if (Digit < 10)
printf("%d", Digit);
else
printf("%c", 'A' + Digit - 10);
}
printf("\n");
}
static inline int Tt_CountOnes(word x) {
x = x - ((x >> 1) & ABC_CONST(0x5555555555555555));
x = (x & ABC_CONST(0x3333333333333333)) + ((x >> 2) & ABC_CONST(0x3333333333333333));
x = (x + (x >> 4)) & ABC_CONST(0x0F0F0F0F0F0F0F0F);
x = x + (x >> 8);
x = x + (x >> 16);
x = x + (x >> 32);
return (int)(x & 0xFF);
}
static inline int Tt_CountOnes2(word x) {
return x ? Tt_CountOnes(x) : 0;
}
static inline int Tt_CountOnesVec(word *x, int nWords) {
int w, Count = 0;
for (w = 0; w < nWords; w++)
Count += Tt_CountOnes2(x[w]);
return Count;
}
static inline int Tt_CountOnesVecMask(word *x, word *pMask, int nWords) {
int w, Count = 0;
for (w = 0; w < nWords; w++)
Count += Tt_CountOnes2(pMask[w] & x[w]);
return Count;
}
static inline void Tt_Clear(word *pOut, int nWords) {
int w;
for (w = 0; w < nWords; w++)
pOut[w] = 0;
}
static inline void Tt_Fill(word *pOut, int nWords) {
int w;
for (w = 0; w < nWords; w++)
pOut[w] = ~(word)0;
}
static inline void Tt_Dup(word *pOut, word *pIn, int nWords) {
int w;
for (w = 0; w < nWords; w++)
pOut[w] = pIn[w];
}
static inline void Tt_DupC(word *pOut, word *pIn, int fC, int nWords) {
int w;
if (fC)
for (w = 0; w < nWords; w++)
pOut[w] = ~pIn[w];
else
for (w = 0; w < nWords; w++)
pOut[w] = pIn[w];
}
static inline void Tt_Not(word *pOut, word *pIn, int nWords) {
int w;
for (w = 0; w < nWords; w++)
pOut[w] = ~pIn[w];
}
static inline void Tt_And(word *pOut, word *pIn1, word *pIn2, int nWords) {
int w;
for (w = 0; w < nWords; w++)
pOut[w] = pIn1[w] & pIn2[w];
}
static inline void Tt_Sharp(word *pOut, word *pIn, int fC, int nWords) {
int w;
if (fC)
for (w = 0; w < nWords; w++)
pOut[w] &= ~pIn[w];
else
for (w = 0; w < nWords; w++)
pOut[w] &= pIn[w];
}
static inline void Tt_OrXor(word *pOut, word *pIn1, word *pIn2, int nWords) {
int w;
for (w = 0; w < nWords; w++)
pOut[w] |= pIn1[w] ^ pIn2[w];
}
static inline int Tt_WordNum(int n) {
return n > 6 ? (1 << (n - 6)) : 1;
}
static inline void Tt_ElemInit(word *pTruth, int iVar, int nWords) {
int k;
if (iVar < 6)
for (k = 0; k < nWords; k++)
pTruth[k] = ss_Truths6[iVar];
else
for (k = 0; k < nWords; k++)
pTruth[k] = (k & (1 << (iVar - 6))) ? ~(word)0 : 0;
}
static inline int Tt_IntersectC(word *pIn1, word *pIn2, int fC, int nWords) {
int w;
if (fC) {
for (w = 0; w < nWords; w++)
if (pIn1[w] & ~pIn2[w])
return 1;
} else {
for (w = 0; w < nWords; w++)
if (pIn1[w] & pIn2[w])
return 1;
}
return 0;
}
static inline int Tt_Equal(word *pIn1, word *pIn2, int nWords) {
int w;
for (w = 0; w < nWords; w++)
if (pIn1[w] != pIn2[w])
return 0;
return 1;
}
static inline int Tt_EqualOnCare(word *pCare, word *pIn1, word *pIn2, int nWords) {
int w;
for (w = 0; w < nWords; w++)
if (pCare[w] & (pIn1[w] ^ pIn2[w]))
return 0;
return 1;
}
static inline int Tt_IsConst0(word *pIn, int nWords) {
int w;
for (w = 0; w < nWords; w++)
if (pIn[w])
return 0;
return 1;
}
static inline int Tt_IsConst1(word *pIn, int nWords) {
int w;
for (w = 0; w < nWords; w++)
if (pIn[w] != ~(word)0)
return 0;
return 1;
}
// read/write/flip i-th bit of a bit string table:
static inline int Tt_GetBit(word *p, int k) {
return (int)(p[k >> 6] >> (k & 63)) & 1;
}
static inline void Tt_SetBit(word *p, int k) {
p[k >> 6] |= (((word)1) << (k & 63));
}
static inline void Tt_XorBit(word *p, int k) {
p[k >> 6] ^= (((word)1) << (k & 63));
}
ABC_NAMESPACE_HEADER_END
#endif // RAR_TT_H

206
src/opt/rar/rewire_vec.h Normal file
View File

@@ -0,0 +1,206 @@
#ifndef RAR_VI_H
#define RAR_VI_H
/*************************************************************
vector of 32-bit integers
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "rewire_rng.h"
ABC_NAMESPACE_HEADER_START
// swapping two variables
#define RW_SWAP(Type, a, b) \
{ \
Type t = a; \
a = b; \
b = t; \
}
typedef struct vi_ {
int size;
int cap;
int *ptr;
} vi;
// iterator through the entries in the vector
#define Vi_ForEachEntry(v, entry, i) for (i = 0; (i < (v)->size) && (((entry) = Vi_Read((v), i)), 1); i++)
#define Vi_ForEachEntryReverse(v, entry, i) for (i = (v)->size - 1; (i >= 0) && (((entry) = Vi_Read((v), i)), 1); i--)
#define Vi_ForEachEntryStart(v, entry, i, start) for (i = start; (i < (v)->size) && (((entry) = Vi_Read((v), i)), 1); i++)
#define Vi_ForEachEntryStop(v, entry, i, stop) for (i = 0; (i < stop) && (((entry) = Vi_Read((v), i)), 1); i++)
static inline void Vi_Start(vi *v, int cap) {
v->size = 0;
v->cap = cap;
v->ptr = (int *)malloc(sizeof(int) * cap);
}
static inline vi *Vi_Alloc(int cap) {
vi *v = (vi *)malloc(sizeof(vi));
Vi_Start(v, cap);
return v;
}
static inline void Vi_Stop(vi *v) {
if (v->ptr) free(v->ptr);
}
static inline void Vi_Free(vi *v) {
if (v->ptr) free(v->ptr);
free(v);
}
static inline int Vi_Size(vi *v) {
return v->size;
}
static inline int Vi_Space(vi *v) {
return v->cap - v->size;
}
static inline int *Vi_Array(vi *v) {
return v->ptr;
}
static inline int Vi_Read(vi *v, int k) {
assert(k < v->size);
return v->ptr[k];
}
static inline void Vi_Write(vi *v, int k, int e) {
assert(k < v->size);
v->ptr[k] = e;
}
static inline void Vi_Shrink(vi *v, int k) {
assert(k <= v->size);
v->size = k;
} // only safe to shrink !!
static inline int Vi_Pop(vi *v) {
assert(v->size > 0);
return v->ptr[--v->size];
}
static inline void Vi_Grow(vi *v) {
if (v->size < v->cap)
return;
int newcap = (v->cap < 4) ? 8 : (v->cap / 2) * 3;
v->ptr = (int *)realloc(v->ptr, sizeof(int) * newcap);
if (v->ptr == NULL) {
printf("Failed to realloc memory from %.1f MB to %.1f MB.\n", 4.0 * v->cap / (1 << 20), (float)4.0 * newcap / (1 << 20));
fflush(stdout);
}
v->cap = newcap;
}
static inline vi *Vi_Dup(vi *v) {
vi *pNew = Vi_Alloc(v->size);
memcpy(pNew->ptr, v->ptr, sizeof(int) * v->size);
pNew->size = v->size;
return pNew;
}
static inline void Vi_Push(vi *v, int e) {
Vi_Grow(v);
v->ptr[v->size++] = e;
}
static inline void Vi_PushTwo(vi *v, int e1, int e2) {
Vi_Push(v, e1);
Vi_Push(v, e2);
}
static inline void Vi_PushArray(vi *v, int *p, int n) {
for (int i = 0; i < n; i++)
Vi_Push(v, p[i]);
}
static inline void Vi_PushOrder(vi *v, int e) {
Vi_Push(v, e);
if (v->size > 1)
for (int i = v->size - 2; i >= 0; i--) {
if (v->ptr[i] > v->ptr[i + 1]) {
RW_SWAP(int, v->ptr[i], v->ptr[i + 1])
} else {
break;
}
}
}
static inline void Vi_Fill(vi *v, int n, int fill) {
int i;
Vi_Shrink(v, 0);
for (i = 0; i < n; i++)
Vi_Push(v, fill);
}
static inline int Vi_Drop(vi *v, int i) {
assert(i >= 0 && i < v->size);
int Entry = v->ptr[i];
for (; i < v->size - 1; i++)
v->ptr[i] = v->ptr[i + 1];
Vi_Shrink(v, v->size - 1);
return Entry;
}
static inline int Vi_Find(vi *v, int e) {
int j;
for (j = 0; j < v->size; j++)
if (v->ptr[j] == e)
return j;
return -1;
}
static inline int Vi_Remove(vi *v, int e) {
int j = Vi_Find(v, e);
if (j == -1)
return 0;
Vi_Drop(v, j);
return 1;
}
static inline void Vi_Randomize(vi *v) {
for (int i = 0; i < v->size; i++) {
int iRand = Random_Num(0) % v->size;
RW_SWAP(int, v->ptr[iRand], v->ptr[i]);
}
}
static inline void Vi_Reverse(vi *v) {
int i, j;
for (i = 0, j = v->size - 1; i < j; i++, j--)
RW_SWAP(int, v->ptr[i], v->ptr[j]);
}
static inline void Vi_Print(vi *v) {
printf("Array with %d entries:", v->size);
int i, entry;
Vi_ForEachEntry(v, entry, i)
printf(" %d", entry);
printf("\n");
}
static inline void Vi_SelectSort(vi *v) {
int *pArray = Vi_Array(v);
int nSize = Vi_Size(v);
int temp, i, j, best_i;
for (i = 0; i < nSize - 1; i++) {
best_i = i;
for (j = i + 1; j < nSize; j++)
if (pArray[j] < pArray[best_i])
best_i = j;
temp = pArray[i];
pArray[i] = pArray[best_i];
pArray[best_i] = temp;
}
}
ABC_NAMESPACE_HEADER_END
#endif // RAR_VI_H