1 #ifndef CPPAD_CG_DEPENDENT_PATTERN_MATCHER_INCLUDED 2 #define CPPAD_CG_DEPENDENT_PATTERN_MATCHER_INCLUDED 31 if (e1->depRefIndex < e2->depRefIndex) {
43 return p1.eq1->depRefIndex < p2.eq1->depRefIndex || (!(p2.eq1->depRefIndex < p1.eq1->depRefIndex) && p1.eq2->depRefIndex < p2.eq2->depRefIndex);
55 enum class INDEXED_OPERATION_TYPE {
60 using Indexed2OpCountType = std::pair<INDEXED_OPERATION_TYPE, size_t>;
61 using Dep1Dep2SharedType = std::map<size_t, std::map<size_t, std::map<OperationNode<Base>*, Indexed2OpCountType> > >;
62 using DepPairType = std::pair<size_t, size_t>;
63 using TotalOps2validDepsType = std::map<size_t, std::map<DepPairType, const std::map<OperationNode<Base>*, Indexed2OpCountType>* > >;
64 using Eq2totalOps2validDepsType = std::map<UniqueEquationPair<Base>, TotalOps2validDepsType*>;
65 using MaxOps2eq2totalOps2validDepsType = std::map<size_t, Eq2totalOps2validDepsType>;
71 const std::vector<std::set<size_t> >& relatedDepCandidates_;
72 std::vector<CGBase> dependents_;
73 const std::vector<CGBase>& independents_;
74 std::vector<EquationPattern<Base>*> equations_;
76 std::map<size_t, EquationPattern<Base>*> dep2Equation_;
77 std::map<EquationPattern<Base>*,
Loop<Base>*> equation2Loop_;
78 std::vector<Loop<Base>*> loops_;
82 std::map<EquationPattern<Base>*, std::set<EquationPattern<Base>*> > incompatible_;
86 std::map<UniqueEquationPair<Base>, Dep1Dep2SharedType> equationShared_;
91 std::map<OperationNode<Base>*,
size_t> origTemp2Index_;
92 std::vector<std::set<size_t> > id2Deps;
113 const std::vector<CGBase>& dependents,
114 const std::vector<CGBase>& independents) :
115 handler_(independents[0].getCodeHandler()),
117 varIndexed_(*handler_),
118 relatedDepCandidates_(relatedDepCandidates),
119 dependents_(dependents),
120 independents_(independents),
122 origShareNodeId_(*handler_),
124 CPPADCG_ASSERT_UNKNOWN(independents_.size() > 0);
125 CPPADCG_ASSERT_UNKNOWN(independents_[0].getCodeHandler() !=
nullptr);
126 equations_.reserve(relatedDepCandidates_.size());
127 origShareNodeId_.adjustSize();
130 const std::vector<EquationPattern<Base>*>& getEquationPatterns()
const {
134 const std::vector<Loop<Base>*>& getLoops()
const {
150 for (
size_t j = 0; j < independents_.size(); j++) {
151 std::vector<size_t>& info = independents_[j].getOperationNode()->getInfo();
158 nonLoopTape = createNewTape();
161 for (
size_t l = 0; l < loops_.size(); l++) {
163 loopTapes.insert(loop->releaseLoopModel());
168 for (
size_t l = 0; l < loops_.size(); l++) {
181 virtual std::vector<Loop<Base>*> findLoops() {
184 size_t rSize = relatedDepCandidates_.size();
185 for (
size_t r = 0; r < rSize; r++) {
186 const std::set<size_t>& candidates = relatedDepCandidates_[r];
187 for (
size_t iDep : candidates) {
198 CPPADCG_ASSERT_UNKNOWN(handler_ == dependents_[iDep].getCodeHandler());
199 dependents_[iDep] =
CG<Base>(*handler_->makeNode(CGOpCode::Alias, *node));
209 id2Deps.resize(idCounter_ + 1);
214 findRelatedVariables();
217 for (
size_t depIt : eq->dependents) {
218 dep2Equation_[depIt] = eq;
222 const size_t eq_size = equations_.size();
223 loops_.reserve(eq_size);
226 std::vector<set<size_t>*> dep2Relations(dependents_.size(),
nullptr);
227 map<size_t, set<size_t> > dependentBlackListRelations;
236 varIndexed_.adjustSize();
237 varIndexed_.fill(
false);
239 for (
size_t e = 0; e < eq_size; e++) {
243 for (
size_t depIt : eq->dependents) {
246 markOperationsWithDependent(node, depIt);
253 handler_->startNewOperationTreeVisit();
255 for (
size_t depIt : eq->dependents) {
256 findSharedTemporaries(dependents_[depIt], depIt);
262 for (
size_t depIt : eq->dependents) {
270 loops_.push_back(loop);
271 equation2Loop_[eq] = loop;
277 MaxOps2eq2totalOps2validDepsType maxOps2Eq2totalOps2validDeps;
278 Eq2totalOps2validDepsType eq2totalOps2validDeps;
286 for (
size_t l1 = 0; l1 < loops_.size(); l1++) {
288 CPPADCG_ASSERT_UNKNOWN(loop1->
equations.size() == 1);
291 for (
size_t l2 = l1 + 1; l2 < loops_.size(); l2++) {
293 CPPADCG_ASSERT_UNKNOWN(loop2->
equations.size() == 1);
297 const auto eqSharedit = equationShared_.find(eqRel);
298 if (eqSharedit == equationShared_.end())
301 const Dep1Dep2SharedType& dep1Dep2Shared = eqSharedit->second;
306 TotalOps2validDepsType* totalOps2validDeps =
new TotalOps2validDepsType();
307 totalOps2validDepsMem.push_back(totalOps2validDeps);
310 bool canCombine =
true;
315 for (
const auto& itDep1Dep2 : dep1Dep2Shared) {
316 size_t dep1 = itDep1Dep2.first;
317 const map<size_t, map<OperationNode<Base>*, Indexed2OpCountType> >& dep2Shared = itDep1Dep2.second;
320 for (
const auto& itDep2 : dep2Shared) {
321 size_t dep2 = itDep2.first;
322 const map<OperationNode<Base>*, Indexed2OpCountType>& sharedTmps = itDep2.second;
325 for (
const auto& itShared : sharedTmps) {
326 if (itShared.second.first == INDEXED_OPERATION_TYPE::BOTH) {
335 totalOps += itShared.second.second;
339 if (!canCombine)
break;
341 DepPairType depRel(dep1, dep2);
342 (*totalOps2validDeps)[totalOps][depRel] = &sharedTmps;
343 maxOps = std::max(maxOps, totalOps);
346 if (!canCombine)
break;
350 maxOps2Eq2totalOps2validDeps[maxOps][eqRel] = totalOps2validDeps;
351 eq2totalOps2validDeps[eqRel] = totalOps2validDeps;
353 incompatible_[eq1].insert(eq2);
354 incompatible_[eq2].insert(eq1);
355 totalOps2validDepsMem.pop_back();
356 delete totalOps2validDeps;
364 typename MaxOps2eq2totalOps2validDepsType::const_reverse_iterator itMaxOps;
365 for (itMaxOps = maxOps2Eq2totalOps2validDeps.rbegin(); itMaxOps != maxOps2Eq2totalOps2validDeps.rend(); ++itMaxOps) {
366 #ifdef CPPADCG_PRINT_DEBUG 367 std::cout <<
"\n\nmaxOps: " << itMaxOps->first <<
" count:" << itMaxOps->second.size() << std::endl;
370 for (
const auto& itEqPair : itMaxOps->second) {
372 #ifdef CPPADCG_PRINT_DEBUG 373 std::cout <<
" eq1: " << *eqRel.eq1->dependents.begin() <<
" eq2: " << *eqRel.eq2->dependents.begin() << std::endl;
376 Loop<Base>* loop1 = equation2Loop_.at(eqRel.eq1);
377 Loop<Base>* loop2 = equation2Loop_.at(eqRel.eq2);
381 if (contains(incompatible_, eqRel.eq1, eqRel.eq2))
389 for (
const set<size_t>* its : dependentRelations) {
390 dependentRelationsBak.insert(
new set<size_t>(*its));
394 set<set<size_t>*> loopRelations;
396 set<EquationPattern<Base>*> indexedLoopRelations;
402 bool compatible = isCompatible(loop1, loop2,
403 eq2totalOps2validDeps,
404 dep2Relations, dependentBlackListRelations, dependentRelations,
405 loopRelations, indexedLoopRelations, nonIndexedLoopRelations);
412 equation2Loop_[itle] = loop1;
414 loop1->
merge(*loop2, indexedLoopRelations, nonIndexedLoopRelations);
416 typename std::vector<Loop<Base>*>::const_iterator it = std::find(loops_.cbegin(), loops_.cend(), loop2);
417 CPPADCG_ASSERT_UNKNOWN(it != loops_.end());
421 loop1->setLinkedDependents(loopRelations);
426 dependentRelations.s.swap(dependentRelationsBak.s);
428 std::fill(dep2Relations.begin(), dep2Relations.end(),
nullptr);
429 for (set<size_t>* relation : dependentRelations) {
430 for (
size_t itd : *relation) {
431 dep2Relations[itd] = relation;
443 for (
size_t l = 0; l < loops_.size(); l++) {
444 loops_[l]->generateDependentLoopIndexes(dep2Equation_);
450 if (!loops_.empty()) {
451 for (
size_t l1 = 0; l1 < loops_.size() - 1; l1++) {
453 for (
size_t l2 = l1 + 1; l2 < loops_.size();) {
459 canMerge = !find(loop1, loop2, incompatible_);
464 loops_.erase(loops_.begin() + l2);
473 size_t l_size = loops_.size();
478 for (
size_t l = 0; l < l_size; l++) {
482 loop->
createLoopModel(dependents_, independents_, dep2Equation_, origTemp2Index_);
488 resetHandlerCounters();
503 const Eq2totalOps2validDepsType& eq2totalOps2validDeps,
504 std::vector<std::set<size_t>* >& dep2Relations,
505 std::map<
size_t, std::set<size_t> >& dependentBlackListRelations,
507 std::set<std::set<size_t>*>& loopRelations,
512 bool compatible =
true;
518 map<size_t, map<UniqueEquationPair<Base>, TotalOps2validDepsType*> > totalOp2eq;
526 typename Eq2totalOps2validDepsType::const_iterator eqSharedit = eq2totalOps2validDeps.find(eqRel);
527 if (eqSharedit == eq2totalOps2validDeps.end())
531 size_t maxOps = eqSharedit->second->rbegin()->first;
532 totalOp2eq[maxOps][eqRel] = eqSharedit->second;
536 typename map<size_t, map<UniqueEquationPair<Base>, TotalOps2validDepsType*> >::const_reverse_iterator itr;
537 for (itr = totalOp2eq.rbegin(); itr != totalOp2eq.rend(); ++itr) {
540 for (
const auto& itEq : itr->second) {
543 TotalOps2validDepsType& totalOps2validDeps = *itEq.second;
549 typename map<size_t, map<DepPairType, const map<OperationNode<Base>*, Indexed2OpCountType>* > >::const_reverse_iterator itOp2Dep2Shared;
550 for (itOp2Dep2Shared = totalOps2validDeps.rbegin(); itOp2Dep2Shared != totalOps2validDeps.rend(); ++itOp2Dep2Shared) {
551 #ifdef CPPADCG_PRINT_DEBUG 552 std::cout <<
" operation count: " << itOp2Dep2Shared->first <<
" relations: " << itOp2Dep2Shared->second.size() << std::endl;
554 for (
const auto& itDep2Shared : itOp2Dep2Shared->second) {
555 DepPairType depRel = itDep2Shared.first;
556 size_t dep1 = depRel.first;
557 size_t dep2 = depRel.second;
559 const map<OperationNode<Base>*, Indexed2OpCountType>& shared = *itDep2Shared.second;
564 compatible = findDepRelations(eq1, dep1, eq2, dep2, shared,
565 dep2Relations, dependentBlackListRelations, dependentRelations);
566 if (!compatible)
break;
569 loopRelations.clear();
575 std::vector<Loop<Base>*> loops(2);
578 bool nonIndexedOnly =
true;
579 for (
size_t l = 0; l < 2; l++) {
582 for (
size_t dep : eq->dependents) {
583 if (dep2Relations[dep] !=
nullptr) {
584 loopRelations.insert(dep2Relations[dep]);
585 nonIndexedOnly =
false;
593 if (nonIndexedOnly) {
594 nonIndexedLoopRelations.push_back(std::make_pair(eq1, eq2));
598 size_t nNonIndexedRel1 = loop1->getLinkedEquationsByNonIndexedCount();
599 size_t nNonIndexedRel2 = loop2->getLinkedEquationsByNonIndexedCount();
600 size_t requiredSize = loop1->
equations.size() + loop2->
equations.size() - nNonIndexedRel1 - nNonIndexedRel2;
602 for (set<size_t>* relations : loopRelations) {
603 if (relations->size() == requiredSize) {
608 #ifdef CPPADCG_PRINT_DEBUG 610 std::cout <<
" loopRelations:";
611 print(loopRelations);
612 std::cout << std::endl;
618 if (!compatible)
break;
622 incompatible_[eq1].insert(eq2);
623 incompatible_[eq2].insert(eq1);
626 indexedLoopRelations.insert(eq1);
627 indexedLoopRelations.insert(eq2);
631 if (!compatible)
break;
650 std::vector<std::set<size_t>* >& dep2Relations,
651 std::map<
size_t, std::set<size_t> >& dependentBlackListRelations,
655 for (
const auto& itShared : sharedNodes) {
659 bool compatible = canCombineEquations(*eq1, dep1, *eq2, dep2, *sharedNode,
660 dep2Relations, dependentBlackListRelations, dependentRelations);
662 if (!compatible)
return false;
675 const set<size_t>& deps = id2Deps[varId_[*shared]];
677 for (
size_t dep : deps) {
680 Loop<Base>* loop = equation2Loop_.at(otherEq);
683 loopSharedTemps[loop][otherEq][origShareNodeId_[shared]] = std::make_pair(shared, indexed);
697 CPPADCG_ASSERT_UNKNOWN(handler_ == independents_[0].getCodeHandler());
699 size_t m = dependents_.size();
700 std::vector<bool> inLoop(m,
false);
701 size_t eqInLoopCount = 0;
706 size_t l_size = loops_.size();
708 for (
size_t l = 0; l < l_size; l++) {
716 for (
size_t eq = 0; eq < ldeps.size(); eq++) {
717 for (
size_t it = 0; it < ldeps[eq].size(); it++) {
719 if (pos.original != std::numeric_limits<size_t>::max()) {
720 inLoop[pos.original] =
true;
730 assert(m >= eqInLoopCount);
731 size_t nonLoopEq = m - eqInLoopCount;
732 std::vector<CGBase> nonLoopDeps(nonLoopEq + origTemp2Index_.size());
734 if (nonLoopDeps.size() == 0)
741 std::vector<size_t> depTape2Orig(nonLoopEq);
742 if (eqInLoopCount < m) {
743 for (
size_t i = 0; i < inLoop.size(); i++) {
745 depTape2Orig[inl] = i;
746 nonLoopDeps[inl++] = dependents_[i];
750 CPPADCG_ASSERT_UNKNOWN(inl == nonLoopEq);
755 for (
const auto& itTmp : origTemp2Index_) {
756 size_t k = itTmp.second;
757 nonLoopDeps[nonLoopEq + k] = handler_->createCG(
Argument<Base>(*itTmp.first));
766 const std::map<size_t, CGAbstractAtomicFun<Base>* >& atomicsOrig = handler_->
getAtomicFunctions();
767 std::map<size_t, atomic_base<CGBase>* > atomics;
768 atomics.insert(atomicsOrig.begin(), atomicsOrig.end());
769 evaluator.addAtomicFunctions(atomics);
771 std::vector<AD<CGBase> > x(independents_.size());
772 for (
size_t j = 0; j < x.size(); j++) {
773 if (independents_[j].isValueDefined())
774 x[j] = independents_[j].getValue();
777 CppAD::Independent(x);
778 std::vector<AD<CGBase> > y = evaluator.
evaluate(x, nonLoopDeps);
780 std::unique_ptr<ADFun<CGBase> > tapeNoLoops(
new ADFun<CGBase>());
781 tapeNoLoops->Dependent(y);
786 std::vector<EquationPattern<Base>*> findRelatedVariables() {
791 varColor.adjustSize();
794 size_t rSize = relatedDepCandidates_.size();
795 for (
size_t r = 0; r < rSize; r++) {
796 const std::set<size_t>& candidates = relatedDepCandidates_[r];
797 std::set<size_t> used;
801 std::set<size_t>::const_iterator itRef;
802 for (itRef = candidates.begin(); itRef != candidates.end(); ++itRef) {
803 size_t iDepRef = *itRef;
806 if (used.find(iDepRef) != used.end()) {
810 if (eqCurr_ ==
nullptr || used.size() > 0) {
812 equations_.push_back(eqCurr_);
815 std::set<size_t>::const_iterator it = itRef;
816 for (++it; it != candidates.end(); ++it) {
819 if (used.find(iDep) != used.end()) {
823 if (eqCurr_->testAdd(iDep, dependents_[iDep], color_, varColor)) {
828 if (eqCurr_->dependents.size() == 1) {
832 equations_.pop_back();
841 for (
size_t eq = 0; eq < equations_.size(); eq++) {
842 equations_[eq]->detectNonIndexedIndependents();
855 inline bool findSharedTemporaries(
const CG<Base>& value,
859 if (findSharedTemporaries(depNode, depIndex, opCount)) {
860 varIndexed_[*depNode] =
true;
881 if (handler_->isVisited(*node)) {
883 return varIndexed_[*node];
886 handler_->markVisited(*node);
888 bool indexedOperation =
false;
890 size_t localOpCount = 1;
891 const std::vector<Argument<Base> >& args = node->
getArguments();
892 size_t arg_size = args.size();
893 for (
size_t a = 0; a < arg_size; a++) {
895 if (argOp !=
nullptr) {
897 indexedOperation |= findSharedTemporaries(argOp, depIndex, localOpCount);
899 indexedOperation |= !eqCurr_->containsConstantIndependent(node, a);
904 opCount += localOpCount;
906 varIndexed_[*node] = indexedOperation;
908 size_t id = varId_[*node];
909 std::set<size_t>& deps = id2Deps[id];
915 for (
size_t otherDep : deps) {
918 if (otherEquation != eqCurr_) {
923 Dep1Dep2SharedType& relation = equationShared_[eqPair];
925 std::map<OperationNode<Base>*, Indexed2OpCountType>* reldepdep;
926 if (eqPair.eq1 == eqCurr_)
927 reldepdep = &relation[depIndex][otherDep];
929 reldepdep = &relation[otherDep][depIndex];
931 INDEXED_OPERATION_TYPE expected = indexedOperation ? INDEXED_OPERATION_TYPE::INDEXED : INDEXED_OPERATION_TYPE::NONINDEXED;
932 typename std::map<OperationNode<Base>*, Indexed2OpCountType>::iterator itIndexedType = reldepdep->find(node);
933 if (itIndexedType == reldepdep->end()) {
934 (*reldepdep)[node] = Indexed2OpCountType(expected, localOpCount);
935 }
else if (itIndexedType->second.first != expected) {
936 itIndexedType->second.first = INDEXED_OPERATION_TYPE::BOTH;
944 return indexedOperation;
959 size_t id = varId_[*node];
961 std::set<size_t>& deps = id2Deps[id];
963 if (deps.size() == 0) {
966 std::pair < std::set<size_t>::iterator,
bool> added = deps.insert(dep);
972 const std::vector<Argument<Base> >& args = node->
getArguments();
973 size_t arg_size = args.size();
974 for (
size_t i = 0; i < arg_size; i++) {
975 markOperationsWithDependent(args[i].getOperation(), dep);
982 size_t rSize = relatedDepCandidates_.size();
983 for (
size_t r = 0; r < rSize; r++) {
984 const std::set<size_t>& candidates = relatedDepCandidates_[r];
986 for (
size_t it : candidates) {
987 assignIds(dependents_[it].getOperationNode());
993 if (node ==
nullptr || varId_[*node] > 0)
996 varId_[*node] = idCounter_;
997 origShareNodeId_.adjustSize(*node);
998 origShareNodeId_[*node] = idCounter_;
1001 const std::vector<Argument<Base> >& args = node->
getArguments();
1002 size_t arg_size = args.size();
1003 for (
size_t i = 0; i < arg_size; i++) {
1004 assignIds(args[i].getOperation());
1008 void resetHandlerCounters() {
1009 size_t rSize = relatedDepCandidates_.size();
1010 for (
size_t r = 0; r < rSize; r++) {
1011 const std::set<size_t>& candidates = relatedDepCandidates_[r];
1013 for (
size_t it : candidates) {
1014 resetHandlerCounters(dependents_[it].getOperationNode());
1020 if (node ==
nullptr || varId_[*node] == 0 || origShareNodeId_[*node] == 0)
1024 origShareNodeId_[*node] = 0;
1026 const std::vector<Argument<Base> >& args = node->
getArguments();
1027 size_t arg_size = args.size();
1028 for (
size_t i = 0; i < arg_size; i++) {
1029 resetHandlerCounters(args[i].getOperation());
1037 const auto itBlack = blackList.find(iteq1);
1038 if (itBlack != blackList.end()) {
1041 if (itBlack->second.find(iteq2) != itBlack->second.end()) {
1052 static inline bool contains(
const std::map<T, std::set<T> >& map, T eq1, T eq2) {
1053 typename std::map<T, std::set<T> >::const_iterator itb1;
1054 itb1 = map.find(eq1);
1055 if (itb1 != map.end()) {
1056 if (itb1->second.find(eq2) != itb1->second.end()) {
1068 std::vector<std::set<size_t>* >& dep2Relations,
1069 std::map<
size_t, std::set<size_t> >& dependentBlackListRelations,
1071 using namespace std;
1074 const set<const OperationNode<Base>*> opWithIndepArgs = eq1.findOperationsUsingIndependents(sharedTemp);
1112 for (
size_t a = 0; a < a1Size; a++) {
1113 const map<size_t, const OperationNode<Base>*>& eq1Dep2Indep = indexed1Ops.
arg2Independents[a];
1114 const map<size_t, const OperationNode<Base>*>& eq2Dep2Indep = indexed2Ops.
arg2Independents[a];
1116 if (eq1Dep2Indep.empty() != eq2Dep2Indep.empty())
1121 if (eq1Dep2Indep.empty()) {
1129 MapIndep2Dep eq1Indep2Dep;
1130 typename MapIndep2Dep::iterator hint = eq1Indep2Dep.begin();
1131 for (
const auto& d2i : eq1Dep2Indep) {
1132 hint = eq1Indep2Dep.insert(hint, std::make_pair(d2i.second, d2i.first));
1136 typename map<const OperationNode<Base>*,
size_t>::const_iterator itHint = eq1Indep2Dep.begin();
1139 for (
const auto& d2i : eq2Dep2Indep) {
1140 size_t dep2 = d2i.first;
1142 typename map<const OperationNode<Base>*,
size_t>::const_iterator it;
1143 if (itHint->first == indep) {
1152 it = eq1Indep2Dep.find(indep);
1155 if (it != eq1Indep2Dep.end()) {
1156 size_t dep1 = it->second;
1159 std::map<size_t, set<size_t> >::const_iterator itBlackL = dependentBlackListRelations.find(dep1);
1160 if (itBlackL != dependentBlackListRelations.end() && itBlackL->second.find(dep2) != itBlackL->second.end()) {
1164 bool related = makeDependentRelation(eq1, dep1, eq2, dep2,
1165 dep2Relations, dependentRelations);
1174 dependentBlackListRelations[dep2].insert(eq1.dependents.begin(), eq1.dependents.end());
1190 using namespace std;
1201 const auto indexed2It = eq2.
indexedOpIndep.op2Arguments.find(op2);
1214 std::vector<std::set<size_t>* >& dep2Relations,
1216 using namespace std;
1218 set<size_t>* related1 = dep2Relations[dep1];
1219 set<size_t>* related2 = dep2Relations[dep2];
1222 if (related1 !=
nullptr) {
1225 if (related2 !=
nullptr) {
1228 if (related1 == related2)
1233 bool canMerge =
true;
1235 for (
size_t dep3 : *related2) {
1239 for (
size_t it : eq3.dependents) {
1240 if (it != dep3 && related1->find(it) != related1->end()) {
1252 for (
size_t dep3 : *related2) {
1253 related1->insert(dep3);
1254 dep2Relations[dep3] = related1;
1257 dependentRelations.erase(related2);
1269 if (related1->find(dep2) == related1->end()) {
1271 bool canMerge =
true;
1272 for (
size_t it : eq2.dependents) {
1273 if (it != dep2 && related1->find(it) != related1->end()) {
1280 related1->insert(dep2);
1281 dep2Relations[dep2] = related1;
1293 }
else if (related2 !=
nullptr) {
1297 bool canMerge =
true;
1298 for (
size_t it : eq1.dependents) {
1299 if (it != dep1 && related2->find(it) != related2->end()) {
1307 related2->insert(dep1);
1308 dep2Relations[dep1] = related2;
1321 set<size_t>* related =
new std::set<size_t>();
1322 dependentRelations.insert(related);
1323 related->insert(dep1);
1324 related->insert(dep2);
1325 dep2Relations[dep1] = related;
1326 dep2Relations[dep2] = related;
virtual void generateTapes(LoopFreeModel< Base > *&nonLoopTape, std::set< LoopModel< Base > *> &loopTapes)
std::vector< ActiveOut > evaluate(ArrayView< const ActiveOut > indepNew, ArrayView< const CG< ScalarIn > > depOld)
std::set< EquationPattern< Base > * > equations
std::map< size_t, std::map< const OperationNode< Base > *, OperationNode< Base > * > > operationEO2Reference
void merge(Loop< Base > &other, const std::set< EquationPattern< Base > *> &indexedLoopRelations, const std::vector< std::pair< EquationPattern< Base > *, EquationPattern< Base > *> > &nonIndexedLoopRelations)
DependentPatternMatcher(const std::vector< std::set< size_t > > &relatedDepCandidates, const std::vector< CGBase > &dependents, const std::vector< CGBase > &independents)
void mergeEqGroups(Loop< Base > &other)
const std::vector< Argument< Base > > & getArguments() const
size_t getIterationCount() const
std::vector< MapDep2Indep_type > arg2Independents
IndexedIndependent< Base > indexedOpIndep
CGOpCode getOperationType() const
const std::map< size_t, CGAbstractAtomicFun< Base > *> & getAtomicFunctions() const
void createLoopModel(const std::vector< CG< Base > > &dependents, const std::vector< CG< Base > > &independents, const std::map< size_t, EquationPattern< Base > *> &dep2Equation, std::map< OperationNode< Base > *, size_t > &origTemp2Index)
const std::vector< std::vector< LoopPosition > > & getDependentIndexes() const