1 #ifndef CPPAD_CG_MODEL_C_SOURCE_GEN_INCLUDED
2 #define CPPAD_CG_MODEL_C_SOURCE_GEN_INCLUDED
27 std::vector<std::set<size_t> > locations;
28 std::vector<size_t> indexes;
41 using SparsitySetType = std::vector<std::set<size_t> >;
42 using TapeVarType = std::pair<size_t, size_t>;
44 static const std::string FUNCTION_FORWAD_ZERO;
45 static const std::string FUNCTION_JACOBIAN;
46 static const std::string FUNCTION_HESSIAN;
47 static const std::string FUNCTION_FORWARD_ONE;
48 static const std::string FUNCTION_REVERSE_ONE;
49 static const std::string FUNCTION_REVERSE_TWO;
50 static const std::string FUNCTION_SPARSE_JACOBIAN;
51 static const std::string FUNCTION_SPARSE_HESSIAN;
52 static const std::string FUNCTION_JACOBIAN_SPARSITY;
53 static const std::string FUNCTION_HESSIAN_SPARSITY;
54 static const std::string FUNCTION_HESSIAN_SPARSITY2;
55 static const std::string FUNCTION_SPARSE_FORWARD_ONE;
56 static const std::string FUNCTION_SPARSE_REVERSE_ONE;
57 static const std::string FUNCTION_SPARSE_REVERSE_TWO;
58 static const std::string FUNCTION_FORWARD_ONE_SPARSITY;
59 static const std::string FUNCTION_REVERSE_ONE_SPARSITY;
60 static const std::string FUNCTION_REVERSE_TWO_SPARSITY;
61 static const std::string FUNCTION_INFO;
62 static const std::string FUNCTION_ATOMIC_FUNC_NAMES;
64 static const std::string CONST;
72 std::vector<size_t> row;
73 std::vector<size_t> col;
79 inline Position(
const std::vector<size_t>& r,
const std::vector<size_t>& c) :
83 CPPADCG_ASSERT_KNOWN(r.size() == c.size(),
"The number of row indexes must be the same as the number of column indexes.")
86 template<
class VectorSet>
87 inline Position(
const VectorSet& elements) :
90 for (
size_t i = 0; i < elements.size(); i++) {
91 nnz += elements[i].size();
97 for (
size_t i = 0; i < elements.size(); i++) {
98 for (
size_t it : elements[i]) {
118 std::vector<size_t> rows;
120 std::vector<size_t> cols;
167 std::vector<Base>
_x;
206 JacobianADMode _jacMode;
244 std::vector<std::set<size_t> > _relatedDepCandidates;
249 std::map<LoopModel<Base>*, std::map<size_t, std::map<size_t, std::set<size_t> > > >
_loopFor1Groups;
259 std::map<LoopModel<Base>*, std::map<size_t, std::map<size_t, std::set<size_t> > > >
_loopRev1Groups;
269 std::map<LoopModel<Base>*, std::map<size_t, std::map<size_t, std::set<size_t> > > >
_loopRev2Groups;
296 _name(std::move(model)),
301 _zeroEvaluated(false),
312 _jacMode(JacobianADMode::Automatic),
318 CPPADCG_ASSERT_KNOWN(!
_name.empty(),
"Model name cannot be empty");
319 CPPADCG_ASSERT_KNOWN((
_name[0] >=
'a' &&
_name[0] <=
'z') ||
321 "Invalid model name character");
322 for (
size_t i = 1; i <
_name.size(); i++) {
324 CPPADCG_ASSERT_KNOWN((c >=
'a' && c <=
'z') ||
325 (c >=
'A' && c <=
'Z') ||
326 (c >=
'0' && c <=
'9') ||
328 ,
"Invalid model name character");
352 template<
class VectorBase>
354 CPPAD_ASSERT_KNOWN(x.size() == 0 || x.size() ==
_fun.Domain(),
355 "Invalid independent variable vector size")
357 for (
size_t i = 0; i < x.size(); i++) {
362 inline void setRelatedDependents(
const std::vector<std::set<size_t> >& relatedDepCandidates) {
363 _relatedDepCandidates = relatedDepCandidates;
366 inline const std::vector<std::set<size_t> >& getRelatedDependents()
const {
367 return _relatedDepCandidates;
423 inline bool isJacobianMultiThreadingEnabled()
const {
427 inline bool isHessianMultiThreadingEnabled()
const {
803 const std::vector<size_t>& col) {
816 template<
class VectorSet>
834 const std::vector<size_t>& col) {
849 template<
class VectorSet>
909 static inline std::string baseTypeName();
912 static void generateFunctionDeclarationSource(std::ostringstream& cache,
913 const std::string& model_function,
914 const std::string& suffix,
915 const std::map<size_t, T>& elements,
916 const std::string& argsDcl);
920 virtual VariableNameGenerator<Base>* createVariableNameGenerator(
const std::string& depName =
"y",
921 const std::string& indepName =
"x",
922 const std::string& tmpName =
"v",
923 const std::string& tmpArrayName =
"array");
925 const std::map<std::string, std::string>& getSources(MultiThreadingType multiThreadingType,
928 virtual void generateSources(MultiThreadingType multiThreadingType,
929 JobTimer* timer =
nullptr);
931 virtual void generateLoops();
933 virtual void generateInfoSource();
935 virtual void generateAtomicFuncNames();
937 virtual bool isAtomicsUsed();
939 virtual const std::map<size_t, AtomicUseInfo<Base> >& getAtomicsInfo();
951 const std::vector<CGBase>& x);
957 virtual void generateJacobianSource();
964 MultiThreadingType multiThreadingType);
966 virtual std::string generateSparseJacobianForRevSingleThreadSource(
const std::string& functionName,
967 std::map<size_t, CompressedVectorInfo> jacInfo,
968 size_t maxCompressedSize,
969 const std::string& functionRevFor,
970 const std::string& revForSuffix,
974 std::map<size_t, CompressedVectorInfo> jacInfo,
975 size_t maxCompressedSize,
976 const std::string& functionRevFor,
977 const std::string& revForSuffix,
979 MultiThreadingType multiThreadingType);
1002 const std::vector<CGBase>& x,
1006 LoopModel<Base>& lModel,
1008 const loops::JacobianWithLoopsRowInfo& rowInfo,
1009 const std::vector<std::map<size_t, CGBase> >& dyiDxtape,
1010 const std::vector<std::map<size_t, CGBase> >& dzDx,
1012 IndexOperationNode<Base>& iterationIndexOp,
1013 std::vector<loops::IfElseInfo<Base> >& ifElses,
1015 std::vector<std::pair<CG<Base>, IndexPattern*> >& indexedLoopResults,
1016 std::set<size_t>& allLocations);
1019 const std::vector<size_t>& cols,
1020 const std::vector<size_t>& location,
1021 SparsitySetType& noLoopEvalSparsity,
1022 std::vector<std::map<
size_t, std::set<size_t> > >& noLoopEvalLocations,
1023 std::map<LoopModel<Base>*, SparsitySetType>& loopsEvalSparsities,
1024 std::map<LoopModel<Base>*, std::vector<loops::JacobianWithLoopsRowInfo> >& loopEqInfo);
1028 size_t maxCompressedSize,
1029 const std::string& localFunctionTypeName,
1030 const std::string& suffix,
1031 const std::string& keyName,
1032 const std::map<
size_t, std::set<size_t> >& nonLoopElements,
1033 const std::map<LoopModel<Base>*, std::map<
size_t, std::map<
size_t, std::set<size_t> > > >& loopGroups,
1034 void (*generateLocalFunctionName)(std::ostringstream& cache,
const std::string& modelName,
const LoopModel<Base>& loop,
size_t g));
1036 inline virtual void generateFunctionNameLoopFor1(std::ostringstream& cache,
1037 const LoopModel<Base>& loop,
1040 inline static void generateFunctionNameLoopFor1(std::ostringstream& cache,
1041 const std::string& modelName,
1042 const LoopModel<Base>& loop,
1045 inline virtual void generateFunctionNameLoopRev1(std::ostringstream& cache,
1046 const LoopModel<Base>& loop,
1049 inline static void generateFunctionNameLoopRev1(std::ostringstream& cache,
1050 const std::string& modelName,
1051 const LoopModel<Base>& loop,
1058 virtual void generateHessianSource();
1066 virtual std::string generateSparseHessianRev2SingleThreadSource(
const std::string& functionName,
1067 std::map<size_t, CompressedVectorInfo> hessInfo,
1068 size_t maxCompressedSize,
1069 const std::string& functionRev2,
1070 const std::string& rev2Suffix);
1073 std::map<size_t, CompressedVectorInfo> hessInfo,
1074 size_t maxCompressedSize,
1075 const std::string& functionRev2,
1076 const std::string& rev2Suffix,
1077 MultiThreadingType multiThreadingType);
1080 std::vector<size_t>& userCols);
1109 std::vector<CGBase>& indVars,
1110 std::vector<CGBase>& w,
1111 const std::vector<size_t>& lowerHessRows,
1112 const std::vector<size_t>& lowerHessCols,
1113 const std::vector<size_t>& lowerHessOrder,
1114 const std::map<size_t, size_t>& duplicates);
1117 const std::vector<size_t>& lowerHessCols,
1118 const std::vector<size_t>& lowerHessOrder,
1119 SparsitySetType& noLoopEvalJacSparsity,
1120 SparsitySetType& noLoopEvalHessSparsity,
1121 std::vector<std::map<
size_t, std::set<size_t> > >& noLoopEvalHessLocations,
1122 std::map<LoopModel<Base>*, loops::HessianWithLoopsInfo<Base> >& loopHessInfo,
1126 size_t maxCompressedSize);
1128 inline virtual void generateFunctionNameLoopRev2(std::ostringstream& cache,
1129 const LoopModel<Base>& loop,
1132 static inline void generateFunctionNameLoopRev2(std::ostringstream& cache,
1133 const std::string& modelName,
1134 const LoopModel<Base>& loop,
1141 virtual void generateSparsity1DSource(
const std::string&
function,
1142 const std::vector<size_t>& sparsity);
1144 virtual void generateSparsity2DSource(
const std::string&
function,
1145 const LocalSparsityInfo& sparsity);
1147 virtual void generateSparsity2DSource2(
const std::string&
function,
1148 const std::vector<LocalSparsityInfo>& sparsities);
1150 virtual void generateSparsity1DSource2(
const std::string&
function,
1151 const std::map<
size_t, std::vector<size_t> >& rows);
1163 virtual void generateForwardOneSources();
1167 virtual void createForwardOneWithLoopsNL(CodeHandler<Base>& handler,
1169 std::vector<CG<Base> >& jacCol);
1172 inline static std::map<size_t, std::map<size_t, CG<Base> > > generateLoopFor1Jac(ADFun<CGBase>& fun,
1173 const SparsitySetType& sparsity,
1174 const SparsitySetType& evalSparsity,
1175 const std::vector<CGBase>& xl,
1176 bool constainsAtomics);
1188 virtual void generateReverseOneSources();
1192 virtual void createReverseOneWithLoopsNL(CodeHandler<Base>& handler,
1194 std::vector<CG<Base> >& jacRow);
1196 inline static std::vector<std::map<size_t, CGBase> > generateLoopRev1Jac(ADFun<CGBase>& fun,
1197 const SparsitySetType& sparsity,
1198 const SparsitySetType& evalSparsity,
1199 const std::vector<CGBase>& xl,
1200 bool constainsAtomics);
1208 virtual void generateSparseReverseTwoSourcesWithAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1211 const std::vector<size_t>& evalRows,
1212 const std::vector<size_t>& evalCols);
1214 virtual void generateReverseTwoSources();
1217 const std::string& function2_suffix,
1218 const std::string& function_sparsity,
1219 const std::map<
size_t, std::vector<size_t> >& elements);
1232 virtual void generateJacobianSparsitySource();
1245 inline std::vector<ModelCSourceGen<Base>::Color>
colorByRow(
const std::set<size_t>& columns,
1246 const SparsitySetType& sparsity);
1248 virtual void generateHessianSparsitySource();
1251 static inline std::map<size_t, std::vector<std::set<size_t> > > determineOrderByCol(
const std::map<
size_t, std::vector<size_t> >& elements,
1252 const LocalSparsityInfo& sparsity);
1254 static inline std::map<size_t, std::vector<std::set<size_t> > > determineOrderByCol(
const std::map<
size_t, std::vector<size_t> >& elements,
1255 const std::vector<size_t>& userRows,
1256 const std::vector<size_t>& userCols);
1258 static inline std::vector<std::set<size_t> > determineOrderByCol(
size_t col,
1259 const std::vector<size_t>& colElements,
1260 const std::vector<size_t>& userRows,
1261 const std::vector<size_t>& userCols);
1263 static inline std::map<size_t, std::vector<std::set<size_t> > > determineOrderByRow(
const std::map<
size_t, std::vector<size_t> >& elements,
1264 const LocalSparsityInfo& sparsity);
1266 static inline std::map<size_t, std::vector<std::set<size_t> > > determineOrderByRow(
const std::map<
size_t, std::vector<size_t> >& elements,
1267 const std::vector<size_t>& userRows,
1268 const std::vector<size_t>& userCols);
1270 static inline std::vector<std::set<size_t> > determineOrderByRow(
size_t row,
1271 const std::vector<size_t>& rowsElements,
1272 const std::vector<size_t>& userRows,
1273 const std::vector<size_t>& userCols);
1282 static void printFileStartPThreads(std::ostringstream& cache,
1283 const std::string& baseTypeName);
1285 static void printFunctionStartPThreads(std::ostringstream& cache,
1288 static void printFunctionEndPThreads(std::ostringstream& cache,
1291 static void printFileStartOpenMP(std::ostringstream& cache);
1293 static void printFunctionStartOpenMP(std::ostringstream& cache,
1296 static void printLoopStartOpenMP(std::ostringstream& cache,
1299 static void printLoopEndOpenMP(std::ostringstream& cache,
1305 inline void startingJob(
const std::string& jobName,
1306 const JobType& type = JobTypeHolder<>::DEFAULT);
1308 inline void finishedJob();
1311 ModelLibraryCSourceGen<Base>;
1314 ModelLibraryProcessor<Base>;
std::map< size_t, std::set< size_t > > row2Columns
maps row indexes to the corresponding columns
std::set< size_t > rows
all row with this color
std::set< size_t > forbiddenRows
used columns
std::map< size_t, size_t > column2Row
maps column indexes to the corresponding row
virtual void prepareSparseReverseOneWithLoops(const std::map< size_t, std::vector< size_t > > &elements)
bool isMultiThreading() const
void setCustomSparseJacobianElements(const VectorSet &elements)
virtual void generateGlobalDirectionalFunctionSource(const std::string &function, const std::string &function2_suffix, const std::string &function_sparsity, const std::map< size_t, std::vector< size_t > > &elements)
virtual std::vector< CGBase > prepareSparseJacobianWithLoops(CodeHandler< Base > &handler, const std::vector< CGBase > &x, bool forward)
virtual std::string generateSparseJacobianForRevMultiThreadSource(const std::string &functionName, std::map< size_t, CompressedVectorInfo > jacInfo, size_t maxCompressedSize, const std::string &functionRevFor, const std::string &revForSuffix, bool forward, MultiThreadingType multiThreadingType)
virtual std::vector< CGBase > prepareForward0WithLoops(CodeHandler< Base > &handler, const std::vector< CGBase > &x)
void analyseSparseHessianWithLoops(const std::vector< size_t > &lowerHessRows, const std::vector< size_t > &lowerHessCols, const std::vector< size_t > &lowerHessOrder, SparsitySetType &noLoopEvalJacSparsity, SparsitySetType &noLoopEvalHessSparsity, std::vector< std::map< size_t, std::set< size_t > > > &noLoopEvalHessLocations, std::map< LoopModel< Base > *, loops::HessianWithLoopsInfo< Base > > &loopHessInfo, bool useSymmetry)
virtual std::string generateSparseHessianRev2MultiThreadSource(const std::string &functionName, std::map< size_t, CompressedVectorInfo > hessInfo, size_t maxCompressedSize, const std::string &functionRev2, const std::string &rev2Suffix, MultiThreadingType multiThreadingType)
virtual void determineSecondOrderElements4Eval(std::vector< size_t > &userRows, std::vector< size_t > &userCols)
void prepareSparseJacobianRowWithLoops(CodeHandler< Base > &handler, LoopModel< Base > &lModel, size_t tapeI, const loops::JacobianWithLoopsRowInfo &rowInfo, const std::vector< std::map< size_t, CGBase > > &dyiDxtape, const std::vector< std::map< size_t, CGBase > > &dzDx, const CGBase &py, IndexOperationNode< Base > &iterationIndexOp, std::vector< loops::IfElseInfo< Base > > &ifElses, size_t &jacLE, std::vector< std::pair< CG< Base >, IndexPattern * > > &indexedLoopResults, std::set< size_t > &allLocations)
bool isCreateReverseTwo() const
ModelCSourceGen(ADFun< CppAD::cg::CG< Base > > &fun, std::string model)
bool isCreateHessianSparsityByEquation() const
void setCreateReverseTwo(bool create)
virtual void generateSparseForwardOneSourcesWithAtomics(const std::map< size_t, std::vector< size_t > > &elements)
std::vector< std::string > _atomicFunctions
bool isSparseHessianReusesRev2() const
bool _forwardOne
generate source code for forward first order mode
virtual void generateSparseForwardOneSources()
bool isCreateReverseOne() const
void setMaxAssignmentsPerFunc(size_t maxAssignPerFunc)
virtual void generateSparseHessianWithLoopsSourceFromRev2(const std::map< size_t, CompressedVectorInfo > &hessInfo, size_t maxCompressedSize)
void setCreateSparseHessian(bool create)
virtual void prepareSparseForwardOneWithLoops(const std::map< size_t, std::vector< size_t > > &elements)
virtual void determineHessianSparsity()
LoopFreeModel< Base > * _funNoLoops
virtual void generateSparseReverseTwoSourcesNoAtomics(const std::map< size_t, std::vector< size_t > > &elements, const std::vector< size_t > &evalRows, const std::vector< size_t > &evalCols)
void setCreateForwardOne(bool create)
void setCustomSparseHessianElements(const VectorSet &elements)
void setCustomSparseHessianElements(const std::vector< size_t > &row, const std::vector< size_t > &col)
void setSparseJacobianReuse1stOrderPasses(bool reuse)
size_t _maxOperationsPerAssignment
std::map< LoopModel< Base > *, std::map< size_t, std::map< size_t, std::set< size_t > > > > _loopFor1Groups
void setJacobianADMode(JacobianADMode mode)
virtual void generateSparseReverseOneSources()
void setTypicalIndependentValues(const VectorBase &x)
bool isSparseJacobianReuse1stOrderPasses() const
bool _sparseHessianReusesRev2
bool isCreateHessian() const
void setCreateSparseJacobian(bool create)
std::ostringstream _cache
virtual std::vector< CGBase > prepareSparseHessianWithLoops(CodeHandler< Base > &handler, std::vector< CGBase > &indVars, std::vector< CGBase > &w, const std::vector< size_t > &lowerHessRows, const std::vector< size_t > &lowerHessCols, const std::vector< size_t > &lowerHessOrder, const std::map< size_t, size_t > &duplicates)
std::map< size_t, AtomicUseInfo< Base > > * _atomicsInfo
size_t getMaxAssignmentsPerFunc() const
std::map< size_t, std::set< size_t > > _nonLoopRev1Elements
bool isCreateSparseForwardOne() const
void setMaxOperationsPerAssignment(size_t maxOperationsPerAssignment)
virtual void generateSparseJacobianWithLoopsSourceFromForRev(const std::map< size_t, CompressedVectorInfo > &jacInfo, size_t maxCompressedSize, const std::string &localFunctionTypeName, const std::string &suffix, const std::string &keyName, const std::map< size_t, std::set< size_t > > &nonLoopElements, const std::map< LoopModel< Base > *, std::map< size_t, std::map< size_t, std::set< size_t > > > > &loopGroups, void(*generateLocalFunctionName)(std::ostringstream &cache, const std::string &modelName, const LoopModel< Base > &loop, size_t g))
virtual void setParameterPrecision(size_t p)
virtual void generateSparseHessianSourceFromRev2(MultiThreadingType multiThreadingType)
void setCreateReverseOne(bool create)
bool isCreateSparseJacobian() const
virtual void generateSparseForwardOneSourcesNoAtomics(const std::map< size_t, std::vector< size_t > > &elements)
bool _zero
generate source code for the zero order model evaluation
std::map< size_t, std::set< size_t > > _nonLoopRev2Elements
bool _sparseHessian
generate source code for a sparse Hessian
std::map< size_t, std::set< size_t > > _nonLoopFor1Elements
const std::string _baseTypeName
size_t _parameterPrecision
virtual void generateSparseReverseTwoSources()
virtual void generateSparseJacobianSource(MultiThreadingType multiThreadingType)
JacobianADMode getJacobianADMode() const
void setCreateJacobian(bool create)
void setCustomSparseJacobianElements(const std::vector< size_t > &row, const std::vector< size_t > &col)
std::map< LoopModel< Base > *, std::map< size_t, std::map< size_t, std::set< size_t > > > > _loopRev1Groups
virtual void generateSparseReverseOneSourcesWithAtomics(const std::map< size_t, std::vector< size_t > > &elements)
virtual void generateSparseHessianSourceDirectly()
bool _sparseJacobianReusesOne
void analyseSparseJacobianWithLoops(const std::vector< size_t > &rows, const std::vector< size_t > &cols, const std::vector< size_t > &location, SparsitySetType &noLoopEvalSparsity, std::vector< std::map< size_t, std::set< size_t > > > &noLoopEvalLocations, std::map< LoopModel< Base > *, SparsitySetType > &loopsEvalSparsities, std::map< LoopModel< Base > *, std::vector< loops::JacobianWithLoopsRowInfo > > &loopEqInfo)
bool _sparseJacobian
generate source code for a sparse Jacobian
void setSparseHessianReusesRev2(bool reuse)
void setCreateForwardZero(bool create)
bool _reverseTwo
generate source code for reverse second order mode
virtual void generateSparseReverseOneSourcesNoAtomics(const std::map< size_t, std::vector< size_t > > &elements)
const std::string & getName() const
void setCreateHessian(bool create)
virtual void determineJacobianSparsity()
std::set< LoopModel< Base > * > _loopTapes
bool isCreateForwardZero() const
bool _jacobian
generate source code for a dense Jacobian
virtual void prepareSparseReverseTwoWithLoops(const std::map< size_t, std::vector< size_t > > &elements)
virtual void generateSparseJacobianForRevSource(bool forward, MultiThreadingType multiThreadingType)
std::map< LoopModel< Base > *, std::map< size_t, std::map< size_t, std::set< size_t > > > > _loopRev2Groups
virtual size_t getParameterPrecision() const
bool _reverseOne
generate source code for reverse first order mode
bool isCreateSparseHessian() const
std::vector< LocalSparsityInfo > _hessSparsities
void setCreateHessianSparsityByEquation(bool create)
size_t getMaxOperationsPerAssignment() const
void setMultiThreading(bool multiThreading)
std::map< std::string, std::string > _sources
bool _hessian
generate source code for a dense Hessian
virtual void generateSparseHessianSource(MultiThreadingType multiThreadingType)
std::vector< ModelCSourceGen< Base >::Color > colorByRow(const std::set< size_t > &columns, const SparsitySetType &sparsity)
virtual void generateZeroSource()
bool isCreateJacobian() const