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;
98 std::vector<Argument<Base> >
xIndexedArgs{iterationIndexOp};
99 std::vector<size_t>
info(2);
103 info[1] =
handler.addLoopIndependentIndexPattern(*
loop.getIndependentIndexPatterns()[
j],
j);
111inline std::vector<CG<Base> > createLoopIndependentVector(CodeHandler<Base>&
handler,
112 LoopModel<Base>&
loop,
114 const std::vector<CG<Base> >& nonIndexed,
126 std::vector<CG<Base> > x(
nTape);
145inline std::vector<CG<Base> > createLoopDependentVector(CodeHandler<Base>&
handler,
146 LoopModel<Base>&
loop,
149 const std::vector<IndexPattern*>&
depIndexes =
loop.getDependentIndexPatterns();
153 size_t x_size =
loop.getTapeIndependentCount();
155 std::vector<Argument<Base> >
xIndexedArgs{iterationIndexOp};
156 std::vector<size_t>
info(2);
169inline CG<Base> createLoopDependentFunctionResult(CodeHandler<Base>&
handler,
170 size_t i,
const CG<Base>&
val, IndexPattern*
ip,
179 std::vector<Argument<Base> >
indexedArgs{asArgument(
val), iterationIndexOp};
185 }
else if (
val.getOperationNode() !=
nullptr &&
186 val.getOperationNode()->getOperationType() == CGOpCode::EndIf) {
189 return handler.createCG(*
handler.makeNode(CGOpCode::DependentRefRhs,{i}, {*val.getOperationNode()}));
206 std::vector<Argument<Base> >
endArgs;
208 std::vector<size_t>
info(2);
215 if (
depInfo.second !=
nullptr) {
230 CPPADCG_ASSERT_UNKNOWN(
n !=
nullptr);
241inline void moveNonIndexedOutsideLoop(CodeHandler<Base>&
handler,
246 std::set<OperationNode<Base>*> nonIndexed;
248 CodeHandlerVector<Base, short> indexed(
handler);
249 indexed.adjustSize();
252 const std::vector<Argument<Base> >&
endArgs = loopEnd.getArguments();
254 CPPADCG_ASSERT_UNKNOWN(
endArgs[
i].getOperation() !=
nullptr);
258 std::vector<Argument<Base> >&
startArgs = loopStart.getArguments();
263 for (
auto it = nonIndexed.begin();
it != nonIndexed.end(); ++
it,
i++) {
273 std::set<OperationNode<Base>*>& nonIndexed_;
283 nonIndexed_(nonIndexed),
285 indexed_.adjustSize();
289 short& idx = indexed_[node];
294 if (&node == &loopIndex_) {
301 size_t size =
args.size();
305 for (
size_t a = 0;
a < size;
a++) {
307 if (
arg !=
nullptr) {
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) {
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++) {
381 const std::set<size_t>& iterations,
390std::vector<size_t> createIndexConditionExpression(
const std::set<size_t>& iterations,
393 CPPADCG_ASSERT_UNKNOWN(!iterations.empty());
399 for (
size_t it : iterations) {
403 std::vector<size_t>
info;
404 info.reserve(iterations.size() / 2 + 2);
418 if (
it->first != max->first + 1) {
439 info.push_back(min->first);
444 info.push_back((std::numeric_limits<size_t>::max)());
455inline CG<Base> createConditionalContribution(CodeHandler<Base>&
handler,
466 set<size_t> iterations;
467 mapKeys(
itb.second.locations, iterations);
474 size_t s = ifElses.size();
475 ifElses.resize(s + 1);
519 usedIter.insert(iterations.begin(), iterations.end());
523 handler.manageLoopDependentIndexPattern(pattern);
534 std::vector<size_t>
ainfo{
handler.addLoopDependentIndexPattern(*pattern), 1};
536 std::vector<Argument<Base> >
indexedArgs{value, iterationIndexOp};
544 branch.iterations = iterations;
565CG<Base> createConditionalContribution(CodeHandler<Base>&
handler,
566 LinearIndexPattern& pattern,
567 const std::set<size_t>& iterations,
574 CPPADCG_ASSERT_UNKNOWN(pattern.getLinearSlopeDy() == 0);
578 SizeN1stIt
pos(iterations.size(), *iterations.begin());
584 size_t s = ifElses.size();
585 ifElses.resize(s + 1);
607 std::vector<size_t>
ainfo{
handler.addLoopDependentIndexPattern(pattern), 1};
618 branch.iterations = iterations;
648std::pair<CG<Base>, IndexPattern*> createLoopResult(CodeHandler<Base>&
handler,
651 const CG<Base>& value,
652 IndexPattern* pattern,
672 set<size_t> iterations;
674 SizeN1stIt
pos(iterations.size(), *iterations.begin());
680 size_t s = ifElses.size();
681 ifElses.resize(s + 1);
701 std::vector<Argument<Base> >
indexedArgs{asArgument(value), iterationIndexOp};
710 branch.iterations = iterations;
720 IndexPattern*
p =
nullptr;
733 resultPattern(
nullptr),
734 compressedPattern(
nullptr) {
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;
778inline 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,
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());
863 CPPADCG_ASSERT_UNKNOWN(
origPos[*
itE].size() == 1);
870 ArrayElementGroup*
eg =
new ArrayElementGroup(keys,
commonElSize);
884 garbage.push_back(data.release());
896void printForRevUsageFunction(std::ostringstream&
out,
897 const std::string& baseTypeName,
902 const std::string&
suffix,
906 const std::map<LoopModel<Base>*, std::map<
size_t, std::map<
size_t, std::set<size_t> > > >&
loopGroups,
908 const std::map<size_t, CompressedVectorInfo>&
matrixInfo,
919 map<size_t, map<LoopModel<Base>*, map<size_t, ArrayGroup*> > >
loopCalls;
930 string loopFArgs =
"inLocal, outLocal, " +
langC.getArgumentAtomic();
931 string argsDcl =
langC.generateDefaultFunctionArgumentsDcl();
932 std::vector<std::string>
argsDcl2 =
langC.generateDefaultFunctionArgumentsDcl2();
940 set<RandomIndexPattern*> indexRandomPatterns;
947 ArrayGroup* group =
itg.second;
949 CodeHandler<Base>::findRandomIndexPatterns(group->pattern.get(), indexRandomPatterns);
951 if (group->startLocPattern.get() !=
nullptr) {
952 CodeHandler<Base>::findRandomIndexPatterns(group->startLocPattern.get(), indexRandomPatterns);
955 for (
const auto&
itc : group->elCount2elements) {
956 const ArrayElementGroup*
eg =
itc.second;
958 for (
const ArrayElementCopyPattern&
ePos :
eg->elements) {
959 CodeHandler<Base>::findRandomIndexPatterns(
ePos.resultPattern, indexRandomPatterns);
960 CodeHandler<Base>::findRandomIndexPatterns(
ePos.compressedPattern, indexRandomPatterns);
971 LanguageC<Base>::generateNames4RandomIndexPatterns(indexRandomPatterns);
977 out <<
" " << baseTypeName <<
" const * inLocal[" <<
inLocalSize <<
"];\n"
978 " " << baseTypeName <<
" inLocal1 = 1;\n"
979 " " << baseTypeName <<
" * outLocal[1];\n"
980 " unsigned long " <<
indexIt <<
";\n"
982 " unsigned long e;\n";
987 out <<
" " << baseTypeName <<
" * " <<
resultName <<
" = out[0];\n"
989 " inLocal[0] = in[0];\n"
990 " inLocal[1] = &inLocal1;\n";
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");
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);
1021 out <<
" outLocal[0] = &" <<
resultName <<
"[" << *location[0].begin() <<
"];\n";
1023 out <<
" outLocal[0] = compressed;\n";
1029 for (
size_t itl : location[
e]) {
1048 LoopModel<Base>&
loop = *
itlg.first;
1051 size_t g =
itg.first;
1052 ArrayGroup* group =
itg.second;
1058 if (group->startLocPattern.get() !=
nullptr) {
1060 out <<
indent <<
"outLocal[0] = &" <<
resultName <<
"[" << LanguageC<Base>::indexPattern2String(*group->startLocPattern,
indexIt) <<
"];\n";
1063 out <<
indent <<
"outLocal[0] = compressed;\n";
1080 if (group->startLocPattern.get() ==
nullptr) {
1081 CPPADCG_ASSERT_UNKNOWN(!group->elCount2elements.m.empty());
1095 bool withIfs = group->elCount2elements.size() > 1;
1096 for (
auto itc = group->elCount2elements.begin();
itc != group->elCount2elements.end(); ++
itc) {
1097 const ArrayElementGroup*
eg =
itc->second;
1098 CPPADCG_ASSERT_UNKNOWN(!
eg->elements.empty());
1103 if (
itc != group->elCount2elements.begin())
1105 if (
itc->first != group->elCount2elements.rbegin()->first) {
1119 for (
size_t e = 0;
e <
eg->elements.size();
e++) {
1120 const ArrayElementCopyPattern&
ePos =
eg->elements[
e];
1123 << LanguageC<Base>::indexPattern2String(*
ePos.resultPattern,
indexIt)
1124 <<
"] += compressed["
1125 << LanguageC<Base>::indexPattern2String(*
ePos.compressedPattern,
indexIt)
1165std::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,
1170 const std::string& baseTypeName,
1171 const std::string&
suffix,
1174 using namespace std;
1177 map<size_t, map<LoopModel<Base>*, set<size_t> > >
functions;
1183 size_t group =
itg.first;
1184 const map<size_t, set<size_t> >&
jrows =
itg.second;
1196 string argsDcl =
langC.generateDefaultFunctionArgumentsDcl();
1197 std::vector<string>
argsDcl2 =
langC.generateDefaultFunctionArgumentsDcl2();
1198 string args =
langC.generateDefaultFunctionArguments();
1201 std::ostringstream
out;
1212 for (
const auto&
it : elements) {
1213 size_t jrow =
it.first;
1215 out <<
" case " << jrow <<
":\n";
1232 LoopModel<Base>*
loop =
itlg.first;
1237 out <<
"(" << jrow <<
", " <<
args <<
");\n";
1244 out <<
" return 0; // done\n";
1246 out <<
" default:\n"
1247 " return 1; // error\n"
1255void generateFunctionDeclarationSourceLoopForRev(std::ostringstream&
out,
1259 const std::map<LoopModel<Base>*, std::map<
size_t, std::map<
size_t, std::set<size_t> > > >&
loopGroups,
1262 std::string
argsDcl =
langC.generateFunctionArgumentsDcl();
1266 const LoopModel<Base>&
loop = *
itlg.first;
1269 size_t group =
itg.first;
static IndexPattern * detect(const VectorSizeT &x2y)
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)
const std::vector< Argument< Base > > & getArguments() const
CGOpCode getOperationType() const
bool GreaterThanZero(const cg::CG< Base > &x)