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;
295 _funNoLoops(nullptr),
296 _name(
std::move(model)),
298 _parameterPrecision(
std::numeric_limits<Base>::digits10),
299 _multiThreading(true),
301 _zeroEvaluated(false),
304 _sparseJacobian(false),
305 _sparseHessian(false),
306 _hessianByEquation(false),
310 _sparseJacobianReusesOne(true),
311 _sparseHessianReusesRev2(true),
312 _jacMode(JacobianADMode::Automatic),
313 _atomicsInfo(nullptr),
314 _maxAssignPerFunc(20000),
315 _maxOperationsPerAssignment(1000),
318 CPPADCG_ASSERT_KNOWN(!_name.empty(),
"Model name cannot be empty")
319 CPPADCG_ASSERT_KNOWN((_name[0] >=
'a' && _name[0] <=
'z') ||
320 (_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;
377 return _parameterPrecision;
387 _parameterPrecision = p;
403 return _multiThreading;
420 _multiThreading = multiThreading;
423 inline bool isJacobianMultiThreadingEnabled()
const {
424 return _multiThreading && _loopTapes.empty() && _sparseJacobian && _sparseJacobianReusesOne && (_forwardOne || _reverseOne);
427 inline bool isHessianMultiThreadingEnabled()
const {
428 return _multiThreading && _loopTapes.empty() && _sparseHessian && _sparseHessianReusesRev2 && _reverseTwo;
514 return _sparseHessian;
536 _sparseHessian = create;
549 return _sparseHessianReusesRev2;
562 _sparseHessianReusesRev2 = reuse;
576 return _hessianByEquation;
590 _hessianByEquation = create;
608 return _sparseJacobian;
626 _sparseJacobian = create;
640 return _sparseJacobianReusesOne;
655 _sparseJacobianReusesOne = reuse;
713 _forwardOne = create;
749 _reverseOne = create;
789 _reverseTwo = create;
803 const std::vector<size_t>& col) {
816 template<
class VectorSet>
834 const std::vector<size_t>& col) {
849 template<
class VectorSet>
863 return _maxAssignPerFunc;
877 _maxAssignPerFunc = maxAssignPerFunc;
886 return _maxOperationsPerAssignment;
896 _maxOperationsPerAssignment = maxOperationsPerAssignment;
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);
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,
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();
945 virtual void generateZeroSource();
951 const std::vector<CGBase>& x);
957 virtual void generateJacobianSource();
959 virtual void generateSparseJacobianSource(MultiThreadingType multiThreadingType);
961 virtual void generateSparseJacobianSource(
bool forward);
963 virtual void generateSparseJacobianForRevSource(
bool forward,
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,
973 virtual std::string generateSparseJacobianForRevMultiThreadSource(
const std::string& functionName,
974 std::map<size_t, CompressedVectorInfo> jacInfo,
975 size_t maxCompressedSize,
976 const std::string& functionRevFor,
977 const std::string& revForSuffix,
979 MultiThreadingType multiThreadingType);
1001 virtual std::vector<CGBase> prepareSparseJacobianWithLoops(
CodeHandler<Base>& handler,
1002 const std::vector<CGBase>& x,
1009 const std::vector<std::map<size_t, CGBase> >& dyiDxtape,
1010 const std::vector<std::map<size_t, CGBase> >& dzDx,
1016 std::set<size_t>& allLocations);
1018 inline void analyseSparseJacobianWithLoops(
const std::vector<size_t>& rows,
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,
1024 std::map<
LoopModel<Base>*, std::vector<loops::JacobianWithLoopsRowInfo> >& loopEqInfo);
1027 virtual void generateSparseJacobianWithLoopsSourceFromForRev(
const std::map<size_t, CompressedVectorInfo>& jacInfo,
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,
1040 inline static void generateFunctionNameLoopFor1(std::ostringstream& cache,
1041 const std::string& modelName,
1045 inline virtual void generateFunctionNameLoopRev1(std::ostringstream& cache,
1049 inline static void generateFunctionNameLoopRev1(std::ostringstream& cache,
1050 const std::string& modelName,
1058 virtual void generateHessianSource();
1060 virtual void generateSparseHessianSource(MultiThreadingType multiThreadingType);
1062 virtual void generateSparseHessianSourceDirectly();
1064 virtual void generateSparseHessianSourceFromRev2(MultiThreadingType multiThreadingType);
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);
1072 virtual std::string generateSparseHessianRev2MultiThreadSource(
const std::string& functionName,
1073 std::map<size_t, CompressedVectorInfo> hessInfo,
1074 size_t maxCompressedSize,
1075 const std::string& functionRev2,
1076 const std::string& rev2Suffix,
1077 MultiThreadingType multiThreadingType);
1079 virtual void determineSecondOrderElements4Eval(std::vector<size_t>& userRows,
1080 std::vector<size_t>& userCols);
1108 virtual std::vector<CGBase> prepareSparseHessianWithLoops(
CodeHandler<Base>& handler,
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);
1116 inline void analyseSparseHessianWithLoops(
const std::vector<size_t>& lowerHessRows,
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,
1125 inline virtual void generateSparseHessianWithLoopsSourceFromRev2(
const std::map<size_t, CompressedVectorInfo>& hessInfo,
1126 size_t maxCompressedSize);
1128 inline virtual void generateFunctionNameLoopRev2(std::ostringstream& cache,
1132 static inline void generateFunctionNameLoopRev2(std::ostringstream& cache,
1133 const std::string& modelName,
1141 virtual void generateSparsity1DSource(
const std::string&
function,
1142 const std::vector<size_t>& sparsity);
1144 virtual void generateSparsity2DSource(
const std::string&
function,
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);
1157 virtual void generateSparseForwardOneSources();
1159 virtual void generateSparseForwardOneSourcesWithAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1161 virtual void generateSparseForwardOneSourcesNoAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1163 virtual void generateForwardOneSources();
1165 virtual void prepareSparseForwardOneWithLoops(
const std::map<
size_t, std::vector<size_t> >& elements);
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);
1182 virtual void generateSparseReverseOneSources();
1184 virtual void generateSparseReverseOneSourcesWithAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1186 virtual void generateSparseReverseOneSourcesNoAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1188 virtual void generateReverseOneSources();
1190 virtual void prepareSparseReverseOneWithLoops(
const std::map<
size_t, std::vector<size_t> >& elements);
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);
1206 virtual void generateSparseReverseTwoSources();
1208 virtual void generateSparseReverseTwoSourcesWithAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1210 virtual void generateSparseReverseTwoSourcesNoAtomics(
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();
1216 virtual void generateGlobalDirectionalFunctionSource(
const std::string&
function,
1217 const std::string& function2_suffix,
1218 const std::string& function_sparsity,
1219 const std::map<
size_t, std::vector<size_t> >& elements);
1224 virtual void prepareSparseReverseTwoWithLoops(
const std::map<
size_t, std::vector<size_t> >& elements);
1230 virtual void determineJacobianSparsity();
1232 virtual void generateJacobianSparsitySource();
1234 virtual void determineHessianSparsity();
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,
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,
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,
1308 inline void finishedJob();
bool _reverseTwo
generate source code for reverse second order mode
bool _sparseJacobian
generate source code for a sparse Jacobian
bool isCreateSparseForwardOne() const
bool isCreateReverseOne() const
std::set< size_t > rows
all row with this color
virtual size_t getParameterPrecision() const
bool isSparseJacobianReuse1stOrderPasses() const
std::vector< std::string > _atomicFunctions
const std::string _baseTypeName
std::map< size_t, std::set< size_t > > row2Columns
maps row indexes to the corresponding columns
std::ostringstream _cache
void setMaxOperationsPerAssignment(size_t maxOperationsPerAssignment)
bool _sparseHessian
generate source code for a sparse Hessian
const std::string & getName() const
bool _sparseJacobianReusesOne
void setCreateForwardZero(bool create)
std::set< LoopModel< Base > * > _loopTapes
void setCreateReverseOne(bool create)
bool _reverseOne
generate source code for reverse first order mode
LoopFreeModel< Base > * _funNoLoops
void setCreateJacobian(bool create)
std::map< size_t, size_t > column2Row
maps column indexes to the corresponding row
size_t _parameterPrecision
JacobianADMode getJacobianADMode() const
size_t getMaxOperationsPerAssignment() const
bool isCreateReverseTwo() const
std::map< size_t, std::set< size_t > > _nonLoopRev1Elements
void setMaxAssignmentsPerFunc(size_t maxAssignPerFunc)
std::map< size_t, std::set< size_t > > _nonLoopRev2Elements
void setCustomSparseHessianElements(const VectorSet &elements)
std::map< size_t, AtomicUseInfo< Base > > * _atomicsInfo
void setCreateSparseHessian(bool create)
std::map< LoopModel< Base > *, std::map< size_t, std::map< size_t, std::set< size_t > > > > _loopFor1Groups
std::vector< LocalSparsityInfo > _hessSparsities
bool isSparseHessianReusesRev2() const
void setMultiThreading(bool multiThreading)
std::map< LoopModel< Base > *, std::map< size_t, std::map< size_t, std::set< size_t > > > > _loopRev1Groups
void setCustomSparseJacobianElements(const VectorSet &elements)
bool isCreateForwardZero() const
void setTypicalIndependentValues(const VectorBase &x)
ModelCSourceGen(ADFun< CppAD::cg::CG< Base > > &fun, std::string model)
size_t _maxOperationsPerAssignment
std::map< size_t, std::set< size_t > > _nonLoopFor1Elements
void setCreateReverseTwo(bool create)
size_t getMaxAssignmentsPerFunc() const
bool isCreateSparseHessian() const
bool _zero
generate source code for the zero order model evaluation
bool _hessian
generate source code for a dense Hessian
bool _sparseHessianReusesRev2
bool isMultiThreading() const
bool _forwardOne
generate source code for forward first order mode
void setCreateSparseJacobian(bool create)
void setCustomSparseHessianElements(const std::vector< size_t > &row, const std::vector< size_t > &col)
void setSparseHessianReusesRev2(bool reuse)
void setSparseJacobianReuse1stOrderPasses(bool reuse)
void setCreateHessian(bool create)
std::map< std::string, std::string > _sources
virtual void setParameterPrecision(size_t p)
std::map< LoopModel< Base > *, std::map< size_t, std::map< size_t, std::set< size_t > > > > _loopRev2Groups
bool isCreateHessianSparsityByEquation() const
void setCreateHessianSparsityByEquation(bool create)
void setCustomSparseJacobianElements(const std::vector< size_t > &row, const std::vector< size_t > &col)
bool isCreateJacobian() const
void setJacobianADMode(JacobianADMode mode)
void setCreateForwardOne(bool create)
std::set< size_t > forbiddenRows
used columns
bool isCreateHessian() const
bool isCreateSparseJacobian() const
bool _jacobian
generate source code for a dense Jacobian