1 #ifndef CPPAD_CG_MODEL_C_SOURCE_GEN_INCLUDED 2 #define CPPAD_CG_MODEL_C_SOURCE_GEN_INCLUDED 26 std::vector<std::set<size_t> > locations;
27 std::vector<size_t> indexes;
40 using SparsitySetType = std::vector<std::set<size_t> >;
41 using TapeVarType = std::pair<size_t, size_t>;
43 static const std::string FUNCTION_FORWAD_ZERO;
44 static const std::string FUNCTION_JACOBIAN;
45 static const std::string FUNCTION_HESSIAN;
46 static const std::string FUNCTION_FORWARD_ONE;
47 static const std::string FUNCTION_REVERSE_ONE;
48 static const std::string FUNCTION_REVERSE_TWO;
49 static const std::string FUNCTION_SPARSE_JACOBIAN;
50 static const std::string FUNCTION_SPARSE_HESSIAN;
51 static const std::string FUNCTION_JACOBIAN_SPARSITY;
52 static const std::string FUNCTION_HESSIAN_SPARSITY;
53 static const std::string FUNCTION_HESSIAN_SPARSITY2;
54 static const std::string FUNCTION_SPARSE_FORWARD_ONE;
55 static const std::string FUNCTION_SPARSE_REVERSE_ONE;
56 static const std::string FUNCTION_SPARSE_REVERSE_TWO;
57 static const std::string FUNCTION_FORWARD_ONE_SPARSITY;
58 static const std::string FUNCTION_REVERSE_ONE_SPARSITY;
59 static const std::string FUNCTION_REVERSE_TWO_SPARSITY;
60 static const std::string FUNCTION_INFO;
61 static const std::string FUNCTION_ATOMIC_FUNC_NAMES;
63 static const std::string CONST;
71 std::vector<size_t> row;
72 std::vector<size_t> col;
78 inline Position(
const std::vector<size_t>& r,
const std::vector<size_t>& c) :
82 CPPADCG_ASSERT_KNOWN(r.size() == c.size(),
"The number of row indexes must be the same as the number of column indexes.");
85 template<
class VectorSet>
86 inline Position(
const VectorSet& elements) :
89 for (
size_t i = 0; i < elements.size(); i++) {
90 nnz += elements[i].size();
96 for (
size_t i = 0; i < elements.size(); i++) {
97 for (
size_t it : elements[i]) {
117 std::vector<size_t> rows;
119 std::vector<size_t> cols;
166 std::vector<Base>
_x;
205 JacobianADMode _jacMode;
239 std::vector<std::set<size_t> > _relatedDepCandidates;
244 std::map<LoopModel<Base>*, std::map<size_t, std::map<size_t, std::set<size_t> > > >
_loopFor1Groups;
254 std::map<LoopModel<Base>*, std::map<size_t, std::map<size_t, std::set<size_t> > > >
_loopRev1Groups;
264 std::map<LoopModel<Base>*, std::map<size_t, std::map<size_t, std::set<size_t> > > >
_loopRev2Groups;
288 const std::string& model) :
290 _funNoLoops(nullptr),
293 _parameterPrecision(
std::numeric_limits<Base>::digits10),
294 _multiThreading(true),
296 _zeroEvaluated(false),
299 _sparseJacobian(false),
300 _sparseHessian(false),
301 _hessianByEquation(false),
305 _sparseJacobianReusesOne(true),
306 _sparseHessianReusesRev2(true),
307 _jacMode(JacobianADMode::Automatic),
308 _atomicsInfo(nullptr),
309 _maxAssignPerFunc(20000),
312 CPPADCG_ASSERT_KNOWN(!_name.empty(),
"Model name cannot be empty");
313 CPPADCG_ASSERT_KNOWN((_name[0] >=
'a' && _name[0] <=
'z') ||
314 (_name[0] >=
'A' && _name[0] <=
'Z'),
315 "Invalid model name character");
316 for (
size_t i = 1; i < _name.size(); i++) {
318 CPPADCG_ASSERT_KNOWN((c >=
'a' && c <=
'z') ||
319 (c >=
'A' && c <=
'Z') ||
320 (c >=
'0' && c <=
'9') ||
322 ,
"Invalid model name character");
346 template<
class VectorBase>
348 CPPAD_ASSERT_KNOWN(x.size() == 0 || x.size() == _fun.Domain(),
349 "Invalid independent variable vector size");
351 for (
size_t i = 0; i < x.size(); i++) {
356 inline void setRelatedDependents(
const std::vector<std::set<size_t> >& relatedDepCandidates) {
357 _relatedDepCandidates = relatedDepCandidates;
360 inline const std::vector<std::set<size_t> >& getRelatedDependents()
const {
361 return _relatedDepCandidates;
371 return _parameterPrecision;
381 _parameterPrecision = p;
397 return _multiThreading;
414 _multiThreading = multiThreading;
417 inline bool isJacobianMultiThreadingEnabled()
const {
418 return _multiThreading && _loopTapes.empty() && _sparseJacobian && _sparseJacobianReusesOne && (_forwardOne || _reverseOne);
421 inline bool isHessianMultiThreadingEnabled()
const {
422 return _multiThreading && _loopTapes.empty() && _sparseHessian && _sparseHessianReusesRev2 && _reverseTwo;
508 return _sparseHessian;
530 _sparseHessian = create;
543 return _sparseHessianReusesRev2;
556 _sparseHessianReusesRev2 = reuse;
570 return _hessianByEquation;
584 _hessianByEquation = create;
602 return _sparseJacobian;
620 _sparseJacobian = create;
634 return _sparseJacobianReusesOne;
649 _sparseJacobianReusesOne = reuse;
707 _forwardOne = create;
743 _reverseOne = create;
783 _reverseTwo = create;
786 inline void setCustomSparseJacobianElements(
const std::vector<size_t>& row,
787 const std::vector<size_t>& col) {
791 template<
class VectorSet>
792 inline void setCustomSparseJacobianElements(
const VectorSet& elements) {
796 inline void setCustomSparseHessianElements(
const std::vector<size_t>& row,
797 const std::vector<size_t>& col) {
801 template<
class VectorSet>
802 inline void setCustomSparseHessianElements(
const VectorSet& elements) {
806 inline size_t getMaxAssignmentsPerFunc()
const {
807 return _maxAssignPerFunc;
810 inline void setMaxAssignmentsPerFunc(
size_t maxAssignPerFunc) {
811 _maxAssignPerFunc = maxAssignPerFunc;
824 static inline std::string baseTypeName();
827 static void generateFunctionDeclarationSource(std::ostringstream& cache,
828 const std::string& model_function,
829 const std::string& suffix,
830 const std::map<size_t, T>& elements,
831 const std::string& argsDcl);
836 const std::string& indepName =
"x",
837 const std::string& tmpName =
"v",
838 const std::string& tmpArrayName =
"array");
840 const std::map<std::string, std::string>& getSources(MultiThreadingType multiThreadingType,
843 virtual void generateSources(MultiThreadingType multiThreadingType,
846 virtual void generateLoops();
848 virtual void generateInfoSource();
850 virtual void generateAtomicFuncNames();
852 virtual bool isAtomicsUsed();
854 virtual const std::map<size_t, AtomicUseInfo<Base> >& getAtomicsInfo();
860 virtual void generateZeroSource();
866 const std::vector<CGBase>& x);
872 virtual void generateJacobianSource();
874 virtual void generateSparseJacobianSource(MultiThreadingType multiThreadingType);
876 virtual void generateSparseJacobianSource(
bool forward);
878 virtual void generateSparseJacobianForRevSource(
bool forward,
879 MultiThreadingType multiThreadingType);
881 virtual std::string generateSparseJacobianForRevSingleThreadSource(
const std::string& functionName,
882 std::map<size_t, CompressedVectorInfo> jacInfo,
883 size_t maxCompressedSize,
884 const std::string& functionRevFor,
885 const std::string& revForSuffix,
888 virtual std::string generateSparseJacobianForRevMultiThreadSource(
const std::string& functionName,
889 std::map<size_t, CompressedVectorInfo> jacInfo,
890 size_t maxCompressedSize,
891 const std::string& functionRevFor,
892 const std::string& revForSuffix,
894 MultiThreadingType multiThreadingType);
916 virtual std::vector<CGBase> prepareSparseJacobianWithLoops(
CodeHandler<Base>& handler,
917 const std::vector<CGBase>& x,
924 const std::vector<std::map<size_t, CGBase> >& dyiDxtape,
925 const std::vector<std::map<size_t, CGBase> >& dzDx,
931 std::set<size_t>& allLocations);
933 inline void analyseSparseJacobianWithLoops(
const std::vector<size_t>& rows,
934 const std::vector<size_t>& cols,
935 const std::vector<size_t>& location,
936 SparsitySetType& noLoopEvalSparsity,
937 std::vector<std::map<
size_t, std::set<size_t> > >& noLoopEvalLocations,
939 std::map<
LoopModel<Base>*, std::vector<loops::JacobianWithLoopsRowInfo> >& loopEqInfo);
942 virtual void generateSparseJacobianWithLoopsSourceFromForRev(
const std::map<size_t, CompressedVectorInfo>& jacInfo,
943 size_t maxCompressedSize,
944 const std::string& localFunctionTypeName,
945 const std::string& suffix,
946 const std::string& keyName,
947 const std::map<
size_t, std::set<size_t> >& nonLoopElements,
948 const std::map<
LoopModel<Base>*, std::map<
size_t, std::map<
size_t, std::set<size_t> > > >& loopGroups,
949 void (*generateLocalFunctionName)(std::ostringstream& cache,
const std::string& modelName,
const LoopModel<Base>& loop,
size_t g));
951 inline virtual void generateFunctionNameLoopFor1(std::ostringstream& cache,
955 inline static void generateFunctionNameLoopFor1(std::ostringstream& cache,
956 const std::string& modelName,
960 inline virtual void generateFunctionNameLoopRev1(std::ostringstream& cache,
964 inline static void generateFunctionNameLoopRev1(std::ostringstream& cache,
965 const std::string& modelName,
973 virtual void generateHessianSource();
975 virtual void generateSparseHessianSource(MultiThreadingType multiThreadingType);
977 virtual void generateSparseHessianSourceDirectly();
979 virtual void generateSparseHessianSourceFromRev2(MultiThreadingType multiThreadingType);
981 virtual std::string generateSparseHessianRev2SingleThreadSource(
const std::string& functionName,
982 std::map<size_t, CompressedVectorInfo> hessInfo,
983 size_t maxCompressedSize,
984 const std::string& functionRev2,
985 const std::string& rev2Suffix);
987 virtual std::string generateSparseHessianRev2MultiThreadSource(
const std::string& functionName,
988 std::map<size_t, CompressedVectorInfo> hessInfo,
989 size_t maxCompressedSize,
990 const std::string& functionRev2,
991 const std::string& rev2Suffix,
992 MultiThreadingType multiThreadingType);
994 virtual void determineSecondOrderElements4Eval(std::vector<size_t>& userRows,
995 std::vector<size_t>& userCols);
1023 virtual std::vector<CGBase> prepareSparseHessianWithLoops(
CodeHandler<Base>& handler,
1024 std::vector<CGBase>& indVars,
1025 std::vector<CGBase>& w,
1026 const std::vector<size_t>& lowerHessRows,
1027 const std::vector<size_t>& lowerHessCols,
1028 const std::vector<size_t>& lowerHessOrder,
1029 const std::map<size_t, size_t>& duplicates);
1031 inline void analyseSparseHessianWithLoops(
const std::vector<size_t>& lowerHessRows,
1032 const std::vector<size_t>& lowerHessCols,
1033 const std::vector<size_t>& lowerHessOrder,
1034 SparsitySetType& noLoopEvalJacSparsity,
1035 SparsitySetType& noLoopEvalHessSparsity,
1036 std::vector<std::map<
size_t, std::set<size_t> > >& noLoopEvalHessLocations,
1040 inline virtual void generateSparseHessianWithLoopsSourceFromRev2(
const std::map<size_t, CompressedVectorInfo>& hessInfo,
1041 size_t maxCompressedSize);
1043 inline virtual void generateFunctionNameLoopRev2(std::ostringstream& cache,
1047 static inline void generateFunctionNameLoopRev2(std::ostringstream& cache,
1048 const std::string& modelName,
1056 virtual void generateSparsity1DSource(
const std::string&
function,
1057 const std::vector<size_t>& sparsity);
1059 virtual void generateSparsity2DSource(
const std::string&
function,
1062 virtual void generateSparsity2DSource2(
const std::string&
function,
1063 const std::vector<LocalSparsityInfo>& sparsities);
1065 virtual void generateSparsity1DSource2(
const std::string&
function,
1066 const std::map<
size_t, std::vector<size_t> >& rows);
1072 virtual void generateSparseForwardOneSources();
1074 virtual void generateSparseForwardOneSourcesWithAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1076 virtual void generateSparseForwardOneSourcesNoAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1078 virtual void generateForwardOneSources();
1080 virtual void prepareSparseForwardOneWithLoops(
const std::map<
size_t, std::vector<size_t> >& elements);
1087 inline static std::map<size_t, std::map<size_t, CG<Base> > > generateLoopFor1Jac(
ADFun<CGBase>& fun,
1088 const SparsitySetType& sparsity,
1089 const SparsitySetType& evalSparsity,
1090 const std::vector<CGBase>& xl,
1091 bool constainsAtomics);
1097 virtual void generateSparseReverseOneSources();
1099 virtual void generateSparseReverseOneSourcesWithAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1101 virtual void generateSparseReverseOneSourcesNoAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1103 virtual void generateReverseOneSources();
1105 virtual void prepareSparseReverseOneWithLoops(
const std::map<
size_t, std::vector<size_t> >& elements);
1111 inline static std::vector<std::map<size_t, CGBase> > generateLoopRev1Jac(
ADFun<CGBase>& fun,
1112 const SparsitySetType& sparsity,
1113 const SparsitySetType& evalSparsity,
1114 const std::vector<CGBase>& xl,
1115 bool constainsAtomics);
1121 virtual void generateSparseReverseTwoSources();
1123 virtual void generateSparseReverseTwoSourcesWithAtomics(
const std::map<
size_t, std::vector<size_t> >& elements);
1125 virtual void generateSparseReverseTwoSourcesNoAtomics(
const std::map<
size_t, std::vector<size_t> >& elements,
1126 const std::vector<size_t>& evalRows,
1127 const std::vector<size_t>& evalCols);
1129 virtual void generateReverseTwoSources();
1131 virtual void generateGlobalDirectionalFunctionSource(
const std::string&
function,
1132 const std::string& function2_suffix,
1133 const std::string& function_sparsity,
1134 const std::map<
size_t, std::vector<size_t> >& elements);
1139 virtual void prepareSparseReverseTwoWithLoops(
const std::map<
size_t, std::vector<size_t> >& elements);
1145 virtual void determineJacobianSparsity();
1147 virtual void generateJacobianSparsitySource();
1149 virtual void determineHessianSparsity();
1160 inline std::vector<ModelCSourceGen<Base>::Color> colorByRow(
const std::set<size_t>& columns,
1161 const SparsitySetType& sparsity);
1163 virtual void generateHessianSparsitySource();
1166 static inline std::map<size_t, std::vector<std::set<size_t> > > determineOrderByCol(
const std::map<
size_t, std::vector<size_t> >& elements,
1169 static inline std::map<size_t, std::vector<std::set<size_t> > > determineOrderByCol(
const std::map<
size_t, std::vector<size_t> >& elements,
1170 const std::vector<size_t>& userRows,
1171 const std::vector<size_t>& userCols);
1173 static inline std::vector<std::set<size_t> > determineOrderByCol(
size_t col,
1174 const std::vector<size_t>& colElements,
1175 const std::vector<size_t>& userRows,
1176 const std::vector<size_t>& userCols);
1178 static inline std::map<size_t, std::vector<std::set<size_t> > > determineOrderByRow(
const std::map<
size_t, std::vector<size_t> >& elements,
1181 static inline std::map<size_t, std::vector<std::set<size_t> > > determineOrderByRow(
const std::map<
size_t, std::vector<size_t> >& elements,
1182 const std::vector<size_t>& userRows,
1183 const std::vector<size_t>& userCols);
1185 static inline std::vector<std::set<size_t> > determineOrderByRow(
size_t row,
1186 const std::vector<size_t>& rowsElements,
1187 const std::vector<size_t>& userRows,
1188 const std::vector<size_t>& userCols);
1197 static void printFileStartPThreads(std::ostringstream& cache,
1198 const std::string& baseTypeName);
1200 static void printFunctionStartPThreads(std::ostringstream& cache,
1203 static void printFunctionEndPThreads(std::ostringstream& cache,
1206 static void printFileStartOpenMP(std::ostringstream& cache);
1208 static void printFunctionStartOpenMP(std::ostringstream& cache,
1211 static void printLoopStartOpenMP(std::ostringstream& cache,
1214 static void printLoopEndOpenMP(std::ostringstream& cache,
1220 inline void startingJob(
const std::string& jobName,
1223 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
ModelCSourceGen(ADFun< CppAD::cg::CG< Base > > &fun, const std::string &model)
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
bool isCreateReverseTwo() const
std::map< size_t, std::set< size_t > > _nonLoopRev1Elements
std::map< size_t, std::set< size_t > > _nonLoopRev2Elements
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
bool isCreateForwardZero() const
void setTypicalIndependentValues(const VectorBase &x)
std::map< size_t, std::set< size_t > > _nonLoopFor1Elements
void setCreateReverseTwo(bool create)
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 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)
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