1 #ifndef CPPAD_CG_LOOP_INCLUDED 2 #define CPPAD_CG_LOOP_INCLUDED 25 const std::vector<const OperationNode<Base>*> order;
35 std::map<size_t, IndependentOrder<Base>*> arg2Order;
54 using IndexValue = std::pair<size_t, CG<Base> >;
74 std::unique_ptr<CodeHandlerVector<Base, size_t>> varId_;
78 std::unique_ptr<CodeHandlerVector<Base, bool>> varIndexed_;
82 size_t iterationCount_;
90 std::vector<EquationGroup<Base> > eqGroups_;
94 std::map<EquationPattern<Base>*,
size_t> equationOrder_;
99 std::vector<std::set<size_t> > iterationDependents_;
103 std::map<size_t, size_t> dep2Iteration_;
107 size_t nIndependents_;
115 std::map<const OperationNode<Base>*, IndexValue> independentsIndexed_;
119 std::map<const OperationNode<Base>*, IndexValue> independentsNonIndexed_;
123 std::map<const OperationNode<Base>*, IndexValue> independentsTemp_;
127 std::map<size_t, OperationNode<Base>*> clonesTemporary_;
145 std::map<const OperationNode<Base>*, std::vector<IndependentOrder<Base>*> > firstIndep2orders_;
154 std::forward_list<OperationArgumentsIndepOrder<Base>*> arg2IndepOrder_;
162 handlerOrig_(eq.depRef.getCodeHandler()),
163 varId_(handlerOrig_ != nullptr ? new
CodeHandlerVector<Base, size_t>(*handlerOrig_): nullptr),
164 varIndexed_(handlerOrig_ != nullptr ? new
CodeHandlerVector<Base, bool>(*handlerOrig_): nullptr),
172 equations.insert(&eq);
173 eqGroups_[0].equations.insert(&eq);
175 if(varId_ !=
nullptr)
176 varId_->adjustSize();
183 equations.insert(&eq);
184 eqGroups_[0].equations.insert(&eq);
187 inline void setLinkedDependents(
const std::set<std::set<size_t>*>& newLoopRelations) {
188 CPPADCG_ASSERT_UNKNOWN(eqGroups_.size() == 1);
190 eqGroups_[0].linkedDependents.clear();
191 eqGroups_[0].linkedDependents.reserve(newLoopRelations.size());
193 for (std::set<size_t>* it : newLoopRelations)
194 eqGroups_[0].linkedDependents.push_back(*it);
199 eqGroups_[0].addLinkedEquationsByNonIndexed(eq1, eq2);
202 inline size_t getLinkedEquationsByNonIndexedCount()
const {
203 return eqGroups_[0].getLinkedEquationsByNonIndexedCount();
210 return iterationCount_;
213 const std::vector<std::set<size_t> >& getIterationDependents()
const {
214 return iterationDependents_;
223 loopModel_ =
nullptr;
235 CPPADCG_ASSERT_UNKNOWN(iterationCount_ == other.iterationCount_)
241 CPPADCG_ASSERT_UNKNOWN(eqGroups_.size() == 1)
242 CPPADCG_ASSERT_UNKNOWN(other.eqGroups_.size() == 1)
246 g.equations.insert(og.equations.begin(), og.equations.end());
248 CPPADCG_ASSERT_UNKNOWN(equationOrder_.empty())
249 CPPADCG_ASSERT_UNKNOWN(iterationDependents_.empty())
251 g.linkedEquationsByNonIndexed.insert(og.linkedEquationsByNonIndexed.begin(), og.linkedEquationsByNonIndexed.end());
253 g.linkedEquationsByNonIndexed.erase(itNIndexed);
256 for (
size_t e = 0; e < nonIndexedLoopRelations.size(); e++) {
257 g.addLinkedEquationsByNonIndexed(nonIndexedLoopRelations[e].first, nonIndexedLoopRelations[e].second);
263 eqGroups_.insert(eqGroups_.end(), other.eqGroups_.begin(), other.eqGroups_.end());
265 size_t nEq = equations.size();
272 for (
const auto& it : other.equationOrder_) {
273 equationOrder_[it.first] = it.second + nEq;
276 CPPADCG_ASSERT_UNKNOWN(iterationDependents_.size() == other.iterationDependents_.size())
277 for (
size_t iter = 0; iter < iterationDependents_.size(); iter++) {
278 iterationDependents_[iter].insert(other.iterationDependents_[iter].begin(), other.iterationDependents_[iter].end());
284 const std::vector<
CG<Base> >& independents,
288 CPPADCG_ASSERT_UNKNOWN(dep2Iteration_.empty())
289 for (
size_t iter = 0; iter < iterationCount_; iter++) {
290 const std::set<size_t>& deps = iterationDependents_[iter];
292 for (
size_t d : deps) {
293 dep2Iteration_[d] = iter;
297 if(varIndexed_ !=
nullptr) {
298 varIndexed_->adjustSize();
299 varIndexed_->fill(
false);
305 for (
size_t g = 0; g < eqGroups_.size(); g++) {
306 eqGroups_[g].findReferenceIteration();
307 #ifdef CPPADCG_PRINT_DEBUG 308 std::cout <<
"reference iteration=" << eqGroups_[g].refIteration <<
"\n";
309 print(eqGroups_[g].iterationDependents);
310 std::cout << std::endl;
312 typename std::set<EquationPattern<Base>*>::const_iterator iteq;
313 for (iteq = eqGroups_[g].equations.begin(); iteq != eqGroups_[g].equations.end(); ++iteq) {
314 std::cout <<
"eq dependents=";
315 print((*iteq)->dependents);
316 std::cout << std::endl;
322 for (
size_t g = 0; g < eqGroups_.size(); g++) {
325 CPPADCG_ASSERT_UNKNOWN(refItDep.size() == group.
equations.size())
327 for (
size_t dep : refItDep) {
331 for (
size_t dep : refItDep) {
335 std::set<const OperationNode<Base>*> indexedOperations;
337 eq->findIndexedPath(dep, dependents, *varIndexed_, indexedOperations);
338 if (dep == eq->depRefIndex) {
343 CPPADCG_ASSERT_UNKNOWN(itop2a.first !=
nullptr)
344 addOperationArguments2Loop(itop2a.first, itop2a.second);
353 CPPADCG_ASSERT_UNKNOWN(opLoopRef !=
nullptr)
356 addOperationArguments2Loop(opLoopRef, eq->
indexedOpIndep.op2Arguments.at(opEqRef));
368 generateIndependentLoopIndexes();
370 if(varId_ !=
nullptr)
373 createLoopTapeNModel(dependents, independents, dep2Equation, origTemp2Index);
378 if(varId_ !=
nullptr)
385 iterationDependents_.clear();
386 equationOrder_.clear();
392 map<EquationPattern<Base>*, set<size_t> > depsInEq;
395 depsInEq[eq] = eq->dependents;
396 nMaxIt = std::max<size_t>(nMaxIt, eq->dependents.size());
399 iterationDependents_.reserve(nMaxIt + 2 * equations.size());
401 for (
size_t g = 0; g < eqGroups_.size(); g++) {
403 const set<EquationPattern<Base>*>& eqs = group.
equations;
407 relatedEqIterationDeps.reserve(iterationDependents_.size());
411 size_t eqo_size = equationOrder_.size();
412 equationOrder_[eq] = eqo_size;
416 set<size_t> dependents;
418 dependents.insert(eq->dependents.begin(), eq->dependents.end());
421 map<size_t, map<EquationPattern<Base>*, set<size_t> > > nIndexedGroupPos2Eq2deps;
424 map<EquationPattern<Base>*, std::vector<size_t> > freeDependents;
426 freeDependents[eq].assign(eq->dependents.begin(), eq->dependents.end());
429 DependentIndexSorter depSorter(group, freeDependents, dep2Equation);
431 auto itDep = dependents.begin();
433 while (itDep != dependents.end()) {
437 if (iterationDependents_.size() <= i)
438 iterationDependents_.resize(i + 1);
439 set<size_t>& itDepi = iterationDependents_[i];
441 if (relatedEqIterationDeps.size() <= i)
442 relatedEqIterationDeps.resize(i + 1);
443 set<size_t>& ritDepi = relatedEqIterationDeps[i];
448 auto bestDep = depSorter.findBestDependentForIteration(dep, eq);
452 long pos = group.findIndexedLinkedDependent(dep);
455 for (
size_t dep2 : linkedDependents[pos]) {
456 if (dep2 == *itDep) itDep++;
458 ritDepi.insert(dep2);
459 dependents.erase(dep2);
462 std::vector<size_t>& eq2FreeDep = freeDependents[eq2];
463 typename std::vector<size_t>::const_iterator itFreeDep2;
464 itFreeDep2 = std::find(eq2FreeDep.cbegin(), eq2FreeDep.cend(), dep2);
465 CPPADCG_ASSERT_UNKNOWN(itFreeDep2 != eq2FreeDep.cend())
467 eq2FreeDep.erase(itFreeDep2);
473 long posN = group.findNonIndexedLinkedRel(eq);
476 dependents.erase(dep);
477 nIndexedGroupPos2Eq2deps[posN][eq].insert(dep);
482 std::vector<size_t>& eqFreeDep = freeDependents[eq];
483 auto itFreeDep = find(eqFreeDep.begin(), eqFreeDep.end(), dep);
484 CPPADCG_ASSERT_UNKNOWN(itFreeDep != eqFreeDep.end())
486 eqFreeDep.erase(itFreeDep);
497 if (!nIndexedGroupPos2Eq2deps.empty()) {
499 map<EquationPattern<Base>*, set<size_t> > eqIterations;
500 for (
size_t i = 0; i < relatedEqIterationDeps.size(); i++) {
501 const set<size_t>& deps = relatedEqIterationDeps[i];
502 for (
size_t dep : deps) {
503 eqIterations[dep2Equation.at(dep)].insert(i);
507 for (
auto& itPos2Eq2Dep : nIndexedGroupPos2Eq2deps) {
508 size_t posN = itPos2Eq2Dep.first;
510 std::vector<size_t> deps;
511 deps.reserve(itPos2Eq2Dep.second.size());
513 set<size_t> usedIterations;
517 const set<size_t>& iters = eqIterations[itRel];
518 usedIterations.insert(iters.begin(), iters.end());
526 for (
auto& itEq2Dep : itPos2Eq2Dep.second) {
527 if (!itEq2Dep.second.empty()) {
528 deps.push_back(*itEq2Dep.second.begin());
529 itEq2Dep.second.erase(itEq2Dep.second.begin());
539 set<size_t>::const_iterator itIter;
540 for (itIter = usedIterations.begin(); itIter != usedIterations.end();) {
543 if (itIter != usedIterations.end()) {
555 usedIterations.insert(i);
557 if (iterationDependents_.size() <= i)
558 iterationDependents_.resize(i + 1);
559 set<size_t>& itDepi = iterationDependents_[i];
561 if (relatedEqIterationDeps.size() <= i)
562 relatedEqIterationDeps.resize(i + 1);
563 set<size_t>& ritDepi = relatedEqIterationDeps[i];
564 itDepi.insert(deps.begin(), deps.end());
565 ritDepi.insert(deps.begin(), deps.end());
577 iterationCount_ = std::max<size_t>(iterationCount_, iterationDependents_.size());
586 for (
const auto& itf : firstIndep2orders_) {
610 CPPADCG_ASSERT_UNKNOWN(!dep2Iteration_.empty());
613 loopOpIndeIndep.arg2Independents.resize(eqOpIndeIndep.
arg2Independents.size());
621 size_t dep = itDepIndep.first;
622 size_t iter = dep2Iteration_.at(dep);
623 loopOpIndeIndep.arg2Independents[a][iter] = itDepIndep.second;
629 void generateIndependentLoopIndexes() {
630 CPPADCG_ASSERT_UNKNOWN(iterationCount_ > 0);
633 for (
const auto& it : indexedOpIndep.op2Arguments) {
638 op2Arg2IndepOrder_[operation] = arg2orderPos;
640 arg2IndepOrder_.push_front(arg2orderPos);
644 for (
size_t argumentIndex = 0; argumentIndex < aSize; argumentIndex++) {
645 const std::map<size_t, const OperationNode<Base>*>& dep2Indep = opInd.
arg2Independents[argumentIndex];
646 if (dep2Indep.empty())
649 std::vector<const OperationNode<Base>*> order(iterationCount_);
654 CPPADCG_ASSERT_UNKNOWN(dep2Indep.size() > 0 && dep2Indep.size() <= iterationCount_)
655 for (
const auto& itDep2Indep : dep2Indep) {
656 size_t iterationIndex = itDep2Indep.first;
659 order[iterationIndex] = indep;
665 std::vector<IndependentOrder<Base>*>& availableOrders = firstIndep2orders_[order[0]];
668 long a_size = availableOrders.size();
669 for (
long o = 0; o < a_size; o++) {
672 for (
size_t iterationIndex = 0; iterationIndex < iterationCount_; iterationIndex++) {
673 if (orderO->order[iterationIndex] != order[iterationIndex]) {
684 if (match !=
nullptr) {
686 arg2orderPos->arg2Order[argumentIndex] = match;
690 availableOrders.push_back(iOrder);
691 arg2orderPos->arg2Order[argumentIndex] = iOrder;
707 void createLoopTapeNModel(
const std::vector<
CG<Base> >& dependents,
708 const std::vector<
CG<Base> >& independents,
713 CPPADCG_ASSERT_UNKNOWN(independents.size() > 0)
714 CPPADCG_ASSERT_UNKNOWN(independents[0].getCodeHandler() !=
nullptr)
723 CPPADCG_ASSERT_UNKNOWN(equationOrder_.size() == equations.size())
725 std::vector<CGB> deps(equations.size());
727 for (
size_t g = 0; g < eqGroups_.size(); g++) {
731 for (
size_t depIndex : iterationDependents) {
737 if (node !=
nullptr) {
739 aClone = createIndependentClone(
nullptr, 0, *node);
741 aClone = makeGraphClones(*eq, *node);
744 aClone = dependents[depIndex].getValue();
747 size_t i = equationOrder_.at(eq);
748 deps[i] = CGB(aClone);
756 CPPADCG_ASSERT_UNKNOWN(indexedIndep2clone_.size() == independentsIndexed_.size());
758 std::vector<const OperationNode<Base>*> indexedCloneOrder;
759 indexedCloneOrder.reserve(indexedIndep2clone_.size());
762 for (
const auto& it : indexedIndep2clone_) {
763 clone2indexedIndep[it.second] = it.first;
764 indexedCloneOrder.push_back(it.second);
767 struct IndexedIndepSorter indexedSorter(clone2indexedIndep);
768 std::sort(indexedCloneOrder.begin(), indexedCloneOrder.end(), indexedSorter);
771 std::map<size_t, const OperationNode<Base>*> nonIndexedCloneOrder;
776 for (
auto itc = orig2ConstIndepClone_.begin(); itc != orig2ConstIndepClone_.end(); ++itc, s++) {
781 clones2ConstIndep[clone] = orig;
782 nonIndexedCloneOrder[j] = clone;
785 size_t nIndexed = indexedCloneOrder.size();
786 size_t nNonIndexed = nonIndexedCloneOrder.size();
787 size_t nTmpIndexed = independentsTemp_.size();
790 size_t nIndep = independentsIndexed_.size() +
791 independentsNonIndexed_.size() +
792 independentsTemp_.size();
793 std::vector<ADCGB> loopIndeps(nIndep);
795 typename std::map<const OperationNode<Base>*, IndexValue>::const_iterator itt;
796 typename std::map<size_t, const OperationNode<Base>*>::const_iterator origJ2CloneIt;
799 loopIndeps.resize(1);
800 loopIndeps[0] = Base(0);
807 for (
size_t j = 0; j < nIndexed; j++) {
808 const IndexValue& iv = independentsIndexed_.at(indexedCloneOrder[j]);
809 loopIndeps[j] = iv.second;
813 for (origJ2CloneIt = nonIndexedCloneOrder.begin(); origJ2CloneIt != nonIndexedCloneOrder.end(); ++origJ2CloneIt, s++) {
814 const IndexValue& iv = independentsNonIndexed_.at(origJ2CloneIt->second);
815 loopIndeps[nIndexed + s] = iv.second;
819 for (itt = independentsTemp_.begin(); itt != independentsTemp_.end(); ++itt, s++) {
820 const IndexValue& iv = itt->second;
821 loopIndeps[nIndexed + nNonIndexed + s] = iv.second;
828 CppAD::Independent(loopIndeps);
833 std::vector<ADCGB> localIndeps(nIndep);
835 for (
size_t j = 0; j < nIndexed; j++) {
836 const IndexValue& iv = independentsIndexed_.at(indexedCloneOrder[j]);
837 size_t localIndex = iv.first;
838 localIndeps[localIndex] = loopIndeps[j];
842 for (origJ2CloneIt = nonIndexedCloneOrder.begin(); origJ2CloneIt != nonIndexedCloneOrder.end(); ++origJ2CloneIt, s++) {
843 size_t localIndex = independentsNonIndexed_.at(origJ2CloneIt->second).first;
844 localIndeps[localIndex] = loopIndeps[nIndexed + s];
848 for (itt = independentsTemp_.begin(); itt != independentsTemp_.end(); ++itt, s++) {
849 size_t localIndex = itt->second.first;
850 localIndeps[localIndex] = loopIndeps[nIndexed + nNonIndexed + s];
860 const std::map<size_t, CGAbstractAtomicFun<Base>* >& atomicsOrig = origHandler.getAtomicFunctions();
861 std::map<size_t, atomic_base<CGB>* > atomics;
862 atomics.insert(atomicsOrig.begin(), atomicsOrig.end());
863 evaluator1stIt.addAtomicFunctions(atomics);
865 std::vector<ADCGB> newDeps = evaluator1stIt.
evaluate(localIndeps, deps);
867 bool containsAtoms = evaluator1stIt.getNumberOfEvaluatedAtomics() > 0;
869 std::unique_ptr<ADFun<CGB> >funIndexed(
new ADFun<CGB>());
870 funIndexed->Dependent(newDeps);
875 std::vector<std::vector<size_t> > dependentOrigIndexes(equations.size(), std::vector<size_t> (iterationCount_, (std::numeric_limits<size_t>::max)()));
876 for (
size_t it = 0; it < iterationCount_; it++) {
877 const std::set<size_t>& itDeps = iterationDependents_[it];
878 for (
size_t origDep : itDeps) {
880 size_t i = equationOrder_.at(eq);
881 dependentOrigIndexes[i][it] = origDep;
886 std::vector<std::vector<size_t> > indexedIndependents(nIndexed, std::vector<size_t>(iterationCount_));
887 for (
size_t j = 0; j < indexedCloneOrder.size(); j++) {
889 for (
size_t it = 0; it < iterationCount_; it++) {
892 if (indep !=
nullptr) {
895 index = (std::numeric_limits<size_t>::max)();
897 indexedIndependents[j][it] = index;
901 std::vector<size_t> temporaryIndependents(nTmpIndexed);
904 for (itt = independentsTemp_.begin(); itt != independentsTemp_.end(); ++itt, j++) {
912 typename std::map<OperationNode<Base>*,
size_t>::const_iterator itz = origTemp2Index.find(origTmpNode);
913 if (itz == origTemp2Index.end()) {
914 k = origTemp2Index.size();
915 origTemp2Index[origTmpNode] = k;
920 temporaryIndependents[j] = k;
923 std::vector<size_t> nonIndexedIndependents(orig2ConstIndepClone_.size());
925 for (origJ2CloneIt = nonIndexedCloneOrder.begin(); origJ2CloneIt != nonIndexedCloneOrder.end(); ++origJ2CloneIt, s++) {
926 nonIndexedIndependents[s] = origJ2CloneIt->first;
932 dependentOrigIndexes,
934 nonIndexedIndependents,
935 temporaryIndependents);
937 loopModel_->detectIndexPatterns();
945 size_t id = (*varId_)[node];
955 (*varId_)[node] = id;
957 if ((*varIndexed_)[node] || node.
getOperationType() == CGOpCode::ArrayCreation) {
962 const std::vector<Argument<Base> >& args = node.
getArguments();
963 size_t arg_size = args.size();
964 std::vector<Argument<Base> > cloneArgs(arg_size);
966 for (
size_t a = 0; a < arg_size; a++) {
968 if (argOp ==
nullptr) {
970 cloneArgs[a] = *args[a].getParameter();
974 cloneArgs[a] = createIndependentClone(&node, a, *argOp);
976 cloneArgs[a] = makeGraphClones(eq, *argOp);
985 clonesTemporary_[id] = cloneOp;
993 return makeTemporaryVarClone(node);
998 size_t argumentIndex,
1003 if (it != indexedOpIndep.op2Arguments.end()) {
1008 return getIndexedIndependentClone(operation, argumentIndex);
1013 return getNonIndexedIndependentClone(independent);
1018 CPPADCG_ASSERT_UNKNOWN(operation ==
nullptr || operation->
getArguments().size() > argIndex)
1019 CPPADCG_ASSERT_UNKNOWN(operation ==
nullptr || operation->
getArguments()[argIndex].getOperation() !=
nullptr)
1020 CPPADCG_ASSERT_UNKNOWN(operation ==
nullptr || operation->
getArguments()[argIndex].getOperation()->getOperationType() == CGOpCode::Inv)
1025 typename std::map<const IndependentOrder<Base>*,
OperationNode<Base>*>::const_iterator it;
1026 it = indexedIndep2clone_.find(indepOrder);
1027 if (it != indexedIndep2clone_.end()) {
1032 independentsIndexed_[newIndep.getOperationNode()] = IndexValue(nIndependents_, newIndep);
1036 indexedIndep2clone_[indepOrder] = clone;
1045 it = orig2ConstIndepClone_.find(&node);
1046 if (it != orig2ConstIndepClone_.end()) {
1052 independentsNonIndexed_[newIndep.getOperationNode()] = IndexValue(nIndependents_, newIndep);
1056 orig2ConstIndepClone_[&node] = clone;
1069 CPPADCG_ASSERT_UNKNOWN(node.
getOperationType() != CGOpCode::SparseArrayCreation)
1075 temporaryClone2Orig_[cloneOp] = &node;
1076 independentsTemp_[cloneOp] = IndexValue(nIndependents_, newIndep);
1079 size_t id = idCounter_++;
1080 clonesTemporary_[id] = cloneOp;
1081 (*varId_)[node] = id;
1089 class DependentIndexSorter {
1092 const std::map<EquationPattern<Base>*, std::vector<size_t> >& freeDependents;
1093 const std::map<size_t, EquationPattern<Base>*>& dep2Equation;
1094 std::set<EquationPattern<Base>*> visitedEq;
1113 inline std::pair<size_t, EquationPattern<Base>*> findBestDependentForIteration(
size_t dep,
EquationPattern<Base>* eq) {
1115 return findBestDependent(dep, eq);
1122 const std::vector<size_t>& eqFreeDep = freeDependents.at(eq);
1123 for (
size_t depRelPos = 0; depRelPos < eqFreeDep.size(); depRelPos++) {
1124 if (eqFreeDep[depRelPos] == dep)
1129 return eqFreeDep.size();
1139 inline std::pair<size_t, EquationPattern<Base>*> findBestDependent(
size_t dep,
EquationPattern<Base>* eq) {
1140 visitedEq.insert(eq);
1142 auto best = std::make_pair(dep, eq);
1145 long pos = group.findIndexedLinkedDependent(dep);
1147 size_t depRelPos = findRelativeFreeDependentInEq(eq, dep);
1153 if (visitedEq.find(eq2) != visitedEq.end())
continue;
1155 size_t dep2RelPos = findRelativeFreeDependentInEq(eq2, dep2);
1156 if (dep2RelPos > depRelPos) {
1159 best = std::make_pair(dep2, eq2);
1160 depRelPos = dep2RelPos;
1164 if (best.first != dep) {
1165 size_t bestDep = *freeDependents.at(best.second).begin();
1166 return findBestDependent(bestDep, best.second);
1179 struct IndexedIndepSorter {
1183 clone2indexedIndep(clone2indexedIndep_) {
1190 CPPADCG_ASSERT_UNKNOWN(indepOrder1->order.size() == indepOrder2->order.size())
1192 size_t size = indepOrder1->order.size();
1193 for (
size_t j = 0; j < size; j++) {
1197 if (indep1 ==
nullptr) {
1198 if (indep2 ==
nullptr) {
1202 }
else if (indep2 ==
nullptr) {
1206 size_t index1 = indep1->
getInfo()[0];
1207 size_t index2 = indep2->
getInfo()[0];
1208 if (index1 < index2)
1210 else if (index1 > index2)
1214 CPPADCG_ASSERT_UNKNOWN(
false)
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)
void mergeEqGroups(Loop< Base > &other)
const std::vector< Argument< Base > > & getArguments() const
size_t getIterationCount() const
std::vector< MapDep2Indep_type > arg2Independents
std::vector< std::set< size_t > > linkedDependents
std::vector< std::set< size_t > > iterationDependents
IndexedIndependent< Base > indexedOpIndep
IndexedIndependent< Base > indexedOpIndep
CGOpCode getOperationType() const
void generateDependentLoopIndexes(const std::map< size_t, EquationPattern< Base > *> &dep2Equation)
void makeVariable(AD< CGB > &variable)
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)
std::vector< std::set< EquationPattern< Base > * > > linkedEquationsByNonIndexedRel
std::set< EquationPattern< Base > * > equations
const std::vector< size_t > & getInfo() const