1 #ifndef CPPAD_CG_MODEL_C_SOURCE_GEN_LOOPS_INCLUDED 2 #define CPPAD_CG_MODEL_C_SOURCE_GEN_LOOPS_INCLUDED 30 std::map<size_t, size_t> locations;
37 const std::map<size_t, size_t>& loc) :
46 std::set<size_t> iterations;
53 std::map<SizeN1stIt, IfBranchInfo<Base> > firstIt2Branch;
64 std::map<size_t, std::vector<size_t> > indexedPositions;
67 std::map<size_t, std::vector<size_t> > nonIndexedPositions;
70 std::set<size_t> nonIndexedEvals;
73 std::map<size_t, std::set<size_t> > tmpEvals;
79 std::vector<size_t> indexes;
80 std::vector<CG<Base> > origVals;
89 inline std::vector<CG<Base> > createIndexedIndependents(
CodeHandler<Base>& handler,
94 size_t nIndexed = indexedIndepIndexes.size();
96 std::vector<CG<Base> > x(nIndexed);
98 std::vector<Argument<Base> > xIndexedArgs{iterationIndexOp};
99 std::vector<size_t> info(2);
102 for (
size_t j = 0; j < nIndexed; j++) {
103 info[1] = handler.addLoopIndependentIndexPattern(*loop.getIndependentIndexPatterns()[j], j);
104 x[j] =
CG<Base>(*handler.makeNode(CGOpCode::LoopIndexedIndep, info, xIndexedArgs));
111 inline std::vector<CG<Base> > createLoopIndependentVector(
CodeHandler<Base>& handler,
113 const std::vector<
CG<Base> >& indexedIndeps,
114 const std::vector<
CG<Base> >& nonIndexed,
115 const std::vector<
CG<Base> >& nonIndexedTmps) {
121 size_t nIndexed = indexedIndepIndexes.size();
122 size_t nNonIndexed = nonIndexedIndepIndexes.size();
123 size_t nTape = nIndexed + nNonIndexed + temporaryIndependents.size();
126 std::vector<CG<Base> > x(nTape);
127 for (
size_t j = 0; j < nIndexed; j++) {
128 x[j] = indexedIndeps[j];
132 for (
size_t j = 0; j < nNonIndexed; j++) {
133 x[nIndexed + j] = nonIndexed[nonIndexedIndepIndexes[j].original];
137 for (
size_t j = 0; j < temporaryIndependents.size(); j++) {
138 x[nIndexed + nNonIndexed + j] = nonIndexedTmps[temporaryIndependents[j].original];
145 inline std::vector<CG<Base> > createLoopDependentVector(
CodeHandler<Base>& handler,
149 const std::vector<IndexPattern*>& depIndexes = loop.getDependentIndexPatterns();
150 std::vector<CG<Base> > deps(depIndexes.size());
152 size_t dep_size = depIndexes.size();
155 std::vector<Argument<Base> > xIndexedArgs{iterationIndexOp};
156 std::vector<size_t> info(2);
159 for (
size_t i = 0; i < dep_size; i++) {
161 info[1] = handler.addLoopIndependentIndexPattern(*ip, x_size + i);
162 deps[i] =
CG<Base>(*handler.makeNode(CGOpCode::LoopIndexedIndep, info, xIndexedArgs));
173 size_t assignOrAdd = 1;
177 std::vector<size_t> aInfo{handler.addLoopDependentIndexPattern(*ip), assignOrAdd};
179 std::vector<Argument<Base> > indexedArgs{asArgument(val), iterationIndexOp};
181 OperationNode<Base>* yIndexed = handler.makeNode(CGOpCode::LoopIndexedDep, aInfo, indexedArgs);
185 }
else if (val.getOperationNode() !=
nullptr &&
186 val.getOperationNode()->getOperationType() == CGOpCode::EndIf) {
189 return handler.createCG(*handler.makeNode(CGOpCode::DependentRefRhs,{i}, {*val.getOperationNode()}));
205 size_t assignOrAdd) {
206 std::vector<Argument<Base> > endArgs;
207 std::vector<Argument<Base> > indexedArgs(1 + indexesOps.size());
208 std::vector<size_t> info(2);
210 size_t dep_size = indexedLoopResults.size();
211 endArgs.reserve(dep_size);
213 for (
size_t i = 0; i < dep_size; i++) {
214 const std::pair<CG<Base>,
IndexPattern*>& depInfo = indexedLoopResults[i];
215 if (depInfo.second !=
nullptr) {
216 indexedArgs.resize(1);
218 indexedArgs[0] = asArgument(depInfo.first);
220 indexedArgs.push_back(*itIndexOp);
223 info[0] = handler.addLoopDependentIndexPattern(*depInfo.second);
224 info[1] = assignOrAdd;
226 OperationNode<Base>* yIndexed = handler.makeNode(CGOpCode::LoopIndexedDep, info, indexedArgs);
227 endArgs.push_back(*yIndexed);
230 CPPADCG_ASSERT_UNKNOWN(n !=
nullptr);
231 endArgs.push_back(*n);
246 std::set<OperationNode<Base>*> nonIndexed;
249 indexed.adjustSize();
252 const std::vector<Argument<Base> >& endArgs = loopEnd.
getArguments();
253 for (
size_t i = 0; i < endArgs.size(); i++) {
254 CPPADCG_ASSERT_UNKNOWN(endArgs[i].getOperation() !=
nullptr);
258 std::vector<Argument<Base> >& startArgs = loopStart.
getArguments();
260 size_t sas = startArgs.size();
261 startArgs.resize(sas + nonIndexed.size());
263 for (
auto it = nonIndexed.begin(); it != nonIndexed.end(); ++it, i++) {
264 startArgs[sas + i] = **it;
273 std::set<OperationNode<Base>*>& nonIndexed_;
283 nonIndexed_(nonIndexed),
284 loopIndex_(loopIndex) {
285 indexed_.adjustSize();
289 short& idx = indexed_[node];
294 if (&node == &loopIndex_) {
300 const std::vector<Argument<Base> >& args = node.
getArguments();
301 size_t size = args.size();
303 bool indexedPath =
false;
304 bool nonIndexedArgs =
false;
305 for (
size_t a = 0; a < size; a++) {
307 if (arg !=
nullptr) {
308 bool nonIndexedArg = findNonIndexedNodes(*arg);
309 nonIndexedArgs |= nonIndexedArg;
310 indexedPath |= !nonIndexedArg;
314 idx = indexedPath ? 2 : 1;
322 if (indexedPath && nonIndexedArgs) {
323 for (
size_t a = 0; a < size; a++) {
325 if (arg !=
nullptr && indexed_[*arg] == 1) {
327 if (op != CGOpCode::Inv && op != CGOpCode::TmpDcl) {
329 if (op == CGOpCode::LoopIndexedTmp) {
332 if (assignArg.getOperation() !=
nullptr) {
335 nonIndexed_.insert(assignNode);
338 nonIndexed_.insert(arg);
351 const std::map<SizeN1stIt, std::pair<
size_t, std::set<size_t> > >& first2Iterations) {
355 for (
size_t f = 0; f < ifElses.size(); f++) {
358 if (first2Iterations.size() != ifElse.firstIt2Branch.size())
362 auto itLoc = first2Iterations.begin();
363 auto itBranches = ifElse.firstIt2Branch.begin();
364 for (; itLoc != first2Iterations.end(); ++itLoc, ++itBranches) {
365 if (itLoc->second.second != itBranches->second.iterations) {
381 const std::set<size_t>& iterations,
382 const std::set<size_t>& usedIter,
385 std::vector<size_t> info = createIndexConditionExpression(iterations, usedIter, maxIter);
386 OperationNode<Base>* node = handler.makeNode(CGOpCode::IndexCondExpr, info,{iterationIndexOp});
390 std::vector<size_t> createIndexConditionExpression(
const std::set<size_t>& iterations,
391 const std::set<size_t>& usedIter,
393 CPPADCG_ASSERT_UNKNOWN(!iterations.empty());
395 std::map<size_t, bool> allIters;
396 for (
size_t it : usedIter) {
397 allIters[it] =
false;
399 for (
size_t it : iterations) {
403 std::vector<size_t> info;
404 info.reserve(iterations.size() / 2 + 2);
406 auto it = allIters.begin();
407 while (it != allIters.end()) {
410 auto minNew = allIters.end();
411 auto maxNew = allIters.end();
417 for (++it; it != allIters.end(); ++it) {
418 if (it->first != max->first + 1) {
424 if (minNew == allIters.end())
430 if (minNew != allIters.end()) {
432 if (maxNew->first == minNew->first) {
434 info.push_back(minNew->first);
435 info.push_back(maxNew->first);
439 info.push_back(min->first);
441 info.push_back(minNew->first);
443 if (max->first == maxIter)
444 info.push_back((std::numeric_limits<size_t>::max)());
446 info.push_back(maxNew->first);
461 bool printResult =
false) {
464 map<SizeN1stIt, pair<size_t, set<size_t> > > firstIt2Count2Iterations;
465 for (
const auto& itb : branches) {
466 set<size_t> iterations;
467 mapKeys(itb.second.locations, iterations);
468 firstIt2Count2Iterations[SizeN1stIt(iterations.size(), *iterations.begin())] = make_pair(itb.first, iterations);
471 IfElseInfo<Base>* ifElseBranches = findExistingIfElse(ifElses, firstIt2Count2Iterations);
472 bool reusingIfElse = ifElseBranches !=
nullptr;
473 if (!reusingIfElse) {
474 size_t s = ifElses.size();
475 ifElses.resize(s + 1);
476 ifElseBranches = &ifElses[s];
485 set<size_t> usedIter;
487 for (
const auto& it1st2Count2Iters : firstIt2Count2Iterations) {
488 size_t firstIt = it1st2Count2Iters.first.second;
489 size_t count = it1st2Count2Iters.second.first;
490 const set<size_t>& iterations = it1st2Count2Iters.second.second;
493 size_t iterCount = iterations.size();
495 SizeN1stIt pos(iterCount, firstIt);
499 ifBranch = ifElseBranches->firstIt2Branch.at(pos).node;
500 if (nextBranchArg.getOperation() !=
nullptr)
503 }
else if (usedIter.size() + iterCount == nLocalIter) {
505 ifBranch = handler.makeNode(CGOpCode::Else,{
Argument<Base>(*ifBranch), nextBranchArg});
508 OperationNode<Base>* cond = createIndexConditionExpressionOp<Base>(handler, iterations, usedIter, maxIter, iterationIndexOp);
510 if (ifStart ==
nullptr) {
512 ifStart = handler.makeNode(CGOpCode::StartIf, *cond);
516 ifBranch = handler.makeNode(CGOpCode::ElseIf,{*ifBranch, *cond, nextBranchArg});
519 usedIter.insert(iterations.begin(), iterations.end());
523 handler.manageLoopDependentIndexPattern(pattern);
530 value = asArgument(branchData.value);
534 std::vector<size_t> ainfo{handler.addLoopDependentIndexPattern(*pattern), 1};
536 std::vector<Argument<Base> > indexedArgs{value, iterationIndexOp};
537 OperationNode<Base>* yIndexed = handler.makeNode(CGOpCode::LoopIndexedDep, ainfo, indexedArgs);
542 if (!reusingIfElse) {
544 branch.iterations = iterations;
545 branch.node = ifBranch;
553 ifElseBranches->endIf->getArguments().push_back(nextBranchArg);
555 ifElseBranches->endIf = handler.makeNode(CGOpCode::EndIf,{*ifBranch, nextBranchArg});
567 const std::set<size_t>& iterations,
574 CPPADCG_ASSERT_UNKNOWN(pattern.getLinearSlopeDy() == 0);
577 map<SizeN1stIt, pair<size_t, set<size_t> > > firstIt2Count2Iterations;
578 SizeN1stIt pos(iterations.size(), *iterations.begin());
579 firstIt2Count2Iterations[pos] = make_pair(1, iterations);
581 IfElseInfo<Base>* ifElseBranches = findExistingIfElse(ifElses, firstIt2Count2Iterations);
582 bool reusingIfElse = ifElseBranches !=
nullptr;
583 if (!reusingIfElse) {
584 size_t s = ifElses.size();
585 ifElses.resize(s + 1);
586 ifElseBranches = &ifElses[s];
596 ifBranch = ifElseBranches->firstIt2Branch.at(pos).node;
600 const set<size_t> usedIter;
601 OperationNode<Base>* cond = createIndexConditionExpressionOp<Base>(handler, iterations, usedIter, maxIter, iterationIndexOp);
603 ifBranch = handler.makeNode(CGOpCode::StartIf, *cond);
607 std::vector<size_t> ainfo{handler.addLoopDependentIndexPattern(pattern), 1};
609 std::vector<Argument<Base> > indexedArgs{asArgument(ddfdxdx), iterationIndexOp};
611 OperationNode<Base>* yIndexed = handler.makeNode(CGOpCode::LoopIndexedDep, ainfo, indexedArgs);
613 OperationNode<Base>* ifAssign = handler.makeNode(CGOpCode::CondResult,{*ifBranch, *yIndexed});
616 if (!reusingIfElse) {
618 branch.iterations = iterations;
619 branch.node = ifBranch;
626 ifElseBranches->endIf->getArguments().push_back(nextBranchArg);
628 ifElseBranches->endIf = handler.makeNode(CGOpCode::EndIf,{*ifBranch, nextBranchArg});
649 const std::map<size_t, size_t>& locationsIter2Pos,
658 if (locationsIter2Pos.size() == iterCount) {
661 return make_pair(value, pattern);
670 map<SizeN1stIt, pair<size_t, set<size_t> > > firstIt2Count2Iterations;
672 set<size_t> iterations;
673 mapKeys(locationsIter2Pos, iterations);
674 SizeN1stIt pos(iterations.size(), *iterations.begin());
675 firstIt2Count2Iterations[pos] = make_pair(*iterations.begin(), iterations);
677 IfElseInfo<Base>* ifElseBranches = findExistingIfElse(ifElses, firstIt2Count2Iterations);
678 bool reusingIfElse = ifElseBranches !=
nullptr;
679 if (!reusingIfElse) {
680 size_t s = ifElses.size();
681 ifElses.resize(s + 1);
682 ifElseBranches = &ifElses[s];
689 ifStart = ifElseBranches->firstIt2Branch.at(pos).node;
692 set<size_t> usedIter;
693 OperationNode<Base>* cond = createIndexConditionExpressionOp<Base>(handler, iterations, usedIter, iterCount - 1, iterationIndexOp);
695 ifStart = handler.makeNode(CGOpCode::StartIf, *cond);
699 std::vector<size_t> ainfo{handler.addLoopDependentIndexPattern(*pattern), assignOrAdd};
701 std::vector<Argument<Base> > indexedArgs{asArgument(value), iterationIndexOp};
703 OperationNode<Base>* yIndexed = handler.makeNode(CGOpCode::LoopIndexedDep, ainfo, indexedArgs);
705 OperationNode<Base>* ifAssign = handler.makeNode(CGOpCode::CondResult,{*ifStart, *yIndexed});
707 if (!reusingIfElse) {
710 branch.iterations = iterations;
711 branch.node = ifStart;
715 ifElseBranches->endIf->
getArguments().push_back(*ifAssign);
717 ifElseBranches->endIf = handler.makeNode(CGOpCode::EndIf,{*ifStart, *ifAssign});
721 return make_pair(handler.createCG(
Argument<Base>(*ifElseBranches->endIf)), p);
733 resultPattern(
nullptr),
734 compressedPattern(
nullptr) {
739 resultPattern(resultPat),
740 compressedPattern(compressedPat) {
744 delete resultPattern;
745 delete compressedPattern;
752 std::set<size_t> keys;
753 std::vector<ArrayElementCopyPattern> elements;
763 std::unique_ptr<IndexPattern> pattern;
764 std::unique_ptr<IndexPattern> startLocPattern;
778 inline void determineForRevUsagePatterns(
const std::map<
LoopModel<Base>*, std::map<
size_t, std::map<
size_t, std::set<size_t> > > >& loopGroups,
779 const std::map<size_t, CompressedVectorInfo>& matrixInfo,
780 std::map<
size_t, std::map<
LoopModel<Base>*, std::map<size_t, ArrayGroup*> > >& loopCalls,
785 std::vector<size_t> arrayStart;
790 std::vector<size_t> localit2jcols;
791 for (
const auto& itlge : loopGroups) {
794 garbage.reserve(garbage.size() + itlge.second.size());
796 for (
const auto& itg : itlge.second) {
797 size_t group = itg.first;
798 const map<size_t, set<size_t> >& jcols2e = itg.second;
801 std::unique_ptr<ArrayGroup> data(
new ArrayGroup());
806 mapKeys(jcols2e, localit2jcols);
813 for (
size_t l = 0; l < localit2jcols.size(); l++) {
814 if (!matrixInfo.at(localit2jcols[l]).ordered) {
821 arrayStart.resize(localit2jcols.size());
823 for (
size_t l = 0; l < localit2jcols.size(); l++) {
824 const std::vector<std::set<size_t> >& location = matrixInfo.at(localit2jcols[l]).locations;
825 arrayStart[l] = *location[0].begin();
834 map<size_t, map<size_t, size_t> > elCount2localIt2jcols;
837 for (
auto itJcols2e = jcols2e.begin(); itJcols2e != jcols2e.end(); ++itJcols2e, localIt++) {
838 size_t elCount = itJcols2e->second.size();
839 elCount2localIt2jcols[elCount][localIt] = itJcols2e->first;
842 for (
const auto& elC2jcolIt : elCount2localIt2jcols) {
843 size_t commonElSize = elC2jcolIt.first;
844 const map<size_t, size_t>& localIt2keys = elC2jcolIt.second;
847 std::vector<std::map<size_t, size_t> > compressPos(commonElSize);
848 std::vector<std::map<size_t, size_t> > resultPos(commonElSize);
852 for (
const auto& lIt2jcolIt : localIt2keys) {
853 size_t localIt = lIt2jcolIt.first;
854 size_t key = lIt2jcolIt.second;
858 const std::vector<std::set<size_t> >& origPos = matrixInfo.at(key).locations;
859 const std::set<size_t>& compressed = jcols2e.at(key);
862 for (
auto itE = compressed.begin(); itE != compressed.end(); ++itE, e++) {
863 CPPADCG_ASSERT_UNKNOWN(origPos[*itE].size() == 1);
864 resultPos[e][localIt] = *origPos[*itE].begin();
866 compressPos[e][localIt] = *itE;
871 data->elCount2elements[commonElSize] = eg;
873 for (
size_t e = 0; e < commonElSize; e++) {
883 loopCalls[localit2jcols.size()][loop][group] = data.get();
884 garbage.push_back(data.release());
896 void printForRevUsageFunction(std::ostringstream& out,
897 const std::string& baseTypeName,
898 const std::string& modelName,
899 const std::string& modelFunction,
901 const std::string& localFunction,
902 const std::string& suffix,
903 const std::string& keyIndexName,
904 const std::string& indexIt,
905 const std::string& resultName,
906 const std::map<
LoopModel<Base>*, std::map<
size_t, std::map<
size_t, std::set<size_t> > > >& loopGroups,
907 const std::map<
size_t, std::set<size_t> >& nonLoopElements,
908 const std::map<size_t, CompressedVectorInfo>& matrixInfo,
909 void (*generateLocalFunctionName)(std::ostringstream& cache,
const std::string& modelName,
const LoopModel<Base>& loop,
size_t g),
911 size_t maxCompressedSize) {
919 map<size_t, map<LoopModel<Base>*, map<size_t, ArrayGroup*> > > loopCalls;
925 determineForRevUsagePatterns(loopGroups, matrixInfo, loopCalls, garbage);
927 string nlRev2Suffix =
"noloop_" + suffix;
930 string loopFArgs =
"inLocal, outLocal, " + langC.getArgumentAtomic();
931 string argsDcl = langC.generateDefaultFunctionArgumentsDcl();
932 std::vector<std::string> argsDcl2 = langC.generateDefaultFunctionArgumentsDcl2();
940 set<RandomIndexPattern*> indexRandomPatterns;
942 for (
const auto& itItlg : loopCalls) {
944 for (
const auto& itlg : itItlg.second) {
946 for (
const auto& itg : itlg.second) {
951 if (group->startLocPattern.get() !=
nullptr) {
955 for (
const auto& itc : group->elCount2elements) {
977 out <<
" " << baseTypeName <<
" const * inLocal[" << inLocalSize <<
"];\n" 978 " " << baseTypeName <<
" inLocal1 = 1;\n" 979 " " << baseTypeName <<
" * outLocal[1];\n" 980 " unsigned long " << indexIt <<
";\n" 981 " unsigned long " << keyIndexName <<
";\n" 982 " unsigned long e;\n";
983 CPPADCG_ASSERT_UNKNOWN(indexIt !=
"e" && keyIndexName !=
"e");
984 if (maxCompressedSize > 0) {
985 out <<
" " << baseTypeName <<
" compressed[" << maxCompressedSize <<
"];\n";
987 out <<
" " << baseTypeName <<
" * " << resultName <<
" = out[0];\n" 989 " inLocal[0] = in[0];\n" 990 " inLocal[1] = &inLocal1;\n";
991 for (
size_t j = 2; j < inLocalSize; j++)
992 out <<
" inLocal[" << j <<
"] = in[" << (j - 1) <<
"];\n";
999 out <<
" for(e = 0; e < " << nnz <<
"; e++) " << resultName <<
"[e] = 0;\n" 1006 langC.setArgumentIn(
"inLocal");
1007 langC.setArgumentOut(
"outLocal");
1008 string argsLocal = langC.generateDefaultFunctionArguments();
1010 bool lastCompressed =
false;
1011 for (
const auto& it : nonLoopElements) {
1012 size_t index = it.first;
1013 const set<size_t>& elPos = it.second;
1014 const std::vector<set<size_t> >& location = matrixInfo.at(index).locations;
1015 CPPADCG_ASSERT_UNKNOWN(elPos.size() <= location.size());
1016 CPPADCG_ASSERT_UNKNOWN(elPos.size() > 0);
1017 bool rowOrdered = matrixInfo.at(index).ordered;
1021 out <<
" outLocal[0] = &" << resultName <<
"[" << *location[0].begin() <<
"];\n";
1022 }
else if (!lastCompressed) {
1023 out <<
" outLocal[0] = compressed;\n";
1025 out <<
" " << localFunction <<
"_" << nlRev2Suffix << index <<
"(" << argsLocal <<
");\n";
1027 for (
size_t e : elPos) {
1029 for (
size_t itl : location[e]) {
1030 out << resultName <<
"[" << itl <<
"] += compressed[" << e <<
"];\n";
1034 lastCompressed = !rowOrdered;
1040 for (
const auto& itItlg : loopCalls) {
1041 size_t itCount = itItlg.first;
1043 lastCompressed =
false;
1044 out <<
" for(" << indexIt <<
" = 0; " << indexIt <<
" < " << itCount <<
"; " << indexIt <<
"++) {\n";
1047 for (
const auto& itlg : itItlg.second) {
1050 for (
const auto& itg : itlg.second) {
1051 size_t g = itg.first;
1054 const map<size_t, set<size_t> >& key2Compressed = loopGroups.at(&loop).at(g);
1056 string indent = itCount == 1 ?
" " :
" ";
1058 if (group->startLocPattern.get() !=
nullptr) {
1062 if (!lastCompressed) {
1063 out << indent <<
"outLocal[0] = compressed;\n";
1065 out << indent <<
"for(e = 0; e < " << maxCompressedSize <<
"; e++) compressed[e] = 0;\n";
1071 (*generateLocalFunctionName)(out, modelName, loop, g);
1072 out <<
"(" << keyIndexName <<
", " << loopFArgs <<
");\n";
1074 size_t key = key2Compressed.begin()->first;
1076 (*generateLocalFunctionName)(out, modelName, loop, g);
1077 out <<
"(" << key <<
", " << loopFArgs <<
");\n";
1080 if (group->startLocPattern.get() ==
nullptr) {
1081 CPPADCG_ASSERT_UNKNOWN(!group->elCount2elements.m.empty());
1083 std::set<size_t> usedIter;
1087 for (
const auto& itKey : key2Compressed) {
1088 size_t key = itKey.first;
1089 for (
size_t k = eKey; k < key; k++) {
1095 bool withIfs = group->elCount2elements.size() > 1;
1096 for (
auto itc = group->elCount2elements.begin(); itc != group->elCount2elements.end(); ++itc) {
1098 CPPADCG_ASSERT_UNKNOWN(!eg->elements.empty());
1100 string indent2 = indent;
1103 if (itc != group->elCount2elements.begin())
1105 if (itc->first != group->elCount2elements.rbegin()->first) {
1108 size_t maxKey = key2Compressed.rbegin()->first;
1109 std::vector<size_t> info = createIndexConditionExpression(eg->keys, usedIter, maxKey);
1113 usedIter.insert(eg->keys.begin(), eg->keys.end());
1119 for (
size_t e = 0; e < eg->elements.size(); e++) {
1122 out << indent2 << resultName <<
"[" 1124 <<
"] += compressed[" 1131 out << indent <<
"}\n";
1137 lastCompressed = group->startLocPattern.get() ==
nullptr;
1164 template<
class Base>
1165 std::string generateGlobalForRevWithLoopsFunctionSource(
const std::map<
size_t, std::vector<size_t> >& elements,
1166 const std::map<
LoopModel<Base>*, std::map<
size_t, std::map<
size_t, std::set<size_t> > > >& loopGroups,
1167 const std::map<
size_t, std::set<size_t> >& nonLoopElements,
1168 const std::string& functionName,
1169 const std::string& modelName,
1170 const std::string& baseTypeName,
1171 const std::string& suffix,
1172 void (*generateLocalFunctionName)(std::ostringstream& cache,
const std::string& modelName,
const LoopModel<Base>& loop,
size_t g)) {
1174 using namespace std;
1177 map<size_t, map<LoopModel<Base>*, set<size_t> > > functions;
1179 for (
const auto& itlj1g : loopGroups) {
1182 for (
const auto& itg : itlj1g.second) {
1183 size_t group = itg.first;
1184 const map<size_t, set<size_t> >& jrows = itg.second;
1186 for (
const auto& itJrow : jrows) {
1187 functions[itJrow.first][loop].insert(group);
1196 string argsDcl = langC.generateDefaultFunctionArgumentsDcl();
1197 std::vector<string> argsDcl2 = langC.generateDefaultFunctionArgumentsDcl2();
1198 string args = langC.generateDefaultFunctionArguments();
1199 string noLoopFunc = functionName +
"_noloop_" + suffix;
1201 std::ostringstream out;
1202 out << LanguageC<Base>::ATOMICFUN_STRUCT_DEFINITION <<
"\n" 1205 generateFunctionDeclarationSourceLoopForRev(out, langC, modelName,
"j", loopGroups, generateLocalFunctionName);
1212 for (
const auto& it : elements) {
1213 size_t jrow = it.first;
1215 out <<
" case " << jrow <<
":\n";
1221 const auto itnl = nonLoopElements.find(jrow);
1222 if (itnl != nonLoopElements.end()) {
1223 out <<
" " << noLoopFunc << jrow <<
"(" << args <<
");\n";
1229 const map<LoopModel<Base>*, set<size_t> >& rowFunctions = functions[jrow];
1231 for (
const auto& itlg : rowFunctions) {
1234 for (
size_t itg : itlg.second) {
1236 generateLocalFunctionName(out, modelName, *loop, itg);
1237 out <<
"(" << jrow <<
", " << args <<
");\n";
1244 out <<
" return 0; // done\n";
1246 out <<
" default:\n" 1247 " return 1; // error\n" 1254 template<
class Base>
1255 void generateFunctionDeclarationSourceLoopForRev(std::ostringstream& out,
1257 const std::string& modelName,
1258 const std::string& keyName,
1259 const std::map<
LoopModel<Base>*, std::map<
size_t, std::map<
size_t, std::set<size_t> > > >& loopGroups,
1260 void (*generateLocalFunctionName)(std::ostringstream& cache,
const std::string& modelName,
const LoopModel<Base>& loop,
size_t g)) {
1262 std::string argsDcl = langC.generateFunctionArgumentsDcl();
1263 std::string argsDclLoop =
"unsigned long " + keyName +
", " + argsDcl;
1265 for (
const auto& itlg : loopGroups) {
1268 for (
const auto& itg : itlg.second) {
1269 size_t group = itg.first;
1272 (*generateLocalFunctionName)(out, modelName, loop, group);
1273 out <<
"(" << argsDclLoop <<
");\n";
const std::vector< LoopPosition > & getTemporaryIndependents() const
const std::vector< Argument< Base > > & getArguments() const
static void printFunctionDeclaration(std::ostringstream &out, const std::string &returnType, const std::string &functionName, const std::vector< std::string > &arguments, const std::vector< std::string > &arguments2={})
static void printRandomIndexPatternDeclaration(std::ostringstream &os, const std::string &identation, const std::set< RandomIndexPattern *> &randomPatterns)
CGOpCode getOperationType() const
static IndexPattern * detect(const VectorSizeT &x2y)
const std::vector< LoopPosition > & getNonIndexedIndepIndexes() const
const std::vector< std::vector< LoopPosition > > & getIndexedIndepIndexes() const
size_t getTapeIndependentCount() const