56 enum class INDEXED_OPERATION_TYPE {
61 using Indexed2OpCountType = std::pair<INDEXED_OPERATION_TYPE, size_t>;
62 using Dep1Dep2SharedType = std::map<size_t, std::map<size_t, std::map<OperationNode<Base>*, Indexed2OpCountType> > >;
63 using DepPairType = std::pair<size_t, size_t>;
64 using TotalOps2validDepsType = std::map<size_t, std::map<DepPairType, const std::map<OperationNode<Base>*, Indexed2OpCountType>* > >;
65 using Eq2totalOps2validDepsType = std::map<UniqueEquationPair<Base>, TotalOps2validDepsType*>;
66 using MaxOps2eq2totalOps2validDepsType = std::map<size_t, Eq2totalOps2validDepsType>;
72 const std::vector<std::set<size_t> >& relatedDepCandidates_;
73 std::vector<CGBase> dependents_;
74 const std::vector<CGBase>& independents_;
75 std::vector<EquationPattern<Base>*> equations_;
77 std::map<size_t, EquationPattern<Base>*> dep2Equation_;
78 std::map<EquationPattern<Base>*,
Loop<Base>*> equation2Loop_;
79 std::vector<Loop<Base>*> loops_;
83 std::map<EquationPattern<Base>*, std::set<EquationPattern<Base>*> > incompatible_;
87 std::map<UniqueEquationPair<Base>, Dep1Dep2SharedType> equationShared_;
92 std::map<OperationNode<Base>*,
size_t> origTemp2Index_;
93 std::vector<std::set<size_t> > id2Deps;
114 const std::vector<CGBase>& dependents,
118 varIndexed_(*handler_),
120 dependents_(dependents),
123 origShareNodeId_(*handler_),
125 CPPADCG_ASSERT_UNKNOWN(independents_.size() > 0)
126 CPPADCG_ASSERT_UNKNOWN(independents_[0].getCodeHandler() !=
nullptr)
127 equations_.reserve(relatedDepCandidates_.size());
128 origShareNodeId_.adjustSize();
131 const std::vector<EquationPattern<Base>*>& getEquationPatterns()
const {
135 const std::vector<Loop<Base>*>& getLoops()
const {
151 for (
size_t j = 0;
j < independents_.size();
j++) {
152 std::vector<size_t>&
info = independents_[
j].getOperationNode()->getInfo();
162 for (
size_t l = 0; l < loops_.size(); l++) {
169 for (
size_t l = 0; l < loops_.size(); l++) {
182 virtual std::vector<Loop<Base>*> findLoops() {
185 size_t rSize = relatedDepCandidates_.size();
186 for (
size_t r = 0;
r <
rSize;
r++) {
187 const std::set<size_t>&
candidates = relatedDepCandidates_[
r];
190 if (node !=
nullptr && node->getOperationType() == CGOpCode::Inv) {
199 CPPADCG_ASSERT_UNKNOWN(handler_ == dependents_[
iDep].getCodeHandler())
200 dependents_[
iDep] = CG<Base>(*handler_->makeNode(CGOpCode::Alias, *node));
210 id2Deps.
resize(idCounter_ + 1);
215 findRelatedVariables();
217 for (EquationPattern<Base>*
eq : equations_) {
218 for (
size_t depIt :
eq->dependents) {
223 const size_t eq_size = equations_.size();
227 std::vector<set<size_t>*>
dep2Relations(dependents_.size(),
nullptr);
237 varIndexed_.adjustSize();
238 varIndexed_.fill(
false);
244 for (
size_t depIt :
eq->dependents) {
247 markOperationsWithDependent(node,
depIt);
254 handler_->startNewOperationTreeVisit();
256 for (
size_t depIt :
eq->dependents) {
257 findSharedTemporaries(dependents_[
depIt],
depIt);
263 for (
size_t depIt :
eq->dependents) {
265 EquationPattern<Base>::uncolor(node, varIndexed_);
270 auto*
loop =
new Loop<Base>(*
eq);
271 loops_.push_back(
loop);
272 equation2Loop_[
eq] =
loop;
287 for (
size_t l1 = 0;
l1 < loops_.size();
l1++) {
288 Loop<Base>*
loop1 = loops_[
l1];
289 CPPADCG_ASSERT_UNKNOWN(
loop1->equations.size() == 1)
290 EquationPattern<Base>* eq1 = *
loop1->equations.begin();
292 for (
size_t l2 =
l1 + 1;
l2 < loops_.size();
l2++) {
293 Loop<Base>*
loop2 = loops_[
l2];
294 CPPADCG_ASSERT_UNKNOWN(
loop2->equations.size() == 1)
295 EquationPattern<Base>* eq2 = *
loop2->equations.begin();
297 UniqueEquationPair<Base>
eqRel(eq1, eq2);
318 const map<size_t, map<OperationNode<Base>*, Indexed2OpCountType> >&
dep2Shared =
itDep1Dep2.second;
323 const map<OperationNode<Base>*, Indexed2OpCountType>&
sharedTmps =
itDep2.second;
327 if (
itShared.second.first == INDEXED_OPERATION_TYPE::BOTH) {
354 incompatible_[eq1].insert(eq2);
355 incompatible_[eq2].insert(eq1);
365 typename MaxOps2eq2totalOps2validDepsType::const_reverse_iterator
itMaxOps;
367#ifdef CPPADCG_PRINT_DEBUG
368 std::cout <<
"\n\nmaxOps: " <<
itMaxOps->first <<
" count:" <<
itMaxOps->second.size() << std::endl;
373#ifdef CPPADCG_PRINT_DEBUG
374 std::cout <<
" eq1: " << *
eqRel.eq1->dependents.begin() <<
" eq2: " << *
eqRel.eq2->dependents.begin() << std::endl;
377 Loop<Base>*
loop1 = equation2Loop_.at(
eqRel.eq1);
378 Loop<Base>*
loop2 = equation2Loop_.at(
eqRel.eq2);
382 if (contains(incompatible_,
eqRel.eq1,
eqRel.eq2))
417 typename std::vector<Loop<Base>*>::const_iterator
it = std::find(loops_.cbegin(), loops_.cend(),
loop2);
418 CPPADCG_ASSERT_UNKNOWN(
it != loops_.end())
444 for (
size_t l = 0; l < loops_.size(); l++) {
445 loops_[l]->generateDependentLoopIndexes(dep2Equation_);
451 if (!loops_.empty()) {
452 for (
size_t l1 = 0;
l1 < loops_.size() - 1;
l1++) {
453 Loop<Base>*
loop1 = loops_[
l1];
454 for (
size_t l2 =
l1 + 1;
l2 < loops_.size();) {
455 Loop<Base>*
loop2 = loops_[
l2];
465 loops_.erase(loops_.begin() +
l2);
474 size_t l_size = loops_.size();
479 for (
size_t l = 0; l <
l_size; l++) {
480 Loop<Base>*
loop = loops_[l];
483 loop->createLoopModel(dependents_, independents_, dep2Equation_, origTemp2Index_);
489 resetHandlerCounters();
502 inline bool isCompatible(Loop<Base>*
loop1,
519 map<size_t, map<UniqueEquationPair<Base>, TotalOps2validDepsType*> >
totalOp2eq;
537 typename map<size_t, map<UniqueEquationPair<Base>, TotalOps2validDepsType*> >::const_reverse_iterator
itr;
550 typename map<size_t, map<DepPairType, const map<OperationNode<Base>*, Indexed2OpCountType>* > >::const_reverse_iterator
itOp2Dep2Shared;
552#ifdef CPPADCG_PRINT_DEBUG
576 std::vector<Loop<Base>*> loops(2);
580 for (
size_t l = 0; l < 2; l++) {
581 Loop<Base>*
loop = loops[l];
583 for (
size_t dep :
eq->dependents) {
609#ifdef CPPADCG_PRINT_DEBUG
611 std::cout <<
" loopRelations:";
613 std::cout << std::endl;
623 incompatible_[eq1].insert(eq2);
624 incompatible_[eq2].insert(eq1);
676 const set<size_t>&
deps = id2Deps[varId_[*
shared]];
698 CPPADCG_ASSERT_UNKNOWN(handler_ == independents_[0].getCodeHandler());
700 size_t m = dependents_.size();
701 std::vector<bool>
inLoop(m,
false);
707 size_t l_size = loops_.size();
709 for (
size_t l = 0; l <
l_size; l++) {
710 Loop<Base>*
loop = loops_[l];
716 const std::vector<std::vector<LoopPosition> >&
ldeps =
loopModel->getDependentIndexes();
719 if (
pos.original != (std::numeric_limits<size_t>::max)()) {
743 for (
size_t i = 0;
i <
inLoop.size();
i++) {
755 for (
const auto&
itTmp : origTemp2Index_) {
767 std::map<size_t, atomic_base<CGBase>* >
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();
786 std::vector<EquationPattern<Base>*> findRelatedVariables() {
788 CodeHandlerVector<Base, size_t>
varColor(*handler_);
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;
810 if (eqCurr_ ==
nullptr || !
used.empty()) {
812 equations_.push_back(eqCurr_);
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,
881 if (handler_->isVisited(*node)) {
883 return varIndexed_[*node];
886 handler_->markVisited(*node);
891 const std::vector<Argument<Base> >&
args = node->getArguments();
895 if (
argOp !=
nullptr) {
896 if (
argOp->getOperationType() != CGOpCode::Inv) {
908 size_t id = varId_[*node];
909 std::set<size_t>&
deps = id2Deps[
id];
911 if (
deps.size() > 1 && node->getOperationType() != CGOpCode::Inv) {
925 std::map<OperationNode<Base>*, Indexed2OpCountType>*
reldepdep;
926 if (
eqPair.eq1 == eqCurr_)
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);
956 if (node ==
nullptr || node->getOperationType() == CGOpCode::Inv)
959 size_t id = varId_[*node];
961 std::set<size_t>&
deps = id2Deps[
id];
972 const std::vector<Argument<Base> >&
args = node->getArguments();
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];
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();
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];
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();
1029 resetHandlerCounters(
args[
i].getOperation());
1033 static bool find(Loop<Base>*
loop1, Loop<Base>*
loop2,
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()) {
1071 using namespace std;
1092 if (
indexed1It == eq1.indexedOpIndep.op2Arguments.end()) {
1093 if (
indexed2It != eq2.indexedOpIndep.op2Arguments.end()) {
1097 if (
indexed2It == eq2.indexedOpIndep.op2Arguments.end()) {
1136 typename map<const OperationNode<Base>*,
size_t>::const_iterator
itHint =
eq1Indep2Dep.begin();
1142 typename map<const OperationNode<Base>*,
size_t>::const_iterator
it;
1156 size_t dep1 =
it->second;
1190 using namespace std;
1194 const set<const OperationNode<Base>*>
opWithIndepArgs = EquationPattern<Base>::findOperationsUsingIndependents(
sharedTemp);
1201 const auto indexed2It = eq2.indexedOpIndep.op2Arguments.find(
op2);
1202 if (
indexed2It != eq2.indexedOpIndep.op2Arguments.end()) {
1216 using namespace std;
1239 for (
size_t it :
eq3.dependents) {
1272 for (
size_t it : eq2.dependents) {
1298 for (
size_t it : eq1.dependents) {
1321 auto*
related =
new std::set<size_t>();