Merge pull request #219 from MyskYko/transduction

Transduction method
This commit is contained in:
alanminko 2023-05-04 14:20:34 -04:00 committed by GitHub
commit 38cd47b46c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 3141 additions and 1 deletions

View File

@ -5111,6 +5111,14 @@ SOURCE=.\src\aig\gia\giaMuxes.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaNewBdd.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaNewTt.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaNf.c
# End Source File
# Begin Source File
@ -5307,6 +5315,14 @@ SOURCE=.\src\aig\gia\giaTtopt.cpp
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaTransduction.cpp
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaTransduction.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaUnate.c
# End Source File
# Begin Source File

View File

@ -1769,10 +1769,14 @@ extern int Gia_ManCountPosWithNonZeroDrivers( Gia_Man_t * p );
extern void Gia_ManUpdateCopy( Vec_Int_t * vCopy, Gia_Man_t * p );
extern Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, int fVerbose );
/*=== giaTtopt.c ===========================================================*/
/*=== giaTtopt.cpp ===========================================================*/
extern Gia_Man_t * Gia_ManTtopt( Gia_Man_t * p, int nIns, int nOuts, int nRounds );
extern Gia_Man_t * Gia_ManTtoptCare( Gia_Man_t * p, int nIns, int nOuts, int nRounds, char * pFileName, int nRarity );
/*=== giaTransduction.cpp ===========================================================*/
extern Gia_Man_t * Gia_ManTransductionBdd( Gia_Man_t * pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t * pExdc, int fNewLine, int nVerbose );
extern Gia_Man_t * Gia_ManTransductionTt( Gia_Man_t * pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t * pExdc, int fNewLine, int nVerbose );
/*=== giaCTas.c ===========================================================*/
typedef struct Tas_Man_t_ Tas_Man_t;
extern Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit );

819
src/aig/gia/giaNewBdd.h Normal file
View File

@ -0,0 +1,819 @@
#ifndef ABC__aig__gia__giaNewBdd_h
#define ABC__aig__gia__giaNewBdd_h
#include <limits>
#include <vector>
#include <iostream>
#include <iomanip>
#include <cmath>
ABC_NAMESPACE_CXX_HEADER_START
namespace NewBdd {
typedef unsigned short var;
typedef int bvar;
typedef unsigned lit;
typedef unsigned short ref;
typedef unsigned long long size;
typedef unsigned edge;
typedef unsigned uniq;
typedef unsigned cac;
static inline var VarMax() { return std::numeric_limits<var>::max(); }
static inline bvar BvarMax() { return std::numeric_limits<bvar>::max(); }
static inline lit LitMax() { return std::numeric_limits<lit>::max(); }
static inline ref RefMax() { return std::numeric_limits<ref>::max(); }
static inline size SizeMax() { return std::numeric_limits<size>::max(); }
static inline uniq UniqHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
static inline cac CacHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
class Cache {
private:
cac nSize;
cac nMax;
cac Mask;
size nLookups;
size nHits;
size nThold;
double HitRate;
int nVerbose;
std::vector<lit> vCache;
public:
Cache(int nCacheSizeLog, int nCacheMaxLog, int nVerbose): nVerbose(nVerbose) {
if(nCacheMaxLog < nCacheSizeLog)
throw std::invalid_argument("nCacheMax must not be smaller than nCacheSize");
nMax = (cac)1 << nCacheMaxLog;
if(!(nMax << 1))
throw std::length_error("Memout (nCacheMax) in init");
nSize = (cac)1 << nCacheSizeLog;
if(nVerbose)
std::cout << "Allocating " << nSize << " cache entries" << std::endl;
vCache.resize(nSize * 3);
Mask = nSize - 1;
nLookups = 0;
nHits = 0;
nThold = (nSize == nMax)? SizeMax(): nSize;
HitRate = 1;
}
~Cache() {
if(nVerbose)
std::cout << "Free " << nSize << " cache entries" << std::endl;
}
inline lit Lookup(lit x, lit y) {
nLookups++;
if(nLookups > nThold) {
double NewHitRate = (double)nHits / nLookups;
if(nVerbose >= 2)
std::cout << "Cache Hits: " << std::setw(10) << nHits << ", "
<< "Lookups: " << std::setw(10) << nLookups << ", "
<< "Rate: " << std::setw(10) << NewHitRate
<< std::endl;
if(NewHitRate > HitRate)
Resize();
if(nSize == nMax)
nThold = SizeMax();
else {
nThold <<= 1;
if(!nThold)
nThold = SizeMax();
}
HitRate = NewHitRate;
}
cac i = (CacHash(x, y) & Mask) * 3;
if(vCache[i] == x && vCache[i + 1] == y) {
if(nVerbose >= 3)
std::cout << "Cache hit: "
<< "x = " << std::setw(10) << x << ", "
<< "y = " << std::setw(10) << y << ", "
<< "z = " << std::setw(10) << vCache[i + 2] << ", "
<< "hash = " << std::hex << (CacHash(x, y) & Mask) << std::dec
<< std::endl;
nHits++;
return vCache[i + 2];
}
return LitMax();
}
inline void Insert(lit x, lit y, lit z) {
cac i = (CacHash(x, y) & Mask) * 3;
vCache[i] = x;
vCache[i + 1] = y;
vCache[i + 2] = z;
if(nVerbose >= 3)
std::cout << "Cache ent: "
<< "x = " << std::setw(10) << x << ", "
<< "y = " << std::setw(10) << y << ", "
<< "z = " << std::setw(10) << z << ", "
<< "hash = " << std::hex << (CacHash(x, y) & Mask) << std::dec
<< std::endl;
}
inline void Clear() {
std::fill(vCache.begin(), vCache.end(), 0);
}
void Resize() {
cac nSizeOld = nSize;
nSize <<= 1;
if(nVerbose >= 2)
std::cout << "Reallocating " << nSize << " cache entries" << std::endl;
vCache.resize(nSize * 3);
Mask = nSize - 1;
for(cac j = 0; j < nSizeOld; j++) {
cac i = j * 3;
if(vCache[i] || vCache[i + 1]) {
cac hash = (CacHash(vCache[i], vCache[i + 1]) & Mask) * 3;
vCache[hash] = vCache[i];
vCache[hash + 1] = vCache[i + 1];
vCache[hash + 2] = vCache[i + 2];
if(nVerbose >= 3)
std::cout << "Cache mov: "
<< "x = " << std::setw(10) << vCache[i] << ", "
<< "y = " << std::setw(10) << vCache[i + 1] << ", "
<< "z = " << std::setw(10) << vCache[i + 2] << ", "
<< "hash = " << std::hex << (CacHash(vCache[i], vCache[i + 1]) & Mask) << std::dec
<< std::endl;
}
}
}
};
struct Param {
int nObjsAllocLog;
int nObjsMaxLog;
int nUniqueSizeLog;
double UniqueDensity;
int nCacheSizeLog;
int nCacheMaxLog;
int nCacheVerbose;
bool fCountOnes;
int nGbc;
bvar nReo;
double MaxGrowth;
bool fReoVerbose;
int nVerbose;
std::vector<var> *pVar2Level;
Param() {
nObjsAllocLog = 20;
nObjsMaxLog = 25;
nUniqueSizeLog = 10;
UniqueDensity = 4;
nCacheSizeLog = 15;
nCacheMaxLog = 20;
nCacheVerbose = 0;
fCountOnes = false;
nGbc = 0;
nReo = BvarMax();
MaxGrowth = 1.2;
fReoVerbose = false;
nVerbose = 0;
pVar2Level = NULL;
}
};
class Man {
private:
var nVars;
bvar nObjs;
bvar nObjsAlloc;
bvar nObjsMax;
bvar RemovedHead;
int nGbc;
bvar nReo;
double MaxGrowth;
bool fReoVerbose;
int nVerbose;
std::vector<var> vVars;
std::vector<var> Var2Level;
std::vector<var> Level2Var;
std::vector<lit> vObjs;
std::vector<bvar> vNexts;
std::vector<bool> vMarks;
std::vector<ref> vRefs;
std::vector<edge> vEdges;
std::vector<double> vOneCounts;
std::vector<uniq> vUniqueMasks;
std::vector<bvar> vUniqueCounts;
std::vector<bvar> vUniqueTholds;
std::vector<std::vector<bvar> > vvUnique;
Cache *cache;
public:
inline lit Bvar2Lit(bvar a) const { return (lit)a << 1; }
inline lit Bvar2Lit(bvar a, bool c) const { return ((lit)a << 1) ^ (lit)c; }
inline bvar Lit2Bvar(lit x) const { return (bvar)(x >> 1); }
inline var VarOfBvar(bvar a) const { return vVars[a]; }
inline lit ThenOfBvar(bvar a) const { return vObjs[Bvar2Lit(a)]; }
inline lit ElseOfBvar(bvar a) const { return vObjs[Bvar2Lit(a, true)]; }
inline ref RefOfBvar(bvar a) const { return vRefs[a]; }
inline lit Const0() const { return (lit)0; }
inline lit Const1() const { return (lit)1; }
inline bool IsConst0(lit x) const { return x == Const0(); }
inline bool IsConst1(lit x) const { return x == Const1(); }
inline lit IthVar(var v) const { return Bvar2Lit((bvar)v + 1); }
inline lit LitRegular(lit x) const { return x & ~(lit)1; }
inline lit LitIrregular(lit x) const { return x | (lit)1; }
inline lit LitNot(lit x) const { return x ^ (lit)1; }
inline lit LitNotCond(lit x, bool c) const { return x ^ (lit)c; }
inline bool LitIsCompl(lit x) const { return x & (lit)1; }
inline bool LitIsEq(lit x, lit y) const { return x == y; }
inline var Var(lit x) const { return vVars[Lit2Bvar(x)]; }
inline var Level(lit x) const { return Var2Level[Var(x)]; }
inline lit Then(lit x) const { return LitNotCond(vObjs[LitRegular(x)], LitIsCompl(x)); }
inline lit Else(lit x) const { return LitNotCond(vObjs[LitIrregular(x)], LitIsCompl(x)); }
inline ref Ref(lit x) const { return vRefs[Lit2Bvar(x)]; }
inline double OneCount(lit x) const {
if(vOneCounts.empty())
throw std::logic_error("fCountOnes was not set");
if(LitIsCompl(x))
return std::pow(2.0, nVars) - vOneCounts[Lit2Bvar(x)];
return vOneCounts[Lit2Bvar(x)];
}
public:
inline void IncRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]++; }
inline void DecRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]--; }
private:
inline bool Mark(lit x) const { return vMarks[Lit2Bvar(x)]; }
inline edge Edge(lit x) const { return vEdges[Lit2Bvar(x)]; }
inline void SetMark(lit x) { vMarks[Lit2Bvar(x)] = true; }
inline void ResetMark(lit x) { vMarks[Lit2Bvar(x)] = false; }
inline void IncEdge(lit x) { vEdges[Lit2Bvar(x)]++; }
inline void DecEdge(lit x) { vEdges[Lit2Bvar(x)]--; }
inline bool MarkOfBvar(bvar a) const { return vMarks[a]; }
inline edge EdgeOfBvar(bvar a) const { return vEdges[a]; }
inline void SetVarOfBvar(bvar a, var v) { vVars[a] = v; }
inline void SetThenOfBvar(bvar a, lit x) { vObjs[Bvar2Lit(a)] = x; }
inline void SetElseOfBvar(bvar a, lit x) { vObjs[Bvar2Lit(a, true)] = x; }
inline void SetMarkOfBvar(bvar a) { vMarks[a] = true; }
inline void ResetMarkOfBvar(bvar a) { vMarks[a] = false; }
inline void RemoveBvar(bvar a) {
var v = VarOfBvar(a);
SetVarOfBvar(a, VarMax());
std::vector<bvar>::iterator q = vvUnique[v].begin() + (UniqHash(ThenOfBvar(a), ElseOfBvar(a)) & vUniqueMasks[v]);
for(; *q; q = vNexts.begin() + *q)
if(*q == a)
break;
bvar next = vNexts[*q];
vNexts[*q] = RemovedHead;
RemovedHead = *q;
*q = next;
vUniqueCounts[v]--;
}
private:
void SetMark_rec(lit x) {
if(x < 2 || Mark(x))
return;
SetMark(x);
SetMark_rec(Then(x));
SetMark_rec(Else(x));
}
void ResetMark_rec(lit x) {
if(x < 2 || !Mark(x))
return;
ResetMark(x);
ResetMark_rec(Then(x));
ResetMark_rec(Else(x));
}
bvar CountNodes_rec(lit x) {
if(x < 2 || Mark(x))
return 0;
SetMark(x);
return 1 + CountNodes_rec(Then(x)) + CountNodes_rec(Else(x));
}
void CountEdges_rec(lit x) {
if(x < 2)
return;
IncEdge(x);
if(Mark(x))
return;
SetMark(x);
CountEdges_rec(Then(x));
CountEdges_rec(Else(x));
}
void CountEdges() {
vEdges.resize(nObjsAlloc);
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
if(RefOfBvar(a))
CountEdges_rec(Bvar2Lit(a));
for(bvar a = 1; a <= (bvar)nVars; a++)
vEdges[a]++;
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
if(RefOfBvar(a))
ResetMark_rec(Bvar2Lit(a));
}
public:
bool Resize() {
if(nObjsAlloc == nObjsMax)
return false;
lit nObjsAllocLit = (lit)nObjsAlloc << 1;
if(nObjsAllocLit > (lit)BvarMax())
nObjsAlloc = BvarMax();
else
nObjsAlloc = (bvar)nObjsAllocLit;
if(nVerbose >= 2)
std::cout << "Reallocating " << nObjsAlloc << " nodes" << std::endl;
vVars.resize(nObjsAlloc);
vObjs.resize((lit)nObjsAlloc * 2);
vNexts.resize(nObjsAlloc);
vMarks.resize(nObjsAlloc);
if(!vRefs.empty())
vRefs.resize(nObjsAlloc);
if(!vEdges.empty())
vEdges.resize(nObjsAlloc);
if(!vOneCounts.empty())
vOneCounts.resize(nObjsAlloc);
return true;
}
void ResizeUnique(var v) {
uniq nUniqueSize, nUniqueSizeOld;
nUniqueSize = nUniqueSizeOld = vvUnique[v].size();
nUniqueSize <<= 1;
if(!nUniqueSize) {
vUniqueTholds[v] = BvarMax();
return;
}
if(nVerbose >= 2)
std::cout << "Reallocating " << nUniqueSize << " unique table entries for Var " << v << std::endl;
vvUnique[v].resize(nUniqueSize);
vUniqueMasks[v] = nUniqueSize - 1;
for(uniq i = 0; i < nUniqueSizeOld; i++) {
std::vector<bvar>::iterator q, tail, tail1, tail2;
q = tail1 = vvUnique[v].begin() + i;
tail2 = q + nUniqueSizeOld;
while(*q) {
uniq hash = UniqHash(ThenOfBvar(*q), ElseOfBvar(*q)) & vUniqueMasks[v];
if(hash == i)
tail = tail1;
else
tail = tail2;
if(tail != q)
*tail = *q, *q = 0;
q = vNexts.begin() + *tail;
if(tail == tail1)
tail1 = q;
else
tail2 = q;
}
}
vUniqueTholds[v] <<= 1;
if((lit)vUniqueTholds[v] > (lit)BvarMax())
vUniqueTholds[v] = BvarMax();
}
bool Gbc() {
if(nVerbose >= 2)
std::cout << "Garbage collect" << std::endl;
if(!vEdges.empty()) {
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
if(!EdgeOfBvar(a) && VarOfBvar(a) != VarMax())
RemoveBvar(a);
} else {
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
if(RefOfBvar(a))
SetMark_rec(Bvar2Lit(a));
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
if(!MarkOfBvar(a) && VarOfBvar(a) != VarMax())
RemoveBvar(a);
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
if(RefOfBvar(a))
ResetMark_rec(Bvar2Lit(a));
}
cache->Clear();
return RemovedHead;
}
private:
inline lit UniqueCreateInt(var v, lit x1, lit x0) {
std::vector<bvar>::iterator p, q;
p = q = vvUnique[v].begin() + (UniqHash(x1, x0) & vUniqueMasks[v]);
for(; *q; q = vNexts.begin() + *q)
if(VarOfBvar(*q) == v && ThenOfBvar(*q) == x1 && ElseOfBvar(*q) == x0)
return Bvar2Lit(*q);
bvar next = *p;
if(nObjs < nObjsAlloc)
*p = nObjs++;
else if(RemovedHead)
*p = RemovedHead, RemovedHead = vNexts[*p];
else
return LitMax();
SetVarOfBvar(*p, v);
SetThenOfBvar(*p, x1);
SetElseOfBvar(*p, x0);
vNexts[*p] = next;
if(!vOneCounts.empty())
vOneCounts[*p] = OneCount(x1) / 2 + OneCount(x0) / 2;
if(nVerbose >= 3) {
std::cout << "Create node " << std::setw(10) << *p << ": "
<< "Var = " << std::setw(6) << v << ", "
<< "Then = " << std::setw(10) << x1 << ", "
<< "Else = " << std::setw(10) << x0;
if(!vOneCounts.empty())
std::cout << ", Ones = " << std::setw(10) << vOneCounts[*q];
std::cout << std::endl;
}
vUniqueCounts[v]++;
if(vUniqueCounts[v] > vUniqueTholds[v]) {
bvar a = *p;
ResizeUnique(v);
return Bvar2Lit(a);
}
return Bvar2Lit(*p);
}
inline lit UniqueCreate(var v, lit x1, lit x0) {
if(x1 == x0)
return x1;
lit x;
while(true) {
if(!LitIsCompl(x0))
x = UniqueCreateInt(v, x1, x0);
else
x = UniqueCreateInt(v, LitNot(x1), LitNot(x0));
if(x == LitMax()) {
bool fRemoved = false;
if(nGbc > 1)
fRemoved = Gbc();
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
throw std::length_error("Memout (node)");
} else
break;
}
return LitIsCompl(x0)? LitNot(x): x;
}
lit And_rec(lit x, lit y) {
if(x == 0 || y == 1)
return x;
if(x == 1 || y == 0)
return y;
if(Lit2Bvar(x) == Lit2Bvar(y))
return (x == y)? x: 0;
if(x > y)
std::swap(x, y);
lit z = cache->Lookup(x, y);
if(z != LitMax())
return z;
var v;
lit x0, x1, y0, y1;
if(Level(x) < Level(y))
v = Var(x), x1 = Then(x), x0 = Else(x), y0 = y1 = y;
else if(Level(x) > Level(y))
v = Var(y), x0 = x1 = x, y1 = Then(y), y0 = Else(y);
else
v = Var(x), x1 = Then(x), x0 = Else(x), y1 = Then(y), y0 = Else(y);
lit z1 = And_rec(x1, y1);
IncRef(z1);
lit z0 = And_rec(x0, y0);
IncRef(z0);
z = UniqueCreate(v, z1, z0);
DecRef(z1);
DecRef(z0);
cache->Insert(x, y, z);
return z;
}
private:
bvar Swap(var i) {
var v1 = Level2Var[i];
var v2 = Level2Var[i + 1];
bvar f = 0;
bvar diff = 0;
for(std::vector<bvar>::iterator p = vvUnique[v1].begin(); p != vvUnique[v1].end(); p++) {
std::vector<bvar>::iterator q = p;
while(*q) {
if(!EdgeOfBvar(*q)) {
SetVarOfBvar(*q, VarMax());
bvar next = vNexts[*q];
vNexts[*q] = RemovedHead;
RemovedHead = *q;
*q = next;
vUniqueCounts[v1]--;
continue;
}
lit f1 = ThenOfBvar(*q);
lit f0 = ElseOfBvar(*q);
if(Var(f1) == v2 || Var(f0) == v2) {
DecEdge(f1);
if(Var(f1) == v2 && !Edge(f1))
DecEdge(Then(f1)), DecEdge(Else(f1)), diff--;
DecEdge(f0);
if(Var(f0) == v2 && !Edge(f0))
DecEdge(Then(f0)), DecEdge(Else(f0)), diff--;
bvar next = vNexts[*q];
vNexts[*q] = f;
f = *q;
*q = next;
vUniqueCounts[v1]--;
continue;
}
q = vNexts.begin() + *q;
}
}
while(f) {
lit f1 = ThenOfBvar(f);
lit f0 = ElseOfBvar(f);
lit f00, f01, f10, f11;
if(Var(f1) == v2)
f11 = Then(f1), f10 = Else(f1);
else
f10 = f11 = f1;
if(Var(f0) == v2)
f01 = Then(f0), f00 = Else(f0);
else
f00 = f01 = f0;
if(f11 == f01)
f1 = f11;
else {
f1 = UniqueCreate(v1, f11, f01);
if(!Edge(f1))
IncEdge(f11), IncEdge(f01), diff++;
}
IncEdge(f1);
IncRef(f1);
if(f10 == f00)
f0 = f10;
else {
f0 = UniqueCreate(v1, f10, f00);
if(!Edge(f0))
IncEdge(f10), IncEdge(f00), diff++;
}
IncEdge(f0);
DecRef(f1);
SetVarOfBvar(f, v2);
SetThenOfBvar(f, f1);
SetElseOfBvar(f, f0);
std::vector<bvar>::iterator q = vvUnique[v2].begin() + (UniqHash(f1, f0) & vUniqueMasks[v2]);
lit next = vNexts[f];
vNexts[f] = *q;
*q = f;
vUniqueCounts[v2]++;
f = next;
}
Var2Level[v1] = i + 1;
Var2Level[v2] = i;
Level2Var[i] = v2;
Level2Var[i + 1] = v1;
return diff;
}
void Sift() {
bvar count = CountNodes();
std::vector<var> sift_order(nVars);
for(var v = 0; v < nVars; v++)
sift_order[v] = v;
for(var i = 0; i < nVars; i++) {
var max_j = i;
for(var j = i + 1; j < nVars; j++)
if(vUniqueCounts[sift_order[j]] > vUniqueCounts[sift_order[max_j]])
max_j = j;
if(max_j != i)
std::swap(sift_order[max_j], sift_order[i]);
}
for(var v = 0; v < nVars; v++) {
bvar lev = Var2Level[sift_order[v]];
bool UpFirst = lev < (bvar)(nVars / 2);
bvar min_lev = lev;
bvar min_diff = 0;
bvar diff = 0;
bvar thold = count * (MaxGrowth - 1);
if(fReoVerbose)
std::cout << "Sift " << sift_order[v] << " : Level = " << lev << " Count = " << count << " Thold = " << thold << std::endl;
if(UpFirst) {
lev--;
for(; lev >= 0; lev--) {
diff += Swap(lev);
if(fReoVerbose)
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
if(diff < min_diff)
min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
else if(diff > thold) {
lev--;
break;
}
}
lev++;
}
for(; lev < (bvar)nVars - 1; lev++) {
diff += Swap(lev);
if(fReoVerbose)
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
if(diff <= min_diff)
min_lev = lev + 1, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
else if(diff > thold) {
lev++;
break;
}
}
lev--;
if(UpFirst) {
for(; lev >= min_lev; lev--) {
diff += Swap(lev);
if(fReoVerbose)
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
}
} else {
for(; lev >= 0; lev--) {
diff += Swap(lev);
if(fReoVerbose)
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
if(diff <= min_diff)
min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
else if(diff > thold) {
lev--;
break;
}
}
lev++;
for(; lev < min_lev; lev++) {
diff += Swap(lev);
if(fReoVerbose)
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
}
}
count += min_diff;
if(fReoVerbose)
std::cout << "Sifted " << sift_order[v] << " : Level = " << min_lev << " Count = " << count << " Thold = " << thold << std::endl;
}
}
public:
Man(int nVars_, Param p) {
nVerbose = p.nVerbose;
// parameter sanity check
if(p.nObjsMaxLog < p.nObjsAllocLog)
throw std::invalid_argument("nObjsMax must not be smaller than nObjsAlloc");
if(nVars_ >= (int)VarMax())
throw std::length_error("Memout (nVars) in init");
nVars = nVars_;
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
if(!nObjsMaxLit)
throw std::length_error("Memout (nObjsMax) in init");
if(nObjsMaxLit > (lit)BvarMax())
nObjsMax = BvarMax();
else
nObjsMax = (bvar)nObjsMaxLit;
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
if(!nObjsAllocLit)
throw std::length_error("Memout (nObjsAlloc) in init");
if(nObjsAllocLit > (lit)BvarMax())
nObjsAlloc = BvarMax();
else
nObjsAlloc = (bvar)nObjsAllocLit;
if(nObjsAlloc <= (bvar)nVars)
throw std::invalid_argument("nObjsAlloc must be larger than nVars");
uniq nUniqueSize = (uniq)1 << p.nUniqueSizeLog;
if(!nUniqueSize)
throw std::length_error("Memout (nUniqueSize) in init");
// allocation
if(nVerbose)
std::cout << "Allocating " << nObjsAlloc << " nodes and " << nVars << " x " << nUniqueSize << " unique table entries" << std::endl;
vVars.resize(nObjsAlloc);
vObjs.resize((lit)nObjsAlloc * 2);
vNexts.resize(nObjsAlloc);
vMarks.resize(nObjsAlloc);
vvUnique.resize(nVars);
vUniqueMasks.resize(nVars);
vUniqueCounts.resize(nVars);
vUniqueTholds.resize(nVars);
for(var v = 0; v < nVars; v++) {
vvUnique[v].resize(nUniqueSize);
vUniqueMasks[v] = nUniqueSize - 1;
if((lit)(nUniqueSize * p.UniqueDensity) > (lit)BvarMax())
vUniqueTholds[v] = BvarMax();
else
vUniqueTholds[v] = (bvar)(nUniqueSize * p.UniqueDensity);
}
if(p.fCountOnes) {
if(nVars > 1023)
throw std::length_error("nVars must be less than 1024 to count ones");
vOneCounts.resize(nObjsAlloc);
}
// set up cache
cache = new Cache(p.nCacheSizeLog, p.nCacheMaxLog, p.nCacheVerbose);
// create nodes for variables
nObjs = 1;
vVars[0] = VarMax();
for(var v = 0; v < nVars; v++)
UniqueCreateInt(v, 1, 0);
// set up variable order
Var2Level.resize(nVars);
Level2Var.resize(nVars);
for(var v = 0; v < nVars; v++) {
if(p.pVar2Level)
Var2Level[v] = (*p.pVar2Level)[v];
else
Var2Level[v] = v;
Level2Var[Var2Level[v]] = v;
}
// set other parameters
RemovedHead = 0;
nGbc = p.nGbc;
nReo = p.nReo;
MaxGrowth = p.MaxGrowth;
fReoVerbose = p.fReoVerbose;
if(nGbc || nReo != BvarMax())
vRefs.resize(nObjsAlloc);
}
~Man() {
if(nVerbose) {
std::cout << "Free " << nObjsAlloc << " nodes (" << nObjs << " live nodes)" << std::endl;
std::cout << "Free {";
std::string delim;
for(var v = 0; v < nVars; v++) {
std::cout << delim << vvUnique[v].size();
delim = ", ";
}
std::cout << "} unique table entries" << std::endl;
if(!vRefs.empty())
std::cout << "Free " << vRefs.size() << " refs" << std::endl;
}
delete cache;
}
void Reorder() {
if(nVerbose >= 2)
std::cout << "Reorder" << std::endl;
int nGbc_ = nGbc;
nGbc = 0;
CountEdges();
Sift();
vEdges.clear();
cache->Clear();
nGbc = nGbc_;
}
inline lit And(lit x, lit y) {
if(nObjs > nReo) {
Reorder();
while(nReo < nObjs) {
nReo <<= 1;
if((lit)nReo > (lit)BvarMax())
nReo = BvarMax();
}
}
return And_rec(x, y);
}
inline lit Or(lit x, lit y) {
return LitNot(And(LitNot(x), LitNot(y)));
}
public:
void SetRef(std::vector<lit> const &vLits) {
vRefs.clear();
vRefs.resize(nObjsAlloc);
for(size_t i = 0; i < vLits.size(); i++)
IncRef(vLits[i]);
}
void TurnOffReo() {
nReo = BvarMax();
if(!nGbc)
vRefs.clear();
}
bvar CountNodes() {
bvar count = 1;
if(!vEdges.empty()) {
for(bvar a = 1; a < nObjs; a++)
if(EdgeOfBvar(a))
count++;
return count;
}
for(bvar a = 1; a <= (bvar)nVars; a++) {
count++;
SetMarkOfBvar(a);
}
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
if(RefOfBvar(a))
count += CountNodes_rec(Bvar2Lit(a));
for(bvar a = 1; a <= (bvar)nVars; a++)
ResetMarkOfBvar(a);
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
if(RefOfBvar(a))
ResetMark_rec(Bvar2Lit(a));
return count;
}
bvar CountNodes(std::vector<lit> const &vLits) {
bvar count = 1;
for(size_t i = 0; i < vLits.size(); i++)
count += CountNodes_rec(vLits[i]);
for(size_t i = 0; i < vLits.size(); i++)
ResetMark_rec(vLits[i]);
return count;
}
void PrintStats() {
bvar nRemoved = 0;
bvar a = RemovedHead;
while(a)
a = vNexts[a], nRemoved++;
bvar nLive = 1;
for(var v = 0; v < nVars; v++)
nLive += vUniqueCounts[v];
std::cout << "ref: " << std::setw(10) << (vRefs.empty()? 0: CountNodes()) << ", "
<< "used: " << std::setw(10) << nObjs << ", "
<< "live: " << std::setw(10) << nLive << ", "
<< "dead: " << std::setw(10) << nRemoved << ", "
<< "alloc: " << std::setw(10) << nObjsAlloc
<< std::endl;
}
};
}
ABC_NAMESPACE_CXX_HEADER_END
#endif

261
src/aig/gia/giaNewTt.h Normal file
View File

@ -0,0 +1,261 @@
#ifndef ABC__aig__gia__giaNewTt_h
#define ABC__aig__gia__giaNewTt_h
#include <limits>
#include <iomanip>
#include <iostream>
#include <vector>
#include <bitset>
ABC_NAMESPACE_CXX_HEADER_START
namespace NewTt {
typedef int bvar;
typedef unsigned lit;
typedef unsigned short ref;
typedef unsigned long long size;
static inline bvar BvarMax() { return std::numeric_limits<bvar>::max(); }
static inline lit LitMax() { return std::numeric_limits<lit>::max(); }
static inline ref RefMax() { return std::numeric_limits<ref>::max(); }
static inline size SizeMax() { return std::numeric_limits<size>::max(); }
struct Param {
int nObjsAllocLog;
int nObjsMaxLog;
int nVerbose;
bool fCountOnes;
int nGbc;
int nReo; // dummy
Param() {
nObjsAllocLog = 15;
nObjsMaxLog = 20;
nVerbose = 0;
fCountOnes = false;
nGbc = 0;
nReo = BvarMax();
}
};
class Man {
private:
typedef unsigned long long word;
typedef std::bitset<64> bsw;
static inline int ww() { return 64; } // word width
static inline int lww() { return 6; } // log word width
static inline word one() {return 0xffffffffffffffffull; }
static inline word vars(int i) {
static const word vars[] = {0xaaaaaaaaaaaaaaaaull,
0xccccccccccccccccull,
0xf0f0f0f0f0f0f0f0ull,
0xff00ff00ff00ff00ull,
0xffff0000ffff0000ull,
0xffffffff00000000ull};
return vars[i];
}
static inline word ones(int i) {
static const word ones[] = {0x0000000000000001ull,
0x0000000000000003ull,
0x000000000000000full,
0x00000000000000ffull,
0x000000000000ffffull,
0x00000000ffffffffull,
0xffffffffffffffffull};
return ones[i];
}
private:
int nVars;
bvar nObjs;
bvar nObjsAlloc;
bvar nObjsMax;
size nSize;
size nTotalSize;
std::vector<word> vVals;
std::vector<bvar> vDeads;
std::vector<ref> vRefs;
int nGbc;
int nVerbose;
public:
inline lit Bvar2Lit(bvar a) const { return (lit)a << 1; }
inline bvar Lit2Bvar(lit x) const { return (bvar)(x >> 1); }
inline lit IthVar(int v) const { return ((lit)v + 1) << 1; }
inline lit LitNot(lit x) const { return x ^ (lit)1; }
inline lit LitNotCond(lit x, bool c) const { return x ^ (lit)c; }
inline bool LitIsCompl(lit x) const { return x & (lit)1; }
inline ref Ref(lit x) const { return vRefs[Lit2Bvar(x)]; }
inline lit Const0() const { return (lit)0; }
inline lit Const1() const { return (lit)1; }
inline bool IsConst0(lit x) const {
bvar a = Lit2Bvar(x);
word c = LitIsCompl(x)? one(): 0;
for(size j = 0; j < nSize; j++)
if(vVals[nSize * a + j] ^ c)
return false;
return true;
}
inline bool IsConst1(lit x) const {
bvar a = Lit2Bvar(x);
word c = LitIsCompl(x)? one(): 0;
for(size j = 0; j < nSize; j++)
if(~(vVals[nSize * a + j] ^ c))
return false;
return true;
}
inline bool LitIsEq(lit x, lit y) const {
if(x == y)
return true;
if(x == LitMax() || y == LitMax())
return false;
bvar xvar = Lit2Bvar(x);
bvar yvar = Lit2Bvar(y);
word c = LitIsCompl(x) ^ LitIsCompl(y)? one(): 0;
for(size j = 0; j < nSize; j++)
if(vVals[nSize * xvar + j] ^ vVals[nSize * yvar + j] ^ c)
return false;
return true;
}
inline size OneCount(lit x) const {
bvar a = Lit2Bvar(x);
size count = 0;
if(nVars > 6) {
for(size j = 0; j < nSize; j++)
count += bsw(vVals[nSize * a + j]).count();
} else
count = bsw(vVals[nSize * a] & ones(nVars)).count();
return LitIsCompl(x)? ((size)1 << nVars) - count: count;
}
public:
inline void IncRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]++; }
inline void DecRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]--; }
public:
bool Resize() {
if(nObjsAlloc == nObjsMax)
return false;
lit nObjsAllocLit = (lit)nObjsAlloc << 1;
if(nObjsAllocLit > (lit)BvarMax())
nObjsAlloc = BvarMax();
else
nObjsAlloc = (bvar)nObjsAllocLit;
nTotalSize = nTotalSize << 1;
if(nVerbose >= 2)
std::cout << "Reallocating " << nObjsAlloc << " nodes" << std::endl;
vVals.resize(nTotalSize);
if(!vRefs.empty())
vRefs.resize(nObjsAlloc);
return true;
}
bool Gbc() {
if(nVerbose >= 2)
std::cout << "Garbage collect" << std::endl;
for(bvar a = nVars + 1; a < nObjs; a++)
if(!vRefs[a])
vDeads.push_back(a);
return vDeads.size();
}
public:
Man(int nVars, Param p): nVars(nVars) {
if(p.nObjsMaxLog < p.nObjsAllocLog)
throw std::invalid_argument("nObjsMax must not be smaller than nObjsAlloc");
if(nVars >= lww())
nSize = 1ull << (nVars - lww());
else
nSize = 1;
if(!nSize)
throw std::length_error("Memout (nVars) in init");
if(!(nSize << p.nObjsMaxLog))
throw std::length_error("Memout (nObjsMax) in init");
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
if(!nObjsMaxLit)
throw std::length_error("Memout (nObjsMax) in init");
if(nObjsMaxLit > (lit)BvarMax())
nObjsMax = BvarMax();
else
nObjsMax = (bvar)nObjsMaxLit;
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
if(!nObjsAllocLit)
throw std::length_error("Memout (nObjsAlloc) in init");
if(nObjsAllocLit > (lit)BvarMax())
nObjsAlloc = BvarMax();
else
nObjsAlloc = (bvar)nObjsAllocLit;
if(nObjsAlloc <= (bvar)nVars)
throw std::invalid_argument("nObjsAlloc must be larger than nVars");
nTotalSize = nSize << p.nObjsAllocLog;
vVals.resize(nTotalSize);
if(p.fCountOnes && nVars > 63)
throw std::length_error("nVars must be less than 64 to count ones");
nObjs = 1;
for(int i = 0; i < 6 && i < nVars; i++) {
for(size j = 0; j < nSize; j++)
vVals[nSize * nObjs + j] = vars(i);
nObjs++;
}
for(int i = 0; i < nVars - 6; i++) {
for(size j = 0; j < nSize; j += (2ull << i))
for(size k = 0; k < (1ull << i); k++)
vVals[nSize * nObjs + j + k] = one();
nObjs++;
}
nVerbose = p.nVerbose;
nGbc = p.nGbc;
if(nGbc || p.nReo != BvarMax())
vRefs.resize(nObjsAlloc);
}
inline lit And(lit x, lit y) {
bvar xvar = Lit2Bvar(x);
bvar yvar = Lit2Bvar(y);
word xcompl = LitIsCompl(x)? one(): 0;
word ycompl = LitIsCompl(y)? one(): 0;
unsigned j;
if(nObjs >= nObjsAlloc && vDeads.empty()) {
bool fRemoved = false;
if(nGbc > 1)
fRemoved = Gbc();
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
throw std::length_error("Memout (node)");
}
bvar zvar;
if(nObjs < nObjsAlloc)
zvar = nObjs++;
else
zvar = vDeads.back(), vDeads.resize(vDeads.size() - 1);
for(j = 0; j < nSize; j++)
vVals[nSize * zvar + j] = (vVals[nSize * xvar + j] ^ xcompl) & (vVals[nSize * yvar + j] ^ ycompl);
return zvar << 1;
}
inline lit Or(lit x, lit y) {
return LitNot(And(LitNot(x), LitNot(y)));
}
void Reorder() {} // dummy
public:
void SetRef(std::vector<lit> const &vLits) {
vRefs.clear();
vRefs.resize(nObjsAlloc);
for(size_t i = 0; i < vLits.size(); i++)
IncRef(vLits[i]);
}
void TurnOffReo() {
if(!nGbc)
vRefs.clear();
}
void PrintNode(lit x) const {
bvar a = Lit2Bvar(x);
word c = LitIsCompl(x)? one(): 0;
for(size j = 0; j < nSize; j++)
std::cout << bsw(vVals[nSize * a + j] ^ c);
std::cout << std::endl;
}
};
}
ABC_NAMESPACE_CXX_HEADER_END
#endif

View File

@ -0,0 +1,125 @@
#ifdef _WIN32
#ifndef __MINGW32__
#pragma warning(disable : 4786) // warning C4786: identifier was truncated to '255' characters in the browser information
#endif
#endif
#include "giaTransduction.h"
#include "giaNewBdd.h"
#include "giaNewTt.h"
ABC_NAMESPACE_IMPL_START
Gia_Man_t *Gia_ManTransductionBdd(Gia_Man_t *pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t *pExdc, int fNewLine, int nVerbose) {
if(nRandom) {
srand(nRandom);
nSortType = rand() % 4;
nPiShuffle = rand();
nParameter = rand() % 16;
}
NewBdd::Param p;
Transduction::Transduction<NewBdd::Man, NewBdd::Param, NewBdd::lit, 0xffffffff> t(pGia, nVerbose, fNewLine, nSortType, nPiShuffle, fLevel, pExdc, p);
int count = t.CountWires();
switch(nType) {
case 0:
count -= fMspf? t.Mspf(): t.Cspf();
break;
case 1:
count -= t.Resub(fMspf);
break;
case 2:
count -= t.ResubMono(fMspf);
break;
case 3:
count -= t.ResubShared(fMspf);
break;
case 4:
count -= t.RepeatResub(false, fMspf);
break;
case 5:
count -= t.RepeatResub(true, fMspf);
break;
case 6: {
bool fInner = (nParameter / 4) % 2;
count -= t.RepeatInner(fMspf, fInner);
break;
}
case 7: {
bool fInner = (nParameter / 4) % 2;
bool fOuter = (nParameter / 8) % 2;
count -= t.RepeatOuter(fMspf, fInner, fOuter);
break;
}
case 8: {
bool fFirstMerge = nParameter % 2;
bool fMspfMerge = fMspf? (nParameter / 2) % 2: false;
bool fInner = (nParameter / 4) % 2;
bool fOuter = (nParameter / 8) % 2;
count -= t.RepeatAll(fFirstMerge, fMspfMerge, fMspf, fInner, fOuter);
break;
}
default:
std::cout << "Unknown transduction type " << nType << std::endl;
}
assert(t.Verify());
assert(count == t.CountWires());
return t.GenerateAig();
}
Gia_Man_t *Gia_ManTransductionTt(Gia_Man_t *pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t *pExdc, int fNewLine, int nVerbose) {
if(nRandom) {
srand(nRandom);
nSortType = rand() % 4;
nPiShuffle = rand();
nParameter = rand() % 16;
}
NewTt::Param p;
Transduction::Transduction<NewTt::Man, NewTt::Param, NewTt::lit, 0xffffffff> t(pGia, nVerbose, fNewLine, nSortType, nPiShuffle, fLevel, pExdc, p);
int count = t.CountWires();
switch(nType) {
case 0:
count -= fMspf? t.Mspf(): t.Cspf();
break;
case 1:
count -= t.Resub(fMspf);
break;
case 2:
count -= t.ResubMono(fMspf);
break;
case 3:
count -= t.ResubShared(fMspf);
break;
case 4:
count -= t.RepeatResub(false, fMspf);
break;
case 5:
count -= t.RepeatResub(true, fMspf);
break;
case 6: {
bool fInner = (nParameter / 4) % 2;
count -= t.RepeatInner(fMspf, fInner);
break;
}
case 7: {
bool fInner = (nParameter / 4) % 2;
bool fOuter = (nParameter / 8) % 2;
count -= t.RepeatOuter(fMspf, fInner, fOuter);
break;
}
case 8: {
bool fFirstMerge = nParameter % 2;
bool fMspfMerge = fMspf? (nParameter / 2) % 2: false;
bool fInner = (nParameter / 4) % 2;
bool fOuter = (nParameter / 8) % 2;
count -= t.RepeatAll(fFirstMerge, fMspfMerge, fMspf, fInner, fOuter);
break;
}
default:
std::cout << "Unknown transduction type " << nType << std::endl;
}
assert(t.Verify());
assert(count == t.CountWires());
return t.GenerateAig();
}
ABC_NAMESPACE_IMPL_END

File diff suppressed because it is too large Load Diff

View File

@ -103,6 +103,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaSwitch.c \
src/aig/gia/giaTim.c \
src/aig/gia/giaTis.c \
src/aig/gia/giaTransduction.cpp \
src/aig/gia/giaTruth.c \
src/aig/gia/giaTsim.c \
src/aig/gia/giaTtopt.cpp \

View File

@ -503,6 +503,7 @@ static int Abc_CommandAbc9LNetEval ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9LNetOpt ( Abc_Frame_t * pAbc, int argc, char ** argv );
//#ifndef _WIN32
static int Abc_CommandAbc9Ttopt ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Transduction ( 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 );
@ -1260,6 +1261,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&lnetopt", Abc_CommandAbc9LNetOpt, 0 );
//#ifndef _WIN32
Cmd_CommandAdd( pAbc, "ABC9", "&ttopt", Abc_CommandAbc9Ttopt, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&transduction", Abc_CommandAbc9Transduction, 0 );
//#endif
Cmd_CommandAdd( pAbc, "ABC9", "&lnetmap", Abc_CommandAbc9LNetMap, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&unmap", Abc_CommandAbc9Unmap, 0 );
@ -42571,6 +42573,173 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc9Transduction( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Gia_Man_t * pTemp, * pExdc = NULL;
int c, nType = 1, fMspf = 0, nRandom = 0, nSortType = 0, nPiShuffle = 0, nParameter = 0, fLevel = 0, fTruth = 0, fNewLine = 0, nVerbose = 2;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "TSIPRVtmnl" ) ) != EOF )
{
switch ( c )
{
case 'T':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-T\" should be followed by a positive integer.\n" );
goto usage;
}
nType = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'R':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-R\" should be followed by a positive integer.\n" );
goto usage;
}
nRandom = 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;
}
nSortType = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'I':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-I\" should be followed by a positive integer.\n" );
goto usage;
}
nPiShuffle = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'P':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-P\" should be followed by a positive integer.\n" );
goto usage;
}
nParameter = 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 't':
fTruth ^= 1;
break;
case 'm':
fMspf ^= 1;
break;
case 'n':
fNewLine ^= 1;
break;
case 'l':
fLevel ^= 1;
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 ( argc == globalUtilOptind + 1 )
{
FILE * pFile = fopen( argv[globalUtilOptind], "rb" );
if ( pFile == NULL )
{
Abc_Print( -1, "Cannot open input file \"%s\". ", argv[globalUtilOptind] );
return 1;
}
fclose( pFile );
pExdc = Gia_AigerRead( argv[globalUtilOptind], 0, 0, 0 );
if ( pExdc == NULL )
{
Abc_Print( -1, "Reading AIGER has failed.\n" );
return 1;
}
}
if ( fLevel && (nType == 3 || nType == 8) )
{
Abc_Print( -1, "Level preserving optimization does not work with transduction type 3 and 8.\n" );
return 1;
}
if ( fTruth )
pTemp = Gia_ManTransductionTt( pAbc->pGia, nType, fMspf, nRandom, nSortType, nPiShuffle, nParameter, fLevel, pExdc, fNewLine, nVerbose );
else
pTemp = Gia_ManTransductionBdd( pAbc->pGia, nType, fMspf, nRandom, nSortType, nPiShuffle, nParameter, fLevel, pExdc, fNewLine, nVerbose );
if ( pExdc != NULL )
Gia_ManStop( pExdc );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
usage:
Abc_Print( -2, "usage: &transduction [-TSIPRV num] [-bmlh] <file>\n" );
Abc_Print( -2, "\t performs transduction-based AIG optimization\n" );
Abc_Print( -2, "\t-T num : transduction type [default = %d]\n", nType );
Abc_Print( -2, "\t 0: remove simply redundant nodes\n" );
Abc_Print( -2, "\t 1: Resub\n" );
Abc_Print( -2, "\t 2: ResubMono\n" );
Abc_Print( -2, "\t 3: ResubShared\n" );
Abc_Print( -2, "\t 4: repeat Resub\n" );
Abc_Print( -2, "\t 5: repeat ResubMono\n" );
Abc_Print( -2, "\t 6: script RepeatInner\n" );
Abc_Print( -2, "\t 7: script RepeatOuter\n" );
Abc_Print( -2, "\t 8: script RepeatAll\n" );
Abc_Print( -2, "\t-S num : fanin sort type [default = %d]\n", nSortType );
Abc_Print( -2, "\t 0: topological order\n" );
Abc_Print( -2, "\t 1: number of ones\n" );
Abc_Print( -2, "\t 2: number of ones before complemented edges\n" );
Abc_Print( -2, "\t 3: pseudo random\n" );
Abc_Print( -2, "\t 4: no sorting\n" );
Abc_Print( -2, "\t-I num : random seed to shuffle PIs (0 = no shuffle) [default = %d]\n", nPiShuffle );
Abc_Print( -2, "\t-P num : parameters for scripts [default = %d]\n", nParameter );
Abc_Print( -2, "\t-R num : random seed to set all parameters (0 = no random) ([default = %d]\n", nRandom );
Abc_Print( -2, "\t-V num : verbosity level [default = %d]\n", nVerbose);
Abc_Print( -2, "\t-t : toggles using truth table instead of BDD [default = %s]\n", fTruth? "yes": "no" );
Abc_Print( -2, "\t-m : toggles using MSPF [default = %s]\n", fMspf? "yes": "no" );
Abc_Print( -2, "\t-n : toggles printing with a new line [default = %s]\n", fNewLine? "yes": "no" );
Abc_Print( -2, "\t-l : toggles level preserving optimization [default = %s]\n", fLevel? "yes": "no" );
Abc_Print( -2, "\t-h : prints the command usage\n");
Abc_Print( -2, "\t<file> : AIGER specifying external don't-cares\n");
Abc_Print( -2, "\t\n" );
Abc_Print( -2, "\t This command was contributed by Yukio Miyasaka.\n" );
return 1;
}
/**Function*************************************************************
Synopsis []