1#ifndef CPPAD_CG_MODEL_C_SOURCE_GEN_HES_INCLUDED
2#define CPPAD_CG_MODEL_C_SOURCE_GEN_HES_INCLUDED
22void ModelCSourceGen<Base>::generateHessianSource() {
25 const std::string
jobName =
"Hessian";
27 startingJob(
"'" +
jobName +
"'", JobTimer::GRAPH);
32 size_t m = _fun.Range();
33 size_t n = _fun.Domain();
40 for (
size_t i = 0;
i <
n;
i++) {
49 for (
size_t i = 0;
i < m;
i++) {
50 w[
i].setValue(Base(1.0));
57 for (
size_t i = 0;
i <
n;
i++) {
58 for (
size_t j = 0;
j <
i;
j++) {
59 hess[
i *
n +
j] = hess[
j *
n +
i];
66 langC.setMaxAssignmentsPerFunction(_maxAssignPerFunc, &_sources);
67 langC.setMaxOperationsPerAssignment(_maxOperationsPerAssignment);
68 langC.setParameterPrecision(_parameterPrecision);
69 langC.setGenerateFunction(_name +
"_" + FUNCTION_HESSIAN);
71 std::ostringstream
code;
72 std::unique_ptr<VariableNameGenerator<Base> > nameGen(createVariableNameGenerator(
"hess"));
83 determineHessianSparsity();
85 if (_sparseHessianReusesRev2 && _reverseTwo) {
88 generateSparseHessianSourceDirectly();
96 const std::string
jobName =
"sparse Hessian";
97 size_t m = _fun.Range();
98 size_t n = _fun.Domain();
107 std::map<size_t, std::map<size_t, size_t> > locations;
111 std::map<size_t, std::map<size_t, size_t> >::iterator
itJ1 = locations.find(
j1);
112 if (
itJ1 == locations.end()) {
113 locations[
j1][
j2] =
e;
115 std::map<size_t, size_t>&
j22e =
itJ1->second;
120 throw CGException(
"Repeated Hessian element requested: ",
j1,
" ",
j2);
132 std::map<size_t, std::map<size_t, size_t> >::const_iterator
itJ;
133 std::map<size_t, size_t>::const_iterator
itI;
140 itJ = locations.find(
j);
141 if (
itJ != locations.end()) {
143 if (
itI !=
itJ->second.end()) {
161 startingJob(
"'" +
jobName +
"'", JobTimer::GRAPH);
164 handler.setJobTimer(_jobTimer);
170 for (
size_t i = 0;
i <
n;
i++) {
179 for (
size_t i = 0;
i < m;
i++) {
180 w[
i].setValue(Base(1.0));
185 if (_loopTapes.empty()) {
190 work.color_method =
"cppad.general";
200 hess[
it2.first] = hess[
it2.second];
214 langC.setMaxAssignmentsPerFunction(_maxAssignPerFunc, &_sources);
215 langC.setMaxOperationsPerAssignment(_maxOperationsPerAssignment);
216 langC.setParameterPrecision(_parameterPrecision);
217 langC.setGenerateFunction(_name +
"_" + FUNCTION_SPARSE_HESSIAN);
219 std::ostringstream
code;
220 std::unique_ptr<VariableNameGenerator<Base> > nameGen(createVariableNameGenerator(
"hess"));
237 std::map<size_t, CompressedVectorInfo>
hessInfo;
254 const std::vector<size_t>&
els =
it.second.indexes;
255 const std::vector<set<size_t> >& location =
it.second.locations;
256 CPPADCG_ASSERT_UNKNOWN(
els.size() == location.size());
257 CPPADCG_ASSERT_UNKNOWN(
els.size() > 0);
261 for (
size_t e = 0;
e <
els.size();
e++) {
262 if (location[
e].size() > 1) {
284 if (!_loopTapes.empty()) {
292 string functionName = _name +
"_" + FUNCTION_SPARSE_HESSIAN;
293 string functionRev2 = _name +
"_" + FUNCTION_SPARSE_REVERSE_TWO;
306 std::map<size_t, CompressedVectorInfo>
hessInfo,
311 std::string
argsDcl =
langC.generateDefaultFunctionArgumentsDcl();
312 std::vector<std::string>
argsDcl2 =
langC.generateDefaultFunctionArgumentsDcl2();
315 _cache <<
"#include <stdlib.h>\n"
321 " " << _baseTypeName <<
" const * inLocal[3];\n"
322 " " << _baseTypeName <<
" inLocal1 = 1;\n"
323 " " << _baseTypeName <<
" * outLocal[1];\n";
327 _cache <<
" " << _baseTypeName <<
" * hess = out[0];\n"
329 " inLocal[0] = in[0];\n"
330 " inLocal[1] = &inLocal1;\n"
331 " inLocal[2] = in[1];\n";
333 _cache <<
" outLocal[0] = compressed;";
336 langC.setArgumentIn(
"inLocal");
337 langC.setArgumentOut(
"outLocal");
341 size_t index =
it.first;
342 const std::vector<size_t>&
els =
it.second.indexes;
343 const std::vector<std::set<size_t> >& location =
it.second.locations;
344 CPPADCG_ASSERT_UNKNOWN(
els.size() == location.size());
345 CPPADCG_ASSERT_UNKNOWN(
els.size() > 0);
350 _cache <<
" outLocal[0] = &hess[" << *location[0].begin() <<
"];\n";
352 _cache <<
" outLocal[0] = compressed;\n";
356 for (
size_t e = 0;
e <
els.size();
e++) {
358 for (
size_t itl : location[
e]) {
359 _cache <<
"hess[" <<
itl <<
"] = ";
361 _cache <<
"compressed[" <<
e <<
"];\n";
375 std::map<size_t, CompressedVectorInfo>
hessInfo,
380 CPPADCG_ASSERT_UNKNOWN(_multiThreading);
384 std::string
argsDcl =
langC.generateDefaultFunctionArgumentsDcl();
385 std::vector<std::string>
argsDcl2 =
langC.generateDefaultFunctionArgumentsDcl2();
388 _cache <<
"#include <stdlib.h>\n"
393 langC.setArgumentIn(
"inLocal");
394 langC.setArgumentOut(
"outLocal");
401 size_t index =
it.first;
402 const std::vector<size_t>&
els =
it.second.indexes;
403 const std::vector<std::set<size_t> >& location =
it.second.locations;
404 CPPADCG_ASSERT_UNKNOWN(
els.size() == location.size());
414 " " << _baseTypeName <<
" const * inLocal[3];\n"
415 " " << _baseTypeName <<
" inLocal1 = 1;\n"
416 " " << _baseTypeName <<
" * outLocal[1];\n"
417 " " << _baseTypeName <<
" compressed[" <<
it.second.indexes.size() <<
"];\n"
418 " " << _baseTypeName <<
" * hess = out[0];\n"
420 " inLocal[0] = in[0];\n"
421 " inLocal[1] = &inLocal1;\n"
422 " inLocal[2] = in[1];\n"
423 " outLocal[0] = compressed;\n";
425 for (
size_t e = 0;
e <
els.size();
e++) {
427 for (
size_t itl : location[
e]) {
428 _cache <<
"hess[" <<
itl <<
"] = ";
430 _cache <<
"compressed[" <<
e <<
"];\n";
436 "typedef void (*cppadcg_function_type) (" <<
argsDcl <<
");\n";
441 printFileStartOpenMP(_cache);
450 printFileStartPThreads(_cache, _baseTypeName);
458 " static const cppadcg_function_type p[" <<
hessInfo.size() <<
"] = {";
460 size_t index =
it.first;
461 if (index !=
hessInfo.begin()->first) _cache <<
", ";
462 if (
it.second.ordered) {
469 " static const long offset["<<
hessInfo.size() <<
"] = {";
471 if (
it.first !=
hessInfo.begin()->first) _cache <<
", ";
472 if (
it.second.ordered) {
473 _cache << *
it.second.locations[0].begin();
479 " " << _baseTypeName <<
" inLocal1 = 1;\n"
480 " " << _baseTypeName <<
" const * inLocal[3] = {in[0], &inLocal1, in[1]};\n"
481 " " << _baseTypeName <<
" * outLocal[1];\n";
482 _cache <<
" " << _baseTypeName <<
" * hess = out[0];\n"
487 printFunctionStartOpenMP(_cache,
hessInfo.size());
489 printLoopStartOpenMP(_cache,
hessInfo.size());
490 _cache <<
" outLocal[0] = &hess[offset[i]];\n"
492 printLoopEndOpenMP(_cache,
hessInfo.size());
498 printFunctionStartPThreads(_cache,
hessInfo.size());
500 " for(i = 0; i < " <<
hessInfo.size() <<
"; ++i) {\n"
501 " args[i] = (ExecArgStruct*) malloc(sizeof(ExecArgStruct));\n"
502 " args[i]->func = p[i];\n"
503 " args[i]->in = inLocal;\n"
504 " args[i]->out[0] = &hess[offset[i]];\n"
505 " args[i]->atomicFun = " <<
langC .getArgumentAtomic() <<
";\n"
508 printFunctionEndPThreads(_cache,
hessInfo.size());
524 evalRows.reserve(_hessSparsity.rows.size());
525 evalCols.reserve(_hessSparsity.cols.size());
527 for (
size_t e = 0;
e < _hessSparsity.rows.size();
e++) {
528 size_t i = _hessSparsity.rows[
e];
529 size_t j = _hessSparsity.cols[
e];
530 if (_hessSparsity.sparsity[
i].find(
j) == _hessSparsity.sparsity[
i].end() &&
531 _hessSparsity.sparsity[
j].find(
i) != _hessSparsity.sparsity[
j].end()) {
545 if (_hessSparsity.sparsity.size() > 0) {
549 size_t m = _fun.Range();
550 size_t n = _fun.Domain();
555 SparsitySetType
r(
n);
556 for (
size_t j = 0;
j <
n;
j++)
558 SparsitySetType jac = _fun.ForSparseJac(
n,
r);
560 SparsitySetType s(1);
561 for (
size_t i = 0;
i < m;
i++) {
564 _hessSparsity.sparsity = _fun.RevSparseHes(
n, s,
false);
567 if (_hessianByEquation || _reverseTwo) {
573 if (_custom_hess.defined) {
577 r = SparsitySetType(
n);
581 jac = _fun.ForSparseJac(
n,
r);
592 _hessSparsities.resize(m);
593 for (
size_t i = 0;
i < m;
i++) {
594 _hessSparsities[
i].sparsity.resize(
n);
597 for (
size_t c = 0;
c <
colors.size();
c++) {
601 r = SparsitySetType(
n);
605 _fun.ForSparseJac(
n,
r);
609 const std::set<size_t>& equations = color.
rows;
610 for (
size_t i : equations) {
614 SparsitySetType
sparsityc = _fun.RevSparseHes(
n, s,
false);
623 _hessSparsities[
i].sparsity[
j].insert(
sparsityc[
j].begin(),
630 for (
size_t i = 0;
i < m;
i++) {
633 if (!_custom_hess.defined) {
638 size_t nnz = _custom_hess.row.size();
639 for (
size_t e = 0;
e < nnz;
e++) {
640 size_t i1 = _custom_hess.row[
e];
641 size_t i2 = _custom_hess.col[
e];
652 if (!_custom_hess.defined) {
653 generateSparsityIndexes(_hessSparsity.sparsity,
654 _hessSparsity.rows, _hessSparsity.cols);
657 _hessSparsity.rows = _custom_hess.row;
658 _hessSparsity.cols = _custom_hess.col;
664 determineHessianSparsity();
666 generateSparsity2DSource(_name +
"_" + FUNCTION_HESSIAN_SPARSITY, _hessSparsity);
667 _sources[_name +
"_" + FUNCTION_HESSIAN_SPARSITY +
".c"] = _cache.str();
670 if (_hessianByEquation || _reverseTwo) {
671 generateSparsity2DSource2(_name +
"_" + FUNCTION_HESSIAN_SPARSITY2, _hessSparsities);
672 _sources[_name +
"_" + FUNCTION_HESSIAN_SPARSITY2 +
".c"] = _cache.str();
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={})
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 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)
virtual void determineHessianSparsity()
virtual void generateSparseHessianSourceFromRev2(MultiThreadingType multiThreadingType)
virtual void generateSparseHessianSourceDirectly()
virtual void generateSparseHessianSource(MultiThreadingType multiThreadingType)
bool GreaterThanZero(const cg::CG< Base > &x)