1 #ifndef CPPAD_CG_MODEL_C_SOURCE_GEN_FOR1_INCLUDED 2 #define CPPAD_CG_MODEL_C_SOURCE_GEN_FOR1_INCLUDED 24 determineJacobianSparsity();
27 std::map<size_t, std::vector<size_t> > elements;
28 for (
size_t e = 0; e < _jacSparsity.rows.size(); e++) {
29 elements[_jacSparsity.cols[e]].push_back(_jacSparsity.rows[e]);
32 if (!_loopTapes.empty()) {
36 prepareSparseForwardOneWithLoops(elements);
43 startingJob(
"'model (forward one)'", JobTimer::SOURCE_GENERATION);
45 if (isAtomicsUsed()) {
46 generateSparseForwardOneSourcesWithAtomics(elements);
48 generateSparseForwardOneSourcesNoAtomics(elements);
55 generateGlobalDirectionalFunctionSource(FUNCTION_SPARSE_FORWARD_ONE,
57 FUNCTION_FORWARD_ONE_SPARSITY,
68 size_t n = _fun.Domain();
72 const std::string jobName =
"model (forward one)";
73 startingJob(
"'" + jobName +
"'", JobTimer::SOURCE_GENERATION);
75 for (
const auto& it : elements) {
77 const std::vector<size_t>& rows = it.second;
80 _cache <<
"model (forward one, indep " << j <<
")";
81 const std::string subJobName = _cache.str();
83 startingJob(
"'" + subJobName +
"'", JobTimer::GRAPH);
86 handler.setJobTimer(_jobTimer);
91 for (
size_t i = 0; i < n; i++) {
92 indVars[i].setValue(_x[i]);
103 _fun.Forward(0, indVars);
107 CPPADCG_ASSERT_UNKNOWN(dy.size() == _fun.Range());
110 for (
size_t it2 : rows) {
111 dyCustom.push_back(dy[it2]);
117 langC.setMaxAssigmentsPerFunction(_maxAssignPerFunc, &_sources);
120 _cache << _name <<
"_" << FUNCTION_SPARSE_FORWARD_ONE <<
"_indep" << j;
121 langC.setGenerateFunction(_cache.str());
123 std::ostringstream code;
124 std::unique_ptr<VariableNameGenerator<Base> > nameGen(createVariableNameGenerator(
"dy"));
127 handler.
generateCode(code, langC, dyCustom, nameGenHess, _atomicFunctions, subJobName);
138 size_t n = _fun.Domain();
141 handler.setJobTimer(_jobTimer);
146 for (
size_t i = 0; i < n; i++) {
147 x[i].setValue(_x[i]);
159 CppAD::sparse_jacobian_work work;
160 _fun.SparseJacobianForward(x, _jacSparsity.sparsity, _jacSparsity.rows, _jacSparsity.cols, jacFlat, work);
165 std::map<size_t, vector<CGBase> > jac;
166 std::map<size_t, std::map<size_t, size_t> > positions;
168 for (
const auto& it : elements) {
170 const std::vector<size_t>& column = it.second;
172 jac[j].resize(column.size());
173 std::map<size_t, size_t>& pos = positions[j];
175 for (
size_t e = 0; e < column.size(); e++) {
176 size_t i = column[e];
181 for (
size_t el = 0; el < _jacSparsity.rows.size(); el++) {
182 size_t i = _jacSparsity.rows[el];
183 size_t j = _jacSparsity.cols[el];
184 size_t e = positions[j].at(i);
187 column[e] = jacFlat[el] * dx;
193 typename std::map<size_t, vector<CGBase> >::iterator itJ;
194 for (itJ = jac.begin(); itJ != jac.end(); ++itJ) {
195 size_t j = itJ->first;
199 _cache <<
"model (forward one, indep " << j <<
")";
200 const std::string subJobName = _cache.str();
203 langC.setMaxAssigmentsPerFunction(_maxAssignPerFunc, &_sources);
206 _cache << _name <<
"_" << FUNCTION_SPARSE_FORWARD_ONE <<
"_indep" << j;
207 langC.setGenerateFunction(_cache.str());
209 std::ostringstream code;
210 std::unique_ptr<VariableNameGenerator<Base> > nameGen(createVariableNameGenerator(
"dy"));
213 handler.
generateCode(code, langC, dyCustom, nameGenHess, _atomicFunctions, subJobName);
220 size_t m = _fun.Range();
221 size_t n = _fun.Domain();
224 _cache << _name <<
"_" << FUNCTION_FORWARD_ONE;
225 std::string model_function(_cache.str());
228 std::string argsDcl = langC.generateDefaultFunctionArgumentsDcl();
229 std::string args = langC.generateDefaultFunctionArguments();
232 _cache <<
"#include <stdlib.h>\n" 235 "int " << _name <<
"_" << FUNCTION_SPARSE_FORWARD_ONE <<
"(unsigned long pos, " << argsDcl <<
");\n" 236 "void " << _name <<
"_" << FUNCTION_FORWARD_ONE_SPARSITY <<
"(unsigned long pos, unsigned long const** elements, unsigned long* nnz);\n" 239 _baseTypeName +
" ty[]",
240 langC.generateArgumentAtomicDcl()});
242 " unsigned long ePos, ej, i, j, nnz, nnzMax;\n" 243 " unsigned long const* pos;\n" 244 " unsigned long* txPos;\n" 245 " unsigned long* txPosTmp;\n" 246 " unsigned long nnzTx;\n" 247 " " << _baseTypeName <<
" const * in[2];\n" 248 " " << _baseTypeName <<
"* out[1];\n" 249 " " << _baseTypeName <<
" x[" << n <<
"];\n" 250 " " << _baseTypeName <<
"* compressed;\n" 256 " for (j = 0; j < " << n <<
"; j++) {\n" 257 " if (tx[j * 2 + 1] != 0.0) {\n" 258 " " << _name <<
"_" << FUNCTION_FORWARD_ONE_SPARSITY <<
"(j, &pos, &nnz);\n" 259 " if (nnz > nnzMax)\n" 261 " else if (nnz == 0)\n" 264 " txPosTmp = (unsigned long*) realloc(txPos, nnzTx * sizeof(unsigned long));\n" 265 " if (txPosTmp != NULL) {\n" 266 " txPos = txPosTmp;\n" 269 " return -1; // failure to allocate memory\n" 271 " txPos[nnzTx - 1] = j;\n" 274 " for (i = 0; i < " << m <<
"; i++) {\n" 275 " ty[i * 2 + 1] = 0;\n" 278 " if (nnzTx == 0) {\n" 280 " return 0; //nothing to do\n" 283 " compressed = (" << _baseTypeName <<
"*) malloc(nnzMax * sizeof(" << _baseTypeName <<
"));\n" 285 " for (j = 0; j < " << n <<
"; j++)\n" 286 " x[j] = tx[j * 2];\n" 288 " for (ej = 0; ej < nnzTx; ej++) {\n" 290 " " << _name <<
"_" << FUNCTION_FORWARD_ONE_SPARSITY <<
"(j, &pos, &nnz);\n" 293 " in[1] = &tx[j * 2 + 1];\n" 294 " out[0] = compressed;\n";
295 if (!_loopTapes.empty()) {
296 _cache <<
" for(ePos = 0; ePos < nnz; ePos++)\n" 297 " compressed[ePos] = 0;\n" 300 _cache <<
" ret = " << _name <<
"_" << FUNCTION_SPARSE_FORWARD_ONE <<
"(j, " << args <<
");\n" 303 " free(compressed);\n" 308 " for (ePos = 0; ePos < nnz; ePos++) {\n" 309 " ty[pos[ePos] * 2 + 1] += compressed[ePos];\n" 313 " free(compressed);\n" 317 _sources[model_function +
".c"] = _cache.str();
virtual void generateSparseForwardOneSourcesNoAtomics(const std::map< size_t, std::vector< size_t > > &elements)
virtual void generateSparseForwardOneSources()
void setValue(const Base &val)
virtual void generateSparseForwardOneSourcesWithAtomics(const std::map< size_t, std::vector< size_t > > &elements)
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={})
void makeVariables(VectorCG &variables)
void makeVariable(AD< CGB > &variable)
virtual void setParameterPrecision(size_t p)
virtual void generateCode(std::ostream &out, Language< Base > &lang, CppAD::vector< CGB > &dependent, VariableNameGenerator< Base > &nameGen, const std::string &jobName="source")