1 #ifndef CPPAD_CG_EQUATION_PATTERN_INCLUDED 2 #define CPPAD_CG_EQUATION_PATTERN_INCLUDED 29 using MapDep2Indep_type = std::map<size_t, const OperationNode<Base>*>;
45 return op2Arguments.at(operation);
49 const auto itIndexes = op2Arguments.find(node);
50 if (itIndexes == op2Arguments.end()) {
67 const size_t depRefIndex;
68 std::set<size_t> dependents;
99 handler_(ref.getCodeHandler()) {
106 bool testAdd(
size_t iDep2,
111 std::map<const OperationNode<Base>*, std::set<size_t> > constOperationIndependentsBackup = constOperationIndependents;
112 std::map<size_t, std::map<const OperationNode<Base>*,
OperationNode<Base>*> > operation2ReferenceBackup = operationEO2Reference;
115 minColor_ = minColor;
116 cmpColor_ = minColor_;
118 bool equals = comparePath(depRef, dep2, iDep2, varColor);
120 minColor = cmpColor_;
123 dependents.insert(iDep2);
128 indexedOpIndep.op2Arguments.swap(independentsBackup.op2Arguments);
129 constOperationIndependents.swap(constOperationIndependentsBackup);
130 operationEO2Reference.swap(operation2ReferenceBackup);
136 inline void findIndexedPath(
size_t dep,
137 const std::vector<
CG<Base> >& depVals,
140 findIndexedPath(depRef, depVals[dep], varIndexed, indexedOperations);
143 std::set<const OperationNode<Base>*> findOperationsUsingIndependents(
OperationNode<Base>& node)
const {
144 std::set<const OperationNode<Base>*> ops;
146 handler_->startNewOperationTreeVisit();
148 findOperationsWithIndeps(node, ops);
155 if (node ==
nullptr || !varIndexed[*node])
158 varIndexed[*node] =
false;
160 const std::vector<Argument<Base> >& args = node->getArguments();
161 size_t size = args.size();
162 for (
size_t a = 0; a < size; a++) {
163 uncolor(args[a].getOperation(), varIndexed);
167 inline bool containsConstantIndependent(
const OperationNode<Base>* operation,
size_t argumentIndex)
const {
168 const auto it = constOperationIndependents.find(operation);
169 if (it != constOperationIndependents.end()) {
170 if (it->second.find(argumentIndex) != it->second.end()) {
182 using MapIndep2Dep_type =
typename OperationIndexedIndependents<Base>::MapDep2Indep_type;
185 auto itop2a = indexedOpIndep.op2Arguments.begin();
186 while (itop2a != indexedOpIndep.op2Arguments.end()) {
194 for (
size_t argIndex = 0; argIndex < aSize; argIndex++) {
201 bool isIndexed =
false;
202 typename MapIndep2Dep_type::const_iterator itDep2Ind = dep2Ind.begin();
205 for (++itDep2Ind; itDep2Ind != dep2Ind.end(); ++itDep2Ind) {
206 if (indep != itDep2Ind->second) {
214 constOperationIndependents[parentOp].insert(argIndex);
225 indexedOpIndep.op2Arguments.erase(itop2a++);
238 bool comparePath(
const CG<Base>& dep1,
246 if (h1 !=
nullptr && h2 !=
nullptr)
247 throw CGException(
"Only one code handler allowed");
259 return comparePath(depRefOp, dep2Op, dep2Index, varColor);
269 saveOperationReference(dep2, sc2, scRef);
270 if (dependents.size() == 1) {
271 saveOperationReference(depRefIndex, scRef, scRef);
275 CPPADCG_ASSERT_KNOWN(scRef->
getArguments().size() == 1,
"Invalid number of arguments for alias")
277 if (sc !=
nullptr && sc->getOperationType() == CGOpCode::Inv)
break;
281 CPPADCG_ASSERT_KNOWN(sc2->
getArguments().size() == 1,
"Invalid number of arguments for alias")
283 if (sc !=
nullptr && sc->getOperationType() == CGOpCode::Inv)
break;
288 if (varColor[*sc2] >= minColor_ && varColor[*scRef] >= minColor_) {
298 if (varColor[*sc2] == varColor[*scRef])
301 varColor[*scRef] = cmpColor_;
302 varColor[*sc2] = cmpColor_;
312 const std::vector<size_t>& info1 = scRef->
getInfo();
313 const std::vector<size_t>& info2 = sc2->
getInfo();
314 if (info1.size() != info2.size()) {
318 for (
size_t e = 0; e < info1.size(); e++) {
319 if (info1[e] != info2[e]) {
324 const std::vector<Argument<Base> >& args1 = scRef->
getArguments();
325 const std::vector<Argument<Base> >& args2 = sc2->
getArguments();
326 size_t size = args1.size();
327 if (size != args2.size()) {
330 for (
size_t a = 0; a < size; a++) {
334 if (a1.getParameter() !=
nullptr) {
335 if (a2.getParameter() ==
nullptr || *a1.getParameter() != *a2.getParameter())
338 if (a2.getOperation() ==
nullptr) {
345 related = saveIndependent(scRef, a, argRefOp, arg2Op);
347 related = comparePath(argRefOp, arg2Op, dep2, varColor);
358 inline void saveOperationReference(
size_t dep2,
361 operationEO2Reference[dep2][sc2] = scRef;
376 const auto it = constOperationIndependents.find(parentOp);
377 if (it != constOperationIndependents.end()) {
378 if (it->second.find(argIndex) != it->second.end()) {
386 std::map<size_t, const OperationNode<Base>*>& dep2Indeps = opIndexedIndep.
arg2Independents[argIndex];
387 if (dep2Indeps.empty())
388 dep2Indeps[depRefIndex] = argRefOp;
389 dep2Indeps[currDep_] = arg2Op;
394 inline void findIndexedPath(
const CG<Base>& depRef,
402 findIndexedPath(depRefOp, dep2Op, varIndexed, indexedOperations);
406 itop2a = indexedOpIndep.op2Arguments.find(
nullptr);
407 if (itop2a != indexedOpIndep.op2Arguments.end() && !itop2a->second.arg2Independents[0].empty()) {
409 indexedOperations.insert(
nullptr);
421 CPPADCG_ASSERT_KNOWN(scRef->
getArguments().size() == 1,
"Invalid number of arguments for alias")
423 if (sc !=
nullptr && sc->getOperationType() == CGOpCode::Inv)
break;
427 CPPADCG_ASSERT_KNOWN(sc2->
getArguments().size() == 1,
"Invalid number of arguments for alias")
429 if (sc !=
nullptr && sc->getOperationType() == CGOpCode::Inv)
break;
438 bool searched =
false;
439 bool indexedDependentPath =
false;
440 bool usesIndexedIndependent =
false;
442 size_t size = argsRef.size();
443 for (
size_t a = 0; a < size; a++) {
445 if (argRefOp !=
nullptr) {
446 bool indexedArg =
false;
450 itop2a = indexedOpIndep.op2Arguments.find(scRef);
453 if (itop2a != indexedOpIndep.op2Arguments.end() && !itop2a->second.arg2Independents[a].empty()) {
456 indexedDependentPath =
true;
457 usesIndexedIndependent =
true;
462 const std::vector<Argument<Base> >& args2 = sc2->
getArguments();
463 CPPADCG_ASSERT_UNKNOWN(size == args2.size())
464 indexedDependentPath |= findIndexedPath(argsRef[a].getOperation(), args2[a].getOperation(), varIndexed, indexedOperations);
469 varIndexed[*sc2] = indexedDependentPath;
471 if (usesIndexedIndependent)
472 indexedOperations.insert(sc2);
474 return indexedDependentPath;
479 if (handler_->isVisited(node))
482 handler_->markVisited(node);
484 const std::vector<Argument<Base> >& args = node.
getArguments();
485 size_t size = args.size();
486 for (
size_t a = 0; a < size; a++) {
488 if (argOp !=
nullptr) {
492 findOperationsWithIndeps(*argOp, ops);
void detectNonIndexedIndependents()
std::map< const OperationNode< Base > *, std::set< size_t > > constOperationIndependents
std::map< size_t, std::map< const OperationNode< Base > *, OperationNode< Base > * > > operationEO2Reference
const Base & getValue() const
const std::vector< Argument< Base > > & getArguments() const
std::vector< MapDep2Indep_type > arg2Independents
IndexedIndependent< Base > indexedOpIndep
CGOpCode getOperationType() const
CodeHandler< Base > * getCodeHandler() const
const std::vector< size_t > & getInfo() const