27 #include "code_generator.hpp"
28 #include "function_internal.hpp"
29 #include "convexify.hpp"
30 #include <casadi_runtime_str.h>
31 #include "global_options.hpp"
32 #include "filesystem_impl.hpp"
57 bool prefix_set =
false;
69 for (
auto&& e : opts) {
70 if (e.first==
"verbose") {
72 }
else if (e.first==
"verbose_runtime") {
74 }
else if (e.first==
"mex") {
76 }
else if (e.first==
"with_sfunction") {
78 }
else if (e.first==
"unroll_args") {
80 }
else if (e.first==
"cpp") {
82 }
else if (e.first==
"main") {
83 this->
main = e.second;
84 }
else if (e.first==
"casadi_real") {
86 }
else if (e.first==
"casadi_int") {
88 }
else if (e.first==
"codegen_scalars") {
90 }
else if (e.first==
"with_header") {
92 }
else if (e.first==
"with_mem") {
94 }
else if (e.first==
"with_export") {
96 }
else if (e.first==
"with_import") {
98 }
else if (e.first==
"include_math") {
100 }
else if (e.first==
"infinity") {
101 this->
infinity = e.second.to_string();
102 }
else if (e.first==
"nan") {
103 this->
nan = e.second.to_string();
104 }
else if (e.first==
"real_min") {
105 this->
real_min = e.second.to_string();
106 }
else if (e.first==
"indent") {
109 }
else if (e.first==
"avoid_stack") {
111 }
else if (e.first==
"prefix") {
112 this->
prefix = e.second.to_string();
114 }
else if (e.first==
"max_declarations_per_line") {
117 "Option max_declarations_per_line must be >=0");
118 }
else if (e.first==
"max_initializer_elements_per_line") {
121 "Option max_initializer_elements_per_line must be >=0");
122 }
else if (e.first==
"force_canonical") {
125 casadi_error(
"Unrecognized option: " +
str(e.first));
131 std::stringstream ss;
132 ss << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
134 ss << std::numeric_limits<float>::min();
137 ss << std::numeric_limits<double>::min();
152 std::string::size_type dotpos =
name.rfind(
'.');
153 if (dotpos==std::string::npos) {
155 this->
suffix = this->
cpp ?
".cpp" :
".c";
157 this->name =
name.substr(0, dotpos);
158 this->
suffix = name.substr(dotpos);
193 this->
header <<
"#include <casadi/mem.h>\n";
210 std::map<std::string, std::set<std::pair<std::string, std::string>>> local_variables_by_type;
212 local_variables_by_type[e.second.first].insert(std::make_pair(e.first, e.second.second));
216 for (
auto&& e : local_variables_by_type) {
218 for (
auto it=e.second.begin(); it!=e.second.end(); ++it) {
219 bool split_declaration = it==e.second.begin() ||
221 if (split_declaration) {
222 if (it!=e.second.begin())
body <<
";\n";
223 body <<
" " << e.first <<
" ";
227 body << it->second << it->first;
240 auto it = funs.find(f);
241 if (it==funs.end()) {
242 casadi_int n = funs.size();
269 *
this <<
"void " << fname <<
"_incref(void) {\n";
274 *
this <<
"void " << fname <<
"_decref(void) {\n";
284 *
this <<
"int " << fname <<
"_alloc_mem(void) {\n";
292 *
this <<
"int " << fname <<
"_init_mem(int mem) {\n";
300 *
this <<
"void " << fname <<
"_free_mem(int mem) {\n";
308 *
this <<
"int " << fname <<
"_checkout(void) {\n";
316 *
this <<
"void " << fname <<
"_release(int mem) {\n";
337 <<
"return " << codegen_name <<
"(arg, res, iw, w, mem);\n"
343 for (casadi_int i=0; i<f.
n_in(); ++i) {
344 *
this <<
"arg[" << i <<
"] = " << f.
name_in(i) <<
";\n";
346 for (casadi_int i=0; i<f.
n_out(); ++i) {
347 *
this <<
"res[" << i <<
"] = " << f.
name_out(i) <<
";\n";
349 *
this <<
"return " << codegen_name <<
"(arg, res, iw, w, mem);\n";
359 if (with_jac_sparsity) {
383 std::stringstream ss;
384 ss << CASADI_MAJOR_VERSION <<
"." << CASADI_MINOR_VERSION <<
"." << CASADI_PATCH_VERSION;
385 if (!CASADI_IS_RELEASE) ss <<
"+";
392 f <<
"/* This file was automatically generated by CasADi " <<
casadi_version() <<
".\n"
393 <<
" * It consists of: \n"
394 <<
" * 1) content generated by CasADi runtime: not copyrighted\n"
395 <<
" * 2) template code copied from CasADi source: permissively licensed (MIT-0)\n"
396 <<
" * 3) user code: owned by the user\n"
402 f <<
"#ifdef __cplusplus\n"
403 <<
"extern \"C\" {\n"
411 f <<
"#ifdef __cplusplus\n"
412 <<
"} /* extern \"C\" */\n"
417 void CodeGenerator::generate_casadi_real(std::ostream &s)
const {
418 s <<
"#ifndef casadi_real\n"
423 void CodeGenerator::generate_export_symbol(std::ostream &s)
const {
424 s <<
"/* Symbol visibility in DLLs */\n"
425 <<
"#ifndef CASADI_SYMBOL_EXPORT\n"
426 <<
" #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)\n"
427 <<
" #if defined(STATIC_LINKED)\n"
428 <<
" #define CASADI_SYMBOL_EXPORT\n"
430 <<
" #define CASADI_SYMBOL_EXPORT __declspec(dllexport)\n"
432 <<
" #elif defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)\n"
433 <<
" #define CASADI_SYMBOL_EXPORT __attribute__ ((visibility (\"default\")))\n"
434 <<
" #else" << std::endl
435 <<
" #define CASADI_SYMBOL_EXPORT\n"
440 void CodeGenerator::generate_import_symbol(std::ostream &s)
const {
441 s <<
"/* Symbol visibility in DLLs */\n"
442 <<
"#ifndef CASADI_SYMBOL_IMPORT\n"
443 <<
" #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)\n"
444 <<
" #if defined(STATIC_LINKED)\n"
445 <<
" #define CASADI_SYMBOL_IMPORT\n"
447 <<
" #define CASADI_SYMBOL_IMPORT __declspec(dllimport)\n"
449 <<
" #elif defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)\n"
450 <<
" #define CASADI_SYMBOL_IMPORT __attribute__ ((visibility (\"default\")))\n"
451 <<
" #else" << std::endl
452 <<
" #define CASADI_SYMBOL_IMPORT\n"
457 void CodeGenerator::generate_casadi_int(std::ostream &s)
const {
458 s <<
"#ifndef casadi_int\n"
466 casadi_assert(
prefix.find(this->name + this->suffix)==std::string::npos,
467 "The signature of CodeGenerator::generate has changed. "
468 "Instead of providing the filename, only provide the prefix.");
474 std::ostream& s = *s_ptr;
481 s <<
"CASADI_SYMBOL_EXPORT casadi_real* CASADI_PREFIX(get_pool_double)(const char* name) {\n";
483 casadi_int i = e.second;
484 s <<
" if (strcmp(name, \"" + e.first +
"\")==0) "
485 <<
"return casadi_pd" +
str(i) +
";\n";
492 if (this->
mex) generate_mex(s);
495 if (this->
main) generate_main(s);
506 generate_sfunction(sfunction_name, sfunction_code);
513 std::ostream& s = *s_ptr;
518 generate_casadi_real(s);
521 generate_casadi_int(s);
536 void CodeGenerator::generate_mex(std::ostream &s)
const {
538 s <<
"#ifdef MATLAB_MEX_FILE\n";
541 if (this->
cpp) s <<
"extern \"C\"\n";
542 s <<
"void mexFunction(int resc, mxArray *resv[], int argc, const mxArray *argv[]) {"
550 s <<
" char buf[" << (buf_len+1) <<
"];\n";
553 s <<
" int buf_ok = argc > 0 && !mxGetString(*argv, buf, sizeof(buf));\n";
556 s <<
" if (!buf_ok) {\n";
559 s <<
" mex_" <<
exposed_fname[0] <<
"(resc, resv, argc, argv);\n"
562 s <<
" /* name error */\n";
565 s <<
" } else if (strcmp(buf, \"" <<
exposed_fname[i] <<
"\")==0) {\n"
566 <<
" mex_" <<
exposed_fname[i] <<
"(resc, resv, argc-1, argv+1);\n"
572 s <<
" mexErrMsgTxt(\"First input should be a command string. Possible values:";
583 void CodeGenerator::generate_sfunction(
const std::string& name,
584 const std::string& sfunction)
const {
587 std::ostream& f = *f_ptr;
590 f <<
"// Must specify the S_FUNCTION_NAME as the name of the S-function\n"
591 <<
"#define S_FUNCTION_NAME sfun_" <<
name <<
"\n"
592 <<
"#define S_FUNCTION_LEVEL 2\n\n"
593 <<
"// Need to include simstruc.h for the definition of the SimStruct and its\n"
594 <<
"// associated macro definitions\n"
595 <<
"#ifndef __SIMSTRUC__\n"
596 <<
"#include \"simstruc.h\"\n"
598 <<
"// Specific header file(s) required by the legacy code function\n"
599 <<
"#include \"" << this->name <<
".h\"\n\n\n";
606 std::string CodeGenerator::codegen_sfunction(
const Function& f)
const {
612 g <<
"/* Function: mdlInitializeSizes ===========================================\n"
614 <<
"* The sizes information is used by Simulink to determine the S-function\n"
615 <<
"* blocks characteristics (number of inputs, outputs, states, etc.).\n"
617 <<
"static void mdlInitializeSizes(SimStruct *S)\n"
619 <<
" /* Declare auxilary variables */\n"
621 <<
" const int_T* sp;\n\n"
622 <<
" /* Set number of simulink s-function block parameters "
623 "(the ones which appear by double click on simulink block) */\n"
624 <<
" ssSetNumSFcnParams(S, 0);\n\n"
625 <<
" /* Report if parameter mismatch occurs */\n"
626 <<
" if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;\n\n"
627 <<
" /* Specify the number of states for which a block detects "
628 "zero crossings that occur between sample points */\n"
629 <<
" ssSetNumNonsampledZCs(S, 0);\n\n"
630 <<
" /* Set number of simulink input ports */\n"
631 <<
" if (!ssSetNumInputPorts(S, " << f->n_in_ <<
")) return;\n\n"
632 <<
" /* Configure simulink input ports (inputs are assumed to be dense "
633 "vectors or matrices) */\n"
634 <<
" for (ii=0; ii<" << f->n_in_ <<
"; ++ii) {\n"
635 <<
" sp = " << f.name() <<
"_sparsity_in(ii);\n"
636 <<
" if (sp[1]==1) {\n"
637 <<
" ssSetInputPortWidth(S, ii, sp[0]);\n"
640 <<
" ssSetInputPortMatrixDimensions(S, ii, sp[0], sp[1]);\n"
642 <<
" ssSetInputPortDirectFeedThrough(S, ii, 1);\n"
644 <<
" /* Set number of simulink output ports */\n"
645 <<
" if (!ssSetNumOutputPorts(S, " << f->n_out_ <<
")) return;\n\n"
646 <<
" /* Configure simulink output ports (dense or sparse vectors or matrices allowed) */\n"
647 <<
" for (ii=0; ii<" << f->n_out_ <<
"; ++ii) {\n"
648 <<
" sp = " << f.name() <<
"_sparsity_out(ii);\n"
649 <<
" if (sp[1]==1) {\n"
650 <<
" ssSetOutputPortWidth(S, ii, sp[0]);\n"
653 <<
" ssSetOutputPortMatrixDimensions(S, ii, sp[0], sp[1]);\n"
656 <<
" ssSetOutputPortOutputExprInRTW(S, 0, 0);\n\n"
657 <<
" /* This S-function can be used in referenced model simulating in normal mode */\n"
658 <<
" ssSetModelReferenceNormalModeSupport(S, MDL_START_AND_MDL_PROCESS_PARAMS_OK);\n\n"
659 <<
" /* Set the number of sample time */\n"
660 <<
" ssSetNumSampleTimes(S, 1);\n\n"
661 <<
" /* Set the compliance with the SimState feature */\n"
662 <<
" ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);\n\n"
664 <<
" * All options have the form SS_OPTION_<name> and are documented in\n"
665 <<
" * matlabroot/simulink/include/simstruc.h. The options should be\n"
666 <<
" * bitwise ord together as in\n"
667 <<
" * ssSetOptions(S, (SS_OPTION_name1 | SS_OPTION_name2))\n"
672 g <<
"/* Function: mdlInitializeSampleTimes =====================================\n"
674 <<
" * This function is used to specify the sample time(s) for your\n"
675 <<
" * S-function. You must register the same number of sample times as\n"
676 <<
" * specified in ssSetNumSampleTimes.\n"
678 <<
"static void mdlInitializeSampleTimes(SimStruct *S)\n"
680 <<
" ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);\n"
681 <<
" ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET);\n"
682 <<
" #if defined(ssSetModelReferenceSampleTimeDefaultInheritance)\n"
683 <<
" ssSetModelReferenceSampleTimeDefaultInheritance(S);\n"
688 g <<
"/* Function: mdlOutputs ===================================================\n"
690 <<
" * In this function, you compute the outputs of your S-function\n"
691 <<
" * block. Generally outputs are placed in the output vector(s),\n"
692 <<
" * ssGetOutputPortSignal.\n"
694 <<
"static void mdlOutputs(SimStruct *S, int_T tid)\n"
696 <<
" /* Declare auxilary variables */\n"
697 <<
" int_T ii, jj, row, col, nnz_col, ind_start_row_index, offset = 0, jj_total = 0;\n"
698 <<
" const int_T* sp;\n\n"
699 <<
" /* Allocate buffers for casadi input and output and simulink output */\n"
700 <<
" " +
array(
"real_T",
"w", f->sz_w()+f->nnz_out())
701 <<
" " +
array(
"int_T",
"iw", f->sz_iw())
702 <<
" const real_T* arg[" << f->sz_arg() <<
"] = {0};\n"
703 <<
" real_T* res[" << f->sz_res() <<
"] = {0};\n"
704 <<
" real_T* y[" << f->n_out_ <<
"] = {0};\n\n"
705 <<
" /* Point inputs directly to casadi input buffer */\n"
706 <<
" for (ii=0; ii<" << f->n_in_ <<
";++ii) {\n"
707 <<
" arg[ii] = *ssGetInputPortRealSignalPtrs( S, ii );\n"
709 <<
" /* Point outputs to buffer */\n"
710 <<
" for (ii=0; ii<" << f->n_out_ <<
";++ii) {\n"
711 <<
" y[ii] = ssGetOutputPortRealSignal( S, ii );\n"
713 <<
" /* Point allocated working array to casadi output buffer */\n";
714 for (casadi_int ii=0; ii<f->n_out_; ++ii) {
715 g <<
" res[" << ii <<
"] = w + offset;\n"
716 <<
" offset += " << f.nnz_out(ii) <<
";\n";
719 <<
" /* Call CasADi function */\n"
720 <<
" " << f.name() <<
"( arg, res, iw, w+offset, 0 );\n\n"
721 <<
" /* Assign results to Simulink output array */\n"
722 <<
" for (ii=0; ii<" << f->n_out_ <<
"; ++ii){\n\n"
723 <<
" /* Get sparsity information of casadi function output "
724 "(sp[0] - n_rows, sp[1] - n_cols, sp[2] - dense/sparse) */\n"
725 <<
" sp = " << f.name() <<
"_sparsity_out(ii);\n\n"
726 <<
" /* Check if output is dense (sp[2]=1) or sparse (sp[2]=0) */\n"
727 <<
" if (sp[2]==0) {\n"
728 <<
" jj_total = 0;\n"
729 <<
" ind_start_row_index = 2 + sp[1] + 1;\n\n"
730 <<
" /* Distribute nonzero elements column by column */\n"
731 <<
" for (col=0; col<sp[1]; col++) {\n\n"
732 <<
" /* The cumulative sum of nonzero elements after each column starts at index 2, "
733 "after last entry of CCS array col_ptr; number of nonzero elements in current column is "
734 "obtained by the difference of two consecutive values */\n"
735 <<
" nnz_col = sp[2+col+1] - sp[2+col];\n\n"
736 <<
" /* Distribute nonzero elements of current column to correct row position */\n"
737 <<
" for (jj=0; jj<nnz_col; jj++) {\n"
738 <<
" row = sp[ind_start_row_index+jj_total];\n"
739 <<
" y[ii][row + sp[0]*col] = res[ii][jj_total];\n"
745 <<
" y[ii] = res[ii];\n"
751 g <<
"/* Function: mdlTerminate =================================================\n"
753 <<
" * In this function, you should perform any actions that are necessary\n"
754 <<
" * at the termination of a simulation.\n"
756 <<
"static void mdlTerminate(SimStruct *S)\n"
759 <<
"/* Required S-function trailer */\n"
760 <<
"#ifdef MATLAB_MEX_FILE\n"
761 <<
"# include \"simulink.c\"\n"
763 <<
"# include \"cg_sfun.h\"\n"
769 void CodeGenerator::generate_main(std::ostream &s)
const {
770 s << this->
dll_export <<
"int main(int argc, char* argv[]) {\n";
773 s <<
" if (argc<2) {\n"
774 <<
" /* name error */\n";
776 s <<
" } else if (strcmp(argv[1], \"" <<
exposed_fname[i] <<
"\")==0) {\n"
777 <<
" return main_" <<
exposed_fname[i] <<
"(argc-2, argv+2);\n";
782 s <<
" fprintf(stderr, \"First input should be a command string. Possible values:";
787 s <<
"Note: you may use function.generate_input to create a command string.";
806 return "casadi_rd" +
str(size);
820 return "casadi_ri" +
str(size);
838 return "casadi_pd" +
str(it->second);
846 s <<
"/* How to prefix internal symbols */\n"
847 <<
"#ifdef CASADI_CODEGEN_PREFIX\n"
848 <<
" #define CASADI_NAMESPACE_CONCAT(NS, ID) _CASADI_NAMESPACE_CONCAT(NS, ID)\n"
849 <<
" #define _CASADI_NAMESPACE_CONCAT(NS, ID) NS ## ID\n"
850 <<
" #define CASADI_PREFIX(ID) CASADI_NAMESPACE_CONCAT(CODEGEN_PREFIX, ID)\n"
852 <<
" #define CASADI_PREFIX(ID) " << this->
prefix <<
"_ ## ID\n"
860 generate_casadi_real(s);
863 generate_casadi_int(s);
866 s <<
"#ifndef CASADI_MAX_NUM_THREADS\n";
867 s <<
"#define CASADI_MAX_NUM_THREADS 1\n";
874 s <<
"#include <casadi/mem.h>\n" << std::endl;
879 s <<
"/* Add prefix to internal symbols */\n";
881 s <<
"#define " <<
"casadi_" << i <<
" CASADI_PREFIX(" << i <<
")\n";
932 std::vector<double> sz_zeros(
sz_zeros_, 0);
933 print_vector(s,
"casadi_zeros", std::vector<double>(sz_zeros));
938 std::vector<double> sz_ones(
sz_ones_, 0);
939 print_vector(s,
"casadi_ones", std::vector<double>(sz_ones));
947 s <<
"static casadi_real casadi_rd" +
str(i++) +
"[" +
str(it.second) +
"];\n";
956 s <<
"static casadi_real casadi_ri" +
str(i++) +
"[" +
str(it.second) +
"];\n";
965 s <<
"casadi_real casadi_pd" +
str(i) +
974 s <<
"/* External functions */\n";
978 s << std::endl << std::endl;
982 s << this->
body.str();
1002 if (n<0)
return "0";
1003 std::stringstream s;
1019 std::stringstream ss;
1026 const std::string& def) {
1027 std::stringstream s;
1030 s <<
"*" <<
name <<
" = 0";
1032 s <<
name <<
"[" << len <<
"]";
1033 if (!def.empty()) s <<
" = " << def;
1040 const std::vector<casadi_int>& v) {
1045 const std::vector<char>& v) {
1050 const std::vector<double>& v) {
1055 const std::vector<std::string>& v) {
1061 std::stringstream s;
1062 s <<
"casadi_print_canonical(" <<
sparsity(sp) <<
", " <<
arg <<
");";
1068 std::stringstream s;
1069 s <<
"casadi_print_vector(" << sz <<
", " <<
arg <<
");";
1075 std::stringstream s;
1076 s <<
"casadi_print_scalar(" <<
arg <<
");";
1085 return "casadi_fabs("+a0+
")";
1088 return "casadi_sq("+a0+
")";
1091 return "casadi_sign("+a0+
")";
1094 return "casadi_log1p("+a0+
")";
1097 return "casadi_expm1("+a0+
")";
1106 return "casadi_fmin("+a0+
","+a1+
")";
1109 return "casadi_fmax("+a0+
","+a1+
")";
1112 return "casadi_hypot("+a0+
","+a1+
")";
1115 return "casadi_printme("+a0+
","+a1+
")";
1122 const std::string& use_ifdef) {
1130 if (!use_ifdef.empty()) this->
includes <<
"#ifdef " << use_ifdef << std::endl;
1133 if (relative_path) {
1134 this->
includes <<
"#include \"" << new_include <<
"\"\n";
1136 this->
includes <<
"#include <" << new_include <<
">\n";
1140 if (!use_ifdef.empty()) this->
includes <<
"#endif\n";
1147 *
this << s <<
".checkout = " <<
name <<
"_checkout;\n";
1149 *
this << s <<
".checkout = 0;\n";
1152 *
this << s <<
".eval = " <<
name <<
";\n";
1154 *
this << s <<
".release = " <<
name <<
"_release;\n";
1156 *
this << s <<
".release = 0;\n";
1162 const std::string& res,
const std::string& iw,
1163 const std::string& w,
const std::string& failure_ret) {
1167 std::string
mem =
"mid";
1168 local(
"flag",
"int");
1170 *
this <<
mem <<
" = " <<
name <<
"_checkout();\n";
1171 *
this <<
"if (" <<
mem <<
"<0) return " << failure_ret <<
";\n";
1172 *
this <<
"flag = " +
name +
"(" +
arg +
", " +
res +
", "
1173 + iw +
", " + w +
", " <<
mem <<
");\n";
1174 *
this <<
name <<
"_release(" <<
mem <<
");\n";
1178 + iw +
", " + w +
", 0)";
1188 return "casadi_" +
name;
1193 if (!allow_adding) {
1194 casadi_assert(added,
"Duplicate macro: " +
name);
1196 return "casadi_" +
name;
1215 casadi_assert_dev(
sizeof(
double) %
sizeof(
size_t)==0);
1216 const casadi_int int_len = v.size()*(
sizeof(double)/
sizeof(
size_t));
1217 const size_t* int_v =
reinterpret_cast<const size_t*
>(&v.front());
1218 for (
size_t i=0; i<int_len; ++i) {
1249 for (
auto i=eq.first; i!=eq.second; ++i) {
1260 casadi_error(
"Constant not found");
1270 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1272 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1283 casadi_error(
"Constant not found");
1293 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1295 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1306 casadi_error(
"Constant not found");
1316 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1318 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1329 casadi_error(
"Constant not found");
1357 const std::string& name,
const std::vector<casadi_int>& v,
const std::string& type) {
1366 (*this) <<
"for (i=0;i<" << v.size() <<
";++i) " +
name +
"[i] = " + ref +
"[i];\n";
1380 for (
auto it=f_match.first; it!=f_match.second; ++it) {
1381 if (it->second==inst)
return;
1513 std::vector<std::string> inst2 = inst;
1514 if (inst.size()==1) inst2.push_back(inst[0]);
1521 std::vector<std::string> inst2 = inst;
1522 if (inst.size()==1) inst2.push_back(inst[0]);
1691 this->
auxiliaries <<
"#define casadi_to_double(x) "
1692 <<
"(" << (this->
cpp ?
"static_cast<double>(x)" :
"(double) x") <<
")\n\n";
1696 <<
"(" << (this->
cpp ?
"static_cast<casadi_int>(x)" :
"(casadi_int) x")
1701 <<
"(" << (this->
cpp ?
"static_cast<x>(y)" :
"(x) y") <<
")\n\n";
1705 this->
auxiliaries <<
"casadi_real casadi_sq(casadi_real x) { return x*x;}\n\n";
1709 this->
auxiliaries <<
"casadi_real casadi_sign(casadi_real x) "
1710 <<
"{ return x<0 ? -1 : x>0 ? 1 : x;}\n\n";
1715 <<
"(casadi_real c, casadi_real x, casadi_real y) "
1716 <<
"{ return c!=0 ? x : y;}\n\n";
1722 <<
" #define CASADI_PRINTF mexPrintf\n"
1724 <<
" #define CASADI_PRINTF printf\n"
1728 this->
auxiliaries <<
"#define CASADI_PRINTF printf\n";
1730 this->
auxiliaries <<
"#define CASADI_SNPRINTF snprintf\n";
1737 this->
auxiliaries <<
"casadi_real casadi_fmin(casadi_real x, casadi_real y) {\n"
1738 <<
"/* Pre-c99 compatibility */\n"
1739 <<
"#if __STDC_VERSION__ < 199901L\n"
1740 <<
" return x<y ? x : y;\n"
1742 <<
" return fmin(x, y);\n"
1748 this->
auxiliaries <<
"casadi_real casadi_fmax(casadi_real x, casadi_real y) {\n"
1749 <<
"/* Pre-c99 compatibility */\n"
1750 <<
"#if __STDC_VERSION__ < 199901L\n"
1751 <<
" return x>y ? x : y;\n"
1753 <<
" return fmax(x, y);\n"
1759 this->
auxiliaries <<
"casadi_real casadi_fabs(casadi_real x) {\n"
1760 <<
"/* Pre-c99 compatibility */\n"
1761 <<
"#if __STDC_VERSION__ < 199901L\n"
1762 <<
" return x>0 ? x : -x;\n"
1764 <<
" return fabs(x);\n"
1770 this->
auxiliaries <<
"casadi_real casadi_isinf(casadi_real x) {\n"
1771 <<
"/* Pre-c99 compatibility */\n"
1772 <<
"#if __STDC_VERSION__ < 199901L\n"
1773 <<
" return x== INFINITY || x==-INFINITY;\n"
1775 <<
" return isinf(x);\n"
1780 this->
auxiliaries <<
"casadi_int casadi_min(casadi_int x, casadi_int y) {\n"
1781 <<
" return x>y ? y : x;\n"
1785 this->
auxiliaries <<
"casadi_int casadi_max(casadi_int x, casadi_int y) {\n"
1786 <<
" return x>y ? x : y;\n"
1801 <<
" #define casadi_inf " << this->
infinity <<
"\n"
1806 <<
" #define casadi_nan " << this->
nan <<
"\n"
1811 <<
" #define casadi_real_min " << this->
real_min <<
"\n"
1816 this->
auxiliaries <<
"casadi_real casadi_log1p(casadi_real x) {\n"
1817 <<
"/* Pre-c99 compatibility */\n"
1818 <<
"#if __STDC_VERSION__ < 199901L\n"
1819 <<
" return log(1+x);\n"
1821 <<
" return log1p(x);\n"
1827 this->
auxiliaries <<
"casadi_real casadi_expm1(casadi_real x) {\n"
1828 <<
"/* Pre-c99 compatibility */\n"
1829 <<
"#if __STDC_VERSION__ < 199901L\n"
1830 <<
" return exp(x)-1;\n"
1832 <<
" return expm1(x);\n"
1838 this->
auxiliaries <<
"casadi_real casadi_hypot(casadi_real x, casadi_real y) {\n"
1839 <<
"/* Pre-c99 compatibility */\n"
1840 <<
"#if __STDC_VERSION__ < 199901L\n"
1841 <<
" return sqrt(x*x+y*y);\n"
1843 <<
" return hypot(x, y);\n"
1886 std::stringstream s;
1887 s <<
"casadi_to_mex(" <<
sparsity(sp) <<
", " <<
arg <<
");";
1892 const std::string& res, std::size_t res_off,
1893 const Sparsity& sp_res,
const std::string& w) {
1898 std::stringstream s;
1899 s <<
"casadi_from_mex(" <<
arg
1900 <<
", " <<
res <<
", " <<
sparsity(sp_res) <<
", " << w <<
");";
1906 std::stringstream ret;
1908 std::istringstream stream(casadi_fmu_str);
1909 while (std::getline(stream, line)) {
1911 if (line.find(
"MODELNAME") != std::string::npos) {
1912 line =
replace(line,
"MODELNAME", modelname);
1915 ret << line <<
"\n";
1921 std::string ret = v;
1922 ret =
replace(ret,
"\\",
"\\\\");
1923 ret =
replace(ret,
"\"",
"\\\"");
1924 return "\"" + ret +
"\"";
1932 return constant(
static_cast<casadi_int
>(v));
1935 std::stringstream s;
1939 }
else if (isinf(v)) {
1944 casadi_int v_int =
static_cast<casadi_int
>(v);
1945 if (
static_cast<double>(v_int)==v) {
1950 std::ios_base::fmtflags fmtfl = s.flags();
1951 s << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1) << v;
1959 std::size_t n,
const std::string& res) {
1960 std::stringstream s;
1963 s <<
"casadi_copy(" <<
arg <<
", " << n <<
", " <<
res <<
");";
1973 bool check_lhs,
bool check_rhs) {
1974 std::vector<std::string> checks;
1975 if (check_lhs) checks.push_back(
arg);
1976 if (check_rhs) checks.push_back(
res);
1977 if (!checks.empty()) *
this <<
"if (" <<
join(checks,
" && ") <<
") ";
1982 const std::string& def,
bool check_rhs) {
1983 *
this <<
"if (" <<
arg <<
") {\n";
1984 if (check_rhs) *
this <<
"if (" <<
res <<
") ";
1986 *
this <<
"} else {\n";
1987 if (check_rhs) *
this <<
"if (" <<
res <<
") ";
1988 *
this <<
fill(
res, n, def) <<
"\n";
1993 std::stringstream s;
1996 s <<
"casadi_clear(" <<
res <<
", " << n <<
");";
2001 return "arg[" +
str(i) +
"]";
2005 return "res[" +
str(i) +
"]";
2011 return mem_array+
"[mem]";
2015 std::size_t n,
const std::string& v) {
2017 std::stringstream s;
2020 s <<
"casadi_fill(" <<
res <<
", " << n <<
", " << v <<
");";
2025 const std::string& y) {
2027 std::stringstream s;
2028 s <<
"casadi_dot(" << n <<
", " << x <<
", " << y <<
")";
2033 const std::string& x,
const std::string& y) {
2035 std::stringstream s;
2036 s <<
"casadi_bilin(" << A <<
", " <<
sparsity(sp_A) <<
", " << x <<
", " << y <<
")";
2041 const std::string& alpha,
const std::string& x,
2042 const std::string& y) {
2044 std::stringstream s;
2045 s <<
"casadi_rank1(" << A <<
", " <<
sparsity(sp_A) <<
", "
2046 << alpha <<
", " << x <<
", " << y <<
");";
2051 const std::string& res, casadi_int ndim,
const std::string& grid,
2052 const std::string& offset,
2053 const std::string& values,
const std::string& x,
2054 const std::string& lookup_mode, casadi_int m,
2055 const std::string& iw,
const std::string& w) {
2057 std::stringstream s;
2058 s <<
"casadi_interpn(" <<
res <<
", " << ndim <<
", " << grid <<
", " << offset <<
", "
2059 << values <<
", " << x <<
", " << lookup_mode <<
", " << m <<
", " << iw <<
", " << w <<
");";
2064 casadi_int ndim,
const std::string& grid,
const std::string& offset,
2065 const std::string& values,
const std::string& x,
2066 const std::string& lookup_mode, casadi_int m,
2067 const std::string& iw,
const std::string& w) {
2069 std::stringstream s;
2070 s <<
"casadi_interpn_grad(" << grad <<
", " << ndim <<
", " << grid <<
", " << offset <<
", "
2071 << values <<
", " << x <<
", " << lookup_mode <<
"," << m <<
", " << iw <<
", " << w <<
");";
2076 const std::string& y,
const Sparsity& sp_y,
2077 const std::string& iw) {
2079 return "casadi_trans(" + x +
"," +
sparsity(sp_x) +
", "
2080 + y +
", " +
sparsity(sp_y) +
", " + iw +
")";
2085 std::string cpp_prefix = this->
cpp ?
"extern \"C\" " :
"";
2093 return cpp_prefix + this->dll_export + s;
2098 const std::string& res,
const Sparsity& sp_res,
2099 const std::string& w) {
2105 std::stringstream s;
2106 s <<
"casadi_project(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", " <<
res <<
", "
2107 <<
sparsity(sp_res) <<
", " << w <<
");";
2113 const std::string& res,
bool lower) {
2116 std::stringstream s;
2117 s <<
"casadi_tri_project(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", ";
2118 s <<
res <<
", " << (lower ? 1: 0) <<
");";
2124 const std::string& res,
bool tr) {
2127 std::stringstream s;
2128 s <<
"casadi_densify(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", " <<
res <<
", "
2129 << (tr ? 1 : 0) <<
");";
2138 std::stringstream s;
2139 s <<
"casadi_sparsify(" <<
arg <<
", " <<
res <<
", "
2140 <<
sparsity(sp_res) <<
", " << (tr ? 1 : 0) <<
");";
2146 std::stringstream s;
2147 s <<
"CASADI_PRINTF(";
2149 std::string::size_type pos = 0, prev = 0;
2150 while ((pos =
str.find(
'\n', prev)) != std::string::npos) {
2152 s <<
"\"" <<
str.substr(prev, pos-prev) <<
"\\n\"\n";
2156 s <<
"\"" <<
str.substr(prev) <<
"\"";
2157 for (casadi_int i=0; i<
arg.size(); ++i) s <<
", " <<
arg[i];
2163 std::vector<std::string>
arg;
2164 arg.push_back(arg1);
2169 const std::string& arg2) {
2170 std::vector<std::string>
arg;
2171 arg.push_back(arg1);
2172 arg.push_back(arg2);
2177 const std::string& arg2,
const std::string& arg3) {
2178 std::vector<std::string>
arg;
2179 arg.push_back(arg1);
2180 arg.push_back(arg2);
2181 arg.push_back(arg3);
2186 const std::string& x,
const std::string& y) {
2188 return "casadi_axpy(" +
str(n) +
", " + a +
", " + x +
", " + y +
");";
2192 const std::string& min,
const std::string& mask) {
2194 return "casadi_clip_min(" + x +
", " +
str(n) +
", " +
min +
", " + mask +
");";
2198 const std::string& min,
const std::string& mask) {
2200 return "casadi_clip_max(" + x +
", " +
str(n) +
", " +
min +
", " + mask +
");";
2204 const std::string& y,
const std::string& z) {
2206 return "casadi_vector_fmax(" +
str(n) +
", " + x +
", " + y +
", " + z +
");";
2210 const std::string& y,
const std::string& z) {
2212 return "casadi_vector_fmin(" +
str(n) +
", " + x +
", " + y +
", " + z +
");";
2216 const std::string& mask) {
2218 return "casadi_masked_norm_inf(" +
str(n) +
", " + x +
", " + mask +
")";
2223 return "casadi_scal(" +
str(n) +
", " + alpha +
", " + x +
");";
2227 const std::string& y,
const std::string& z,
bool tr) {
2229 return "casadi_mv(" + x +
", " +
sparsity(sp_x) +
", " + y +
", "
2230 + z +
", " + (tr ?
"1" :
"0") +
");";
2234 const std::string& y,
const std::string& z,
bool tr) {
2236 return "casadi_mv_dense(" + x +
", " +
str(nrow_x) +
", " +
str(ncol_x) +
", "
2237 + y +
", " + z +
", " + (tr ?
"1" :
"0") +
");";
2241 const std::string& y,
const Sparsity& sp_y,
2242 const std::string& z,
const Sparsity& sp_z,
2243 const std::string& w,
bool tr) {
2245 return "casadi_mtimes(" + x +
", " +
sparsity(sp_x) +
", " + y +
", " +
sparsity(sp_y) +
", "
2246 + z +
", " +
sparsity(sp_z) +
", " + w +
", " + (tr ?
"1" :
"0") +
");";
2250 const std::string& y,
bool tr,
bool unity, casadi_int nrhs) {
2252 return "casadi_trilsolve(" +
sparsity(sp_x) +
", " + x +
", " + y +
", " +
str(tr) +
", "
2253 +
str(unity) +
", " +
str(nrhs) +
");";
2257 const std::string& y,
bool tr,
bool unity, casadi_int nrhs) {
2259 return "casadi_triusolve(" +
sparsity(sp_x) +
", " + x +
", " + y +
", " +
str(tr) +
", "
2260 +
str(unity) +
", " +
str(nrhs) +
");";
2266 std::stringstream s;
2267 s <<
"casadi_logsumexp(" << A <<
", " << n <<
");";
2273 if (s.empty())
return;
2277 casadi_int shift = s.front()==
'}' ? -1 : 0;
2291 }
else if (c==
'}') {
2301 size_t pos = s.find(
'\n', off);
2302 if (pos==std::string::npos) {
2320 this->
buffer.str(std::string());
2324 const std::string& ref) {
2332 casadi_assert(it->second.first==type,
"Type mismatch for " +
name);
2333 casadi_assert(it->second.second==ref,
"Type mismatch for " +
name);
2339 return "w[" +
str(i) +
"]";
2353 casadi_assert(it->second==def,
"Initial value mismatch for " +
name);
2360 const std::vector<std::string>& inst,
bool add_shorthand) {
2363 for (
const std::string& s : inst) {
2364 if (s!=
"casadi_real") {
2365 for (
const std::string& s : inst)
suffix +=
"_" + s;
2371 std::vector<std::pair<std::string, std::string> > rep;
2372 for (casadi_int i=0; i<inst.size(); ++i) {
2373 rep.push_back(std::make_pair(
"T" +
str(i+1), inst[i]));
2377 std::stringstream ret;
2380 std::istringstream stream(src);
2381 while (std::getline(stream, line)) {
2385 if (line.find(
"template")==0)
continue;
2388 if (line.find(
"#define")==0)
continue;
2389 if (line.find(
"#undef")==0)
continue;
2392 if (line ==
"inline")
continue;
2395 if (line.find(
"// SYMBOL") != std::string::npos) {
2396 n1 = line.find(
"\"");
2397 n2 = line.find(
"\"", n1+1);
2398 std::string sym = line.substr(n1+1, n2-n1-1);
2401 rep.push_back(std::make_pair(sym, sym +
suffix));
2407 if (line.find(
"// C-REPLACE") != std::string::npos) {
2409 n1 = line.find(
"\"");
2410 n2 = line.find(
"\"", n1+1);
2411 std::string key = line.substr(n1+1, n2-n1-1);
2413 n1 = line.find(
"\"", n2+1);
2414 n2 = line.find(
"\"", n1+1);
2415 std::string sub = line.substr(n1+1, n2-n1-1);
2417 rep.push_back(std::make_pair(key, sub));
2422 if (!
verbose_runtime && line.find(
"// C-VERBOSE") != std::string::npos) {
2424 std::getline(stream, line);
2429 if ((n1 = line.find(
"//")) != std::string::npos) line.erase(n1);
2432 if ((n1 = line.find_last_not_of(
' ')) != std::string::npos) {
2439 for (
auto&& it = rep.rbegin(); it!=rep.rend(); ++it) {
2440 line =
replace(line, it->first, it->second);
2444 ret << line <<
"\n";
2454 *
this <<
"/* " << s <<
" */\n";
2460 const std::vector<Sparsity>& sp_in,
2461 const std::vector<Sparsity>& sp_out) {
2466 *
this <<
declare(
"const casadi_int* " +
name +
"_sparsity_in(casadi_int i)") <<
" {\n"
2467 <<
"switch (i) {\n";
2468 for (casadi_int i=0; i<sp_in.size(); ++i) {
2471 *
this <<
"default: return 0;\n}\n"
2475 *
this <<
declare(
"const casadi_int* " +
name +
"_sparsity_out(casadi_int i)") <<
" {\n"
2476 <<
"switch (i) {\n";
2477 for (casadi_int i=0; i<sp_out.size(); ++i) {
2480 *
this <<
"default: return 0;\n}\n"
2485 qr(
const std::string& sp,
const std::string& A,
const std::string& w,
2486 const std::string& sp_v,
const std::string& v,
const std::string& sp_r,
2487 const std::string& r,
const std::string& beta,
const std::string& prinv,
2488 const std::string& pc) {
2490 return "casadi_qr(" + sp +
", " + A +
", " + w +
", "
2491 + sp_v +
", " + v +
", " + sp_r +
", " + r +
", "
2492 + beta +
", " + prinv +
", " + pc +
");";
2496 qr_solve(
const std::string& x, casadi_int nrhs,
bool tr,
2497 const std::string& sp_v,
const std::string& v,
2498 const std::string& sp_r,
const std::string& r,
2499 const std::string& beta,
const std::string& prinv,
2500 const std::string& pc,
const std::string& w) {
2502 return "casadi_qr_solve(" + x +
", " +
str(nrhs) +
", " + (tr ?
"1" :
"0") +
", "
2503 + sp_v +
", " + v +
", " + sp_r +
", " + r +
", "
2504 + beta +
", " + prinv +
", " + pc +
", " + w +
");";
2508 lsqr_solve(
const std::string& A,
const std::string&x,
2509 casadi_int nrhs,
bool tr,
const std::string& sp,
const std::string& w) {
2511 return "casadi_lsqr_solve(" + A +
", " + x +
", " +
str(nrhs) +
", "
2512 + (tr ?
"1" :
"0") +
", " + sp +
", " + w +
");";
2516 ldl(
const std::string& sp_a,
const std::string& a,
2517 const std::string& sp_lt,
const std::string& lt,
const std::string& d,
2518 const std::string& p,
const std::string& w) {
2520 return "casadi_ldl(" + sp_a +
", " + a +
", " + sp_lt +
", " + lt +
", "
2521 + d +
", " + p +
", " + w +
");";
2525 ldl_solve(
const std::string& x, casadi_int nrhs,
2526 const std::string& sp_lt,
const std::string& lt,
const std::string& d,
2527 const std::string& p,
const std::string& w) {
2529 return "casadi_ldl_solve(" + x +
", " +
str(nrhs) +
", " + sp_lt +
", "
2530 + lt +
", " + d +
", " + p +
", " + w +
");";
2534 fmax(
const std::string& x,
const std::string& y) {
2536 return "casadi_fmax(" + x +
", " + y +
");";
2540 fmin(
const std::string& x,
const std::string& y) {
2542 return "casadi_fmin(" + x +
", " + y +
");";
2546 vfmax(
const std::string& x, casadi_int n,
const std::string& y) {
2548 return "casadi_vfmax(" + x +
", " +
str(n) +
", " + y +
");";
2552 vfmin(
const std::string& x, casadi_int n,
const std::string& y) {
2554 return "casadi_vfmin(" + x +
", " +
str(n) +
", " + y +
");";
2558 vfmax(
const std::string& x,
const std::string& n,
const std::string& y) {
2560 return "casadi_vfmax(" + x +
", " + n +
", " + y +
");";
2564 vfmin(
const std::string& x,
const std::string& n,
const std::string& y) {
2566 return "casadi_vfmin(" + x +
", " + n +
", " + y +
");";
2570 max(
const std::string& x,
const std::string& y) {
2572 return "casadi_max(" + x +
", " + y +
")";
2576 min(
const std::string& x,
const std::string& y) {
2578 return "casadi_min(" + x +
", " + y +
")";
2582 mmax(
const std::string& x, casadi_int n,
bool is_dense) {
2584 return "casadi_mmax(" + x +
", " +
str(n) +
", " +
str(casadi_int(is_dense)) +
")";
2588 mmin(
const std::string& x, casadi_int n,
bool is_dense) {
2590 return "casadi_mmin(" + x +
", " +
str(n) +
", " +
str(casadi_int(is_dense)) +
")";
2594 max_viol(casadi_int n,
const std::string& x,
const std::string& lb,
const std::string& ub) {
2596 return "casadi_max_viol(" +
str(n) +
", " + x+
", " + lb +
", " + ub +
")";
2600 sum_viol(casadi_int n,
const std::string& x,
const std::string& lb,
const std::string& ub) {
2602 return "casadi_sum_viol(" +
str(n) +
", " + x+
", " + lb +
", " + ub +
")";
2606 norm_inf(casadi_int n,
const std::string& x) {
2608 return "casadi_norm_inf(" +
str(n) +
", " + x +
")";
2612 norm_1(casadi_int n,
const std::string& x) {
2614 return "casadi_norm_1(" +
str(n) +
", " + x +
")";
2618 norm_2(casadi_int n,
const std::string& x) {
2620 return "casadi_norm_2(" +
str(n) +
", " + x +
")";
2626 return "casadi_lb_eig(" +
sparsity(sp_h) +
", " + h +
")";
2632 return "casadi_regularize(" +
sparsity(sp_h) +
", " + h +
", " + reg +
");";
2637 const std::string& Hin,
const std::string& Hout,
const std::string& iw,
const std::string& w) {
2643 low(
const std::string& x,
const std::string& grid, casadi_int ng, casadi_int lookup_mode) {
2645 return "casadi_low(" + x +
", " + grid +
", " +
str(ng) +
", " +
str(lookup_mode) +
");";
2650 const std::string& lam,
const std::string& lbx,
const std::string& ubx) {
2652 return "casadi_bound_consistency(" +
str(n) +
", " + x +
", " + lam +
2653 ", " + lbx +
", " + ubx +
")";
2657 file_slurp(
const std::string& fname, casadi_int n,
const std::string& a) {
2659 return "casadi_file_slurp(\"" + fname +
"\", " +
str(n) +
", " + a +
")";
2663 cache_check(
const std::string& key,
const std::string& cache,
const std::string& loc,
2664 casadi_int stride, casadi_int sz, casadi_int key_sz,
const std::string& val) {
2666 return "cache_check(" + key +
", " + cache +
", " + loc +
", " +
2667 str(stride) +
", " +
str(sz) +
", " +
str(key_sz) +
", " + val +
")";
2671 sz_arg = sz_res = sz_iw = sz_w = 0;
2673 sz_arg = std::max(sz_arg, f.f.sz_arg());
2674 sz_res = std::max(sz_res, f.f.sz_res());
2675 sz_iw = std::max(sz_iw, f.f.sz_iw());
2676 sz_w = std::max(sz_w, f.f.sz_w());
Helper class for C code generation.
std::string triusolve(const Sparsity &sp_x, const std::string &x, const std::string &y, bool tr, bool unity, casadi_int nrhs)
Codegen upper triangular solve.
void define_pool_double(const std::string &name, const std::vector< double > &def)
Allocate file scope double writeable memory.
bool codegen_scalars
Codegen scalar.
std::string fill(const std::string &res, std::size_t n, const std::string &v)
Create a fill operation.
std::stringstream includes
std::string axpy(casadi_int n, const std::string &a, const std::string &x, const std::string &y)
Codegen axpy: y += a*x.
static std::string fmu_helpers(const std::string &modelname)
FMU helper functions.
std::string lsqr_solve(const std::string &A, const std::string &x, casadi_int nrhs, bool tr, const std::string &sp, const std::string &w)
std::set< std::string > added_externals_
std::string logsumexp(const std::string &A, casadi_int n)
std::string clip_min(const std::string &x, casadi_int n, const std::string &min, const std::string &mask)
Codegen clip_min: Clips the smaller entries in a vector than min to the min.
std::string project(const std::string &arg, const Sparsity &sp_arg, const std::string &res, const Sparsity &sp_res, const std::string &w)
Sparse assignment.
std::string add_dependency(const Function &f)
Add a function dependency.
std::string mmax(const std::string &x, casadi_int n, bool is_dense)
mmax
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string arg(casadi_int i) const
Refer to argument.
std::string dump()
Generate a file, return code as string.
std::string wrapper(const Function &base, const std::string &name)
std::vector< std::string > added_sfunctions
std::string pool_double(const std::string &name) const
Access file scope double writeable memory.
void add_io_sparsities(const std::string &name, const std::vector< Sparsity > &sp_in, const std::vector< Sparsity > &sp_out)
Add io sparsity patterns of a function.
void scope_enter()
Enter a local scope.
std::string rom_integer(const void *id) const
Access file scope integer read-only memory.
std::string norm_2(casadi_int n, const std::string &x)
norm_2
std::string copy(const std::string &arg, std::size_t n, const std::string &res)
Create a copy operation.
std::map< std::string, casadi_int > pool_double_
void comment(const std::string &s)
Write a comment line (ignored if not verbose)
void reserve_work(casadi_int n)
Reserve a maximum size of work elements, used for padding of index.
std::string masked_norm_inf(casadi_int n, const std::string &x, const std::string &mask)
codegen masked_norm_inf: The mask tells what entry is used in the inf-norm.
std::set< std::string > added_includes_
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
std::string casadi_real_type
void add(const Function &f, bool with_jac_sparsity=false)
Add a function (name generated)
void flush(std::ostream &s)
Flush the buffer to a stream of choice.
casadi_int add_sparsity(const Sparsity &sp, bool canonical=true)
std::string scal(casadi_int n, const std::string &alpha, const std::string &x)
What does scal do??
static void stream_open(std::ostream &f, bool cpp)
Print file header.
std::string rank1(const std::string &A, const Sparsity &sp_A, const std::string &alpha, const std::string &x, const std::string &y)
Rank-1 update.
std::string low(const std::string &x, const std::string &grid, casadi_int ng, casadi_int lookup_mode)
low
std::multimap< Auxiliary, std::vector< std::string > > added_auxiliaries_
CodeGenerator(const std::string &name, const Dict &opts=Dict())
Constructor.
std::string fmin(const std::string &x, const std::string &y)
fmin
static void stream_close(std::ostream &f, bool cpp)
Print file header.
std::string sum_viol(casadi_int n, const std::string &x, const std::string &lb, const std::string &ub)
sum_viol
std::string to_mex(const Sparsity &sp, const std::string &arg)
Create matrix in MATLAB's MEX format.
std::string printf(const std::string &str, const std::vector< std::string > &arg=std::vector< std::string >())
Printf.
std::string print_op(casadi_int op, const std::string &a0)
Print an operation to a c file.
std::map< std::string, std::pair< std::string, std::string > > local_variables_
std::string max(const std::string &x, const std::string &y)
max
void indent()
Increase indentation.
std::string rom_double(const void *id) const
Access file scope double read-only memory.
std::map< std::string, std::string > local_default_
std::vector< std::vector< char > > char_constants_
static std::string array(const std::string &type, const std::string &name, casadi_int len, const std::string &def=std::string())
std::string bilin(const std::string &A, const Sparsity &sp_A, const std::string &x, const std::string &y)
Codegen bilinear form.
std::string bound_consistency(casadi_int n, const std::string &x, const std::string &lam, const std::string &lbx, const std::string &ubx)
bound_consistency
std::string vector_fmax(casadi_int n, const std::string &x, const std::string &y, const std::string &z)
Codegen vector_fmax: Takes vectorwise max of a vector and writes the result to second vector.
std::string casadi_int_type
std::string sparsify(const std::string &arg, const std::string &res, const Sparsity &sp_res, bool tr=false)
Sparsify.
std::string mv(const std::string &x, const Sparsity &sp_x, const std::string &y, const std::string &z, bool tr)
Codegen sparse matrix-vector multiplication.
static size_t hash(const std::vector< double > &v)
std::vector< std::vector< double > > pool_double_defaults_
std::string ldl_solve(const std::string &x, casadi_int nrhs, const std::string &sp_lt, const std::string <, const std::string &d, const std::string &p, const std::string &w)
LDL solve.
CodeGenerator & operator<<(const std::string &s)
Print a string to buffer.
std::string generate(const std::string &prefix="")
Generate file(s)
std::string ldl(const std::string &sp_a, const std::string &a, const std::string &sp_lt, const std::string <, const std::string &d, const std::string &p, const std::string &w)
LDL factorization.
std::string lb_eig(const Sparsity &sp_h, const std::string &h)
lb_eig
std::string operator()(const Function &f, const std::string &arg, const std::string &res, const std::string &iw, const std::string &w, const std::string &failure_ret="1")
Generate a call to a function (generic signature)
std::string mmin(const std::string &x, casadi_int n, bool is_dense)
mmin
std::string densify(const std::string &arg, const Sparsity &sp_arg, const std::string &res, bool tr=false)
Densify.
std::multimap< size_t, size_t > added_double_constants_
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
void add_external(const std::string &new_external)
Add an external function declaration.
std::string workel(casadi_int n) const
casadi_int current_indent_
std::string min(const std::string &x, const std::string &y)
min
void setup_callback(const std::string &s, const Function &f)
Setup a callback.
casadi_int max_initializer_elements_per_line
std::string mem(const Function &f)
Access thread-local memory.
void print_vector(std::ostream &s, const std::string &name, const std::vector< casadi_int > &v)
Print casadi_int vector to a c file.
void unindent()
Decrease indentation.
std::string from_mex(std::string &arg, const std::string &res, std::size_t res_off, const Sparsity &sp_res, const std::string &w)
Get matrix from MATLAB's MEX format.
std::vector< std::vector< double > > double_constants_
std::string res(casadi_int i) const
Refer to resuly.
std::vector< std::vector< casadi_int > > integer_constants_
std::string interpn(const std::string &res, casadi_int ndim, const std::string &grid, const std::string &offset, const std::string &values, const std::string &x, const std::string &lookup_mode, casadi_int m, const std::string &iw, const std::string &w)
Multilinear interpolation.
void sz_work(size_t &sz_arg, size_t &sz_res, size_t &sz_iw, size_t &sz_w) const
Get number of temporary variables needed for all functions.
std::multimap< size_t, size_t > added_char_constants_
std::vector< std::vector< std::string > > string_constants_
std::string vfmax(const std::string &x, casadi_int n, const std::string &y)
vfmax
std::string norm_inf(casadi_int n, const std::string &x)
norm_inf
std::string ones(casadi_int sz)
std::string vector_fmin(casadi_int n, const std::string &x, const std::string &y, const std::string &z)
Codegen vector_fmin: Takes vectorwise min of a vector and writes the result to second vector.
std::map< const void *, casadi_int > file_scope_integer_
std::string declare(std::string s)
Declare a function.
std::string mtimes(const std::string &x, const Sparsity &sp_x, const std::string &y, const Sparsity &sp_y, const std::string &z, const Sparsity &sp_z, const std::string &w, bool tr)
Codegen sparse matrix-matrix multiplication.
void scope_exit()
Exit a local scope.
std::string vfmin(const std::string &x, casadi_int n, const std::string &y)
vfmin
void init_local(const std::string &name, const std::string &def)
Specify the default value for a local variable.
std::string cache_check(const std::string &key, const std::string &cache, const std::string &loc, casadi_int stride, casadi_int sz, casadi_int key_sz, const std::string &val)
cache check
void define_rom_integer(const void *id, casadi_int size)
Allocate file scope integer read-only memory.
std::string qr_solve(const std::string &x, casadi_int nrhs, bool tr, const std::string &sp_v, const std::string &v, const std::string &sp_r, const std::string &r, const std::string &beta, const std::string &prinv, const std::string &pc, const std::string &w)
QR solve.
casadi_int max_declarations_per_line
std::string sanitize_source(const std::string &src, const std::vector< std::string > &inst, bool add_shorthand=true)
Sanitize source files for codegen.
std::string dot(casadi_int n, const std::string &x, const std::string &y)
Codegen inner product.
std::vector< FunctionMeta > added_functions_
std::string clip_max(const std::string &x, casadi_int n, const std::string &min, const std::string &mask)
Codegen clip_max: Clips the larger entries in a vector than max to the max.
static std::string casadi_version()
Current CasADi version as string.
void define_rom_double(const void *id, casadi_int size)
Allocate file scope double read-only memory.
std::string interpn_grad(const std::string &grad, casadi_int ndim, const std::string &grid, const std::string &offset, const std::string &values, const std::string &x, const std::string &lookup_mode, casadi_int m, const std::string &iw, const std::string &w)
Multilinear interpolation - calculate gradient.
void add_include(const std::string &new_include, bool relative_path=false, const std::string &use_ifdef=std::string())
Add an include file optionally using a relative path "..." instead of an absolute path <....
std::string shorthand(const std::string &name) const
Get a shorthand.
Auxiliary
Auxiliary functions.
@ AUX_BLAZING_2D_BOOR_EVAL
@ AUX_BLAZING_1D_BOOR_EVAL
@ AUX_INTERPN_INTERPOLATE
@ AUX_BLAZING_3D_BOOR_EVAL
void constant_copy(const std::string &var_name, const std::vector< casadi_int > &v, const std::string &type="casadi_int")
Represent an array constant; adding it when new.
std::map< std::string, std::map< FunctionInternal *, casadi_int > > added_wrappers_
void copy_check(const std::string &arg, std::size_t n, const std::string &res, bool check_lhs=true, bool check_rhs=true)
std::string tri_project(const std::string &arg, const Sparsity &sp_arg, const std::string &res, bool lower)
Project triangular part.
std::multimap< size_t, size_t > added_integer_constants_
std::multimap< size_t, size_t > added_string_constants_
std::map< const void *, casadi_int > file_scope_double_
std::string file_slurp(const std::string &fname, casadi_int n, const std::string &a)
Slurp a file.
std::string initializer(const std::vector< T > &v)
Print an initializer.
std::string norm_1(casadi_int n, const std::string &x)
norm_1
std::set< std::string > sparsity_meta
std::string max_viol(casadi_int n, const std::string &x, const std::string &lb, const std::string &ub)
max_viol
std::string convexify_eval(const ConvexifyData &d, const std::string &Hin, const std::string &Hout, const std::string &iw, const std::string &w)
convexify
std::vector< std::string > exposed_fname
std::string sparsity(const Sparsity &sp, bool canonical=true)
std::string print_scalar(const std::string &arg)
Print canonical representaion of a scalar.
void copy_default(const std::string &arg, std::size_t n, const std::string &res, const std::string &def, bool check_rhs=true)
std::string trans(const std::string &x, const Sparsity &sp_x, const std::string &y, const Sparsity &sp_y, const std::string &iw)
Transpose.
casadi_int padding_length_
casadi_int get_constant(const std::vector< double > &v, bool allow_adding=false)
Get or add a constant.
casadi_int get_sparsity(const Sparsity &sp) const
Get the index of an existing sparsity pattern.
void print_formatted(const std::string &s)
Print without newline characters.
bool elide_copy(casadi_int sz)
std::string zeros(casadi_int sz)
std::string trilsolve(const Sparsity &sp_x, const std::string &x, const std::string &y, bool tr, bool unity, casadi_int nrhs)
Codegen lower triangular solve.
std::set< std::string > added_shorthands_
static bool equal(const std::vector< T > &v1, const std::vector< T > &v2)
std::stringstream auxiliaries
std::string qr(const std::string &sp, const std::string &A, const std::string &w, const std::string &sp_v, const std::string &v, const std::string &sp_r, const std::string &r, const std::string &beta, const std::string &prinv, const std::string &pc)
QR factorization.
std::string fmax(const std::string &x, const std::string &y)
fmax
std::string clear(const std::string &res, std::size_t n)
Create a fill operation.
std::string print_canonical(const Sparsity &sp, const std::string &arg)
Print canonical representaion of a matrix.
std::string format_padded(casadi_int i) const
std::string regularize(const Sparsity &sp_h, const std::string &h, const std::string ®)
regularize
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
std::string sx_work(casadi_int i)
Declare a work vector element.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
static std::unique_ptr< std::ostream > ofstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
Internal class for Function.
bool has_refcount_
Reference counting in codegen?
virtual std::string codegen_mem_type() const
Thread-local memory object type.
std::vector< Sparsity > sparsity_in_
Input and output sparsity.
virtual void codegen_free_mem(CodeGenerator &g) const
Codegen for free_mem.
virtual void codegen_incref(CodeGenerator &g) const
Codegen incref for dependencies.
std::string signature_unrolled(const std::string &fname) const
Code generate the function.
virtual std::string codegen_name(const CodeGenerator &g, bool ns=true) const
Get name in codegen.
void codegen(CodeGenerator &g, const std::string &fname) const
Generate code the function.
virtual void codegen_release(CodeGenerator &g) const
Codegen for release.
virtual void codegen_alloc_mem(CodeGenerator &g) const
Codegen decref for alloc_mem.
virtual void codegen_checkout(CodeGenerator &g) const
Codegen for checkout.
virtual void codegen_declarations(CodeGenerator &g) const
Generate code for the declarations of the C function.
std::string signature(const std::string &fname) const
Code generate the function.
void codegen_meta(CodeGenerator &g) const
Generate meta-information allowing a user to evaluate a generated function.
virtual void codegen_init_mem(CodeGenerator &g) const
Codegen decref for init_mem.
virtual void codegen_decref(CodeGenerator &g) const
Codegen decref for dependencies.
FunctionInternal * get() const
const std::vector< std::string > & name_in() const
Get input scheme.
const std::string & name() const
Name of the function.
static bool check_name(const std::string &name)
Check if a string is a valid function name.
casadi_int n_out() const
Get the number of function outputs.
casadi_int n_in() const
Get the number of function inputs.
const std::vector< Sparsity > & jac_sparsity(bool compact=false) const
Get, if necessary generate, the sparsity of all Jacobian blocks.
const std::vector< std::string > & name_out() const
Get output scheme.
static casadi_int copy_elision_min_size
casadi_int nnz() const
Get the number of (structural) non-zeros.
std::vector< casadi_int > compress(bool canonical=true) const
Compress a sparsity pattern.
std::string join(const std::vector< std::string > &l, const std::string &delim)
CASADI_EXPORT std::string replace(const std::string &s, const std::string &p, const std::string &r)
Replace all occurences of p with r in s.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
void hash_combine(std::size_t &seed, T v)
Generate a hash value incrementally (function taken from boost)
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.