131 template <
typename Ntk,
typename Ana>
160 this->nTried += other.
nTried;
161 this->nAdded += other.
nAdded;
163 this->nUps += other.
nUps;
164 this->nEqs += other.
nEqs;
165 this->nDowns += other.
nDowns;
172 std::stringstream ss;
173 PrintNext(ss,
"tried node/fanin",
"=",
nTried,
"/",
nTriedFis,
",",
"added node/fanin",
"=",
nAdded,
"/",
nAddedFis,
",",
"changed",
"=",
nChanged,
",",
"up/eq/dn",
"=",
nUps,
"/",
nEqs,
"/",
nDowns);
182 template <
typename Ntk,
typename Ana>
183 template <
typename... Args>
184 inline void Optimizer<Ntk, Ana>::Print(
int nVerboseLevel, Args... args) {
185 if(nVerbose > nVerboseLevel) {
186 std::stringstream ss;
187 for(
int i = 0; i < nVerboseLevel; i++) {
199 template <
typename Ntk,
typename Ana>
200 void Optimizer<Ntk, Ana>::ActionCallback(
Action const &action) {
202 std::stringstream ss = GetActionDescription(action);
204 std::getline(ss, str);
206 while(std::getline(ss, str)) {
210 switch(action.type) {
212 if(action.id != target) {
220 if(action.id == target) {
225 if(action.id != target) {
255 template <
typename Ntk,
typename Ana>
256 inline void Optimizer<Ntk, Ana>::MarkTfo(
int id) {
263 vTfoMarks.resize(pNtk->GetNumNodes());
264 vTfoMarks[id] =
true;
265 pNtk->ForEachTfo(
id,
false, [&](
int fo) {
266 vTfoMarks[fo] =
true;
274 template <
typename Ntk,
typename Ana>
275 inline bool Optimizer<Ntk, Ana>::Timeout() {
278 if(DurationInSeconds(start, current) > nTimeout) {
289 template <
typename Ntk,
typename Ana>
290 inline void Optimizer<Ntk, Ana>::SetRandPiOrder() {
291 if(int_size(vRandPiOrder) != pNtk->GetNumPis()) {
292 vRandPiOrder.clear();
293 vRandPiOrder.resize(pNtk->GetNumPis());
294 std::iota(vRandPiOrder.begin(), vRandPiOrder.end(), 0);
295 std::shuffle(vRandPiOrder.begin(), vRandPiOrder.end(), rng);
299 template <
typename Ntk,
typename Ana>
300 inline void Optimizer<Ntk, Ana>::SetRandCosts() {
301 std::uniform_real_distribution<> dis(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max());
302 while(int_size(vRandCosts) < pNtk->GetNumNodes()) {
303 vRandCosts.push_back(dis(rng));
307 template <
typename Ntk,
typename Ana>
308 inline void Optimizer<Ntk, Ana>::SortFanins(
int id) {
313 pNtk->SortFanins(
id, [&](
int i,
int j) {
314 return !pNtk->IsPi(i) && pNtk->IsPi(j);
318 pNtk->SortFanins(
id, [&](
int i,
int j) {
319 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
320 return pNtk->GetPiIndex(i) > pNtk->GetPiIndex(j);
322 return pNtk->IsPi(j);
327 pNtk->SortFanins(
id, [&](
int i,
int j) {
328 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
329 return vRandPiOrder[pNtk->GetPiIndex(i)] > vRandPiOrder[pNtk->GetPiIndex(j)];
331 return pNtk->IsPi(j);
335 pNtk->SortFanins(
id, [&](
int i,
int j) {
336 return pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j);
340 pNtk->SortFanins(
id, [&](
int i,
int j) {
341 if(pNtk->IsPi(i) && !pNtk->IsPi(j)) {
344 if(!pNtk->IsPi(i) && pNtk->IsPi(j)) {
347 return pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j);
351 pNtk->SortFanins(
id, [&](
int i,
int j) {
352 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
353 return pNtk->GetPiIndex(i) > pNtk->GetPiIndex(j);
361 return pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j);
366 pNtk->SortFanins(
id, [&](
int i,
int j) {
367 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
368 return vRandPiOrder[pNtk->GetPiIndex(i)] > vRandPiOrder[pNtk->GetPiIndex(j)];
376 return pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j);
380 pNtk->SortFanins(
id, [&](
int i,
int j) {
381 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
390 return pNtk->GetIntIndex(i) > pNtk->GetIntIndex(j);
394 pNtk->SortFanins(
id, [&](
int i,
int j) {
395 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
396 return pNtk->GetPiIndex(i) > pNtk->GetPiIndex(j);
404 return pNtk->GetIntIndex(i) > pNtk->GetIntIndex(j);
409 pNtk->SortFanins(
id, [&](
int i,
int j) {
410 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
411 return vRandPiOrder[pNtk->GetPiIndex(i)] > vRandPiOrder[pNtk->GetPiIndex(j)];
419 return pNtk->GetIntIndex(i) > pNtk->GetIntIndex(j);
423 pNtk->SortFanins(
id, [&](
int i,
int j) {
424 if(pNtk->IsPi(i) && !pNtk->IsPi(j)) {
427 if(!pNtk->IsPi(i) && pNtk->IsPi(j)) {
430 if(pNtk->GetNumFanouts(i) > pNtk->GetNumFanouts(j)) {
433 if(pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j)) {
436 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
439 return pNtk->GetIntIndex(i) > pNtk->GetIntIndex(j);
443 pNtk->SortFanins(
id, [&](
int i,
int j) {
444 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
445 return pNtk->GetPiIndex(i) > pNtk->GetPiIndex(j);
453 if(pNtk->GetNumFanouts(i) > pNtk->GetNumFanouts(j)) {
456 if(pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j)) {
459 return pNtk->GetIntIndex(i) > pNtk->GetIntIndex(j);
464 pNtk->SortFanins(
id, [&](
int i,
int j) {
465 if(pNtk->IsPi(i) && pNtk->IsPi(j)) {
466 return vRandPiOrder[pNtk->GetPiIndex(i)] > vRandPiOrder[pNtk->GetPiIndex(j)];
474 if(pNtk->GetNumFanouts(i) > pNtk->GetNumFanouts(j)) {
477 if(pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j)) {
480 return pNtk->GetIntIndex(i) > pNtk->GetIntIndex(j);
485 pNtk->SortFanins(
id, [&](
int i,
int j) {
486 return vRandCosts[i] > vRandCosts[j];
491 pNtk->SortFanins(
id, [&](
int i,
int j) {
492 if(pNtk->IsPi(i) && !pNtk->IsPi(j)) {
495 if(!pNtk->IsPi(i) && pNtk->IsPi(j)) {
498 return vRandCosts[i] > vRandCosts[j];
503 pNtk->SortFanins(
id, [&](
int i,
int j) {
504 if(pNtk->GetNumFanouts(i) > pNtk->GetNumFanouts(j)) {
507 if(pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j)) {
510 return vRandCosts[i] > vRandCosts[j];
515 pNtk->SortFanins(
id, [&](
int i,
int j) {
516 if(pNtk->IsPi(i) && !pNtk->IsPi(j)) {
519 if(!pNtk->IsPi(i) && pNtk->IsPi(j)) {
522 if(pNtk->GetNumFanouts(i) > pNtk->GetNumFanouts(j)) {
525 if(pNtk->GetNumFanouts(i) < pNtk->GetNumFanouts(j)) {
528 return vRandCosts[i] > vRandCosts[j];
536 template <
typename Ntk,
typename Ana>
537 inline void Optimizer<Ntk, Ana>::SortFanins() {
538 pNtk->ForEachInt([&](
int id) {
547 template <
typename Ntk,
typename Ana>
548 inline bool Optimizer<Ntk, Ana>::ReduceFanins(
int id,
bool fRemoveUnused) {
549 assert(pNtk->GetNumFanouts(
id) > 0);
550 bool fReduced =
false;
551 for(
int idx = 0; idx < pNtk->GetNumFanins(
id); idx++) {
553 if(mapNewFanins.count(
id)) {
554 int fi = pNtk->GetFanin(
id, idx);
555 if(mapNewFanins[
id].count(fi)) {
560 if(ana.CheckRedundancy(
id, idx)) {
561 int fi = pNtk->GetFanin(
id, idx);
562 pNtk->RemoveFanin(
id, idx);
565 if(fRemoveUnused && pNtk->GetNumFanouts(fi) == 0) {
566 pNtk->RemoveUnused(fi,
true);
609 template <
typename Ntk,
typename Ana>
610 bool Optimizer<Ntk, Ana>::Reduce(
bool fSubRoutine) {
612 bool fReduced =
false;
613 std::vector<int> vInts = pNtk->GetInts();
614 for(critr it = vInts.rbegin(); it != vInts.rend(); it++) {
615 if(!pNtk->IsInt(*it)) {
618 if(pNtk->GetNumFanouts(*it) == 0) {
619 pNtk->RemoveUnused(*it);
622 fReduced |= ReduceFanins(*it);
623 if(pNtk->GetNumFanins(*it) <= 1) {
624 pNtk->Propagate(*it);
660 template <
typename Ntk,
typename Ana>
661 bool Optimizer<Ntk, Ana>::RemoveRedundancy() {
663 bool fReduced =
false;
665 while(Reduce(
true)) {
670 std::vector<int> vInts = pNtk->GetInts();
671 for(critr it = vInts.rbegin(); it != vInts.rend();) {
672 if(!pNtk->IsInt(*it)) {
676 if(pNtk->GetNumFanouts(*it) == 0) {
677 pNtk->RemoveUnused(*it);
682 bool fReduced_ = ReduceFanins(*it);
683 fReduced |= fReduced_;
684 if(pNtk->GetNumFanins(*it) <= 1) {
685 pNtk->Propagate(*it);
733 template <
typename Ntk,
typename Ana>
734 template <
typename T>
735 T Optimizer<Ntk, Ana>::SingleAdd(
int id, T begin, T end) {
738 pNtk->ForEachFanin(
id, [&](
int fi) {
739 vTfoMarks[fi] =
true;
742 for(; it != end; it++) {
743 if(!pNtk->IsInt(*it) && !pNtk->IsPi(*it)) {
750 if(ana.CheckFeasibility(
id, *it,
false)) {
751 pNtk->AddFanin(
id, *it,
false);
753 }
else if(pNtk->UseComplementedEdges() && ana.CheckFeasibility(
id, *it,
true)) {
754 pNtk->AddFanin(
id, *it,
true);
759 mapNewFanins[id].insert(*it);
762 pNtk->ForEachFanin(
id, [&](
int fi) {
763 vTfoMarks[fi] =
false;
766 statsLocal.
durationAdd += Duration(timeStart, timeEnd);
770 template <
typename Ntk,
typename Ana>
771 int Optimizer<Ntk, Ana>::MultiAdd(
int id, std::vector<int>
const &vCands,
int nMax) {
774 pNtk->ForEachFanin(
id, [&](
int fi) {
775 vTfoMarks[fi] =
true;
778 for(
int cand: vCands) {
779 if(!pNtk->IsInt(cand) && !pNtk->IsPi(cand)) {
782 if(vTfoMarks[cand]) {
786 if(ana.CheckFeasibility(
id, cand,
false)) {
787 pNtk->AddFanin(
id, cand,
false);
789 }
else if(pNtk->UseComplementedEdges() && ana.CheckFeasibility(
id, cand,
true)) {
790 pNtk->AddFanin(
id, cand,
true);
795 mapNewFanins[id].insert(cand);
797 if(nAddedFis_ == nMax) {
801 pNtk->ForEachFanin(
id, [&](
int fi) {
802 vTfoMarks[fi] =
false;
805 statsLocal.
durationAdd += Duration(timeStart, timeEnd);
809 template <
typename Ntk,
typename Ana>
810 void Optimizer<Ntk, Ana>::Undo() {
811 for(
auto const &entry: mapNewFanins) {
812 int id = entry.first;
813 for(
int fi: entry.second) {
814 int idx = pNtk->FindFanin(
id, fi);
815 pNtk->RemoveFanin(
id, idx);
824 template <
typename Ntk,
typename Ana>
825 void Optimizer<Ntk, Ana>::SingleResub(
int id, std::vector<int>
const &vCands) {
828 assert(pNtk->GetNumFanouts(
id) != 0);
829 assert(pNtk->GetNumFanins(
id) > 1);
831 pNtk->TrivialCollapse(
id);
834 if(fGreedy || fCompatible) {
838 double cost = CostFunction(pNtk);
839 bool fTried =
false, fAdded =
false;
840 for(citr it = vCands.begin(); it != vCands.end(); it++) {
844 if(!pNtk->IsInt(
id)) {
848 it = SingleAdd<citr>(
id, it, vCands.end());
849 if(it == vCands.end()) {
853 Print(2,
"cand", *it,
"(", int_distance(vCands.begin(), it) + 1,
"/", int_size(vCands),
")",
":",
"cost",
"=", cost);
854 if(RemoveRedundancy()) {
855 double costNew = CostFunction(pNtk);
860 }
else if (costNew == cost) {
867 if(costNew <= cost) {
884 mapNewFanins.clear();
886 if(pNtk->IsInt(
id)) {
887 pNtk->TrivialDecompose(
id);
893 if(fGreedy || fCompatible) {
904 template <
typename Ntk,
typename Ana>
905 void Optimizer<Ntk, Ana>::MultiResub(
int id, std::vector<int>
const &vCands,
int nMax) {
908 assert(pNtk->GetNumFanouts(
id) != 0);
909 assert(pNtk->GetNumFanins(
id) > 1);
913 if(fGreedy || fCompatible) {
917 pNtk->TrivialCollapse(
id);
919 double cost = CostFunction(pNtk);
920 if(MultiAdd(
id, vCands, nMax)) {
922 if(RemoveRedundancy()) {
923 mapNewFanins.clear();
925 double costNew = CostFunction(pNtk);
930 }
else if (costNew == cost) {
936 if(fGreedy && costNew > cost) {
945 mapNewFanins.clear();
948 if(pNtk->IsInt(
id)) {
949 pNtk->TrivialDecompose(
id);
955 if(fGreedy || fCompatible) {
964 template <
typename Ntk,
typename Ana>
965 bool Optimizer<Ntk, Ana>::SingleResubStop(
int id, std::vector<int>
const &vCands) {
970 assert(pNtk->GetNumFanouts(
id) != 0);
971 assert(pNtk->GetNumFanins(
id) > 1);
972 Print(2,
"method",
"=",
"single");
974 pNtk->TrivialCollapse(
id);
976 int slot = pNtk->Save();
978 std::set<int> sFanins = pNtk->GetExtendedFanins(
id);
979 Print(3,
"extended fanins",
":", sFanins);
981 bool fChanged =
false;
982 double cost = CostFunction(pNtk);
983 bool fTried =
false, fAdded =
false;
984 for(citr it = vCands.begin(); it != vCands.end(); it++) {
990 it = SingleAdd<citr>(
id, it, vCands.end());
991 if(it == vCands.end()) {
995 Print(3,
"cand", *it,
"(", int_distance(vCands.begin(), it) + 1,
"/", int_size(vCands),
")",
":",
"cost",
"=", cost);
996 if(RemoveRedundancy()) {
997 mapNewFanins.clear();
998 double costNew = CostFunction(pNtk);
999 if(costNew <= cost) {
1001 if(costNew < cost || !pNtk->IsInt(
id)) {
1004 std::set<int> sNewFanins = pNtk->GetExtendedFanins(
id);
1005 Print(3,
"new extended fanins",
":", sNewFanins);
1006 if(sFanins != sNewFanins) {
1012 if(costNew < cost) {
1014 }
else if (costNew == cost) {
1029 mapNewFanins.clear();
1032 if(pNtk->IsInt(
id)) {
1033 pNtk->TrivialDecompose(
id);
1045 template <
typename Ntk,
typename Ana>
1046 bool Optimizer<Ntk, Ana>::MultiResubStop(
int id, std::vector<int>
const &vCands,
int nMax) {
1051 assert(pNtk->GetNumFanouts(
id) != 0);
1052 assert(pNtk->GetNumFanins(
id) > 1);
1053 Print(2,
"method",
"=",
"multi");
1056 int slot = pNtk->Save();
1058 std::set<int> sFanins = pNtk->GetExtendedFanins(
id);
1059 Print(3,
"extended fanins",
":", sFanins);
1061 pNtk->TrivialCollapse(
id);
1063 bool fChanged =
false;
1064 double cost = CostFunction(pNtk);
1065 if(MultiAdd(
id, vCands, nMax)) {
1067 if(RemoveRedundancy()) {
1068 mapNewFanins.clear();
1070 double costNew = CostFunction(pNtk);
1071 if(!fGreedy || costNew <= cost) {
1073 if(costNew < cost || !pNtk->IsInt(
id)) {
1076 std::set<int> sNewFanins = pNtk->GetExtendedFanins(
id);
1077 Print(3,
"new extended fanins",
":", sNewFanins);
1078 if(sFanins != sNewFanins) {
1084 if(costNew < cost) {
1086 }
else if (costNew == cost) {
1094 mapNewFanins.clear();
1098 if(pNtk->IsInt(
id)) {
1099 pNtk->TrivialDecompose(
id);
1112 template <
typename Ntk,
typename Ana>
1113 bool Optimizer<Ntk, Ana>::MultiTargetResub(std::vector<int> vTargets,
int nMax) {
1115 int slot = pNtk->Save();
1116 double dCost = CostFunction(pNtk);
1118 for(
int id: vTargets) {
1119 if(pNtk->IsInt(
id)) {
1120 pNtk->TrivialCollapse(
id);
1123 for(itr it = vTargets.begin(); it != vTargets.end();) {
1124 if(!pNtk->IsInt(*it)) {
1125 it = vTargets.erase(it);
1131 Print(2,
"targets",
":", vTargets);
1132 std::vector<std::set<int>> vsFanins;
1133 for(
int id: vTargets) {
1135 std::vector<int> vCands;
1137 vCands = pNtk->GetNeighbors(
id,
true, nDistance);
1139 vCands = pNtk->GetPisInts();
1141 std::shuffle(vCands.begin(), vCands.end(), rng);
1143 std::set<int> sFanins = pNtk->GetExtendedFanins(
id);
1144 Print(3,
"extended fanins",
":", sFanins);
1145 vsFanins.push_back(std::move(sFanins));
1147 MultiAdd(
id, vCands, nMax);
1151 mapNewFanins.clear();
1154 double dNewCost = CostFunction(pNtk);
1155 Print(2,
"cost =", dCost,
"->", dNewCost);
1156 if(!fGreedy || dNewCost <= dCost) {
1157 bool fChanged =
false;
1158 if(dNewCost < dCost) {
1161 for(
int id: vTargets) {
1162 if(!pNtk->IsInt(
id)) {
1167 for(
int i = 0; !fChanged && i < int_size(vTargets); i++) {
1168 std::set<int> sNewFanins = pNtk->GetExtendedFanins(vTargets[i]);
1169 Print(3,
"new extended fanins",
":", sNewFanins);
1170 if(vsFanins[i] != sNewFanins) {
1176 for(
int id: vTargets) {
1177 if(pNtk->IsInt(
id)) {
1178 pNtk->TrivialDecompose(
id);
1194 template <
typename Ntk,
typename Ana>
1195 void Optimizer<Ntk, Ana>::ApplyReverseTopologically(std::function<
void(
int)>
const &func) {
1196 std::vector<int> vInts = pNtk->GetInts();
1197 for(critr it = vInts.rbegin(); it != vInts.rend(); it++) {
1201 if(!pNtk->IsInt(*it)) {
1204 Print(1,
"node", *it,
"(", int_distance(vInts.crbegin(), it) + 1,
"/", int_size(vInts),
")",
":",
"cost",
"=", CostFunction(pNtk));
1209 template <
typename Ntk,
typename Ana>
1210 void Optimizer<Ntk, Ana>::ApplyRandomlyStop(std::function<
bool(
int)>
const &func) {
1211 std::vector<int> vInts = pNtk->GetInts();
1212 std::shuffle(vInts.begin(), vInts.end(), rng);
1213 for(citr it = vInts.begin(); it != vInts.end(); it++) {
1217 if(!pNtk->IsInt(*it)) {
1220 Print(1,
"node", *it,
"(", int_distance(vInts.cbegin(), it) + 1,
"/", int_size(vInts),
")",
":",
"cost",
"=", CostFunction(pNtk));
1227 template <
typename Ntk,
typename Ana>
1228 void Optimizer<Ntk, Ana>::ApplyCombinationRandomlyStop(
int k, std::function<
bool(std::vector<int>
const &)>
const &func) {
1229 std::vector<int> vInts = pNtk->GetInts();
1230 std::shuffle(vInts.begin(), vInts.end(), rng);
1232 int nCombs = k * (k - 1) / 2;
1233 ForEachCombinationStop(int_size(vInts), k, [&](std::vector<int>
const &vIdxs) {
1234 Print(1,
"comb", vIdxs,
"(", ++nTried_,
"/", nCombs,
")");
1235 assert(int_size(vIdxs) == k);
1239 std::vector<int> vTargets(k);
1240 for(
int i = 0; i < k; i++) {
1241 vTargets[i] = vInts[vIdxs[i]];
1243 return func(vTargets);
1247 template <
typename Ntk,
typename Ana>
1248 void Optimizer<Ntk, Ana>::ApplyCombinationSampledRandomlyStop(
int k,
int nSamples, std::function<
bool(std::vector<int>
const &)>
const &func) {
1249 std::vector<int> vInts = pNtk->GetInts();
1250 for(
int i = 0; i < nSamples; i++) {
1254 std::set<int> sIdxs;
1255 while(int_size(sIdxs) < k) {
1256 int idx = rng() % pNtk->GetNumInts();
1259 std::vector<int> vIdxs(sIdxs.begin(), sIdxs.end());
1260 std::shuffle(vIdxs.begin(), vIdxs.end(), rng);
1261 Print(1,
"comb", vIdxs,
"(", i + 1,
"/", nSamples,
")");
1262 std::vector<int> vTargets(k);
1263 for(
int i = 0; i < k; i++) {
1264 vTargets[i] = vInts[vIdxs[i]];
1266 if(func(vTargets)) {
1276 template <
typename Ntk,
typename Ana>
1279 nVerbose(pPar->nOptimizerVerbose),
1280 CostFunction(CostFunction),
1281 nSortTypeOriginal(pPar->nSortType),
1282 nSortType(pPar->nSortType),
1283 nFlow(pPar->nOptimizerFlow),
1284 nDistance(pPar->nDistance),
1285 fCompatible(pPar->fUseBddCspf),
1286 fGreedy(pPar->fGreedy),
1291 template <
typename Ntk,
typename Ana>
1295 pNtk->AddCallback(std::bind(&Optimizer<Ntk, Ana>::ActionCallback,
this, std::placeholders::_1));
1296 ana.AssignNetwork(pNtk, fReuse);
1299 template <
typename Ntk,
typename Ana>
1301 PrintLine = PrintLine_;
1308 template <
typename Ntk,
typename Ana>
1311 vRandPiOrder.clear();
1313 if(nSortTypeOriginal < 0) {
1314 nSortType = rng() % 18;
1315 Print(0,
"fanin cost function =", nSortType);
1317 nTimeout = nTimeout_;
1318 start = GetCurrentTime();
1323 ApplyReverseTopologically([&](
int id) {
1324 std::vector<int> vCands;
1326 vCands = pNtk->GetNeighbors(
id,
true, nDistance);
1328 vCands = pNtk->GetPisInts();
1330 SingleResub(
id, vCands);
1332 stats[
"single"] += statsLocal;
1333 Print(0, statsLocal.GetString());
1338 ApplyReverseTopologically([&](
int id) {
1339 std::vector<int> vCands;
1341 vCands = pNtk->GetNeighbors(
id,
true, nDistance);
1343 vCands = pNtk->GetPisInts();
1345 MultiResub(
id, vCands);
1347 stats[
"multi"] += statsLocal;
1348 Print(0, statsLocal.GetString());
1352 double dCost = CostFunction(pNtk);
1355 ApplyReverseTopologically([&](
int id) {
1356 std::vector<int> vCands;
1358 vCands = pNtk->GetNeighbors(
id,
true, nDistance);
1360 vCands = pNtk->GetPisInts();
1362 SingleResub(
id, vCands);
1364 stats[
"single"] += statsLocal;
1365 Print(0,
"single",
":",
"cost",
"=", CostFunction(pNtk),
",", statsLocal.GetString());
1367 ApplyReverseTopologically([&](
int id) {
1368 std::vector<int> vCands;
1370 vCands = pNtk->GetNeighbors(
id,
true, nDistance);
1372 vCands = pNtk->GetPisInts();
1375 MultiResub(
id, vCands);
1377 stats[
"multi"] += statsLocal;
1378 Print(0,
"multi ",
":",
"cost",
"=", CostFunction(pNtk),
",", statsLocal.GetString());
1379 double dNewCost = CostFunction(pNtk);
1380 if(dNewCost < dCost) {
1390 std::vector<int> vCands;
1392 vCands = pNtk->GetPisInts();
1393 std::shuffle(vCands.begin(), vCands.end(), rng);
1395 Stats statsSingle, statsMulti;
1396 ApplyRandomlyStop([&](
int id) {
1399 vCands = pNtk->GetNeighbors(
id,
true, nDistance);
1400 std::shuffle(vCands.begin(), vCands.end(), rng);
1404 fChanged = SingleResubStop(
id, vCands);
1405 statsSingle += statsLocal;
1407 fChanged = MultiResubStop(
id, vCands);
1408 statsMulti += statsLocal;
1412 stats[
"single"] += statsSingle;
1413 stats[
"multi"] += statsMulti;
1414 Print(0,
"single",
":", statsSingle.
GetString());
1415 Print(0,
"multi ",
":", statsMulti.
GetString());
1420 ApplyCombinationSampledRandomlyStop(3, 100, [&](std::vector<int>
const &vTargets) {
1421 return MultiTargetResub(vTargets);
1434 template <
typename Ntk,
typename Ana>
1440 template <
typename Ntk,
typename Ana>
1443 for(
auto const &entry: stats) {
1444 v.emplace_back(
"opt " + entry.first +
" tried node", entry.second.nTried);
1445 v.emplace_back(
"opt " + entry.first +
" tried fanin", entry.second.nTriedFis);
1446 v.emplace_back(
"opt " + entry.first +
" added node", entry.second.nAdded);
1447 v.emplace_back(
"opt " + entry.first +
" added fanin", entry.second.nAddedFis);
1448 v.emplace_back(
"opt " + entry.first +
" changed", entry.second.nChanged);
1449 v.emplace_back(
"opt " + entry.first +
" up", entry.second.nUps);
1450 v.emplace_back(
"opt " + entry.first +
" eq", entry.second.nEqs);
1451 v.emplace_back(
"opt " + entry.first +
" dn", entry.second.nDowns);
1454 v.insert(v.end(), v2.begin(), v2.end());
1458 template <
typename Ntk,
typename Ana>
1461 for(
auto const &entry: stats) {
1462 v.emplace_back(
"opt " + entry.first +
" add", entry.second.durationAdd);
1463 v.emplace_back(
"opt " + entry.first +
" reduce", entry.second.durationReduce);
1466 v.insert(v.end(), v2.begin(), v2.end());